mcwl-pc/app/components/PublishContent.vue

218 lines
6.3 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 { FolderPlus, Image, ImagePlus } from 'lucide-vue-next'
import { useMessage } from 'naive-ui'
import { computed, 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({
content: '',
fileUrl: '',
fileName: '',
imageUrl: '',
})
// 图片上传相关
const fileUrl = ref<string[]>([])
const fileName = ref<string[]>([])
const imageUrl = ref<string[]>([])
const loading = ref(false)
// 表单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,
fileUrl: fileUrl.value.join(','),
fileName: fileName.value.join(','),
imageUrl: imageUrl.value.join(','),
}
const res = await request.post('/publish/publish', params)
if (res.code === 200) {
message.success('发布成功')
// 重置表单
formData.value = {
content: '',
fileUrl: '',
fileName: '',
imageUrl: '',
}
fileUrl.value = []
fileName.value = []
imageUrl.value = [] // 清空图片URL列表
emit('success') // 触发成功事件
}
}
catch (error) {
console.error(error)
}
finally {
loading.value = false
}
}
// 当前上传类型
const currentUploadType = ref<string | null>(null)
const acceptTypes = computed(() => {
return currentUploadType.value === 'img'
? 'image/*'
: 'application/pdf,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document,application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-powerpoint,application/vnd.openxmlformats-officedocument.presentationml.presentation,text/plain,application/zip'
})
// 图片上传input
const pictureInput = ref<HTMLInputElement | null>(null)
function handlePictureInput(type: string) {
currentUploadType.value = type
nextTick(() => {
pictureInput.value?.click()
})
}
// 处理图片上传
async function handlePictureChange(event: Event) {
const files = (event.target as HTMLInputElement).files
if (!files || files.length === 0)
return message.error('请选择有效的文件')
try {
const fileList = Array.from(files)
const isImageUpload = currentUploadType.value === 'img'
// 根据上传类型验证文件
const validFiles = fileList.filter(file =>
isImageUpload ? file.type.startsWith('image/') : !file.type.startsWith('image/'),
)
if (validFiles.length === 0)
return message.error(`请选择${isImageUpload ? '图片' : '文档'}文件`)
const uploadResults = await uploadImagesInBatches(validFiles)
// 处理上传结果
if (isImageUpload) {
imageUrl.value.push(...uploadResults.map((item: any) => item.url))
}
else {
fileUrl.value.push(...uploadResults.map((item: any) => item.url))
fileName.value.push(...uploadResults.map((item: any) => item.fileName))
}
pictureInput.value!.value = '' // 清空input值允许重复选择相同文件
}
catch (error) {
message.error(currentUploadType.value === 'img' ? '图片上传失败' : '文件上传失败')
}
}
</script>
<template>
<div class="bg-white rounded-lg px-6">
<n-form
ref="formRef"
:model="formData"
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="fileName.length > 0" class="mt-4 flex flex-wrap gap-3 mb-2">
<div
v-for="(item, index) in fileName"
:key="index"
class="flex items-center gap-2"
>
{{ item }}
<n-icon color="#3f7ef7" class="cursor-pointer flex items-center justify-center w-6 h-6">
<CloseOutline class="text-[20px]" size="20" @click="fileName.splice(index, 1)" />
</n-icon>
</div>
</div>
<!-- 上传的图片预览 -->
<div v-if="imageUrl.length > 0" class="mt-4 flex flex-wrap gap-3 mb-2">
<div
v-for="(item, index) in imageUrl"
:key="index"
class="relative group"
>
<img
:src="item"
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-form-item> -->
<div class="flex items-center justify-between my-2">
<div class="flex">
<div class="border border-gray-300 rounded p-1 cursor-pointer hover:bg-gray-50 transition-colors mr-6" @click="handlePictureInput('img')">
<ImagePlus class="w-5 h-5" />
</div>
<div class="border border-gray-300 rounded p-1 cursor-pointer hover:bg-gray-50 transition-colors" @click="handlePictureInput('file')">
<FolderPlus class="w-5 h-5" />
</div>
</div>
<div class="flex items-center gap-8">
<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="acceptTypes"
class="hidden"
multiple="true"
@change="handlePictureChange"
>
</div>
</template>