Files
PetCommunity/miniprogram/pages/post/post.ts
2026-06-05 17:46:51 +08:00

197 lines
5.5 KiB
TypeScript

import { api } from '../../utils/api'
import { chooseAndUploadMedia } from '../../utils/auth'
import { MOOD_OPTIONS, HOT_HASHTAGS } from '../../utils/constants'
import { getPetEmoji } from '../../utils/format'
const app = getApp<{ userInfo: any; currentLocation: any }>()
Page({
data: {
statusBarHeight: 0,
content: '',
images: [] as any[],
location: null as any,
selectedPetId: '',
selectedHashtags: [] as string[],
hashtagInput: '',
selectedMood: '',
moods: MOOD_OPTIONS,
hotHashtags: HOT_HASHTAGS.slice(0, 6),
myPets: [] as any[],
submitting: false,
canSubmit: false,
},
onLoad() {
const info = wx.getSystemInfoSync()
this.setData({ statusBarHeight: info.statusBarHeight })
this.loadMyPets()
this.autoGetLocation()
},
loadMyPets() {
const user = app.globalData?.userInfo
if (!user?.pets?.length) return
const pets = user.pets.map((p: any) => ({
...p,
emoji: getPetEmoji(p.species, p.breed),
}))
this.setData({
myPets: pets,
selectedPetId: pets[0]?._id || '',
})
},
autoGetLocation() {
const loc = app.globalData?.currentLocation
if (!loc) return
wx.reverseGeocoder({
location: { longitude: loc.longitude, latitude: loc.latitude },
success: (res: any) => {
const name = res.result?.address || ''
if (name) {
this.setData({
location: { name, latitude: loc.latitude, longitude: loc.longitude },
})
this.checkCanSubmit()
}
},
fail: () => {},
} as any)
},
onContentInput(e: WechatMiniprogram.CustomEvent) {
this.setData({ content: e.detail.value })
this.checkCanSubmit()
},
checkCanSubmit() {
const { content, images } = this.data
this.setData({ canSubmit: content.trim().length > 0 || images.length > 0 })
},
async onChooseImage() {
try {
const fileIDs = await chooseAndUploadMedia(9 - this.data.images.length)
const newImages = fileIDs.map(id => ({ fileID: id, tempPath: id }))
this.setData({ images: [...this.data.images, ...newImages] })
this.checkCanSubmit()
} catch (e: any) {
if (e?.errMsg?.includes('cancel')) return
wx.showToast({ title: '上传失败', icon: 'none' })
}
},
onRemoveImage(e: WechatMiniprogram.CustomEvent) {
const idx = e.currentTarget.dataset.idx as number
const images = [...this.data.images]
images.splice(idx, 1)
this.setData({ images })
this.checkCanSubmit()
},
onPreviewImage(e: WechatMiniprogram.CustomEvent) {
const idx = e.currentTarget.dataset.idx as number
wx.previewImage({
current: this.data.images[idx]?.tempPath || this.data.images[idx],
urls: this.data.images.map((img: any) => img.tempPath || img),
})
},
onChooseLocation() {
wx.chooseLocation({
success: res => {
this.setData({
location: {
name: res.name || res.address,
latitude: res.latitude,
longitude: res.longitude,
},
})
},
fail: () => {},
})
},
onRemoveLocation() {
this.setData({ location: null })
},
onSelectPet(e: WechatMiniprogram.CustomEvent) {
const id = e.currentTarget.dataset.id as string
this.setData({ selectedPetId: this.data.selectedPetId === id ? '' : id })
},
onHashtagInput(e: WechatMiniprogram.CustomEvent) {
this.setData({ hashtagInput: e.detail.value })
},
onAddHashtag() {
let tag = this.data.hashtagInput.trim().replace(/^#/, '')
if (!tag) return
const tags = [...this.data.selectedHashtags]
if (!tags.includes(tag) && tags.length < 5) {
tags.push(tag)
}
this.setData({ selectedHashtags: tags, hashtagInput: '' })
},
onRemoveHashtag(e: WechatMiniprogram.CustomEvent) {
const idx = e.currentTarget.dataset.idx as number
const tags = [...this.data.selectedHashtags]
tags.splice(idx, 1)
this.setData({ selectedHashtags: tags })
},
onHotTag(e: WechatMiniprogram.CustomEvent) {
const tag = (e.currentTarget.dataset.tag as string).replace(/^#/, '')
const tags = [...this.data.selectedHashtags]
if (!tags.includes(tag) && tags.length < 5) {
tags.push(tag)
this.setData({ selectedHashtags: tags })
}
},
onSelectMood(e: WechatMiniprogram.CustomEvent) {
const val = e.currentTarget.dataset.val as string
this.setData({ selectedMood: this.data.selectedMood === val ? '' : val })
},
async onSubmit() {
if (!this.data.canSubmit || this.data.submitting) return
this.setData({ submitting: true })
try {
const moodLabel = MOOD_OPTIONS.find(m => m.value === this.data.selectedMood)?.label
await api.createPost({
content: this.data.content.trim(),
images: this.data.images.map((img: any) => img.fileID || img),
location: this.data.location,
hashtags: this.data.selectedHashtags.map(t => `#${t}`),
mood: moodLabel,
petId: this.data.selectedPetId || undefined,
})
wx.showToast({ title: '发布成功!', icon: 'success' })
setTimeout(() => wx.navigateBack(), 1200)
} catch {
wx.showToast({ title: '发布失败,请重试', icon: 'none' })
this.setData({ submitting: false })
}
},
onCancel() {
if (this.data.content || this.data.images.length > 0) {
wx.showModal({
title: '放弃编辑?',
content: '内容将不会保存',
confirmText: '放弃',
cancelText: '继续',
success: res => { if (res.confirm) wx.navigateBack() },
})
} else {
wx.navigateBack()
}
},
})