Commit 6c3c8269 authored by guang.wu's avatar guang.wu

fix: 删除供应商\连锁店\系统设置

parent 506c55d2
import slash from 'slash2'; import slash from 'slash2';
import defaultSettings from './defaultSettings'; // https://umijs.org/config/ import defaultSettings from './defaultSettings'; // https://umijs.org/config/
import webpackPlugin from './plugin.config'; import webpackPlugin from './plugin.config';
import groupMealRoute from './groupMealRoute';
const { pwa, primaryColor } = defaultSettings; // preview.pro.ant.design only do not use in your production ; const { pwa, primaryColor } = defaultSettings; // preview.pro.ant.design only do not use in your production ;
// preview.pro.ant.design 专用环境变量,请不要在你的项目中使用它。 // preview.pro.ant.design 专用环境变量,请不要在你的项目中使用它。
...@@ -124,18 +123,6 @@ export default { ...@@ -124,18 +123,6 @@ export default {
name: 'afterSaleAddress', name: 'afterSaleAddress',
component: './afterSaleAddress', component: './afterSaleAddress',
}, },
{
title: '商户管理后台',
path: '/reconciliation',
name: 'reconciliation',
component: './reconciliation',
},
{
title: '商户管理后台',
path: '/reconciliation/detail',
name: 'reconciliationDetail',
component: './reconciliation/detail/index',
},
{ {
title: '商户管理后台', title: '商户管理后台',
path: '/settleManage', path: '/settleManage',
...@@ -202,92 +189,18 @@ export default { ...@@ -202,92 +189,18 @@ export default {
icon: 'smile', icon: 'smile',
component: './distributionArea', component: './distributionArea',
}, },
{
title: '商户管理后台',
path: '/reconciliationQuery',
name: 'reconciliationQuery',
icon: 'smile',
component: './ReconciliationQuery',
},
{
title: '商户管理后台',
path: '/settlementSheet',
name: 'settlementSheet',
icon: 'smile',
component: './SettlementSheet',
},
{
title: '商户管理后台',
path: '/paymentMange',
name: 'paymentMange',
icon: 'smile',
component: './PaymentMange',
},
{ {
path: '/password', path: '/password',
name: 'password', name: 'password',
icon: 'smile', icon: 'smile',
component: './password', component: './password',
}, },
{
path: '/chainStoreManage',
name: 'chainStoreManage',
icon: 'smile',
component: './chainStoreManage',
},
// {
// path: '/GoodsManage-new',
// name: 'GoodsManageNew',
// component: './GoodsManage-new',
// },
{ {
title: '服务商品改造-商品模块', title: '服务商品改造-商品模块',
path: '/ServiceGoods/:id', path: '/ServiceGoods/:id',
name: 'ServiceGoods', name: 'ServiceGoods',
component: './ServiceGoods/index', component: './ServiceGoods/index',
}, },
{
title: '商户管理后台-账号管理',
path: '/systemManage/account',
name: 'systemManageAccount',
component: './systemManage/Account',
},
{
title: '商户管理后台-账号管理-用户信息',
path: '/systemManage/account/userInfo',
name: 'accountUserInfo',
component: './systemManage/Account/UserInfo',
},
{
title: '商户管理后台-角色管理',
path: '/systemManage/role',
name: 'systemManageRole',
component: './systemManage/Role',
},
{
title: '商户管理后台-角色管理-角色信息',
path: '/systemManage/role/roleInfo',
name: 'roleInfo',
component: './systemManage/Role/RoleInfo',
},
{
title: '商户管理后台-日志管理',
path: '/systemManage/log',
name: 'systemManageLog',
component: './systemManage/Log',
},
{
title: '商户管理后台-合同查看',
path: '/contractView',
name: 'contractView',
component: './contractView',
},
{
title: '商户管理后台-商家资料',
path: '/businessInfo',
name: 'businessInfo',
component: './businessManage/info',
},
{ {
title: '商户管理后台-品牌管理', title: '商户管理后台-品牌管理',
path: '/brandManage', path: '/brandManage',
...@@ -300,7 +213,6 @@ export default { ...@@ -300,7 +213,6 @@ export default {
name: 'supplyPriceUpdate', name: 'supplyPriceUpdate',
component: './GoodsManage/SupplyPriceUpdate', component: './GoodsManage/SupplyPriceUpdate',
}, },
...groupMealRoute,
{ {
component: './404', component: './404',
}, },
......
export default [
{
title: '商户管理后台-企业团餐-企业客户',
path: '/businessCustomer',
name: 'BusinessCustomer',
component: './businessCustomer/index',
},
{
title: '商户管理后台-企业团餐-外卖商品',
path: '/takeawayGoods',
name: 'TakeawayGoods',
component: './businessGoods/takeawayGoods',
},
{
title: '商户管理后台-企业团餐-外卖商品-添加商品',
path: '/takeawayGoodsInfo',
name: 'TakeawayGoodsInfo',
component: './businessGoods/takeawayGoodsInfo',
},
{
title: '商户管理后台-企业团餐-虚拟商品',
path: '/virtualGoods',
name: 'VirtualGoods',
component: './businessGoods/virtualGoods',
},
{
title: '商户管理后台-企业团餐-虚拟商品-添加商品',
path: '/virtualGoodsInfo',
name: 'VirtualGoodsInfo',
component: './businessGoods/virtualGoodsInfo',
},
{
title: '商户管理后台-企业团餐-企业店铺管理',
path: '/StoreManagement',
name: 'StoreManagement',
component: './StoreManagement',
},
{
title: '商户管理后台-企业团餐-企业员工管理',
path: '/EmployeeManagement',
name: 'EmployeeManagement',
component: './EmployeeManagement',
},
];
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 } from 'antd';
import { Form } from '@ant-design/compatible';
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;
}
if (!values?.fileList[0]?.url) {
notification.error({ message: '请上传发票错误,请重新上传' });
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, notification } from 'antd';
import React, { useState, useEffect } from 'react';
import config from '../../../../config/env.config';
import styles from '../style.less';
import UUID from '../../../utils/uuid';
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 }) => {
let filename = '';
let suffix = '';
if (file.name) {
const index = file.name.lastIndexOf('.');
filename = file.name.substr(0, index);
suffix = file.name.substr(index + 1, file.name.length - 1);
const types = ['pdf', 'doc', 'docx', 'zip', 'rar', 'png', 'jpeg'];
if (!types.includes(suffix)) {
message.error('文件格式错误!');
return;
}
}
const vm = this;
// eslint-disable-next-line new-cap
const data = `${UUID.createUUID()}.${suffix}`;
if (!token) {
message.error('上传失败,请刷新页面重试!');
return;
}
const observable = qiniu.upload(file, data, token);
const observer = {
next() {
// ...
},
error(t) {
if (t.code === 614) {
notification.error({
message: '文件名重复,请更换文件名。',
});
}
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}
disabled={status !== 1}
onRemove={status === 1 ? this.clearFileList : ''}
accept=".pdf,.doc,.docx,.zip,.rar,.png,.jpeg"
>
{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: () => (
<div style={{ textAlign: 'center' }}>
<div>蓝字金额</div>
<div style={{ color: '#f00' }}>(开票金额)</div>
</div>
),
dataIndex: 'currentRefundAmount',
key: 'currentRefundAmount',
width: '100px',
hideInSearch: true,
align: 'center',
},
{
title: '应付金额',
dataIndex: 'payableAmount',
width: '140px',
hideInSearch: true,
align: 'center',
render: (value, row) => (
<div>
<div>{row.payableAmount}</div>
<div style={{ color: '#f00' }}>赔付 ({row.claimAmount})</div>
<div>(实付 {row.needPayAmount})</div>
</div>
),
},
{
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',
render: (_, row) => (
<div>
{res.canEditable ? (
<>
<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 { connect } from 'dva';
import { PAYMENT_MANAGE } from '@/../config/permission.config';
import ToExamineModal from './ToExamine';
import { columns, toolBarRender } from './data';
import {
query,
selfPaymentExport,
selfPaymentexportDetail,
settlement,
merchantView,
} from './service';
const { confirm } = Modal;
const PaymentMange = props => {
const { permissions } = props;
const canEditable = permissions[PAYMENT_MANAGE.EDITABLE];
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,
canEditable,
};
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: '100%', y: 500 }}
/>
<ToExamineModal
visible={toExamineModalVisibel}
toExamineData={toExamineData}
status={status}
close={() => {
onColse();
}}
/>
</PageHeaderWrapper>
</Spin>
);
};
export default connect(({ menu }) => ({
permissions: menu.permissions,
}))(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,
// });
const data = await request.get('/api/kdsp/common/upload/token', {
prefix: config.opapiHost,
});
return data?.data?.token;
}
// 付款单导出
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: 0 auto 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',
render: (value, row) => {
const msg = row.billType === 20 ? <div>包含赔付金额</div> : null;
return (
<div>
<div>{value}</div>
{msg}
</div>
);
},
},
{
title: '笔数',
dataIndex: 'quantity',
width: '100px',
hideInSearch: true,
align: 'center',
render: (value, row) => {
const msg = row.billType === 20 ? <div>包含赔付笔数</div> : null;
return (
<div>
<div>{value}</div>
{msg}
</div>
);
},
},
{
title: '状态',
dataIndex: 'status',
valueEnum: orderStateNum,
width: '100px',
filters: false,
align: 'center',
},
];
}
export const toolBarRender = gather => {
const { onDownload, confirmAction, canEditable } = gather;
return () => [
<Button type="primary" style={{ marginRight: '20px' }} onClick={onDownload}>
下载
</Button>,
canEditable ? (
<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 { connect } from 'dva';
import { RECONCILIATION_QUERY } from '@/../config/permission.config';
import { columns, toolBarRender } from './data';
import { query, confirmSelfBill, downloadSelfBillDetail } from './service';
const ReconciliationQuery = props => {
const { permissions } = props;
const canEditable = permissions[RECONCILIATION_QUERY.EDITABLE];
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,
canEditable,
};
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%', y: 400 }}
/>
</PageHeaderWrapper>
</Spin>
);
};
export default connect(({ menu }) => ({
permissions: menu.permissions,
}))(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',
});
}
This diff is collapsed.
...@@ -33,95 +33,6 @@ export const TaskList = (canAddService, canAddNormal, canTakeawayService) => [ ...@@ -33,95 +33,6 @@ export const TaskList = (canAddService, canAddNormal, canTakeawayService) => [
}, },
}, },
}, },
// {
// name: '虚拟商品',
// type: 2,
// desc: '无需物流',
// hide: !canAddNormal,
// imgConfig: {
// commonImageList: {
// title: '公共滑动图',
// rule: false,
// limit: null,
// renderExtra: () => '(图片最大上传2M)',
// },
// imageList: {
// rule: false,
// limit: null,
// renderExtra: () => '(图片最大上传2M)',
// },
// detailImageList: {
// title: '详情图',
// rule: true,
// limit: null,
// renderExtra: () => '(图片最大上传2M)',
// },
// },
// },
{
name: '服务类商品',
type: 4,
desc: '无需物流',
hide: !canAddService,
imgConfig: {
commonImageList: {
title: '封面图片',
rule: true,
limit: 1,
renderExtra(leng) {
return `建议尺寸: ##宽##高 (${leng} / 1) 封面图第一张 `;
},
},
cardImageList: {
title: '商品图片',
rule: true,
limit: 11,
renderExtra(leng) {
return `建议尺寸: ##宽##高,sku商品轮播图(${leng} / 11)`;
},
},
detailImageList: {
title: '商品详情图',
// rule: true,
limit: 30,
renderExtra() {
return '最多上传30张';
},
},
},
},
{
name: '外卖商品',
type: 5,
desc: '无需物流',
hide: !canTakeawayService,
imgConfig: {
commonImageList: {
title: '封面图片',
rule: true,
limit: 1,
renderExtra(leng) {
return `建议尺寸: ##宽##高 (${leng} / 1) 封面图第一张 `;
},
},
cardImageList: {
title: '商品图片',
rule: true,
limit: 11,
renderExtra(leng) {
return `建议尺寸: ##宽##高,sku商品轮播图(${leng} / 11)`;
},
},
detailImageList: {
title: '商品详情图',
// rule: true,
limit: 30,
renderExtra() {
return '最多上传30张';
},
},
},
},
]; ];
export const WeeksList = [ export const WeeksList = [
......
...@@ -10,7 +10,6 @@ import FormRuleSetting from './components/FormRuleSetting'; ...@@ -10,7 +10,6 @@ import FormRuleSetting from './components/FormRuleSetting';
import FormRuleVPictures from './components/FormRuleVPictures'; import FormRuleVPictures from './components/FormRuleVPictures';
import FormSettlementOthers from './components/FormSettlementOthers'; import FormSettlementOthers from './components/FormSettlementOthers';
import FormAttr from './components/FormAttr'; import FormAttr from './components/FormAttr';
import FormTakeaway from './components/FormTakeaway';
import localStorage from '@/utils/localStorage'; import localStorage from '@/utils/localStorage';
import { import {
merchantBrandList, merchantBrandList,
...@@ -625,18 +624,6 @@ const ServiceGoods = options => { ...@@ -625,18 +624,6 @@ const ServiceGoods = options => {
onValuesChange={onValuesChange} onValuesChange={onValuesChange}
/> />
)} )}
{productType === 5 && (
<>
<FormTakeaway
ref={takeawayRef}
takeAway={takeAway}
editData={takeawayEditData}
takeawayInfoMation={takeawayInfoMation}
supplierIdList={supplierIdList}
onValuesChange={onValuesChange}
/>
</>
)}
</ServiceContext.Provider> </ServiceContext.Provider>
</WrapperContainer> </WrapperContainer>
</Spin> </Spin>
......
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',
render: (value, row) => (
<div>
<div>{value}</div>
<div style={{ color: '#f00' }}>(赔付{row.claimAmount})</div>
</div>
),
},
{
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, canEditable }) => () => [
canEditable ? (
<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 { connect } from 'dva';
import { columns, toolBarRender, dateStateEnum } from './data';
import { query, selfPaymentBill } from './service';
import { SETTLEMENT_SHEET } from '@/../config/permission.config';
const SettlementSheet = props => {
const { permissions } = props;
const canEditable = permissions[SETTLEMENT_SHEET.EDITABLE];
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, canEditable });
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%', y: 400 }}
/>
</PageHeaderWrapper>
</Spin>
);
};
export default connect(({ menu }) => ({
permissions: menu.permissions,
}))(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,
});
}
This diff is collapsed.
import React from 'react';
import { Checkbox } from 'antd';
import { mealSections } from '../staticData/index';
const MealCheckbox = props => {
const onChange = e => {
props.onChange(props.field);
props.changeType(e);
};
return (
<Checkbox
onChange={onChange}
checked={props.meals[props.field]}
id={props.field}
label={mealSections[props.field]}
>
{mealSections[props.field]}
</Checkbox>
);
};
export default MealCheckbox;
import React from 'react';
import { Form, InputNumber, Row, Col } from 'antd';
import style from '../style/info.less';
import { validateRequired, isCheckPriceTwoDecimal } from '@/utils/validator';
const MealLimit = props => (
<Form.Item
label={`${props.label}限额`}
name={props.name}
rules={[
{ validator: validateRequired, message: `请输入${props.label}限额` },
{ validator: isCheckPriceTwoDecimal, message: '请输入正确的价格' },
]}
>
<InputNumber addonAfter="元" max={999.99} />
</Form.Item>
);
export default MealLimit;
import React from 'react';
import { Form, Space, TimePicker } from 'antd';
import { mealSections } from '../staticData/index';
import MealCheckbox from './MealCheckbox';
const MealSection = props => (
<Form.List name="mealTimePeriod">
{fields => (
<>
{Object.keys(mealSections).map((field, i) => (
<Space key={field} align="baseline">
<Form.Item label="" name={[i, 'mealPeriodType']}>
<MealCheckbox changeType={props.onChange} meals={props.meals} field={field} />
</Form.Item>
<Form.Item
name={[i, 'time']}
rules={
props.meals[field] ? [{ type: 'array', required: true, message: '请选择!' }] : []
}
>
<TimePicker.RangePicker format="HH:mm" minuteStep={30} />
</Form.Item>
</Space>
))}
</>
)}
</Form.List>
);
export default MealSection;
import React, { useState, useRef } from 'react';
import ProTable from '@ant-design/pro-table';
import { Button } from 'antd';
import { PlusOutlined } from '@ant-design/icons';
import { customerColumn } from './staticData/index';
import CustomerInfo from './components/CustomerInfo';
import utilStyle from '@/utils/utils.less';
import { stringOrObjectTrim } from '@/utils/utils';
import { apiEnterpriseList } from './service';
const BusinessCustomer = () => {
const refTable = useRef();
const [visible, setVisible] = useState(false);
const [id, setId] = useState('');
const query = async params => {
const data = {
page: params.current,
size: params.pageSize,
data: stringOrObjectTrim(params),
};
const res = await apiEnterpriseList(data);
return {
data: res.data.records,
total: res.data.total,
};
};
const onEdit = v => {
setId(v);
setVisible(true);
};
return (
<div className={utilStyle.formPageBox}>
<ProTable
actionRef={refTable}
search={{
collapsed: false,
collapseRender: () => null,
}}
columns={customerColumn({ onEdit })}
request={params => query({ ...params })}
rowKey={r => r.id}
expandIconColumnIndex={10}
bordered
options={false}
toolBarRender={() => [
<Button
key="3"
icon={<PlusOutlined />}
type="primary"
onClick={() => {
setId('');
setVisible(!0);
}}
>
添加企业客户
</Button>,
]}
/>
<CustomerInfo
visible={visible}
id={id}
reFresh={() => refTable.current.reload()}
handleClose={setVisible}
/>
</div>
);
};
export default BusinessCustomer;
import request from '@/utils/request';
import config from '@/../config/env.config';
// import qs from 'qs';
const { roleApi, apiPrefix } = config;
/**
* 获取企业客户列表
* /yapi/project/389/interface/api/65324
*/
export async function apiEnterpriseList(data) {
return request.post(`${apiPrefix}/enterprise/pageList`, {
data,
prefix: roleApi,
});
}
/**
* 获取企业客户详细
* /yapi/project/389/interface/api/65339
*/
export async function apiEnterpriseInfo(id) {
return request.get(`${apiPrefix}/enterprise/info?id=${id}`, {
prefix: roleApi,
});
}
/**
* 添加企业客户
* /yapi/project/389/interface/api/65329
*/
export async function apiNewEnterprise(data) {
return request.post(`${apiPrefix}/enterprise/save`, {
data,
prefix: roleApi,
});
}
/**
* 编辑企业客户
* /yapi/project/389/interface/api/65334
*/
export async function apiEditEnterprise(data) {
return request.post(`${apiPrefix}/enterprise/update`, {
data,
prefix: roleApi,
});
}
/**
* 查询自提点列表
* /yapi/project/389/interface/api/65494
*/
export async function apiEnterprisePickSelf() {
return request.get(`${apiPrefix}/selfPickUpLocation/list`, {
prefix: roleApi,
});
}
import React from 'react';
import { Button } from 'antd';
export const layout = {
labelCol: { span: 4 },
wrapperCol: { span: 18 },
};
// 餐品类型:(1外卖 2 自助餐 4到店)
export const mealType = {
1: '外卖',
2: '自助餐',
4: '到店',
};
export const infoOptions = [
{ label: '商品价格及图片', value: 1 },
{ label: '仅商品价格', value: 2 },
{ label: '仅商品图片', value: 3 },
{ label: '均不展示', value: 4 },
];
export const boolOptions = [{ label: '', value: 1 }, { label: '', value: 0 }];
export const hideOptions = [
{ label: '隐藏商品价格', value: 'hidePrice' },
{ label: '隐藏商品图片', value: 'hideImage' },
];
export const mealSections = {
1: '早餐',
2: '午餐',
4: '晚餐',
};
// 企业列表字段
export const customerColumn = options => {
const { onEdit } = options;
return [
{
title: 'ID',
dataIndex: 'enterpriseId',
hideInTable: true,
},
{
title: 'ID',
dataIndex: 'id',
width: 120,
align: 'center',
hideInSearch: true,
},
{
title: '公司名称',
dataIndex: 'name',
width: 120,
align: 'center',
},
{
title: '截单时间(分钟)',
dataIndex: 'endOrderTime',
width: 120,
align: 'center',
hideInSearch: true,
},
{
title: '餐品类型',
dataIndex: 'mealType',
width: 120,
align: 'center',
hideInSearch: true,
render(types) {
if (types && types.length && typeof types === 'object') {
const arr = types.map(meal => mealType[meal]);
return arr.join('/');
}
return '-';
},
},
{
title: '创建人',
dataIndex: 'createdBy',
width: 120,
align: 'center',
hideInSearch: true,
},
{
title: '创建时间',
dataIndex: 'createdAt',
width: 120,
align: 'center',
hideInSearch: true,
},
{
title: '操作',
hideInSearch: true,
dataIndex: 'action',
width: 200,
align: 'center',
fixed: 'right',
render: (val, r) => (
<Button key="edit" onClick={() => onEdit(r.id)}>
编辑
</Button>
),
},
];
};
.tip {
height: 32px;
padding-left: 5px;
line-height: 32px;
}
import React, { useEffect } from 'react';
import { Form, InputNumber, Modal, notification } from 'antd';
import { isCheckPriceTwoDecimal } from '@/utils/validator';
import { apiMealInfoUpdate } from '../service';
const SaleDateModal = props => {
const [form] = Form.useForm();
const layout = {
labelCol: { span: 8 },
wrapperCol: { span: 14 },
};
// 关闭弹窗
const handleCancel = () => {
props.handleClose(false);
};
// 提交
const handleConfirm = async () => {
const res = await form.validateFields();
if (props.id) {
const params = {
id: props.id,
enterprisePrice: res.price,
};
await apiMealInfoUpdate(params);
notification.success({ message: '保存成功' });
}
handleCancel();
props.handleRefresh(res.price);
};
useEffect(() => {
if (props.visible) {
const price = props.item?.enterprisePrice || props.item?.activityPrice || null;
form.setFieldsValue({ price });
}
}, [props.visible]);
return (
<Modal
title="修改企业商品价格"
open={props.visible}
destroyOnClose
maskClosable={false}
width="400px"
okText="保存"
onOk={handleConfirm}
onCancel={handleCancel}
>
<Form name="basicInfo" {...layout} form={form}>
<Form.Item
label="企业商品价格"
name="price"
rules={[
{ required: true, message: '请输入企业商品价格!' },
{ validator: isCheckPriceTwoDecimal, message: '请输入正确的价格' },
]}
>
<InputNumber addonAfter="元" max={99999.99} />
</Form.Item>
</Form>
</Modal>
);
};
export default SaleDateModal;
import React, { useEffect } from 'react';
import { Form, InputNumber, Modal, notification } from 'antd';
import { apiMealInfoUpdate } from '../service';
const SaleDateModal = props => {
const [form] = Form.useForm();
const layout = {
labelCol: { span: 8 },
wrapperCol: { span: 14 },
};
// 关闭弹窗
const handleCancel = () => {
props.handleClose(false);
};
// 提交
const handleConfirm = async () => {
const res = await form.validateFields();
const params = {
id: props.id,
sort: res.sort,
};
await apiMealInfoUpdate(params);
notification.success({ message: '保存成功' });
handleCancel();
props.handleRefresh();
};
useEffect(() => {
if (props.visible) {
const sort = props.item?.sort || 1000;
form.setFieldsValue({ sort });
}
}, [props.visible]);
return (
<Modal
title="修改商品排序"
open={props.visible}
destroyOnClose
maskClosable={false}
width="300px"
okText="保存"
onOk={handleConfirm}
onCancel={handleCancel}
>
<Form name="basicInfo" {...layout} form={form}>
<Form.Item label="排序" name="sort" rules={[{ required: true, message: '请输入排序!' }]}>
<InputNumber max={999999} min={0} />
</Form.Item>
</Form>
</Modal>
);
};
export default SaleDateModal;
import React, { useState, useEffect } from 'react';
import { Checkbox, Space, message, Modal, notification, Button } from 'antd';
import { weekOptions } from '../staticData/goods';
import { apiMealInfoUpdate, apiCheckInfo } from '../service';
import style from '../style/index.less';
const SaleDateModal = props => {
const [value, setValue] = useState([]);
const [loading, setLoading] = useState(false);
const [checkAll, setCheckAll] = useState(false);
// 关闭弹窗
const handleCancel = () => {
props.handleClose(false);
};
const onChangeWeek = e => {
setValue(e);
setCheckAll(e?.length === 7);
};
// 提交
const handleConfirm = async () => {
if (!value || value.length < 1) {
message.error('请选择可售日期');
return;
}
if (props.productType === 4) {
const data = [];
props.dataSource.forEach(item => {
const obj = {
saleDateList: item.saleDate,
tabCateList: item.tabCate?.map(v => ({ tabId: v })),
};
if (props.item.skuId === item.skuId && item.tabCate) {
obj.saleDateList = value;
data.push(obj);
} else if (item.saleDate?.length && item.tabCate?.length) {
data.push(obj);
}
});
setLoading(true);
const res = await apiCheckInfo(data);
setLoading(false);
if (!res || !res.success) {
return;
}
}
if (props.id) {
const params = {
id: props.id,
saleDateList: value,
};
setLoading(true);
await apiMealInfoUpdate(params);
setLoading(false);
notification.success({ message: '保存成功' });
}
handleCancel();
props.handleRefresh(value);
};
useEffect(() => {
if (props.visible) {
let v = [];
let dateList = [];
if (props.item) {
if (props.type) {
dateList = props.item[props.type];
}
dateList = dateList || props.item.saleDateList || props.item.saleDate;
}
if (dateList && dateList.length) {
v = dateList.map(item => {
if (typeof item === 'object') {
return `${item.code}`;
}
return `${item}`;
});
}
setCheckAll(v.length === 7);
setValue(v);
}
}, [props.visible]);
// 全选事件
const onCheckAll = e => {
if (e.target.checked) {
setValue(Object.keys(weekOptions).map(w => `${w}`));
} else {
setValue([]);
}
setCheckAll(e.target.checked);
};
// 弹窗底部
const footerComponent = [
<div key="footer" className={style.modalFooters}>
<Checkbox checked={checkAll} onChange={onCheckAll}>
全选
</Checkbox>
<div>
<Button onClick={handleCancel}> 取消 </Button>
<Button type="primary" loading={loading} onClick={handleConfirm}>
{' '}
保存{' '}
</Button>
</div>
</div>,
];
return (
<Modal
title={props.title || '设置可售日期'}
open={props.visible}
destroyOnClose
maskClosable={false}
width="300px"
footer={footerComponent}
>
<Checkbox.Group onChange={onChangeWeek} value={value}>
<Space direction="vertical">
{Object.keys(weekOptions).map(key => (
<Checkbox key={key} value={key}>
{weekOptions[key]}
</Checkbox>
))}
</Space>
</Checkbox.Group>
</Modal>
);
};
export default SaleDateModal;
import React, { useState, useEffect } from 'react';
import { Checkbox, Space, Modal, notification, message } from 'antd';
import { mealColumn } from '../staticData/goods';
import { apiMealInfoUpdate, apiEnterpriseInfo, apiCheckInfo } from '../service';
const SaleDateModal = props => {
const [value, setValue] = useState([]);
const [loading, setLoading] = useState(false);
const [tabCateList, setTabCateList] = useState(Object.keys(mealColumn));
// 关闭弹窗
const handleCancel = () => {
props.handleClose(false);
};
const onChangeMeal = e => {
setValue(e);
};
// 提交
const handleConfirm = async () => {
if (!value || value.length < 1) {
message.error('请选择餐段');
return;
}
const arr = value.sort((x, y) => x - y);
if (props.productType === 4) {
const data = [];
props.dataSource.forEach(item => {
const obj = {
saleDateList: item.saleDate,
tabCateList: item.tabCate?.map(v => ({ tabId: v })),
};
if (props.item.skuId === item.skuId && item.saleDate) {
obj.tabCateList = arr.map(v => ({ tabId: v }));
data.push(obj);
} else if (item.saleDate?.length && item.tabCate?.length) {
data.push(obj);
}
});
const res = await apiCheckInfo(data);
if (!res || !res.success) {
return;
}
}
if (props.id) {
const params = {
id: props.id,
tabIds: arr,
};
await apiMealInfoUpdate(params);
notification.success({ message: '保存成功' });
}
handleCancel();
props.handleRefresh(arr);
};
// 获取店铺餐段通过企业ID
const getEnterpriseMealColumn = async valueList => {
setLoading(true);
const res = await apiEnterpriseInfo(props.enterpriseID);
setLoading(false);
if (res && res.data && res.data.mealTimePeriod && res.data.mealTimePeriod.length) {
const arr = res.data.mealTimePeriod.map(item => `${item.mealPeriodType}`);
setTabCateList(arr);
// 餐段的值需在企业配置的可选餐段之内
const v = [];
valueList.forEach(t => {
arr.includes(t) && v.push(t);
});
setValue(v);
}
};
useEffect(() => {
if (props.visible) {
let v = [];
let tabCate = [];
if (props.item) {
if (props.type) {
tabCate = props.item[props.type];
}
tabCate = tabCate || props.item.tabCateList || props.item.tabCate;
}
if (tabCate && tabCate.length) {
v = tabCate.map(item => {
if (typeof item === 'object') {
return `${item.tabId}`;
}
return `${item}`;
});
}
setValue(v);
if (props.enterpriseID) {
getEnterpriseMealColumn(v);
}
}
}, [props.visible]);
return (
<Modal
title={props.title || '设置可售餐段'}
open={props.visible}
destroyOnClose
maskClosable={false}
width="200px"
okText="保存"
confirmLoading={loading}
onOk={handleConfirm}
onCancel={handleCancel}
>
<Checkbox.Group onChange={onChangeMeal} value={value}>
<Space direction="vertical">
{tabCateList.map(key => (
<Checkbox key={key} value={key}>
{mealColumn[key]}
</Checkbox>
))}
</Space>
</Checkbox.Group>
</Modal>
);
};
export default SaleDateModal;
import React, { useState, useEffect } from 'react';
import { Select, Modal, Table, Input, Button, Pagination, notification } from 'antd';
import { SearchOutlined } from '@ant-design/icons';
import { apiSelGoodsList, apiSelVirtualGoodsList, apiShopListByPickSelfID } from '../service';
import { SelectGoodsColumn, productType, weekOptions } from '../staticData/goods';
import style from '../style/index.less';
import { jsonToArray, deepClone } from '@/utils/utils';
const { Option } = Select;
const SaleDateModal = props => {
const [searchType, setSearchType] = useState('1');
const [searchKeyword, setSearchKeyword] = useState('');
const [shopId, setShopId] = useState(props.shopID || null);
const [shopName, setShopName] = useState('');
const [searchName, setSearchName] = useState('');
const [loading, setLoading] = useState(false);
const [page, setPage] = useState(1);
const [pageSize, setPageSize] = useState(10);
const [total, setTotal] = useState(0);
const [dataSource, setDataSource] = useState([]);
const [shopList, setShopList] = useState([]);
const [selectedRowKeys, setSelectedRowKeys] = useState(props.selectedRowKeys || []);
const [selectedRows, setSelectedRows] = useState(props.selectedRows || []);
const searchList = async params => {
const { enterpriseId } = props;
const searchObj = {};
if (searchKeyword && searchType && !params.search) {
if (searchType === '1') {
searchObj.name = searchKeyword;
} else {
searchObj.skuId = searchKeyword;
}
}
const data = {
page: params.current || page,
size: params.pageSize || pageSize,
data: Object.assign(
{
shopId,
productType: props.productType,
enterpriseId,
},
searchObj,
params,
),
};
setLoading(true);
let api = apiSelGoodsList;
if (props.type === 'virtual') {
api = apiSelVirtualGoodsList;
}
const res = await api(data);
const arr =
res?.data?.records?.map(item => {
item.enterprisePrice = item.salePrice;
return item;
}) || [];
setDataSource(arr);
setTotal(res?.data?.total || 0);
setLoading(false);
};
// 点击搜索
const onSearch = () => {
setSearchKeyword(searchName);
setPage(1);
searchList({ [searchType === '1' ? 'name' : 'skuId']: searchName, current: 1 });
};
// 切换店铺
const onChangeShop = v => {
setShopId(v);
setPage(1);
searchList({
shopId: v,
current: 1,
});
setSelectedRowKeys([]);
setSelectedRows([]);
};
// 关闭弹窗
const handleCancel = () => {
props.handleClose(false);
};
// 提交
const handleConfirm = async () => {
if (!selectedRows || selectedRows.length < 1) {
notification.error({ message: '请选择要添加的商品' });
return;
}
let sName = '';
if (shopList && shopList.length) {
shopList.forEach(item => {
if (+item.value === +shopId) {
sName = item.label;
}
});
} else {
sName = shopName;
}
const arr = deepClone(selectedRows).map(item => ({
...item,
shopId,
saleDate:
!item.saleDate || item.saleDate.length < 1 ? Object.keys(weekOptions) : item.saleDate,
shopName: sName,
}));
props.onSelectChange(arr);
if (!props.shopID) {
props.onChangeShop(shopId);
}
if (props.onSelectedRowKeys) {
props.onSelectedRowKeys(selectedRowKeys);
}
handleCancel();
};
// 商品单选
const onSelectChange = (record, selected) => {
const { skuId } = record;
if (selected) {
const keys = [...selectedRowKeys, skuId];
const arr = [...selectedRows, record];
setSelectedRowKeys(keys);
setSelectedRows(arr);
} else {
const rows = [];
const keys = [];
selectedRows.forEach(item => {
if (item.skuId !== skuId) {
rows.push(item);
keys.push(item.skuId);
}
});
setSelectedRowKeys(keys);
setSelectedRows(rows);
}
};
// 商品全选
const onSelectAllChange = (selected, rows) => {
const keys = [...selectedRowKeys];
const arr = [...selectedRows];
if (selected) {
rows.forEach(item => {
if (item && !keys.includes(item.skuId)) {
keys.push(item.skuId);
arr.push(item);
}
});
setSelectedRowKeys(keys);
setSelectedRows(arr);
} else {
dataSource.forEach(item => {
const index = keys.findIndex(k => k === item.skuId);
if (index > -1) {
keys.splice(index, 1);
arr.splice(index, 1);
}
});
setSelectedRowKeys(keys);
setSelectedRows(arr);
}
};
// 切换页码
const onPageChange = (current, size) => {
setPage(current);
setPageSize(size);
searchList({
current,
pageSize: size,
});
};
// 获取店铺列表
const getShopList = async () => {
const res = await apiShopListByPickSelfID({
enterpriseId: props.enterpriseId,
pickSelfIdList: props.pickSelfIdList,
});
if (res && res.data) {
setShopList(
res.data.map(item => ({
label: item.name,
value: item.id,
})),
);
}
};
const rowSelection = {
selectedRowKeys,
onSelect: onSelectChange,
onSelectAll: onSelectAllChange,
getCheckboxProps: record => ({
disabled: !!record.selected,
}),
};
const onChangeSearchType = v => {
setSearchType(v);
setSearchName('');
};
const selectBefore = (
<Select defaultValue="1" onChange={onChangeSearchType}>
<Option value="1" key={1}>
名称
</Option>
<Option value="2" key={2}>
SKU
</Option>
</Select>
);
const selectAfter = <SearchOutlined onClick={onSearch} />;
const footers = () => [
<div className={style.footers} key="footer">
<Pagination defaultCurrent={1} total={total} showQuickJumper onChange={onPageChange} />
<div className={style['footers-btn']}>
<div className={style['footers-desc']}>
已选商品(<span className={style['footers-num']}>{selectedRowKeys.length}</span>)
</div>
<Button key="back" onClick={handleCancel}>
取消
</Button>
<Button key="submit" type="primary" loading={loading} onClick={handleConfirm}>
确定
</Button>
</div>
</div>,
];
useEffect(() => {
if (+props.productType === 5) {
setShopId(null);
getShopList();
} else {
setShopId(props.shopID);
setShopName(props.shopName);
searchList({});
}
}, []);
return (
<Modal
title="选择商品"
open={props.visible}
destroyOnClose
maskClosable={false}
width="1000px"
onOk={handleConfirm}
onCancel={handleCancel}
footer={footers()}
>
<div className={style['select-goods-box']}>
{props.productType === 5 ? (
<Select
placeholder="请选择店铺"
options={shopList}
value={shopId}
onChange={onChangeShop}
className={style['select-goods-box--select']}
/>
) : (
<Input disabled value={shopName} className={style['select-goods-box--txt']} />
)}
<Select
placeholder="请选择商品类型"
disabled
value={`${props.productType}`}
options={jsonToArray(productType)}
className={style['select-goods-box--select']}
/>
<Input
addonBefore={selectBefore}
addonAfter={selectAfter}
value={searchName}
allowClear
type={+searchType === 2 ? 'number' : 'text'}
onChange={e => setSearchName(e.target.value)}
onPressEnter={onSearch}
className={style['select-goods-box--txt']}
/>
</div>
<Table
rowSelection={rowSelection}
rowKey="skuId"
columns={SelectGoodsColumn}
pagination={false}
dataSource={dataSource}
/>
</Modal>
);
};
export default SaleDateModal;
import { apiEnterpriseList, apiShopList, apiShopListByPickSelfID } from './index';
// 获取企业列表
export const getEnterpriseList = async (param = {}) => {
const res = await apiEnterpriseList({
page: 1,
size: 10000,
data: param,
});
if (res?.data?.records?.length) {
const data = res.data.records;
const arr = data.map(item => ({
label: item.name,
value: item.id,
key: item.id,
}));
return {
id: data[0].id,
list: arr,
};
}
return {
id: '',
list: [],
};
};
// 获取店铺列表
export const getShopList = async e => {
if (e.keyWords) {
const res = await apiShopList({ name: e.keyWords });
if (res && res.data) {
const { data } = res;
return data.map(item => ({
value: item.id,
label: item.name,
}));
}
}
return [];
};
// 获取店铺列表通过自提点ID
export const getShopListByPickSelf = async e => {
const { name } = e;
const res = await apiShopListByPickSelfID({ name });
if (res && res.data && res.data.records) {
const data = res.data.records;
const json = {};
data.forEach(item => {
json[item.id] = { text: item.name };
});
return {
id: res[res.length - 1].id,
list: json,
};
}
return {
id: '',
list: {},
};
};
// 获取店铺名称
export const getEnterpriseName = (arr, id) => {
let name = '';
if (arr && arr.length) {
arr.forEach(item => {
if (+item.value === +id) {
name = item.label;
}
});
}
return name;
};
import request from '@/utils/request';
import config from '@/../config/env.config';
const { roleApi, apiPrefix } = config;
/**
* 获取企业外卖商品列表
* /yapi/project/389/interface/api/64794
*/
export async function apiTakeawayList(param) {
const res = await request.post(`${apiPrefix}/product/enterprise/main/pageList`, {
data: param,
prefix: roleApi,
});
return res.data;
}
/**
* 获取企业虚拟商品列表
* /yapi/project/389/interface/api/64794
*/
export async function apiVirtualList(param) {
return request.post(`${apiPrefix}/product/enterprise/virtual/pageList`, {
data: param,
prefix: roleApi,
});
}
/**
* 企业客户列表
* /yapi/project/389/interface/api/65324
*/
export async function apiEnterpriseList(param) {
return request.post(`${apiPrefix}/enterprise/pageList`, {
data: param,
prefix: roleApi,
});
}
/**
* 模糊查询店铺列表
* /yapi/project/389/interface/api/65289
*/
export async function apiShopList(param) {
return request.post(`${apiPrefix}/shops/getListByName`, {
data: param,
prefix: roleApi,
});
}
/**
* 企业团餐-查询餐段配置
* /yapi/project/389/interface/api/65444
*/
export async function apiMealTimePeriod(param) {
return request.post(`${apiPrefix}/product/enterprise/getMealTimePeriod`, {
data: param,
prefix: roleApi,
});
}
/**
* 企业团餐->信息修改
* /yapi/project/389/interface/api/65099
*/
export async function apiMealInfoUpdate(param) {
return request.post(`${apiPrefix}/product/enterprise/main/update`, {
data: param,
prefix: roleApi,
});
}
/**
* 企业团餐->删除外卖商品
* /yapi/project/389/interface/api/65109
*/
export async function apiTakeawayGoodsDel(param) {
return request.post(`${apiPrefix}/product/enterprise/main/deleteById`, {
data: param,
prefix: roleApi,
});
}
/**
* 企业团餐->删除虚拟商品
* /yapi/project/389/interface/api/65109
*/
export async function apiVirtualGoodsDel(param) {
return request.post(`${apiPrefix}/product/enterprise/virtual/deleteById`, {
data: param,
prefix: roleApi,
});
}
/**
* 企业团餐->查询自提点列表
* /yapi/project/389/interface/api/65494
*/
export async function apiPickSelfList() {
return request.get(`${apiPrefix}/selfPickUpLocation/list`, {
prefix: roleApi,
});
}
/**
* 企业团餐->根据企业ID查询已选择自提点
* /yapi/project/389/interface/api/65449
*/
export async function apiSelPickSelfList(param) {
return request.post(`${apiPrefix}/product/enterprise/queryByEnterpriseId`, {
data: param,
prefix: roleApi,
});
}
/**
* 企业团餐->查询外卖商品 - 选择商品弹窗
* /yapi/project/389/interface/api/65479
*/
export async function apiSelGoodsList(param) {
return request.post(`${apiPrefix}/product/enterprise/sku/page`, {
data: param,
prefix: roleApi,
});
}
/**
* 企业团餐->查询商品 - 选择虚拟商品弹窗
* /yapi/project/389/interface/api/65479
*/
export async function apiSelVirtualGoodsList(param) {
return request.post(`${apiPrefix}/product/enterprise/virtual/sku/page`, {
data: param,
prefix: roleApi,
});
}
/**
* 企业团餐->添加外卖商品保存
* /yapi/project/389/interface/api/65094
*/
export async function apiSaveGoodsList(param) {
return request.post(`${apiPrefix}/product/enterprise/add`, {
data: param,
prefix: roleApi,
});
}
/**
* 企业团餐->添加虚拟商品保存
* /yapi/project/389/interface/api/65484
*/
export async function apiSaveVirtualGoodsList(param) {
return request.post(`${apiPrefix}/product/enterprise/virtual/add`, {
data: param,
prefix: roleApi,
});
}
/**
* 企业团餐->虚拟品->根据企业ID查询店铺列表
* /yapi/project/389/interface/api/65504
*/
export async function apiShopListByEnterpriseID(param) {
return request.post(`${apiPrefix}/product/enterprise/virtual/shops`, {
data: param,
prefix: roleApi,
});
}
/**
* 企业团餐->根据企业ID+自提点列表查询店铺列表
* /yapi/project/389/interface/api/65539
*/
export async function apiShopListByPickSelfID(param) {
return request.post(`${apiPrefix}/product/enterprise/queryByEnterpriseIdAndPickSelfId`, {
data: param,
prefix: roleApi,
});
}
/**
* 企业团餐->根据企业ID 获取企业客户详细
* /yapi/project/389/interface/api/65339
*/
export async function apiEnterpriseInfo(id) {
return request.get(`${apiPrefix}/enterprise/info?id=${id}`, {
prefix: roleApi,
});
}
/**
* 企业团餐->虚拟商品 校验是否可修改餐段和可售日期
* /yapi/project/389/interface/api/65674
*/
export async function apiCheckInfo(data) {
return request.post(`${apiPrefix}/product/enterprise/virtual/addParamCheck`, {
data,
prefix: roleApi,
});
}
This diff is collapsed.
.search {
padding: 0;
:global {
.ant-form-item {
display: block !important;
}
}
}
.info-box {
min-height: 100%;
padding: 20px 40px;
background-color: #fff;
&--line {
min-height: 32px;
margin-bottom: 15px;
line-height: 32px;
}
&--label {
text-align: right;
}
&--select {
width: 100%;
min-width: 200px;
}
&--btns {
margin-top: 20px;
&__confirm {
margin-right: 15px;
}
}
&--batch-btn {
text-align: right;
}
}
.select-goods-box {
display: flex;
padding: 5px 0;
.select-goods-box--select {
width: 200px;
}
.select-goods-box--txt {
width: 300px;
:global {
.ant-input::-webkit-inner-spin-button,
.ant-input::-webkit-outer-spin-button {
margin: 0;
-webkit-appearance: none;
}
.ant-input {
-webkit-appearance: textfield;
}
}
}
}
.footers {
display: flex;
align-items: center;
justify-content: space-between;
&-btn {
display: flex;
align-items: center;
justify-content: flex-end;
text-align: right;
}
&-desc {
margin-right: 10px;
}
&-num {
color: #1890ff;
}
}
.columnTip {
color: #999;
}
.columnBtnEdit {
cursor: pointer;
}
.modalFooters {
display: flex;
align-items: center;
justify-content: space-between;
}
This diff is collapsed.
This diff is collapsed.
import React, { useState, useEffect, useRef } from 'react';
import { useHistory } from 'react-router-dom';
import { ProTable } from '@ant-design/pro-components';
import { Button, notification } from 'antd';
import { PlusOutlined } from '@ant-design/icons';
import { virtualGoodsColumn } from './staticData/goods';
import utilStyle from '@/utils/utils.less';
import { apiVirtualList, apiVirtualGoodsDel } from './service';
import { getEnterpriseList, getEnterpriseName } from './service/bll';
import { getToUrlQuery } from '@/utils/utils';
// 企业虚拟商品
const VirtualGoods = () => {
const history = useHistory();
const refTable = useRef();
const [pageLoaded, setPageLoaded] = useState(false);
const [enterprises, setEnterprises] = useState(null); // 企业列表
const [enterpriseId, setEnterpriseId] = useState(''); // 选中企业ID
// 刷新列表
const onRefresh = () => {
if (pageLoaded) {
refTable?.current?.reloadAndRest();
}
};
// 搜索商品列表
const searchList = async params => {
if (params.createDate && params.createDate.length) {
const [startDateTime, endDateTime] = params.createDate;
params.startDateTime = startDateTime;
params.endDateTime = endDateTime;
}
const data = {
page: params.current || 1,
size: params.pageSize || 10,
data: Object.assign({}, params, {
enterpriseId,
}),
};
const res = await apiVirtualList(data);
if (res && res.data && res.data.records && res.data.records.length) {
return {
data: res.data.records || [],
total: res.data.total || 0,
};
}
return {
data: [],
total: 0,
};
};
// 删除商品
const onDel = async id => {
await apiVirtualGoodsDel({
id,
});
refTable.current.reload();
notification.success({
message: '删除成功',
});
};
// 跳转添加商品
const toAdd = async () => {
const params = getToUrlQuery();
const query = Object.assign(
{
id: enterpriseId,
name: getEnterpriseName(enterprises, enterpriseId),
},
params,
);
history.push({
pathname: '/virtualGoodsInfo',
query,
});
};
// 改变企业
const onChangeEnterprise = v => {
setEnterpriseId(v);
onRefresh();
};
// 获取企业列表
const getList = async () => {
const obj = await getEnterpriseList({
type: 2,
});
if (obj.list && Object.keys(obj.list).length) {
setEnterprises(obj.list);
setEnterpriseId(`${obj.id}`);
} else if (!enterpriseId) {
notification.error({ message: '未找到企业' });
}
setPageLoaded(true);
};
useEffect(() => {
getList();
}, []);
const options = {
onDel,
enterprises,
enterpriseId,
onChangeEnterprise,
};
let request = () => ({
data: [],
total: 0,
});
if (enterpriseId) {
request = params => searchList({ ...params });
}
return (
<div className={utilStyle.formPageBox}>
{pageLoaded && (
<ProTable
search={{
span: 6,
className: utilStyle.formSearch,
collapsed: false,
collapseRender: () => null,
}}
actionRef={refTable}
tableClassName={utilStyle.formTable}
columns={virtualGoodsColumn(options)}
request={request}
rowKey={r => r.id}
bordered
options={false}
scroll={{ x: 1300 }}
toolbar={{
actions: [
<Button key="1" icon={<PlusOutlined />} type="primary" onClick={toAdd}>
添加虚拟商品
</Button>,
],
}}
/>
)}
</div>
);
};
export default VirtualGoods;
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
const Model = {
namespace: 'BusinessManage',
state: {},
effects: {},
reducers: {},
};
export default Model;
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
import { stringify } from 'querystring';
import request from '@/utils/request';
import _ from 'lodash';
import config from '../../../config/env.config';
const { goodsApi } = config;
// 分页查询所有数据
export async function query(params) {
const param = {
...params,
pageIndex: params.current,
pageSize: params.pageSize || 20,
};
const data = await request.post('/api/merchants/suppliers/contract/list', {
prefix: goodsApi,
data: param,
headers: {
'Content-Type': 'application/json;charset=UTF-8',
},
});
if (data.data) {
return {
data: data.data,
};
}
return {
total: 0,
data: [],
};
}
.contract {
text-align: center;
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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