123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237 |
- import { Icon, Image, Toast, Uploader } from 'vant'
- import { defineComponent } from 'vue'
- import styles from './index.module.less'
- import ColCropper from '../col-cropper'
- import { useCustomFieldValue } from '@vant/use'
- import { postMessage } from '@/helpers/native-message'
- import umiRequest from 'umi-request'
- import iconUploader from '@common/images/icon_uploader.png'
- import request from '@/helpers/request'
- import { getOssUploadUrl, state } from '@/state'
- export default defineComponent({
- name: 'col-upload',
- props: {
- modelValue: String,
- tips: {
- type: String,
- default: '点击上传'
- },
- deletable: {
- type: Boolean,
- default: true
- },
- native: {
- // 是否原生上传
- type: Boolean,
- default: false
- },
- cropper: {
- // 是否进行裁切
- type: Boolean,
- default: false
- },
- options: {
- // 裁切需要参数
- type: Object,
- default: {}
- },
- uploadSize: {
- // 上传图片大小
- type: Number,
- default: 5
- },
- onUploadChange: {
- type: Function,
- default: (url: string) => {}
- },
- bucket: {
- type: String,
- default: 'daya'
- }
- },
- methods: {
- nativeUpload() {
- postMessage(
- {
- api: 'chooseFile',
- content: { type: 'img', max: 1, bucket: this.bucket }
- },
- (res: any) => {
- console.log(res, 'fileUrl')
- this.$emit('update:modelValue', res.fileUrl)
- }
- )
- },
- beforeRead(file: any) {
- console.log(file, 'beforeRead')
- const isLt2M = file.size / 1024 / 1024 < this.uploadSize
- if (!isLt2M) {
- Toast(`上传文件大小不能超过 ${this.uploadSize}MB`)
- return false
- }
- return true
- },
- beforeDelete(file: any, detail: { index: any }) {
- // this.dataModel.splice(detail.index, 1)
- return true
- },
- async afterRead(file: any, detail: any) {
- try {
- file.status = 'uploading'
- file.message = '上传中...'
- await this.uploadFile(file.file)
- } catch (error) {
- //
- console.log(error, '2323')
- Toast.clear()
- }
- },
- onClose(e: any) {
- this.$emit('update:modelValue', null)
- this.onUploadChange()
- e.stopPropagation()
- },
- async getFile(file: any) {
- try {
- await this.uploadFile(file)
- } catch {
- //
- }
- },
- async uploadFile(file: any) {
- // 上传文件
- try {
- // 获取签名
- const signUrl =
- state.platformType === 'TEACHER'
- ? '/api-teacher/getUploadSign'
- : '/api-student/getUploadSign'
- const tempName = file.name || ''
- const fileName = 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
- }
- }
- })
- Toast.loading({
- 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
- }
- 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
- Toast.clear()
- this.$emit('update:modelValue', uploadUrl)
- this.onUploadChange(uploadUrl)
- } catch (error) {
- console.log(error, 'uploadFile')
- }
- }
- },
- render() {
- useCustomFieldValue(() => this.modelValue)
- return (
- <div class={styles['uploader-section']}>
- {this.modelValue && this.deletable ? (
- <Icon
- name="cross"
- onClick={this.onClose}
- class={styles['img-close']}
- />
- ) : null}
- {this.cropper && !this.native ? (
- <div class={styles['col-uploader']}>
- {this.modelValue ? (
- <Image
- fit="cover"
- position="center"
- class={styles.uploadImg}
- src={this.modelValue}
- />
- ) : (
- <div class={styles.uploader}>
- <Icon name={iconUploader} size="32" />
- <p class={styles.uploaderText}>{this.tips}</p>
- </div>
- )}
- <ColCropper option={this.options} getFile={this.getFile} />
- </div>
- ) : this.native ? (
- <div
- style={{
- display: 'flex',
- alignItems: 'center',
- justifyContent: 'center',
- height: '100%'
- }}
- onClick={this.nativeUpload}
- >
- {this.modelValue ? (
- <Image
- fit="cover"
- position="center"
- class={styles.uploadImg}
- src={this.modelValue}
- />
- ) : (
- <div class={styles.uploader}>
- <Icon name={iconUploader} size="32" />
- <p class={styles.uploaderText}>{this.tips}</p>
- </div>
- )}
- </div>
- ) : (
- <Uploader
- afterRead={this.afterRead}
- beforeRead={this.beforeRead}
- beforeDelete={this.beforeDelete}
- v-slots={{
- default: () =>
- this.modelValue ? (
- <Image
- fit="cover"
- position="center"
- class={styles.uploadImg}
- src={this.modelValue}
- />
- ) : (
- <div class={styles.uploader}>
- <Icon name={iconUploader} size="32" />
- <p class={styles.uploaderText}>{this.tips}</p>
- </div>
- )
- }}
- />
- )}
- </div>
- )
- }
- })
|