fix:修复快递归还异常bug

This commit is contained in:
2025-10-10 20:25:57 +08:00
parent a67030ec43
commit 30e298d9d2
7 changed files with 239 additions and 216 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
// export const URL = "https://my.gxfs123.com/api" //正式服务器 // export const URL = "https://my.gxfs123.com/api" //正式服务器
export const URL = "https://fansdev.gxfs123.com/api" //测试服务器 export const URL = "https://fansdev.gxfs123.com/api" //测试服务器
// export const URL = "http://192.168.5.22:8080" //本地调试 // export const URL = "http://192.168.169.66:8080" //本地调试
// export const URL = "http://127.0.0.1:8080" //本地调试 // export const URL = "http://127.0.0.1:8080" //本地调试
export const appid = "wx2165f0be356ae7a9" //小程序appid export const appid = "wx2165f0be356ae7a9" //小程序appid
+3 -3
View File
@@ -109,10 +109,10 @@ export const overOrderById = (orderId) => {
//立即租借 //立即租借
export const rentPowerBank = (deviceNo, phone) => { export const rentPowerBank = (deviceNo, phone) => {
return request({ return request({
url: '/app/device/rentPowerBank', url: `/app/device/rentPowerBank?deviceNo=${deviceNo}`,
method: 'post', method: 'post',
data: { data: {
deviceNo, // deviceNo,
phone phone
} }
}) })
@@ -210,7 +210,7 @@ export const getPotionsDetail = (data) => {
export const uploadOssResource = (filePath) => { export const uploadOssResource = (filePath) => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
uni.uploadFile({ uni.uploadFile({
url: URL + '/resource/oss/upload', url: URL + '/manager/upload',
filePath, filePath,
name: 'file', name: 'file',
header: { header: {
+1 -1
View File
@@ -195,7 +195,7 @@ const handleSubmit = async () => {
res = await fillExpressTrackingNumber({ id: Number(recordId.value), logisticsTrackingNumber: trackingNumber.value }) res = await fillExpressTrackingNumber({ id: Number(recordId.value), logisticsTrackingNumber: trackingNumber.value })
} else { } else {
res = await applyExpressReturn({ res = await applyExpressReturn({
orderId: Number(orderId.value), orderId: orderId.value,
logisticsTrackingNumber: trackingNumber.value, logisticsTrackingNumber: trackingNumber.value,
remark: '' remark: ''
}) })
+219 -206
View File
@@ -19,15 +19,16 @@
<!-- 中间内容 --> <!-- 中间内容 -->
<view class="item-content"> <view class="item-content">
<view class="item-header"> <view class="item-header">
<text class="express-company">{{ item.expressCompany }}</text> <text class="tracking-number">运单号{{ item.logisticsTrackingNumber }}</text>
<text class="tracking-number">运单号{{ item.trackingNumber }}</text> <!-- <text class="express-company">{{ item.expressCompany }}</text> -->
</view> </view>
<view class="item-details"> <view class="item-details">
<text class="return-address">归还地址{{ item.returnAddress }}</text> <text class="return-address">归还地址{{ item.returnAddress }}</text>
<text class="return-time">归还时间{{ item.returnTime }}</text> <text class="return-time">填写时间{{ item.returnTime }}</text>
</view> </view>
<view class="item-footer"> <view class="item-footer">
<text class="package-info">包裹{{ item.packageType }} | {{ item.weight }}</text> <text class="package-info">订单号{{ item.orderId }}</text>
<text class="user-phone" v-if="item.userPhone">用户电话{{ item.userPhone }}</text>
</view> </view>
</view> </view>
@@ -57,242 +58,254 @@ const loading = ref(false)
const query = ref({ pageNum: 1, pageSize: 20 }) const query = ref({ pageNum: 1, pageSize: 20 })
const loadList = async () => { const loadList = async () => {
try { try {
loading.value = true loading.value = true
const res = await getExpressReturnList(query.value) const res = await getExpressReturnList(query.value)
if (res && res.code === 200) { if (res && res.code === 200) {
// 将后端字段映射到前端展示字段 // 将后端字段映射到前端展示字段
const rows = (res.data && (res.data.rows || res.data)) || [] const rows = (res.data && (res.data.rows || res.data)) || []
returnList.value = rows.map(r => ({ returnList.value = rows.map(r => ({
id: r.id, id: r.id,
expressCompany: r.expressCompany || r.company || '-', expressCompany: r.expressCompany || r.company || '待填写',
trackingNumber: r.logisticsTrackingNumber || r.trackingNumber || '-', trackingNumber: r.logisticsTrackingNumber || r.trackingNumber || '待填写',
returnAddress: r.returnAddress || r.address || '-', returnAddress: r.returnAddress || r.address || '待填写',
returnTime: r.createTime || r.returnTime || '-', returnTime: r.expressFillTime || r.createTime || r.returnTime || '待填写',
packageType: r.packageType || '-', packageType: r.packageType || '待填写',
weight: r.weight || '-', weight: r.weight || '待填写',
status: mapStatus(r.status), status: mapStatus(r.status),
rawStatus: r.status rawStatus: r.status,
})) userPhone: r.userPhone,
} else { orderId: r.orderId,
throw new Error(res?.msg || '获取列表失败') remark: r.remark
} }))
} catch (e) { } else {
uni.showToast({ title: e.message || '加载失败', icon: 'none' }) throw new Error(res?.msg || '获取列表失败')
} finally { }
loading.value = false } catch (e) {
} uni.showToast({ title: e.message || '加载失败', icon: 'none' })
} finally {
loading.value = false
}
} }
// 状态映射 // 状态映射
const mapStatus = (status) => { const mapStatus = (status) => {
// 文档:0-未填写 1-已填写 2-已取消 3-审批通过 4-审批拒绝 5-订单完成 // 文档:0-未填写 1-已填写 2-已取消 3-审批通过 4-审批拒绝 5-订单完成
if (status === 5) return 'completed' if (status === 5) return 'completed'
if (status === 3 || status === 1) return 'processing' if (status === 3 || status === 1) return 'processing'
if (status === 4 || status === 2 || status === 0) return 'pending' if (status === 4 || status === 2 || status === 0) return 'pending'
return 'pending' return 'pending'
} }
const getStatusClass = (status) => ({ const getStatusClass = (status) => ({
'completed': 'status-completed', 'completed': 'status-completed',
'processing': 'status-processing', 'processing': 'status-processing',
'pending': 'status-pending' 'pending': 'status-pending'
}[status] || 'status-pending') }[status] || 'status-pending')
const getStatusIcon = (status) => ({ const getStatusIcon = (status) => ({
'completed': '✓', 'completed': '✓',
'processing': '⏳', 'processing': '⏳',
'pending': '⏸' 'pending': '⏸'
}[status] || '⏸') }[status] || '⏸')
const getStatusText = (status) => ({ const getStatusText = (status) => ({
'completed': '已完成', 'completed': '已完成',
'processing': '处理中', 'processing': '处理中',
'pending': '待处理' 'pending': '待处理'
}[status] || '待处理') }[status] || '待处理')
// 点击列表项 // 点击列表项
const handleItemClick = (item) => { const handleItemClick = (item) => {
console.log('点击了归还记录:', item) console.log('点击了归还记录:', item)
// 未填写(status=0 -> mapped 'pending')时跳转到补填页,其它跳详情 // 未填写(status=0 -> mapped 'pending')时跳转到补填页,其它跳详情
if (item && item.rawStatus === 0) { if (item && item.rawStatus === 0) {
uni.navigateTo({ url: `/pages/expressReturn/addExpressReturn?id=${item.id}` }) uni.navigateTo({ url: `/pages/expressReturn/addExpressReturn?id=${item.id}` })
} else { } else {
uni.navigateTo({ url: `/pages/expressReturn/detail?id=${item.id}` }) uni.navigateTo({ url: `/pages/expressReturn/detail?id=${item.id}` })
}
} }
}
onMounted(loadList) onMounted(loadList)
</script> </script>
<style lang="scss"> <style lang="scss">
.express-return-container { .express-return-container {
min-height: 100vh; min-height: 100vh;
background-color: #f8f9fa;
padding: 20rpx;
}
.page-header {
margin-bottom: 40rpx;
padding: 20rpx 0;
}
.page-title {
display: block;
font-size: 36rpx;
font-weight: 600;
color: #2c3e50;
margin-bottom: 10rpx;
}
.page-subtitle {
display: block;
font-size: 28rpx;
color: #7f8c8d;
}
.list-container {
background-color: transparent;
}
.return-item {
display: flex;
align-items: center;
padding: 30rpx 24rpx;
background-color: #ffffff;
border-radius: 16rpx;
margin-bottom: 20rpx;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.08);
transition: background-color 0.2s ease;
&:last-child {
margin-bottom: 0;
}
&:active {
background-color: #f8f9fa; background-color: #f8f9fa;
padding: 20rpx; }
}
.item-icon {
margin-right: 24rpx;
}
.icon-wrapper {
width: 80rpx;
height: 80rpx;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 32rpx;
font-weight: bold;
&.status-completed {
background-color: #e8f5e8;
color: #27ae60;
} }
.page-header { &.status-processing {
margin-bottom: 40rpx; background-color: #fff3cd;
padding: 20rpx 0; color: #f39c12;
} }
.page-title { &.status-pending {
display: block; background-color: #f8f9fa;
font-size: 36rpx; color: #6c757d;
font-weight: 600; }
color: #2c3e50; }
margin-bottom: 10rpx;
.item-content {
flex: 1;
margin-right: 20rpx;
}
.item-header {
margin-bottom: 12rpx;
}
.express-company {
display: block;
font-size: 32rpx;
font-weight: 600;
color: #2c3e50;
margin-bottom: 8rpx;
}
.tracking-number {
display: block;
font-size: 26rpx;
color: #7f8c8d;
}
.item-details {
margin-bottom: 12rpx;
}
.return-address,
.return-time {
display: block;
font-size: 26rpx;
color: #34495e;
line-height: 1.5;
margin-bottom: 6rpx;
}
.item-footer {
margin-top: 8rpx;
display: flex;
flex-direction: column;
align-items: flex-start;
}
.package-info {
font-size: 24rpx;
color: #95a5a6;
margin-bottom: 4rpx;
}
.user-phone {
font-size: 24rpx;
color: #95a5a6;
}
.item-status {
text-align: right;
}
.status-text {
font-size: 26rpx;
font-weight: 500;
padding: 8rpx 16rpx;
border-radius: 20rpx;
&.status-completed {
background-color: #e8f5e8;
color: #27ae60;
} }
.page-subtitle { &.status-processing {
display: block; background-color: #fff3cd;
font-size: 28rpx; color: #f39c12;
color: #7f8c8d;
} }
.list-container { &.status-pending {
background-color: transparent; background-color: #f8f9fa;
color: #6c757d;
} }
}
.return-item { .empty-state {
display: flex; display: flex;
align-items: center; flex-direction: column;
padding: 30rpx 24rpx; align-items: center;
background-color: #ffffff; justify-content: center;
border-radius: 16rpx; padding: 120rpx 40rpx;
margin-bottom: 20rpx; // background-color: #ffffff;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.08); // border-radius: 16rpx;
transition: background-color 0.2s ease; // box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.08);
}
&:last-child { .empty-icon {
margin-bottom: 0; font-size: 80rpx;
} margin-bottom: 20rpx;
}
&:active { .empty-text {
background-color: #f8f9fa; font-size: 28rpx;
} color: #7f8c8d;
} }
.item-icon {
margin-right: 24rpx;
}
.icon-wrapper {
width: 80rpx;
height: 80rpx;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 32rpx;
font-weight: bold;
&.status-completed {
background-color: #e8f5e8;
color: #27ae60;
}
&.status-processing {
background-color: #fff3cd;
color: #f39c12;
}
&.status-pending {
background-color: #f8f9fa;
color: #6c757d;
}
}
.item-content {
flex: 1;
margin-right: 20rpx;
}
.item-header {
margin-bottom: 12rpx;
}
.express-company {
display: block;
font-size: 32rpx;
font-weight: 600;
color: #2c3e50;
margin-bottom: 8rpx;
}
.tracking-number {
display: block;
font-size: 26rpx;
color: #7f8c8d;
}
.item-details {
margin-bottom: 12rpx;
}
.return-address,
.return-time {
display: block;
font-size: 26rpx;
color: #34495e;
line-height: 1.5;
margin-bottom: 6rpx;
}
.item-footer {
margin-top: 8rpx;
}
.package-info {
font-size: 24rpx;
color: #95a5a6;
}
.item-status {
text-align: right;
}
.status-text {
font-size: 26rpx;
font-weight: 500;
padding: 8rpx 16rpx;
border-radius: 20rpx;
&.status-completed {
background-color: #e8f5e8;
color: #27ae60;
}
&.status-processing {
background-color: #fff3cd;
color: #f39c12;
}
&.status-pending {
background-color: #f8f9fa;
color: #6c757d;
}
}
.empty-state {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 120rpx 40rpx;
// background-color: #ffffff;
// border-radius: 16rpx;
// box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.08);
}
.empty-icon {
font-size: 80rpx;
margin-bottom: 20rpx;
}
.empty-text {
font-size: 28rpx;
color: #7f8c8d;
}
</style> </style>
+4 -3
View File
@@ -21,7 +21,7 @@
</view> </view>
<!-- 图片上传 --> <!-- 图片上传 -->
<!-- <view class="upload-section"> <view class="upload-section">
<view class="section-title">图片上传选填</view> <view class="section-title">图片上传选填</view>
<view class="upload-grid"> <view class="upload-grid">
<view class="upload-item" v-for="(img, index) in images" :key="index"> <view class="upload-item" v-for="(img, index) in images" :key="index">
@@ -33,7 +33,7 @@
<text class="tip">上传图片</text> <text class="tip">上传图片</text>
</view> </view>
</view> </view>
</view> --> </view>
<!-- 联系方式 --> <!-- 联系方式 -->
<view class="contact-section"> <view class="contact-section">
@@ -80,6 +80,7 @@
uni.chooseImage({ uni.chooseImage({
count: 3 - images.value.length, count: 3 - images.value.length,
success: async (res) => { success: async (res) => {
console.log(res);
const toUpload = res.tempFilePaths || [] const toUpload = res.tempFilePaths || []
for (const localPath of toUpload) { for (const localPath of toUpload) {
// 先追加本地预览,再上传并替换为远程URL // 先追加本地预览,再上传并替换为远程URL
@@ -142,7 +143,7 @@
type: paramsType.value, type: paramsType.value,
content: description.value, content: description.value,
phone: contact.value, phone: contact.value,
// images: images.value picturePath: images.value
} }
uni.request({ uni.request({
+8
View File
@@ -163,6 +163,10 @@
'order_cancelled': { 'order_cancelled': {
text: '已取消', text: '已取消',
class: 'status-cancelled' class: 'status-cancelled'
},
'express_return': {
text: '快递归还',
class: 'status-express-return'
} }
}); });
@@ -501,6 +505,10 @@
&.status-cancelled { &.status-cancelled {
color: #9E9E9E; color: #9E9E9E;
} }
&.status-express-return {
color: #FF9800;
}
} }
} }
+3 -2
View File
@@ -119,7 +119,7 @@
<view v-if="orderInfo.orderStatus === 'in_used'" class="action-item secondary" @click="checkReturnStatus"> <view v-if="orderInfo.orderStatus === 'in_used'" class="action-item secondary" @click="checkReturnStatus">
刷新状态</view> 刷新状态</view>
<view v-if="orderInfo.orderStatus === 'in_used' && !showExpressAction" class="action-item primary"> <view v-if="orderInfo.orderStatus === 'in_used' && !showExpressAction" class="action-item primary">
{{ formatHms(countdownRemaining) }} 后可发起快递归还 倒计时{{ formatHms(countdownRemaining) }}
</view> </view>
<view v-if="orderInfo.orderStatus === 'in_used' && showExpressAction" class="action-item primary" @click="expressRetrunOrder"> <view v-if="orderInfo.orderStatus === 'in_used' && showExpressAction" class="action-item primary" @click="expressRetrunOrder">
暂停计费快递归还 暂停计费快递归还
@@ -178,7 +178,8 @@
statusCheckInterval: 5000, // 5秒检查一次 statusCheckInterval: 5000, // 5秒检查一次
isPageActive: false, // 跟踪页面是否活跃 isPageActive: false, // 跟踪页面是否活跃
// 倒计时与快递归还触发(默认4小时=14400秒,可被配置覆盖) // 倒计时与快递归还触发(默认4小时=14400秒,可被配置覆盖)
countdownRemaining: 14400, // countdownRemaining: 14400,
countdownRemaining: 0,
showExpressAction: false, showExpressAction: false,
countdownTimer: null countdownTimer: null
} }