feat: enable multi-option polls

This commit is contained in:
Tim
2025-08-31 12:13:41 +08:00
parent 3808becc8b
commit 2f339fdbdb
12 changed files with 117 additions and 32 deletions

View File

@@ -18,6 +18,12 @@
<flat-pickr v-model="data.endTime" :config="dateConfig" class="time-picker" />
</client-only>
</div>
<div class="poll-multiple-row">
<label class="poll-row-title">
<input type="checkbox" v-model="data.multiple" class="multiple-checkbox" />
多选
</label>
</div>
</div>
</template>
@@ -80,6 +86,13 @@ const removeOption = (idx) => {
display: flex;
flex-direction: column;
}
.poll-multiple-row {
display: flex;
align-items: center;
}
.multiple-checkbox {
margin-right: 5px;
}
.time-picker {
max-width: 200px;
height: 30px;

View File

@@ -29,23 +29,42 @@
</div>
</div>
<div v-else>
<div
v-for="(opt, idx) in poll.options"
:key="idx"
class="poll-option"
@click="voteOption(idx)"
>
<input type="radio" :checked="false" name="poll-option" class="poll-option-input" />
<span class="poll-option-text">{{ opt }}</span>
</div>
<div class="multi-selection-container">
<div class="multi-selection-title">
<i class="fas fa-info-circle info-icon"></i>
该投票为多选
<template v-if="poll.multiple">
<div
v-for="(opt, idx) in poll.options"
:key="idx"
class="poll-option"
@click="toggleOption(idx)"
>
<input
type="checkbox"
:checked="selectedOptions.includes(idx)"
class="poll-option-input"
/>
<span class="poll-option-text">{{ opt }}</span>
</div>
<div class="join-poll-button"><i class="fas fa-plus"></i> 加入投票</div>
</div>
<div class="multi-selection-container">
<div class="multi-selection-title">
<i class="fas fa-info-circle info-icon"></i>
该投票为多选
</div>
<div class="join-poll-button" @click="submitMultiPoll">
<i class="fas fa-plus"></i> 加入投票
</div>
</div>
</template>
<template v-else>
<div
v-for="(opt, idx) in poll.options"
:key="idx"
class="poll-option"
@click="voteOption(idx)"
>
<input type="radio" :checked="false" name="poll-option" class="poll-option-input" />
<span class="poll-option-text">{{ opt }}</span>
</div>
</template>
</div>
</div>
<div class="poll-info">
@@ -178,6 +197,40 @@ const voteOption = async (idx) => {
toast.error(data.error || '操作失败')
}
}
const selectedOptions = ref([])
const toggleOption = (idx) => {
const i = selectedOptions.value.indexOf(idx)
if (i >= 0) {
selectedOptions.value.splice(i, 1)
} else {
selectedOptions.value.push(idx)
}
}
const submitMultiPoll = async () => {
const token = getToken()
if (!token) {
toast.error('请先登录')
return
}
if (!selectedOptions.value.length) {
toast.error('请选择至少一个选项')
return
}
const params = selectedOptions.value.map((o) => `option=${o}`).join('&')
const res = await fetch(`${API_BASE_URL}/api/posts/${props.postId}/poll/vote?${params}`, {
method: 'POST',
headers: { Authorization: `Bearer ${token}` },
})
const data = await res.json().catch(() => ({}))
if (res.ok) {
toast.success('投票成功')
emit('refresh')
showPollResult.value = true
} else {
toast.error(data.error || '操作失败')
}
}
</script>
<style scoped>