Files
gaoYuJournal/miniprogram/pages/main/travel-editor/index.ts
2025-12-17 16:16:10 +08:00

338 lines
7.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// pages/main/travel-editor/index.ts
import Time from "../../../utils/Time";
import { TravelApi } from "../../../api/TravelApi";
import { TravelStatus, TransportationType } from "../../../types/Travel";
interface TravelEditorData {
/** 模式create 或 edit */
mode: "create" | "edit";
/** 出行 ID编辑模式 */
id?: number;
/** 标题 */
title: string;
/** 内容 */
content: string;
/** 出行日期 */
date: string;
/** 出行时间 */
time: string;
/** 出行时间是否未定 */
travelAtUndecided: boolean;
/** 天数 */
days: number;
/** 天数是否未定 */
daysUndecided: boolean;
/** 交通类型 */
transportationType: TransportationType;
/** 状态 */
status: TravelStatus;
/** 是否正在加载(编辑模式) */
isLoading: boolean;
/** 是否正在保存 */
isSaving: boolean;
/** 交通类型选项 */
transportationTypes: { label: string; value: TransportationType }[];
/** 交通类型选中索引 */
transportationTypeIndex: number;
/** 状态选项 */
statuses: { label: string; value: TravelStatus }[];
/** 状态选中索引 */
statusIndex: number;
/** 删除对话框可见性 */
deleteDialogVisible: boolean;
/** 删除确认文本 */
deleteConfirmText: string;
}
Page({
data: <TravelEditorData>{
mode: "create",
id: undefined,
title: "",
content: "",
date: "2025-06-28",
time: "16:00",
travelAtUndecided: true,
days: 1,
daysUndecided: true,
transportationType: TransportationType.SELF_DRIVING,
transportationTypeIndex: 4,
status: TravelStatus.PLANNING,
statusIndex: 0,
isLoading: false,
isSaving: false,
transportationTypes: [
{ label: "飞机", value: TransportationType.PLANE },
{ label: "火车", value: TransportationType.TRAIN },
{ label: "汽车", value: TransportationType.CAR },
{ label: "轮船", value: TransportationType.SHIP },
{ label: "自驾", value: TransportationType.SELF_DRIVING },
{ label: "其他", value: TransportationType.OTHER }
],
statuses: [
{ label: "计划中", value: TravelStatus.PLANNING },
{ label: "进行中", value: TravelStatus.ONGOING },
{ label: "已完成", value: TravelStatus.COMPLETED }
],
deleteDialogVisible: false,
deleteConfirmText: ""
},
onLoad(options: any) {
// 判断模式:有 ID 是编辑,无 ID 是创建
const id = options.id ? parseInt(options.id) : undefined;
if (id) {
// 编辑模式
this.setData({
mode: "edit",
id,
isLoading: true
});
this.loadTravelDetail(id);
} else {
// 创建模式
this.setData({
mode: "create",
isLoading: false
});
// 设置当前时间
const unixTime = new Date().getTime();
this.setData({
date: Time.toDate(unixTime),
time: Time.toTime(unixTime)
});
}
},
/** 加载出行详情(编辑模式) */
async loadTravelDetail(id: number) {
wx.showLoading({ title: "加载中...", mask: true });
try {
const travel = await TravelApi.getDetail(id);
// 格式化数据
let date = "";
let time = "";
let travelAtUndecided = true;
if (travel.travelAt) {
date = Time.toDate(travel.travelAt);
time = Time.toTime(travel.travelAt);
travelAtUndecided = false;
}
// 判断天数是否未定
const daysUndecided = !travel.days;
const days = travel.days || 1;
// 计算交通类型索引
const transportationType = travel.transportationType || TransportationType.SELF_DRIVING;
const transportationTypeIndex = this.data.transportationTypes.findIndex(
item => item.value === transportationType
);
// 计算状态索引
const status = travel.status || TravelStatus.PLANNING;
const statusIndex = this.data.statuses.findIndex(item => item.value === status);
this.setData({
title: travel.title || "",
content: travel.content || "",
date,
time,
travelAtUndecided,
days,
daysUndecided,
transportationType,
transportationTypeIndex: transportationTypeIndex >= 0 ? transportationTypeIndex : 4,
status,
statusIndex: statusIndex >= 0 ? statusIndex : 0,
isLoading: false
});
} catch (error) {
wx.showToast({
title: "加载失败",
icon: "error"
});
setTimeout(() => {
wx.navigateBack();
}, 1500);
} finally {
wx.hideLoading();
}
},
/** 改变交通类型 */
onChangeTransportationType(e: any) {
const index = e.detail.value;
this.setData({
transportationTypeIndex: index,
transportationType: this.data.transportationTypes[index].value
});
},
/** 改变状态 */
onChangeStatus(e: any) {
const index = e.detail.value;
this.setData({
statusIndex: index,
status: this.data.statuses[index].value
});
},
/** 切换出行时间未定状态 */
toggleTravelAtUndecided(e: any) {
this.setData({ travelAtUndecided: e.detail.value });
},
/** 切换天数未定状态 */
toggleDaysUndecided(e: any) {
this.setData({ daysUndecided: e.detail.value });
},
/** 清除出行时间 */
clearTravelAt() {
this.setData({ travelAtUndecided: true });
},
/** 清除天数 */
clearDays() {
this.setData({ daysUndecided: true });
},
/** 点击未定文字选择时间 */
selectTravelAt() {
// 设置为已定状态,会自动显示选择器
const unixTime = new Date().getTime();
this.setData({
travelAtUndecided: false,
date: Time.toDate(unixTime),
time: Time.toTime(unixTime)
});
},
/** 点击未定文字选择天数 */
selectDays() {
this.setData({
daysUndecided: false,
days: 1
});
},
/** 取消 */
cancel() {
wx.navigateBack();
},
/** 提交/保存 */
submit() {
// 验证必填字段
if (!this.data.title.trim()) {
wx.showToast({
title: "请输入标题",
icon: "error"
});
return;
}
if (this.data.mode === "create") {
this.createTravel();
} else {
this.updateTravel();
}
},
/** 创建出行 */
async createTravel() {
this.setData({ isSaving: true });
try {
await TravelApi.create({
title: this.data.title.trim(),
content: this.data.content.trim(),
travelAt: this.data.travelAtUndecided ? null : Time.now(),
days: this.data.daysUndecided ? null : this.data.days,
transportationType: this.data.transportationType,
status: this.data.status
});
wx.showToast({
title: "创建成功",
icon: "success"
});
setTimeout(() => {
wx.navigateBack();
}, 1000);
} catch (error) {
this.setData({ isSaving: false });
}
},
/** 更新出行 */
async updateTravel() {
this.setData({ isSaving: true });
try {
await TravelApi.update({
id: this.data.id!,
title: this.data.title.trim(),
content: this.data.content.trim(),
travelAt: this.data.travelAtUndecided
? null
: new Date(`${this.data.date}T${this.data.time}:00`).getTime(),
days: this.data.daysUndecided ? null : this.data.days,
transportationType: this.data.transportationType,
status: this.data.status
});
wx.showToast({
title: "保存成功",
icon: "success"
});
setTimeout(() => {
wx.navigateBack();
}, 1000);
} catch (error) {
this.setData({ isSaving: false });
}
},
/** 删除出行 */
deleteTravel() {
this.setData({
deleteDialogVisible: true,
deleteConfirmText: ""
});
},
/** 取消删除 */
cancelDelete() {
this.setData({
deleteDialogVisible: false,
deleteConfirmText: ""
});
},
/** 确认删除 */
confirmDelete() {
const inputText = this.data.deleteConfirmText.trim();
if (inputText !== "确认删除") {
wx.showToast({
title: "输入不匹配",
icon: "error"
});
return;
}
this.setData({
deleteDialogVisible: false
});
this.executeDelete();
},
/** 执行删除 */
async executeDelete() {
if (!this.data.id) return;
wx.showLoading({ title: "删除中...", mask: true });
try {
await TravelApi.delete(this.data.id);
wx.showToast({
title: "删除成功",
icon: "success"
});
setTimeout(() => {
wx.navigateBack({ delta: 2 });
}, 1500);
} catch (error) {
// 错误已由 Network 类处理
} finally {
wx.hideLoading();
}
}
});