// 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: { 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 : 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 }); } }, /** 更新旅行 */ 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(); } } });