feat:新增快递归还相关接口
This commit is contained in:
@@ -238,3 +238,71 @@ export const uploadOssResource = (filePath) => {
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// 获取系统配置(预留接口)
|
||||
// 期望后端返回形如:{ code: 200, data: { expressReturnCountdownSeconds: number } }
|
||||
export const getSystemConfig = () => {
|
||||
return request({
|
||||
url: '/app/system/config',
|
||||
method: 'get',
|
||||
hideLoading: true
|
||||
})
|
||||
}
|
||||
|
||||
// ===================== 快递归还相关接口 =====================
|
||||
// 1) 申请快递归还
|
||||
export const applyExpressReturn = (data) => {
|
||||
// data: { orderId: number, logisticsTrackingNumber?: string, remark?: string }
|
||||
return request({
|
||||
url: '/app/express-return/apply',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 2) 补填快递单号
|
||||
export const fillExpressTrackingNumber = (data) => {
|
||||
// data: { id: number, logisticsTrackingNumber: string }
|
||||
return request({
|
||||
url: '/app/express-return/fill-tracking-number',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 3) 查询快递归还记录列表
|
||||
export const getExpressReturnList = (params) => {
|
||||
// params: { orderId?: number, status?: number, logisticsTrackingNumber?: string, pageNum?: number, pageSize?: number }
|
||||
return request({
|
||||
url: '/app/express-return/list',
|
||||
method: 'get',
|
||||
data: params,
|
||||
hideLoading: true
|
||||
})
|
||||
}
|
||||
|
||||
// 4) 根据订单ID查询快递归还记录
|
||||
export const getExpressReturnByOrder = (orderId) => {
|
||||
return request({
|
||||
url: `/app/express-return/by-order/${orderId}`,
|
||||
method: 'get',
|
||||
hideLoading: true
|
||||
})
|
||||
}
|
||||
|
||||
// 5) 获取快递归还记录详情
|
||||
export const getExpressReturnDetail = (id) => {
|
||||
return request({
|
||||
url: `/app/express-return/${id}`,
|
||||
method: 'get',
|
||||
hideLoading: true
|
||||
})
|
||||
}
|
||||
|
||||
// 6) 取消快递归还申请
|
||||
export const cancelExpressReturn = (id) => {
|
||||
return request({
|
||||
url: `/app/express-return/cancel/${id}`,
|
||||
method: 'post'
|
||||
})
|
||||
}
|
||||
+5
-34
@@ -500,41 +500,12 @@
|
||||
try {
|
||||
// 调用微信支付分小程序
|
||||
const payResult = await initiateWeChatScorePayment(res);
|
||||
// 支付成功后的逻辑处理 - 可以根据业务需求决定是否跳转或刷新页面
|
||||
// 成功则跳转等待页,轮询在等待页处理
|
||||
if (payResult.errCode == '0') {
|
||||
const res = await getOrderByOrderNoScorePayStatus(order.orderNo);
|
||||
console.log(res.data.orderStatus);
|
||||
if (res.data.orderStatus == 'in_used') {
|
||||
// 用户完成了支付流程,可以查询订单状态或跳转到订单页
|
||||
uni.showToast({
|
||||
title: '设备租借成功',
|
||||
icon: 'success'
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
// 延迟跳转到租用中页面或订单页
|
||||
uni.redirectTo({
|
||||
url: '/pages/order/index'
|
||||
});
|
||||
}, 1500);
|
||||
} else if (res.data.orderStatus == 'waiting_for_payment') {
|
||||
uni.showToast({
|
||||
title: '设备租借失败,订单已取消',
|
||||
icon: 'error'
|
||||
});
|
||||
|
||||
await cancelOrder({
|
||||
orderId: order.orderNo
|
||||
});
|
||||
// 延迟跳转到租用中页面或订单页
|
||||
setTimeout(() => {
|
||||
uni.switchTab({
|
||||
url: '/pages/index/index'
|
||||
});
|
||||
}, 1500)
|
||||
|
||||
}
|
||||
// 用户取消等其他情况,不做特殊处理
|
||||
uni.redirectTo({
|
||||
url: `/pages/waiting/index?orderNo=${order.orderNo}&deviceId=${deviceId.value}`
|
||||
});
|
||||
return;
|
||||
}
|
||||
// 用户取消等其他情况,不做特殊处理
|
||||
} catch (payError) {
|
||||
|
||||
@@ -45,11 +45,17 @@
|
||||
import {
|
||||
onLoad
|
||||
} from '@dcloudio/uni-app'
|
||||
import {
|
||||
queryById
|
||||
} from '@/config/user.js'
|
||||
import {
|
||||
queryById,
|
||||
applyExpressReturn,
|
||||
getExpressReturnByOrder,
|
||||
getExpressReturnDetail,
|
||||
fillExpressTrackingNumber
|
||||
} from '@/config/user.js'
|
||||
|
||||
const orderId = ref('')
|
||||
const recordId = ref('')
|
||||
const isFillMode = ref(false)
|
||||
const orderInfo = reactive({
|
||||
orderNo: '',
|
||||
deviceNo: '',
|
||||
@@ -62,6 +68,14 @@
|
||||
|
||||
onLoad(async (options) => {
|
||||
orderId.value = options?.orderId || ''
|
||||
recordId.value = options?.id || ''
|
||||
isFillMode.value = !!recordId.value
|
||||
|
||||
if (isFillMode.value) {
|
||||
await loadRecordAndOrderByRecord()
|
||||
return
|
||||
}
|
||||
|
||||
if (!orderId.value) {
|
||||
uni.showToast({
|
||||
title: '缺少订单号',
|
||||
@@ -73,6 +87,7 @@
|
||||
return
|
||||
}
|
||||
await loadOrder()
|
||||
await checkExistingExpressReturn()
|
||||
})
|
||||
|
||||
const loadOrder = async () => {
|
||||
@@ -100,6 +115,57 @@
|
||||
}
|
||||
}
|
||||
|
||||
const loadRecordAndOrderByRecord = async () => {
|
||||
try {
|
||||
uni.showLoading({ title: '加载中' })
|
||||
const res = await getExpressReturnDetail(recordId.value)
|
||||
if (res?.code === 200 && res.data) {
|
||||
if (res.data.orderId) {
|
||||
orderId.value = res.data.orderId
|
||||
await loadOrder()
|
||||
}
|
||||
if (res.data.userPhone && !phone.value) phone.value = res.data.userPhone
|
||||
} else {
|
||||
throw new Error(res?.msg || '获取记录失败')
|
||||
}
|
||||
} catch (e) {
|
||||
uni.showToast({ title: e.message || '加载失败', icon: 'none' })
|
||||
} finally {
|
||||
uni.hideLoading()
|
||||
}
|
||||
}
|
||||
|
||||
const checkExistingExpressReturn = async () => {
|
||||
try {
|
||||
const res = await getExpressReturnByOrder(orderId.value)
|
||||
if (res && res.code === 200 && res.data) {
|
||||
const rec = res.data
|
||||
if (rec.status === 0) {
|
||||
recordId.value = rec.id
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '已存在快递归还申请,是否前往补填快递单号?',
|
||||
confirmText: '去补填',
|
||||
cancelText: '取消',
|
||||
success: (r) => {
|
||||
if (r.confirm) {
|
||||
uni.redirectTo({ url: `/pages/expressReturn/addExpressReturn?id=${rec.id}` })
|
||||
}
|
||||
}
|
||||
})
|
||||
return
|
||||
} else {
|
||||
uni.showToast({ title: '已有归还记录', icon: 'none' })
|
||||
setTimeout(() => {
|
||||
uni.redirectTo({ url: `/pages/expressReturn/detail?id=${rec.id}` })
|
||||
}, 800)
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
// 无记录则忽略
|
||||
}
|
||||
}
|
||||
|
||||
const validate = () => {
|
||||
// 简单手机检查(兼容座机/国际号,放宽到至少 5 位数字)
|
||||
const digits = (phone.value || '').replace(/\D/g, '')
|
||||
@@ -110,7 +176,7 @@
|
||||
})
|
||||
return false
|
||||
}
|
||||
if (!trackingNumber.value) {
|
||||
if (isFillMode.value && !trackingNumber.value) {
|
||||
uni.showToast({
|
||||
title: '请填写快递单号',
|
||||
icon: 'none'
|
||||
@@ -120,38 +186,32 @@
|
||||
return true
|
||||
}
|
||||
|
||||
const handleSubmit = async () => {
|
||||
if (!validate()) return
|
||||
// 这里保留与后端联调位置(未给出具体提交接口,先本地成功提示)
|
||||
try {
|
||||
uni.showLoading({
|
||||
title: '提交中'
|
||||
})
|
||||
|
||||
// 示例:
|
||||
// await uni.request({
|
||||
// url: `${URL}/app/express-return/submit`,
|
||||
// method: 'POST',
|
||||
// header: { 'Authorization': `Bearer ${uni.getStorageSync('token')}` },
|
||||
// data: { orderId: orderId.value, phone: phone.value, trackingNumber: trackingNumber.value }
|
||||
// })
|
||||
await new Promise(r => setTimeout(r, 500))
|
||||
uni.showToast({
|
||||
title: '提交成功',
|
||||
icon: 'success'
|
||||
})
|
||||
setTimeout(() => {
|
||||
uni.navigateBack()
|
||||
}, 800)
|
||||
} catch (e) {
|
||||
uni.showToast({
|
||||
title: e.message || '提交失败',
|
||||
icon: 'none'
|
||||
})
|
||||
} finally {
|
||||
uni.hideLoading()
|
||||
}
|
||||
}
|
||||
const handleSubmit = async () => {
|
||||
if (!validate()) return
|
||||
try {
|
||||
uni.showLoading({ title: isFillMode.value ? '补填中' : '提交中' })
|
||||
let res
|
||||
if (isFillMode.value) {
|
||||
res = await fillExpressTrackingNumber({ id: Number(recordId.value), logisticsTrackingNumber: trackingNumber.value })
|
||||
} else {
|
||||
res = await applyExpressReturn({
|
||||
orderId: Number(orderId.value),
|
||||
logisticsTrackingNumber: trackingNumber.value,
|
||||
remark: ''
|
||||
})
|
||||
}
|
||||
if (res && res.code === 200) {
|
||||
uni.showToast({ title: isFillMode.value ? '补填成功' : '提交成功', icon: 'success' })
|
||||
setTimeout(() => { uni.navigateBack() }, 800)
|
||||
} else {
|
||||
throw new Error(res?.msg || (isFillMode.value ? '补填失败' : '提交失败'))
|
||||
}
|
||||
} catch (e) {
|
||||
uni.showToast({ title: e.message || (isFillMode.value ? '补填失败' : '提交失败'), icon: 'none' })
|
||||
} finally {
|
||||
uni.hideLoading()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -87,20 +87,21 @@
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { getExpressReturnDetail } from '@/config/user.js'
|
||||
|
||||
// 详情数据
|
||||
const detailData = ref({
|
||||
id: 1,
|
||||
expressCompany: '顺丰速运',
|
||||
trackingNumber: 'SF1234567890123',
|
||||
returnAddress: '北京市朝阳区建国门外大街1号',
|
||||
returnTime: '2024-01-15 14:30:00',
|
||||
processTime: '2024-01-15 15:00:00',
|
||||
completeTime: '2024-01-15 16:30:00',
|
||||
packageType: '文件',
|
||||
weight: '0.5kg',
|
||||
status: 'completed',
|
||||
remark: '包裹已安全送达,感谢您的使用!'
|
||||
id: '',
|
||||
expressCompany: '-',
|
||||
trackingNumber: '-',
|
||||
returnAddress: '-',
|
||||
returnTime: '-',
|
||||
processTime: '-',
|
||||
completeTime: '-',
|
||||
packageType: '-',
|
||||
weight: '-',
|
||||
status: 'pending',
|
||||
remark: ''
|
||||
})
|
||||
|
||||
// 获取状态样式类
|
||||
@@ -174,18 +175,46 @@ const handleContactService = () => {
|
||||
}
|
||||
|
||||
// 页面加载时获取详情数据
|
||||
onMounted(() => {
|
||||
// 这里可以根据路由参数获取详情数据
|
||||
const pages = getCurrentPages()
|
||||
const currentPage = pages[pages.length - 1]
|
||||
const options = currentPage.options
|
||||
|
||||
if (options.id) {
|
||||
// 根据ID获取详情数据
|
||||
console.log('获取详情数据,ID:', options.id)
|
||||
// 这里可以调用API获取详情数据
|
||||
}
|
||||
onMounted(async () => {
|
||||
const pages = getCurrentPages()
|
||||
const currentPage = pages[pages.length - 1]
|
||||
const options = currentPage.options || {}
|
||||
if (!options.id) return
|
||||
try {
|
||||
uni.showLoading({ title: '加载中' })
|
||||
const res = await getExpressReturnDetail(options.id)
|
||||
if (res && res.code === 200 && res.data) {
|
||||
const r = res.data
|
||||
detailData.value = {
|
||||
id: r.id,
|
||||
expressCompany: r.expressCompany || r.company || '-',
|
||||
trackingNumber: r.logisticsTrackingNumber || r.trackingNumber || '-',
|
||||
returnAddress: r.returnAddress || r.address || '-',
|
||||
returnTime: r.createTime || r.returnTime || '-',
|
||||
processTime: r.processTime || '-',
|
||||
completeTime: r.completeTime || '-',
|
||||
packageType: r.packageType || '-',
|
||||
weight: r.weight || '-',
|
||||
status: mapStatus(r.status),
|
||||
remark: r.remark || ''
|
||||
}
|
||||
} else {
|
||||
throw new Error(res?.msg || '获取详情失败')
|
||||
}
|
||||
} catch (e) {
|
||||
uni.showToast({ title: e.message || '加载失败', icon: 'none' })
|
||||
} finally {
|
||||
uni.hideLoading()
|
||||
}
|
||||
})
|
||||
|
||||
// 状态映射
|
||||
const mapStatus = (status) => {
|
||||
if (status === 5) return 'completed'
|
||||
if (status === 3 || status === 1) return 'processing'
|
||||
if (status === 4 || status === 2 || status === 0) return 'pending'
|
||||
return 'pending'
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
@@ -49,71 +49,80 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
ref
|
||||
} from 'vue'
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { getExpressReturnList } from '@/config/user.js'
|
||||
|
||||
// 模拟数据
|
||||
const returnList = ref([{
|
||||
id: 1,
|
||||
expressCompany: '顺丰速运',
|
||||
trackingNumber: 'SF1234567890123',
|
||||
returnAddress: '北京市朝阳区建国门外大街1号',
|
||||
returnTime: '2024-01-15 14:30:00',
|
||||
packageType: '文件',
|
||||
weight: '0.5kg',
|
||||
status: 'completed'
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
expressCompany: '圆通快递',
|
||||
trackingNumber: 'YT9876543210987',
|
||||
returnAddress: '上海市浦东新区陆家嘴环路1000号',
|
||||
returnTime: '2024-01-14 09:15:00',
|
||||
packageType: '电子产品',
|
||||
weight: '2.1kg',
|
||||
status: 'processing'
|
||||
}
|
||||
])
|
||||
const returnList = ref([])
|
||||
const loading = ref(false)
|
||||
const query = ref({ pageNum: 1, pageSize: 20 })
|
||||
|
||||
// 获取状态样式类
|
||||
const getStatusClass = (status) => {
|
||||
const statusMap = {
|
||||
'completed': 'status-completed',
|
||||
'processing': 'status-processing',
|
||||
'pending': 'status-pending'
|
||||
}
|
||||
return statusMap[status] || 'status-pending'
|
||||
}
|
||||
const loadList = async () => {
|
||||
try {
|
||||
loading.value = true
|
||||
const res = await getExpressReturnList(query.value)
|
||||
if (res && res.code === 200) {
|
||||
// 将后端字段映射到前端展示字段
|
||||
const rows = (res.data && (res.data.rows || res.data)) || []
|
||||
returnList.value = rows.map(r => ({
|
||||
id: r.id,
|
||||
expressCompany: r.expressCompany || r.company || '-',
|
||||
trackingNumber: r.logisticsTrackingNumber || r.trackingNumber || '-',
|
||||
returnAddress: r.returnAddress || r.address || '-',
|
||||
returnTime: r.createTime || r.returnTime || '-',
|
||||
packageType: r.packageType || '-',
|
||||
weight: r.weight || '-',
|
||||
status: mapStatus(r.status),
|
||||
rawStatus: r.status
|
||||
}))
|
||||
} else {
|
||||
throw new Error(res?.msg || '获取列表失败')
|
||||
}
|
||||
} catch (e) {
|
||||
uni.showToast({ title: e.message || '加载失败', icon: 'none' })
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 获取状态图标
|
||||
const getStatusIcon = (status) => {
|
||||
const iconMap = {
|
||||
'completed': '✓',
|
||||
'processing': '⏳',
|
||||
'pending': '⏸'
|
||||
}
|
||||
return iconMap[status] || '⏸'
|
||||
}
|
||||
// 状态映射
|
||||
const mapStatus = (status) => {
|
||||
// 文档:0-未填写 1-已填写 2-已取消 3-审批通过 4-审批拒绝 5-订单完成
|
||||
if (status === 5) return 'completed'
|
||||
if (status === 3 || status === 1) return 'processing'
|
||||
if (status === 4 || status === 2 || status === 0) return 'pending'
|
||||
return 'pending'
|
||||
}
|
||||
|
||||
// 获取状态文本
|
||||
const getStatusText = (status) => {
|
||||
const textMap = {
|
||||
'completed': '已完成',
|
||||
'processing': '处理中',
|
||||
'pending': '待处理'
|
||||
}
|
||||
return textMap[status] || '待处理'
|
||||
}
|
||||
const getStatusClass = (status) => ({
|
||||
'completed': 'status-completed',
|
||||
'processing': 'status-processing',
|
||||
'pending': 'status-pending'
|
||||
}[status] || 'status-pending')
|
||||
|
||||
// 点击列表项
|
||||
const handleItemClick = (item) => {
|
||||
const getStatusIcon = (status) => ({
|
||||
'completed': '✓',
|
||||
'processing': '⏳',
|
||||
'pending': '⏸'
|
||||
}[status] || '⏸')
|
||||
|
||||
const getStatusText = (status) => ({
|
||||
'completed': '已完成',
|
||||
'processing': '处理中',
|
||||
'pending': '待处理'
|
||||
}[status] || '待处理')
|
||||
|
||||
// 点击列表项
|
||||
const handleItemClick = (item) => {
|
||||
console.log('点击了归还记录:', item)
|
||||
// 跳转到详情页面
|
||||
uni.navigateTo({
|
||||
url: `/pages/expressReturn/detail?id=${item.id}`
|
||||
})
|
||||
// 未填写(status=0 -> mapped 'pending')时跳转到补填页,其它跳详情
|
||||
if (item && item.rawStatus === 0) {
|
||||
uni.navigateTo({ url: `/pages/expressReturn/addExpressReturn?id=${item.id}` })
|
||||
} else {
|
||||
uni.navigateTo({ url: `/pages/expressReturn/detail?id=${item.id}` })
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(loadList)
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
+2
-2
@@ -77,7 +77,7 @@
|
||||
<uni-icons type="right" size="16" color="#999"></uni-icons>
|
||||
</view>
|
||||
</view>
|
||||
<!-- <view class="function-item" @click="navigateTo('/pages/expressReturn/index')">
|
||||
<view class="function-item" @click="navigateTo('/pages/expressReturn/index')">
|
||||
<view class="item-left">
|
||||
<view class="item-icon">
|
||||
<image src="/static/express.png" mode="aspectFit"></image>
|
||||
@@ -87,7 +87,7 @@
|
||||
<view class="item-right">
|
||||
<uni-icons type="right" size="16" color="#999"></uni-icons>
|
||||
</view>
|
||||
</view> -->
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!--
|
||||
|
||||
Reference in New Issue
Block a user