/**
|
* CImagePicker
|
* @author Tevin
|
*/
|
|
<template>
|
<view class="c-image-picker">
|
<AtInput
|
ref="input"
|
:name="itemRes.name"
|
:title="itemRes.label"
|
:required="itemRes.required"
|
:error="itemRes.error"
|
/>
|
<AtImagePicker
|
ref="picker"
|
multiple
|
mode="aspectFit"
|
:count="9"
|
:length="3"
|
:files="files"
|
:onChange="(files,operationType,index)=>handleChange(files,operationType,index)"
|
:onFail="evt=>handleFail(evt)"
|
:onImageClick="(index, file)=>handleImgView(index,file)"
|
/>
|
<CImageCompressor ref="compressor" />
|
</view>
|
</template>
|
|
<script>
|
import Taro from '@tarojs/taro';
|
import { $ } from '@tarojs/extend';
|
import { AtInput, AtImagePicker, AtCurtain } from 'taro-ui-vue';
|
import { $fetchCommon } from '@fetchers/FCommon';
|
import CImageCompressor from './CImageCompressor.vue';
|
import './cImagePicker.scss';
|
|
export default {
|
name: 'CImagePicker',
|
components: {
|
CImageCompressor,
|
AtInput,
|
AtImagePicker,
|
AtCurtain,
|
},
|
props: {
|
// 表单数据资源(表单组件内部机制专用)
|
itemRes: Object,
|
},
|
data() {
|
return {};
|
},
|
computed: {
|
files() {
|
const value = this.itemRes.formData[this.itemRes.name];
|
let files = [];
|
if (Object.prototype.toString.call(value) === '[object String]') {
|
files = value.split(',').map(url => ({ url }));
|
} else if (Object.prototype.toString.call(value) === '[object Array]') {
|
files = value.map(url => ({ url }));
|
}
|
files.push({ type: 'btn' });
|
return files;
|
},
|
},
|
methods: {
|
triggerChange(files) {
|
const value = [];
|
files.forEach(file => {
|
if (file.type === 'btn') {
|
return;
|
}
|
value.push(file.url);
|
});
|
this.itemRes.onChange(value);
|
},
|
handleChange(files, operationType, index) {
|
// 添加图片
|
if (operationType === 'add') {
|
const needs = files
|
.map((file, needIndex) => {
|
const fileInfo = file.file;
|
// 没有 file 信息对象,或者不是 blob 类型
|
if (!fileInfo || fileInfo.path.indexOf('blob') < 0) {
|
return false;
|
}
|
// 尺寸小于 2M 的图片
|
if (fileInfo.size < 1 * 1024 * 1024) {
|
return false;
|
}
|
return [fileInfo, needIndex];
|
})
|
.filter(Boolean);
|
// 存在需要压缩的图片,一次性压缩
|
if (needs.length > 0) {
|
const files2 = [...files];
|
const needPaths = needs.map(need => need[0].path);
|
this.$refs.compressor.$compress(needPaths, compressedFiles => {
|
compressedFiles.forEach((cpPath, cpIndex) => {
|
const filesIndex = needs[cpIndex][1];
|
files2[filesIndex] = {
|
url: cpPath.compress,
|
};
|
});
|
this.triggerChange(files2);
|
});
|
}
|
// 不存在,直接显示
|
else {
|
this.triggerChange(files);
|
}
|
}
|
// 删除图片,直接显示
|
else {
|
this.triggerChange(files);
|
}
|
},
|
handleImgView(index, file) {
|
const urls = this.files
|
.map(file => (file.type === 'btn' ? false : file.url))
|
.filter(Boolean);
|
Taro.previewImage({
|
current: file.url, // 当前显示图片的http链接
|
urls, // 需要预览的图片http链接列表
|
});
|
},
|
handleImgClose() {
|
this.showImg = false;
|
},
|
handleFail(msg) {
|
console.log(msg);
|
Taro.showToast({
|
title: msg,
|
icon: 'none',
|
mask: true,
|
duration: 2000,
|
});
|
},
|
$uploadImage(callback) {
|
const url = $fetchCommon.getUploadImgURL();
|
const uploadTeam = [];
|
const imgs = [];
|
this.files.forEach(file => {
|
if (file.type === 'btn') {
|
return;
|
}
|
// blob 临时文件才上传
|
if (file.url.indexOf('blob') >= 0) {
|
uploadTeam.push(
|
new Promise((resolve, reject) => {
|
Taro.uploadFile({
|
url,
|
filePath: file.url,
|
name: 'file',
|
formData: {},
|
success(res) {
|
const res2 =
|
typeof res.data === 'string'
|
? JSON.parse(res.data)
|
: res.data;
|
if (res2.state.code === 2000) {
|
resolve(
|
$fetchCommon.transImgPath(
|
'fix',
|
res2.data.src
|
)
|
);
|
} else {
|
reject({ message: res2.state.msg });
|
}
|
},
|
cancel() {
|
reject({ message: '上传图片已取消!' });
|
},
|
fail() {
|
reject({ message: '上传图片失败!' });
|
},
|
});
|
})
|
);
|
}
|
// 其他类型视为 url,忽略
|
else {
|
uploadTeam.push(Promise.resolve(file.url));
|
}
|
});
|
Promise.all(uploadTeam)
|
.then(res => {
|
this.itemRes.onChange(res);
|
setTimeout(() => {
|
callback('success');
|
}, 0);
|
})
|
.catch(err => {
|
callback('error', err);
|
});
|
},
|
},
|
mounted() {
|
if (process.env.TARO_ENV === 'h5') {
|
$(this.$refs.input.$el)
|
.find('.at-input__input')
|
.prepend(this.$refs.picker.$el);
|
} else if (process.env.TARO_ENV === 'weapp') {
|
$(this.$refs.input.$el)
|
.find('.at-input__container')
|
.append(this.$refs.picker.$el);
|
}
|
},
|
};
|
</script>
|