Commit cd6b961e authored by 李腾's avatar 李腾

feat: 完善售后取消订单逻辑

parent 7534953c
import React from 'react';
import React, { useState } from 'react';
import { Form, Input, Select, DatePicker, Button, Space } from 'antd';
import { moment, Moment } from 'moment';
import moment from 'moment';
import style from './index.less';
const { Option } = Select;
......@@ -82,11 +82,27 @@ const FormSearch = props => {
// 选择日期范围类型
const FormItemRangePicker = config => {
const { originOptions = {} } = config;
const { originOptions = {}, bindKey, rangeNum, rangeUnit } = config;
const attrs = { placeholder: ['开始日期', '结束日期'], ...originOptions };
// 自动截取日期限制的范围
const onOpenChange = open => {
if (!open) {
const [date1, date2] = form.getFieldValue(bindKey);
const diffNum = date2.diff(date1, 'months');
if (diffNum >= 3) {
setTimeout(() => {
form.setFieldsValue({
[bindKey]: [moment(date1), moment(date1).add(3, 'month')],
});
});
}
}
};
return (
<FormItemBox {...config}>
<RangePicker className={style['form-item-tag']} {...attrs} />
<RangePicker className={style['form-item-tag']} onOpenChange={onOpenChange} {...attrs} />
</FormItemBox>
);
};
......@@ -107,7 +123,7 @@ const FormSearch = props => {
// 输入框类型
const FormItemInput = config => {
const { originOptions = {} } = config;
const attrs = { placeholder: '请输入', ...originOptions };
const attrs = { placeholder: '请输入', allowClear: true, ...originOptions };
return (
<FormItemBox {...config}>
<Input className={style['form-item-tag']} {...attrs} />
......
import React, { useState, useEffect, forwardRef, useImperativeHandle } from 'react';
import { useHistory } from 'react-router-dom';
import { Modal, Tabs, Pagination, Spin, notification, Checkbox, Badge } from 'antd';
import { apiGetBussinessMsgList, apiGetBusinessMsgUnReadCount } from '@/services/messageReminder';
import { connect } from 'dva';
......@@ -16,7 +17,7 @@ const INIT_QUERY_PARAMS = {
};
const MessageItem = props => {
const { item, onMark } = props;
const { item, onMark, viewDetail } = props;
/**
* type: 0订单消息,1售后消息
* readStatus: 0未读,1已读
......@@ -28,11 +29,18 @@ const MessageItem = props => {
} catch (e) {
console.error('消息数据格式错误');
}
const goodList = message.items.map(good => (
<div className={styles.good}>
<span className={styles.good__name}>{good.skuName}</span>
<span className={styles.good__count}>x{good.quantity}</span>
</div>
));
return (
<div className={styles['complex-list__item']}>
<div className={styles['complex-list__item--header']}>
<span className={styles['order-number']}> 订单编号:{message.orderNo}</span>
<span className={styles.time}>订单时间:{message.createdAt}</span>
<span className={styles.time}>订单时间:{message.time}</span>
{readStatus === 0 ? (
<a className={styles['read-status']} onClick={() => onMark([item.id])}>
标记为已读
......@@ -41,15 +49,12 @@ const MessageItem = props => {
<span className={styles['read-status--read']}>已读</span>
)}
</div>
<div className={styles['complex-list__item--body']}>
<div className={styles.good}>
<span className={styles.good__name}>商品名称商品名称商品名称商品名称</span>
<span className={styles.good__count}>x10</span>
</div>
</div>
<div className={styles['complex-list__item--body']}>{goodList}</div>
<div className={styles['complex-list__item--footer']}>
<div className={styles.actions}>
<a className={styles.notice}>新的xxx订单,请查看</a>
<a onClick={() => viewDetail(message)} className={styles.notice}>
{message.title},请查看
</a>
</div>
</div>
</div>
......@@ -58,6 +63,7 @@ const MessageItem = props => {
const Complex = props => {
const { dispatch, refInstance } = props;
const history = useHistory();
const [visible, setVisible] = useState(false);
const [dataTotal, setDataTotal] = useState(10);
const [loading, setLoading] = useState(false);
......@@ -133,6 +139,33 @@ const Complex = props => {
});
};
const open = () => {
setVisible(true);
getMsgReadCount();
};
const close = () => {
setVisible(false);
};
// 跳转到详情
const viewDetail = message => {
console.log(message);
const { orderNo } = message;
// 待发货
history.push({
pathname: '/orderManage/pendingDeliveryOrder',
query: { orderNo },
});
// 已发货
// /orderManage/deliveryOrder
// 售后
close();
};
// 切换消息类型
const onTabChange = index => {
setQueryParams({
......@@ -161,15 +194,6 @@ const Complex = props => {
});
};
const open = () => {
setVisible(true);
getMsgReadCount();
};
const close = () => {
setVisible(false);
};
// 展开初始化
useEffect(() => {
if (visible) {
......@@ -261,7 +285,9 @@ const Complex = props => {
<FilterRender />
<div className={styles['complex-list']}>
{messageData.length ? (
messageData.map(item => <MessageItem key={item.id} item={item} onMark={onMark} />)
messageData.map(item => (
<MessageItem key={item.id} item={item} onMark={onMark} viewDetail={viewDetail} />
))
) : (
<Empty text="暂无数据" />
)}
......
......@@ -31,6 +31,7 @@ const Message = props => {
} catch (e) {
console.error('消息数据格式错误');
}
return (
<div className={styles.item}>
<div className={styles.info}>
......@@ -43,7 +44,7 @@ const Message = props => {
<span>{message.createdAt}</span>
</div>
<div className={styles.notice}>
<a>您有新的xxxxx订单,请查看</a>
<a>{message.title},请查看</a>
</div>
</div>
);
......@@ -125,7 +126,6 @@ const Simple = props => {
notification.error(res.msg);
return;
}
console.log(res);
const { content } = res.data;
setVisible(!!content.length);
dispatch({
......
......@@ -2,6 +2,7 @@
position: fixed;
right: 30px;
bottom: 10px;
z-index: 19;
// width: 112px;
// height: 50px;
color: #fff;
......
......@@ -53,28 +53,28 @@ const BasicLayout = props => {
const [siderCollapsed, setSiderCollapsed] = useState(false);
const messageReminderComplexRef = useRef();
/**
* constructor
*/
// const audioRef = useRef()
useEffect(() => {
const token = window.localStorage.getItem('token');
const channelId = 100001;
const socket = new Socket({
url: getSocketUrl({ token, channelId }),
});
socket.connection();
const token = window.localStorage.getItem('token');
const channelId = 100001;
const socket = new Socket({
url: getSocketUrl({ token, channelId }),
});
socket.connection();
socket.event.on('open', () => {
console.log('连接成功3');
});
socket.event.on('open', () => {
console.log('连接成功3');
});
useEffect(() => {
socket.event.on('message', msg => {
console.log(msg);
// audioRef.current.click()
dispatch({
type: 'messageReminder/setUnReadData',
payload: [JSON.parse(msg.data)],
});
// socket.play()
});
// let a = 100000000000;
// setInterval(() => {
......@@ -85,7 +85,7 @@ const BasicLayout = props => {
// channelId: 100001,
// bussinessId: 'self_40',
// type: 0,
// sendContent: `{"name":"商品21111", "orderNo":${a},"createdAt":"2022-10-13 12:12:12", "count":11}`,
// sendContent: `{"name":"商品21111","title":"商品21111", "orderNo":${a},"createdAt":"2022-10-13 12:12:12", "count":11}`,
// readStatus: 0,
// createdAt: '2022-10-18 14:05:12',
// updatedAt: '2022-10-18 17:15:19',
......@@ -226,7 +226,7 @@ const BasicLayout = props => {
<MessageReminder.Simple complexRef={messageReminderComplexRef} />
<MessageReminder.Complex ref={messageReminderComplexRef} />
{/* <audio id="myaudio" src="https://img.lkbang.net/10544.b57be67d.mp3" loop="loop" preload="preload" muted="muted" /> */}
{/* <Button ref={audioRef} onClick={() => { socket.play() }}>声音</Button> */}
</ProLayout>
);
};
......
import React from 'react';
import { Form } from '@ant-design/compatible';
import '@ant-design/compatible/assets/index.css';
import { Modal, Input, Cascader, notification } from 'antd';
import { cancelShopAudit } from '../services';
const FormItem = Form.Item;
const { TextArea } = Input;
const AuditModal = props => {
const {
visible,
onCancel,
form: { getFieldDecorator, getFieldValue, validateFields, resetFields },
formData = {},
} = props;
const handleCancel = isSuccess => {
resetFields();
onCancel(isSuccess);
};
const treeData = [
{
label: '同意',
value: true,
},
{
label: '不同意',
value: false,
children: [
{
label: '订单已发货',
value: 10,
},
{
label: '已与客户沟通继续发货',
value: 20,
},
{
label: '其他',
value: 30,
},
],
},
];
const handleOk = () => {
validateFields(async (error, fieldsValue) => {
if (!error) {
const { approve } = fieldsValue;
const data = await cancelShopAudit({
...fieldsValue,
refuseReasonCode: approve?.[1],
approve: approve?.[0],
serviceNo: formData?.serviceNo,
});
if (data.businessCode === '0000') {
notification.success({ message: approve?.[0] ? '审核成功' : '审核拒绝提交成功' });
handleCancel(true);
}
}
});
};
const layout = {
labelCol: { span: 6 },
wrapperCol: { span: 16 },
};
const approve = getFieldValue('approve');
const isRefuse = () => approve && approve[0] !== 1;
return (
<Modal
title="售后操作确认"
visible={visible}
onOk={() => handleOk()}
onCancel={() => handleCancel()}
>
<Form {...layout} name="formData">
<FormItem label="审核结果">
{getFieldDecorator('approve')(
<Cascader
allowClear
showSearch
style={{ width: '315px' }}
dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
options={treeData}
placeholder="请选择"
/>,
)}
</FormItem>
{isRefuse() && approve[1] === 30 && (
<FormItem label="拒绝原因">
{getFieldDecorator('refuseReasonRemark', {
initialValue: formData.refuseDesc,
rules: [
{
required: true,
message: '请填写拒绝原因!',
},
],
})(
<TextArea
placeholder="请填写拒绝原因"
allowClear
autoSize={{ minRows: 3, maxRows: 6 }}
/>,
)}
</FormItem>
)}
</Form>
</Modal>
);
};
export default Form.create()(AuditModal);
import React from 'react';
import { Modal, Table } from 'antd';
export default props => {
const { visible, onCancel, dataSource } = props;
const handleCancel = () => {
onCancel();
};
const columns = [
{
title: '商品名称',
width: 400,
dataIndex: 'skuName',
},
{
title: '商品属性',
dataIndex: 'skuAttr',
},
{
title: '商品件数',
dataIndex: 'count',
},
];
return (
<Modal title="订单详情" visible={visible} onCancel={handleCancel} footer={null} width={800}>
<Table
dataSource={dataSource}
columns={columns}
key={r => r.orderId}
pagination={false}
bordered
/>
</Modal>
);
};
import React from 'react';
import { Form } from '@ant-design/compatible';
import '@ant-design/compatible/assets/index.css';
import { Modal, Input, notification } from 'antd';
import { shopCheck } from '../service';
const FormItem = Form.Item;
const { TextArea } = Input;
const RejectModal = props => {
const {
visible,
onCancel,
form: { getFieldDecorator, validateFields, resetFields },
serviceNo = null,
} = props;
const handleCancel = isSuccess => {
resetFields();
onCancel(isSuccess);
};
const handleOk = () => {
validateFields(async (error, fieldsValue) => {
if (!error) {
const data = await shopCheck({
...fieldsValue,
serviceNo,
auditResult: 2,
});
if (data.code === '0000') {
notification.success({ message: '操作成功' });
handleCancel(true);
}
}
});
};
const layout = {
labelCol: { span: 6 },
wrapperCol: { span: 16 },
};
return (
<Modal title="驳回" visible={visible} onOk={() => handleOk()} onCancel={() => handleCancel()}>
<Form {...layout} name="formData">
<FormItem label="原因">
{getFieldDecorator('refuseReasonRemark', {
rules: [
{
required: true,
message: '请填写原因!',
},
],
})(
<TextArea placeholder="请填写原因" allowClear autoSize={{ minRows: 3, maxRows: 6 }} />,
)}
</FormItem>
</Form>
</Modal>
);
};
export default Form.create()(RejectModal);
......@@ -130,16 +130,14 @@ export const getFormConfig = (props = {}) => {
bindKey: 'receiverPhone',
},
{
type: SEARCH_TYPE.DATE_PICKER,
label: '订单开始日期',
type: SEARCH_TYPE.RANGE_PICKER,
label: '售后日期',
column: 5,
bindKey: 'startDate',
},
{
type: SEARCH_TYPE.DATE_PICKER,
label: '订单结束日期',
column: 5,
bindKey: 'endDate',
bindKey: 'afterTime',
originOptions: {
placeholder: ['开始日期', '结束日期'],
allowClear: false,
},
},
],
btnConfig: [
......@@ -152,9 +150,10 @@ export const getFormConfig = (props = {}) => {
actionRef.current.reload();
return;
}
setTableParams(params);
const { type, dealStatus } = params;
let hasMatchingKey = '';
console.log(111111, params);
Object.keys(TAB_MAPPING_DATA).forEach(key => {
const item = TAB_MAPPING_DATA[key];
if (type === item.type && dealStatus === item.dealStatus) {
......@@ -162,14 +161,17 @@ export const getFormConfig = (props = {}) => {
}
});
setCurrentTab(hasMatchingKey);
setTableParams(params);
},
},
{
label: '重置',
type: '',
clickType: 'reset',
onClick: () => {
setTableParams({});
onClick: ({ params }) => {
// setTableParams({});
actionRef.current.reload();
setCurrentTab('');
},
},
],
......@@ -193,6 +195,8 @@ export const getColumns = props => {
refund,
reject,
canEditable,
openCancelAudit,
viewCancelDetail,
} = props;
return [
{
......@@ -222,10 +226,18 @@ export const getColumns = props => {
title: '售后类型',
dataIndex: 'serviceType',
hideInSearch: true,
width: 120,
width: 140,
render: serviceType => {
if (+serviceType === 0) {
return <span style={{ color: '#ff1616' }}>仅退款(未发货)</span>;
}
if (+serviceType === 1) {
return <span style={{ color: '#ff1616' }}>仅退款</span>;
return (
<span style={{ color: '#ff1616' }}>
{/* {AFTER_TYPE.find(item=> item.value === serviceType)} */}
仅退款
</span>
);
}
return <span>退货退款</span>;
},
......@@ -386,10 +398,11 @@ export const getColumns = props => {
key: 'pop',
};
/** @name applyTpye=1 */
// 允许退款/已退款按钮
const refundBtn = (
<Popconfirm {...refundBtnProps} onConfirm={() => refund(record)} disabled={!showRefund}>
<Button key="link1" disabled={!showRefund}>
<Button key="link1" {...btnProps} disabled={!showRefund}>
{showRefunded ? '已退款' : '允许退款'}
</Button>
</Popconfirm>
......@@ -400,6 +413,7 @@ export const getColumns = props => {
审核
</Button>
);
// 驳回按钮
let refuseBtn = (
<Button key="link3" onClick={() => reject(record)} {...btnProps} disabled={!showRefuse}>
......@@ -445,14 +459,28 @@ export const getColumns = props => {
</Button>
);
const cancelAuditBtn = (
<Button key="cancellink1" onClick={() => openCancelAudit(record)} {...btnProps}>
审核
</Button>
);
const cancelDetailBtn = (
<Button key="cancellink2" onClick={() => viewCancelDetail(record)} {...btnProps}>
订单详情
</Button>
);
/** @name applyTpye=2 */
if (!canEditable) {
auditBtn = '';
refuseBtn = '';
logisticsInterceptionBtn = '';
}
// 服务商品 || 实物商品-仅退款未发货 serviceType = 0
if (isServiceGoods || serviceType === 0) {
// 服务商品
if (isServiceGoods) {
// 待商户审核14
if ([14].includes(status)) {
return [auditBtn, detailBtn, viewLogBtn];
......@@ -464,6 +492,19 @@ export const getColumns = props => {
}
}
// 实物商品-仅退款未发货 serviceType = 0
if (serviceType === 0) {
// 待商户审核14 待审核0
if ([14, 0].includes(status)) {
return [cancelAuditBtn, cancelDetailBtn, viewLogBtn];
}
// 拒绝16, 处理成功70
if ([16, 70].includes(status)) {
return [cancelDetailBtn, viewLogBtn];
}
}
// 实物商品-仅退款 serviceType = 1
if (serviceType === 1) {
// 待商户审核14
......
......@@ -13,6 +13,8 @@ import AppealDetail from '@/pages/afterSale/components/detail';
import AfterLog from './components/AfterLog';
import RejectModal from './components/rejectModal';
import LogisticsCom from '../orderManage/pendingDeliveryOrder/components/LogisticsCom';
import CancelAuditModal from './components/CancelAuditModal';
import CancelDetailTable from './components/CancelDetailTable';
import { getColumns, getFormConfig, TAB_MAPPING_DATA } from './data.js';
import { getDetail } from '@/pages/afterSale/appeal/services';
......@@ -25,6 +27,7 @@ import {
trackInfo,
shopCheck,
getAfterPendingNum,
cancelOrderDetail,
} from './services';
import styles from './index.less';
......@@ -41,7 +44,13 @@ const AfterSale = props => {
const [currentTab, setCurrentTab] = useState('');
const [appealDetailModal, setAppealDetailModal] = useState(false);
const [selectedRow, setSelectedRow] = useState({});
const [tabInfoData, setTabInfoData] = useState({});
const [tabInfoData, setTabInfoData] = useState({
cancelOrderPendingAuditNum: 0,
refundPendingAuditNum: 0,
returnPendingAuditNum: 0,
returnWaitAuditNum: 0,
afterSalseDoneNum: 0,
});
// 申诉
const [proofsData, setProofsData] = useState([]);
const [proofsVisible, setProofsVisible] = useState(false);
......@@ -65,6 +74,14 @@ const AfterSale = props => {
const [serviceNoInfo, setServiceNoInfo] = useState({});
const [rejectVisible, setRejectVisible] = useState(false);
// 取消订单审核
const [cancelVisible, setCancelVisible] = useState(false);
const [cancelAuditInfo, setCancelAuditInfo] = useState({});
// 取消订单审核详情
const [cancelDetailVisible, setCancelDetailVisible] = useState(false);
const [cancelDetailInfo, setCancelDetailInfo] = useState({});
// 关闭modal
const closeModal = isReload => {
if (isReload === true) {
......@@ -77,6 +94,8 @@ const AfterSale = props => {
setAppealDetailModal(false);
setAfterVisible(false);
setLogisticsComModalVisible(false);
setCancelVisible(false);
setCancelDetailVisible(false);
};
// 查看申诉详情
......@@ -187,6 +206,20 @@ const AfterSale = props => {
setRejectVisible(true);
};
// 取消订单审核
const openCancelAudit = async ({ serviceNo }) => {
// const data = await auditInfoApi({ serviceNo });
setCancelAuditInfo({ serviceNo });
setCancelVisible(true);
};
// 取消订单审核详情
const viewCancelDetail = async ({ serviceNo }) => {
const data = await cancelOrderDetail({ serviceNo });
setCancelDetailInfo(data || []);
setCancelDetailVisible(true);
};
const [form] = Form.useForm();
const formConfig = getFormConfig({
actionRef,
......@@ -194,9 +227,13 @@ const AfterSale = props => {
setTableParams,
setCurrentTab,
});
const afterTime = [moment().subtract(3, 'month'), moment()];
const FormSearchProps = {
form,
initialValues: {},
initialValues: {
afterTime,
},
formOptions: {},
...formConfig,
};
......@@ -205,11 +242,16 @@ const AfterSale = props => {
const tabChange = tabIndex => {
setCurrentTab(tabIndex);
const { type, dealStatus } = TAB_MAPPING_DATA[tabIndex];
form.resetFields();
form.setFieldsValue({
...tableParams,
dealStatus,
type,
});
setTableParams({ ...tableParams, dealStatus, type });
// setTimeout(() => {
// form.submit()
// }, 0)
};
const columns = getColumns({
......@@ -223,6 +265,8 @@ const AfterSale = props => {
refund,
reject,
canEditable,
openCancelAudit,
viewCancelDetail,
});
// 表格属性
......@@ -233,11 +277,10 @@ const AfterSale = props => {
scroll: { x: '100%', y: 500 },
rowKey: r => r.serviceNo,
request: async params => {
console.log(params);
console.log('搜索', params);
const [start, end] = params.afterTime || afterTime;
const { current: page, pageSize: size } = params;
const startDate = params.startDate ? moment(params.startDate).format('YYYY-MM-DD') : '';
const endDate = params.endDate ? moment(params.endDate).format('YYYY-MM-DD') : '';
const startDate = start ? moment(start).format('YYYY-MM-DD') : '';
const endDate = end ? moment(end).format('YYYY-MM-DD') : '';
const requestParams = {
page,
size,
......@@ -245,8 +288,20 @@ const AfterSale = props => {
startDate,
endDate,
};
delete requestParams.afterTime;
delete requestParams.current;
delete requestParams.pageSize;
const countRes = await getAfterPendingNum({
startDate,
endDate,
});
const res = await searchList(requestParams);
const { records = [], total } = res.data;
console.log(countRes);
if (countRes.code === '0000') {
setTabInfoData(countRes.data);
}
return {
data: records,
total,
......@@ -278,11 +333,14 @@ const AfterSale = props => {
tabBarStyle={{ padding: '0 30px' }}
>
<TabPane key="" tab="全部"></TabPane>
<TabPane key="1" tab="仅退款(未发货)待审核0"></TabPane>
<TabPane key="2" tab="仅退款待审核8"></TabPane>
<TabPane key="3" tab="退货退款待审核0"></TabPane>
<TabPane key="4" tab="退货入库待审核0"></TabPane>
<TabPane key="5" tab="已完成0"></TabPane>
<TabPane
key="1"
tab={`仅退款(未发货)待审核${tabInfoData.cancelOrderPendingAuditNum}`}
></TabPane>
<TabPane key="2" tab={`仅退款待审核${tabInfoData.refundPendingAuditNum}`}></TabPane>
<TabPane key="3" tab={`退货退款待审核${tabInfoData.returnPendingAuditNum}`}></TabPane>
<TabPane key="4" tab={`退货入库待审核${tabInfoData.returnWaitAuditNum}`}></TabPane>
<TabPane key="5" tab={`已完成${tabInfoData.afterSalseDoneNum}`}></TabPane>
</Tabs>
</div>
<ProTable
......@@ -310,6 +368,13 @@ const AfterSale = props => {
></AppealDetail>
<AfterLog visible={afterVisible} onCancel={closeModal} data={afterList} />
<RejectModal visible={rejectVisible} onCancel={closeModal} serviceNo={serviceNoInfo} />
<CancelAuditModal visible={cancelVisible} onCancel={closeModal} formData={cancelAuditInfo} />
<CancelDetailTable
visible={cancelDetailVisible}
onCancel={closeModal}
dataSource={cancelDetailInfo}
/>
</PageHeaderWrapper>
);
};
......
......@@ -9,7 +9,7 @@ const { kdspApi } = config;
export const searchList = params =>
request.post('/api/kdsp/op/afs/shop/list', {
prefix: kdspApi,
data: stringify(_.omitBy(params, v => !v)),
data: stringify(_.omitBy(params, v => !v && v !== 0)),
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
......@@ -51,6 +51,19 @@ export function orderDetail(params) {
},
});
}
// 取消售后单详情
export async function cancelOrderDetail(params) {
const data = await request.get('/cancel-order/sku', {
prefix: kdspApi,
params,
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
});
return data.data || [];
}
// 售后审核
export async function shopAudit(params) {
return request.post('/api/kdsp/op/afs/shop/audit', {
......@@ -58,6 +71,15 @@ export async function shopAudit(params) {
prefix: kdspApi,
});
}
// 取消订单审核
export async function cancelShopAudit(params) {
return request.post('/cancel-order/audit', {
data: params,
prefix: kdspApi,
});
}
// 查询审核信息
export async function auditInfoApi(params) {
return request.get('/api/kdsp/op/afs/back-info', {
......
import { Button, notification, Modal, Popover } from 'antd';
import React, { useState, useEffect, useRef } from 'react';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import { useLocation } from 'react-router-dom';
import ProTable from '@ant-design/pro-table';
import { FormInstance } from 'antd/lib/form';
import moment from 'moment';
......@@ -23,8 +24,10 @@ import {
const { confirm } = Modal;
const TableList = props => {
const location = useLocation();
const dateFormat = 'YYYY-MM-DD';
const { permissions } = props;
// 因待发货 和 已发货都使用当前组件,功能且相同,所以只要授权其中一个均可获得发货物流权限
const canEditable =
permissions[PENDING_DELIVERY_ORDER.EDITABLE] || permissions[DELIVERY_ORDER.EDITABLE];
......@@ -44,6 +47,7 @@ const TableList = props => {
const [endTime, setEndTime] = useState(moment());
const [orderStatus, setorderStatus] = useState(1);
const [orderNo, setOrderNo] = useState('');
const [endTimeStr, setEndTimeStr] = useState(moment().format(dateFormat));
const [visibleDelay, setVisibleDelay] = useState(false);
......@@ -133,6 +137,15 @@ const TableList = props => {
return '';
};
const PopoverNotice = noticeProps => {
const { time, content } = noticeProps;
return (
<div className={style['popover-notice']}>
{time}{content}
</div>
);
};
const columns = [
{
title: '订单ID',
......@@ -141,14 +154,32 @@ const TableList = props => {
order: 6,
width: 250,
fixed: 'left',
render: (_, record) => (
<>
{_}
<Popover placement="top" title="催发货" content={<>111</>} trigger="click">
<span className={style.urge}></span>
</Popover>
</>
),
formItemProps: {
value: orderNo,
onChange(e) {
console.log(e.target.value);
setOrderNo(e.target.value);
},
},
render: (_, record) => {
const { urgeDeliverGoodsList } = record;
const content = () =>
urgeDeliverGoodsList?.map(item => (
<PopoverNotice time={item.time} content={item.content} />
));
return (
<>
{_}
{urgeDeliverGoodsList ? (
<Popover placement="top" title="催发货" content={<>{content()}</>} trigger="hover">
<span className={style.urge}></span>
</Popover>
) : (
''
)}
</>
);
},
},
{
title: '订单提醒',
......@@ -156,19 +187,43 @@ const TableList = props => {
key: 'orderNotice',
width: 150,
render: (_, record) => {
const { address } = record;
const { updateAddressList, platformRemark } = record;
let addressData;
if (updateAddressList) {
addressData = updateAddressList.pop();
}
return (
<div className={style['notice-btn']}>
<Popover placement="top" title="收货地址变更" content={<>111</>} trigger="click">
<Button block type="primary">
收货地址变更
</Button>
</Popover>
<Popover placement="top" title="平台备注" content={<>222</>} trigger="click">
<Button block type="warning">
平台备注
</Button>
</Popover>
{updateAddressList ? (
<Popover
placement="top"
title="收货地址变更"
content={<PopoverNotice time={addressData.time} content={addressData.content} />}
trigger="hover"
>
<Button block type="primary">
收货地址变更
</Button>
</Popover>
) : (
''
)}
{platformRemark ? (
<Popover
placement="top"
title="平台备注"
content={
<PopoverNotice time={platformRemark.time} content={platformRemark.content} />
}
trigger="hover"
>
<Button block type="warning">
平台备注
</Button>
</Popover>
) : (
''
)}
</div>
);
},
......@@ -187,7 +242,7 @@ const TableList = props => {
hideInTable: true,
formItemProps: {
// eslint-disable-next-line no-nested-ternary
value: orderStatus ? (orderStatus === 1 ? '' : '') : '',
value: orderStatus ? (orderStatus === 1 ? '' : '') : null,
onChange(status) {
setorderStatus(Number(status));
},
......@@ -395,6 +450,19 @@ const TableList = props => {
}
}, []);
// 监听路由query参数变化重新发起请求
useEffect(() => {
if (location?.query) {
const { orderNo: orderNumber } = location?.query;
setOrderNo(orderNumber);
if (actionRef.current) {
actionRef.current.reload();
}
} else {
setOrderNo('');
}
}, [location]);
const queryToSendFn = params => {
const transformedParam = {
...params,
......@@ -402,6 +470,7 @@ const TableList = props => {
pageNo: params.current,
pageSize: params.pageSize || 20,
timeOutType: orderStatus || '',
orderNo,
};
return queryToSend(transformedParam);
};
......
......@@ -88,9 +88,15 @@
display: inline-block;
width: 20px;
height: 20px;
margin-left: 5px;
color: #fff;
line-height: 20px;
text-align: center;
background-color: red;
border-radius: 50%;
cursor: pointer;
}
.popover-notice {
max-width: 300px;
}
import EventEmitter from 'events';
import { Modal } from 'antd';
class Socket extends EventEmitter {
event = new EventEmitter();
......@@ -11,7 +12,7 @@ class Socket extends EventEmitter {
this.taskRemindInterval = null;
this.connected = false;
this.waitingSendData = [];
this.reconnectCount = 0;
return this;
}
......@@ -73,20 +74,21 @@ class Socket extends EventEmitter {
// 根据后端返回的状态码做操作
// 我的项目是当前页面打开两个或者以上,就把当前以打开的socket关闭
// 否则就20秒重连一次,直到重连成功为止
if (e.code === '4500') {
this.socket.close();
} else {
const reconnect = () => {
clearTimeout(this.taskRemindInterval);
this.taskRemindInterval = setTimeout(() => {
if (!this.connected) {
this.connection();
reconnect();
}
}, 5000);
};
reconnect();
if (this.reconnectCount > 10) {
this.reconnectCount = 0;
return;
}
const reconnect = () => {
clearTimeout(this.taskRemindInterval);
this.taskRemindInterval = setTimeout(() => {
if (!this.connected) {
this.reconnectCount++;
this.connection();
reconnect();
}
}, 2000);
};
reconnect();
};
onerror = e => {
......
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