283 lines
8.5 KiB
JavaScript
283 lines
8.5 KiB
JavaScript
// 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' });
|
|
}
|
|
}
|
|
})
|