Compare commits
11 Commits
84fc382c91
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 8adc28ae9c | |||
| e31a3432a0 | |||
| 2c6478c729 | |||
| f4232e8752 | |||
| 41e2959a72 | |||
| bf5deff045 | |||
| f94cf05f62 | |||
| 9538a21e42 | |||
| 3b091c4f18 | |||
| b64e2767c2 | |||
| df7cfa95a0 |
@ -2,7 +2,7 @@
|
|||||||
import { Journal } from "../../types/Journal";
|
import { Journal } from "../../types/Journal";
|
||||||
import config from "../../config/index";
|
import config from "../../config/index";
|
||||||
import Toolkit from "../../utils/Toolkit";
|
import Toolkit from "../../utils/Toolkit";
|
||||||
import { ImageMetadata, MediaAttachExt, MediaAttachType } from "../../types/Attachment";
|
import { MediaAttachType, PreviewImageMetadata } from "../../types/Attachment";
|
||||||
import { MediaItem, MediaItemType } from "../../types/UI";
|
import { MediaItem, MediaItemType } from "../../types/UI";
|
||||||
import Time from "../../utils/Time";
|
import Time from "../../utils/Time";
|
||||||
import { JournalApi } from "../../api/JournalApi";
|
import { JournalApi } from "../../api/JournalApi";
|
||||||
@ -47,12 +47,12 @@ Component({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const mediaItems: MediaItem[] = thumbItems.map((thumbItem, index) => {
|
const mediaItems: MediaItem[] = thumbItems.map((thumbItem, index) => {
|
||||||
const metadata = thumbItem.metadata as ImageMetadata;
|
const metadata = (typeof thumbItem.metadata === "string" ? JSON.parse(thumbItem.metadata) : thumbItem.metadata) as PreviewImageMetadata;
|
||||||
const ext = thumbItem.ext = JSON.parse(thumbItem.ext!.toString()) as MediaAttachExt;
|
|
||||||
const thumbURL = `${config.url}/attachment/read/${thumbItem.mongoId}`;
|
const thumbURL = `${config.url}/attachment/read/${thumbItem.mongoId}`;
|
||||||
const sourceURL = `${config.url}/attachment/read/${ext.sourceMongoId}`;
|
const sourceURL = `${config.url}/attachment/read/${metadata.sourceMongoId}`;
|
||||||
|
const isVideo = metadata.sourceMimeType?.startsWith("video/");
|
||||||
return {
|
return {
|
||||||
type: ext.isVideo ? MediaItemType.VIDEO : MediaItemType.IMAGE,
|
type: isVideo ? MediaItemType.VIDEO : MediaItemType.IMAGE,
|
||||||
thumbURL,
|
thumbURL,
|
||||||
sourceURL,
|
sourceURL,
|
||||||
size: thumbItem.size || 0,
|
size: thumbItem.size || 0,
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
// components/travel-location-popup/index.ts
|
// components/travel-location-popup/index.ts
|
||||||
import { TravelLocation, TravelLocationTypeLabel, TravelLocationTypeIcon } from "../../types/Travel";
|
import { TravelLocation, TravelLocationTypeLabel, TravelLocationTypeIcon } from "../../types/Travel";
|
||||||
import { TravelLocationApi } from "../../api/TravelLocationApi";
|
import { TravelLocationApi } from "../../api/TravelLocationApi";
|
||||||
import { ImageMetadata, MediaAttachType } from "../../types/Attachment";
|
import { MediaAttachType, PreviewImageMetadata } from "../../types/Attachment";
|
||||||
import { MediaItem, MediaItemType } from "../../types/UI";
|
import { MediaItem, MediaItemType } from "../../types/UI";
|
||||||
import config from "../../config/index";
|
import config from "../../config/index";
|
||||||
import Toolkit from "../../utils/Toolkit";
|
import Toolkit from "../../utils/Toolkit";
|
||||||
@ -43,12 +43,12 @@ Component({
|
|||||||
|
|
||||||
if (0 < thumbItems.length) {
|
if (0 < thumbItems.length) {
|
||||||
const mediaItems: MediaItem[] = thumbItems.map((thumbItem, index) => {
|
const mediaItems: MediaItem[] = thumbItems.map((thumbItem, index) => {
|
||||||
const metadata = thumbItem.metadata as ImageMetadata;
|
const metadata = (typeof thumbItem.metadata === "string" ? JSON.parse(thumbItem.metadata) : thumbItem.metadata) as PreviewImageMetadata;
|
||||||
const ext = typeof thumbItem.ext === "string" ? JSON.parse(thumbItem.ext) : thumbItem.ext;
|
|
||||||
const thumbURL = `${config.url}/attachment/read/${thumbItem.mongoId}`;
|
const thumbURL = `${config.url}/attachment/read/${thumbItem.mongoId}`;
|
||||||
const sourceURL = `${config.url}/attachment/read/${ext.sourceMongoId}`;
|
const sourceURL = `${config.url}/attachment/read/${metadata.sourceMongoId}`;
|
||||||
|
const isVideo = metadata.sourceMimeType?.startsWith("video/");
|
||||||
return {
|
return {
|
||||||
type: ext.isVideo ? MediaItemType.VIDEO : MediaItemType.IMAGE,
|
type: isVideo ? MediaItemType.VIDEO : MediaItemType.IMAGE,
|
||||||
thumbURL,
|
thumbURL,
|
||||||
sourceURL,
|
sourceURL,
|
||||||
size: thumbItem.size || 0,
|
size: thumbItem.size || 0,
|
||||||
|
|||||||
@ -1,11 +1,12 @@
|
|||||||
const envArgs = {
|
const envArgs = {
|
||||||
develop: {
|
develop: {
|
||||||
|
url: "http://localhost:8091"
|
||||||
// url: "https://api.imyeyu.dev"
|
// url: "https://api.imyeyu.dev"
|
||||||
// url: "https://api.imyeyu.com"
|
// url: "https://api.imyeyu.com"
|
||||||
// url: "http://192.168.3.123:8091"
|
// url: "http://192.168.3.123:8091"
|
||||||
// url: "http://192.168.3.137:8091"
|
// url: "http://192.168.3.137:8091"
|
||||||
// url: "http://192.168.3.173:8091"
|
// url: "http://192.168.3.173:8091"
|
||||||
url: "http://192.168.3.174:8091"
|
// url: "http://192.168.3.174:8091"
|
||||||
},
|
},
|
||||||
trial: {
|
trial: {
|
||||||
url: "https://api.imyeyu.com"
|
url: "https://api.imyeyu.com"
|
||||||
|
|||||||
@ -1,7 +1,5 @@
|
|||||||
// index.ts
|
// index.ts
|
||||||
|
import { JournalPageType } from "../../types/Journal";
|
||||||
import config from "../../config/index"
|
|
||||||
import { JournalPage, JournalPageType } from "../../types/Journal";
|
|
||||||
import { JournalApi } from "../../api/JournalApi";
|
import { JournalApi } from "../../api/JournalApi";
|
||||||
|
|
||||||
interface IndexData {
|
interface IndexData {
|
||||||
@ -22,12 +20,12 @@ Page({
|
|||||||
},
|
},
|
||||||
async navigateToMain() {
|
async navigateToMain() {
|
||||||
try {
|
try {
|
||||||
|
wx.setStorageSync("key", this.data.key);
|
||||||
await JournalApi.getList({
|
await JournalApi.getList({
|
||||||
index: 0,
|
index: 0,
|
||||||
size: 1,
|
size: 1,
|
||||||
type: JournalPageType.PREVIEW
|
type: JournalPageType.PREVIEW
|
||||||
});
|
});
|
||||||
wx.setStorageSync("key", this.data.key);
|
|
||||||
wx.switchTab({
|
wx.switchTab({
|
||||||
url: "/pages/main/journal/index",
|
url: "/pages/main/journal/index",
|
||||||
})
|
})
|
||||||
|
|||||||
@ -26,7 +26,7 @@
|
|||||||
</view>
|
</view>
|
||||||
<view class="item">
|
<view class="item">
|
||||||
<text class="label">版本:</text>
|
<text class="label">版本:</text>
|
||||||
<text>1.6.2</text>
|
<text>1.6.6</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="item copyright">
|
<view class="item copyright">
|
||||||
<text>{{copyright}}</text>
|
<text>{{copyright}}</text>
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import Toolkit from "../../../utils/Toolkit";
|
|||||||
import config from "../../../config/index";
|
import config from "../../../config/index";
|
||||||
import { Location, MediaItem, MediaItemType, WechatMediaItem } from "../../../types/UI";
|
import { Location, MediaItem, MediaItemType, WechatMediaItem } from "../../../types/UI";
|
||||||
import { JournalType } from "../../../types/Journal";
|
import { JournalType } from "../../../types/Journal";
|
||||||
import { MediaAttachExt, MediaAttachType } from "../../../types/Attachment";
|
import { MediaAttachType, PreviewImageMetadata } from "../../../types/Attachment";
|
||||||
import IOSize, { Unit } from "../../../utils/IOSize";
|
import IOSize, { Unit } from "../../../utils/IOSize";
|
||||||
import { JournalApi } from "../../../api/JournalApi";
|
import { JournalApi } from "../../../api/JournalApi";
|
||||||
|
|
||||||
@ -156,11 +156,12 @@ Page({
|
|||||||
const thumbItems = items.filter((item) => item.attachType === MediaAttachType.THUMB);
|
const thumbItems = items.filter((item) => item.attachType === MediaAttachType.THUMB);
|
||||||
|
|
||||||
const mediaList: MediaItem[] = thumbItems.map((thumbItem) => {
|
const mediaList: MediaItem[] = thumbItems.map((thumbItem) => {
|
||||||
const ext = thumbItem.ext = JSON.parse(thumbItem.ext!.toString()) as MediaAttachExt;
|
const metadata = (typeof thumbItem.metadata === "string" ? JSON.parse(thumbItem.metadata) : thumbItem.metadata) as PreviewImageMetadata;
|
||||||
const thumbURL = `${config.url}/attachment/read/${thumbItem.mongoId}`;
|
const thumbURL = `${config.url}/attachment/read/${thumbItem.mongoId}`;
|
||||||
const sourceURL = `${config.url}/attachment/read/${ext.sourceMongoId}`;
|
const sourceURL = `${config.url}/attachment/read/${metadata.sourceMongoId}`;
|
||||||
|
const isVideo = metadata.sourceMimeType?.startsWith("video/");
|
||||||
return {
|
return {
|
||||||
type: ext.isVideo ? MediaItemType.VIDEO : MediaItemType.IMAGE,
|
type: isVideo ? MediaItemType.VIDEO : MediaItemType.IMAGE,
|
||||||
thumbURL,
|
thumbURL,
|
||||||
sourceURL,
|
sourceURL,
|
||||||
size: thumbItem.size || 0,
|
size: thumbItem.size || 0,
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import Events from "../../../utils/Events";
|
|||||||
import Toolkit from "../../../utils/Toolkit";
|
import Toolkit from "../../../utils/Toolkit";
|
||||||
import { Journal, JournalPage, JournalPageType } from "../../../types/Journal";
|
import { Journal, JournalPage, JournalPageType } from "../../../types/Journal";
|
||||||
import { OrderType } from "../../../types/Model";
|
import { OrderType } from "../../../types/Model";
|
||||||
import { ImageMetadata, MediaAttachExt } from "../../../types/Attachment";
|
import { PreviewImageMetadata } from "../../../types/Attachment";
|
||||||
import { MediaItem, MediaItemType } from "../../../types/UI";
|
import { MediaItem, MediaItemType } from "../../../types/UI";
|
||||||
import { JournalApi } from "../../../api/JournalApi";
|
import { JournalApi } from "../../../api/JournalApi";
|
||||||
|
|
||||||
@ -163,12 +163,12 @@ Page({
|
|||||||
}
|
}
|
||||||
list.forEach(journal => {
|
list.forEach(journal => {
|
||||||
const mediaItems = journal.items!.filter((item) => item.attachType === "THUMB").map((thumbItem, index) => {
|
const mediaItems = journal.items!.filter((item) => item.attachType === "THUMB").map((thumbItem, index) => {
|
||||||
const metadata = thumbItem.metadata as ImageMetadata;
|
const metadata = (typeof thumbItem.metadata === "string" ? JSON.parse(thumbItem.metadata) : thumbItem.metadata) as PreviewImageMetadata;
|
||||||
const ext = thumbItem.ext = JSON.parse(thumbItem.ext!.toString()) as MediaAttachExt;
|
|
||||||
const thumbURL = `${config.url}/attachment/read/${thumbItem.mongoId}`;
|
const thumbURL = `${config.url}/attachment/read/${thumbItem.mongoId}`;
|
||||||
const sourceURL = `${config.url}/attachment/read/${ext.sourceMongoId}`;
|
const sourceURL = `${config.url}/attachment/read/${metadata.sourceMongoId}`;
|
||||||
|
const isVideo = metadata.sourceMimeType?.startsWith("video/");
|
||||||
return {
|
return {
|
||||||
type: ext.isVideo ? MediaItemType.VIDEO : MediaItemType.IMAGE,
|
type: isVideo ? MediaItemType.VIDEO : MediaItemType.IMAGE,
|
||||||
thumbURL,
|
thumbURL,
|
||||||
sourceURL,
|
sourceURL,
|
||||||
size: thumbItem.size || 0,
|
size: thumbItem.size || 0,
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import IOSize, { Unit } from "../../../utils/IOSize";
|
|||||||
import Time from "../../../utils/Time";
|
import Time from "../../../utils/Time";
|
||||||
import Toolkit from "../../../utils/Toolkit";
|
import Toolkit from "../../../utils/Toolkit";
|
||||||
import { Location, MediaItemType } from "../../../types/UI";
|
import { Location, MediaItemType } from "../../../types/UI";
|
||||||
import { MediaAttachExt } from "../../../types/Attachment";
|
import { PreviewImageMetadata } from "../../../types/Attachment";
|
||||||
import { MomentApi } from "../../../api/MomentApi";
|
import { MomentApi } from "../../../api/MomentApi";
|
||||||
import { JournalApi } from "../../../api/JournalApi";
|
import { JournalApi } from "../../../api/JournalApi";
|
||||||
import { Network } from "../../../utils/Network";
|
import { Network } from "../../../utils/Network";
|
||||||
@ -134,12 +134,13 @@ Page({
|
|||||||
}
|
}
|
||||||
this.setData({
|
this.setData({
|
||||||
list: list.map((item: any) => {
|
list: list.map((item: any) => {
|
||||||
const ext = JSON.parse(item.ext) as MediaAttachExt;
|
const metadata = (typeof item.metadata === "string" ? JSON.parse(item.metadata) : item.metadata) as PreviewImageMetadata;
|
||||||
const thumbURL = `${config.url}/attachment/read/${item.mongoId}`;
|
const thumbURL = `${config.url}/attachment/read/${item.mongoId}`;
|
||||||
const sourceURL = `${config.url}/attachment/read/${ext.sourceMongoId}`;
|
const sourceURL = `${config.url}/attachment/read/${metadata.sourceMongoId}`;
|
||||||
|
const isImage = metadata.sourceMimeType?.startsWith("image/");
|
||||||
return {
|
return {
|
||||||
id: item.id,
|
id: item.id,
|
||||||
type: ext.isImage ? MediaItemType.IMAGE : MediaItemType.VIDEO,
|
type: isImage ? MediaItemType.IMAGE : MediaItemType.VIDEO,
|
||||||
thumbURL,
|
thumbURL,
|
||||||
sourceURL,
|
sourceURL,
|
||||||
checked: false
|
checked: false
|
||||||
@ -259,12 +260,13 @@ Page({
|
|||||||
const list = await MomentApi.create(tempFileIds);
|
const list = await MomentApi.create(tempFileIds);
|
||||||
wx.showToast({ title: "上传成功", icon: "success" });
|
wx.showToast({ title: "上传成功", icon: "success" });
|
||||||
const added = list.map((item: any) => {
|
const added = list.map((item: any) => {
|
||||||
const ext = JSON.parse(item.ext) as MediaAttachExt;
|
const metadata = (typeof item.metadata === "string" ? JSON.parse(item.metadata) : item.metadata) as PreviewImageMetadata;
|
||||||
const thumbURL = `${config.url}/attachment/read/${item.mongoId}`;
|
const thumbURL = `${config.url}/attachment/read/${item.mongoId}`;
|
||||||
const sourceURL = `${config.url}/attachment/read/${ext.sourceMongoId}`;
|
const sourceURL = `${config.url}/attachment/read/${metadata.sourceMongoId}`;
|
||||||
|
const isImage = item.mimeType?.startsWith("image/");
|
||||||
return {
|
return {
|
||||||
id: item.id,
|
id: item.id,
|
||||||
type: ext.isImage ? MediaItemType.IMAGE : MediaItemType.VIDEO,
|
type: isImage ? MediaItemType.IMAGE : MediaItemType.VIDEO,
|
||||||
thumbURL,
|
thumbURL,
|
||||||
sourceURL,
|
sourceURL,
|
||||||
checked: false
|
checked: false
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import Events from "../../../utils/Events";
|
|||||||
import Toolkit from "../../../utils/Toolkit";
|
import Toolkit from "../../../utils/Toolkit";
|
||||||
import { Journal, JournalPage, JournalPageType } from "../../../types/Journal";
|
import { Journal, JournalPage, JournalPageType } from "../../../types/Journal";
|
||||||
import { OrderType, } from "../../../types/Model";
|
import { OrderType, } from "../../../types/Model";
|
||||||
import { ImageMetadata, MediaAttachExt } from "../../../types/Attachment";
|
import { PreviewImageMetadata } from "../../../types/Attachment";
|
||||||
import { MediaItem, MediaItemType } from "../../../types/UI";
|
import { MediaItem, MediaItemType } from "../../../types/UI";
|
||||||
import { JournalApi } from "../../../api/JournalApi";
|
import { JournalApi } from "../../../api/JournalApi";
|
||||||
|
|
||||||
@ -92,12 +92,12 @@ Page({
|
|||||||
}
|
}
|
||||||
list.forEach(journal => {
|
list.forEach(journal => {
|
||||||
const mediaItems = journal.items!.filter((item) => item.attachType === "THUMB").map((thumbItem, index) => {
|
const mediaItems = journal.items!.filter((item) => item.attachType === "THUMB").map((thumbItem, index) => {
|
||||||
const metadata = thumbItem.metadata as ImageMetadata;
|
const metadata = (typeof thumbItem.metadata === "string" ? JSON.parse(thumbItem.metadata) : thumbItem.metadata) as PreviewImageMetadata;
|
||||||
const ext = thumbItem.ext = JSON.parse(thumbItem.ext!.toString()) as MediaAttachExt;
|
|
||||||
const thumbURL = `${config.url}/attachment/read/${thumbItem.mongoId}`;
|
const thumbURL = `${config.url}/attachment/read/${thumbItem.mongoId}`;
|
||||||
const sourceURL = `${config.url}/attachment/read/${ext.sourceMongoId}`;
|
const sourceURL = `${config.url}/attachment/read/${metadata.sourceMongoId}`;
|
||||||
|
const isVideo = metadata.sourceMimeType?.startsWith("video/");
|
||||||
return {
|
return {
|
||||||
type: ext.isVideo ? MediaItemType.VIDEO : MediaItemType.IMAGE,
|
type: isVideo ? MediaItemType.VIDEO : MediaItemType.IMAGE,
|
||||||
thumbURL,
|
thumbURL,
|
||||||
sourceURL,
|
sourceURL,
|
||||||
size: thumbItem.size || 0,
|
size: thumbItem.size || 0,
|
||||||
|
|||||||
@ -42,9 +42,55 @@
|
|||||||
|
|
||||||
.header {
|
.header {
|
||||||
padding: 16rpx 32rpx;
|
padding: 16rpx 32rpx;
|
||||||
|
|
||||||
|
.left-actions {
|
||||||
|
gap: 16rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.type-picker {
|
||||||
|
|
||||||
|
.picker-button {
|
||||||
|
gap: 8rpx;
|
||||||
|
color: var(--theme-wx);
|
||||||
|
border: 1px solid var(--theme-wx);
|
||||||
|
display: flex;
|
||||||
|
padding: 14rpx 24rpx 14rpx 32rpx;
|
||||||
|
font-size: 26rpx;
|
||||||
|
background: var(--theme-bg-card);
|
||||||
|
align-items: center;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.location {
|
.location {
|
||||||
|
.thumb {
|
||||||
|
width: 96rpx;
|
||||||
|
height: 96rpx;
|
||||||
|
border: 1px solid var(--theme-border-light);
|
||||||
|
overflow: hidden;
|
||||||
|
background: var(--theme-bg-page);
|
||||||
|
flex-shrink: 0;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.thumb-img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.thumb-placeholder {
|
||||||
|
color: var(--theme-text-secondary);
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
font-size: 24rpx;
|
||||||
|
background: var(--theme-bg-page);
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
.note {
|
.note {
|
||||||
width: 2em;
|
width: 2em;
|
||||||
|
|||||||
@ -3,7 +3,13 @@
|
|||||||
import Time from "../../../utils/Time";
|
import Time from "../../../utils/Time";
|
||||||
import { TravelApi } from "../../../api/TravelApi";
|
import { TravelApi } from "../../../api/TravelApi";
|
||||||
import { TravelLocationApi } from "../../../api/TravelLocationApi";
|
import { TravelLocationApi } from "../../../api/TravelLocationApi";
|
||||||
import { Travel, TravelStatusLabel, TravelStatusIcon, TransportationTypeLabel, TravelLocation, TravelLocationTypeLabel, TravelLocationTypeIcon, TransportationTypeIcon } from "../../../types/Travel";
|
import config from "../../../config/index";
|
||||||
|
import { Travel, TravelStatusLabel, TravelStatusIcon, TransportationTypeLabel, TravelLocation, TravelLocationTypeLabel, TravelLocationTypeIcon, TransportationTypeIcon, TravelLocationType } from "../../../types/Travel";
|
||||||
|
|
||||||
|
interface TravelLocationView extends TravelLocation {
|
||||||
|
/** 预览图 */
|
||||||
|
previewThumb?: string;
|
||||||
|
}
|
||||||
|
|
||||||
interface TravelDetailData {
|
interface TravelDetailData {
|
||||||
/** 出行详情 */
|
/** 出行详情 */
|
||||||
@ -13,7 +19,7 @@ interface TravelDetailData {
|
|||||||
/** 是否正在加载 */
|
/** 是否正在加载 */
|
||||||
isLoading: boolean;
|
isLoading: boolean;
|
||||||
/** 地点列表 */
|
/** 地点列表 */
|
||||||
locations: TravelLocation[];
|
locations: TravelLocationView[];
|
||||||
/** 是否正在加载地点 */
|
/** 是否正在加载地点 */
|
||||||
isLoadingLocations: boolean;
|
isLoadingLocations: boolean;
|
||||||
/** 状态标签映射 */
|
/** 状态标签映射 */
|
||||||
@ -28,6 +34,10 @@ interface TravelDetailData {
|
|||||||
locationTypeLabels: typeof TravelLocationTypeLabel;
|
locationTypeLabels: typeof TravelLocationTypeLabel;
|
||||||
/** 地点类型图标映射 */
|
/** 地点类型图标映射 */
|
||||||
locationTypeIcons: typeof TravelLocationTypeIcon;
|
locationTypeIcons: typeof TravelLocationTypeIcon;
|
||||||
|
/** 地点类型选项 */
|
||||||
|
locationTypes: string[];
|
||||||
|
/** 选中的地点类型索引 */
|
||||||
|
selectedLocationTypeIndex: number;
|
||||||
/** 删除对话框可见性 */
|
/** 删除对话框可见性 */
|
||||||
deleteDialogVisible: boolean;
|
deleteDialogVisible: boolean;
|
||||||
/** 删除确认文本 */
|
/** 删除确认文本 */
|
||||||
@ -47,6 +57,8 @@ Page({
|
|||||||
transportIcons: TransportationTypeIcon,
|
transportIcons: TransportationTypeIcon,
|
||||||
locationTypeLabels: TravelLocationTypeLabel,
|
locationTypeLabels: TravelLocationTypeLabel,
|
||||||
locationTypeIcons: TravelLocationTypeIcon,
|
locationTypeIcons: TravelLocationTypeIcon,
|
||||||
|
locationTypes: ["全部", ...Object.values(TravelLocationTypeLabel)],
|
||||||
|
selectedLocationTypeIndex: 0,
|
||||||
deleteDialogVisible: false,
|
deleteDialogVisible: false,
|
||||||
deleteConfirmText: ""
|
deleteConfirmText: ""
|
||||||
},
|
},
|
||||||
@ -109,15 +121,39 @@ Page({
|
|||||||
this.setData({ isLoadingLocations: true });
|
this.setData({ isLoadingLocations: true });
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
const { selectedLocationTypeIndex, locationTypes } = this.data;
|
||||||
|
|
||||||
|
// 构建查询条件
|
||||||
|
const equalsExample: { [key: string]: number | string } = {
|
||||||
|
travelId: Number(travelId)
|
||||||
|
};
|
||||||
|
|
||||||
|
// 添加类型过滤(索引 0 表示"全部")
|
||||||
|
if (0 < selectedLocationTypeIndex) {
|
||||||
|
const selectedTypeLabel = locationTypes[selectedLocationTypeIndex];
|
||||||
|
const selectedType = Object.keys(TravelLocationTypeLabel).find(
|
||||||
|
key => TravelLocationTypeLabel[key as TravelLocationType] === selectedTypeLabel
|
||||||
|
) as TravelLocationType | undefined;
|
||||||
|
|
||||||
|
if (selectedType) {
|
||||||
|
equalsExample.type = selectedType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const result = await TravelLocationApi.getList({
|
const result = await TravelLocationApi.getList({
|
||||||
index: 0,
|
index: 0,
|
||||||
size: 100,
|
size: 999,
|
||||||
equalsExample: {
|
equalsExample
|
||||||
travelId: Number(travelId)
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
this.setData({ locations: result.list });
|
const locations = result.list.map((location) => {
|
||||||
|
const previewItem = location.items && 0 < location.items.length ? location.items[0] : undefined;
|
||||||
|
return {
|
||||||
|
...location,
|
||||||
|
previewThumb: previewItem ? `${config.url}/attachment/read/${previewItem.mongoId}` : undefined
|
||||||
|
};
|
||||||
|
});
|
||||||
|
this.setData({ locations });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("获取地点列表失败:", error);
|
console.error("获取地点列表失败:", error);
|
||||||
} finally {
|
} finally {
|
||||||
@ -125,6 +161,14 @@ Page({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/** 地点类型改变 */
|
||||||
|
onLocationTypeChange(e: WechatMiniprogram.PickerChange) {
|
||||||
|
const index = Number(e.detail.value);
|
||||||
|
this.setData({ selectedLocationTypeIndex: index });
|
||||||
|
// 重新从接口获取过滤后的数据
|
||||||
|
this.fetchLocations(this.data.travelId);
|
||||||
|
},
|
||||||
|
|
||||||
/** 编辑出行 */
|
/** 编辑出行 */
|
||||||
toEdit() {
|
toEdit() {
|
||||||
const { travel } = this.data;
|
const { travel } = this.data;
|
||||||
|
|||||||
@ -52,7 +52,15 @@
|
|||||||
<t-cell-group class="section locations">
|
<t-cell-group class="section locations">
|
||||||
<view slot="title" class="title">地点列表</view>
|
<view slot="title" class="title">地点列表</view>
|
||||||
<t-cell class="header">
|
<t-cell class="header">
|
||||||
<t-button slot="left-icon" theme="primary" icon="map" size="small" bind:tap="toMap">地图浏览</t-button>
|
<view slot="left-icon" class="left-actions">
|
||||||
|
<t-button theme="primary" icon="map" size="small" bind:tap="toMap">地图浏览</t-button>
|
||||||
|
<picker class="type-picker" mode="selector" range="{{locationTypes}}" value="{{selectedLocationTypeIndex}}" bind:change="onLocationTypeChange">
|
||||||
|
<view class="picker-button">
|
||||||
|
<text>{{locationTypes[selectedLocationTypeIndex]}}</text>
|
||||||
|
<t-icon class="icon" name="chevron-down" size="16px" />
|
||||||
|
</view>
|
||||||
|
</picker>
|
||||||
|
</view>
|
||||||
<t-icon slot="right-icon" name="add" size="20px" color="var(--theme-wx)" bind:tap="toAddLocation" />
|
<t-icon slot="right-icon" name="add" size="20px" color="var(--theme-wx)" bind:tap="toAddLocation" />
|
||||||
</t-cell>
|
</t-cell>
|
||||||
<t-cell wx:if="{{isLoadingLocations}}" class="loading">
|
<t-cell wx:if="{{isLoadingLocations}}" class="loading">
|
||||||
@ -63,12 +71,17 @@
|
|||||||
class="location"
|
class="location"
|
||||||
wx:for="{{locations}}"
|
wx:for="{{locations}}"
|
||||||
wx:key="id"
|
wx:key="id"
|
||||||
left-icon="{{locationTypeIcons[item.type]}}"
|
|
||||||
title="{{item.title || '未命名地点'}}"
|
title="{{item.title || '未命名地点'}}"
|
||||||
bind:tap="toLocationDetail"
|
bind:tap="toLocationDetail"
|
||||||
data-id="{{item.id}}"
|
data-id="{{item.id}}"
|
||||||
arrow
|
arrow
|
||||||
>
|
>
|
||||||
|
<view slot="left-icon" class="thumb">
|
||||||
|
<image wx:if="{{item.previewThumb}}" class="thumb-img" src="{{item.previewThumb}}" mode="aspectFill" />
|
||||||
|
<view wx:else class="thumb-placeholder">
|
||||||
|
<t-icon name="{{locationTypeIcons[item.type]}}" size="28px" color="var(--theme-wx)" />
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
<view slot="note" class="note">{{locationTypeLabels[item.type]}}</view>
|
<view slot="note" class="note">{{locationTypeLabels[item.type]}}</view>
|
||||||
<view slot="description" class="description">
|
<view slot="description" class="description">
|
||||||
<view wx:if="{{item.requireIdCard}}" class="item">
|
<view wx:if="{{item.requireIdCard}}" class="item">
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
import config from "../../../config/index";
|
import config from "../../../config/index";
|
||||||
import { TravelLocationApi } from "../../../api/TravelLocationApi";
|
import { TravelLocationApi } from "../../../api/TravelLocationApi";
|
||||||
import { TravelLocation, TravelLocationTypeIcon, TravelLocationTypeLabel } from "../../../types/Travel";
|
import { TravelLocation, TravelLocationTypeIcon, TravelLocationTypeLabel } from "../../../types/Travel";
|
||||||
import { MediaAttachExt, MediaAttachType } from "../../../types/Attachment";
|
import { MediaAttachType, PreviewImageMetadata } from "../../../types/Attachment";
|
||||||
import { MapMarker, MediaItem, MediaItemType } from "../../../types/UI";
|
import { MapMarker, MediaItem, MediaItemType } from "../../../types/UI";
|
||||||
import Toolkit from "../../../utils/Toolkit";
|
import Toolkit from "../../../utils/Toolkit";
|
||||||
|
|
||||||
@ -95,18 +95,19 @@ Page({
|
|||||||
|
|
||||||
thumbItems.forEach((thumbItem) => {
|
thumbItems.forEach((thumbItem) => {
|
||||||
try {
|
try {
|
||||||
const ext = JSON.parse(thumbItem.ext!.toString()) as MediaAttachExt;
|
const metadata = (typeof thumbItem.metadata === "string" ? JSON.parse(thumbItem.metadata) : thumbItem.metadata) as PreviewImageMetadata;
|
||||||
const thumbURL = `${config.url}/attachment/read/${thumbItem.mongoId}`;
|
const thumbURL = `${config.url}/attachment/read/${thumbItem.mongoId}`;
|
||||||
const sourceURL = `${config.url}/attachment/read/${ext.sourceMongoId}`;
|
const sourceURL = `${config.url}/attachment/read/${metadata.sourceMongoId}`;
|
||||||
|
const isVideo = metadata.sourceMimeType?.startsWith("video/");
|
||||||
mediaItems.push({
|
mediaItems.push({
|
||||||
type: ext.isVideo ? MediaItemType.VIDEO : MediaItemType.IMAGE,
|
type: isVideo ? MediaItemType.VIDEO : MediaItemType.IMAGE,
|
||||||
thumbURL,
|
thumbURL,
|
||||||
sourceURL,
|
sourceURL,
|
||||||
size: thumbItem.size || 0,
|
size: thumbItem.size || 0,
|
||||||
attachmentId: thumbItem.id!
|
attachmentId: thumbItem.id!
|
||||||
});
|
});
|
||||||
} catch (parseError) {
|
} catch (parseError) {
|
||||||
console.warn("解析附件扩展信息失败", parseError);
|
console.warn("解析附件元数据失败", parseError);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
import { Network, WechatMediaItem } from "../../../utils/Network";
|
import { Network, WechatMediaItem } from "../../../utils/Network";
|
||||||
import { TravelLocationApi } from "../../../api/TravelLocationApi";
|
import { TravelLocationApi } from "../../../api/TravelLocationApi";
|
||||||
import { TravelLocationType } from "../../../types/Travel";
|
import { TravelLocationType, TravelLocationTypeLabel } from "../../../types/Travel";
|
||||||
import { MediaAttachExt, MediaAttachType } from "../../../types/Attachment";
|
import { MediaAttachType, PreviewImageMetadata } from "../../../types/Attachment";
|
||||||
import config from "../../../config/index";
|
import config from "../../../config/index";
|
||||||
import { MediaItem, MediaItemType } from "../../../types/UI";
|
import { MediaItem, MediaItemType } from "../../../types/UI";
|
||||||
|
|
||||||
@ -93,7 +93,7 @@ Page({
|
|||||||
mediaItemTypeEnum: {
|
mediaItemTypeEnum: {
|
||||||
...MediaItemType
|
...MediaItemType
|
||||||
},
|
},
|
||||||
locationTypes: ["美食", "酒店", "交通", "景点", "购物", "玩乐", "生活"],
|
locationTypes: Object.values(TravelLocationTypeLabel),
|
||||||
locationTypeValues: [
|
locationTypeValues: [
|
||||||
TravelLocationType.FOOD,
|
TravelLocationType.FOOD,
|
||||||
TravelLocationType.HOTEL,
|
TravelLocationType.HOTEL,
|
||||||
@ -161,11 +161,12 @@ Page({
|
|||||||
const thumbItems = items.filter((item) => item.attachType === MediaAttachType.THUMB);
|
const thumbItems = items.filter((item) => item.attachType === MediaAttachType.THUMB);
|
||||||
|
|
||||||
const mediaList: MediaItem[] = thumbItems.map((thumbItem) => {
|
const mediaList: MediaItem[] = thumbItems.map((thumbItem) => {
|
||||||
const ext = thumbItem.ext = JSON.parse(thumbItem.ext!.toString()) as MediaAttachExt;
|
const metadata = (typeof thumbItem.metadata === "string" ? JSON.parse(thumbItem.metadata) : thumbItem.metadata) as PreviewImageMetadata;
|
||||||
const thumbURL = `${config.url}/attachment/read/${thumbItem.mongoId}`;
|
const thumbURL = `${config.url}/attachment/read/${thumbItem.mongoId}`;
|
||||||
const sourceURL = `${config.url}/attachment/read/${ext.sourceMongoId}`;
|
const sourceURL = `${config.url}/attachment/read/${metadata.sourceMongoId}`;
|
||||||
|
const isVideo = metadata.sourceMimeType?.startsWith("video/");
|
||||||
return {
|
return {
|
||||||
type: ext.isVideo ? MediaItemType.VIDEO : MediaItemType.IMAGE,
|
type: isVideo ? MediaItemType.VIDEO : MediaItemType.IMAGE,
|
||||||
thumbURL,
|
thumbURL,
|
||||||
sourceURL,
|
sourceURL,
|
||||||
size: thumbItem.size || 0,
|
size: thumbItem.size || 0,
|
||||||
|
|||||||
@ -17,7 +17,7 @@ export type Attachment = {
|
|||||||
|
|
||||||
mimeType?: string;
|
mimeType?: string;
|
||||||
|
|
||||||
metadata?: string | ImageMetadata;
|
metadata?: string | ImageMetadata | PreviewImageMetadata;
|
||||||
|
|
||||||
/** 文件 MD5 */
|
/** 文件 MD5 */
|
||||||
md5: string;
|
md5: string;
|
||||||
@ -27,9 +27,6 @@ export type Attachment = {
|
|||||||
|
|
||||||
/** 大小 */
|
/** 大小 */
|
||||||
size: number;
|
size: number;
|
||||||
|
|
||||||
/** 扩展数据 */
|
|
||||||
ext?: string | MediaAttachExt;
|
|
||||||
} & Model;
|
} & Model;
|
||||||
|
|
||||||
/** 媒体附件类型 */
|
/** 媒体附件类型 */
|
||||||
@ -52,8 +49,7 @@ export type ImageMetadata = {
|
|||||||
height: number;
|
height: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 媒体附件扩展数据 */
|
export type PreviewImageMetadata = {
|
||||||
export type MediaAttachExt = {
|
|
||||||
|
|
||||||
/** 原文件附件 ID */
|
/** 原文件附件 ID */
|
||||||
sourceId: number;
|
sourceId: number;
|
||||||
@ -61,15 +57,6 @@ export type MediaAttachExt = {
|
|||||||
/** 原文件访问 mongoId */
|
/** 原文件访问 mongoId */
|
||||||
sourceMongoId: string;
|
sourceMongoId: string;
|
||||||
|
|
||||||
/** true 为图片 */
|
/** 原文件 MimeType */
|
||||||
isImage: boolean;
|
sourceMimeType: string;
|
||||||
|
} & ImageMetadata;
|
||||||
/** true 为视频 */
|
|
||||||
isVideo: boolean;
|
|
||||||
|
|
||||||
/** 原图宽度(像素) */
|
|
||||||
width?: number;
|
|
||||||
|
|
||||||
/** 原图高度(像素) */
|
|
||||||
height?: number;
|
|
||||||
}
|
|
||||||
|
|||||||
@ -94,6 +94,7 @@ export enum TravelLocationType {
|
|||||||
HOTEL = "HOTEL",
|
HOTEL = "HOTEL",
|
||||||
TRANSPORT = "TRANSPORT",
|
TRANSPORT = "TRANSPORT",
|
||||||
ATTRACTION = "ATTRACTION",
|
ATTRACTION = "ATTRACTION",
|
||||||
|
MALL = "MALL",
|
||||||
SHOPPING = "SHOPPING",
|
SHOPPING = "SHOPPING",
|
||||||
PLAY = "PLAY",
|
PLAY = "PLAY",
|
||||||
LIFE = "LIFE"
|
LIFE = "LIFE"
|
||||||
@ -105,6 +106,7 @@ export const TravelLocationTypeLabel: Record<TravelLocationType, string> = {
|
|||||||
[TravelLocationType.HOTEL]: "酒店",
|
[TravelLocationType.HOTEL]: "酒店",
|
||||||
[TravelLocationType.TRANSPORT]: "交通",
|
[TravelLocationType.TRANSPORT]: "交通",
|
||||||
[TravelLocationType.ATTRACTION]: "景点",
|
[TravelLocationType.ATTRACTION]: "景点",
|
||||||
|
[TravelLocationType.MALL]: "商场",
|
||||||
[TravelLocationType.SHOPPING]: "购物",
|
[TravelLocationType.SHOPPING]: "购物",
|
||||||
[TravelLocationType.PLAY]: "玩乐",
|
[TravelLocationType.PLAY]: "玩乐",
|
||||||
[TravelLocationType.LIFE]: "生活"
|
[TravelLocationType.LIFE]: "生活"
|
||||||
@ -116,6 +118,7 @@ export const TravelLocationTypeIcon: Record<TravelLocationType, string> = {
|
|||||||
[TravelLocationType.HOTEL]: "city-8",
|
[TravelLocationType.HOTEL]: "city-8",
|
||||||
[TravelLocationType.TRANSPORT]: "map-route-planning",
|
[TravelLocationType.TRANSPORT]: "map-route-planning",
|
||||||
[TravelLocationType.ATTRACTION]: "image-1",
|
[TravelLocationType.ATTRACTION]: "image-1",
|
||||||
|
[TravelLocationType.MALL]: "chart-3d",
|
||||||
[TravelLocationType.SHOPPING]: "shop",
|
[TravelLocationType.SHOPPING]: "shop",
|
||||||
[TravelLocationType.PLAY]: "ferris-wheel",
|
[TravelLocationType.PLAY]: "ferris-wheel",
|
||||||
[TravelLocationType.LIFE]: "location"
|
[TravelLocationType.LIFE]: "location"
|
||||||
|
|||||||
Reference in New Issue
Block a user