oak-general-business/wechatMp/components/extraFile/gallery/index.ts

225 lines
7.5 KiB
TypeScript

import assert from 'assert';
import { EntityDict } from "oak-app-domain";
import { DeduceCreateOperationData } from "oak-domain/lib/types";
import { isMockId } from "oak-frontend-base/src/utils/mockId";
import { composeFileUrl } from '../../../../src/utils/extraFile';
OakComponent({
entity: 'extraFile',
async formData (files) {
const number2 = this.data.maxNumber;
if (typeof number2 === 'number' && (number2 === 0 || files?.length >= number2)) {
return {
files,
disableInsert: true,
};
}
return {
files,
disableInsert: false,
};
}
}, {
data: {
selected: -1,
// 根据 size 不同,计算的图片显示大小不同
itemSizePercentage: '',
},
externalClasses: ['l-class', 'l-item-class'],
properties: {
oakFullpath: String,
oakParent: String,
oakPath: String,
maxNumber: {
type: Number,
value: 100,
},
selectCount: {
type: Number,
value: 1,
},
sourceType: {
type: Array,
value: ['album', 'camera'],
},
mediaType: {
type: Array,
value: ['image'],
},
// 图片显示模式
mode: {
type: String,
value: 'aspectFit',
},
// 图片是否可预览
preview: {
type: Boolean,
value: true,
},
// 每行可显示的个数
size: {
type: Number,
value: 3,
},
// 图片是否可预览
disableDelete: {
type: Boolean,
value: false,
},
type: String,
origin: String,
tag1: String,
tag2: String,
},
methods: {
/**
* 获取组件内部节点位置信息(单个)
* @param component 组件实例
* @param selector {String} css选择器
* @returns boundingClientRect() 回调函数的值
*/
async getNodeRectFromComponent(component: any, selector: any) {
return await new Promise((resolve) => {
component
.createSelectorQuery()
.select(selector)
.boundingClientRect((res: any) => {
resolve(res);
})
.exec();
});
},
/**
// * px 转 rpx
// * @param px 像素值
// */
px2rpx(px: number) {
const windowWidth = wx.getSystemInfoSync().windowWidth;
return (750 / windowWidth) * px;
},
async onPick() {
const { selectCount, mediaType, sourceType, type, origin, tag1, tag2} =
this.data;
try {
const { errMsg, tempFiles } = await wx.chooseMedia({
count: selectCount,
mediaType,
sourceType,
});
if (errMsg !== 'chooseMedia:ok') {
this.triggerEvent('error', {
level: 'warning',
msg: errMsg,
});
} else {
await Promise.all(tempFiles.map(
async (tempExtraFile) => {
const { tempFilePath, thumbTempFilePath } = tempExtraFile;
const filePath = tempFilePath || thumbTempFilePath;
const filename = filePath.match(/[^/]+(?!.*\/)/g)![0];
assert(origin === 'qiniu'); // 目前只支持七牛上传
const ele: Parameters<typeof this['pushNode']>[1] = {
updateData: {
extra1: filePath,
origin,
type,
tag1,
tag2,
objectId: await generateNewId(),
filename: filename,
},
beforeExecute: async (updateData) => {
const { url, bucket } = await this.features.extraFile.upload(
updateData as DeduceCreateOperationData<EntityDict['extraFile']['Schema']>, "extraFile:gallery:upload");
Object.assign(updateData, {
bucket,
extra1: url,
});
},
};
this.pushNode(undefined, ele);
}
));
}
} catch (err: any) {
console.error(err);
if (err.errMsg !== 'chooseMedia:fail cancel') {
this.triggerEvent('error', {
level: 'error',
msg: err.errMsg,
});
}
}
},
async onItemTapped(event: WechatMiniprogram.Touch) {
const { files } = this.data;
const { index } = event.currentTarget.dataset;
const imageUrl = composeFileUrl(files[index]);
const urls = files?.map((ele) => composeFileUrl(ele));
const detail = {
all: files,
index,
urls: urls,
current: imageUrl,
};
this.triggerEvent('tap', detail);
// 预览图片
if (this.data.preview) {
const result = await wx.previewImage({
urls: urls,
current: imageUrl,
});
this.triggerEvent('preview', detail);
}
},
async onDelete(event: WechatMiniprogram.Touch) {
const { value, index } = event.currentTarget.dataset;
const { id } = value;
if (isMockId(id)) {
this.removeNode(this.data.oakFullpath, `${index}`);
} else {
const result = await wx.showModal({
title: '确认删除吗',
content: '删除现有文件',
});
const { confirm } = result;
if (confirm) {
this.removeNode(this.data.oakFullpath, `${index}`);
}
}
},
},
observers: {
maxNumber: function (maxNumber) {
this.reRender();
},
/**
* size 属性变化时,重新调整图片大小
* @param size 新值
*/
size: async function (size: number) {
if (!size) {
this.setData({ itemSizePercentage: '' });
return;
}
// 获取 .file-list__container 容器宽度
const res: any = await this.getNodeRectFromComponent(
this,
'.file-list__container'
);
const widthRpx = this.px2rpx(res.right - res.left);
// 根据容器宽度计算单张图片宽度百分比
const itemSizePercentage =
(10 / size) * 10 - (20 / widthRpx) * 100 + '%;';
this.setData({ itemSizePercentage: itemSizePercentage });
},
},
});