Commit 58911a19 authored by 张子雨's avatar 张子雨

feat: 合并master

parents d6679a1c a27fa28a
...@@ -164,6 +164,24 @@ export default { ...@@ -164,6 +164,24 @@ export default {
icon: 'smile', icon: 'smile',
component: './distributionArea', component: './distributionArea',
}, },
{
path: '/reconciliationQuery',
name: 'reconciliationQuery',
icon: 'smile',
component: './ReconciliationQuery',
},
{
path: '/settlementSheet',
name: 'settlementSheet',
icon: 'smile',
component: './SettlementSheet',
},
{
path: '/paymentMange',
name: 'paymentMange',
icon: 'smile',
component: './PaymentMange',
},
// { // {
// path: '/GoodsManage-new', // path: '/GoodsManage-new',
// name: 'GoodsManageNew', // name: 'GoodsManageNew',
......
...@@ -2,14 +2,15 @@ const isProduction = process.env.NODE_ENV === 'production'; ...@@ -2,14 +2,15 @@ const isProduction = process.env.NODE_ENV === 'production';
const isPre = process.env.PRE_ENV === 'pre'; const isPre = process.env.PRE_ENV === 'pre';
const envAPi = { const envAPi = {
api: '//backstms-test4.liangkebang.net', api: '//backstms-test9.liangkebang.net',
kdspOpApi: 'https://kdsp-operation-test4.liangkebang.net', kdspOpApi: 'https://kdsp-operation-test9.liangkebang.net',
kdspApi: 'https://sc-op-api-test4.liangkebang.net', kdspApi: 'https://sc-op-api-test9.liangkebang.net',
goodsApi: 'https://sc-op-api-test4.liangkebang.net', goodsApi: 'https://sc-op-api-test9.liangkebang.net',
// goodsApi: '//192.168.28.107:7000', querysApi: 'https://sc-settlement-api-test9.liangkebang.net',
prologueDomain: 'https://mall-test4.liangkebang.net', // goodsApi: '//192.168.188.111:7000',
prologueDomain: 'https://mall-test9.liangkebang.net',
qiniuHost: 'https://appsync.lkbang.net', qiniuHost: 'https://appsync.lkbang.net',
opapiHost: 'https://opapi-test4.liangkebang.net', opapiHost: 'https://opapi-test9.liangkebang.net',
}; };
const prodApi = { const prodApi = {
...@@ -21,6 +22,7 @@ const prodApi = { ...@@ -21,6 +22,7 @@ const prodApi = {
// goodsApi: 'https://sc-merchant-api.q-gp.com', // 线上环境打包域名 // goodsApi: 'https://sc-merchant-api.q-gp.com', // 线上环境打包域名
qiniuHost: 'https://appsync.lkbang.net', qiniuHost: 'https://appsync.lkbang.net',
opapiHost: 'https://opapi.xyqb.com', opapiHost: 'https://opapi.xyqb.com',
querysApi: 'https://sc-settlement-api.q-gp.com',
}; };
const preProdApi = { const preProdApi = {
...@@ -31,6 +33,7 @@ const preProdApi = { ...@@ -31,6 +33,7 @@ const preProdApi = {
goodsApi: 'https://sc-merchant-api-pre.q-gp.com', goodsApi: 'https://sc-merchant-api-pre.q-gp.com',
qiniuHost: 'https://appsync.lkbang.net', qiniuHost: 'https://appsync.lkbang.net',
opapiHost: 'https://opapi-pre.q-gp.com', opapiHost: 'https://opapi-pre.q-gp.com',
querysApi: 'https://sc-settlement-api.q-gp.com',
}; };
let exportApi = envAPi; let exportApi = envAPi;
......
...@@ -114,9 +114,7 @@ const BasicLayout = props => { ...@@ -114,9 +114,7 @@ const BasicLayout = props => {
</Menu> </Menu>
</Sider> </Sider>
<Layout style={{ zIndex: 1 }}> <Layout style={{ zIndex: 1 }}>
<Authorized authority={authorized.authority} noMatch={noMatch}> <Authorized noMatch={noMatch}>{children}</Authorized>
{children}
</Authorized>
</Layout> </Layout>
</Layout> </Layout>
</div> </div>
......
import React from 'react';
import { Button } from 'antd';
export function renderModal() {
return [
<Button type="primary" key="cancel" onClick={() => this.handleCancel()}>
取消
</Button>,
<Button type="primary" onClick={() => this.handleSubmit()} key="save">
提交
</Button>,
];
}
export function detailsModal(filePath) {
return [
<Button type="primary" key="cancel" onClick={() => this.handleCancel()}>
取消
</Button>,
<Button type="primary" href={filePath} target="_blank" key="down">
下载
</Button>,
];
}
export const formItemLayout = {
labelCol: { span: 6 },
wrapperCol: { span: 18 },
};
import React, { Component } from 'react';
import { Modal, Input, Button, Icon, notification, Form } from 'antd';
import styles from '../style.less';
import { renderModal, detailsModal, formItemLayout } from './data';
import Upload from './upload';
import { uploadBill } from '../service';
const { Item: FormItem } = Form;
class toExamine extends Component {
uploadRef = React.createRef();
handleCancel = () => {
const { resetFields, getFieldValue } = this.props.form;
const { clearFileList } = this.uploadRef.current;
clearFileList();
resetFields();
this.props.close();
};
normFile = fileList => fileList;
handleSubmit = async () => {
const {
form: { validateFields },
toExamineData: { id },
} = this.props;
validateFields(async (err, values) => {
if (err) {
return;
}
const params = {
filePath: values?.fileList[0].url,
fileName: values?.fileList[0].name,
id,
};
const data = await uploadBill(params);
if (data.businessCode === '0000') {
this.handleCancel();
notification.success({ message: '上传成功' });
}
});
};
render() {
const {
form: { getFieldDecorator },
visible,
status,
toExamineData: { filePath, fileName, refuseReason },
} = this.props;
const listFile = [{ url: filePath, name: fileName }];
return (
<Modal
width={400}
title={status === 1 ? '上传发票' : '查看发票'}
visible={visible}
onCancel={() => this.handleCancel()}
footer={status === 1 ? renderModal.call(this) : detailsModal.call(this, filePath)}
className={styles.textArea}
>
<Form className="login-form" {...formItemLayout}>
<FormItem label="上传发票">
{getFieldDecorator('fileList', {
rules: [{ required: true, message: '请上传发票' }],
valuePropName: 'fileList',
getValueFromEvent: this.normFile,
initialValue: status === 1 ? [] : listFile,
})(<Upload max={1} ref={this.uploadRef} status={status} />)}
</FormItem>
{status === 2 ? (
<FormItem label="备注">
{getFieldDecorator('remark', {
initialValue: refuseReason,
})(<Input.TextArea rows={5} disabled />)}
</FormItem>
) : (
<div className="tipMessage">支持格式:pdf/doc/docx/png/jpeg/.zip/.rar</div>
)}
</Form>
</Modal>
);
}
}
export default Form.create()(toExamine);
import { Upload, Icon, Modal, message, Button } from 'antd';
import React, { useState, useEffect } from 'react';
import config from '../../../../config/env.config';
import styles from '../style.less';
import { qiniuToken } from '@/services/qiniu';
const qiniu = require('@/utils/qiniu.min.js');
const { qiniuHost } = config;
let token = null;
class PicturesWall extends React.Component {
state = {
fileList: [],
};
async componentDidMount() {
this.initFileList(this.props.fileList || []);
if (this.props.status === 1) {
token = await qiniuToken();
}
}
componentWillReceiveProps(nextProps) {
if (!nextProps?.fileList?.fileList) {
this.initFileList(nextProps.fileList || []);
}
}
initFileList = fileList => {
const fileLists =
fileList.map((item, index) => ({
url: item.url,
name: item.name ? item.name : '发票',
uid: index,
status: 'done',
})) || [];
this.setState({ fileList: fileLists });
};
clearFileList = () => {
this.setState({
fileList: [],
});
};
customRequest = ({ file, onError, onSuccess }) => {
const lastFile = file.name.split('.');
const index = lastFile.length - 1;
const types = ['pdf', 'doc', 'docx', 'zip', 'rar', 'png', 'jpeg'];
if (!types.includes(lastFile[index])) {
message.error('文件格式错误!');
return;
}
const vm = this;
const name = file.name + file.uid;
const observable = qiniu.upload(file, file.name, token);
const observer = {
next() {
// ...
},
error() {
onError(file);
// ...
},
complete(res) {
const comFile = file;
const url = `${qiniuHost}/${res.key}`;
comFile.url = url;
const list = vm.state.fileList;
list.push({
url: file.url,
name: file.name,
uid: list.length,
status: 'done',
});
vm.setState({ fileList: [...list] });
vm.props.onChange(list);
onSuccess(comFile);
// ...
},
};
observable.subscribe(observer); // 上传开始
};
clearFileList = () => {
this.setState({
fileList: [],
});
};
render() {
const { fileList } = this.state;
const { status } = this.props;
const uploadButton = (
<div className={styles.uploadButton}>
<Icon type="upload" />
<span style={{ paddingLeft: '10px' }}>点击上传发票</span>
</div>
);
const { max } = this.props;
return (
<div className="clearfix">
<Upload
{...this.props}
customRequest={this.customRequest}
listType="text"
fileList={fileList}
onRemove={status === 1 ? this.clearFileList : ''}
>
{max && fileList.length >= max ? null : uploadButton}
</Upload>
</div>
);
}
}
export default PicturesWall;
import React from 'react';
import { Button } from 'antd';
import styles from './style.less';
export const payStateEnum = {
1: { text: '待申请' },
2: { text: '待审批' },
3: { text: '已通过' },
4: { text: '待打款' },
5: { text: '已打款' },
};
export const orderStateNum = {
1: { text: '待上传' },
2: { text: '待审核' },
3: { text: '未通过' },
4: { text: '已通过' },
};
export const redInvoiceState = {
1: { text: '', actionValue: 2 },
2: { text: '', actionValue: 1 },
};
export function columns(res, pages) {
const { current, pageSize } = pages;
return [
{
title: '序号',
dataIndex: 'index',
hideInSearch: true,
width: '50px',
align: 'center',
render: (text, record, index) => (current - 1) * pageSize + index + 1,
},
{
title: '供应商名称',
dataIndex: 'supplierName',
width: '150px',
hideInSearch: true,
},
{
title: '付款单批次号',
dataIndex: 'payBatchNo',
width: '160px',
align: 'center',
},
{
title: '付款单生成日期',
key: 'dateTimeRange',
dataIndex: 'createdAtRange',
valueType: 'dateRange',
width: '120px',
hideInTable: true,
initialValue: [],
align: 'center',
},
{
title: '打款日期',
key: 'payTimeRange',
dataIndex: 'payAtRange',
valueType: 'dateRange',
width: '120px',
hideInTable: true,
initialValue: [],
align: 'center',
},
{
title: '帐单确认周期',
dataIndex: 'createdAtRange',
key: 'created',
hideInSearch: true,
align: 'center',
width: '160px',
render: (text, record) => `${record.billPeriodStart}-${record.billPeriodEnd}`,
},
{
title: '付款单生成日期',
dataIndex: 'createdAt',
key: 'createdAt',
hideInSearch: true,
align: 'center',
width: '160px',
},
{
title: '销售总额',
dataIndex: 'saleAmount',
width: '100px',
hideInSearch: true,
align: 'center',
},
{
title: '退款总额',
dataIndex: 'refundAmount',
width: '100px',
hideInSearch: true,
align: 'center',
},
{
title: '红字金额',
dataIndex: 'pastRefundAmount',
width: '100px',
hideInSearch: true,
align: 'center',
},
{
title: '蓝字金额',
dataIndex: 'currentRefundAmount',
width: '100px',
hideInSearch: true,
align: 'center',
},
{
title: '应付金额',
dataIndex: 'payableAmount',
width: '100px',
hideInSearch: true,
align: 'center',
},
{
title: '是否缺少红字发票',
dataIndex: 'redInvoiceState',
valueEnum: redInvoiceState,
align: 'center',
width: 100,
},
{
title: '付款状态',
dataIndex: 'payState',
valueEnum: payStateEnum,
width: '110px',
align: 'center',
},
{
title: '发票状态',
dataIndex: 'blueInvoiceState',
valueEnum: orderStateNum,
width: '110px',
align: 'center',
},
{
title: '操作',
dataIndex: 'option',
valueType: 'option',
key: 'option',
align: 'center',
fixed: 'right',
width: 80,
render: (_, row) => (
<div>
<Button
type="primary"
disabled={row.payState !== 1}
className={styles.button}
onClick={() => res.edit(0, row)}
>
申请结算
</Button>
<Button
type="primary"
disabled={
!((row.blueInvoiceState === 1 || row.blueInvoiceState === 3) && row.payState === 3)
}
className={styles.button}
onClick={() => res.edit(1, row)}
>
上传发票
</Button>
<Button
type="primary"
disabled={row.blueInvoiceState === 1}
className={styles.button}
onClick={() => res.edit(2, row)}
>
查看发票
</Button>
<Button type="primary" className={styles.button} onClick={() => res.edit(3, row)}>
下载账单
</Button>
</div>
),
},
];
}
export const toolBarRender = onExport => () => [];
/* eslint-disable no-shadow */
import { Button, notification, Modal, Spin } from 'antd';
import React, { useRef, useState } from 'react';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import ProTable from '@ant-design/pro-table';
import { saveAs } from 'file-saver';
import { format } from 'date-fns';
import moment from 'moment';
import ToExamineModal from './ToExamine';
import { columns, toolBarRender } from './data';
import {
query,
selfPaymentExport,
selfPaymentexportDetail,
settlement,
merchantView,
} from './service';
const { confirm } = Modal;
const PaymentMange = () => {
const actionRef = useRef();
const formRef = useRef();
const [toExamineData, settoExamineData] = useState({});
const [loading, setloading] = useState(false);
const [status, setstatus] = useState(1);
const [pages, setpages] = useState({});
const [toExamineModalVisibel, setToExamineModalVisibel] = useState(false);
const reload = () => {
if (actionRef.current) {
actionRef.current.reload();
}
};
// 下载账单付款单明细
const exportDetail = async params => {
setloading(true);
const data = await selfPaymentexportDetail(params);
if (data) {
const blob = new Blob([data]);
saveAs(blob, `账单付款单明细-${format(new Date(), 'yyyyMMddHHmmss')}.xlsx`);
} else {
notification.error({ message: '下载失败' });
}
setloading(false);
};
// 申请结算
const applySettlement = async params => {
setloading(true);
const data = await settlement(params);
if (data.businessCode === '0000') {
reload();
notification.success({ message: '申请成功' });
}
setloading(false);
};
const showConfirm = params => {
confirm({
title: '申请结算',
content: '现在结算?',
onOk() {
applySettlement(params);
},
});
};
// 查看发票
const invoiceDetail = async params => {
const data = await merchantView(params);
if (data.businessCode === '0000') {
settoExamineData({ ...data.data });
setToExamineModalVisibel(true);
}
};
// 0申请结算 1上传发票 2查看发票 3下载账单付款单明细
const edit = async (status, { id }) => {
if (status === 0) {
showConfirm(id);
} else if (status === 1) {
setstatus(status);
settoExamineData({ id });
setToExamineModalVisibel(true);
} else if (status === 2) {
setstatus(status);
invoiceDetail(id);
} else if (status === 3) {
exportDetail(id);
}
};
const onColse = () => {
if (status === 1) {
reload();
}
setToExamineModalVisibel(false);
};
const checkedTime = ({ dateTimeRange }) => {
const startTimeStr = moment(dateTimeRange?.[0]).format('YYYY-MM-DD');
const endTimeStr = moment(dateTimeRange?.[1]).format('YYYY-MM-DD');
const diffTime = moment(endTimeStr).valueOf() - moment(startTimeStr).valueOf();
const maxTime = 62 * 3600 * 24 * 1000;
if (!dateTimeRange?.[0]) {
notification.error({ message: '付款单开始时间不能为空' });
return false;
}
if (diffTime > maxTime) {
notification.error({ message: '只允许下载2个月的数据' });
return false;
}
return true;
};
const onExport = async () => {
const params = formRef.current.getFieldsValue();
setloading(true);
if (checkedTime(params)) {
const data = await selfPaymentExport(params);
const blob = new Blob([data]);
saveAs(blob, `付款单导出数据-${format(new Date(), 'yyyyMMddHHmmss')}.xlsx`);
}
setloading(false);
};
const onToolBarRender = toolBarRender();
const res = {
edit,
};
const searchRender = ({ searchText, resetText }, { form }) => [
<Button
key="search"
type="primary"
style={{ marginRight: '10px' }}
onClick={() => {
// eslint-disable-next-line no-unused-expressions
form?.submit();
}}
>
{searchText}
</Button>,
<Button
key="rest"
style={{ marginRight: '10px' }}
onClick={() => {
// eslint-disable-next-line no-unused-expressions
form?.resetFields();
// eslint-disable-next-line no-unused-expressions
form?.submit();
}}
>
{resetText}
</Button>,
<Button
key="export"
type="primary"
style={{ marginRight: '10px' }}
onClick={() => {
// eslint-disable-next-line no-unused-expressions
onExport();
}}
>
导出
</Button>,
];
return (
<Spin tip="处理中..." spinning={loading} delay={100}>
<PageHeaderWrapper>
<ProTable
actionRef={actionRef}
formRef={formRef}
request={params => {
const { current, pageSize } = params;
setpages({ current, pageSize });
return query({ ...params });
}}
columns={columns(res, pages)}
rowKey={r => r.id}
search={{
collapsed: false,
optionRender: searchRender,
}}
bordered
toolBarRender={onToolBarRender}
scroll={{ x: '1700px' }}
/>
<ToExamineModal
visible={toExamineModalVisibel}
toExamineData={toExamineData}
status={status}
close={() => {
onColse();
}}
/>
</PageHeaderWrapper>
</Spin>
);
};
export default PaymentMange;
import request from '@/utils/request';
import config from '../../../config/env.config';
import moment from 'moment';
import _ from 'lodash';
// 分页查询所有数据
const { querysApi } = config;
export async function query(params) {
const queryParams = {
pageSize: params.pageSize || 10,
pageNo: params.current || 1,
payBatchNo: params?.payBatchNo,
payBeginDate: params?.dateTimeRange?.[0],
payEndDate: params?.dateTimeRange?.[1],
paidBeginDate: params?.payTimeRange?.[0],
paidEndDate: params?.payTimeRange?.[1],
redInvoiceState: params?.redInvoiceState,
blueInvoiceState: params?.blueInvoiceState,
payState: params?.payState,
};
const { data } = await request.post('/selfPaymentBill/merchant/page', {
prefix: querysApi,
data: _.omitBy(queryParams, v => !v),
});
return {
data: data?.records || [],
total: data.total || 1,
};
}
export async function qiniuToken() {
const data = await request.get('/upload/getToken', {
prefix: config.opapiHost,
});
return data?.uptoken;
}
// 付款单导出
export async function selfPaymentExport(params) {
console.log(params?.dateTimeRange?.[0]);
const queryParams = {
payBatchNo: params?.payBatchNo,
payBeginDate: params?.dateTimeRange?.[0]
? moment(params?.dateTimeRange?.[0]).format('yyyy-MM-DD')
: '',
payEndDate: params?.dateTimeRange?.[1]
? moment(params?.dateTimeRange?.[1]).format('yyyy-MM-DD')
: '',
paidBeginDate: params?.payTimeRange?.[0]
? moment(params?.payTimeRange?.[1]).format('yyyy-MM-DD')
: '',
paidEndDate: params?.payTimeRange?.[1]
? moment(params?.payTimeRange?.[1]).format('yyyy-MM-DD')
: '',
redInvoiceState: params?.redInvoiceState,
blueInvoiceState: params?.blueInvoiceState,
payState: params?.payState,
};
return request.post('/selfPaymentBill/merchant/export', {
prefix: querysApi,
data: _.omitBy(queryParams, v => !v),
responseType: 'arrayBuffer',
});
}
// 付款单导出
export async function selfPaymentexportDetail(params) {
return request.post('/selfPaymentBill/merchant/exportDetail', {
prefix: querysApi,
data: params,
responseType: 'arrayBuffer',
headers: {
'Content-Type': 'application/json;charset=UTF-8',
},
});
}
// 申请结算单
export async function settlement(params) {
return request.get(`/selfPaymentBill/merchant/apply/settlement/${params}`, {
prefix: querysApi,
});
}
// 上传发票
export async function uploadBill(params) {
return request.post('/selfPaymentBill/merchant/upload/bill', {
prefix: querysApi,
data: params,
});
}
// 查看发票
export async function merchantView(params) {
return request.get(`/selfPaymentBill/merchant/view/${params}`, {
prefix: querysApi,
});
}
.button {
display: block;
margin-bottom: 10px;
}
.uploadButton {
padding: 5px 10px;
border: 1px solid #cecece;
cursor: pointer;
}
.textArea {
:global {
.ant-modal-footer {
text-align: center;
}
.ant-btn-primary {
margin-left: 20px;
}
.tipMessage {
margin-top: -20px;
padding-left: 5px;
color: red;
}
}
}
import { Button } from 'antd';
import React from 'react';
export const activeStateEnum = {
10: { text: '销售' },
20: { text: '售后' },
};
export const orderStateNum = {
1: { text: '待确认' },
2: { text: '已确认' },
3: { text: '已生成结算单' },
};
export function columns(pages) {
const { current, pageSize } = pages;
return [
{
title: '序号',
dataIndex: 'index',
hideInSearch: true,
width: '50px',
align: 'center',
render: (text, record, index) => (current - 1) * pageSize + index + 1,
},
{
title: '供应商名称',
dataIndex: 'supplierName',
width: '150px',
align: 'center',
hideInSearch: true,
},
{
title: '结算单批次号',
dataIndex: 'settleBatchNo',
width: '160px',
align: 'center',
},
{
title: '账单日期',
key: 'dateTimeRange',
dataIndex: 'createdAtRange',
valueType: 'dateRange',
width: '120px',
hideInTable: true,
initialValue: [],
align: 'center',
},
{
title: '账单日期',
dataIndex: 'billDateStr',
key: 'billDateStr',
hideInSearch: true,
align: 'center',
width: '160px',
},
{
title: '账单类型',
dataIndex: 'billType',
valueEnum: activeStateEnum,
width: '120px',
filters: false,
align: 'center',
},
{
title: '金额',
dataIndex: 'amount',
width: '100px',
hideInSearch: true,
align: 'center',
},
{
title: '笔数',
dataIndex: 'quantity',
width: '100px',
hideInSearch: true,
align: 'center',
},
{
title: '状态',
dataIndex: 'status',
valueEnum: orderStateNum,
width: '100px',
filters: false,
align: 'center',
},
];
}
export const toolBarRender = gather => {
const { onDownload, confirmAction } = gather;
return () => [
<Button type="primary" style={{ marginRight: '20px' }} onClick={onDownload}>
下载
</Button>,
<Button type="primary" onClick={confirmAction}>
确认
</Button>,
];
};
/* eslint-disable no-shadow */
import { Button, Upload, notification, Spin } from 'antd';
import React, { useRef, useEffect, useState } from 'react';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import ProTable from '@ant-design/pro-table';
import { saveAs } from 'file-saver';
import { format } from 'date-fns';
import { columns, toolBarRender } from './data';
import { query, confirmSelfBill, downloadSelfBillDetail } from './service';
const ReconciliationQuery = () => {
const actionRef = useRef();
const [selectedRowKeys, setselectedRowKeys] = useState([]);
const [selectedRows, setselectedRows] = useState([]);
const [loading, setloading] = useState(false);
const [pages, setpages] = useState({});
const [billName, setbillName] = useState('');
const reload = () => {
if (actionRef.current) {
actionRef.current.reload();
}
};
// 检查是否是同类型的
const checkedBillType = data => {
const billType = data[0]?.billType;
const sameData = data.filter(item => item.billType === billType);
if (data.length === sameData.length && sameData.length < 32) {
const billName = billType === 10 ? '销售' : '售后';
setbillName(billName);
return true;
}
if (sameData.length > 31) {
notification.error({ message: '一次最多选择31个账单批次' });
return false;
}
notification.error({ message: '不同账单类型不可批量操作' });
return false;
};
// 检查是否是确认账单
const checkedStatus = data => {
const sameData = data.filter(item => item.status === 1);
if (sameData.length > 0 && data.length === sameData.length) {
return true;
}
if (!sameData.length && !data.length) {
notification.error({ message: '请选择1~31条账单批次' });
return false;
}
notification.error({ message: '只有待确认账单可以确认' });
return false;
};
const onSelectChange = (selectedRowKeys, selectedRows) => {
if (checkedBillType(selectedRows)) {
setselectedRowKeys(selectedRowKeys);
setselectedRows(selectedRows);
}
};
const queryData = async params => {
const { current, pageSize } = params;
setpages({ current, pageSize });
setselectedRowKeys([]);
setselectedRows([]);
const data = await query({ ...params });
return data;
};
const confirmAction = async () => {
setloading(true);
if (checkedStatus(selectedRows)) {
const data = await confirmSelfBill(selectedRowKeys);
if (data.businessCode === '0000') {
setselectedRowKeys([]);
setselectedRows([]);
actionRef.current.reloadAndRest();
// reload();
// queryData({ current: 1, pageSize: 20 })
notification.success({ message: '确认成功' });
}
setloading(false);
} else {
setloading(false);
}
};
const onDownload = async () => {
if (selectedRowKeys.length && selectedRowKeys.length < 32) {
setloading(true);
const data = await downloadSelfBillDetail(selectedRowKeys);
const blob = new Blob([data]);
saveAs(blob, `${billName}-${format(new Date(), 'yyyyMMddHHmmss')}.xlsx`);
setloading(false);
setselectedRowKeys([]);
setselectedRows([]);
reload();
} else {
notification.error({ message: '请选择1~31条账单批次' });
setloading(false);
}
};
const gather = {
onDownload,
confirmAction,
};
const onToolBarRender = toolBarRender(gather);
const rowSelection = {
selectedRowKeys,
onChange: onSelectChange,
};
const searchRender = ({ searchText, resetText }, { form }) => [
<Button
key="search"
type="primary"
style={{ marginRight: '10px' }}
onClick={() => {
// eslint-disable-next-line no-unused-expressions
form?.submit();
}}
>
{searchText}
</Button>,
<Button
key="rest"
style={{ marginRight: '10px' }}
onClick={() => {
// eslint-disable-next-line no-unused-expressions
form?.resetFields();
// eslint-disable-next-line no-unused-expressions
form?.submit();
}}
>
{resetText}
</Button>,
];
return (
<Spin tip="处理中..." spinning={loading} delay={100}>
<PageHeaderWrapper>
<ProTable
actionRef={actionRef}
request={params => queryData(params)}
columns={columns(pages)}
rowKey={r => r.id}
search={{
collapsed: false,
optionRender: searchRender,
}}
rowSelection={rowSelection}
bordered
toolBarRender={onToolBarRender}
scroll={{ x: '100%' }}
/>
</PageHeaderWrapper>
</Spin>
);
};
export default ReconciliationQuery;
import request from '@/utils/request';
import config from '../../../config/env.config';
import _ from 'lodash';
// 分页查询所有数据
const { querysApi } = config;
export async function query(params) {
const queryParams = {
pageSize: params.pageSize || 10,
pageNo: params.current || 1,
beginBillDate: params?.dateTimeRange?.[0],
endBillDate: params?.dateTimeRange?.[1],
settleBatchNo: params?.settleBatchNo,
billType: params?.billType,
status: params?.status,
};
const { data } = await request.post('/selfBill/merchant/querySelfBill', {
prefix: querysApi,
data: _.omitBy(queryParams, v => !v),
});
return {
data: data?.records || [],
total: data?.total || 1,
};
}
// 对账单确认
export async function confirmSelfBill(params) {
return request.post('/selfBill/merchant/confirmSelfBill', {
prefix: querysApi,
data: params,
});
}
// 对账下载
export async function downloadSelfBillDetail(params) {
return request.post('/selfBill/merchant/downloadSelfBillDetail', {
prefix: querysApi,
data: params,
responseType: 'arrayBuffer',
});
}
import React from 'react';
import { Button } from 'antd';
export const dateStateEnum = {
1: { text: '一周', maxlength: 8 },
2: { text: '半个月', maxlength: 4 },
3: { text: ' 一个月', maxlength: 2 },
};
export const orderStateNum = {
1: { text: '待结算' },
2: { text: '已结算' },
3: { text: '无需结算' },
};
export const paymentStateEnum = {
true: { text: '' },
false: { text: '' },
};
export function columns(pages) {
const { current, pageSize } = pages;
return [
{
title: '序号',
dataIndex: 'index',
hideInSearch: true,
width: '50px',
align: 'center',
render: (text, record, index) => (current - 1) * pageSize + index + 1,
},
{
title: '供应商名称',
dataIndex: 'supplierName',
width: '150px',
hideInSearch: true,
align: 'center',
},
{
title: '付款单批次号',
dataIndex: 'payBatchNo',
width: '160px',
align: 'center',
},
{
title: '结算单批次号',
dataIndex: 'settleBatchNo',
width: '150px',
align: 'center',
},
{
title: '结算单生成日期',
key: 'dateTimeRange',
dataIndex: 'createdAtRange',
valueType: 'dateRange',
width: '120px',
hideInTable: true,
initialValue: [],
align: 'center',
},
{
title: '帐单确认周期',
dataIndex: 'createdAtRange',
key: 'createdAtRange',
hideInSearch: true,
align: 'center',
width: '160px',
render: (text, record) => `${record.billPeriodStart}-${record.billPeriodEnd}`,
},
{
title: '账期',
dataIndex: 'billPeriodType',
valueEnum: dateStateEnum,
width: '120px',
hideInSearch: true,
filters: false,
align: 'center',
},
{
title: '结算单生成日期',
dataIndex: 'createdAt',
key: 'createdAt',
hideInSearch: true,
align: 'center',
width: '160px',
},
{
title: '销售金额',
dataIndex: 'saleAmount',
width: '100px',
hideInSearch: true,
align: 'center',
},
{
title: '退款金额',
dataIndex: 'refundAmount',
width: '100px',
hideInSearch: true,
align: 'center',
},
{
title: '结算金额',
dataIndex: 'payableAmount',
width: '130px',
hideInSearch: true,
align: 'center',
},
{
title: '结算状态',
dataIndex: 'settleState',
valueEnum: orderStateNum,
width: '100px',
initialValue: 0,
filters: false,
align: 'center',
},
{
title: '是否生成付款单',
dataIndex: 'isCreatePaymentBill',
valueEnum: paymentStateEnum,
hideInTable: true,
align: 'center',
},
];
}
export const toolBarRender = paymentOrder => () => [
<Button type="primary" onClick={paymentOrder}>
生成付款单
</Button>,
];
/* eslint-disable no-undef */
/* eslint-disable no-shadow */
/* eslint-disable no-return-assign */
import { Button, Upload, notification, Spin } from 'antd';
import React, { useRef, useEffect, useState } from 'react';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import ProTable from '@ant-design/pro-table';
import { columns, toolBarRender, dateStateEnum } from './data';
import { query, selfPaymentBill } from './service';
const SettlementSheet = () => {
const actionRef = useRef();
const [selectedRowKeys, setselectedRowKeys] = useState([]);
const [selectedRowsList, setselectedRowsList] = useState([]);
const [loading, setloading] = useState(false);
const [pages, setpages] = useState({});
const reload = () => {
if (actionRef.current) {
actionRef.current.reload();
}
};
// 计算当前结算金额为0或负
const checkedAmount = data => {
const totalPrice = data.reduce(
(totalPrice, item) => (totalPrice += Number(item.payableAmount)),
0,
);
if (totalPrice <= 0) {
notification.warning({ message: '当前结算金额为0或负' });
}
};
// 检查帐期类型的最多下载条数
const checkedBillType = data => {
if (!data.length) {
notification.error({ message: '请选择数据' });
return false;
}
const billPeriodType = data[0]?.billPeriodType;
const billPeriodData = dateStateEnum[billPeriodType];
if (data.length <= billPeriodData.maxlength) {
return true;
}
notification.error({
message: `${billPeriodData.text}帐期最多可选${billPeriodData.maxlength}条`,
});
return false;
};
// 检查帐期周期是否连续
const checkedTime = data => {
const minTime = data[0]?.billPeriodStart;
const maxTime = data[0]?.billPeriodEnd;
let minTimeNum = new Date(minTime).getTime();
let maxTimeNum = new Date(maxTime).getTime();
if (data.length < 2) {
return true;
}
for (let i = 1; i < data.length; i += 1) {
const startTime = data[i]?.billPeriodStart;
const endTime = data[i]?.billPeriodEnd;
const startTimeNum = new Date(startTime).getTime();
const endTimeNum = new Date(endTime).getTime();
if (startTimeNum > maxTimeNum && maxTimeNum + 24 * 3600 * 1000 === startTimeNum) {
maxTimeNum = endTimeNum;
} else if (minTimeNum > endTimeNum && endTimeNum + 24 * 3600 * 1000 === minTimeNum) {
minTimeNum = startTimeNum;
}
}
const endRulstTime = data[data.length - 1]?.billPeriodEnd;
const endRulstTimeNum = new Date(endRulstTime).getTime();
if (endRulstTimeNum <= maxTimeNum && minTimeNum <= endRulstTimeNum) {
return true;
}
notification.error({ message: '账单周期不连续' });
return false;
};
const onSelectChange = (selectedRowKeys, selectedRows) => {
if (selectedRowsList.length > selectedRows.length) {
setselectedRowKeys(selectedRowKeys);
setselectedRowsList(selectedRows);
} else if (checkedTime(selectedRows)) {
setselectedRowKeys(selectedRowKeys);
setselectedRowsList(selectedRows);
}
};
const paymentOrder = async () => {
if (checkedBillType(selectedRowsList)) {
setloading(true);
checkedAmount(selectedRowsList);
const data = await selfPaymentBill(selectedRowKeys);
if (data.businessCode === '0000') {
setselectedRowKeys([]);
setselectedRowsList([]);
reload();
notification.success({ message: '生成付款单成功' });
}
setloading(false);
}
};
const queryData = async params => {
const { current, pageSize } = params;
setpages({ current, pageSize });
setselectedRowKeys([]);
setselectedRowsList([]);
const data = await query({ ...params });
return data;
};
const onToolBarRender = toolBarRender(paymentOrder);
const rowSelection = {
selectedRowKeys,
onChange: onSelectChange,
getCheckboxProps: record => ({
disabled: !(record.settleState === 1 && !record.payBatchNo), // Column configuration not to be checked
}),
};
const searchRender = ({ searchText, resetText }, { form }) => [
<Button
key="search"
type="primary"
style={{ marginRight: '10px' }}
onClick={() => {
// eslint-disable-next-line no-unused-expressions
form?.submit();
}}
>
{searchText}
</Button>,
<Button
key="rest"
style={{ marginRight: '10px' }}
onClick={() => {
// eslint-disable-next-line no-unused-expressions
form?.resetFields();
// eslint-disable-next-line no-unused-expressions
form?.submit();
}}
>
{resetText}
</Button>,
];
return (
<Spin tip="处理中..." spinning={loading} delay={100}>
<PageHeaderWrapper>
<ProTable
actionRef={actionRef}
request={params => queryData(params)}
columns={columns(pages)}
rowKey={r => r.settleBatchNo}
search={{
collapsed: false,
optionRender: searchRender,
}}
rowSelection={rowSelection}
bordered
toolBarRender={onToolBarRender}
scroll={{ x: '100%' }}
/>
</PageHeaderWrapper>
</Spin>
);
};
export default SettlementSheet;
import request from '@/utils/request';
import config from '../../../config/env.config';
import _ from 'lodash';
// 分页查询所有数据
const { querysApi } = config;
export async function query(params) {
const queryParams = {
pageSize: params.pageSize || 10,
pageNo: params.current || 1,
createStart: params?.dateTimeRange?.[0],
createEnd: params?.dateTimeRange?.[1],
settleState: params?.settleState,
settleBatchNo: params?.settleBatchNo,
isCreatePaymentBill: params?.isCreatePaymentBill,
payBatchNo: params?.payBatchNo,
};
const { data } = await request.post('/selfSettleBill/merchant/pageQuery', {
prefix: querysApi,
data: _.omitBy(queryParams, v => !v),
});
return {
data: data?.records || [],
total: data.total || 1,
};
}
// 生成付款单
export async function selfPaymentBill(params) {
return request.post('/selfPaymentBill/merchant/generate/paymentBill', {
prefix: querysApi,
data: params,
});
}
...@@ -167,7 +167,6 @@ class PicturesWall extends React.Component { ...@@ -167,7 +167,6 @@ class PicturesWall extends React.Component {
if (!onRightImgList.length) { if (!onRightImgList.length) {
return; return;
} }
console.log('校验通过的队列=======>', onRightImgList);
this.setState( this.setState(
state => ({ state => ({
newFile: [...state.newFile, ...onRightImgList], newFile: [...state.newFile, ...onRightImgList],
......
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