Commit 4ee3e994 authored by 张子雨's avatar 张子雨

Merge branch 'feat/aging2.1' into 'master'

Feat/aging2.1

See merge request !41
parents f8b83422 25038678
...@@ -2,16 +2,16 @@ const isProduction = process.env.NODE_ENV === 'production'; ...@@ -2,16 +2,16 @@ const isProduction = process.env.NODE_ENV === 'production';
const isPre = process.env.PRE_ENV === 'pre'; const isPre = process.env.PRE_ENV === 'pre';
const envAPi = { const envAPi = {
api: '//backstms-vcc3.liangkebang.net', api: '//backstms-yxm.liangkebang.net',
kdspOpApi: 'https://kdsp-operation-vcc3.liangkebang.net', kdspOpApi: 'https://kdsp-operation-yxm.liangkebang.net',
kdspApi: 'https://sc-op-api-vcc3.liangkebang.net', kdspApi: 'https://sc-op-api-yxm.liangkebang.net',
goodsApi: 'https://sc-op-api-vcc3.liangkebang.net', goodsApi: 'https://sc-op-api-yxm.liangkebang.net',
querysApi: 'https://sc-settlement-api-vcc3.liangkebang.net', querysApi: 'https://sc-settlement-api-yxm.liangkebang.net',
// goodsApi: '//192.168.188.111:7000', // goodsApi: '//192.168.188.111:7000',
prologueDomain: 'https://mall-vcc3.liangkebang.net', prologueDomain: 'https://mall-yxm.liangkebang.net',
// qiniuHost: 'https://appsync.lkbang.net', // qiniuHost: 'https://appsync.lkbang.net',
qiniuHost: 'https://kdspstatic.q-gp.com/', qiniuHost: 'https://kdspstatic.q-gp.com/',
opapiHost: 'https://opapi-vcc3.liangkebang.net', opapiHost: 'https://opapi-yxm.liangkebang.net',
}; };
const prodApi = { const prodApi = {
......
import React, { useState, useRef } from 'react'; import React, { useState, useRef } from 'react';
import { Button, notification, Popconfirm } from 'antd'; import { Button, notification, Popconfirm } from 'antd';
import ProTable from '@ant-design/pro-table'; import ProTable from '@ant-design/pro-table';
import { searchList, shopCheck, orderDetail, trackInfo } from '../services'; import { searchList, shopCheck, orderDetail, trackInfo, getOpLog } from '../services';
import { getDetail } from '../../afterSale/appeal/services'; import { getDetail } from '../../afterSale/appeal/services';
import { columnPassAudit } from '../data'; import { columnPassAudit } from '../data';
import RejectModal from '../components/rejectModal'; import RejectModal from '../components/rejectModal';
...@@ -9,6 +9,7 @@ import DetailTable from '../components/detailTable'; ...@@ -9,6 +9,7 @@ import DetailTable from '../components/detailTable';
import ProofsModal from '../components/proofsModal'; import ProofsModal from '../components/proofsModal';
import LogisticsCom from '../../orderManage/pendingDeliveryOrder/components/LogisticsCom'; import LogisticsCom from '../../orderManage/pendingDeliveryOrder/components/LogisticsCom';
import AppealDetail from '../../afterSale/components/detail'; import AppealDetail from '../../afterSale/components/detail';
import AfterLog from '../components/AfterLog';
export default () => { export default () => {
const table = useRef(); const table = useRef();
...@@ -22,6 +23,8 @@ export default () => { ...@@ -22,6 +23,8 @@ export default () => {
const [LogisticsComModalVisible, handleComModalVisible] = useState(false); const [LogisticsComModalVisible, handleComModalVisible] = useState(false);
const [appealDetailModal, setAppealDetailModal] = useState(false); const [appealDetailModal, setAppealDetailModal] = useState(false);
const [selectedRow, setSelectedRow] = useState({}); const [selectedRow, setSelectedRow] = useState({});
const [afterVisible, setAfterVisible] = useState(false);
const [afterList, setAfterList] = useState([]);
const viewDetail = async ({ serviceNo }) => { const viewDetail = async ({ serviceNo }) => {
const data = await orderDetail({ serviceNo }); const data = await orderDetail({ serviceNo });
setDetailInfo(data || []); setDetailInfo(data || []);
...@@ -37,6 +40,7 @@ export default () => { ...@@ -37,6 +40,7 @@ export default () => {
setProofsVisible(false); setProofsVisible(false);
handleComModalVisible(false); handleComModalVisible(false);
setAppealDetailModal(false); setAppealDetailModal(false);
setAfterVisible(false);
}; };
const reject = async ({ serviceNo }) => { const reject = async ({ serviceNo }) => {
setServiceNoInfo(serviceNo); setServiceNoInfo(serviceNo);
...@@ -60,6 +64,13 @@ export default () => { ...@@ -60,6 +64,13 @@ export default () => {
closeModal(true); closeModal(true);
} }
}; };
const viewLog = async r => {
const data = await getOpLog(r.serviceNo);
if (data?.data?.length) {
setAfterList(data.data);
setAfterVisible(true);
}
};
const handleCom = async ({ expressCompanyCode, deliveryNo }) => { const handleCom = async ({ expressCompanyCode, deliveryNo }) => {
const tempObj = { const tempObj = {
detailList: [], detailList: [],
...@@ -147,6 +158,9 @@ export default () => { ...@@ -147,6 +158,9 @@ export default () => {
> >
查看物流 查看物流
</Button>, </Button>,
<Button className="mr10 mt10" type="primary" onClick={() => viewLog(r)}>
查看记录
</Button>,
], ],
}, },
]; ];
...@@ -183,6 +197,7 @@ export default () => { ...@@ -183,6 +197,7 @@ export default () => {
modalVisible={appealDetailModal} modalVisible={appealDetailModal}
onCancel={closeModal} onCancel={closeModal}
></AppealDetail> ></AppealDetail>
<AfterLog visible={afterVisible} onCancel={closeModal} data={afterList} />,
</div> </div>
); );
}; };
import React, { useState, useRef } from 'react'; import React, { useState, useRef } from 'react';
import { notification, Button, Popconfirm } from 'antd'; import { notification, Button, Popconfirm, Modal, Statistic } from 'antd';
import ProTable from '@ant-design/pro-table'; import ProTable from '@ant-design/pro-table';
import moment from 'moment'; import moment from 'moment';
import _ from 'lodash'; import _ from 'lodash';
import { searchList, auditInfoApi, orderDetail } from '../services'; import { searchList, auditInfoApi, orderDetail, logisticsIntercept, getOpLog } from '../services';
import { columnSticData, appealType } from '../data'; import { columnSticData, appealType } from '../data';
import AuditModal from '../components/auditModal'; import AuditModal from '../components/auditModal';
import DetailTable from '../components/detailTable'; import DetailTable from '../components/detailTable';
import ProofsModal from '../components/proofsModal'; import ProofsModal from '../components/proofsModal';
import { getDetail } from '../../afterSale/appeal/services'; import { getDetail } from '../../afterSale/appeal/services';
import AppealDetail from '../../afterSale/components/detail'; import AppealDetail from '../../afterSale/components/detail';
import AfterLog from '../components/AfterLog';
const { Countdown } = Statistic;
const { confirm } = Modal;
export default () => { export default () => {
const table = useRef(); const table = useRef();
const [visible, setVisible] = useState(false); const [visible, setVisible] = useState(false);
...@@ -23,6 +27,8 @@ export default () => { ...@@ -23,6 +27,8 @@ export default () => {
const [selectedRow, setSelectedRow] = useState({}); const [selectedRow, setSelectedRow] = useState({});
const [timeString, setTimeString] = useState({}); const [timeString, setTimeString] = useState({});
const [time, setTime] = useState({}); const [time, setTime] = useState({});
const [afterVisible, setAfterVisible] = useState(false);
const [afterList, setAfterList] = useState([]);
const viewDetail = async ({ serviceNo }) => { const viewDetail = async ({ serviceNo }) => {
const data = await orderDetail({ serviceNo }); const data = await orderDetail({ serviceNo });
setDetailInfo(data || []); setDetailInfo(data || []);
...@@ -37,10 +43,11 @@ export default () => { ...@@ -37,10 +43,11 @@ export default () => {
setDetailVisible(false); setDetailVisible(false);
setProofsVisible(false); setProofsVisible(false);
setAppealDetailModal(false); setAppealDetailModal(false);
setAfterVisible(false);
}; };
const openAudit = async ({ serviceNo }) => { const openAudit = async ({ serviceNo, serviceType }) => {
const data = await auditInfoApi({ serviceNo }); const data = await auditInfoApi({ serviceNo });
setAuditInfo({ ...data?.data, serviceNo }); setAuditInfo({ ...data?.data, serviceNo, serviceType });
setVisible(true); setVisible(true);
}; };
const viewProofs = proofs => { const viewProofs = proofs => {
...@@ -56,39 +63,63 @@ export default () => { ...@@ -56,39 +63,63 @@ export default () => {
setAppealDetailModal(true); setAppealDetailModal(true);
setSelectedRow(detailData); setSelectedRow(detailData);
}; };
const renderContent = (record, index, action) => { const viewLog = async r => {
if (!time[record.serviceNo]) { const data = await getOpLog(r.serviceNo);
const serviceTime = moment(record.serviceTime).valueOf() + 24 * 3600 * 1000; if (data?.data?.length) {
const nowTime = moment(record.nowTime).valueOf(); setAfterList(data.data);
let timeNumber = (serviceTime - nowTime) / 1000; setAfterVisible(true);
time[record.serviceNo] = setInterval(() => {
if (timeNumber > 0) {
timeNumber -= 1;
// eslint-disable-next-line radix
const hours = parseInt((timeNumber / 3600) % 24)
.toString()
.padStart(2, '0');
// eslint-disable-next-line radix
const minutes = parseInt((timeNumber / 60) % 60)
.toString()
.padStart(2, '0');
// eslint-disable-next-line radix
const seconds = parseInt(timeNumber % 60)
.toString()
.padStart(2, '0');
const str = `${hours}${minutes}${seconds}秒`;
timeString[record.serviceNo] = str;
const strings = _.cloneDeep(timeString);
setTimeString(strings);
} else {
clearInterval(time[record.serviceNo]);
timeString[record.serviceNo] = '0时0分0秒';
const strings = _.cloneDeep(timeString);
setTimeString(strings);
} }
}, 1000); };
const openLogistics = r => {
confirm({
content: '请在48小时内完成物流包裹拦截,确认是否需要进行物流拦截?',
async onOk() {
const data = await logisticsIntercept({ serviceNo: r.serviceNo });
if (data.businessCode === '0000') {
notification.success({ message: '拦截成功' });
table.current.reload();
} else {
notification.error({ message: data.msg || '拦截失败' });
} }
},
onCancel() {
console.log('Cancel');
},
});
}; };
// const renderContent = (record, index, action) => {
// if (!time[record.serviceNo]) {
// const serviceTime = moment(record.approvalEndTime).valueOf();
// const nowTime = moment(record.nowTime).valueOf();
// let timeNumber = (serviceTime - nowTime) / 1000;
// time[record.serviceNo] = setInterval(() => {
// if (timeNumber > 0) {
// timeNumber -= 1;
// // eslint-disable-next-line radix
// const hours = parseInt(timeNumber / 3600)
// .toString()
// .padStart(2, '0');
// // eslint-disable-next-line radix
// const minutes = parseInt((timeNumber / 60) % 60)
// .toString()
// .padStart(2, '0');
// // eslint-disable-next-line radix
// const seconds = parseInt(timeNumber % 60)
// .toString()
// .padStart(2, '0');
// const str = `${hours}时${minutes}分${seconds}秒`;
// timeString[record.serviceNo] = str;
// const strings = _.cloneDeep(timeString);
// setTimeString(strings);
// } else {
// clearInterval(time[record.serviceNo]);
// timeString[record.serviceNo] = '0时0分0秒';
// const strings = _.cloneDeep(timeString);
// setTimeString(strings);
// }
// }, 1000);
// }
// };
const columns = [ const columns = [
{ {
title: '审核倒计时', title: '审核倒计时',
...@@ -96,12 +127,22 @@ export default () => { ...@@ -96,12 +127,22 @@ export default () => {
key: 'serviceTime', key: 'serviceTime',
hideInSearch: true, hideInSearch: true,
width: 150, width: 150,
render: (val, record, index, action) => [ // render: (val, record, index, action) => [
<span style={{ color: 'red' }}> // <span style={{ color: 'red' }}>
{renderContent(record, index, action)} // {renderContent(record, index, action)}
{timeString[record.serviceNo]} // {timeString[record.serviceNo]}
</span>, // </span>,
], // ],
render: (val, record) => {
const serviceTime = moment(record.approvalEndTime).valueOf();
return (
<Countdown
format="HH时mm分ss秒"
value={serviceTime}
valueStyle={{ color: 'red', fontSize: '14px' }}
/>
);
},
}, },
{ {
title: '售后状态', title: '售后状态',
...@@ -140,9 +181,20 @@ export default () => { ...@@ -140,9 +181,20 @@ export default () => {
<Button key="link1" onClick={() => openAudit(r)} className="mr10" type="primary"> <Button key="link1" onClick={() => openAudit(r)} className="mr10" type="primary">
审核 审核
</Button>, </Button>,
<Button key="link" onClick={() => viewDetail(r)} type="primary"> <Button
disabled={r.serviceType !== 1 || (r.serviceType === 1 && r.intercept)}
onClick={() => openLogistics(r)}
className="mr10"
type="primary"
>
物流拦截
</Button>,
<Button className="mr10 mt10" key="link" onClick={() => viewDetail(r)} type="primary">
订单详情 订单详情
</Button>, </Button>,
<Button type="primary" onClick={() => viewLog(r)}>
查看记录
</Button>,
], ],
}, },
]; ];
...@@ -172,6 +224,7 @@ export default () => { ...@@ -172,6 +224,7 @@ export default () => {
modalVisible={appealDetailModal} modalVisible={appealDetailModal}
onCancel={closeModal} onCancel={closeModal}
></AppealDetail> ></AppealDetail>
<AfterLog visible={afterVisible} onCancel={closeModal} data={afterList} />
</div> </div>
); );
}; };
/* eslint-disable no-restricted-syntax */
/* eslint-disable guard-for-in */
import React, { useState, useEffect } from 'react';
import { Modal, Timeline, Button } from 'antd';
import styles from '../styles.less';
const LogisticsCom = props => {
const { visible, onCancel, data } = props;
return (
<Modal
destroyOnClose
title="查看记录"
visible={visible}
onCancel={() => onCancel()}
onOk={() => onCancel()}
footer={false}
>
{data?.length ? (
<Timeline>
{data?.map((item, index) => (
// eslint-disable-next-line react/no-array-index-key
<Timeline.Item color={index > 0 ? 'gray' : 'blue'} key={index}>
<p>{item.optDesc}</p>
<p>{item.optTime}</p>
</Timeline.Item>
))}
</Timeline>
) : (
'暂无查看记录'
)}
<Button type="primary" onClick={props.onCancel} className={styles.logBtn}>
关闭
</Button>
</Modal>
);
};
export default LogisticsCom;
...@@ -13,7 +13,6 @@ const AuditModal = props => { ...@@ -13,7 +13,6 @@ const AuditModal = props => {
form: { getFieldDecorator, getFieldValue, validateFields, resetFields }, form: { getFieldDecorator, getFieldValue, validateFields, resetFields },
formData = {}, formData = {},
} = props; } = props;
const handleCancel = isSuccess => { const handleCancel = isSuccess => {
resetFields(); resetFields();
onCancel(isSuccess); onCancel(isSuccess);
...@@ -103,7 +102,7 @@ const AuditModal = props => { ...@@ -103,7 +102,7 @@ const AuditModal = props => {
/>, />,
)} )}
</FormItem> </FormItem>
{isAgree() && ( {isAgree() && +formData.serviceType === 2 && (
<div> <div>
<FormItem label="退货地址"> <FormItem label="退货地址">
{getFieldDecorator('receiveAddress', { {getFieldDecorator('receiveAddress', {
...@@ -189,6 +188,8 @@ const AuditModal = props => { ...@@ -189,6 +188,8 @@ const AuditModal = props => {
placeholder="请填写补充说明" placeholder="请填写补充说明"
allowClear allowClear
autoSize={{ minRows: 3, maxRows: 6 }} autoSize={{ minRows: 3, maxRows: 6 }}
maxLength={120}
showCount
/>, />,
)} )}
</FormItem> </FormItem>
......
...@@ -54,6 +54,17 @@ export const columnSticData = [ ...@@ -54,6 +54,17 @@ export const columnSticData = [
}, },
width: 100, width: 100,
}, },
{
title: '售后类型',
dataIndex: 'type',
hideInTable: true,
width: 120,
valueEnum: {
1: '仅退款',
2: '退货退款',
},
},
{ {
title: '收货人姓名', title: '收货人姓名',
dataIndex: 'receiverName', dataIndex: 'receiverName',
...@@ -92,7 +103,7 @@ export const columnSticData = [ ...@@ -92,7 +103,7 @@ export const columnSticData = [
hideInSearch: true, hideInSearch: true,
width: 120, width: 120,
valueEnum: { valueEnum: {
1: '退款不退货', 1: '仅退款',
2: '退货退款', 2: '退货退款',
}, },
}, },
......
...@@ -79,3 +79,17 @@ export async function trackInfo(params) { ...@@ -79,3 +79,17 @@ export async function trackInfo(params) {
} }
return {}; return {};
} }
// 物流拦截
export async function logisticsIntercept(params) {
return request.get('/api/kdsp/op/afs/shop/logisticsIntercept', {
params,
prefix: kdspApi,
});
}
// 售后操作日志
export async function getOpLog(params) {
return request.get(`/afterSaleAdmin/getOpLog/${params}`, {
prefix: kdspApi,
});
}
...@@ -16,3 +16,8 @@ ...@@ -16,3 +16,8 @@
max-height: 600px; max-height: 600px;
overflow: auto; overflow: auto;
} }
.logBtn {
display: inherit;
margin: 20px auto;
}
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