123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225 |
- <template>
- <view class="custom_upload mtb20">
- <slot>
- <view class="choose_box">
- <slot name="list">
- <view class="images_box" :style="imageBoxStyle" v-for="(item,index) in images"
- v-if="images[0]!==''&&images.length>0" :key="index">
- <u-transition show mode="fade-right">
- <u-image showLoading lazyLoad @click="previewImage(index,images)" :src="item" width="100%"
- :height="imageBoxStyle.height?imageBoxStyle.height:'188rpx'" radius="17rpx" />
- <view class="close_icon centerV" @click="images.splice(index,1)">
- <u-icon name="close" color="#fff" size="22rpx" bold></u-icon>
- </view>
- </u-transition>
- </view>
- </slot>
- <view class="upload_box centerV" :style="imageBoxStyle" @click="props.readonly?null:showPopup=true">
- <slot name="upload-image">
- <u-image showLoading lazyLoad :src="config.getResource('icons/upload.png')" width="59rpx" height="59rpx"
- radius="17rpx" />
- </slot>
- </view>
- </view>
- </slot>
- <u-popup :show="showPopup" @close="close" closeOnClickOverlay round="20rpx" :safeAreaInsetBottom="true" closeable>
- <view class="upload_content column">
- <text class="bold center mb20">{{title}}</text>
- <view class="mt20">
- <u-button shape="circle" text="拍照" @click="uploadImg({sourceType:['camera']})"
- :custom-style="{marginRight:'10rpx',height:'96rpx',border: '2rpx solid #1f1f1f',color:'#1f1f1f'}"></u-button>
- <u-button shape="circle" color="#1f1f1f" type="primary" text="相册" @click="uploadImg({sourceType:['album']})"
- :custom-style="{height:'96rpx',marginTop:'24rpx'}"></u-button>
- </view>
- </view>
- </u-popup>
- <modal-popup ref="showModal" />
- </view>
- </template>
- <script setup>
- import {
- ref,
- watchEffect
- } from "vue";
- import fileUpload from '@/utils/request/upload/upload';
- import config from "@/core/config";
- import {
- doUploadsReady
- } from "@/api/upload.js"
- import {
- showToast,
- previewImage
- } from "@/core/app";
- const props = defineProps({
- value: {
- type: [String, Array],
- default: ''
- },
- show: {
- type: Boolean,
- default: false
- },
- title: {
- type: String,
- default: '上传图片'
- },
- options: {
- type: Object,
- default: {}
- },
- maxLength: {
- type: Number,
- default: 1
- },
- uploadType: {
- type: String,
- default: 'list'
- },
- imageBoxStyle: {
- type: Object,
- default: {}
- },
- readonly: {
- type: Boolean,
- default: false
- }
- })
- const emits = defineEmits(['update:value', 'update:show', 'close'])
- // 图片列表
- const images = ref([])
- const showPopup = ref(props.show)
- watchEffect(() => {
- images.value = props.value ? props.value.split(',') : props.value.split('')
- showPopup.value = props.show
- })
- // 关闭popup
- const close = () => {
- showPopup.value = false
- emits('update:show', false)
- emits('close', false)
- }
- // 上传头像
- const uploadImg = async (options = {}) => {
- if (props.uploadType == 'list') {
- if (images.value.length >= props.maxLength) return showToast(
- `只能上传${props.maxLength}张`)
- }
- // #ifdef APP
- empowerCameraAlbum(options.sourceType[0])
- // #endif
- const fupload = new fileUpload({});
- const data1 = await fupload.ossImagUpload({
- ...options,
- ...props.options
- })
- for (let item of data1) {
- const result = await doUploadsReady(item);
- if (result) {
- const {
- data
- } = result;
- uni.uploadFile({
- url: data.host,
- filePath: item.path,
- name: 'file',
- formData: {
- key: data.key,
- policy: data.policy,
- OSSAccessKeyId: data.ossAccessKeyId,
- signature: data.signature,
- },
- success: async (res) => {
- if (res.statusCode === 200) {
- if (props.uploadType == 'list') {
- if (images.value.length >= props.maxLength) return showToast(
- `只能上传${props.maxLength}张`)
- }
- if (props.uploadType == 'list') {
- images.value.push(JSON.parse(res.data).data.filePath)
- } else {
- images.value = JSON.parse(res.data).data.filePath
- }
- emits('update:value', typeof images.value == 'string' ? images.value : images.value.join(','))
- close()
- }
- },
- fail: err => {}
- });
- }
- }
- }
- // 权限检查
- const showModal = ref(null)
- const empowerCameraAlbum = (permissionType, cameraMsg = "申请相机,存储写入权限为了拍照和使用图片上传头像", albumMsg =
- "申请相册读取权限,为了选择相册图片上传头像") => {
- let permissionID = []
- let authorizedType = null
- if (permissionType === 'camera') {
- authorizedType = 'cameraAuthorized'
- permissionID = ['android.permission.CAMERA', 'android.permission.WRITE_EXTERNAL_STORAGE']
- } else {
- authorizedType = 'albumAuthorized'
- permissionID = ['android.permission.READ_EXTERNAL_STORAGE']
- }
- if (uni.getAppAuthorizeSetting()[authorizedType] !== 'authorized') {
- showModal.value.open({
- content: permissionType == 'camera' ? cameraMsg : albumMsg,
- popType: 'popup'
- })
- }
- }
- // 方法暴露
- defineExpose({
- uploadImg,
- empowerCameraAlbum,
- showPopup
- })
- </script>
- <style lang="scss">
- .custom_upload {
- width: 100%;
- .upload_content {
- padding: 25rpx;
- margin-bottom: 100rpx;
- }
- .choose_box {
- width: 100%;
- display: grid;
- grid-template-columns: 1fr 1fr 1fr;
- grid-row-gap: 20rpx;
- grid-column-gap: 30rpx;
- .images_box,
- .upload_box {
- width: 100%;
- height: 188rpx;
- border-radius: 17rpx;
- }
- .images_box {
- position: relative;
- animation: zoom 1s;
- }
- .close_icon {
- position: absolute;
- top: -15rpx;
- right: -10rpx;
- width: 35rpx;
- height: 35rpx;
- background: rgba(0, 0, 0, .5);
- border-radius: 50%;
- }
- .upload_box {
- background: #F6F6F6;
- }
- }
- }
- </style>
|