Commit 885f1aaa authored by 武广's avatar 武广

Merge branch 'master' of git.quantgroup.cn:ui/merchant-manage-ui into feature/draft

parents 12399379 a53c3146
...@@ -146,6 +146,13 @@ export default { ...@@ -146,6 +146,13 @@ export default {
icon: 'smile', icon: 'smile',
component: './AfterSaleManage/index', component: './AfterSaleManage/index',
}, },
{
title: '商户管理后台',
path: '/afterSalesClaimForm',
name: 'afterSalesClaimForm',
icon: 'smile',
component: './AfterSalesClaimForm/index',
},
{ {
title: '商户管理后台', title: '商户管理后台',
path: '/afterSaleManageOld', path: '/afterSaleManageOld',
......
const isProduction = process.env.NODE_ENV === 'production'; const isProduction = process.env.NODE_ENV === 'production';
const isPre = process.env.PRE_ENV === 'pre'; const isPre = process.env.PRE_ENV === 'pre';
const environment = 'sc'; const environment = 'yxm2';
const envAPi = { const envAPi = {
api: `https://security-${environment}.liangkebang.net`, //'https://security-xyqb.liangkebang.net', api: `https://security-${environment}.liangkebang.net`, //'https://security-xyqb.liangkebang.net',
kdspOpApi: `https://sc-merchant-api-${environment}.liangkebang.net`, kdspOpApi: `https://sc-merchant-api-${environment}.liangkebang.net`,
......
...@@ -139,7 +139,7 @@ const Simple = props => { ...@@ -139,7 +139,7 @@ const Simple = props => {
} }
const params = { const params = {
pageNo: 1, pageNo: 1,
pageSize: 1000, pageSize: 200,
}; };
const data = { const data = {
channelId: CHANNEL_ID, channelId: CHANNEL_ID,
......
import React, { useState, forwardRef, useImperativeHandle, useEffect } from 'react'; import React, { useState, forwardRef, useImperativeHandle, useEffect } from 'react';
import { Modal, Timeline, notification, Spin } from 'antd'; import { Modal, Timeline, notification, Spin, Collapse } from 'antd';
import { getLogisticsRecord } from '../services'; import { getLogisticsRecord, apiDeliveriesTraceList } from '../services';
import styles from '../index.less';
const { Panel } = Collapse;
const LogisticsRecordModal = (props, ref) => { const LogisticsRecordModal = (props, ref) => {
// const { } = props; // const { } = props;
const [visible, setVisible] = useState(false); const [visible, setVisible] = useState(false);
const [result, setResult] = useState({});
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [dataList, setDataList] = useState([]);
const [isSingle, setIsSingle] = useState(false);
const getRecordList = async orderNo => { const getRecordList = async params => {
const tempObj = {
detailList: [],
key: Date.now(),
};
setLoading(true); setLoading(true);
const res = await getLogisticsRecord({ orderNo }); const res = await apiDeliveriesTraceList(params);
setLoading(false); setLoading(false);
if (!res) { if (!res) {
notification.info({ message: '暂无物流信息' }); notification.info({ message: '暂无物流信息' });
return; return;
} }
const { logisticsName, logisticsBillNo, logisticsList = [] } = res.data;
tempObj.expressCompanyName = logisticsName; setDataList(res.data);
tempObj.deliveryNo = logisticsBillNo;
logisticsList.forEach(v => {
tempObj.detailList = [...tempObj.detailList, ...v.detailList];
});
setResult(tempObj);
}; };
const open = orderNo => { const open = (record, type) => {
setVisible(true); setVisible(true);
getRecordList(orderNo); getRecordList(record);
if (type === 'single') {
setIsSingle(true);
}
}; };
const onCancel = () => { const onCancel = () => {
setVisible(false); setVisible(false);
setResult([]); setTimeout(() => {
setDataList([]);
}, 1000);
}; };
useImperativeHandle(ref, () => ({ useImperativeHandle(ref, () => ({
open, open,
...@@ -59,18 +59,70 @@ const LogisticsRecordModal = (props, ref) => { ...@@ -59,18 +59,70 @@ const LogisticsRecordModal = (props, ref) => {
return ( return (
<Modal {...modalProps}> <Modal {...modalProps}>
<Spin spinning={loading}> <Spin spinning={loading}>
{result.detailList?.length ? ( {dataList.length ? (
<Timeline> dataList.map((dataItem, dataIndex) => (
{result?.detailList?.map((item, index) => ( <div className={styles['logistics-record']}>
<Timeline.Item color={index > 0 ? 'gray' : 'blue'} key={index.toString()}> {!isSingle ? (
<p>{item.desc}</p> <div className={styles['logistics-record__topbar']}>包裹{dataIndex + 1}</div>
<p>{item.logisticsTime}</p> ) : (
</Timeline.Item> ''
))} )}
</Timeline> <div className={styles['logistics-record__head']}>
<span className={styles.name}>物流公司:{dataItem.expressCompanyName}</span>
<span className={styles.no}>物流单号:{dataItem.expressNo}</span>
</div>
{dataItem.traceList.map(traceItem => (
<Timeline>
{traceItem?.detailList.length ? (
traceItem?.detailList?.map((item, index) => (
<Timeline.Item color={index > 0 ? 'gray' : 'blue'} key={index.toString()}>
<p>{item.desc}</p>
<p>{item.time}</p>
</Timeline.Item>
))
) : (
<div style={emptyStyle}>暂无物流信息</div>
)}
</Timeline>
))}
</div>
))
) : ( ) : (
<div style={emptyStyle}>暂无物流信息</div> <div style={emptyStyle}>暂无物流信息</div>
)} )}
{/* 折叠 */}
{/* <Collapse defaultActiveKey={['0']} ghost >
{dataList.length ? (
dataList.map((dataItem, dataIndex) => (
<Panel showArrow={false} header={<div className={styles['logistics-record__topbar']}>包裹{dataIndex + 1}</div>} key={dataIndex.toString()}>
<div className={styles['logistics-record']}>
<div className={styles['logistics-record__head']}>
<span className={styles.name}>物流公司:{dataItem.expressCompanyName}</span>
<span className={styles.no}>物流单号:{dataItem.expressNo}</span>
</div>
{dataItem.traceList.map(traceItem => (
<Timeline>
{traceItem?.detailList.length ? (
traceItem?.detailList?.map((item, index) => (
<Timeline.Item color={index > 0 ? 'gray' : 'blue'} key={index.toString()}>
<p>{item.desc}</p>
<p>{item.time}</p>
</Timeline.Item>
))
) : (
<div style={emptyStyle}>暂无物流信息</div>
)}
</Timeline>
))}
</div>
</Panel>
))
) : (
<div style={emptyStyle}>暂无物流信息</div>
)}
</Collapse> */}
</Spin> </Spin>
</Modal> </Modal>
); );
......
...@@ -105,7 +105,8 @@ const AuditModal = props => { ...@@ -105,7 +105,8 @@ const AuditModal = props => {
}; };
const openLogisticsRecord = () => { const openLogisticsRecord = () => {
logisticsRecordModalRef.current.open(formData.orderNo); const { orderNo, skuNo } = formData;
logisticsRecordModalRef.current.open({ orderNo, skuNo });
}; };
const layout = { const layout = {
......
...@@ -16,6 +16,7 @@ import RejectModal from './components/rejectModal'; ...@@ -16,6 +16,7 @@ import RejectModal from './components/rejectModal';
import LogisticsCom from '../orderManage/pendingDeliveryOrder/components/LogisticsCom'; import LogisticsCom from '../orderManage/pendingDeliveryOrder/components/LogisticsCom';
import CancelAuditModal from './components/CancelAuditModal'; import CancelAuditModal from './components/CancelAuditModal';
import CancelDetailTable from './components/CancelDetailTable'; import CancelDetailTable from './components/CancelDetailTable';
import LogisticsRecordModal from './components/LogisticsRecordModal';
import { getColumns, getFormConfig, TAB_MAPPING_DATA } from './data.js'; import { getColumns, getFormConfig, TAB_MAPPING_DATA } from './data.js';
import { getDetail } from '@/pages/afterSale/appeal/services'; import { getDetail } from '@/pages/afterSale/appeal/services';
...@@ -44,6 +45,7 @@ const AfterSale = props => { ...@@ -44,6 +45,7 @@ const AfterSale = props => {
const actionRef = useRef(); const actionRef = useRef();
const formRef = useRef(); const formRef = useRef();
const logisticsRecordModalRef = useRef();
const [tableParams, setTableParams] = useState({}); const [tableParams, setTableParams] = useState({});
const [currentTab, setCurrentTab] = useState(''); const [currentTab, setCurrentTab] = useState('');
// const [appealDetailModal, setAppealDetailModal] = useState(false); // const [appealDetailModal, setAppealDetailModal] = useState(false);
...@@ -125,32 +127,35 @@ const AfterSale = props => { ...@@ -125,32 +127,35 @@ const AfterSale = props => {
}; };
// 审核 // 审核
const openAudit = async ({ serviceNo, serviceType, orderNo }) => { const openAudit = async ({ serviceNo, serviceType, orderNo, skuNo }) => {
const data = await auditInfoApi({ serviceNo }); const data = await auditInfoApi({ serviceNo });
setAuditInfo({ ...data?.data, serviceNo, serviceType, orderNo }); setAuditInfo({ ...data?.data, serviceNo, serviceType, orderNo, skuNo });
setVisible(true); setVisible(true);
}; };
// 查看物流 // 查看物流
const handleCom = async ({ expressCompanyCode, deliveryNo }) => { const handleCom = async record => {
const tempObj = { console.log('record', record);
detailList: [], const { expressCompanyCode, deliveryNo: expressNo } = record;
key: Date.now(), logisticsRecordModalRef.current.open({ expressCompanyCode, expressNo }, 'single');
}; // const tempObj = {
const data = await trackInfo({ expressCompanyCode, logisticsNo: deliveryNo }); // detailList: [],
if (!data) { // key: Date.now(),
notification.info({ message: '暂无物流信息' }); // };
return; // const data = await trackInfo({ expressCompanyCode, logisticsNo: deliveryNo });
} // if (!data) {
tempObj.expressCompanyName = data.logisticsName; // notification.info({ message: '暂无物流信息' });
tempObj.deliveryNo = data.logisticsBillNo; // return;
if (data.logisticsList?.length) { // }
data.logisticsList.forEach(v => { // tempObj.expressCompanyName = data.logisticsName;
tempObj.detailList = [...tempObj.detailList, ...v.detailList]; // tempObj.deliveryNo = data.logisticsBillNo;
}); // if (data.logisticsList?.length) {
} // data.logisticsList.forEach(v => {
setLogisticsComModalVisible(true); // tempObj.detailList = [...tempObj.detailList, ...v.detailList];
setLogisticsComList(tempObj); // });
// }
// setLogisticsComModalVisible(true);
// setLogisticsComList(tempObj);
}; };
// 物流拦截 // 物流拦截
...@@ -439,6 +444,8 @@ const AfterSale = props => { ...@@ -439,6 +444,8 @@ const AfterSale = props => {
onCancel={closeModal} onCancel={closeModal}
dataSource={cancelDetailInfo} dataSource={cancelDetailInfo}
/> />
<LogisticsRecordModal ref={logisticsRecordModalRef} />
</PageHeaderWrapper> </PageHeaderWrapper>
); );
}; };
......
...@@ -59,3 +59,24 @@ ...@@ -59,3 +59,24 @@
} }
} }
} }
.logistics-record {
&__topbar {
margin-bottom: 15px;
padding-left: 10px;
color: #000;
font-weight: bold;
font-size: 16px;
border-left: 10px solid #2391fe;
}
&__head {
padding-bottom: 25px;
color: #000;
font-weight: 500;
font-size: 14px;
line-height: 1;
.no {
margin-left: 20px;
}
}
}
...@@ -131,6 +131,21 @@ export async function getLogisticsRecord(params) { ...@@ -131,6 +131,21 @@ export async function getLogisticsRecord(params) {
}); });
} }
/**
* 多物流发货-查询物流轨迹
* @see http://yapi.quantgroups.com/project/389/interface/api/46120
*/
export function apiDeliveriesTraceList(data) {
return request.post('/api/merchants/deliveries/trace/list', {
data: stringify(data),
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
prefix: kdspApi,
});
}
// 查询售后待办数量 // 查询售后待办数量
export function getAfterPendingNum(data) { export function getAfterPendingNum(data) {
return request.post('/api/kdsp/op/afs/getPendingNum', { return request.post('/api/kdsp/op/afs/getPendingNum', {
......
import React, { useState, forwardRef, useImperativeHandle } from 'react';
import { Form } from '@ant-design/compatible';
import { Modal, Button } from 'antd';
// 0: 待财务审核
// 1: 审核通过
// 2: 审核拒绝,
const ExamineFormModal = forwardRef((props, ref) => {
const { form, claimVisible, closeClaimDescription, refresh } = props;
const [detailData, setDetailData] = useState({});
useImperativeHandle(ref, () => ({
setDetailData,
...form,
}));
const onCancelEvent = () => {
closeClaimDescription();
};
const footerButton = [
<Button type="primary" key="cancel" onClick={onCancelEvent}>
关闭
</Button>,
];
return (
<Modal
title="赔款说明"
centered
visible={claimVisible}
footer={detailData.audit ? footerButton : null}
bodyStyle={{ padding: '12px 0' }}
onCancel={onCancelEvent}
></Modal>
);
});
export default Form.create()(ExamineFormModal);
import React, { useState, useRef, useEffect } from 'react';
import ProTable from '@ant-design/pro-table';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import { Button, Image } from 'antd';
import { saveAs } from 'file-saver';
import { columnsConfig, getLastItem, checkImage } from './staticdata';
import { getQueryClamsList } from './service';
import ClaimDescription from './ClaimDescription';
/**
* 售后赔款单
* 售后赔款单
* @param {*} router options
* @returns ReactDOM
*/
const AfterSalesClaimForm = ({ route }) => {
const ref = useRef();
const actionRef = useRef();
const [claimVisible, setclaimVisible] = useState(false);
const [claimLoading, setclaimLoading] = useState(false);
const [imagePreView, setImagePreView] = useState({
src: '',
visible: false,
});
const search = {
collapsed: false,
collapseRender: () => null,
};
const query = async params => {
const { createdAt, singleType, singleNumber, current: pageNo, ...other } = params;
const queryParams = { ...other, pageNo };
if (singleType && singleNumber) {
if (+singleType === 0) queryParams.id = singleNumber;
if (+singleType === 1) queryParams.orderNo = singleNumber;
}
if (createdAt?.length) {
const [startTime, endTime] = createdAt;
queryParams.startTime = startTime;
queryParams.endTime = endTime;
}
const { data } = await getQueryClamsList(queryParams);
return {
total: data.total,
data: data?.records,
};
};
const openSetclaimModal = async (row, audit) => {
setclaimLoading(true);
setclaimVisible(true);
setclaimLoading(false);
};
const closeClaimDescription = () => {
setclaimVisible(false);
};
const refreshTable = () => {
ref.current.reload();
};
// eslint-disable-next-line consistent-return
const downLoadFile = async url => {
if (await checkImage(url)) {
setImagePreView({ src: url, visible: true });
return null;
}
saveAs(url, getLastItem(url));
};
// const toolBarRender = () => [
// <Button type="link" onClick={openSetclaimModal}>
// 赔款说明
// </Button>,
// ];
// toolBarRender={toolBarRender}
const onReset = () => {};
return (
<PageHeaderWrapper>
<ProTable
bordered
loading={claimLoading}
type="cardList"
request={query}
tableClassName="capital"
columns={columnsConfig({ downLoadFile })}
rowKey={row => row.id}
search={search}
options={false}
actionRef={ref}
pagination={{ pageSize: 10 }}
onReset={onReset}
scroll={{ x: '100%', y: 430 }}
/>
<ClaimDescription
refresh={refreshTable}
claimVisible={claimVisible}
wrappedComponentRef={actionRef}
closeClaimDescription={closeClaimDescription}
/>
<Image
width={200}
style={{ display: 'none' }}
src={imagePreView.src}
preview={{
visible: imagePreView.visible,
scaleStep: '1',
src: imagePreView.src,
onVisibleChange: value => {
setImagePreView({
src: '',
visible: false,
});
},
}}
/>
</PageHeaderWrapper>
);
};
export default AfterSalesClaimForm;
import request from '@/utils/request';
import config from '@/../config/env.config';
export const getQueryClamsList = params =>
request.post('/api/kdsp/queryClams', {
prefix: config.goodsApi,
data: params || {},
});
import React from 'react';
import { Image as ImageComponent, Button } from 'antd';
export const getLastItem = thePath => thePath.substring(thePath.lastIndexOf('/') + 1);
export const isImageType = url => {
const index = url.lastIndexOf('.');
const ext = url.substr(index + 1);
return ['png', 'jpg', 'jpeg', 'bmp', 'gif', 'webp', 'psd', 'svg', 'tiff'].includes(
ext.toLowerCase(),
);
};
export const checkImage = url =>
new Promise(resolve => {
const image = new Image();
image.onload = () => {
resolve(true);
};
image.onerror = () => {
resolve(false);
};
image.src = url;
});
const csListStyle = {
color: '#1890FF',
textAlign: 'left',
whiteSpace: 'nowrap',
textOverflow: 'ellipsis',
overflow: 'hidden',
cursor: 'pointer',
};
export const typeConfig = {
1: {
text: '退运费',
},
2: {
text: '商品破损',
},
};
const singleNumberSearch = {
0: {
text: '赔款单号',
},
1: {
text: '订单编号',
},
};
export const columnsConfig = props => [
{
title: '单号搜索',
key: 'singleType',
dataIndex: 'singleType',
hideInTable: true,
valueEnum: singleNumberSearch,
},
{
key: 'singleNumber',
dataIndex: 'singleNumber',
hideInTable: true,
},
{
title: '赔款单号',
key: 'id',
dataIndex: 'id',
align: 'center',
hideInSearch: true,
},
{
title: '订单号',
key: 'orderNo',
dataIndex: 'orderNo',
align: 'center',
hideInSearch: true,
},
{
title: '赔款金额',
key: 'amount',
dataIndex: 'amount',
align: 'center',
width: 100,
hideInSearch: true,
},
{
title: '赔款类型',
key: 'type',
dataIndex: 'type',
align: 'center',
valueEnum: typeConfig,
},
{
title: '索赔原因',
key: 'reason',
dataIndex: 'reason',
align: 'center',
hideInSearch: true,
},
{
title: '退款说明',
key: 'remark',
dataIndex: 'remark',
align: 'center',
ellipsis: true,
hideInSearch: true,
},
{
title: '创建时间',
key: 'createdAt',
dataIndex: 'createdAt',
align: 'center',
valueType: 'dateRange',
},
{
title: '用户凭证',
key: 'proof',
dataIndex: 'proof',
align: 'center',
width: 190,
hideInSearch: true,
render: value =>
(value.userList || []).map(item => (
<ImageComponent style={{ paddingLeft: 5, marginTop: 5 }} key={item} width={50} src={item} />
)),
},
{
title: '审核意见',
key: 'proof',
dataIndex: 'proof',
align: 'center',
width: 190,
hideInSearch: true,
render: value =>
(value.csList || []).map(item => (
<div style={csListStyle} onClick={() => props.downLoadFile(item)}>
{item}
</div>
)),
},
];
...@@ -2,6 +2,7 @@ import { Upload, Icon, Modal, message, Button, notification } from 'antd'; ...@@ -2,6 +2,7 @@ import { Upload, Icon, Modal, message, Button, notification } from 'antd';
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect } from 'react';
import config from '../../../../config/env.config'; import config from '../../../../config/env.config';
import styles from '../style.less'; import styles from '../style.less';
import UUID from '../../../utils/uuid';
import { qiniuToken } from '@/services/qiniu'; import { qiniuToken } from '@/services/qiniu';
const qiniu = require('@/utils/qiniu.min.js'); const qiniu = require('@/utils/qiniu.min.js');
...@@ -60,7 +61,7 @@ class PicturesWall extends React.Component { ...@@ -60,7 +61,7 @@ class PicturesWall extends React.Component {
} }
const vm = this; const vm = this;
// eslint-disable-next-line new-cap // eslint-disable-next-line new-cap
const data = `${filename}-${new Date().getTime()}.${suffix}`; const data = `${UUID.createUUID()}.${suffix}`;
const observable = qiniu.upload(file, data, token); const observable = qiniu.upload(file, data, token);
const observer = { const observer = {
next() { next() {
......
...@@ -104,8 +104,14 @@ export function columns(res, pages) { ...@@ -104,8 +104,14 @@ export function columns(res, pages) {
align: 'center', align: 'center',
}, },
{ {
title: '蓝字金额', title: () => (
<div style={{ textAlign: 'center' }}>
<div>蓝字金额</div>
<div style={{ color: '#f00' }}>(开票金额)</div>
</div>
),
dataIndex: 'currentRefundAmount', dataIndex: 'currentRefundAmount',
key: 'currentRefundAmount',
width: '100px', width: '100px',
hideInSearch: true, hideInSearch: true,
align: 'center', align: 'center',
...@@ -113,9 +119,16 @@ export function columns(res, pages) { ...@@ -113,9 +119,16 @@ export function columns(res, pages) {
{ {
title: '应付金额', title: '应付金额',
dataIndex: 'payableAmount', dataIndex: 'payableAmount',
width: '100px', width: '140px',
hideInSearch: true, hideInSearch: true,
align: 'center', align: 'center',
render: (value, row) => (
<div>
<div>{row.payableAmount}</div>
<div style={{ color: '#f00' }}>赔付 ({row.claimAmount})</div>
<div>(实付 {row.needPayAmount})</div>
</div>
),
}, },
{ {
title: '是否缺少红字发票', title: '是否缺少红字发票',
......
...@@ -68,6 +68,15 @@ export function columns(pages) { ...@@ -68,6 +68,15 @@ export function columns(pages) {
width: '100px', width: '100px',
hideInSearch: true, hideInSearch: true,
align: 'center', align: 'center',
render: (value, row) => {
const msg = row.billType === 20 ? <div>包含赔付金额</div> : null;
return (
<div>
<div>{value}</div>
{msg}
</div>
);
},
}, },
{ {
title: '笔数', title: '笔数',
...@@ -75,6 +84,15 @@ export function columns(pages) { ...@@ -75,6 +84,15 @@ export function columns(pages) {
width: '100px', width: '100px',
hideInSearch: true, hideInSearch: true,
align: 'center', align: 'center',
render: (value, row) => {
const msg = row.billType === 20 ? <div>包含赔付笔数</div> : null;
return (
<div>
<div>{value}</div>
{msg}
</div>
);
},
}, },
{ {
title: '状态', title: '状态',
......
...@@ -75,6 +75,11 @@ ...@@ -75,6 +75,11 @@
.pictureWrapper { .pictureWrapper {
position: relative; position: relative;
:global {
.ant-form-item-label > label {
word-break: break-all;
}
}
} }
.pullImage { .pullImage {
position: absolute; position: absolute;
......
import React, { useState } from 'react'; import React from 'react';
import { Select, Form, InputNumber, Input, Button, Popover } from 'antd'; import { Select, Form, InputNumber, Input, Button, Popover } from 'antd';
import commonStyle from '../common.less'; import commonStyle from '../common.less';
...@@ -108,7 +108,12 @@ export const CreateFormInput = props => { ...@@ -108,7 +108,12 @@ export const CreateFormInput = props => {
return ( return (
<> <>
{record.skuLink && ( {record.skuLink && (
<Button type="primary" size="small" onClick={() => onClickEvent('cloneImg', record)}> <Button
type="primary"
size="small"
disabled={props.disabled}
onClick={() => onClickEvent('cloneImg', record)}
>
拉图片 拉图片
</Button> </Button>
)} )}
......
...@@ -120,7 +120,18 @@ const EditFormTable = forwardRef((props, ref) => { ...@@ -120,7 +120,18 @@ const EditFormTable = forwardRef((props, ref) => {
tableList: newDataSource, tableList: newDataSource,
}); });
}; };
const onClickEvent = () => {}; const onClickEvent = (type, row) => {
// 点击拉取京东图片功能
if (type === 'cloneImg') {
customer.onEventBus(type, row);
return;
}
// 修改sku名称
if (type === 'updateName') {
rowOnClickEvent(row);
}
};
useImperativeHandle(ref, () => ({ useImperativeHandle(ref, () => ({
onCheck, onCheck,
...@@ -179,8 +190,8 @@ const EditFormTable = forwardRef((props, ref) => { ...@@ -179,8 +190,8 @@ const EditFormTable = forwardRef((props, ref) => {
<Form form={form} scrollToFirstError component={false} onValuesChange={getFormValues}> <Form form={form} scrollToFirstError component={false} onValuesChange={getFormValues}>
<EditableContext.Provider value={form}> <EditableContext.Provider value={form}>
<Table <Table
scroll={{ y: 300, x: 1000 }} scroll={{ y: 320, x: 1000 }}
height={300} height={320}
pagination={false} pagination={false}
size="small" size="small"
bordered bordered
......
...@@ -93,6 +93,9 @@ const FormAttr = forwardRef((props, ref) => { ...@@ -93,6 +93,9 @@ const FormAttr = forwardRef((props, ref) => {
setInitAttrData(initValue.initValue); setInitAttrData(initValue.initValue);
setCategoryAttrs(res.data); setCategoryAttrs(res.data);
}); });
} else {
setInitAttrData({});
setCategoryAttrs([]);
} }
}; };
...@@ -169,6 +172,9 @@ const FormAttr = forwardRef((props, ref) => { ...@@ -169,6 +172,9 @@ const FormAttr = forwardRef((props, ref) => {
const ids = props.categoryIds; const ids = props.categoryIds;
if (ids && ids.length) { if (ids && ids.length) {
getAttribute(ids[ids.length - 1]); getAttribute(ids[ids.length - 1]);
} else {
setInitAttrData({});
setCategoryAttrs([]);
} }
}, [props.categoryIds]); }, [props.categoryIds]);
......
...@@ -97,6 +97,7 @@ const FormInformationBasic = forwardRef((props, ref) => { ...@@ -97,6 +97,7 @@ const FormInformationBasic = forwardRef((props, ref) => {
> >
<Cascader <Cascader
placeholder="请选择商品类目!" placeholder="请选择商品类目!"
disabled={customer.isEdit && customer.isNormal}
showSearch={{ filter: filterCategoryOptions }} showSearch={{ filter: filterCategoryOptions }}
fieldNames={{ label: 'name', value: 'id', children: 'children' }} fieldNames={{ label: 'name', value: 'id', children: 'children' }}
onChange={props.onCategoryChange} onChange={props.onCategoryChange}
...@@ -111,8 +112,8 @@ const FormInformationBasic = forwardRef((props, ref) => { ...@@ -111,8 +112,8 @@ const FormInformationBasic = forwardRef((props, ref) => {
extra="若需新增品牌请联系业务员" extra="若需新增品牌请联系业务员"
> >
<Select <Select
disabled={customer.isService}
showSearch showSearch
disabled={customer.isDisabled}
placeholder="请选择商品品牌" placeholder="请选择商品品牌"
filterOption={fileterBrandOptions} filterOption={fileterBrandOptions}
> >
...@@ -131,14 +132,9 @@ const FormInformationBasic = forwardRef((props, ref) => { ...@@ -131,14 +132,9 @@ const FormInformationBasic = forwardRef((props, ref) => {
{ required: true, min: 2, message: '请输入最少两个字符的商品名称!', whitespace: true }, { required: true, min: 2, message: '请输入最少两个字符的商品名称!', whitespace: true },
]} ]}
> >
<Input placeholder="请输入商品名称" /> <Input placeholder="请输入商品名称" disabled={customer.isDisabled} />
</Form.Item> </Form.Item>
</Popover> </Popover>
{customer.isJDGoods && (
<Button key="jdMsg" danger type="text">
*本列表的商品名称仅供搜索使用,不在前端作展示。若要修改APP端展示的商品名称,请在商品信息中修改。
</Button>
)}
{!customer.isCard && ( {!customer.isCard && (
<Form.Item <Form.Item
name="character" name="character"
......
...@@ -59,7 +59,7 @@ const SpecificationTemplate = (props, _) => { ...@@ -59,7 +59,7 @@ const SpecificationTemplate = (props, _) => {
const handleChange = (val, option) => { const handleChange = (val, option) => {
const optionSpecName = option ? option.specName : null; const optionSpecName = option ? option.specName : null;
form.setFieldsValue({ [selectName]: optionSpecName }); form.setFieldsValue({ [selectName]: optionSpecName });
// onChange(); onChange();
}; };
const inputOnblurEvent = event => { const inputOnblurEvent = event => {
...@@ -78,11 +78,14 @@ const SpecificationTemplate = (props, _) => { ...@@ -78,11 +78,14 @@ const SpecificationTemplate = (props, _) => {
return; return;
} }
addCallback(); addCallback();
onChange();
}; };
const bundlePlusRemoveSpecEvent = (removeCallback, fieldName) => { const bundlePlusRemoveSpecEvent = (removeCallback, fieldName) => {
removeCallback(fieldName); removeCallback(fieldName);
form.setFieldsValue({
bacthFirst: undefined,
bacthSecon: undefined,
});
const timer = setTimeout(() => { const timer = setTimeout(() => {
onChange(); onChange();
clearTimeout(timer); clearTimeout(timer);
...@@ -93,7 +96,7 @@ const SpecificationTemplate = (props, _) => { ...@@ -93,7 +96,7 @@ const SpecificationTemplate = (props, _) => {
<> <>
<Form.Item name={formName} label={label}> <Form.Item name={formName} label={label}>
<Select <Select
disabled={customer.isEdit} disabled={customer.isEdit && customer.isNormal}
allowClear allowClear
options={specList} options={specList}
style={{ width: 200 }} style={{ width: 200 }}
...@@ -115,8 +118,9 @@ const SpecificationTemplate = (props, _) => { ...@@ -115,8 +118,9 @@ const SpecificationTemplate = (props, _) => {
{fields.map((field, index) => ( {fields.map((field, index) => (
<Form.Item key={field.key} noStyle shouldUpdate={(prevValues, curValues) => false}> <Form.Item key={field.key} noStyle shouldUpdate={(prevValues, curValues) => false}>
{() => ( {() => (
<Space key={field.key} align="baseline"> <Space key={`space_${field.key}`} align="baseline">
<Form.Item <Form.Item
key={`item_${field.key}`}
style={{ marginLeft: 10 }} style={{ marginLeft: 10 }}
name={[field.name, specName]} name={[field.name, specName]}
rules={[ rules={[
...@@ -144,6 +148,7 @@ const SpecificationTemplate = (props, _) => { ...@@ -144,6 +148,7 @@ const SpecificationTemplate = (props, _) => {
</Form.Item> </Form.Item>
{!(specDataList[index] && specDataList[index].id) && ( {!(specDataList[index] && specDataList[index].id) && (
<MinusCircleOutlined <MinusCircleOutlined
key={`minus_${field.key}`}
onClick={() => bundlePlusRemoveSpecEvent(remove, field.name)} onClick={() => bundlePlusRemoveSpecEvent(remove, field.name)}
/> />
)} )}
...@@ -151,8 +156,8 @@ const SpecificationTemplate = (props, _) => { ...@@ -151,8 +156,8 @@ const SpecificationTemplate = (props, _) => {
)} )}
</Form.Item> </Form.Item>
))} ))}
{fields.length < 3 && ( {(!customer.isCard || fields.length < 3) && !customer.isDisabled && (
<Form.Item noStyle> <Form.Item noStyle key="btnpush">
<Button <Button
style={{ marginLeft: 10, marginBottom: 24 }} style={{ marginLeft: 10, marginBottom: 24 }}
type="dashed" type="dashed"
...@@ -203,7 +208,12 @@ const CreateBatchFormItems = ({ specInitValue, batchChange, editRef, defaultColu ...@@ -203,7 +208,12 @@ const CreateBatchFormItems = ({ specInitValue, batchChange, editRef, defaultColu
fieldNames={{ label: 'secondSpecValue', value: 'secondSpecValue' }} fieldNames={{ label: 'secondSpecValue', value: 'secondSpecValue' }}
/> />
{formItems.concat( {formItems.concat(
<Button key="batch" type="primary" onClick={batchChange}> <Button
key="batch"
type="primary"
disabled={customer.isEdit && customer.isNormal}
onClick={batchChange}
>
批量设置 批量设置
</Button>, </Button>,
)} )}
...@@ -226,6 +236,24 @@ const FormPriceOrStock = forwardRef((props, ref) => { ...@@ -226,6 +236,24 @@ const FormPriceOrStock = forwardRef((props, ref) => {
const [tableData, setTableData] = useState([]); const [tableData, setTableData] = useState([]);
const [mergeTable, setMergeTable] = useState(false); const [mergeTable, setMergeTable] = useState(false);
const insertSpecID = items => {
const sids = items.filter(item => item.id);
if (sids.length !== skuList.length) {
let i = 0;
const ids = skuList.reduce((prev, cur) => {
if (!sids.includes(cur.id)) {
prev.push(cur.id);
}
return prev;
}, []);
items.forEach(item => {
if (!item.id && i < ids.length) {
item.id = ids[i++];
}
});
}
};
const onCheck = async () => { const onCheck = async () => {
try { try {
let setMealContent = ''; let setMealContent = '';
...@@ -233,6 +261,14 @@ const FormPriceOrStock = forwardRef((props, ref) => { ...@@ -233,6 +261,14 @@ const FormPriceOrStock = forwardRef((props, ref) => {
setMealContent = await packageRef.current.onCheck(); setMealContent = await packageRef.current.onCheck();
} }
const values = await form.validateFields(); const values = await form.validateFields();
if (!values.firstSpecValue || !values.firstSpecValue.length) {
values.firstSpecId = null;
values.firstSpec = '';
}
if (!values.secondSpecValue || !values.secondSpecValue.length) {
values.secondSpecId = null;
values.secondSpec = '';
}
const items = await editRef.current.onCheck(); const items = await editRef.current.onCheck();
if (customer.isCard && !setMealContent) { if (customer.isCard && !setMealContent) {
notification.open({ notification.open({
...@@ -241,7 +277,10 @@ const FormPriceOrStock = forwardRef((props, ref) => { ...@@ -241,7 +277,10 @@ const FormPriceOrStock = forwardRef((props, ref) => {
}); });
return null; return null;
} }
if (items) { if (items && items.length) {
if (customer.isEdit && skuList.length) {
insertSpecID(items);
}
const obj = { ...values, items, temp: 'infoSpecData' }; const obj = { ...values, items, temp: 'infoSpecData' };
customer.isCard && setMealContent && (obj.setMealContent = setMealContent); customer.isCard && setMealContent && (obj.setMealContent = setMealContent);
return obj; return obj;
...@@ -278,7 +317,6 @@ const FormPriceOrStock = forwardRef((props, ref) => { ...@@ -278,7 +317,6 @@ const FormPriceOrStock = forwardRef((props, ref) => {
inputType: 'text', inputType: 'text',
}); });
} }
const dynamicColumns = [...columsData, ...StaticColumns(customer)]; const dynamicColumns = [...columsData, ...StaticColumns(customer)];
setDefaultColumns(dynamicColumns); setDefaultColumns(dynamicColumns);
}; };
...@@ -289,8 +327,10 @@ const FormPriceOrStock = forwardRef((props, ref) => { ...@@ -289,8 +327,10 @@ const FormPriceOrStock = forwardRef((props, ref) => {
const cleanValues = { const cleanValues = {
firstValues: cleanArray(values.firstSpecValue || []), firstValues: cleanArray(values.firstSpecValue || []),
secondValues: cleanArray(values.secondSpecValue || []), secondValues: cleanArray(values.secondSpecValue || []),
firstSpecId: values.firstSpecId, firstSpecId:
secondSpecId: values.secondSpecId, values.firstSpecValue && values.firstSpecValue.length ? values.firstSpecId : null,
secondSpecId:
values.secondSpecValue && values.secondSpecValue.length ? values.secondSpecId : null,
}; };
const { inIdList: fisrtInIdList, noIdList: fisrtNoIdList } = filterSkuNotIdList( const { inIdList: fisrtInIdList, noIdList: fisrtNoIdList } = filterSkuNotIdList(
...@@ -299,7 +339,6 @@ const FormPriceOrStock = forwardRef((props, ref) => { ...@@ -299,7 +339,6 @@ const FormPriceOrStock = forwardRef((props, ref) => {
const { inIdList: secndInIdList, noIdList: secndNoIdList } = filterSkuNotIdList( const { inIdList: secndInIdList, noIdList: secndNoIdList } = filterSkuNotIdList(
cleanValues.secondValues, cleanValues.secondValues,
); );
const createSkuList = createProductData( const createSkuList = createProductData(
{ {
firstSpecId: cleanValues.firstSpecId, firstSpecId: cleanValues.firstSpecId,
...@@ -310,23 +349,25 @@ const FormPriceOrStock = forwardRef((props, ref) => { ...@@ -310,23 +349,25 @@ const FormPriceOrStock = forwardRef((props, ref) => {
secndNoIdList, secndNoIdList,
}, },
customer.isEdit, customer.isEdit,
skuList,
); );
CreateColumnsEvent(values); CreateColumnsEvent(values);
// 没有规格默认创建一条数据
if (!cleanValues.firstSpecId && !createSkuList.secondSpecId) { if (!cleanValues.firstSpecId && !createSkuList.secondSpecId) {
setTableData([...createSkuList]); setTableData([...createSkuList]);
return; return;
} }
// 是否合并单元格
setMergeTable(Boolean(cleanValues.secondValues.length)); setMergeTable(Boolean(cleanValues.secondValues.length));
setTableData(fliterSkuListSortData([...skuList, ...createSkuList])); setTableData(fliterSkuListSortData([...createSkuList]));
} catch (error) { } catch (error) {
console.log(error); console.log(error);
} }
}; };
const batchChange = () => { const batchChange = () => {
const batchItem = form.getFieldValue('batchItem'); const values = form.getFieldsValue();
const bacthFirst = form.getFieldValue('bacthFirst'); const { batchItem, bacthFirst, bacthSecon } = values;
const bacthSecon = form.getFieldValue('bacthSecon');
const resetObject = batchTableSourceData({ batchItem, tableData, bacthSecon, bacthFirst }); const resetObject = batchTableSourceData({ batchItem, tableData, bacthSecon, bacthFirst });
props.onValuesChange({ tableList: resetObject }); props.onValuesChange({ tableList: resetObject });
setTableData(resetObject); setTableData(resetObject);
...@@ -335,6 +376,8 @@ const FormPriceOrStock = forwardRef((props, ref) => { ...@@ -335,6 +376,8 @@ const FormPriceOrStock = forwardRef((props, ref) => {
const onSpecificationEvent = async () => { const onSpecificationEvent = async () => {
try { try {
const values = await form.validateFields(); const values = await form.validateFields();
console.log('values :>> ', values);
console.log('cleanArray(values.secondSpecValue) :>> ', cleanArray(values.secondSpecValue));
const cleanValues = { const cleanValues = {
firstSpec: values.firstSpec, firstSpec: values.firstSpec,
firstSpecId: values.firstSpecId, firstSpecId: values.firstSpecId,
...@@ -360,10 +403,12 @@ const FormPriceOrStock = forwardRef((props, ref) => { ...@@ -360,10 +403,12 @@ const FormPriceOrStock = forwardRef((props, ref) => {
); );
onSpecChange(firstSpecValueList); onSpecChange(firstSpecValueList);
} }
onFinish();
}; };
const seconOnChangeEvent = async () => { const seconOnChangeEvent = async () => {
await onSpecificationEvent(); await onSpecificationEvent();
onFinish();
}; };
useImperativeHandle(ref, () => ({ useImperativeHandle(ref, () => ({
...@@ -417,16 +462,18 @@ const FormPriceOrStock = forwardRef((props, ref) => { ...@@ -417,16 +462,18 @@ const FormPriceOrStock = forwardRef((props, ref) => {
specList={specList} specList={specList}
specDataList={specInitValue.secondSpecValue} specDataList={specInitValue.secondSpecValue}
/> />
<div style={{ display: 'flex', justifyContent: 'center', marginBottom: 20 }}> {/* <div style={{ display: 'flex', justifyContent: 'center', marginBottom: 20 }}>
<Button type="primary" onClick={onFinish}> <Button type="primary" onClick={onFinish}>
生成商品信息 生成商品信息
</Button> </Button>
</div> */}
<div>
<CreateBatchFormItems
batchChange={batchChange}
specInitValue={specInitValue}
defaultColumns={defaultColumns}
/>
</div> </div>
<CreateBatchFormItems
batchChange={batchChange}
specInitValue={specInitValue}
defaultColumns={defaultColumns}
/>
</Form> </Form>
<EditFormTable <EditFormTable
ref={editRef} ref={editRef}
......
...@@ -98,19 +98,14 @@ const FormRuleSetting = forwardRef((props, ref) => { ...@@ -98,19 +98,14 @@ const FormRuleSetting = forwardRef((props, ref) => {
> >
<Form.Item name="purchaseTime" label="购买时间" {...rangeConfig}> <Form.Item name="purchaseTime" label="购买时间" {...rangeConfig}>
<RangePicker <RangePicker
showTime={{
defaultValue: [moment('00:00:00', 'HH:mm:ss'), moment('23:59:59', 'HH:mm:ss')],
}}
format="YYYY-MM-DD HH:mm:ss" format="YYYY-MM-DD HH:mm:ss"
defaultPickerValue={[nowDateTime, nowDateTimeEnd]} defaultPickerValue={[nowDateTime, nowDateTimeEnd]}
/> />
</Form.Item> </Form.Item>
<Form.Item name="useTime" label="有效期" {...rangeConfig}> <Form.Item name="useTime" label="有效期" {...rangeConfig}>
<RangePicker <RangePicker
showTime={{
defaultValue: [moment('00:00:00', 'HH:mm:ss'), moment('23:59:59', 'HH:mm:ss')],
}}
format="YYYY-MM-DD HH:mm:ss" format="YYYY-MM-DD HH:mm:ss"
defaultPickerValue={[nowDateTime, nowDateTimeEnd]}
/> />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
......
/* eslint-disable guard-for-in */
/* eslint-disable no-restricted-syntax */
import React, { useState, useEffect, useContext, forwardRef, useImperativeHandle } from 'react'; import React, { useState, useEffect, useContext, forwardRef, useImperativeHandle } from 'react';
import { Form, Button } from 'antd'; import { Form, Button } from 'antd';
import { ServiceContext } from '../context'; import { ServiceContext } from '../context';
...@@ -73,7 +75,16 @@ const FormRuleVPictures = forwardRef((props, ref) => { ...@@ -73,7 +75,16 @@ const FormRuleVPictures = forwardRef((props, ref) => {
useImperativeHandle(ref, () => ({ useImperativeHandle(ref, () => ({
onCheck, onCheck,
setFieldsValue: form.setFieldsValue, setFieldsValue: obj => {
setDetailImageList(obj.detailImageList || []);
for (const key in obj.imageList) {
if (!obj.imageList[key]) {
obj.imageList[key] = [];
}
}
setImageList(obj.imageList || {});
form.setFieldsValue(obj);
},
getFieldsValue: form.getFieldsValue, getFieldsValue: form.getFieldsValue,
reset: () => { reset: () => {
form.resetFields(); form.resetFields();
...@@ -106,6 +117,14 @@ const FormRuleVPictures = forwardRef((props, ref) => { ...@@ -106,6 +117,14 @@ const FormRuleVPictures = forwardRef((props, ref) => {
}); });
}; };
// 拉取公共图片
const onPullCommonImg = key => {
const cimg = form.getFieldValue('commonImageList');
const obj = { ...imageList };
obj[key] = cimg;
setImageList(obj);
};
const onDetailSuccessImageList = imgList => { const onDetailSuccessImageList = imgList => {
setDetailImageList(imgList); setDetailImageList(imgList);
form.setFieldsValue({ form.setFieldsValue({
...@@ -116,7 +135,10 @@ const FormRuleVPictures = forwardRef((props, ref) => { ...@@ -116,7 +135,10 @@ const FormRuleVPictures = forwardRef((props, ref) => {
return ( return (
<Form <Form
form={form} form={form}
{...formItemLayout} labelCol={{ flex: '110px' }}
labelAlign="right"
labelWrap
colon
initialValues={{ initialValues={{
commonImageList: [], commonImageList: [],
cardImageList: [], cardImageList: [],
...@@ -150,9 +172,12 @@ const FormRuleVPictures = forwardRef((props, ref) => { ...@@ -150,9 +172,12 @@ const FormRuleVPictures = forwardRef((props, ref) => {
]} ]}
> >
<UploadImage <UploadImage
disabled={customer.isService} multiple={!customer.isCard}
multiple={false} maxWidth={customer.isCard ? 0 : 1200}
maxHeight={customer.isCard ? 0 : 1200}
superTips="公共滑动图尺寸不可大于 1200*1200"
name="commonImageList" name="commonImageList"
disabled={customer.isDisabled}
limit={imgConfig.commonImageList.limit} limit={imgConfig.commonImageList.limit}
pictures={commonImageList} pictures={commonImageList}
setPictureList={list => onCommonSuccessEvent(list)} setPictureList={list => onCommonSuccessEvent(list)}
...@@ -172,9 +197,9 @@ const FormRuleVPictures = forwardRef((props, ref) => { ...@@ -172,9 +197,9 @@ const FormRuleVPictures = forwardRef((props, ref) => {
]} ]}
> >
<UploadImage <UploadImage
disabled={customer.isService}
name="cardImageList" name="cardImageList"
limit={imgConfig.cardImageList.limit} limit={imgConfig.cardImageList.limit}
disabled={customer.isDisabled}
pictures={cardImageList} pictures={cardImageList}
setPictureList={list => onCardSuccessImageList(list)} setPictureList={list => onCardSuccessImageList(list)}
/> />
...@@ -193,16 +218,23 @@ const FormRuleVPictures = forwardRef((props, ref) => { ...@@ -193,16 +218,23 @@ const FormRuleVPictures = forwardRef((props, ref) => {
extra={imgConfig.imageList.renderExtra()} extra={imgConfig.imageList.renderExtra()}
> >
<UploadImage <UploadImage
disabled={customer.isService}
name={key} name={key}
limit={11} limit={11}
disabled={customer.isDisabled}
pictures={imageList[key]} pictures={imageList[key]}
setPictureList={list => onPictureSuccessEvent(list, key)} setPictureList={list => onPictureSuccessEvent(list, key)}
/> />
</Form.Item> </Form.Item>
<Button className={commonStyle.pullImage} type="primary"> {!imageList[key]?.length && (
拉取公共图 <Button
</Button> disabled={imageList[key]?.length}
className={commonStyle.pullImage}
onClick={() => onPullCommonImg(key)}
type="primary"
>
拉取公共图
</Button>
)}
</div> </div>
))} ))}
<Form.Item <Form.Item
...@@ -218,9 +250,11 @@ const FormRuleVPictures = forwardRef((props, ref) => { ...@@ -218,9 +250,11 @@ const FormRuleVPictures = forwardRef((props, ref) => {
extra={imgConfig.detailImageList.renderExtra()} extra={imgConfig.detailImageList.renderExtra()}
> >
<UploadImage <UploadImage
disabled={customer.isService}
limit={imgConfig.detailImageList.limit} limit={imgConfig.detailImageList.limit}
maxWidth={customer.isCard ? 0 : 800}
superTips="详情图宽度不可大于800"
name="detailImageList" name="detailImageList"
disabled={customer.isDisabled}
pictures={detailImageList} pictures={detailImageList}
setPictureList={list => onDetailSuccessImageList(list)} setPictureList={list => onDetailSuccessImageList(list)}
/> />
......
...@@ -72,26 +72,83 @@ const UploadImage = forwardRef((props, ref) => { ...@@ -72,26 +72,83 @@ const UploadImage = forwardRef((props, ref) => {
const freshFiles = fileList?.filter(ele => ele.uid !== file.uid); const freshFiles = fileList?.filter(ele => ele.uid !== file.uid);
bundleChange(freshFiles); bundleChange(freshFiles);
}; };
const checkFile = file =>
new Promise(resolve => { const cleanArray = (actual = []) =>
const curType = file.name.substr(file.name.lastIndexOf('.') + 1).toLowerCase(); actual.reduce((prev, cur) => {
const fileType = ['jpg', 'jpeg', 'png']; cur && prev.push(cur);
if (!fileType.includes(curType)) { return prev;
notification.open({ }, []);
message: file.name,
description: '图片格式须为jpg、jpeg、png!', const warningTip = description => {
}); notification.warning({
return resolve(null); message: '图片上传失败',
description,
});
};
const getBase64 = (img, callback) => {
const reader = new FileReader();
reader.addEventListener('load', () => callback(reader.result));
reader.readAsDataURL(img);
};
const ImageInfo = file =>
new Promise((resolve, reject) => {
const LtMB = file.size / 1024 / 1024;
if (LtMB > 2) {
warningTip(`[${file.name}] 图片不可以大于2MB`);
resolve(null);
} }
if (file.size > MAX_FILE_SIZE * UNIT) { getBase64(file, url => {
notification.open({ const image = new Image();
message: file.name, image.addEventListener('load', () => {
description: `单个图片大小不能超过${MAX_FILE_SIZE}M!`, const { width } = image;
const { height } = image;
file.width = width;
file.height = height;
file.LtMB = LtMB;
resolve(file);
});
image.addEventListener('error', () => {
warningTip(`${file.name}图片上传失败!`);
resolve(null);
}); });
return resolve(null); image.src = url;
});
});
const CheckImageInfoList = async files => {
const promiseImage = files.map(file => ImageInfo(file));
const clearImage = await Promise.all(promiseImage);
return cleanArray(clearImage);
};
const isUploadNext = async imgFileList => {
const filterImage = imgFileList.filter(img => {
if (
(imgOptions.maxWidth && img.width > imgOptions.maxWidth) ||
(imgOptions.maxHeight && img.height > imgOptions.maxHeight)
) {
warningTip(`[${img.name}] ${imgOptions.superTips}`);
return false;
}
return true;
});
return filterImage;
};
const checkFile = files => {
const fileType = ['jpg', 'jpeg', 'png'];
const filterImage = files.filter(file => {
const curType = file.name.substr(file.name.lastIndexOf('.') + 1).toLowerCase();
if (!fileType.includes(curType)) {
warningTip('图片格式须为jpg、jpeg、png!');
return false;
} }
return resolve(file); return true;
}); });
return filterImage;
};
const imageLoading = (file, ret) => const imageLoading = (file, ret) =>
new Promise(resolve => { new Promise(resolve => {
...@@ -119,12 +176,14 @@ const UploadImage = forwardRef((props, ref) => { ...@@ -119,12 +176,14 @@ const UploadImage = forwardRef((props, ref) => {
}); });
return Upload.LIST_IGNORE; return Upload.LIST_IGNORE;
} }
const fileAll = fileArray.map(item => checkFile(item)); const flies = checkFile(fileArray);
const checkFiles = (await Promise.all(fileAll)).filter(item => item !== null); const optionsArray = await CheckImageInfoList(flies);
const checkFiles = await isUploadNext(optionsArray);
try { try {
if (checkFiles.length) { if (checkFiles.length) {
setUploadLoading(true); setUploadLoading(true);
const res = await merchantUpload(checkFiles); const res = await merchantUpload(checkFiles);
console.log('res :>> ', res);
if (res.data) { if (res.data) {
const proFiles = (res.data || []).map((urlItem, urlIndex) => const proFiles = (res.data || []).map((urlItem, urlIndex) =>
imageLoading(checkFiles[urlIndex], urlItem), imageLoading(checkFiles[urlIndex], urlItem),
...@@ -176,10 +235,12 @@ const UploadImage = forwardRef((props, ref) => { ...@@ -176,10 +235,12 @@ const UploadImage = forwardRef((props, ref) => {
onClick={() => handlePreview(item)} onClick={() => handlePreview(item)}
/> */} /> */}
<EyeOutlined className={styles.maskIcon} onClick={() => handlePreview(item)} /> <EyeOutlined className={styles.maskIcon} onClick={() => handlePreview(item)} />
<DeleteOutlined {!disabled && (
className={styles.maskIcon} <DeleteOutlined
onClick={() => handleRemove(item)} className={styles.maskIcon}
/> onClick={() => handleRemove(item)}
/>
)}
{/* <Icon {/* <Icon
type="delete" type="delete"
className={styles.maskIcon} className={styles.maskIcon}
......
...@@ -58,34 +58,6 @@ export const TaskList = (canAddService, canAddNormal) => [ ...@@ -58,34 +58,6 @@ export const TaskList = (canAddService, canAddNormal) => [
}, },
}, },
}, },
// {
// name: '电子卡卷',
// type: 3,
// desc: '无需物流',
// hide: true,
// imgConfig: {
// commonImageList: {
// title: '封面图片',
// rule: true,
// limit: 11,
// renderExtra(leng) {
// return `建议尺寸: ##宽##高 (${leng} / 1) `;
// },
// },
// imageList: {
// rule: true,
// limit: 1,
// },
// detailImageList: {
// title: '商品图片',
// rule: true,
// limit: null,
// renderExtra() {
// return '请上传商品图!';
// },
// },
// },
// },
{ {
name: '电子卡卷', name: '电子卡卷',
type: 4, type: 4,
...@@ -166,7 +138,7 @@ export const StaticColumns = customer => [ ...@@ -166,7 +138,7 @@ export const StaticColumns = customer => [
min: 0, min: 0,
}, },
roleRules: { required: true }, roleRules: { required: true },
disabeldRender: () => customer.isJDGoods, disabeldRender: () => customer.isDisabled,
}, },
{ {
title: '佣金费率', title: '佣金费率',
...@@ -189,7 +161,7 @@ export const StaticColumns = customer => [ ...@@ -189,7 +161,7 @@ export const StaticColumns = customer => [
min: 0, min: 0,
}, },
roleRules: { required: true }, roleRules: { required: true },
// disabeldRender: () => customer.isService, disabeldRender: () => customer.isDisabled,
}, },
{ {
title: '销售价', title: '销售价',
...@@ -202,6 +174,7 @@ export const StaticColumns = customer => [ ...@@ -202,6 +174,7 @@ export const StaticColumns = customer => [
precision: 2, precision: 2,
min: 0, min: 0,
}, },
disabeldRender: () => customer.isDisabled,
}, },
{ {
title: '重量(kg)', title: '重量(kg)',
...@@ -220,7 +193,7 @@ export const StaticColumns = customer => [ ...@@ -220,7 +193,7 @@ export const StaticColumns = customer => [
precision: 3, precision: 3,
max: 999999.999, max: 999999.999,
}, },
// disabeldRender: () => customer.isService, disabeldRender: () => customer.isDisabled,
}, },
{ {
title: '库存', title: '库存',
...@@ -237,7 +210,10 @@ export const StaticColumns = customer => [ ...@@ -237,7 +210,10 @@ export const StaticColumns = customer => [
min: 0, min: 0,
}, },
roleRules: { required: true }, roleRules: { required: true },
disabeldRender: v => v.id && customer.isService, disabeldRender: record => {
if (record.stock === null) return false;
return customer.isEdit && customer.isNormal;
},
}, },
{ {
title: '库存预警', title: '库存预警',
...@@ -245,13 +221,12 @@ export const StaticColumns = customer => [ ...@@ -245,13 +221,12 @@ export const StaticColumns = customer => [
editable: true, editable: true,
batchRole: [1], batchRole: [1],
role: [1, 4], role: [1, 4],
roleRules: { required: true },
roleProps: { roleProps: {
min: 0, min: 0,
precision: 0, precision: 0,
maxLength: 5, maxLength: 5,
}, },
// disabeldRender: () => customer.isService, disabeldRender: () => customer.isDisabled,
}, },
{ {
title: '商品自编码', title: '商品自编码',
...@@ -260,7 +235,7 @@ export const StaticColumns = customer => [ ...@@ -260,7 +235,7 @@ export const StaticColumns = customer => [
role: [1, 2], role: [1, 2],
inputType: 'input', inputType: 'input',
roleRules: { required: true }, roleRules: { required: true },
disabeldRender: () => customer.isService, disabeldRender: () => customer.isDisabled,
}, },
{ {
title: '京东链接', title: '京东链接',
...@@ -269,7 +244,7 @@ export const StaticColumns = customer => [ ...@@ -269,7 +244,7 @@ export const StaticColumns = customer => [
role: [1, 2], role: [1, 2],
inputType: 'input', inputType: 'input',
roleRules: { required: false }, roleRules: { required: false },
disabeldRender: () => customer.isService, disabeldRender: () => customer.isDisabled,
}, },
{ {
title: 'sku名称', title: 'sku名称',
...@@ -278,6 +253,7 @@ export const StaticColumns = customer => [ ...@@ -278,6 +253,7 @@ export const StaticColumns = customer => [
role: customer.isEdit && customer.isJDGoods ? [1, 2] : [], role: customer.isEdit && customer.isJDGoods ? [1, 2] : [],
inputType: 'btnText', inputType: 'btnText',
roleRules: { required: false }, roleRules: { required: false },
disabeldRender: () => customer.isDisabled,
}, },
{ {
title: '操作', title: '操作',
...@@ -287,8 +263,10 @@ export const StaticColumns = customer => [ ...@@ -287,8 +263,10 @@ export const StaticColumns = customer => [
inputType: 'option', inputType: 'option',
roleProps: { roleProps: {
isJDGoods: customer.isJDGoods, isJDGoods: customer.isJDGoods,
disabled: customer.isDisabled,
min: 0, min: 0,
}, },
roleRules: { required: false }, roleRules: { required: false },
disabeldRender: () => customer.isDisabled,
}, },
]; ];
...@@ -73,6 +73,7 @@ const ServiceGoods = options => { ...@@ -73,6 +73,7 @@ const ServiceGoods = options => {
const productChange = task => { const productChange = task => {
setProductType(task.type); setProductType(task.type);
setPageLoading(true); setPageLoading(true);
setCategoryIds([]);
const timer = setTimeout(() => { const timer = setTimeout(() => {
setPageLoading(false); setPageLoading(false);
resetForm(); resetForm();
...@@ -154,6 +155,7 @@ const ServiceGoods = options => { ...@@ -154,6 +155,7 @@ const ServiceGoods = options => {
const submitEvent = async () => { const submitEvent = async () => {
const checkPromiseList = clearCurrent(checkFormList).map(({ current }) => current.onCheck()); const checkPromiseList = clearCurrent(checkFormList).map(({ current }) => current.onCheck());
const resuslt = await Promise.all(checkPromiseList); const resuslt = await Promise.all(checkPromiseList);
console.log('resuslt :>> ', resuslt);
if (!resuslt.includes(null)) { if (!resuslt.includes(null)) {
const params = resuslt.reduce((origin, item) => { const params = resuslt.reduce((origin, item) => {
const { temp, ...other } = item; const { temp, ...other } = item;
...@@ -176,9 +178,8 @@ const ServiceGoods = options => { ...@@ -176,9 +178,8 @@ const ServiceGoods = options => {
const detailList = result.detailList || []; const detailList = result.detailList || [];
const newImageList = imageList[result.firstSpecValue]; const newImageList = imageList[result.firstSpecValue];
const carouseList = result.carouseList || []; const carouseList = result.carouseList || [];
imageList[result.firstSpecValue] = newImageList imageList[result.firstSpecValue] =
? [...newImageList, ...carouseList] (newImageList ? [...newImageList, ...carouseList] : carouseList) || [];
: carouseList;
picturesRef.current.setFieldsValue({ picturesRef.current.setFieldsValue({
imageList, imageList,
detailImageList: [...detailImageList, ...detailList], detailImageList: [...detailImageList, ...detailList],
...@@ -254,7 +255,10 @@ const ServiceGoods = options => { ...@@ -254,7 +255,10 @@ const ServiceGoods = options => {
canAddService, // 是否可以添加服务商品(电子卡券) canAddService, // 是否可以添加服务商品(电子卡券)
canAddNormal, // 是否可以添加实物商品 canAddNormal, // 是否可以添加实物商品
isCard: productType === 4, isCard: productType === 4,
isService: SourceData.state && SourceData.state !== 4, // 0, "商品删除" 1, "新建" 2, "提交审核" 3, "待审核" 4, "驳回" 5, "未上架" 6, "已上架" 7, "已下架"
isNormal: SourceData.state && SourceData.state !== 4, // 商品不是驳回状态
// 当商品进行编辑 & 类型不为电子卡券 & 商品状态不为驳回 禁用当前功能
isDisabled: isEdit && productType !== 4 && SourceData.state && SourceData.state !== 4,
isJDGoods: isEdit && SourceData.pageProductType && +SourceData.pageProductType !== 1, isJDGoods: isEdit && SourceData.pageProductType && +SourceData.pageProductType !== 1,
onEventBus, onEventBus,
}; };
......
...@@ -184,29 +184,38 @@ const createInitSkuItems = () => ({ ...@@ -184,29 +184,38 @@ const createInitSkuItems = () => ({
name: null, name: null,
}); });
export const createSkuListData = (first, second, firstSpecId, secondSpecId) => { const getSecordValue = (firstSpecValue, sec, skuList = []) =>
skuList.find(
sku =>
sku.firstSpecValue === firstSpecValue &&
(!sku.secondSpecValue || sku.secondSpecValue === sec.secondSpecValue),
);
export const createSkuListData = (first, second, firstSpecId, secondSpecId, skuList) => {
const list = []; const list = [];
const skuItem = createInitSkuItems(); const skuItem = createInitSkuItems();
console.log(first, second, firstSpecId, secondSpecId);
if (first && first.length) { if (first && first.length) {
// 一级规格有值时,生成的编辑表格 // 一级规格有值时,生成的编辑表格
first.forEach(fir => { first.forEach(fir => {
const copy = { ...skuItem }; let copy = { ...skuItem };
copy.firstSpecId = firstSpecId; copy.firstSpecId = firstSpecId;
copy.firstSpecValue = fir.firstSpecValue; copy.firstSpecValue = fir.firstSpecValue;
// console.log(copy);
if (second.length) { if (second.length) {
second.forEach(sec => { second.forEach(sec => {
const copySec = { ...copy }; const v = getSecordValue(fir.firstSpecValue, sec, skuList);
const copySec = v || { ...copy };
copySec.secondSpecId = secondSpecId; copySec.secondSpecId = secondSpecId;
copySec.secondSpecValue = sec.secondSpecValue; copySec.secondSpecValue = sec.secondSpecValue;
delete copySec.rowSpanCount;
list.push(copySec); list.push(copySec);
}); });
return; return;
} }
const v = getSecordValue(`${fir.firstSpecValue}`, {}, skuList);
if (v) {
copy = { ...v };
}
list.push(copy); list.push(copy);
}); });
} else if (second && second.length) { } else if (second && second.length) {
...@@ -217,6 +226,8 @@ export const createSkuListData = (first, second, firstSpecId, secondSpecId) => { ...@@ -217,6 +226,8 @@ export const createSkuListData = (first, second, firstSpecId, secondSpecId) => {
copy.secondSpecValue = sec.secondSpecValue; copy.secondSpecValue = sec.secondSpecValue;
list.push(copy); list.push(copy);
}); });
} else if (skuList && skuList.length) {
list.push(...skuList);
} else { } else {
// 缺少一级和二级规格时生成的编辑表格 // 缺少一级和二级规格时生成的编辑表格
list.push(skuItem); list.push(skuItem);
...@@ -224,7 +235,7 @@ export const createSkuListData = (first, second, firstSpecId, secondSpecId) => { ...@@ -224,7 +235,7 @@ export const createSkuListData = (first, second, firstSpecId, secondSpecId) => {
return list; return list;
}; };
export const createProductData = (props, isEdit) => { export const createProductData = (props, isEdit, skuList) => {
const { const {
firstSpecId, firstSpecId,
secondSpecId, secondSpecId,
...@@ -233,21 +244,14 @@ export const createProductData = (props, isEdit) => { ...@@ -233,21 +244,14 @@ export const createProductData = (props, isEdit) => {
fisrtInIdList, fisrtInIdList,
secndInIdList, secndInIdList,
} = props; } = props;
const newFirstList = fisrtNoIdList.concat(fisrtInIdList || []);
let list = []; let list = [];
// if (!isFirstSame && !isSecondSame) { if (isEdit) {
if (!isEdit) { const newFirstList = fisrtNoIdList.concat(fisrtInIdList || []);
list = createSkuListData(fisrtNoIdList, secndNoIdList, firstSpecId, secondSpecId); const newSecondList = secndInIdList.concat(secndNoIdList || []);
list = createSkuListData(newFirstList, newSecondList, firstSpecId, secondSpecId, skuList);
} else { } else {
const list1 = fisrtNoIdList.length list = createSkuListData(fisrtNoIdList, secndNoIdList, firstSpecId, secondSpecId);
? createSkuListData(fisrtNoIdList, secndInIdList, firstSpecId, secondSpecId)
: [];
const list2 = secndNoIdList.length
? createSkuListData(newFirstList, secndNoIdList, firstSpecId, secondSpecId)
: [];
list = [...list1, ...list2];
} }
// }
return list; return list;
}; };
......
...@@ -97,6 +97,12 @@ export function columns(pages) { ...@@ -97,6 +97,12 @@ export function columns(pages) {
width: '100px', width: '100px',
hideInSearch: true, hideInSearch: true,
align: 'center', align: 'center',
render: (value, row) => (
<div>
<div>{value}</div>
<div style={{ color: '#f00' }}>(赔付{row.claimAmount})</div>
</div>
),
}, },
{ {
title: '结算金额', title: '结算金额',
......
...@@ -31,7 +31,7 @@ const LogisticsCom = props => { ...@@ -31,7 +31,7 @@ const LogisticsCom = props => {
// eslint-disable-next-line react/no-array-index-key // eslint-disable-next-line react/no-array-index-key
<Timeline.Item color={index > 0 ? 'gray' : 'blue'} key={index}> <Timeline.Item color={index > 0 ? 'gray' : 'blue'} key={index}>
<p>{item.desc}</p> <p>{item.desc}</p>
<p>{item.logisticsTime}</p> <p>{item.time}</p>
</Timeline.Item> </Timeline.Item>
))} ))}
</Timeline> </Timeline>
......
.sku-list-module {
margin-bottom: 20px;
padding: 10px 20px;
border: 1px solid #f2f2f2;
&__index {
margin-bottom: 5px;
font-weight: 700;
font-size: 14px;
}
}
.sku-list-box {
padding-bottom: 10px;
.sku-list {
display: flex;
// padding-bottom: 19px;
&__goods-name {
flex: 1;
margin-bottom: 0 !important;
}
&__goods-count {
width: 100px;
margin-bottom: 5px !important;
}
}
}
.operation {
font-size: 24px;
text-align: center;
> * {
margin: 0 10px;
}
}
...@@ -12,6 +12,8 @@ import LogisticsForm from './components/LogisticsForm'; ...@@ -12,6 +12,8 @@ import LogisticsForm from './components/LogisticsForm';
import PopoverDom from './components/PreviewImage'; import PopoverDom from './components/PreviewImage';
import LogisticsCom from './components/LogisticsCom'; import LogisticsCom from './components/LogisticsCom';
import DelayDeliverGoods from './components/DelayDeliverGoods'; import DelayDeliverGoods from './components/DelayDeliverGoods';
import MultiLogisticsModal from './components/MultiLogisticsModal';
import { import {
queryToSend, queryToSend,
queryExpress, queryExpress,
...@@ -19,6 +21,8 @@ import { ...@@ -19,6 +21,8 @@ import {
getLogistics, getLogistics,
downOrder, downOrder,
getJDLogisticsInfo, getJDLogisticsInfo,
apiQueryOrderInfo,
apiDeliveriesTraceList,
} from './service'; } from './service';
const { confirm } = Modal; const { confirm } = Modal;
...@@ -58,25 +62,34 @@ const TableList = props => { ...@@ -58,25 +62,34 @@ const TableList = props => {
// const endDisabledDate = current => // const endDisabledDate = current =>
// current && (current.diff(startTime, 'days') > 30 || current.diff(startTime, 'days') < 0); // current && (current.diff(startTime, 'days') > 30 || current.diff(startTime, 'days') < 0);
const multiLogisticsModalRef = useRef();
const actionRef = useRef(); const actionRef = useRef();
const ref = useRef(FormInstance); const ref = useRef(FormInstance);
const handleCom = async (record, skuItem) => { const handleCom = async (skuInfo, expressInfo) => {
const tempObj = { const tempObj = {
expressCompanyCode: skuItem?.expressCompanyCode ?? '', expressCompanyCode: expressInfo?.expressCompanyCode ?? '',
expressCompanyName: skuItem.expressCompanyName ?? '', expressCompanyName: expressInfo.expressCompanyName ?? '',
deliveryNo: skuItem?.deliveryNo ?? '', deliveryNo: expressInfo?.expressNo ?? '',
detailList: [], detailList: [],
key: Date.now(), key: Date.now(),
}; };
const data = await getJDLogisticsInfo(skuItem.orderSkuId);
const res = await apiDeliveriesTraceList({
expressCompanyCode: expressInfo.expressCompanyCode,
expressNo: expressInfo.expressNo,
orderNo: skuInfo.orderNo,
});
const data = res.data[0];
console.log(data);
if (!data) { if (!data) {
notification.info({ message: '暂无物流信息' }); notification.info({ message: '暂无物流信息' });
return; return;
} }
tempObj.expressCompanyName = data?.logisticsName || tempObj.expressCompanyName; tempObj.expressCompanyName = data?.expressCompanyName || tempObj.expressCompanyName;
tempObj.deliveryNo = data?.logisticsBillNo || tempObj.deliveryNo; tempObj.deliveryNo = data?.expressNo || tempObj.deliveryNo;
if (data.logisticsList?.length) { if (data.traceList?.length) {
data.logisticsList.forEach(v => { data.traceList.forEach(v => {
tempObj.detailList = [...tempObj.detailList, ...v.detailList]; tempObj.detailList = [...tempObj.detailList, ...v.detailList];
}); });
} }
...@@ -109,30 +122,60 @@ const TableList = props => { ...@@ -109,30 +122,60 @@ const TableList = props => {
const renderContent = (record, key) => { const renderContent = (record, key) => {
if (record.mchOrderSkuVoList) { if (record.mchOrderSkuVoList) {
return record?.mchOrderSkuVoList.map((item, index) => ( return record?.mchOrderSkuVoList.map((item, index) => {
<p const tableContentHeight = item?.expressList?.length || 1;
className={[
'tableContent', return (
index < record?.mchOrderSkuVoList?.length - 1 ? 'border' : null, <div
].join(' ')} // eslint-disable-next-line prefer-template
key={item.orderSkuId} style={{ height: tableContentHeight * 60 + 'px' }}
> className={[
{key === 'skuName' ? <PopoverDom name={item[key]} url={item.imageUrl} /> : ''} 'tableContent',
{key === 'action' && props.type === 2 ? ( index < record?.mchOrderSkuVoList?.length - 1 ? 'border' : null,
<Button ].join(' ')}
size="small" key={item.orderSkuId}
type="primary" >
onClick={() => { {key === 'skuName' ? <PopoverDom name={item[key]} url={item.imageUrl} /> : ''}
handleCom(record, item); {key === 'expressCompanyName' ? (
}} <div className="expressList">
> {item.expressList?.map((info, idx) => (
查看物流 <span
</Button> className={[
) : ( 'subContent',
item[key] idx < item.expressList?.length - 1 ? 'border' : null,
)} ].join(' ')}
</p> >
)); {info.expressCompanyName}
</span>
))}
</div>
) : (
''
)}
{key === 'deliveryNo' ? (
<div className="expressList">
{item.expressList?.map((info, idx) => (
<a
onClick={() => {
handleCom(item, info);
}}
className={[
'subContent',
idx < item.expressList?.length - 1 ? 'border' : null,
].join(' ')}
>
{info.expressNo}
</a>
))}
</div>
) : (
''
)}
{item[key]}
</div>
);
});
} }
return ''; return '';
}; };
...@@ -148,7 +191,7 @@ const TableList = props => { ...@@ -148,7 +191,7 @@ const TableList = props => {
const columns = [ const columns = [
{ {
title: '订单ID', title: '订单',
dataIndex: 'orderNo', dataIndex: 'orderNo',
key: 'orderNo', key: 'orderNo',
order: 6, order: 6,
...@@ -322,7 +365,7 @@ const TableList = props => { ...@@ -322,7 +365,7 @@ const TableList = props => {
title: '物流公司', title: '物流公司',
dataIndex: 'expressCompanyName', dataIndex: 'expressCompanyName',
key: 'expressCompanyName', key: 'expressCompanyName',
width: 100, width: 120,
className: 'colStyle', className: 'colStyle',
hideInSearch: true, hideInSearch: true,
render: (_, record) => renderContent(record, 'expressCompanyName'), render: (_, record) => renderContent(record, 'expressCompanyName'),
...@@ -331,20 +374,20 @@ const TableList = props => { ...@@ -331,20 +374,20 @@ const TableList = props => {
title: '物流单号', title: '物流单号',
dataIndex: 'deliveryNo', dataIndex: 'deliveryNo',
key: 'deliveryNo', key: 'deliveryNo',
width: 180, width: 210,
className: 'colStyle', className: 'colStyle',
hideInSearch: true, hideInSearch: true,
render: (_, record) => renderContent(record, 'deliveryNo'), render: (_, record) => renderContent(record, 'deliveryNo'),
}, },
{ // {
title: '物流信息', // title: '物流信息',
dataIndex: 'action', // dataIndex: 'action',
key: 'action', // key: 'action',
width: 150, // width: 150,
hideInSearch: true, // hideInSearch: true,
className: 'colStyle', // className: 'colStyle',
render: (_, record) => renderContent(record, 'action'), // render: (_, record) => renderContent(record, 'action'),
}, // },
{ {
title: '订单状态', title: '订单状态',
dataIndex: 'orderStatusDesc', dataIndex: 'orderStatusDesc',
...@@ -400,19 +443,30 @@ const TableList = props => { ...@@ -400,19 +443,30 @@ const TableList = props => {
marginBottom: '10px', marginBottom: '10px',
}} }}
onClick={async () => { onClick={async () => {
const skuListData = await getGoods(record?.orderId); // const skuListData = await getGoods(record?.orderId);
let logisticsData = [{}]; // let logisticsData = [{}];
setSkuList(skuListData); // setSkuList(skuListData);
const data = await getLogistics(record?.orderId); // const data = await getLogistics(record?.orderId);
logisticsData = data.map(item => ({ // logisticsData = data.map(item => ({
selectedGoods: item?.skus?.map(sku => sku?.orderSkuId), // selectedGoods: item?.skus?.map(sku => sku?.orderSkuId),
selectedCompany: item.expressCompanyCode // selectedCompany: item.expressCompanyCode
? `${item?.expressCompanyCode}-${item?.expressCompanyName}` // ? `${item?.expressCompanyCode}-${item?.expressCompanyName}`
: null, // : null,
orderNum: item?.deliveryNo, // orderNum: item?.deliveryNo,
})); // }));
setLogisticsData(logisticsData); // setLogisticsData(logisticsData);
handleModalVisible(true); // handleModalVisible(true);
const res = await apiQueryOrderInfo({
orderNo: record.orderNo,
});
multiLogisticsModalRef.current.open(
{
...record,
packageList: res.data.packageList || [],
},
actionRef,
);
}} }}
> >
{props.type === 2 ? '更新物流信息' : '填写物流信息'} {props.type === 2 ? '更新物流信息' : '填写物流信息'}
...@@ -566,6 +620,8 @@ const TableList = props => { ...@@ -566,6 +620,8 @@ const TableList = props => {
orderId={delayOrderIDs} orderId={delayOrderIDs}
onCancel={e => onCancelDelay(e)} onCancel={e => onCancelDelay(e)}
/> />
<MultiLogisticsModal companys={companys} ref={multiLogisticsModalRef} />
</PageHeaderWrapper> </PageHeaderWrapper>
); );
}; };
......
...@@ -5,12 +5,30 @@ ...@@ -5,12 +5,30 @@
.tableContent { .tableContent {
display: flex; display: flex;
align-items: center; align-items: center;
height: 60px; // height: 60px;
padding: 16px; min-height: 60px;
padding: 0 12px;
} }
.border { .border {
border-bottom: 1px solid #e8e8e8; border-bottom: 1px solid #e8e8e8;
} }
.subContent {
flex: 1;
padding: 12px;
overflow: hidden;
line-height: 36px;
white-space: nowrap;
text-overflow: ellipsis;
}
.expressList {
display: flex;
flex-direction: column;
width: calc(100% + 24px);
height: 100%;
margin: -12px;
}
tbody .colStyle { tbody .colStyle {
padding: 0; padding: 0;
} }
......
...@@ -62,7 +62,7 @@ export async function getLogistics(orderId) { ...@@ -62,7 +62,7 @@ export async function getLogistics(orderId) {
export async function uploadFile(file) { export async function uploadFile(file) {
const params = new FormData(); const params = new FormData();
params.append('file', file); params.append('file', file);
const data = await request.post('/api/kdsp/op/mch-order/order-logistics-batch-import', { const data = await request.post('/api/merchants/orders/deliveries/batches/import', {
data: params, data: params,
prefix: config.kdspApi, prefix: config.kdspApi,
}); });
...@@ -71,7 +71,8 @@ export async function uploadFile(file) { ...@@ -71,7 +71,8 @@ export async function uploadFile(file) {
export function downTemplate() { export function downTemplate() {
window.location.href = window.location.href =
// 'https://kdspstatic.q-gp.com/%E8%AE%A2%E5%8D%95%E7%89%A9%E6%B5%81%E4%BF%A1%E6%81%AF%E5%AF%BC%E5%85%A5%E6%A8%A1%E6%9D%BF-v1.xlsx'; // 'https://kdspstatic.q-gp.com/%E8%AE%A2%E5%8D%95%E7%89%A9%E6%B5%81%E4%BF%A1%E6%81%AF%E5%AF%BC%E5%85%A5%E6%A8%A1%E6%9D%BF-v1.xlsx';
'https://kdspstatic.q-gp.com/order_import_templatev2.xlsx'; // 'https://kdspstatic.q-gp.com/order_import_templatev2.xlsx';
'https://sc-img.q-gp.com/orders/templates/batch_deliveriesV2.xlsx';
} }
export async function downOrder(params) { export async function downOrder(params) {
const data = await request.post('/api/kdsp/op/mch-order/order-export', { const data = await request.post('/api/kdsp/op/mch-order/order-export', {
...@@ -151,3 +152,86 @@ export function apiDelayDeliverGoods(data) { ...@@ -151,3 +152,86 @@ export function apiDelayDeliverGoods(data) {
prefix: config.kdspApi, prefix: config.kdspApi,
}); });
} }
/**
* 多物流发货-查询多物流订单信息
* @param {*} params
* @returns
* @see http://yapi.quantgroups.com/project/389/interface/api/45840
*/
export function apiQueryOrderInfo(params) {
// return new Promise(resolve => {
// setTimeout(() => {
// resolve({
// packageList: [
// {
// expressCompanyCode: 'yunda',
// expressCompanyName: '',
// expressNo: 'YUNDA012345678',
// serialNumber: '0011223344',
// skuInfoList: [
// {
// skuNo: ['529355424931841'],
// quantity: '2',
// },
// {
// skuNo: ['530724210084865'],
// quantity: '12',
// },
// ],
// },
// {
// expressCompanyCode: 'yunda',
// expressCompanyName: '',
// expressNo: 'YUNDA012345678',
// serialNumber: '0011223344',
// skuInfoList: [
// {
// skuNo: ['529355424931841'],
// quantity: '2',
// },
// ],
// },
// ],
// });
// }, 1000);
// });
return request.get('/api/merchants/orders/deliveries/packages/detail', {
params,
prefix: config.kdspApi,
});
}
/**
* 多物流发货-新建发货/更新发货信息
* @param {*} data
* @returns
* @see http://yapi.quantgroups.com/project/389/interface/api/45816
*/
export function apiDeliveriesAdd(data) {
return request.post('/api/merchants/orders/deliveries/add', {
data,
prefix: config.kdspApi,
});
}
export function apiDeliveriesEdit(data) {
return request.post('/api/merchants/orders/deliveries/edit', {
data,
prefix: config.kdspApi,
});
}
/**
* 多物流发货-查询物流轨迹
* @see http://yapi.quantgroups.com/project/389/interface/api/46120
*/
export function apiDeliveriesTraceList(data) {
return request.post('/api/merchants/deliveries/trace/list', {
data: stringify(data),
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
prefix: config.kdspApi,
});
}
...@@ -45,7 +45,7 @@ const CustomTable = props => { ...@@ -45,7 +45,7 @@ const CustomTable = props => {
subDataItem && subDataItem[key] !== undefined ? subDataItem[key] : dataSourceItem[key]; subDataItem && subDataItem[key] !== undefined ? subDataItem[key] : dataSourceItem[key];
let rowSpan = 1; let rowSpan = 1;
// 设置了自动合并 && 只设置第一条数据的值,其他的返回<></</> // 设置了自动合并 && 只设置第一条数据的值,其他的返回<></>
if (column.rowSpanMode === 'auto' && subData) { if (column.rowSpanMode === 'auto' && subData) {
rowSpan = subData.length; rowSpan = subData.length;
if (subDataIndex > 0) { if (subDataIndex > 0) {
......
import { Form, Tabs, Input, Button, Pagination } from 'antd'; import { Form, Tabs, Input, Button, Pagination, notification } from 'antd';
import React, { useState, useEffect, useRef } from 'react'; import React, { useState, useEffect, useRef } from 'react';
import { PageHeaderWrapper } from '@ant-design/pro-layout'; import { PageHeaderWrapper } from '@ant-design/pro-layout';
import { connect } from 'dva'; import { connect } from 'dva';
import { QUERY_ORDER } from '@/../config/permission.config'; import { QUERY_ORDER } from '@/../config/permission.config';
import { values } from 'lodash';
import style from './index.less'; import style from './index.less';
import { CustomTable } from './components/CustomTable/index'; import { CustomTable } from './components/CustomTable/index';
import { FormSearch, SEARCH_TYPE } from './components/FormSearch/index'; import { FormSearch, SEARCH_TYPE } from './components/FormSearch/index';
import LogisticsForm from './components/LogisticsFormModel'; import MultiLogisticsModal from '../pendingDeliveryOrder/components/MultiLogisticsModal';
import LogisticsCom from '../pendingDeliveryOrder/components/LogisticsCom';
import DetailModal from './components/DetailModal/index'; import DetailModal from './components/DetailModal/index';
import { queryOrderList, getGoods, getLogistics, queryExpress, queryToSend } from './service'; import { queryOrderList, getGoods, getLogistics, queryExpress, queryToSend } from './service';
import { apiQueryOrderInfo, apiDeliveriesTraceList } from '../pendingDeliveryOrder/service';
import { ORDER_SEARCH_TYPE, ORDER_TYPE, ORDER_STATUS } from './const'; import { ORDER_SEARCH_TYPE, ORDER_TYPE, ORDER_STATUS } from './const';
const { TabPane } = Tabs; const { TabPane } = Tabs;
...@@ -20,16 +23,15 @@ const OrderList = props => { ...@@ -20,16 +23,15 @@ const OrderList = props => {
const canEditable = permissions[QUERY_ORDER.EDITABLE]; const canEditable = permissions[QUERY_ORDER.EDITABLE];
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const detailModalRef = useRef(); const detailModalRef = useRef();
const multiLogisticsModalRef = useRef();
/** @module 发货弹框 */ /** @module 发货弹框 */
// 物流公司数据 // 物流公司数据
const [companys, setCompanys] = useState([]); const [companys, setCompanys] = useState([]);
// 物流弹出框展示
const [LogisticsModalVisible, handleModalVisible] = useState(false); /** @module 查看物流记录 */
// 订单下商品列表 const [LogisticsComList, setLogisticsComList] = useState({});
const [skuList, setSkuList] = useState([]); const [LogisticsComModalVisible, handleComModalVisible] = useState(false);
// 当前物流数据
const [LogisticsData, setLogisticsData] = useState([{}]);
/** @module 表格区域 */ /** @module 表格区域 */
const [tableData, setTableData] = useState([]); const [tableData, setTableData] = useState([]);
...@@ -95,12 +97,50 @@ const OrderList = props => { ...@@ -95,12 +97,50 @@ const OrderList = props => {
}); });
} }
// 获取物流记录信息
const handleCom = async (skuInfo, expressInfo) => {
const tempObj = {
expressCompanyCode: expressInfo?.expressCompanyCode ?? '',
expressCompanyName: expressInfo.expressCompanyName ?? '',
deliveryNo: expressInfo?.expressNo ?? '',
detailList: [],
key: Date.now(),
};
const res = await apiDeliveriesTraceList({
expressCompanyCode: expressInfo.expressCompanyCode,
expressNo: expressInfo.expressNo,
orderNo: skuInfo.orderNo,
});
const data = res.data[0];
console.log(data);
if (!data) {
notification.info({ message: '暂无物流信息' });
return;
}
tempObj.expressCompanyName = data?.expressCompanyName || tempObj.expressCompanyName;
tempObj.deliveryNo = data?.expressNo || tempObj.deliveryNo;
if (data.traceList?.length) {
data.traceList.forEach(v => {
tempObj.detailList = [...tempObj.detailList, ...v.detailList];
});
}
handleComModalVisible(true);
setLogisticsComList(tempObj);
};
// 重载 // 重载
const reload = () => { const reload = () => {
handleModalVisible(false);
getOrderList(); getOrderList();
}; };
const actionRef = {
current: {
reload,
},
};
// 获取物流公司列表 // 获取物流公司列表
const getCompanys = async () => { const getCompanys = async () => {
const res = await queryExpress(); const res = await queryExpress();
...@@ -267,9 +307,27 @@ const OrderList = props => { ...@@ -267,9 +307,27 @@ const OrderList = props => {
}, },
{ {
title: '配送方式', title: '配送方式',
dataIndex: 'deliveryType', dataIndex: 'deliveryMethodList',
rowSpanMode: 'auto', // rowSpanMode: 'auto',
width: 150, width: 150,
render: ({ value, record, subRecord }) => {
console.log(value);
const info = {
orderNo: record.orderNoStr,
};
return value?.map(item => (
<p>
{item.expressCompanyName}/
<a
onClick={() => {
handleCom(info, item);
}}
>
{item.expressNo}
</a>
</p>
));
},
}, },
{ {
title: '售后', title: '售后',
...@@ -315,19 +373,23 @@ const OrderList = props => { ...@@ -315,19 +373,23 @@ const OrderList = props => {
<Button <Button
type="primary" type="primary"
onClick={async () => { onClick={async () => {
const skuListData = await getGoods(record?.orderId); const res = await apiQueryOrderInfo({
let logisticsData = [{}]; orderNo: record.orderNoStr,
setSkuList(skuListData); });
const res = await getLogistics(record?.orderId);
logisticsData = res.map(item => ({ multiLogisticsModalRef.current.open(
selectedGoods: item?.skus?.map(sku => sku?.orderSkuId), {
selectedCompany: item.expressCompanyCode ...record,
? `${item?.expressCompanyCode}-${item?.expressCompanyName}` orderNo: record.orderNoStr,
: null, mchOrderSkuVoList: record.skuVos.map(item => ({
orderNum: item?.deliveryNo, ...item,
})); skuNo: item.skuId?.toString(),
setLogisticsData(logisticsData); orderNo: record.orderNoStr,
handleModalVisible(true); })),
packageList: res.data.packageList || [],
},
actionRef,
);
}} }}
> >
{text} {text}
...@@ -406,15 +468,14 @@ const OrderList = props => { ...@@ -406,15 +468,14 @@ const OrderList = props => {
)} )}
</div> </div>
<LogisticsForm <LogisticsCom
onSubmit={reload} onSubmit={reload}
skuList={skuList} onCancel={() => handleComModalVisible(false)}
companys={companys} modalVisible={LogisticsComModalVisible}
onCancel={() => handleModalVisible(false)} value={LogisticsComList}
modalVisible={LogisticsModalVisible} key={LogisticsComList.key}
value={LogisticsData}
/> />
<MultiLogisticsModal companys={companys} ref={multiLogisticsModalRef} />
<DetailModal ref={detailModalRef} /> <DetailModal ref={detailModalRef} />
</PageHeaderWrapper> </PageHeaderWrapper>
); );
......
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