// components/journal-detail-panel/index.ts import { Journal } from "../../types/Journal"; import config from "../../config/index"; import { MediaAttachExt, MediaAttachType } from "../../types/Attachment"; import { MediaItem, MediaItemType } from "../../types/UI"; import Time from "../../utils/Time"; interface JournalDetailPanelData { journals: Journal[]; currentJournalIndex: number; } Component({ properties: { visible: { type: Boolean, value: false }, ids: { type: Array, value: [] }, mode: { type: String, value: "DATE" } }, data: { journals: [], currentJournalIndex: 0, }, observers: { async 'ids, visible'(ids: number[], visible: boolean) { if (visible && ids && 0 < ids.length) { wx.showLoading({ title: "加载中...", mask: true }); try { const journals: Journal[] = await new Promise((resolve, reject) => { wx.request({ url: `${config.url}/journal/list/ids`, method: "POST", header: { Key: wx.getStorageSync("key") }, data: ids, success: (resp: any) => { if (resp.data.code === 20000) { resolve(resp.data.data); } else { reject(new Error(resp.data.message || "加载失败")); } }, fail: reject }); }) || []; journals.forEach(journal => { journal.date = Time.toPassedDate(journal.createdAt); journal.time = Time.toTime(journal.createdAt); journal.datetime = Time.toPassedDateTime(journal.createdAt); const thumbItems = journal.items?.filter((item) => item.attachType === MediaAttachType.THUMB); if (!thumbItems) { return; } const mediaItems: MediaItem[] = thumbItems.map((thumbItem) => { const ext = thumbItem.ext = JSON.parse(thumbItem.ext!.toString()) as MediaAttachExt; const thumbURL = `${config.url}/attachment/read/${thumbItem.mongoId}`; const sourceURL = `${config.url}/attachment/read/${ext.sourceMongoId}`; return { type: ext.isVideo ? MediaItemType.VIDEO : MediaItemType.IMAGE, thumbURL, sourceURL, size: thumbItem.size || 0, attachmentId: thumbItem.id } as MediaItem; }); journal.mediaItems = mediaItems; }) this.setData({ journals, currentJournalIndex: 0, }); wx.hideLoading(); } catch (err: any) { wx.hideLoading(); wx.showToast({ title: err.message || "加载失败", icon: "error" }); } } } }, methods: { /** 关闭详情 */ closeDetail() { this.triggerEvent("close"); }, /** swiper 切换事件 */ onSwiperChange(e: WechatMiniprogram.SwiperChange) { this.setData({ currentJournalIndex: e.detail.current }); }, /** 打开位置 */ openLocation(e: WechatMiniprogram.BaseEvent) { const { journalIndex } = e.currentTarget.dataset; if (!journalIndex && this.properties.mode !== "LOCATION") { return; } const journals = this.properties.journals as Journal[]; const journal = journals[journalIndex || 0]; if (journal.lat && journal.lng) { wx.openLocation({ latitude: journal.lat, longitude: journal.lng, }); } }, /** 预览媒体 */ previewMedia(e: WechatMiniprogram.BaseEvent) { const journals = this.properties.journals as Journal[]; if (!journals || journals.length === 0) { return; } const { itemIndex } = e.currentTarget.dataset; const items = journals[this.data.currentJournalIndex].mediaItems!; const total = items.length; const startIndex = Math.max(0, itemIndex - 25); const endIndex = Math.min(total, startIndex + 50); const newCurrentIndex = itemIndex - startIndex; const sources = items.slice(startIndex, endIndex).map((item) => { return { url: item.sourceURL, type: item.type === 0 ? "image" : "video" } }) as any; wx.previewMedia({ current: newCurrentIndex, sources }) } } });