You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

189 lines
4.4 KiB

<template>
<view class="upload-container">
<view v-for="(item, index) in files" class="upload-item">
<template v-if="item.filePath">
<net-image :filepath="item.filePath" />
</template>
<image :src="item.localFilepath" v-else style="width: 100%; height: 100%" />
<button class="remove-btn" @tap="handleRemove(index)">
<uni-icons type="closeempty" color="#fff" size="18" />
</button>
</view>
<view class="upload-btn upload-item" @tap="chooseImage">
<uni-icons type="plusempty" size="32" color="#162582" />
</view>
</view>
</template>
<script setup>
import { ref, defineProps, defineEmits } from 'vue'
import store from '@/store'
import { pathToBase64 } from 'image-tools'
import {
uploadFileBase64
} from '@/api/file'
import permission from '@/common/permission'
var sourceType = [
['camera'],
['album'],
['camera', 'album']
]
var sizeType = [
['compressed'],
['original'],
['compressed', 'original']
]
const props = defineProps({
modelValue: {
type: Array,
default: []
}
});
const emit = defineEmits(['update:modelValue']);
const files = ref(props.modelValue || [])
async function chooseImage() {
// #ifdef APP-PLUS
// TODO 选择相机或相册时 需要弹出actionsheet,目前无法获得是相机还是相册,在失败回调中处理
// if (this.sourceTypeIndex !== 2) {
// let status = await this.checkPermission();
// if (status !== 1) {
// return;
// }
// }
// #endif
uni.chooseImage({
sourceType: ['camera'],
sizeType: ['original'],
count: 3,
success: (res) => {
res.tempFiles.forEach(async (file) => {
const filename = file.path.substring(file.path.lastIndexOf('/') + 1)
const fileItem = {
localFilepath: file.path,
fileName: filename
}
files.value.push(fileItem);
try {
const base64 = await pathToBase64(file.path);
const data = await uploadFileBase64({
base64,
originalFilename: filename
})
fileItem.filePath = data.filePath;
} catch(e) {
files.value.splice(files.value.indexOf(fileItem), 1)
}
emit('update:modelValue', files.value)
})
},
fail: (err) => {
console.log("err: ", err);
// #ifdef APP-PLUS
if (err['code'] && err.code !== 0 && this.sourceTypeIndex === 2) {
this.checkPermission(err.code);
}
// #endif
// #ifdef MP
if (err.errMsg.indexOf('cancel') !== '-1') {
return;
}
uni.getSetting({
success: (res) => {
let authStatus = false;
switch (this.sourceTypeIndex) {
case 0:
authStatus = res.authSetting['scope.camera'];
break;
case 1:
authStatus = res.authSetting['scope.album'];
break;
case 2:
authStatus = res.authSetting['scope.album'] && res
.authSetting['scope.camera'];
break;
default:
break;
}
if (!authStatus) {
uni.showModal({
title: '授权失败',
content: 'Hello uni-app需要从您的相机或相册获取图片,请在设置界面打开相关权限',
success: (res) => {
if (res.confirm) {
uni.openSetting()
}
}
})
}
}
})
// #endif
}
})
}
async function checkPermission(code) {
let type = code ? code - 1 : this.sourceTypeIndex;
let status = await permision.requestAndroid(type === 0 ? 'android.permission.CAMERA' :
'android.permission.READ_EXTERNAL_STORAGE');
if (status === null || status === 1) {
status = 1;
} else {
uni.showModal({
content: "没有开启权限",
confirmText: "设置",
success: function(res) {
if (res.confirm) {
permision.gotoAppSetting();
}
}
})
}
return status;
}
function handleRemove(index) {
files.value.splice(index, 1)
}
</script>
<style lang="scss" scoped>
.upload-container {
display: flex;
gap: 38rpx;
flex-wrap: wrap;
.upload-item {
height: 178rpx;
width: 178rpx;
position: relative;
image {
width: 100%;
height: 100%;
}
.remove-btn {
height: 46rpx;
width: 46rpx;
line-height: 46rpx;
border-radius: 50%;
position: absolute;
top: -20rpx;
right: -20rpx;
padding: 0;
background-color: #fff;
background-color: $uni-color-error;
}
}
}
.upload-btn {
display: flex;
justify-content: center;
align-items: center;
border: 1px solid #162582;
}
</style>