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
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> |