1.2
This commit is contained in:
@@ -49,6 +49,20 @@
|
||||
<div class="compose-body">
|
||||
<n-input v-model:value="composeText" type="textarea" :rows="4"
|
||||
placeholder="分享你的想法..." maxlength="1000" show-count />
|
||||
<!-- 图片选择 -->
|
||||
<div class="image-upload-area">
|
||||
<div class="image-previews">
|
||||
<div v-for="(img, i) in composeImages" :key="i" class="image-preview-item">
|
||||
<img :src="img" />
|
||||
<span class="remove-img" @click="composeImages.splice(i, 1)">✕</span>
|
||||
</div>
|
||||
<div v-if="composeImages.length < 9" class="add-image-btn" @click="triggerMomentImage">
|
||||
<span>+</span>
|
||||
<span style="font-size:11px">图片</span>
|
||||
</div>
|
||||
</div>
|
||||
<input ref="momentImageInput" type="file" accept="image/*" multiple style="display:none" @change="handleMomentImages" />
|
||||
</div>
|
||||
<div class="compose-options">
|
||||
<div class="visibility-select">
|
||||
<span class="option-label">可见范围:</span>
|
||||
@@ -73,6 +87,7 @@
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { useMomentsStore } from '@/stores/moments'
|
||||
import { useMessage } from 'naive-ui'
|
||||
import api from '@/api/client'
|
||||
import MomentCard from './MomentCard.vue'
|
||||
|
||||
const momentsStore = useMomentsStore()
|
||||
@@ -82,18 +97,41 @@ const showCompose = ref(false)
|
||||
const composeText = ref('')
|
||||
const composeVisibility = ref('friends')
|
||||
const publishing = ref(false)
|
||||
const composeImages = ref<string[]>([])
|
||||
const momentImageInput = ref<HTMLInputElement>()
|
||||
|
||||
onMounted(() => {
|
||||
momentsStore.fetchFeed(true)
|
||||
})
|
||||
|
||||
function triggerMomentImage() {
|
||||
momentImageInput.value?.click()
|
||||
}
|
||||
|
||||
async function handleMomentImages(event: Event) {
|
||||
const target = event.target as HTMLInputElement
|
||||
const files = target.files
|
||||
if (!files) return
|
||||
for (let i = 0; i < files.length && composeImages.value.length < 9; i++) {
|
||||
try {
|
||||
const formData = new FormData()
|
||||
formData.append('file', files[i])
|
||||
const { data } = await api.post('/uploads/file', formData, { headers: { 'Content-Type': 'multipart/form-data' } })
|
||||
composeImages.value.push(data.url)
|
||||
} catch {}
|
||||
}
|
||||
target.value = ''
|
||||
}
|
||||
|
||||
async function publishMoment() {
|
||||
if (!composeText.value.trim()) return
|
||||
publishing.value = true
|
||||
try {
|
||||
await momentsStore.createMoment(composeText.value.trim(), undefined, composeVisibility.value)
|
||||
const images = composeImages.value.length > 0 ? composeImages.value : undefined
|
||||
await momentsStore.createMoment(composeText.value.trim(), images, composeVisibility.value)
|
||||
message.success('动态发布成功')
|
||||
composeText.value = ''
|
||||
composeImages.value = []
|
||||
showCompose.value = false
|
||||
} catch {
|
||||
message.error('发布失败')
|
||||
@@ -159,6 +197,24 @@ async function handleComment(momentId: string, content: string) {
|
||||
.close-btn:hover { color: var(--color-text-primary); }
|
||||
.compose-body { padding: 16px 24px; }
|
||||
.compose-options { margin-top: 12px; }
|
||||
|
||||
/* 图片上传 */
|
||||
.image-upload-area { margin-top: 10px; }
|
||||
.image-previews { display: flex; gap: 8px; flex-wrap: wrap; }
|
||||
.image-preview-item { width: 64px; height: 64px; position: relative; border-radius: 8px; overflow: hidden; }
|
||||
.image-preview-item img { width: 100%; height: 100%; object-fit: cover; }
|
||||
.remove-img {
|
||||
position: absolute; top: 2px; right: 2px; width: 18px; height: 18px;
|
||||
background: rgba(0,0,0,0.5); color: white; border-radius: 50%;
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
font-size: 10px; cursor: pointer;
|
||||
}
|
||||
.add-image-btn {
|
||||
width: 64px; height: 64px; border: 2px dashed var(--color-border); border-radius: 8px;
|
||||
display: flex; flex-direction: column; align-items: center; justify-content: center;
|
||||
cursor: pointer; color: var(--color-text-hint); font-size: 24px; transition: border-color 0.2s;
|
||||
}
|
||||
.add-image-btn:hover { border-color: var(--color-primary-lighter); color: var(--color-primary); }
|
||||
.visibility-select { display: flex; align-items: center; gap: 8px; }
|
||||
.option-label { font-size: 13px; color: var(--color-text-secondary); }
|
||||
.compose-footer {
|
||||
|
||||
Reference in New Issue
Block a user