// pages/community/create/index.js import request from '../../../utils/request'; Page({ data: { content: '', images: [], canPublish: false, // Only depends on content autoFocus: true, location: '', selectedTopics: [], suggestedTopics: ['植物养护', '多肉日记', '绿植分享', '花卉美照', '阳台花园', '新手入门'], showImageSheet: false, imageSheetItems: [ { label: '拍照', value: 'camera' }, { label: '从相册选取', value: 'album' } ], topicColors: ['#558B2F', '#1976D2', '#7B1FA2', '#F57C00', '#C2185B', '#00796B'], topicBgColors: ['#E8F5E9', '#E3F2FD', '#F3E5F5', '#FFF3E0', '#FCE4EC', '#E0F2F1'] }, onLoad() { this.fetchTopics(); }, fetchTopics() { request.get('/topic/list').then(res => { const list = res.list || []; const topics = list.map(t => t.title); if (topics.length > 0) { this.setData({ suggestedTopics: topics }); } }).catch(err => { console.error('Fetch topics failed', err); }); }, onContentInput(e) { const content = e.detail.value; this.setData({ content, canPublish: content.trim().length > 0 }); }, showImageSourceSheet() { this.setData({ showImageSheet: true }); }, hideImageSheet() { this.setData({ showImageSheet: false }); }, onImageSheetSelect(e) { const { value } = e.detail.selected; this.setData({ showImageSheet: false }); if (value === 'camera') { this.takePhoto(); } else { this.chooseImage(); } }, chooseImage() { const remaining = 9 - this.data.images.length; if (remaining <= 0) { wx.showToast({ title: '最多9张图片', icon: 'none' }); return; } wx.chooseMedia({ count: remaining, mediaType: ['image'], sourceType: ['album'], success: (res) => { const newImages = res.tempFiles.map(f => f.tempFilePath); this.setData({ images: [...this.data.images, ...newImages] }); } }); }, takePhoto() { if (this.data.images.length >= 9) { wx.showToast({ title: '最多9张图片', icon: 'none' }); return; } wx.chooseMedia({ count: 1, mediaType: ['image'], sourceType: ['camera'], camera: 'back', success: (res) => { const newImage = res.tempFiles[0].tempFilePath; this.setData({ images: [...this.data.images, newImage] }); } }); }, removeImage(e) { const index = e.currentTarget.dataset.index; const images = [...this.data.images]; images.splice(index, 1); this.setData({ images }); }, showImageMenu(e) { const index = e.currentTarget.dataset.index; wx.showActionSheet({ itemList: ['设为封面', '删除'], success: (res) => { if (res.tapIndex === 0) { const images = [...this.data.images]; const [img] = images.splice(index, 1); images.unshift(img); this.setData({ images }); wx.showToast({ title: '已设为封面', icon: 'success' }); } else if (res.tapIndex === 1) { this.removeImage({ currentTarget: { dataset: { index } } }); } } }); }, chooseLocation() { wx.chooseLocation({ success: (res) => { const formatted = this.formatLocation(res.address, res.name); this.setData({ location: formatted }); }, fail: () => { } }); }, formatLocation(address, name) { if (!address && !name) return ''; const source = address || ''; // 直辖市 const munis = ['北京', '上海', '天津', '重庆']; for (let m of munis) { if (source.startsWith(m + '市') || source.startsWith(m)) { return m; } } // 特别行政区 if (source.startsWith('香港') || source.startsWith('澳门')) { return source.substring(0, 2); } // 自治区:提取简称 const autoRegions = [ { prefix: '内蒙古', full: '内蒙古自治区' }, { prefix: '广西', full: '广西壮族自治区' }, { prefix: '西藏', full: '西藏自治区' }, { prefix: '宁夏', full: '宁夏回族自治区' }, { prefix: '新疆', full: '新疆维吾尔自治区' } ]; for (let region of autoRegions) { if (source.startsWith(region.prefix)) { return region.prefix; } } // 标准省份:只提取省名 const provinceMatch = source.match(/^(.+?)省/); if (provinceMatch) { return provinceMatch[1]; } // 如果都不匹配,截取短地址 if (source.length > 6) { return source.substring(0, 6); } return source || name || ''; }, toggleTopic(e) { const topic = e.currentTarget.dataset.topic; const hashtag = `#${topic} `; let { content, selectedTopics } = this.data; if (selectedTopics.includes(topic)) { // Remove topic and hashtag from content selectedTopics = selectedTopics.filter(t => t !== topic); content = content.replace(hashtag, ''); } else { if (selectedTopics.length >= 3) { wx.showToast({ title: '最多选择3个话题', icon: 'none' }); return; } // Add topic and insert hashtag into content selectedTopics.push(topic); content = content + hashtag; } this.setData({ selectedTopics, content, canPublish: content.trim().length > 0 }); }, handleCancel() { wx.navigateBack(); }, async handlePublish() { if (!this.data.content || !this.data.content.trim()) { wx.showToast({ title: '请输入内容', icon: 'none' }); return; } wx.showLoading({ title: '发布中...', mask: true }); try { // 1. Upload Images const ossIds = []; const images = this.data.images; if (images.length > 0) { const uploadPromises = images.map(filePath => { return request.upload(filePath).then(res => { // Res structure: { file: { id: "...", url: "..." } } return res && res.file ? res.file.id : null; }); }); const uploadedIds = await Promise.all(uploadPromises); uploadedIds.forEach(id => { if (id) ossIds.push(id); }); if (images.length > 0 && ossIds.length === 0) { throw new Error('图片上传失败'); } } // 2. Publish Post // Title is removed from UI. Using content snippet or default title. const content = this.data.content.trim(); const title = content.length > 20 ? content.substring(0, 20) + '...' : content; const payload = { title: title || '新动态', // Fallback title content: content, location: this.data.location || '', ossIds: ossIds }; await request.post('/post/publish', payload); wx.hideLoading(); wx.showToast({ title: '发布成功', icon: 'success' }); // 直接通知上一页(社区列表页)刷新数据 const pages = getCurrentPages(); const communityPage = pages[pages.length - 2]; if (communityPage && communityPage.onRefresh) { communityPage.onRefresh(); } setTimeout(() => { wx.navigateBack(); }, 1000); } catch (err) { wx.hideLoading(); console.error('Publish failed', err); wx.showToast({ title: '发布失败', icon: 'none' }); } } })