feat: 新增确认送达弹框组件、添加安卓打包测试证书、骑手配送流程接口对接
This commit is contained in:
298
pages/index/components/delivery-popup.vue
Normal file
298
pages/index/components/delivery-popup.vue
Normal file
@@ -0,0 +1,298 @@
|
||||
<template>
|
||||
<u-popup :show="show" mode="bottom" :closeable="true" @close="onClose" :safeAreaInsetBottom="false" border-radius="16">
|
||||
<view class="delivery-popup">
|
||||
<!-- 标题 -->
|
||||
<view class="popup-header">
|
||||
<text class="popup-title">确认送达</text>
|
||||
</view>
|
||||
|
||||
<!-- 内容区域 -->
|
||||
<view class="popup-content">
|
||||
<view class="upload-label">
|
||||
<text class="required">*</text>
|
||||
<text>上传送达照片:</text>
|
||||
</view>
|
||||
|
||||
<!-- 照片列表 -->
|
||||
<up-upload
|
||||
:fileList="photoList"
|
||||
@afterRead="afterRead"
|
||||
@delete="deleteUpload"
|
||||
:maxCount="1"
|
||||
:maxSize="5 * 1024 * 1024"
|
||||
uploadText="上传照片"
|
||||
:previewFullImage="true"
|
||||
></up-upload>
|
||||
</view>
|
||||
|
||||
<!-- 底部按钮 -->
|
||||
<view class="popup-footer">
|
||||
<view class="btn submit" @click="onSubmit">提交</view>
|
||||
</view>
|
||||
</view>
|
||||
</u-popup>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, watch } from 'vue';
|
||||
import sheep from '@/sheep';
|
||||
import { baseUrl, apiPath } from '@/sheep/config';
|
||||
|
||||
const props = defineProps({
|
||||
// 控制显示隐藏
|
||||
show: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
});
|
||||
|
||||
const emit = defineEmits(['update:show', 'submit', 'close']);
|
||||
|
||||
// 照片列表 (用于 up-upload 组件)
|
||||
const photoList = ref([])
|
||||
|
||||
// 监听弹框显示,重置数据
|
||||
watch(() => props.show, (newVal) => {
|
||||
if (newVal) {
|
||||
photoList.value = [];
|
||||
}
|
||||
});
|
||||
|
||||
// 关闭弹框
|
||||
function onClose() {
|
||||
emit('update:show', false);
|
||||
emit('close');
|
||||
}
|
||||
|
||||
// 删除上传的图片
|
||||
function deleteUpload(event) {
|
||||
photoList.value.splice(event.index, 1);
|
||||
}
|
||||
|
||||
// 上传单个文件到 OSS
|
||||
async function uploadFile(filePath) {
|
||||
const token = uni.getStorageSync('token');
|
||||
return new Promise((resolve, reject) => {
|
||||
uni.uploadFile({
|
||||
url: baseUrl + apiPath + '/app/file/uploadOss', // 上传接口地址
|
||||
header: {
|
||||
'Authorization': token
|
||||
},
|
||||
filePath: filePath,
|
||||
name: 'file',
|
||||
success: (res) => {
|
||||
if (res.statusCode === 200) {
|
||||
try {
|
||||
const data = JSON.parse(res.data);
|
||||
if (data.code === 0 && data.data) {
|
||||
resolve(data.data);
|
||||
} else {
|
||||
console.error('上传失败:', data.msg);
|
||||
resolve(null);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('解析上传响应失败:', e);
|
||||
resolve(null);
|
||||
}
|
||||
} else {
|
||||
console.error('上传失败:', res.statusCode);
|
||||
resolve(null);
|
||||
}
|
||||
},
|
||||
fail: (err) => {
|
||||
console.error('上传请求失败:', err);
|
||||
reject(err);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// 上传图片后的回调
|
||||
async function afterRead(event) {
|
||||
// 当设置 mutiple 为 true 时, event.file.list 为数组
|
||||
const { file } = event;
|
||||
|
||||
// 如果是单选,转换为数组处理
|
||||
const fileList = Array.isArray(file) ? file : [file];
|
||||
|
||||
for (const item of fileList) {
|
||||
// 标记为上传中
|
||||
photoList.value.push({
|
||||
...item,
|
||||
status: 'uploading',
|
||||
message: '上传中'
|
||||
});
|
||||
}
|
||||
|
||||
// 依次上传文件
|
||||
for (let i = 0; i < fileList.length; i++) {
|
||||
const item = fileList[i];
|
||||
const index = photoList.value.findIndex(f => f.url === item.url);
|
||||
|
||||
try {
|
||||
const url = await uploadFile(item.url);
|
||||
|
||||
if (url) {
|
||||
// 上传成功,更新状态
|
||||
photoList.value[index] = {
|
||||
...photoList.value[index],
|
||||
status: 'success',
|
||||
message: ''
|
||||
};
|
||||
} else {
|
||||
// 上传失败
|
||||
photoList.value[index] = {
|
||||
...photoList.value[index],
|
||||
status: 'failed',
|
||||
message: '上传失败'
|
||||
};
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('上传图片异常:', error);
|
||||
photoList.value[index] = {
|
||||
...photoList.value[index],
|
||||
status: 'failed',
|
||||
message: '上传失败'
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 提交
|
||||
async function onSubmit() {
|
||||
if (photoList.value.length === 0) {
|
||||
uni.showToast({
|
||||
title: '请上传送达照片',
|
||||
icon: 'none'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// 查找上传成功的照片
|
||||
const uploadedPhoto = photoList.value.find(p => p.status === 'success');
|
||||
|
||||
if (!uploadedPhoto) {
|
||||
uni.showToast({
|
||||
title: '照片上传中,请稍候',
|
||||
icon: 'none'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// 提交成功,返回上传后的 URL
|
||||
emit('submit', uploadedPhoto.url);
|
||||
onClose();
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.delivery-popup {
|
||||
padding: 30rpx;
|
||||
padding-bottom: calc(30rpx + constant(safe-area-inset-bottom));
|
||||
padding-bottom: calc(30rpx + env(safe-area-inset-bottom));
|
||||
}
|
||||
|
||||
.popup-header {
|
||||
text-align: center;
|
||||
padding-bottom: 30rpx;
|
||||
border-bottom: 1rpx solid #f0f0f0;
|
||||
}
|
||||
|
||||
.popup-title {
|
||||
font-size: 34rpx;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.popup-content {
|
||||
padding: 30rpx 0;
|
||||
}
|
||||
|
||||
.upload-label {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
|
||||
.required {
|
||||
color: #f5222d;
|
||||
margin-right: 4rpx;
|
||||
}
|
||||
|
||||
.photo-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 20rpx;
|
||||
}
|
||||
|
||||
.photo-item {
|
||||
position: relative;
|
||||
width: 180rpx;
|
||||
height: 180rpx;
|
||||
border-radius: 12rpx;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.photo-preview {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
|
||||
.photo-delete {
|
||||
position: absolute;
|
||||
top: 10rpx;
|
||||
right: 10rpx;
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.delete-icon {
|
||||
color: #fff;
|
||||
font-size: 32rpx;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.photo-add {
|
||||
width: 180rpx;
|
||||
height: 180rpx;
|
||||
background: #f5f5f5;
|
||||
border-radius: 12rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border: 2rpx dashed #ddd;
|
||||
}
|
||||
|
||||
.add-icon {
|
||||
font-size: 72rpx;
|
||||
color: #999;
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
.popup-footer {
|
||||
margin-top: 40rpx;
|
||||
}
|
||||
|
||||
.btn {
|
||||
width: 100%;
|
||||
height: 88rpx;
|
||||
line-height: 88rpx;
|
||||
text-align: center;
|
||||
border-radius: 12rpx;
|
||||
font-size: 32rpx;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.btn.submit {
|
||||
background: #1e9fff;
|
||||
color: #fff;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user