mcwl-pc/app/components/QuestionPublish.vue

213 lines
5.6 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<script setup lang="ts">
import { CloseOutline } from '@vicons/ionicons5'
import { Image } from 'lucide-vue-next'
import { useMessage } from 'naive-ui'
import { ref } from 'vue'
import { uploadImagesInBatches } from '../utils/uploadImg.ts'
const props = defineProps<Props>()
const emit = defineEmits(['success'])
const userStore = useUserStore()
interface Props {
communityId: number | string
tenantId: number | string
}
const message = useMessage()
// 表单数据
const formData = ref({
type: 0, // 提问类型0免费1付费
amount: 10, // 付费金额
content: '', // 提问内容
isAnonymous: 0, // 是否匿名 1匿名 0不匿名
questionUrl: '', // 提问图片
})
// 图片上传相关
const fileList = ref<string[]>([])
const questionUrlList = ref<string[]>([])
const loading = ref(false)
// 表单验证规则
const rules = {
content: {
required: true,
message: '请输入提问内容',
// trigger: ['blur'],
},
amount: {
required: (formData: any) => formData.type === 1,
message: '请输入付费金额',
// trigger: ['blur', 'change'],
type: 'number',
},
}
// 表单ref
const formRef = ref()
// 处理发布提问
async function handlePublish() {
try {
await formRef.value?.validate()
loading.value = true
const params = {
...formData.value,
communityId: props.communityId,
tenantId: props.tenantId,
questionUserId: userStore.userInfo.userId,
questionUrl: questionUrlList.value.join(','), // 将图片URL数组转为逗号分隔的字符串
}
const res = await request.post('/question/addQuestion', params)
if (res.code === 200) {
message.success('提问成功')
// 重置表单
formData.value = {
type: 0,
amount: undefined,
content: '',
isAnonymous: 0,
questionUrl: '',
}
fileList.value = []
questionUrlList.value = [] // 清空图片URL列表
emit('success') // 触发成功事件
}
}
catch (error) {
console.error(error)
}
finally {
loading.value = false
}
}
const pictureInput = ref<HTMLInputElement | null>(null)
function handlePictureInput() {
pictureInput.value?.click()
}
// 处理图片上传
async function handlePictureChange(event: Event) {
const files = (event.target as HTMLInputElement).files
if (!files || files.length === 0)
return
const imageFiles = Array.from(files).filter(file => file.type.startsWith('image/'))
if (imageFiles.length === 0) {
message.error('请选择有效的图片文件')
return
}
try {
const pictureResultList = await uploadImagesInBatches(imageFiles)
questionUrlList.value.push(...pictureResultList.map((item: any) => item.url))
pictureInput.value!.value = ''
}
catch (error: any) {
message.error('图片上传失败')
}
}
</script>
<template>
<div class="bg-white rounded-lg px-6">
<n-form
ref="formRef"
:model="formData"
:rules="rules"
label-placement="left"
label-width="auto"
require-mark-placement="right-hanging"
>
<n-form-item path="content" :show-label="false">
<n-input
v-model:value="formData.content"
type="textarea"
placeholder="请输入提问内容"
:autosize="{ minRows: 5, maxRows: 10 }"
class="rounded-lg"
/>
</n-form-item>
<!-- 上传的图片预览 -->
<div v-if="questionUrlList.length > 0" class="mt-4 flex flex-wrap gap-3 mb-2">
<div
v-for="(url, index) in questionUrlList"
:key="index"
class="relative group"
>
<img
:src="url"
class="w-[125px] h-[125px] rounded"
>
<n-icon color="#fff" class="absolute top-1 right-1 p-1 z-40 cursor-pointer w-6 h-6">
<CloseOutline class="text-[20px]" size="20" @click="questionUrlList.splice(index, 1)" />
</n-icon>
</div>
</div>
<!-- <n-form-item v-if="formData.type === 1" path="amount" class="mb-3"> -->
<n-input-number
v-if="formData.type === 1"
v-model:value="formData.amount"
:min="10"
:max="999.9"
:precision="1"
placeholder="请输入付费金额"
class="w-[240px] my-5"
>
<template #prefix>
¥
</template>
</n-input-number>
<!-- </n-form-item> -->
<div class="flex items-center justify-between my-4">
<div class="border border-gray-300 rounded p-1 cursor-pointer hover:bg-gray-50 transition-colors" @click="handlePictureInput">
<Image class="w-6 h-6 size-6" />
</div>
<div class="flex items-center gap-8">
<n-radio-group v-model:value="formData.type">
<n-radio :value="0">
免费
</n-radio>
<n-radio :value="1">
</n-radio>
</n-radio-group>
<n-checkbox v-model:checked="formData.isAnonymous" unchecked-value="0" checked-value="1">
匿名提问
</n-checkbox>
<n-button
type="primary"
:loading="loading"
class="!px-8 rounded"
:theme-overrides="{
common: {
primaryColor: '#3f7ef7',
primaryColorHover: '#3f7ef7',
},
}"
@click="handlePublish"
>
提问
</n-button>
</div>
</div>
</n-form>
<input
ref="pictureInput"
type="file"
accept="image/*"
class="hidden"
@change="handlePictureChange"
>
</div>
</template>