123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389 |
- import {
- closeToast,
- Icon,
- Image,
- showLoadingToast,
- showToast,
- Uploader
- } from 'vant';
- import { defineComponent, PropType } from 'vue';
- import styles from './index.module.less';
- import { useCustomFieldValue } from '@vant/use';
- import { postMessage } from '@/helpers/native-message';
- import umiRequest from 'umi-request';
- import iconUploader from '@common/images/icon-upload.png';
- // import iconUploadClose from '@common/images/icon-upload-close.png';
- import iconVideoDefault from '@common/images/icon-video-c.png';
- import request from '@/helpers/request';
- import { getOssUploadUrl } from '@/state';
- export default defineComponent({
- name: 'col-upload',
- props: {
- modelValue: {
- type: Array,
- default: () => []
- },
- deletable: {
- type: Boolean,
- default: true
- },
- maxCount: {
- type: Number,
- default: 1
- },
- native: {
- // 是否原生上传
- type: Boolean,
- default: false
- },
- uploadSize: {
- // 上传图片大小
- type: Number,
- default: 5
- },
- uploadType: {
- type: String as PropType<'IMAGE' | 'VIDEO'>,
- default: 'IMAGE'
- },
- accept: {
- type: String,
- default: 'image/*'
- },
- bucket: {
- type: String,
- default: 'gyt'
- },
- path: {
- type: String,
- default: ''
- },
- uploadIcon: {
- type: String,
- default: iconUploader
- },
- size: {
- type: String,
- default: 'default'
- },
- disabled: {
- type: Boolean,
- default: false
- },
- position: {
- type: String as PropType<'outside' | 'inside'>,
- default: 'outside'
- }
- },
- emits: ['uploadChange', 'update:modelValue'],
- methods: {
- nativeUpload() {
- if (this.disabled) {
- return;
- }
- const type = this.uploadType === 'VIDEO' ? 'video' : 'img';
- let imgCount = 1;
- if (this.maxCount > 1) {
- imgCount = this.maxCount - this.modelValue.length;
- } else {
- imgCount = this.maxCount;
- }
- postMessage(
- {
- api: 'chooseFile',
- content: {
- type: type,
- max: imgCount,
- bucket: this.bucket,
- path: this.path
- }
- },
- (res: any) => {
- console.log(res, 'fileUrl');
- // 判断是否是多选
- if (this.maxCount > 1) {
- const files = res.fileUrl;
- console.log(files, 'files');
- this.$emit('update:modelValue', [
- ...this.modelValue,
- ...files.split(',')
- ]);
- this.$emit('uploadChange', [
- ...this.modelValue,
- ...files.split(',')
- ]);
- } else {
- this.$emit('update:modelValue', [res.fileUrl]);
- this.$emit('uploadChange', [res.fileUrl]);
- }
- }
- );
- },
- beforeRead(file: any) {
- console.log(file, 'beforeRead');
- const isLt2M = file.size / 1024 / 1024 < this.uploadSize;
- if (!isLt2M) {
- showToast(`上传文件大小不能超过 ${this.uploadSize}MB`);
- return false;
- }
- return true;
- },
- beforeDelete() {
- // this.dataModel.splice(detail.index, 1)
- return true;
- },
- async afterRead(file: any) {
- try {
- file.status = 'uploading';
- file.message = '上传中...';
- await this.uploadFile(file.file);
- } catch (error) {
- closeToast();
- }
- },
- onClose(e: any, item: any) {
- const models = this.modelValue;
- const index = models.findIndex(model => model == item);
- if (index > -1) {
- models.splice(index, 1);
- this.$emit('update:modelValue', models);
- this.$emit('uploadChange');
- }
- e.stopPropagation();
- },
- async getFile(file: any) {
- try {
- await this.uploadFile(file);
- } catch {
- //
- }
- },
- async uploadFile(file: any) {
- // 上传文件
- try {
- // 获取签名
- const signUrl = '/api-web/getUploadSign';
- const tempName = file.name || '';
- const fileName =
- this.path + '/' + (tempName && tempName.replace(/ /gi, '_'));
- const key = new Date().getTime() + fileName;
- console.log(file);
- const res = await request.post(signUrl, {
- data: {
- filename: fileName,
- bucketName: this.bucket,
- postData: {
- filename: fileName,
- acl: 'public-read',
- key: key,
- unknowValueField: []
- }
- }
- });
- showLoadingToast({
- message: '加载中...',
- forbidClick: true,
- loadingType: 'spinner',
- duration: 0
- });
- const obj = {
- policy: res.data.policy,
- signature: res.data.signature,
- key: key,
- KSSAccessKeyId: res.data.kssAccessKeyId,
- acl: 'public-read',
- name: fileName
- } as any;
- const formData = new FormData();
- for (const key in obj) {
- formData.append(key, obj[key]);
- }
- formData.append('file', file, fileName);
- await umiRequest(getOssUploadUrl(this.bucket), {
- method: 'POST',
- data: formData
- });
- console.log(getOssUploadUrl(this.bucket) + key);
- const uploadUrl = getOssUploadUrl(this.bucket) + key;
- closeToast();
- // 判断是否是多选
- if (this.maxCount > 1) {
- this.$emit('update:modelValue', [...this.modelValue, uploadUrl]);
- this.$emit('uploadChange', [...this.modelValue, uploadUrl]);
- } else {
- this.$emit('update:modelValue', [uploadUrl]);
- this.$emit('uploadChange', [uploadUrl]);
- }
- } catch (error) {
- console.log(error, 'uploadFile');
- }
- }
- },
- render() {
- useCustomFieldValue(() => this.modelValue);
- return (
- <div class={styles['uploader-section']}>
- {this.modelValue.length > 0 &&
- this.maxCount > 1 &&
- this.modelValue.map((item: any) => (
- <div class={['van-uploader', styles.uploader, styles[this.size]]}>
- {/* 删除按钮 */}
- {this.deletable && !this.disabled && (
- <Icon
- name="cross"
- onClick={(e: any) => this.onClose(e, item)}
- class={styles['img-close']}
- />
- )}
- <div class={['van-uploader__upload']}>
- {this.uploadType === 'IMAGE' ? (
- <Image
- src={item + '@base@tag=imgScale&w=200'}
- class={styles.previewImg}
- fit="cover"
- />
- ) : (
- <video
- ref="videoUpload"
- style={{ backgroundColor: '#F8F8F8' }}
- class={styles.previewImg}
- poster={iconVideoDefault}
- src={item + '#t=1,4'}
- />
- )}
- </div>
- </div>
- ))}
- {this.native ? (
- this.maxCount > 1 ? (
- // 小于长度才显示
- this.modelValue.length < this.maxCount && (
- <div
- class={['van-uploader', styles.uploader, styles[this.size]]}
- onClick={this.nativeUpload}>
- <Icon
- name={this.uploadIcon}
- class={['van-uploader__upload']}
- size="32"
- />
- </div>
- )
- ) : (
- <div
- class={['van-uploader', styles.uploader, styles[this.size]]}
- onClick={this.nativeUpload}>
- {this.modelValue.length > 0 ? (
- <div class={['van-uploader__upload']}>
- {this.modelValue.map((item: any) => (
- <>
- {/* 删除按钮 */}
- {this.deletable && !this.disabled && (
- <Icon
- name="cross"
- onClick={(e: any) => this.onClose(e, item)}
- class={[styles['img-close'], styles.singleImgClose]}
- />
- )}
- {this.uploadType === 'IMAGE' ? (
- <Image
- fit="cover"
- position="center"
- class={styles.uploadImg}
- src={item + '@base@tag=imgScale&w=200'}
- />
- ) : (
- <video
- ref="videoUpload"
- class={styles.uploadImg}
- style={{ backgroundColor: '#F8F8F8' }}
- poster={iconVideoDefault}
- src={item + '#t=1,4'}
- />
- )}
- </>
- ))}
- </div>
- ) : (
- <Icon
- name={this.uploadIcon}
- class={['van-uploader__upload']}
- size="32"
- />
- )}
- </div>
- )
- ) : this.maxCount > 1 ? (
- // 小于长度才显示
- this.modelValue.length < this.maxCount && (
- <Uploader
- class={['van-uploader', styles.uploader, styles[this.size]]}
- afterRead={this.afterRead}
- beforeRead={this.beforeRead}
- beforeDelete={this.beforeDelete}
- uploadIcon={this.uploadIcon}
- maxCount={this.maxCount}
- disabled={this.disabled}
- accept={this.accept}
- />
- )
- ) : (
- <Uploader
- class={['van-uploader', styles.uploader, styles[this.size]]}
- afterRead={this.afterRead}
- beforeRead={this.beforeRead}
- beforeDelete={this.beforeDelete}
- uploadIcon={this.uploadIcon}
- accept={this.accept}
- disabled={this.disabled}>
- {this.modelValue.length > 0 ? (
- <div class={['van-uploader__upload']}>
- {this.modelValue.map((item: any) => (
- <>
- {/* 删除按钮 */}
- {this.deletable && !this.disabled && (
- <Icon
- name="cross"
- onClick={(e: any) => this.onClose(e, item)}
- class={[styles['img-close'], styles.singleImgClose]}
- />
- )}
- {this.uploadType === 'IMAGE' ? (
- <Image
- fit="cover"
- position="center"
- class={styles.uploadImg}
- src={item + '@base@tag=imgScale&w=200'}
- />
- ) : (
- <video
- ref="videoUpload"
- class={styles.uploadImg}
- style={{ backgroundColor: '#F8F8F8' }}
- poster={iconVideoDefault}
- src={item + '#t=1,4'}
- />
- )}
- </>
- ))}
- </div>
- ) : (
- <Icon
- name={this.uploadIcon}
- class={['van-uploader__upload']}
- size="32"
- />
- )}
- </Uploader>
- )}
- {this.$slots.default && this.$slots.default()}
- </div>
- );
- }
- });
|