开发票

This commit is contained in:
lyp 2025-04-02 15:30:55 +08:00
parent 458ae8efaf
commit f59ab1d7c4
15 changed files with 2829 additions and 1673 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,22 +1,27 @@
import { Button, Dropdown, Flex, MenuProps, Modal, Popconfirm, Space, Table, TableProps, Tag } from "antd"; import { Button, Dropdown, Flex, MenuProps, Modal, Popconfirm, Space, Table, TableProps, Tag, Spin } from "antd";
import { PlusOutlined } from "@ant-design/icons"; import { PlusOutlined } from "@ant-design/icons";
import { import {
useEffect, useEffect,
// useRef, // useRef,
useState useState,
useContext
} from "react"; } from "react";
import { get, put } from "../../util/AjaxUtils.ts"; import { getInvoiceRecordList,cancelInvoice } from "../../request/api.ts";
import { IListPage } from "../../interfaces/listpage/IListPage.ts"; import {downloadInvoice} from '../../request/request.ts'
import { GlobalContext } from "../../context/GlobalContext.ts";
// import { get, put } from "../../util/AjaxUtils.ts";
// import { IListPage } from "../../interfaces/listpage/IListPage.ts";
import useMessage from "antd/es/message/useMessage"; import useMessage from "antd/es/message/useMessage";
import InvoiceSave from "./InvoiceSave.tsx"; // import InvoiceSave from "./InvoiceSave.tsx";
import InvoiceEdit from "./InvoiceEdit.tsx"; import InvoiceSave from "./NewInvoiceSave.tsx";
import InvoiceEdit from "./NewInvoiceEdit.tsx";
import InvoiceShow from "./InvoiceShow.tsx"; import InvoiceShow from "./InvoiceShow.tsx";
enum InvoiceStatusEnum { enum InvoiceStatusEnum {
PENDING = 'PENDING', PENDING = '1',
COMPLETE = 'COMPLETE', COMPLETE = '2',
FAILED = 'FAILED', FAILED = '0',
CANCEL = 'CANCEL', CANCEL = '-1',
} }
type DataType = { type DataType = {
@ -38,6 +43,8 @@ type DataType = {
invoiceStatus: InvoiceStatusEnum; invoiceStatus: InvoiceStatusEnum;
invoiceTitle: string; invoiceTitle: string;
orderIds: string[]; orderIds: string[];
invoiceRechargeId: string;
invoiceFile: string;
} }
export default function InvoiceList() { export default function InvoiceList() {
@ -49,57 +56,80 @@ export default function InvoiceList() {
const [isEditModalOpen, setIsEditModalOpen] = useState(false); const [isEditModalOpen, setIsEditModalOpen] = useState(false);
const [isShowModalOpen, setIsShowModalOpen] = useState(false); const [isShowModalOpen, setIsShowModalOpen] = useState(false);
// const invoiceId = useRef(''); // const invoiceId = useRef('');
const [invoiceId, setInvoiceId] = useState(''); // const [invoiceId, setInvoiceId] = useState('');
const [status, setStatus] = useState(''); //状态
const [invoiceRechargeId, setInvoiceRechargeId] = useState(''); //查看订单主键
// const [invdataArray,setInvDataArray] = useState<any[]>([]); // const [invdataArray,setInvDataArray] = useState<any[]>([]);
//点击取消
const cancel = async(value:string) => {
try{
await cancelInvoice(value)
getData()
messageApi.open({
type: 'success',
content: '取消成功',
})
}catch(error: any) {
if (error.response) {
const data = error.response.data;
messageApi.open({
type: 'error',
content: data.msg ? data.msg : `${data.path}(${data.status})`,
});
} else {
console.error(error)
}
}
};
const columns: TableProps<DataType>['columns'] = [ const columns: TableProps<DataType>['columns'] = [
{ {
title: '名称', title: '名称',
dataIndex: 'invoiceTitle', dataIndex: 'invoiceName',
align: 'center', align: 'center',
width: 180 width: 180
}, },
{ {
title: '纳税人识别号', title: '纳税人识别号',
dataIndex: 'invoiceNo', dataIndex: 'invoiceNumber',
align: 'center',
width: 180
},
{
title: '地址',
dataIndex: 'invoiceAddress',
align: 'center',
width: 180
},
{
title: '电话',
dataIndex: 'invoicePhone',
align: 'center',
width: 180
},
{
title: '开户行',
dataIndex: 'invoiceBank',
align: 'center',
width: 180
},
{
title: '开户行账号',
dataIndex: 'invoiceAccount',
align: 'center', align: 'center',
width: 180 width: 180
}, },
// {
// title: '地址',
// dataIndex: 'invoiceOrgaddress',
// align: 'center',
// width: 180
// },
// {
// title: '电话',
// dataIndex: 'invoiceOrgtel',
// align: 'center',
// width: 180
// },
// {
// title: '开户行',
// dataIndex: 'invoiceBank',
// align: 'center',
// width: 180
// },
// {
// title: '开户行账号',
// dataIndex: 'invoiceBanknumber',
// align: 'center',
// width: 180
// },
{ {
title: '金额', title: '金额',
dataIndex: 'invoiceAmount', dataIndex: 'invoiceRechargeMoney',
align: 'center', align: 'center',
width: 160, width: 160,
render: (value) => {
return (value / 100).toFixed(2)
}
}, },
{ {
title: '备注', title: '备注',
dataIndex: 'invoiceNote', dataIndex: 'invoiceRecord',
align: 'center', align: 'center',
width: 180 width: 180
}, },
@ -114,7 +144,7 @@ export default function InvoiceList() {
dataIndex: 'invoiceStatus', dataIndex: 'invoiceStatus',
align: 'center', align: 'center',
width: 100, width: 100,
fixed: 'right', // fixed: 'right',
render: (value) => { render: (value) => {
if (value === InvoiceStatusEnum.PENDING) { if (value === InvoiceStatusEnum.PENDING) {
return <Tag color="magenta"></Tag> return <Tag color="magenta"></Tag>
@ -123,11 +153,12 @@ export default function InvoiceList() {
return <Tag color="green"></Tag> return <Tag color="green"></Tag>
} }
if (value === InvoiceStatusEnum.FAILED) { if (value === InvoiceStatusEnum.FAILED) {
return <Tag color="red"></Tag> return <Tag color="red"></Tag>
} }
if (value === InvoiceStatusEnum.CANCEL) { if (value === InvoiceStatusEnum.CANCEL) {
return <Tag color="cyan"></Tag> return <Tag color="cyan"></Tag>
} }
} }
}, },
{ {
@ -135,7 +166,7 @@ export default function InvoiceList() {
dataIndex: 'operate', dataIndex: 'operate',
align: 'center', align: 'center',
width: 120, width: 120,
fixed: 'right', // fixed: 'right',
render: (_value, record) => { render: (_value, record) => {
if (record.invoiceStatus === InvoiceStatusEnum.PENDING) { if (record.invoiceStatus === InvoiceStatusEnum.PENDING) {
return <Flex justify="center"> return <Flex justify="center">
@ -146,7 +177,8 @@ export default function InvoiceList() {
}} onClick={() => { }} onClick={() => {
// invoiceId.current = record.invoiceId; // invoiceId.current = record.invoiceId;
// console.log(record.invoiceId); // console.log(record.invoiceId);
setInvoiceId(record.invoiceId); // setInvoiceId(record.invoiceId);
setInvoiceRechargeId(record.invoiceRechargeId);
setIsShowModalOpen(true); setIsShowModalOpen(true);
}}></Button> }}></Button>
<Popconfirm <Popconfirm
@ -161,14 +193,15 @@ export default function InvoiceList() {
} }
}} }}
onConfirm={() => { onConfirm={() => {
put<any>({ // put<any>({
messageApi, // messageApi,
url: `/api/invoice/update-cancel/${record.invoiceId}`, // url: `/api/invoice/update-cancel/${record.invoiceId}`,
onSuccess() { // onSuccess() {
messageApi.success('取消成功'); // messageApi.success('取消成功');
getData(); // getData();
} // }
}) // })
cancel(record.invoiceRechargeId);
}} }}
> >
<Button type="link" danger style={{ <Button type="link" danger style={{
@ -179,52 +212,100 @@ export default function InvoiceList() {
</Space> </Space>
</Flex> </Flex>
} }
if (record.invoiceStatus === InvoiceStatusEnum.CANCEL) { if (record.invoiceStatus === InvoiceStatusEnum.CANCEL||record.invoiceStatus === InvoiceStatusEnum.FAILED ) {
return <Button type="link" style={{ return <Button type="link" style={{
padding: '0' padding: '0'
}} onClick={() => { }} onClick={() => {
// invoiceId.current = record.invoiceId; // invoiceId.current = record.invoiceId;
console.log(record.invoiceId); // console.log(record.invoiceId);
setInvoiceId(record.invoiceId); // setInvoiceId(record.invoiceId);
setStatus(record.invoiceStatus )
setInvoiceRechargeId(record.invoiceRechargeId);
setIsEditModalOpen(true); setIsEditModalOpen(true);
}}></Button> }}></Button>
} }
// if (record.invoiceStatus === InvoiceStatusEnum.FAILED ) {
// return <Button type="link" style={{
// padding: '0'
// }} onClick={() => {
// // invoiceId.current = record.invoiceId;
// // console.log(record.invoiceId);
// // setInvoiceId(record.invoiceId);
// setInvoiceRechargeId(record.invoiceRechargeId);
// setIsEditModalOpen(true);
// // setFailed(true)
// }}>编辑</Button>
// }
if (record.invoiceStatus == InvoiceStatusEnum.COMPLETE) { if (record.invoiceStatus == InvoiceStatusEnum.COMPLETE) {
const items: MenuProps['items'] = []; const items: MenuProps['items'] = [];
record.invoiceFileList.forEach((item, index) => { const arr = record.invoiceFile.split(',');
// record.invoiceFileList.forEach((item, index) => {
// items.push({
// key: index,
// label: (
// <a href={item} download target="_blank">下载发票{index + 1}</a>
// )
// });
// })
arr.forEach((item, index) => {
items.push({ items.push({
key: index, key: index,
label: ( label: (
<a href={item} download target="_blank">{index + 1}</a> <a href={downloadInvoice(item)} download target="_blank">{index + 1}</a>
) )
}); });
}) })
return ( return (
<Dropdown menu={{ items }} placement="bottom" arrow> <Dropdown menu={{ items }} placement="bottom" arrow>
<Button type="link"></Button> <Button type="link" ></Button>
</Dropdown> </Dropdown>
) )
} }
} }
}, },
] ]
const globalContext = useContext(GlobalContext);
const [loading, setLoading] = useState(false);
const getData = async () => {
try {
setLoading(true);
const res: any = await getInvoiceRecordList(globalContext.user.userId, { page: page, rows: 20 })
setLoading(false);
// console.log(res);
setPage(res.page);
setTotal(res.total);
setDataArray(res.rows);
} catch (error: any) {
const getData = () => { if (error.response) {
get<IListPage<DataType>>({ const data = error.response.data;
messageApi, messageApi.open({
url: '/api/invoice/listpage/self', type: 'error',
config: { content: data.msg ? data.msg : `${data.path}(${data.status})`,
params: { });
page: page, } else {
rows: 20 console.error(error)
}
},
onSuccess({ data }) {
setPage(data.page);
setTotal(data.total);
setDataArray(data.rows);
} }
}) }
// get<IListPage<DataType>>({
// messageApi,
// url: '/api/invoice/listpage/self',
// config: {
// params: {
// page: page,
// rows: 20
// }
// },
// onSuccess({ data }) {
// setPage(data.page);
// setTotal(data.total);
// setDataArray(data.rows);
// }
// })
} }
useEffect(() => { useEffect(() => {
@ -240,15 +321,17 @@ export default function InvoiceList() {
setIsSaveModalOpen(true); setIsSaveModalOpen(true);
}}><PlusOutlined /> </Button> }}><PlusOutlined /> </Button>
</div> </div>
<Table columns={columns} dataSource={dataArray} pagination={ <Spin tip="正在处理,请稍后..." size="small" spinning={loading}>
{ <Table columns={columns} dataSource={dataArray} pagination={
pageSize: 20, {
total: total, pageSize: 20,
onChange: (currentPage) => { total: total,
setPage(currentPage); onChange: (currentPage) => {
}, setPage(currentPage);
} },
} scroll={{ y: 500 }} bordered key="dataTable" rowKey="invoiceId" /> }
} scroll={{ y:500}} bordered key="dataTable" rowKey="invoiceRechargeId" />
</Spin>
</div> </div>
</div> </div>
<Modal open={isSaveModalOpen} <Modal open={isSaveModalOpen}
@ -279,8 +362,9 @@ export default function InvoiceList() {
destroyOnClose destroyOnClose
> >
<InvoiceEdit <InvoiceEdit
invoiceId={invoiceId} // invoiceId={invoiceId}
// invdataArray={invdataArray} // invdataArray={invdataArray}
invoiceRechargeId={invoiceRechargeId}
handleOk={() => { handleOk={() => {
getData(); getData();
setIsEditModalOpen(false); setIsEditModalOpen(false);
@ -288,6 +372,7 @@ export default function InvoiceList() {
handleCancel={() => { handleCancel={() => {
setIsEditModalOpen(false); setIsEditModalOpen(false);
}} }}
status={status}
/> />
</Modal> </Modal>
<Modal open={isShowModalOpen} <Modal open={isShowModalOpen}
@ -299,7 +384,8 @@ export default function InvoiceList() {
> >
{/* {invoiceId.current} */} {/* {invoiceId.current} */}
<InvoiceShow <InvoiceShow
invoiceId={invoiceId} invoiceRechargeId={invoiceRechargeId}
// invoiceId={invoiceId}
/> />
</Modal> </Modal>
{messageContext} {messageContext}

File diff suppressed because it is too large Load Diff

View File

@ -1,27 +1,28 @@
import { Button, Divider, Modal } from "antd"; import { Button, Divider, Modal } from "antd";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { get } from "../../util/AjaxUtils.ts"; // import { get } from "../../util/AjaxUtils.ts";
import {getInvoiceInfoById} from '../../request/api.ts'
import useMessage from "antd/es/message/useMessage"; import useMessage from "antd/es/message/useMessage";
import InvoiceInfoSelectedList from "./order/InvoiceOrderSelectedList.tsx" import InvoiceInfoSelectedList from "./order/InvoiceOrderSelectedList.tsx"
type DataType = { type DataType = {
invoiceTitle: string; invoiceName: string;
invoiceNo: string; invoiceNumber: string;
invoiceAddress: string; invoiceOrgaddress: string;
invoicePhone: string; invoiceOrgtel: string;
invoiceAccount: string; invoiceBanknumber: string;
invoiceBank: string; invoiceBank: string;
content: string; invoicePurpose: string;
rate: string; invoiceTaxrate: string;
type: string; invoiceClassify: string;
orderIds: string[]; orderIds: string[];
invoiceNote: string; invoiceRecord: string;
isSaveInvoiceInfo: boolean; isSaveInvoiceInfo: boolean;
invoiceAmount: number; invoiceAmount: number;
} }
type ShowProps = { type ShowProps = {
invoiceId: string; invoiceRechargeId: string;
} }
export default function InvoiceShow(props: ShowProps) { export default function InvoiceShow(props: ShowProps) {
@ -29,23 +30,44 @@ export default function InvoiceShow(props: ShowProps) {
const [isInvoiceOrderListOpen, setIsInvoiceOrderListOpen] = useState(false); const [isInvoiceOrderListOpen, setIsInvoiceOrderListOpen] = useState(false);
const [invoiceData, setInvoiceData] = useState<DataType | null>(null); const [invoiceData, setInvoiceData] = useState<DataType | null>(null);
const [orderAmount, setOrderAmount] = useState('0'); const [orderAmount, setOrderAmount] = useState('0');
const getData = async () => {
try {
const res: any = await getInvoiceInfoById(props.invoiceRechargeId)
console.log('数据', res);
setInvoiceData({ ...res })
setOrderAmount(res.invoiceRechargeMoney )
} catch(error:any){
if (error.response) {
if (error.response) {
const data = error.response.data;
messageApi.open({
type: 'error',
content: data.msg ? data.msg : `${data.path}(${data.status})`,
});
} else {
console.error(error)
}
}
}
}
useEffect(() => { useEffect(() => {
if (!props.invoiceId) { if (!props.invoiceRechargeId) {
return; return;
} }
get<DataType>({
messageApi, // get<DataType>({
url: `/api/invoice/get/${props.invoiceId}`, // messageApi,
onSuccess({ data }) { // url: `/api/invoice/get/${props.invoiceId}`,
setInvoiceData({ // onSuccess({ data }) {
...data // setInvoiceData({
}); // ...data
setOrderAmount((data.invoiceAmount / 100).toFixed(2)); // });
} // setOrderAmount((data.invoiceAmount / 100).toFixed(2));
}) // }
// })
getData();
}, []); }, []);
@ -61,39 +83,39 @@ export default function InvoiceShow(props: ShowProps) {
<tbody> <tbody>
<tr> <tr>
<td className="table-label"> *</td> <td className="table-label"> *</td>
<td>{invoiceData?.invoiceTitle}</td> <td>{invoiceData?.invoiceName}</td>
</tr> </tr>
<tr> <tr>
<td className="table-label"> *</td> <td className="table-label"> *</td>
<td>{invoiceData?.invoiceNo}</td> <td>{invoiceData?.invoiceNumber}</td>
</tr> </tr>
<tr> <tr>
<td className="table-label"> *</td> <td className="table-label"> *</td>
<td>{invoiceData?.invoiceAddress}</td> <td>{invoiceData?.invoiceOrgaddress}</td>
</tr> </tr>
<tr> <tr>
<td className="table-label"> *</td> <td className="table-label"> *</td>
<td>{invoiceData?.invoicePhone}</td> <td>{invoiceData?.invoiceOrgtel}</td>
</tr> </tr>
<tr> <tr>
<td className="table-label"> *</td> <td className="table-label"> *</td>
<td>{invoiceData?.invoiceAccount}</td>
</tr>
<tr>
<td className="table-label"> *</td>
<td>{invoiceData?.invoiceBank}</td> <td>{invoiceData?.invoiceBank}</td>
</tr> </tr>
<tr>
<td className="table-label"> *</td>
<td>{invoiceData?.invoiceBanknumber}</td>
</tr>
<tr> <tr>
<td className="table-label"> *</td> <td className="table-label"> *</td>
<td>{invoiceData?.content}</td> <td>{invoiceData?.invoicePurpose}</td>
</tr> </tr>
<tr> <tr>
<td className="table-label"> *</td> <td className="table-label"> *</td>
<td>{invoiceData?.rate}</td> <td>{invoiceData?.invoiceTaxrate}</td>
</tr> </tr>
<tr> <tr>
<td className="table-label"> *</td> <td className="table-label"> *</td>
<td>{invoiceData?.type}</td> <td>{invoiceData?.invoiceClassify}</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
@ -112,24 +134,24 @@ export default function InvoiceShow(props: ShowProps) {
<span style={{ fontSize: '20px', fontWeight: 'bold' }}>{orderAmount}</span> <span style={{ fontSize: '20px', fontWeight: 'bold' }}>{orderAmount}</span>
<Button type="link" size="small" onClick={() => { <Button type="link" size="small" onClick={() => {
setIsInvoiceOrderListOpen(true); setIsInvoiceOrderListOpen(true);
}}></Button> }}></Button>
</div> </div>
</td> </td>
</tr> </tr>
<tr> <tr>
<td className="table-label"></td> <td className="table-label"></td>
<td>{invoiceData?.invoiceNote}</td> <td>{invoiceData?.invoiceRecord}</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
<Modal open={isInvoiceOrderListOpen} <Modal open={isInvoiceOrderListOpen}
centered centered
title="开票订单" title="开票的充值记录"
width={1000} width={1000}
footer={false} footer={false}
onCancel={() => setIsInvoiceOrderListOpen(false)} onCancel={() => setIsInvoiceOrderListOpen(false)}
> >
<InvoiceInfoSelectedList invoiceId={props.invoiceId} /> <InvoiceInfoSelectedList invoiceRechargeId={props.invoiceRechargeId} />
</Modal> </Modal>
</> </>
); );

View File

@ -0,0 +1,424 @@
import { Button, Flex, Form, Input, Modal, Radio, Space } from "antd";
import { useEffect, useState } from "react";
import { listDictionary, IDictionary } from "../../util/AjaxUtils.ts";
import { getInvoiceInfoByinvoiceRechargeId, getInvoiceRechargeList, updateInvoiceInfoByinvoiceRechargeId } from '../../request/api.ts'
import useMessage from "antd/es/message/useMessage";
import InvoiceInfoList from "./info/InvoiceInfoList.tsx";
import InvoiceOrderList from "./order/InvoiceOrderList.tsx";
import useModal from "antd/es/modal/useModal";
type FormFieldType = {
invoiceName: string;
invoiceNumber: string;
invoiceOrgaddress: string;
invoiceOrgtel: string;
invoiceBank: string;
invoiceBanknumber: string;
invoicePurpose: string;
invoiceTaxrate: string;
invoiceClassify: string;
accountRechargeIds: string[];
invoiceRecord: string;
isSaveInvoiceInfo: boolean;
}
type EditProps = {
invoiceRechargeId: string;
handleOk: () => void;
handleCancel: () => void;
// invdataArray: any[];
// isEditModalOpen: boolean;
showFailed?: boolean;
status?: string;
}
export default function InvoiceEdit(props: EditProps) {
const [selectedOrders, setSelectedOrders] = useState<any[]>([]); //被选择的数组
const [invoiceId, setInvoiceId] = useState(''); // 开票信息id
const [messageApi, messageContext] = useMessage();
const [modal, modalContext] = useModal();
const [form] = Form.useForm<FormFieldType>();
const [contentArray, setContentArray] = useState<IDictionary[]>([]);
const [rateArray, setRateArray] = useState<IDictionary[]>([]);
const [typeArray, setTypeArray] = useState<IDictionary[]>([]);
const [isInvoiceInfoListOpen, setIsInvoiceInfoListOpen] = useState(false);
const [isInvoiceOrderListOpen, setIsInvoiceOrderListOpen] = useState(false);
const [orderAmount, setOrderAmount] = useState('0');
const [invoiceFinalRecord, setInvoiceFinalRecord] = useState(''); //未通过原因
const getData = async () => {
try {
const res: any = await getInvoiceInfoByinvoiceRechargeId(props.invoiceRechargeId)
// console.log(res);
form.setFieldsValue(res)
setInvoiceId(res.invoiceId)
setInvoiceFinalRecord(res.invoiceFinalRecord)
form.setFieldValue('accountRechargeIds', res.invoiceRechargeIds);
setOrderAmount(res.invoiceRechargeMoney)
} catch (error: any) {
if (error.response) {
const data = error.response.data;
messageApi.open({
type: 'error',
content: data.msg ? data.msg : `${data.path}(${data.status})`,
});
} else {
console.error(error)
}
}
}
const getSelect = async () => {
try {
const res: any = await getInvoiceRechargeList(props.invoiceRechargeId, { page: 1, rows: 1000 })
// console.log(res);
setSelectedOrders(res.rows);
} catch (error: any) {
if (error.response) {
const data = error.response.data;
messageApi.open({
type: 'error',
content: data.msg ? data.msg : `${data.path}(${data.status})`,
});
} else {
console.error(error)
}
}
}
const upData = async () => {
console.log(form.getFieldsValue())
try {
const res: any = await updateInvoiceInfoByinvoiceRechargeId(props.invoiceRechargeId, {
...form.getFieldsValue(),
invoiceType: '企业',
invoiceRechargeId: props.invoiceRechargeId,
invoiceId: invoiceId,
// invoiceId:
})
console.log(res);
props.handleOk()
messageApi.success('提交成功');
} catch (error: any) {
if (error.response) {
const data = error.response.data;
messageApi.open({
type: 'error',
content: data.msg ? data.msg : `${data.path}(${data.status})`,
});
} else {
console.error(error)
}
}
}
useEffect(() => {
// console.log(props.invoiceRechargeId);
if (!props.invoiceRechargeId) {
return;
}
// 开票内容
listDictionary('e0251d55-cd52-4f57-be92-b2bef8a6dd62', messageApi).then((data) => {
setContentArray([...data]);
})
// 开票税率
listDictionary('b67d5208-db1d-4d0e-99de-cc22d9d50041', messageApi).then((data) => {
setRateArray([...data]);
})
// 开票类型
listDictionary('e4808c45-64ee-42fa-a413-a470fbdc0aea', messageApi).then((data) => {
setTypeArray([...data]);
})
getData()
getSelect()
// get<FormFieldType>({
// messageApi,
// url: `/api/invoice/get/${props.invoiceId}`,
// onSuccess({data}) {
// form.setFieldsValue(data);
// setOrderAmount((data.invoiceAmount / 100).toFixed(2));
// }
// })
}, []);
return (
<>
{messageContext}
{modalContext}
<Form
name="basic"
initialValues={{ isSaveInvoiceInfo: 0 }}
form={form}
onFinish={() => {
modal.confirm({
title: '提示',
centered: true,
content: '确定提交吗?',
okText: '确定',
cancelText: '取消',
okButtonProps: {
style: {
backgroundColor: 'val(--color-primary)'
}
},
onOk: () => {
upData()
// put<any>({
// messageApi,
// url: `/api/invoice/update/${props.invoiceId}`,
// body: values,
// onSuccess() {
// messageApi.success('提交成功');
// props.handleOk();
// }
// })
}
});
}}
>
<div className="payBox">
<div>
<div className="payTitle"></div>
<div style={{
marginTop: '20px',
}}>
{/* <Button type="link"
onClick={() => {
setIsInvoiceInfoListOpen(true);
}}></Button> */}
</div>
<div className="payRow">
<div className="payRowL" style={{
position: 'relative',
}}>
<div className="payName"><span style={{ color: 'red' }}>*</span></div>
<Form.Item
name="invoiceName"
rules={[{ required: true, message: '请选择开票信息' }]}
>
<Input style={{
width: '300px'
}} placeholder="请选择开票信息" />
</Form.Item>
<div style={{
position: 'absolute',
height: '32px',
width: '300px',
// backgroundColor: 'pink',
top: 0,
left: 105,
cursor: 'pointer'
}}
onClick={() => {
setIsInvoiceInfoListOpen(true);
}}
>
</div>
</div>
<div className="payRowR">
<div className="payName"><span style={{ color: 'red' }}>*</span></div>
<Form.Item
name="invoiceClassify"
rules={[{ required: true, message: '请选择发票类型' }]}
>
<Radio.Group>
<div style={{
width: '300px',
}}>
{typeArray.map(item => <Radio value={item.dataName}
key={item.dataId}>{item.dataName}</Radio>)}
</div>
</Radio.Group>
</Form.Item>
</div>
</div>
<div className="payRow" >
<div className="payRowL">
<div className="payName"><span style={{ color: 'red' }}>*</span></div>
<Form.Item
name="invoicePurpose"
rules={[{ required: true, message: '请选择开票内容' }]}
>
<Radio.Group>
<div style={{
width: '300px',
}}>
{contentArray.map(item => <Radio value={item.dataName}
key={item.dataId}>{item.dataName}</Radio>)}
</div>
</Radio.Group>
</Form.Item>
</div>
<div className="payRowR">
<div className="payName"><span style={{ color: 'red' }}>*</span></div>
<Form.Item
name="invoiceTaxrate"
rules={[{ required: true, message: '请选择开票税率' }]}
>
<Radio.Group>
<div style={{
width: '300px',
}}>
{rateArray.map(item => <Radio value={item.dataName}
key={item.dataId}>{item.dataName}</Radio>)}
</div>
</Radio.Group>
</Form.Item>
</div>
</div>
</div>
<div>
<div className="payTitle"
></div>
<div style={{
marginTop: '10px',
position: 'relative',
}}>
<div style={{
position: 'absolute',
right: 90,
top: 5,
fontSize: '16px',
fontWeight: 'bold',
color: 'red',
display: props.status == '0' ? 'block' : 'none'
}}> : {invoiceFinalRecord}</div>
<div style={{
display: 'flex',
}}>
<div className="payName" style={{
marginTop: '2px',
}}><span style={{ color: 'red' }}>*</span></div>
<Form.Item
name="accountRechargeIds"
rules={[{ required: true, message: '请选择开票金额' }]}
>
<div>
<span></span>
<span style={{ fontSize: '20px', fontWeight: 'bold' }}>{orderAmount}</span>
<Button type="link" size="small" onClick={() => {
setIsInvoiceOrderListOpen(true);
}}></Button>
</div>
</Form.Item>
</div>
<div style={{
display: 'flex',
}}>
<div className="payName" style={{
marginTop: '2px',
}}></div>
<Form.Item
name="invoiceRecord"
>
<Input.TextArea placeholder="请输入开票备注"
style={{
resize: 'none',
width: '820px',
height: '100px',
}}
/>
</Form.Item>
</div>
</div>
</div>
</div>
<Form.Item style={{ marginBottom: '0' }}>
<Flex justify="center" style={{ marginTop: '15px' }}>
<Space>
<Button type="primary" htmlType="submit" style={{
backgroundColor: 'var(--color-primary)'
}}></Button>
<Button type="default" onClick={() => {
props.handleCancel();
}}></Button>
</Space>
</Flex>
</Form.Item>
</Form>
<Modal open={isInvoiceInfoListOpen}
centered
title="开票信息"
width={1000}
footer={false}
destroyOnClose
onCancel={() => setIsInvoiceInfoListOpen(false)}
>
<InvoiceInfoList
handleOk={(selectedInvoice) => {
setInvoiceId(selectedInvoice.invoiceId);
form.setFieldsValue({
invoiceName: selectedInvoice.invoiceName,
invoiceNumber: selectedInvoice.invoiceNumber,
invoiceOrgaddress: selectedInvoice.invoiceOrgaddress,
invoiceOrgtel: selectedInvoice.invoiceOrgtel,
invoiceBank: selectedInvoice.invoiceBank,
invoiceBanknumber: selectedInvoice.invoiceBanknumber
});
setIsInvoiceInfoListOpen(false);
}}
handleCancel={() => {
setIsInvoiceInfoListOpen(false);
}}
/>
</Modal>
<Modal open={isInvoiceOrderListOpen}
title="开票订单"
width={1000}
footer={false}
destroyOnClose
onCancel={() => setIsInvoiceOrderListOpen(false)}
centered
>
<InvoiceOrderList
// selectedOrderIds={form.getFieldValue('accountRechargeIds')}
handleOk={(selectedArr) => {
// let totalAmount = 0;
// const orderIds: string[] = [];
// selectedOrders.forEach((item) => {
// totalAmount += item.totalAmount;
// orderIds.push(item.orderId);
// });
// setOrderAmount((totalAmount / 100).toFixed(2));
// setIsInvoiceOrderListOpen(false);
// form.setFieldValue('orderIds', orderIds);
setSelectedOrders(selectedArr);
let totalAmount = 0;
const orderIds: string[] = [];
selectedArr.forEach((item) => {
totalAmount += item.rechargeMoney;
orderIds.push(item.accountRechargeId);
});
const orderIdsString = orderIds.join(',');
setOrderAmount(String(totalAmount.toFixed(2)));
setIsInvoiceOrderListOpen(false);
form.setFieldValue('accountRechargeIds', orderIdsString);
}}
handleCancel={() => {
setIsInvoiceOrderListOpen(false);
}}
selectedOrders={selectedOrders}
setSelectedOrders={setSelectedOrders}
/>
</Modal>
</>
);
}

View File

@ -0,0 +1,357 @@
import { Button, Flex, Form, Input, Modal, Radio, Space } from "antd";
import { useEffect, useState, useContext } from "react";
import { GlobalContext } from "../../context/GlobalContext.ts";
import {
listDictionary, IDictionary,
// post
} from "../../util/AjaxUtils.ts";
import useMessage from "antd/es/message/useMessage";
import InvoiceInfoList from "./info/InvoiceInfoList.tsx";
import InvoiceOrderList from "./order/InvoiceOrderList.tsx";
import useModal from "antd/es/modal/useModal";
import { submitInvoiceApply } from "../../request/api.ts"
import './InvoiceSave.css'
type FormFieldType = {
invoiceName: string;
invoiceNumber: string;
invoiceOrgaddress: string;
invoiceOrgtel: string;
invoiceBank: string;
invoiceBanknumber: string;
invoicePurpose: string;
invoiceTaxrate: string;
invoiceClassify: string;
accountRechargeIds: string[];
invoiceRecord: string;
isSaveInvoiceInfo: boolean;
}
type SaveProps = {
handleOk: () => void;
handleCancel: () => void;
}
export default function InvoiceSave(props: SaveProps) {
const [messageApi, messageContext] = useMessage();
// const [selectedOrderIds, setSelectedOrderIds] = useState<string[]>([]); // 选中的订单id数组
const [modal, modalContext] = useModal();
const [form] = Form.useForm<FormFieldType>();
const [contentArray, setContentArray] = useState<IDictionary[]>([]);
const [rateArray, setRateArray] = useState<IDictionary[]>([]);
const [typeArray, setTypeArray] = useState<IDictionary[]>([]);
const [isInvoiceInfoListOpen, setIsInvoiceInfoListOpen] = useState(false);
const [isInvoiceOrderListOpen, setIsInvoiceOrderListOpen] = useState(false);
const [orderAmount, setOrderAmount] = useState('0');
const [invoiceId, setInvoiceId] = useState(''); // 开票信息id
const globalContext = useContext(GlobalContext);
const [selectedOrders, setSelectedOrders] = useState<any[]>([]); //被选择的数组
const submitInvoice = async (values: any) => {
try {
await submitInvoiceApply(globalContext.user.userId, values)
messageApi.success('提交成功');
props.handleOk();
} catch (error: any) {
if (error.response) {
const data = error.response.data;
messageApi.open({
type: 'error',
content: data.msg ? data.msg : `${data.path}(${data.status})`,
});
} else {
console.error(error)
}
}
}
// const [selectedOrders, setSelectedOrders] = useState<any[]>([]); //被选择的数组
useEffect(() => {
// 开票内容
listDictionary('e0251d55-cd52-4f57-be92-b2bef8a6dd62', messageApi).then((data) => {
setContentArray([...data]);
})
// 开票税率
listDictionary('b67d5208-db1d-4d0e-99de-cc22d9d50041', messageApi).then((data) => {
setRateArray([...data]);
})
// 开票类型
listDictionary('e4808c45-64ee-42fa-a413-a470fbdc0aea', messageApi).then((data) => {
setTypeArray([...data]);
})
}, []);
return (
<>
{messageContext}
{modalContext}
<Form
name="basic"
initialValues={{ isSaveInvoiceInfo: 0 }}
form={form}
onFinish={(values) => {
modal.confirm({
title: '提示',
content: '确定提交吗?',
okText: '确定',
cancelText: '取消',
centered: true,
okButtonProps: {
style: {
backgroundColor: 'val(--color-primary)'
}
},
onOk: () => {
console.log(values);
submitInvoice(
{
invoiceId,
invoiceTaxrate: values.invoiceTaxrate,
invoicePurpose: values.invoicePurpose,
invoiceClassify: values.invoiceClassify,
accountRechargeIds: values.accountRechargeIds,
invoiceRecord: values.invoiceRecord,
// invoiceRechargeMoney: orderAmount,
})
// console.log(values);
// post<any>({
// messageApi,
// url: '/api/invoice/save',
// body: values,
// onSuccess() {
// messageApi.success('提交成功');
// props.handleOk();
// }
// })
}
});
}}
>
<div className="payBox">
<div>
<div className="payTitle"></div>
<div style={{
marginTop: '20px',
}}>
{/* <Button type="link"
onClick={() => {
setIsInvoiceInfoListOpen(true);
}}></Button> */}
</div>
<div className="payRow">
<div className="payRowL" style={{
position: 'relative',
}}>
<div className="payName"><span style={{ color: 'red' }}>*</span></div>
<Form.Item
name="invoiceName"
rules={[{ required: true, message: '请选择开票信息' }]}
>
<Input style={{
width: '300px'
}} placeholder="请选择开票信息" />
</Form.Item>
<div style={{
position: 'absolute',
height: '32px',
width: '300px',
// backgroundColor: 'pink',
top: 0,
left: 105,
cursor: 'pointer'
}}
onClick={() => {
setIsInvoiceInfoListOpen(true);
}}
>
</div>
</div>
<div className="payRowR">
<div className="payName"><span style={{ color: 'red' }}>*</span></div>
<Form.Item
name="invoiceClassify"
rules={[{ required: true, message: '请选择发票类型' }]}
>
<Radio.Group>
<div style={{
width: '300px',
}}>
{typeArray.map(item => <Radio value={item.dataName}
key={item.dataId}>{item.dataName}</Radio>)}
</div>
</Radio.Group>
</Form.Item>
</div>
</div>
<div className="payRow" >
<div className="payRowL">
<div className="payName"><span style={{ color: 'red' }}>*</span></div>
<Form.Item
name="invoicePurpose"
rules={[{ required: true, message: '请选择开票内容' }]}
>
<Radio.Group>
<div style={{
width: '300px',
}}>
{contentArray.map(item => <Radio value={item.dataName}
key={item.dataId}>{item.dataName}</Radio>)}
</div>
</Radio.Group>
</Form.Item>
</div>
<div className="payRowR">
<div className="payName"><span style={{ color: 'red' }}>*</span></div>
<Form.Item
name="invoiceTaxrate"
rules={[{ required: true, message: '请选择开票税率' }]}
>
<Radio.Group>
<div style={{
width: '300px',
}}>
{rateArray.map(item => <Radio value={item.dataName}
key={item.dataId}>{item.dataName}</Radio>)}
</div>
</Radio.Group>
</Form.Item>
</div>
</div>
<div className="payRow" style={{
}}>
</div>
</div>
<div>
<div className="payTitle"></div>
<div style={{
marginTop: '10px',
}}>
<div style={{
display: 'flex',
}}>
<div className="payName" style={{
marginTop: '2px',
}}><span style={{ color: 'red' }}>*</span></div>
<Form.Item
name="accountRechargeIds"
rules={[{ required: true, message: '请选择开票金额' }]}
>
<div>
<span></span>
<span style={{ fontSize: '20px', fontWeight: 'bold' }}>{orderAmount}</span>
<Button type="link" size="small" onClick={() => {
setIsInvoiceOrderListOpen(true);
}}></Button>
</div>
</Form.Item>
</div>
<div style={{
display: 'flex',
}}>
<div className="payName" style={{
marginTop: '2px',
}}></div>
<Form.Item
name="invoiceRecord"
>
<Input.TextArea placeholder="请输入开票备注"
style={{
resize: 'none',
width: '820px',
height: '100px',
}}
/>
</Form.Item>
</div>
</div>
</div>
</div>
<Form.Item style={{ marginBottom: '0' }}>
<Flex justify="center" style={{ marginTop: '15px' }}>
<Space>
<Button type="primary" htmlType="submit" style={{
backgroundColor: 'var(--color-primary)'
}}></Button>
<Button type="default" onClick={() => {
props.handleCancel();
}}></Button>
</Space>
</Flex>
</Form.Item>
</Form>
<Modal open={isInvoiceInfoListOpen}
destroyOnClose
centered
title="开票信息"
width={1000}
footer={false}
onCancel={() => {
setIsInvoiceInfoListOpen(false);
}}
>
<InvoiceInfoList
handleOk={(selectedInvoice) => {
// console.log(selectedInvoice.invoiceId);
setInvoiceId(selectedInvoice.invoiceId);
form.setFieldsValue({
invoiceName: selectedInvoice.invoiceName,
invoiceNumber: selectedInvoice.invoiceNumber,
invoiceOrgaddress: selectedInvoice.invoiceOrgaddress,
invoiceOrgtel: selectedInvoice.invoiceOrgtel,
invoiceBank: selectedInvoice.invoiceBank,
invoiceBanknumber: selectedInvoice.invoiceBanknumber
});
setIsInvoiceInfoListOpen(false);
}}
handleCancel={() => {
setIsInvoiceInfoListOpen(false);
}}
/>
</Modal>
<Modal open={isInvoiceOrderListOpen}
title="需要开票的充值记录"
width={1000}
footer={false}
onCancel={() => setIsInvoiceOrderListOpen(false)}
destroyOnClose
centered
>
<InvoiceOrderList
handleOk={(selectedArr) => {
setSelectedOrders(selectedArr);
let totalAmount = 0;
const orderIds: string[] = [];
selectedArr.forEach((item) => {
totalAmount += item.rechargeMoney;
orderIds.push(item.accountRechargeId);
});
const orderIdsString = orderIds.join(',');
setOrderAmount(String(totalAmount.toFixed(2)));
setIsInvoiceOrderListOpen(false);
form.setFieldValue('accountRechargeIds', orderIdsString);
}}
handleCancel={() => {
setIsInvoiceOrderListOpen(false);
}}
selectedOrders={selectedOrders}
setSelectedOrders={setSelectedOrders}
/>
</Modal>
</>
);
}

View File

@ -1,9 +1,9 @@
import {Button, Flex, Form, Input, Space} from "antd"; import { Button, Flex, Form, Input, Space } from "antd";
import {useForm} from "antd/es/form/Form"; import { useForm } from "antd/es/form/Form";
import useModal from "antd/es/modal/useModal"; import useModal from "antd/es/modal/useModal";
import {get, post} from "../../../util/AjaxUtils.ts"; // import { get, post } from "../../../util/AjaxUtils.ts";
import useMessage from "antd/es/message/useMessage"; import useMessage from "antd/es/message/useMessage";
import {useEffect} from "react"; import { useEffect } from "react";
type FormDataType = { type FormDataType = {
invoiceTitle: string; invoiceTitle: string;
@ -15,28 +15,71 @@ type FormDataType = {
} }
interface EditProps { interface EditProps {
invoiceInfoId: string; invoiceId: string;
handleOk: () => void; handleOk: () => void;
handleCancel: () => void; handleCancel: () => void;
} }
import { getInvoiceInfo, updateInvoiceInfo } from '../../../request/api.ts'
export default function InvoiceInfoSave(props: EditProps) { export default function InvoiceInfoSave(props: EditProps) {
const [messageApi, messageContext] = useMessage(); const [messageApi, messageContext] = useMessage();
const [modal, modalContext] = useModal(); const [modal, modalContext] = useModal();
const [form] = useForm<FormDataType>() const [form] = useForm<FormDataType>()
const getInfoData = async () => {
try {
const res: any = await getInvoiceInfo(props.invoiceId)
// console.log(res);
form.setFieldsValue(res)
} catch (error: any) {
if (error.response) {
const data = error.response.data;
messageApi.open({
type: 'error',
content: data.msg ? data.msg : `${data.path}(${data.status})`,
});
} else {
console.error(error)
}
}
}
const upInfoData = async () => {
try {
await updateInvoiceInfo(props.invoiceId, { ...form.getFieldsValue(), invoiceType: '企业' });
messageApi.success('保存成功');
props.handleOk();
} catch (error: any) {
if (error.response) {
const data = error.response.data;
messageApi.open({
type: 'error',
content: data.msg ? data.msg : `${data.path}(${data.status})`,
});
} else {
console.error(error)
}
}
}
useEffect(() => { useEffect(() => {
if (!props.invoiceInfoId) { if (!props.invoiceId) {
return; return;
} }
get<FormDataType>({ getInfoData();
messageApi,
url: `/api/invoice-info/get/${props.invoiceInfoId}`, // get<FormDataType>({
onSuccess({data}) { // messageApi,
form.setFieldsValue(data); // url: `/api/invoice-info/get/${props.invoiceInfoId}`,
} // onSuccess({data}) {
}) // form.setFieldsValue(data);
}, [props.invoiceInfoId]); // }
// })
}, [props.invoiceId]);
return ( return (
<> <>
@ -44,8 +87,9 @@ export default function InvoiceInfoSave(props: EditProps) {
name="basic" name="basic"
layout="vertical" layout="vertical"
form={form} form={form}
onFinish={(values) => { onFinish={() => {
modal.confirm({ modal.confirm({
centered: true,
title: '提示', title: '提示',
content: '确定保存吗', content: '确定保存吗',
okText: '确定', okText: '确定',
@ -56,65 +100,66 @@ export default function InvoiceInfoSave(props: EditProps) {
} }
}, },
onOk: () => { onOk: () => {
post<any>({ // post<any>({
messageApi, // messageApi,
url: `/api/invoice-info/update/${props.invoiceInfoId}`, // url: `/api/invoice-info/update/${props.invoiceInfoId}`,
body: values, // body: values,
onSuccess() { // onSuccess() {
messageApi.success('保存成功'); // messageApi.success('保存成功');
props.handleOk(); // props.handleOk();
} // }
}) // })
upInfoData()
} }
}) })
}} }}
> >
<Form.Item <Form.Item
label="公司名称" label="公司名称"
name="invoiceTitle" name="invoiceName"
rules={[{required: true, message: '请输入公司名称'}]} rules={[{ required: true, message: '请输入公司名称' }]}
> >
<Input placeholder="请输入公司名称"/> <Input placeholder="请输入公司名称" />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label="纳税人识别号" label="纳税人识别号"
name="invoiceNo" name="invoiceNumber"
rules={[{required: true, message: '请输入纳税人识别号'}]} rules={[{ required: true, message: '请输入纳税人识别号' }]}
> >
<Input placeholder="请输入纳税人识别号"/> <Input placeholder="请输入纳税人识别号" />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label="公司地址" label="公司地址"
name="invoiceAddress" name="invoiceOrgaddress"
rules={[{required: true, message: '请输入公司地址'}]} rules={[{ required: false, message: '请输入公司地址' }]}
> >
<Input placeholder="请输入公司地址"/> <Input placeholder="请输入公司地址" />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label="公司电话" label="公司电话"
name="invoicePhone" name="invoiceOrgtel"
rules={[{required: true, message: '请输入公司电话'}]} rules={[{ required: false, message: '请输入公司电话' }]}
> >
<Input placeholder="请输入公司电话"/> <Input placeholder="请输入公司电话" />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label="开户行" label="开户行"
name="invoiceBank" name="invoiceBank"
rules={[{required: true, message: '请输入开户行'}]} rules={[{ required: false, message: '请输入开户行' }]}
> >
<Input placeholder="请输入开户行"/> <Input placeholder="请输入开户行" />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label="开户行账号" label="开户行账号"
name="invoiceAccount" name="invoiceBanknumber"
rules={[{required: true, message: '请输入开户行账号'}]} rules={[{ required: false, message: '请输入开户行账号' }]}
> >
<Input placeholder="请输入开户行账号"/> <Input placeholder="请输入开户行账号" />
</Form.Item> </Form.Item>
<Flex justify="center"> <Flex justify="center">
<Space size={5}> <Space size={5}>
<Button type="primary" htmlType="submit" <Button type="primary" htmlType="submit"
style={{backgroundColor: 'var(--color-primary)'}}></Button> style={{ backgroundColor: 'var(--color-primary)' }}></Button>
<Button type="default" onClick={() => { <Button type="default" onClick={() => {
props.handleCancel(); props.handleCancel();
}}></Button> }}></Button>

View File

@ -1,22 +1,21 @@
import {Button, Flex, Modal, Popconfirm, Space, Table, TableProps} from "antd"; import { Empty,Button, Flex, Modal, Popconfirm, Space, Table, TableProps } from "antd";
import {DeleteOutlined, EditOutlined, PlusOutlined} from "@ant-design/icons"; import { DeleteOutlined, EditOutlined, PlusOutlined } from "@ant-design/icons";
import useMessage from "antd/es/message/useMessage"; import useMessage from "antd/es/message/useMessage";
import {useEffect, useRef, useState} from "react"; import { useEffect, useRef, useState, useContext } from "react";
import {del, get} from "../../../util/AjaxUtils.ts"; // import { del, get } from "../../../util/AjaxUtils.ts";
import {IListPage} from "../../../interfaces/listpage/IListPage.ts"; // import { IListPage } from "../../../interfaces/listpage/IListPage.ts";
import InvoiceInfoSave from "./InvoiceInfoSave.tsx"; import InvoiceInfoSave from "./InvoiceInfoSave.tsx";
import InvoiceInfoEdit from "./InvoiceInfoEdit.tsx"; import InvoiceInfoEdit from "./InvoiceInfoEdit.tsx";
import { getInvoiceList, deleteInvoiceInfo } from '../../../request/api.ts'
import { GlobalContext } from "../../../context/GlobalContext.ts";
type DataType = { type DataType = {
invoiceTitle: string; invoiceName: string;
invoicePhone: string; invoiceNumber: string;
invoiceNo: string; invoiceOrgaddress: string;
invoiceInfoId: string; invoiceOrgtel: string;
invoiceBank: string; invoiceBank: string;
invoiceAddress: string; invoiceBanknumber: string;
invoiceAccount: string; invoiceId: string;
gmtCreate: number;
creator: string;
} }
interface ListProps { interface ListProps {
@ -37,54 +36,54 @@ export default function InvoiceInfoList(props: ListProps) {
const columns: TableProps<DataType>['columns'] = [ const columns: TableProps<DataType>['columns'] = [
{ {
title: '公司名称', title: '公司名称',
dataIndex: 'invoiceTitle', dataIndex: 'invoiceName',
align: 'center', align: 'center',
width: 180, width: 180,
fixed: 'left' fixed: 'left'
}, },
{ {
title: '纳税人识别号', title: '纳税人识别号',
dataIndex: 'invoiceNo', dataIndex: 'invoiceNumber',
align: 'center', align: 'center',
width: 180 width: 180
}, },
{ {
title: '公司地址', title: '公司地址',
dataIndex: 'invoiceAddress', dataIndex: 'invoiceOrgaddress',
align: 'center', align: 'center',
width: 180 width: 180
}, },
{ {
title: '联系电话', title: '联系电话',
dataIndex: 'invoicePhone', dataIndex: 'invoiceOrgtel',
align: 'center',
width: 180
},
{
title: '开户行',
dataIndex: 'invoiceBank',
align: 'center',
width: 180
},
{
title: '开户行账号',
dataIndex: 'invoiceAccount',
align: 'center', align: 'center',
width: 180 width: 180
}, },
// {
// title: '开户行',
// dataIndex: 'invoiceBank',
// align: 'center',
// width: 180
// },
// {
// title: '开户行账号',
// dataIndex: 'invoiceBanknumber',
// align: 'center',
// width: 180
// },
{ {
title: '操作', title: '操作',
dataIndex: 'option', dataIndex: 'option',
align: 'center', align: 'center',
width: 100, width: 100,
fixed: 'right', // fixed: 'right',
render: (_value, record) => { render: (_value, record) => {
return ( return (
<Space size={5}> <Space size={5}>
<Button type="primary" size="small" onClick={() => { <Button type="primary" size="small" onClick={() => {
editInvoiceInfoId.current = record.invoiceInfoId; editInvoiceInfoId.current = record.invoiceId;
setIsInvoiceInfoEditOpen(true); setIsInvoiceInfoEditOpen(true);
}}><EditOutlined/></Button> }}><EditOutlined /></Button>
<Popconfirm <Popconfirm
placement="right" placement="right"
title={false} title={false}
@ -92,83 +91,157 @@ export default function InvoiceInfoList(props: ListProps) {
okText="确定" okText="确定"
cancelText="取消" cancelText="取消"
onConfirm={() => { onConfirm={() => {
del<any>({ deleteInvoice(record.invoiceId);
messageApi, // del<any>({
url: `/api/invoice-info/remove/${record.invoiceInfoId}`, // messageApi,
onSuccess() { // url: `/api/invoice-info/remove/${record.invoiceId}`,
messageApi.success('删除成功'); // onSuccess() {
getData(); // messageApi.success('删除成功');
} // getData();
}) // }
// })
}} }}
> >
<Button type="primary" size="small" danger><DeleteOutlined/></Button> <Button type="primary" size="small" danger><DeleteOutlined /></Button>
</Popconfirm> </Popconfirm>
</Space> </Space>
) )
} }
}, },
] ]
const globalContext = useContext(GlobalContext);
const getData = async () => {
const getData = () => { try {
get<IListPage<DataType>>({ const res: any = await getInvoiceList(globalContext.user.userId, { page: page, rows: 20 })
messageApi, // console.log(res);
url: '/api/invoice-info/listpage/self', setTotal(res.total)
config: { setDataArray(res.rows)
params: { } catch (error: any) {
page: page, if (error.response) {
rows: 20 const data = error.response.data;
} messageApi.open({
}, type: 'error',
onSuccess({data}) { content: data.msg ? data.msg : `${data.path}(${data.status})`,
setPage(data.page); });
setTotal(data.total); } else {
setDataArray(data.rows); console.error(error)
} }
}) }
// get<IListPage<DataType>>({
// messageApi,
// url: '/api/invoice-info/listpage/self',
// config: {
// params: {
// page: page,
// rows: 20
// }
// },
// onSuccess({data}) {
// setPage(data.page);
// setTotal(data.total);
// setDataArray(data.rows);
// }
// })
}
const deleteInvoice = async (id: string) => {
try {
await deleteInvoiceInfo(id)
// console.log(res);
messageApi.success('删除成功');
getData();
} catch (error: any) {
if (error.response) {
const data = error.response.data;
messageApi.open({
type: 'error',
content: data.msg ? data.msg : `${data.path}(${data.status})`,
});
} else {
console.error(error)
}
}
} }
useEffect(() => { useEffect(() => {
getData(); getData();
}, [page]); }, [page]);
return ( return (
<> <>
<div className="invoice-list-container"> <div className="invoice-list-container">
<div className="mod-list"> <div className="mod-list">
<div className="table-btn-group" style={{marginBottom: '15px'}}> <div className="table-btn-group" style={{ marginBottom: '15px' }}>
<Button value="small" onClick={() => { <Button value="small" onClick={() => {
setIsInvoiceInfoSaveOpen(true); setIsInvoiceInfoSaveOpen(true);
}}><PlusOutlined/> </Button> }}><PlusOutlined /> </Button>
</div> </div>
<Table rowSelection={ {dataArray.length > 0
{ ? <>
type: 'radio', <Table
onChange: (_selectedRowKeys, selectedRows) => { rowSelection={
selectedInvoice.current = selectedRows[0]; {
}, type: 'radio',
} onChange: (_selectedRowKeys, selectedRows) => {
} columns={columns} dataSource={dataArray} pagination={ selectedInvoice.current = selectedRows[0];
{ },
pageSize: 20,
total: total, }
onChange: (currentPage) => { }
setPage(currentPage);
columns={columns} dataSource={dataArray} pagination={
{
pageSize: 20,
total: total,
onChange: (currentPage) => {
setPage(currentPage);
}
}
} scroll={{ y: 500 }} bordered key="dataTable" rowKey="invoiceId"
/>
</> :
<>
<div style={{
width: '100%', height: '200px', display: 'flex', justifyContent: 'center', alignItems: 'center', fontSize: '20px'
}}>
<Empty description='暂无开票信息,请添加' />
</div>
</>
}
{/* <Table
rowSelection={
{
type: 'radio',
onChange: (_selectedRowKeys, selectedRows) => {
selectedInvoice.current = selectedRows[0];
},
} }
} }
} scroll={{y: 500}} bordered key="dataTable" rowKey="invoiceInfoId"/>
columns={columns} dataSource={dataArray} pagination={
{
pageSize: 20,
total: total,
onChange: (currentPage) => {
setPage(currentPage);
}
}
} scroll={{ y: 500 }} bordered key="dataTable" rowKey="invoiceId"
/> */}
</div> </div>
<Flex justify="center"> <Flex justify="center">
<Space size={5}> <Space size={5}>
<Button type="primary" <Button type="primary"
style={{backgroundColor: 'var(--color-primary)'}} style={{ backgroundColor: 'var(--color-primary)' }}
onClick={() => { onClick={() => {
if (!selectedInvoice.current) { if (!selectedInvoice.current) {
messageApi.error('请选择开票信息'); messageApi.error('请选择开票信息');
return; return;
} }
props.handleOk(selectedInvoice.current); props.handleOk(selectedInvoice.current);
}} }}
></Button> ></Button>
<Button type="default" onClick={() => { <Button type="default" onClick={() => {
props.handleCancel(); props.handleCancel();
@ -177,11 +250,12 @@ export default function InvoiceInfoList(props: ListProps) {
</Flex> </Flex>
</div> </div>
<Modal open={isInvoiceInfoSaveOpen} <Modal open={isInvoiceInfoSaveOpen}
title="新增" title="新增"
footer={false} footer={false}
onCancel={() => { onCancel={() => {
setIsInvoiceInfoSaveOpen(false) setIsInvoiceInfoSaveOpen(false)
}} }}
destroyOnClose
> >
<InvoiceInfoSave <InvoiceInfoSave
handleOk={() => { handleOk={() => {
@ -194,14 +268,14 @@ export default function InvoiceInfoList(props: ListProps) {
/> />
</Modal> </Modal>
<Modal open={isInvoiceInfoEditOpen} <Modal open={isInvoiceInfoEditOpen}
title="编辑" title="编辑"
footer={false} footer={false}
onCancel={() => { onCancel={() => {
setIsInvoiceInfoEditOpen(false) setIsInvoiceInfoEditOpen(false)
}} }}
> >
<InvoiceInfoEdit <InvoiceInfoEdit
invoiceInfoId={editInvoiceInfoId.current} invoiceId={editInvoiceInfoId.current}
handleOk={() => { handleOk={() => {
getData(); getData();
setIsInvoiceInfoEditOpen(false); setIsInvoiceInfoEditOpen(false);

View File

@ -1,8 +1,11 @@
import {Button, Flex, Form, Input, Space} from "antd"; import { Button, Flex, Form, Input, Space } from "antd";
import {useForm} from "antd/es/form/Form"; import { useForm } from "antd/es/form/Form";
import useModal from "antd/es/modal/useModal"; import useModal from "antd/es/modal/useModal";
import {post} from "../../../util/AjaxUtils.ts"; // import { post } from "../../../util/AjaxUtils.ts";
import useMessage from "antd/es/message/useMessage"; import useMessage from "antd/es/message/useMessage";
import { addInvoiceInfo } from '../../../request/api.ts'
import { GlobalContext } from "../../../context/GlobalContext.ts";
import { useContext } from "react";
type FormDataType = { type FormDataType = {
invoiceTitle: string; invoiceTitle: string;
@ -22,7 +25,7 @@ export default function InvoiceInfoSave(props: SaveProps) {
const [messageApi, messageContext] = useMessage(); const [messageApi, messageContext] = useMessage();
const [modal, modalContext] = useModal(); const [modal, modalContext] = useModal();
const [form] = useForm<FormDataType>() const [form] = useForm<FormDataType>()
const globalContext = useContext(GlobalContext);
return ( return (
<> <>
<Form <Form
@ -31,6 +34,7 @@ export default function InvoiceInfoSave(props: SaveProps) {
form={form} form={form}
onFinish={(values) => { onFinish={(values) => {
modal.confirm({ modal.confirm({
centered: true,
title: '提示', title: '提示',
content: '确定保存吗', content: '确定保存吗',
okText: '确定', okText: '确定',
@ -40,66 +44,85 @@ export default function InvoiceInfoSave(props: SaveProps) {
backgroundColor: 'var(--color-primary)' backgroundColor: 'var(--color-primary)'
} }
}, },
onOk: () => { onOk: async () => {
post<any>({ // console.log(values);
messageApi, try {
url: '/api/invoice-info/save', await addInvoiceInfo(globalContext.user.userId, {
body: values, ...values,
onSuccess() { invoiceType: '企业'
messageApi.success('保存成功'); })
props.handleOk(); props.handleOk();
} catch (error: any) {
if (error.response) {
const data = error.response.data;
messageApi.open({
type: 'error',
content: data.msg ? data.msg : `${data.path}(${data.status})`,
});
} else {
console.error(error)
} }
}) }
// post<any>({
// messageApi,
// url: '/api/invoice-info/save',
// body: values,
// onSuccess() {
// messageApi.success('保存成功');
// props.handleOk();
// }
// })
} }
}) })
}} }}
> >
<Form.Item <Form.Item
label="公司名称" label="公司名称"
name="invoiceTitle" name="invoiceName"
rules={[{required: true, message: '请输入公司名称'}]} rules={[{ required: true, message: '请输入公司名称' }]}
> >
<Input placeholder="请输入公司名称"/> <Input placeholder="请输入公司名称" />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label="纳税人识别号" label="纳税人识别号"
name="invoiceNo" name="invoiceNumber"
rules={[{required: true, message: '请输入纳税人识别号'}]} rules={[{ required: true, message: '请输入纳税人识别号' }]}
> >
<Input placeholder="请输入纳税人识别号"/> <Input placeholder="请输入纳税人识别号" />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label="公司地址" label="公司地址"
name="invoiceAddress" name="invoiceOrgaddress"
rules={[{required: true, message: '请输入公司地址'}]} rules={[{ required: false, message: '请输入公司地址' }]}
> >
<Input placeholder="请输入公司地址"/> <Input placeholder="请输入公司地址" />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label="公司电话" label="公司电话"
name="invoicePhone" name="invoiceOrgtel"
rules={[{required: true, message: '请输入公司电话'}]} rules={[{ required: false, message: '请输入公司电话' }]}
> >
<Input placeholder="请输入公司电话"/> <Input placeholder="请输入公司电话" />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label="开户行" label="开户行"
name="invoiceBank" name="invoiceBank"
rules={[{required: true, message: '请输入开户行'}]} rules={[{ required: false, message: '请输入开户行' }]}
> >
<Input placeholder="请输入开户行"/> <Input placeholder="请输入开户行" />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label="开户行账号" label="开户行账号"
name="invoiceAccount" name="invoiceBanknumber"
rules={[{required: true, message: '请输入开户行账号'}]} rules={[{ required: false, message: '请输入开户行账号' }]}
> >
<Input placeholder="请输入开户行账号"/> <Input placeholder="请输入开户行账号" />
</Form.Item> </Form.Item>
<Flex justify="center"> <Flex justify="center">
<Space size={5}> <Space size={5}>
<Button type="primary" htmlType="submit" <Button type="primary" htmlType="submit"
style={{backgroundColor: 'var(--color-primary)'}}></Button> style={{ backgroundColor: 'var(--color-primary)' }}></Button>
<Button type="default" onClick={() => { <Button type="default" onClick={() => {
props.handleCancel(); props.handleCancel();
}}></Button> }}></Button>

View File

@ -1,172 +1,184 @@
import {Button, Flex, Space, Table, TableProps, Tooltip} from "antd"; import {
Button, Flex, Space, Table, TableProps,Empty
} from "antd";
import useMessage from "antd/es/message/useMessage"; import useMessage from "antd/es/message/useMessage";
import {useEffect, useRef, useState} from "react"; import { useEffect, useState, useContext } from "react";
import {get} from "../../../util/AjaxUtils.ts";
import {IListPage} from "../../../interfaces/listpage/IListPage.ts"; import { getRechargeRecordList } from '../../../request/api.ts'
import { GlobalContext } from "../../../context/GlobalContext.ts";
type DetailDataType = [{
productType: string;
quantity: number;
unitPrice: number;
notes: string;
productDescription: string;
}]
type DataType = { type DataType = {
orderId: string; rechargeMoney: number;
orderNo: string; thirdParty: string;
totalAmount: number; reconciliationTime: string;
orderDetails: DetailDataType; rechargeFinalTime: string;
orderStatus: string; accountRechargeId: string;
gmtCreate: string;
} }
interface ListProps { interface ListProps {
selectedOrderIds?: string[]; selectedOrderIds?: string[];
handleOk: (selectedOrders: DataType[]) => void; handleOk: (selectedOrders: DataType[]) => void;
handleCancel: () => void; handleCancel: () => void;
selectedOrders?: any;
setSelectedOrders?: React.Dispatch<React.SetStateAction<any[]>>;
// isInvoiceInfoListOpen?: any;
} }
export default function InvoiceInfoList(props: ListProps) { export default function InvoiceInfoList(props: ListProps) {
const {
selectedOrders,
setSelectedOrders,
} = props;
const [messageApi, messageContext] = useMessage(); const [messageApi, messageContext] = useMessage();
const [page, setPage] = useState(1); const [page, setPage] = useState(1);
const [total, setTotal] = useState(0); const [total, setTotal] = useState(0);
const [dataArray, setDataArray] = useState<DataType[]>([]); const [dataArray, setDataArray] = useState<DataType[]>([]);
const selectedOrders = useRef<DataType[] | null>(null);
const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]); const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);
const [applyOrders, setApplyOrders] = useState<DataType[]>(selectedOrders);
const columns: TableProps<DataType>['columns'] = [ const columns: TableProps<DataType>['columns'] = [
{
title: '订单号',
dataIndex: 'orderNo',
align: 'center',
width: 250,
fixed: 'left'
},
{
title: '总金额',
dataIndex: 'totalAmount',
align: 'center',
width: 100,
fixed: 'left',
render: (value) => {
return (value / 100).toFixed(2)
}
},
{
title: '订单状态',
dataIndex: 'orderStatus',
align: 'center',
width: 100,
render: (value) => {
if(value === 'COMPLETE') {
return '完成';
}
if(value === 'CHARGEBACK') {
return '已退款';
}
}
},
{
title: '创建时间',
dataIndex: 'gmtCreate',
align: 'center',
width: 180
},
{
title: '产品类型',
dataIndex: 'orderDetails.productType',
align: 'center',
width: 100,
render: (_value, record) => {
if(record.orderDetails[0].productType === 'PROJ') {
return '项目创建'
}
if(record.orderDetails[0].productType === 'AGENT') {
return '项目代理'
}
return record.orderDetails[0].productType
}
},
{
title: '数量',
dataIndex: 'detail.quantity',
align: 'center',
width: 100,
render: (_value, record) => {
return record.orderDetails[0].quantity
}
},
{
title: '单价',
dataIndex: 'detail.unitPrice',
align: 'center',
width: 100,
render: (_value, record) => {
return (record.orderDetails[0].unitPrice / 100).toFixed(2)
}
},
{
title: '订单备注',
dataIndex: 'detail.notes',
align: 'center',
width: 300,
render: (_value, record) => {
return record.orderDetails[0].notes
}
},
{
title: '描述',
dataIndex: 'detail.productDescription',
align: 'center',
width: 300,
ellipsis: {
showTitle: false,
},
render: (_value, record) => {
return <Tooltip placement="top" title={record.orderDetails[0].productDescription}>{record.orderDetails[0].productDescription}</Tooltip>
}
},
]
const getData = () => { {
get<IListPage<DataType>>({ title: '充值金额',
messageApi, dataIndex: 'rechargeMoney',
url: '/api/order/listpage/complete/no-invoiced/self', align: 'center',
config: { width: 80,
params: {
page: page, },
rows: 20 {
} title: '充值方式',
}, dataIndex: 'thirdParty',
onSuccess({data}) { align: 'center',
console.log('数据',data.rows); width: 80,
setPage(data.page); },
setTotal(data.total); {
setDataArray(data.rows); title: '充值时间',
dataIndex: 'reconciliationTime',
align: 'center',
width: 100,
},
{
title: '充值到账时间',
dataIndex: 'rechargeFinalTime',
align: 'center',
width: 100,
},
]
const globalContext = useContext(GlobalContext);
const getData = async () => {
try {
const res: any = await getRechargeRecordList(globalContext.user.userId, { page: page, rows: 20 })
// console.log('数据', res);
setPage(res.page);
setTotal(res.total);
setDataArray(res.rows);
} catch (error: any) {
if (error.response) {
const data = error.response.data;
messageApi.open({
type: 'error',
content: data.msg ? data.msg : `${data.path}(${data.status})`,
});
} else {
console.error(error)
} }
}) }
} }
useEffect(() => { useEffect(() => {
getData(); getData();
if(props.selectedOrderIds && props.selectedOrderIds.length > 0) {
setSelectedRowKeys(props.selectedOrderIds)
}
}, [page]); }, [page]);
useEffect(() => {
// console.log('11', applyOrders);
if (applyOrders) {
const selectedIds = applyOrders.map((order: DataType) => order.accountRechargeId);
setSelectedRowKeys(selectedIds);
}
}, [applyOrders])
return ( return (
<> <>
<div className="invoice-list-container"> <div className="invoice-list-container">
<div className="mod-list"> <div className="mod-list">
<Table rowSelection={ {dataArray.length > 0 ?
<>
<Table rowSelection={
{
selectedRowKeys,
onSelect: (data) => {
const isSelect = applyOrders?.some((item: DataType) => item.accountRechargeId === data.accountRechargeId)
// console.log('onSelect', data, isSelect);
if (!isSelect) {
setApplyOrders?.([...applyOrders, data])
} else {
setApplyOrders?.(applyOrders?.filter((item: DataType) => item.accountRechargeId !== data.accountRechargeId))
}
},
onSelectAll: (isAll) => {
if (isAll) {
const newSelectedOrders = dataArray.filter((item: DataType) => !applyOrders?.some((order: DataType) => order.accountRechargeId === item.accountRechargeId));
// const setectSelectedOrders = applyOrders?.filter((item: DataType) => !dataArray?.some((order: DataType) => order.accountRechargeId === item.accountRechargeId));
// console.log('newSelectedOrders', newSelectedOrders, setectSelectedOrders);
setApplyOrders?.([...applyOrders, ...newSelectedOrders])
} else {
const setectSelectedOrders = applyOrders?.filter((item: DataType) => !dataArray?.some((order: DataType) => order.accountRechargeId === item.accountRechargeId));
// console.log('setectSelectedOrders', setectSelectedOrders);
setApplyOrders?.([...setectSelectedOrders])
}
},
}
} columns={columns} dataSource={dataArray} pagination={
{
pageSize: 20,
total: total,
showSizeChanger: false,
onChange: (currentPage) => {
setPage(currentPage);
}
}
} scroll={{ y: 500 }} bordered key="dataTable" rowKey="accountRechargeId" />
</> :
<>
<div style={{
width: '100%', height: '200px', display: 'flex', justifyContent: 'center', alignItems: 'center', fontSize: '20px'
}}>
<Empty description='暂无信息' />
</div>
</>
}
{/* <Table rowSelection={
{ {
selectedRowKeys, selectedRowKeys,
onChange: (selectedRowKeys, selectedRows) => { onSelect: (data) => {
setSelectedRowKeys(selectedRowKeys); const isSelect = applyOrders?.some((item: DataType) => item.accountRechargeId === data.accountRechargeId)
selectedOrders.current = selectedRows; // console.log('onSelect', data, isSelect);
if (!isSelect) {
setApplyOrders?.([...applyOrders, data])
} else {
setApplyOrders?.(applyOrders?.filter((item: DataType) => item.accountRechargeId !== data.accountRechargeId))
}
}, },
onSelectAll: (isAll) => {
if (isAll) {
const newSelectedOrders = dataArray.filter((item: DataType) => !applyOrders?.some((order: DataType) => order.accountRechargeId === item.accountRechargeId));
// const setectSelectedOrders = applyOrders?.filter((item: DataType) => !dataArray?.some((order: DataType) => order.accountRechargeId === item.accountRechargeId));
// console.log('newSelectedOrders', newSelectedOrders, setectSelectedOrders);
setApplyOrders?.([...applyOrders, ...newSelectedOrders])
} else {
const setectSelectedOrders = applyOrders?.filter((item: DataType) => !dataArray?.some((order: DataType) => order.accountRechargeId === item.accountRechargeId));
// console.log('setectSelectedOrders', setectSelectedOrders);
setApplyOrders?.([...setectSelectedOrders])
}
},
} }
} columns={columns} dataSource={dataArray} pagination={ } columns={columns} dataSource={dataArray} pagination={
{ {
@ -177,21 +189,25 @@ export default function InvoiceInfoList(props: ListProps) {
setPage(currentPage); setPage(currentPage);
} }
} }
} scroll={{y: 500}} bordered key="dataTable" rowKey="orderId"/> } scroll={{ y: 500 }} bordered key="dataTable" rowKey="accountRechargeId" /> */}
</div> </div>
<Flex justify="center"> <Flex justify="center">
<Space size={5}> <Space size={5}>
<Button type="primary" <Button type="primary"
style={{backgroundColor: 'var(--color-primary)'}} style={{ backgroundColor: 'var(--color-primary)' }}
onClick={() => { onClick={() => {
if (!selectedOrders.current) { // console.log('onok', applyOrders);
messageApi.error('请选择开票订单'); if (!applyOrders || applyOrders?.length === 0) {
return; messageApi.error('请选择开票订单');
} return;
props.handleOk(selectedOrders.current); }
}} // setSelectedOrders?.(applyOrders);
setSelectedOrders?.(applyOrders);
props.handleOk(applyOrders);
}}
></Button> ></Button>
<Button type="default" onClick={() => { <Button type="default" onClick={() => {
setSelectedOrders?.(selectedOrders);
props.handleCancel(); props.handleCancel();
}}></Button> }}></Button>
</Space> </Space>

View File

@ -1,9 +1,13 @@
import {Table, TableProps, import {
Tooltip} from "antd"; Table, TableProps,
// Tooltip
} from "antd";
import useMessage from "antd/es/message/useMessage"; import useMessage from "antd/es/message/useMessage";
import {useEffect, useState} from "react"; import { useEffect, useState } from "react";
import {get} from "../../../util/AjaxUtils.ts"; import { get } from "../../../util/AjaxUtils.ts";
import {IListPage} from "../../../interfaces/listpage/IListPage.ts"; import { IListPage } from "../../../interfaces/listpage/IListPage.ts";
import { getInvoiceRechargeList } from "../../../request/api.ts"
// type DetailDataType = { // type DetailDataType = {
// productType: string; // productType: string;
@ -14,16 +18,15 @@ import {IListPage} from "../../../interfaces/listpage/IListPage.ts";
// } // }
type DataType = { type DataType = {
orderId: string; rechargeMoney: number;
orderNo: string; thirdParty: string;
totalAmount: number; reconciliationTime: string;
orderDetails: any; rechargeFinalTime: string;
orderStatus: string; accountRechargeId: string;
gmtCreate: string;
} }
interface ListProps { interface ListProps {
invoiceId: string; invoiceRechargeId: string;
} }
export default function InvoiceInfoSelectedList(props: ListProps) { export default function InvoiceInfoSelectedList(props: ListProps) {
@ -32,124 +35,181 @@ export default function InvoiceInfoSelectedList(props: ListProps) {
const [total, setTotal] = useState(0); const [total, setTotal] = useState(0);
const [dataArray, setDataArray] = useState<DataType[]>([]); const [dataArray, setDataArray] = useState<DataType[]>([]);
const columns: TableProps<DataType>['columns'] = [ // const columns: TableProps<DataType>['columns'] = [
{ // {
title: '订单号', // title: '订单号',
dataIndex: 'orderNo', // dataIndex: 'orderNo',
align: 'center', // align: 'center',
width: 250, // width: 250,
fixed: 'left' // fixed: 'left'
}, // },
{ // {
title: '总金额', // title: '总金额',
dataIndex: 'totalAmount', // dataIndex: 'totalAmount',
align: 'center', // align: 'center',
width: 100, // width: 100,
fixed: 'left', // fixed: 'left',
render: (value) => { // render: (value) => {
return (value / 100).toFixed(2) // return (value / 100).toFixed(2)
} // }
}, // },
{ // {
title: '订单状态', // title: '订单状态',
dataIndex: 'orderStatus', // dataIndex: 'orderStatus',
align: 'center', // align: 'center',
width: 100, // width: 100,
render: (value) => { // render: (value) => {
if(value === 'COMPLETE') { // if(value === 'COMPLETE') {
return '完成'; // return '完成';
} // }
if(value === 'CHARGEBACK') { // if(value === 'CHARGEBACK') {
return '已退款'; // return '已退款';
} // }
} // }
}, // },
{ // {
title: '创建时间', // title: '创建时间',
dataIndex: 'gmtCreate', // dataIndex: 'gmtCreate',
align: 'center', // align: 'center',
width: 180 // width: 180
}, // },
{ // {
title: '产品类型', // title: '产品类型',
dataIndex: 'orderDetails.0.productType', // dataIndex: 'orderDetails.0.productType',
align: 'center', // align: 'center',
width: 100, // width: 100,
render: (_value, record) => { // render: (_value, record) => {
if(record.orderDetails[0].productType === 'PROJ') { // if(record.orderDetails[0].productType === 'PROJ') {
return '项目创建' // return '项目创建'
} // }
if(record.orderDetails[0].productType === 'AGENT') { // if(record.orderDetails[0].productType === 'AGENT') {
return '项目代理' // return '项目代理'
} // }
return record.orderDetails[0].productType // return record.orderDetails[0].productType
} // }
}, // },
{ // {
title: '数量', // title: '数量',
dataIndex: 'orderDetails.0.quantity', // dataIndex: 'orderDetails.0.quantity',
align: 'center', // align: 'center',
width: 100, // width: 100,
render: (_value, record) => { // render: (_value, record) => {
return record.orderDetails[0].quantity // return record.orderDetails[0].quantity
} // }
}, // },
{ // {
title: '单价', // title: '单价',
dataIndex: 'orderDetails.0.unitPrice', // dataIndex: 'orderDetails.0.unitPrice',
align: 'center', // align: 'center',
width: 100, // width: 100,
render: (_value, record) => { // render: (_value, record) => {
return (record.orderDetails[0].unitPrice / 100).toFixed(2) // return (record.orderDetails[0].unitPrice / 100).toFixed(2)
} // }
}, // },
{ // {
title: '订单备注', // title: '订单备注',
dataIndex: 'orderDetails.0.notes', // dataIndex: 'orderDetails.0.notes',
align: 'center', // align: 'center',
width: 120, // width: 120,
render: (_value, record) => { // render: (_value, record) => {
return record.orderDetails[0].notes // return record.orderDetails[0].notes
} // }
}, // },
{ // {
title: '描述', // title: '描述',
dataIndex: 'orderDetails.0.productDescription', // dataIndex: 'orderDetails.0.productDescription',
align: 'center', // align: 'center',
width: 200, // width: 200,
ellipsis: { // ellipsis: {
showTitle: false, // showTitle: false,
}, // },
render: (_value, record) => { // render: (_value, record) => {
return <Tooltip placement="top" title={record.orderDetails[0].productDescription}>{record.orderDetails[0].productDescription}</Tooltip> // return <Tooltip placement="top" title={record.orderDetails[0].productDescription}>{record.orderDetails[0].productDescription}</Tooltip>
} // }
}, // },
] // ]
// const columns = [] // const columns = []
useEffect(() => { const columns: TableProps<DataType>['columns'] = [
get<IListPage<DataType>>({
messageApi, {
url: `/api/order/listpage/complete/self?invoiceId=${props.invoiceId}`, title: '充值金额',
config: { dataIndex: 'rechargeMoney',
params: { align: 'center',
page: page, width: 150,
rows: 20 key: 'accountRechargeId',
}
}, },
onSuccess({data}) { {
setPage(data.page); title: '充值方式',
setTotal(data.total); dataIndex: 'thirdParty',
setDataArray(data.rows); align: 'center',
width: 150,
key: 'thirdParty',
},
{
title: '充值时间',
dataIndex: 'reconciliationTime',
align: 'center',
// width: 150,
key: 'reconciliationTime',
},
{
title: '充值到账时间',
dataIndex: 'rechargeFinalTime',
align: 'center',
// width: 150,
key:'rechargeFinalTime',
},
]
const getData = async () => {
try {
const res: any = await getInvoiceRechargeList(props.invoiceRechargeId, { page: page, rows: 20 })
console.log('数据', res);
setPage(res.page);
setTotal(res.total);
setDataArray(res.rows);
} catch (error: any) {
if (error.response) {
const data = error.response.data;
messageApi.open({
type: 'error',
content: data.msg ? data.msg : `${data.path}(${data.status})`,
});
} else {
console.error(error)
} }
}) }
}
useEffect(() => {
getData()
// get<IListPage<DataType>>({
// messageApi,
// url: `/api/order/listpage/complete/self?invoiceId=${props.invoiceId}`,
// config: {
// params: {
// page: page,
// rows: 20
// }
// },
// onSuccess({data}) {
// setPage(data.page);
// setTotal(data.total);
// setDataArray(data.rows);
// }
// })
}, [page]); }, [page]);
return ( return (
<> <>
{messageContext} {messageContext}
<div className="invoice-list-container"> <div className="invoice-list-container">
<div className="mod-list"> <div className="mod-list">
<Table columns={columns} dataSource={dataArray} pagination={ <Table columns={columns} dataSource={dataArray}
pagination={
{ {
pageSize: 20, pageSize: 20,
total: total, total: total,
@ -157,9 +217,10 @@ export default function InvoiceInfoSelectedList(props: ListProps) {
onChange: (currentPage) => { onChange: (currentPage) => {
setPage(currentPage); setPage(currentPage);
} }
} }
} scroll={{y: 500}} bordered key="dataTable" rowKey="orderId"/> } scroll={{ y: 500 }} bordered key="accountRechargeId" rowKey="accountRechargeId"
/>
</div> </div>
</div> </div>
</> </>

View File

@ -80,9 +80,9 @@ export default function ListProj() {
rows: 10, rows: 10,
keywords: keywords, keywords: keywords,
// charge: type, // charge: type,
chargeType: type, chargeType: type, //类型
chargeAdditionals: chargeAdditionals, chargeAdditionals: chargeAdditionals, //拓展收费
tagDataId: part1, tagDataId: part1, //标签
projRemindId: projRemindId, projRemindId: projRemindId,
authorId: authorId, authorId: authorId,
payStatus: payStatus, payStatus: payStatus,

View File

@ -845,7 +845,7 @@ export default function Head() {
} }
}) })
} }
useEffect(() => { useEffect(() => {
getUnRead() getUnRead()
// 五分钟刷新一次用户信息 // 五分钟刷新一次用户信息
@ -853,24 +853,36 @@ export default function Head() {
getMyPackNum() getMyPackNum()
}, []) }, [])
const loginFlag = async() => { const loginFlag = async () => {
// await getLoginflag(globalContext.user.userId) try {
await getLoginflag(globalContext.user.userId)
await getLoginflag(globalContext.user.userId);
sessionStorage.setItem('isLoggedIn', 'true'); sessionStorage.setItem('isLoggedIn', 'true');
}
catch (error: any) {
if (error.response) {
const data = error.response.data;
messageApi.open({
type: 'error',
content: data.msg ? data.msg : `${data.path}(${data.status})`,
});
} else {
console.error(error)
}
}
} }
useEffect(() => { useEffect(() => {
if (globalContext.user.userId) { if (globalContext.user.userId) {
const islogin = sessionStorage.getItem('isLoggedIn'); const islogin = sessionStorage.getItem('isLoggedIn');
if (!islogin ) { if (!islogin) {
loginFlag() loginFlag()
} }
// loginFlag() // loginFlag()
} }
// loginFlag() // loginFlag()
}, [globalContext.user.userId]) }, [globalContext.user.userId])
const items: MenuProps['items'] = [ const items: MenuProps['items'] = [
@ -1319,9 +1331,10 @@ export default function Head() {
<Modal open={isInvoiceModalOpen} <Modal open={isInvoiceModalOpen}
centered centered
title="发票管理" title="发票管理"
width={1100} width={1300}
footer={false} footer={false}
onCancel={() => setIsInvoiceModalOpen(false)} onCancel={() => setIsInvoiceModalOpen(false)}
destroyOnClose
> >
<InvoiceList /> <InvoiceList />
</Modal> </Modal>

View File

@ -1,4 +1,30 @@
import request from './request' import request from './request'
// 获取登录标志 // 获取登录标志
export const getLoginflag = (userId:string) => request.get(`/operator-plugin/app/contentcensusrelease/log?requestUrl=网页USER${userId}`) export const getLoginflag = (userId:string) => request.get(`/operator-plugin/app/contentcensusrelease/log?requestUrl=网页USER${userId}`)
// 获取开票记录列表
export const getInvoiceRecordList = (userId:string,params: any) => request.get(`/operator-plugin/api/invoicerecharge/listpage/${userId}`,{params})
// 获取开票信息数组
export const getInvoiceList = (userId:string,params: any) => request.get(`/operator-plugin/api/invoice-config/listpage/${userId}`,{params})
// 新增开票信息
export const addInvoiceInfo = (userId:string,params:any) => request.post(`/operator-plugin/api/invoice-config/save/${userId}`,params)
// 获取开票信息
export const getInvoiceInfo = (invoiceId: string) => request.get(`/operator-plugin/api/invoice-config/get/${invoiceId}`)
//更新开票信息
export const updateInvoiceInfo = (invoiceId: string,params:any) => request.put(`/operator-plugin/api/invoice-config/update/${invoiceId}`,params)
// 删除开票信息
export const deleteInvoiceInfo = (invoiceId: string) => request.delete(`/operator-plugin/api/invoice-config/remove/${invoiceId}`)
// 获取可申请开票的充值记录列表
export const getRechargeRecordList = (userId:string,params: any) => request.get(`/operator-plugin/api/invoicerecharge/recharge-listpage/${userId}/not`,{params})
//获取开票的充值记录(点击查看开票的充值记录)
export const getInvoiceRechargeList = (invoiceRechargeId:string,params:any) => request.get(`/operator-plugin/api/invoicerecharge/listpage-byid/${invoiceRechargeId}`,{params})
// 提交开票申请
export const submitInvoiceApply = (userId:string,params:any) => request.post(`/operator-plugin/api/invoicerecharge/save/${userId}`,params)
// 查看开票信息
export const getInvoiceInfoById = (invoiceRechargeId: string) => request.get(`/operator-plugin/api/invoicerecharge/get/${invoiceRechargeId}`)
// 取消开票
export const cancelInvoice = (invoiceRechargeId: string) => request.put(`/operator-plugin/api/invoicerecharge/cancel/${invoiceRechargeId}`)
// 获取开票信息
export const getInvoiceInfoByinvoiceRechargeId = (invoiceRechargeId: string) => request.get(`/operator-plugin/api/invoicerecharge/get/${invoiceRechargeId}`)
// 修改开票信息
export const updateInvoiceInfoByinvoiceRechargeId = (invoiceRechargeId: string,params:any) => request.put(`/operator-plugin/api/invoicerecharge/update/${invoiceRechargeId}`,params)

View File

@ -1,5 +1,6 @@
import axios from "axios"; import axios from "axios";
const baseURL = 'https://www.aimzhu.com'; const baseURL = 'http://192.168.0.115:8099';
// const baseURL = 'https://www.aimzhu.com';
const request = axios.create({ const request = axios.create({
baseURL: baseURL, baseURL: baseURL,
timeout: 5000, timeout: 5000,
@ -23,5 +24,9 @@ request.interceptors.response.use(
(err) => Promise.reject(err) (err) => Promise.reject(err)
); );
// 下载发票
export const downloadInvoice = (id: string) => {
return `${baseURL}/operator-plugin/route/file/download/false/${id}`
};
export default request export default request