Commit 6efca93d authored by GuanHua's avatar GuanHua

feat: 添加发票管理页面

parent 73730410
.itemTitle {
font-size: 12px;
color: #303133;
margin-bottom: 16px;
display: flex;
align-items: center;
&::before {
content: ' ';
width: 2px;
height: 12px;
background-color: #00A98F;
border-radius: 1px;
margin-right: 6px;
}
}
.baseItem {
display: flex;
font-size: 12px;
margin-bottom: 16px;
.label {
width: 104px;
color: #909399;
margin: 0;
p {
margin: 0;
}
}
.content {
flex: 1;
margin: 0;
word-break: break-all;
}
}
.invoiceList {
padding: 14px 32px;
background-color: #FAFBFC;
border-radius: 4px;
font-size: 12px;
margin-bottom: 16px;
.title {
color: #91959B;
height: 16px;
}
.content {
color: #303133;
}
}
.addInvoice {
color: #91959B;
margin-bottom: 8px;
.required {
color: #F25767;
}
}
.addInvoiceTable {
:global {
.ant-form-item {
margin-bottom: 12px;
}
.ant-input,
.ant-picker {
background-color: #F5F6F7;
border-color: #F5F6F7;
&:focus {
border-color: #F5F6F7;
box-shadow: none;
}
}
.ant-input-focused,
.ant-picker-focused {
border-color: #F5F6F7;
box-shadow: none;
}
}
}
.customerButton {
background-color: #F5F6F7;
border: 0;
&:hover{
background-color: #F5F6F7;
}
}
import React, { Fragment, useEffect, useState, useMemo, useRef } from 'react';
import { Row, Col, Button, Form, Input, DatePicker } from 'antd';
import { MinusOutlined, PlusOutlined } from '@ant-design/icons'
import { priceFormat } from '@/utils/numberFomat';
import Card from '@/pages/transaction/purchaseAbility/components/card';
import styles from './index.less';
interface InvoiceCardProps {
id: string,
title: string,
editAble: boolean,
data?: any,
formRef?: any
}
interface InvoiceListItem {
number: number,
invoiceDate: string | number,
invoiceAmount: number,
remark: string
}
interface InvoiceListProps {
data: InvoiceListItem
}
const Col_1 = [
{ label: '开具类型', key: 'typeName' },
{ label: '发票种类', key: 'kindName' },
{ label: '发票抬头', key: 'invoiceTitle' },
{ label: '纳税号', key: 'taxNo' },
]
const Col_2 = [
{ label: '开户行', key: 'bankOfDeposit' },
{ label: '账号', key: 'account' },
{ label: '地址', key: 'address' },
{ label: '电话号码', key: 'tel' },
]
const InvoiceList: React.FC<InvoiceListProps> = (props: InvoiceListProps) => {
const { data } = props;
return (
<Row gutter={[8, 8]} className={styles.invoiceList}>
<Col span={6}>
<div className={styles.title}>发票号码</div>
<div className={styles.content}>{data.number}</div>
</Col>
<Col span={6}>
<div className={styles.title}>开票日期</div>
<div className={styles.content}>{data.invoiceDate}</div>
</Col>
<Col span={6}>
<div className={styles.title}>开票金额(元)</div>
<div className={styles.content}>¥ {priceFormat(data.invoiceAmount)}</div>
</Col>
<Col span={6}>
<div className={styles.title}>备注</div>
<div className={styles.content}>{data.remark}</div>
</Col>
</Row>
)
}
const InvoiceCard: React.FC<InvoiceCardProps> = (props: InvoiceCardProps) => {
const { id, title, data } = props;
const [dataSource, setDataSource] = useState<any>([])
const _handleAdd = () => {
setDataSource([...dataSource, {}])
}
const _handleRemove = (index: number) => {
const arr = [...dataSource];
arr.splice(index, 1);
setDataSource(arr)
}
return (
<Card id={id} title={title}>
<div className={styles.itemTitle}>原订单开票信息 (DPTY12)</div>
<Row gutter={[8, 8]}>
<Col span={12}>
{Col_1.map((item) => (
<div className={styles.baseItem}>
<h5 className={styles.label}>{item.label}</h5>
<h5 className={styles.content}>{data[item.key]}</h5>
</div>
))}
</Col>
<Col span={12}>
{Col_2.map((item) => (
<div className={styles.baseItem}>
<h5 className={styles.label}>{item.label}</h5>
<h5 className={styles.content}>{data[item.key]}</h5>
</div>
))}
</Col>
</Row>
<div className={styles.itemTitle}>原订单发票信息</div>
{data?.invoiceList?.map((item, index) => (
<InvoiceList data={item} key={`invoiceList_${index}`} />
))}
<div className={styles.itemTitle}>新增发票信息</div>
<Row gutter={[8, 8]} className={styles.addInvoice}>
<Col flex='auto'>
<Row gutter={[8, 8]}>
<Col span={6}>
发票号码<span className={styles.required}>*</span>
</Col>
<Col span={6}>
开票日期<span className={styles.required}>*</span>
</Col>
<Col span={6}>
开票金额(元)<span className={styles.required}>*</span>
</Col>
<Col span={6}>
备注<span className={styles.required}>*</span>
</Col>
</Row>
</Col>
<Col flex='32px'></Col>
</Row>
{dataSource.map((item, index) => (
<Row key={`invoiceTable_${index}`} gutter={[8, 8]} className={styles.addInvoiceTable}>
<Col flex='auto'>
<Row gutter={[8, 8]}>
<Col span={6}>
<Form.Item
name={`number`}
rules={[{ required: true, message: '请输入发票号码' }]}
>
<Input />
</Form.Item>
</Col>
<Col span={6}>
<Form.Item
name={`invoiceDate`}
rules={[{ required: true, message: '请选择日期' }]}
>
<DatePicker style={{ width: '100%' }} />
</Form.Item>
</Col>
<Col span={6}>
<Form.Item
name={`invoiceAmount`}
rules={[{ required: true, message: '请输入金额' }]}
>
<Input />
</Form.Item>
</Col>
<Col span={6}>
<Form.Item
name={`remark`}
>
<Input />
</Form.Item>
</Col>
</Row>
</Col>
<Col flex='32px'>
<Button className={styles.customerButton} icon={<MinusOutlined />} onClick={() => { _handleRemove(index) }} />
</Col>
</Row>
))}
<Button block className={styles.customerButton} type='dashed' icon={<PlusOutlined />} onClick={_handleAdd}>新增发票</Button>
</Card>
);
}
export default InvoiceCard;
import React, { useState, useMemo } from 'react';
import { Form, Popconfirm, Button } from 'antd';
import { getIntl, history } from 'umi';
import { CheckCircleOutlined } from '@ant-design/icons';
import PeripheralLayout from '@/pages/transaction/purchaseAbility/components/detail';
import InvoiceCard from './components/invoiceCard';
const intl = getIntl();
const Detail = () => {
const {
query: {
id,
no
},
pathname,
} = history.location;
const [pathPci] = useState(pathname.split('/')[pathname.split('/').length - 2]);
const [path] = useState(pathname.split('/')[pathname.split('/').length - 1]);
const [dataSource, setDataSource] = useState<any>([{ invoiceList: [{}, {}] }, { invoiceList: [{}] }]);
const [form] = Form.useForm();
const _editAble = useMemo(() => {
return path !== 'preview';
}, [path])
const _tabs = useMemo(() => {
let _list = [];
dataSource.forEach((_, index) => {
_list.push({ id: `invoice_${index}`, title: `发票${index + 1}` })
})
return _list;
}, [dataSource])
const _handleSubmit = () => {
form.validateFields().then(formRes => {
console.log(formRes)
})
}
const _returnTopButton = () => {
return <Button type='primary' icon={<CheckCircleOutlined />} onClick={_handleSubmit}>保存</Button>
}
return (
<div style={{ margin: '-24px -24px 0' }}>
<PeripheralLayout
no={_editAble ? '开具发票' : '发票详情'}
// detail={dataSource?.reconciliationAbstract}
effect={_editAble && _returnTopButton()}
tabLink={_tabs}
components={
<Form form={form}>
{dataSource.map((item, index) => (
<InvoiceCard
id={`invoice_${index}`}
title={`发票${index + 1}`}
data={item}
key={`invoice_${index}`}
formRef={form}
editAble={_editAble} />
))}
</Form>
}
/>
</div>
)
}
export default Detail;
.text {
color: @main-color;
cursor: pointer;
}
\ No newline at end of file
This diff is collapsed.
import { getIntl } from 'umi'
import { FORM_FILTER_PATH } from '@/formSchema/const';
import { ISchema, createFormActions } from '@formily/antd';
const intl = getIntl()
/**
* 开票管理列表页schema
*/
export const schema: ISchema = {
type: 'object',
properties: {
megaLayout: {
type: 'object',
'x-component': 'mega-layout',
properties: {
topLayout: {
type: 'object',
'x-component': 'Mega-Layout',
'x-component-props': {
grid: true,
},
properties: {
ctl: {
type: "object",
"x-component": "exportBtn",
},
orderNo: {
type: 'string',
'x-component': 'Search',
'x-component-props': {
placeholder: intl.formatMessage({ id: 'balance.accountsReceivable.invoice.schema.orderNo' }),
},
},
},
},
[FORM_FILTER_PATH]: {
type: 'object',
'x-component': 'flex-layout',
'x-component-props': {
colStyle: {
marginLeft: 20,
},
},
properties: {
orderAbstract: {
type: 'string',
default: undefined,
'x-component-props': {
placeholder: intl.formatMessage({ id: 'balance.accountsReceivable.invoice.schema.orderAbstract' }),
allowClear: true,
},
},
"[orderStartTime, orderEndTime]": {
type: 'object',
'x-component': 'RangePicker',
'x-component-props': {
placeholder: [intl.formatMessage({ id: 'balance.accountsReceivable.invoice.schema.orderStartTime' }), intl.formatMessage({ id: 'balance.accountsReceivable.invoice.schema.orderEndTime' })],
allowClear: true,
},
},
"[payStartTime, payEndTime]": {
type: 'object',
'x-component': 'RangePicker',
'x-component-props': {
placeholder: [intl.formatMessage({ id: 'balance.accountsReceivable.invoice.schema.payStartTime' }), intl.formatMessage({ id: 'balance.accountsReceivable.invoice.schema.payEndTime' })],
allowClear: true,
},
},
invoiceStatus: {
type: 'string',
enum: [],
'x-component-props': {
placeholder: intl.formatMessage({ id: 'balance.accountsReceivable.invoice.schema.invoiceStatus' }),
allowClear: true,
},
},
payStatus: {
type: 'string',
enum: [],
'x-component-props': {
placeholder: intl.formatMessage({ id: 'balance.accountsReceivable.invoice.schema.payStatus' }),
allowClear: true,
},
},
submit: {
'x-component': 'Submit',
'x-mega-props': {
span: 1,
},
'x-component-props': {
children: intl.formatMessage({ id: 'balance.accountsReceivable.invoice.schema.submit' }),
},
},
},
},
},
},
},
};
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment