mcwl-pc/app/components/CreatePlanet.vue

286 lines
6.9 KiB
Vue

<script setup lang="ts">
import type { FormInst } from 'naive-ui'
import { commonApi } from '@/api/common'
import { uploadImagesInBatches } from '@/utils/uploadImg.ts'
import { NButton, NForm, NFormItem, NInput, NInputNumber, NModal, NRadio, NRadioGroup, NSelect, NSpace, NTextarea, useMessage } from 'naive-ui'
import { computed, ref } from 'vue'
const props = withDefaults(defineProps<Props>(), {
show: false,
})
const emit = defineEmits<{
(e: 'update:show', value: boolean): void
(e: 'success'): void
(e: 'refresh'): void
}>()
const message = useMessage()
interface Props {
show: boolean
}
const formRef = ref<FormInst | null>(null)
const loading = ref(false)
const formValue = ref({
imageUrl: '',
communityName: '',
communityTag: null,
type: '1',
price: 0,
validityDay: null,
description: '', // 添加描述字段
})
const rules = {
imageUrl: {
required: true,
message: '请上传封面',
trigger: 'change',
},
communityName: {
required: true,
message: '请输入星球名称',
},
communityTag: {
required: true,
message: '请选择星球标签',
},
validityDay: {
required: true,
message: '请选择有效期',
},
}
// 获取标签列表
const tagList = ref<{ dictLabel: string, dictValue: string }[]>([])
async function getDictType() {
try {
const res = await commonApi.dictType({ type: 'community_tag' })
if (res.code === 200)
tagList.value = res.data
}
catch (error) {
console.error(error)
}
}
getDictType()
const validTimeOptions = [
{ label: '1年', value: '1' },
{ label: '2年', value: '2' },
{ label: '3年', value: '3' },
]
const modelValue = computed({
get: () => props.show,
set: (value: boolean) => emit('update:show', value),
})
async function handleSubmit() {
try {
await formRef.value?.validate()
loading.value = true
const params = {
...formValue.value,
price: formValue.value.type === '1' ? formValue.value.price : 0,
}
const res = await request.post('/community/addCommunity', params)
if (res.code === 200) {
message.success('创建成功')
emit('success')
emit('refresh')
handleClose()
}
}
catch (error) {
console.error(error)
}
finally {
loading.value = false
}
}
function handleClose() {
emit('update:show', false)
formValue.value = {
name: '',
tags: [],
type: '',
price: 0,
validTime: 0,
description: '', // 重置描述字段
}
}
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
if (files.length > 1) {
message.error('只能选择 1 张图片')
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)
formValue.value.imageUrl = pictureResultList[0].url
;(event.target as HTMLInputElement).value = ''
}
catch (error: any) {
message.error('图片上传失败')
}
}
</script>
<template>
<NModal
v-model:show="modelValue"
preset="dialog"
title="创建星球"
:show-icon="false"
:mask-closable="false"
style="width: 420px"
:style="{
'width': '420px',
'--n-title-text-align': 'center',
}"
@close="handleClose"
>
<NForm
ref="formRef"
:model="formValue"
:rules="rules"
label-placement="top"
label-width="auto"
require-mark-placement="right-hanging"
size="large"
>
<!-- 上传封面 -->
<div class="flex justify-center">
<NFormItem path="imageUrl" style="margin-bottom: 0">
<div
class="w-[120px] h-[120px] bg-[#f7f8fa] rounded-lg flex items-center justify-center cursor-pointer mb-6 overflow-hidden"
@click="handlePictureInput"
>
<img
v-if="formValue.imageUrl"
:src="formValue.imageUrl"
class="w-full h-full object-cover"
alt="封面"
>
<span v-else>上传封面</span>
</div>
</NFormItem>
</div>
<!-- 星球名称 -->
<NFormItem label="星球名称" path="communityName">
<NInput v-model:value="formValue.communityName" placeholder="请输入星球名称" />
</NFormItem>
<!-- 星球标签 -->
<NFormItem label="星球标签" path="communityTag">
<NSelect
v-model:value="formValue.communityTag"
:options="tagList.map(item => ({ label: item.dictLabel, value: item.dictValue }))"
placeholder="请选择星球标签"
/>
</NFormItem>
<!-- 描述 -->
<!-- <NFormItem label="描述" path="description">
<NTextarea
v-model:value="formValue.description"
placeholder="请输入星球描述"
:autosize="{
minRows: 3,
maxRows: 5,
}"
/>
</NFormItem> -->
<NFormItem label="描述" path="description">
<NInput
v-model:value="formValue.description"
placeholder="请输入星球描述"
type="textarea"
:autosize="{
minRows: 3,
maxRows: 5,
}"
/>
</NFormItem>
<!-- 星球类型 -->
<NFormItem label="星球类型" path="type">
<NRadioGroup v-model:value="formValue.type" name="type">
<NSpace>
<NRadio value="1">
付费星球
</NRadio>
<NRadio value="0">
免费星球
</NRadio>
</NSpace>
</NRadioGroup>
</NFormItem>
<!-- 设置加入费用 -->
<NFormItem v-if="formValue.type === '1'" label="设置加入费用" path="price">
<NInputNumber
v-model:value="formValue.price"
:min="0"
:max="99999"
:step="1"
placeholder="请输入加入费用"
>
<template #suffix>
积分
</template>
</NInputNumber>
</NFormItem>
<!-- 设置成员加入有效期 -->
<NFormItem label="设置成员加入有效期" path="validityDay">
<NSelect
v-model:value="formValue.validityDay"
:options="validTimeOptions"
placeholder="请选择有效期"
/>
</NFormItem>
</NForm>
<template #action>
<NSpace>
<NButton @click="handleClose">
取消
</NButton>
<NButton type="primary" :loading="loading" @click="handleSubmit">
</NButton>
</NSpace>
</template>
</NModal>
<input
ref="pictureInput"
type="file"
accept="image/*"
class="hidden"
@change="handlePictureChange"
>
</template>