|
|
@@ -3,14 +3,40 @@
|
|
|
<el-button text @click="router.back()">← 返回</el-button>
|
|
|
<h1>编辑宠物</h1>
|
|
|
<el-form ref="formRef" :model="form" :rules="rules" label-width="100px" class="form">
|
|
|
+ <el-form-item label="头像">
|
|
|
+ <div class="avatar-uploader">
|
|
|
+ <el-avatar v-if="avatarUrl" :size="80" :src="avatarUrl" />
|
|
|
+ <el-avatar v-else :size="80">+</el-avatar>
|
|
|
+ <el-upload
|
|
|
+ :show-file-list="false"
|
|
|
+ :on-change="handleAvatarChange"
|
|
|
+ :auto-upload="false"
|
|
|
+ accept="image/jpeg,image/png,image/gif,image/webp"
|
|
|
+ >
|
|
|
+ <template #trigger>
|
|
|
+ <el-button size="small" :loading="uploading">选择图片</el-button>
|
|
|
+ </template>
|
|
|
+ </el-upload>
|
|
|
+ </div>
|
|
|
+ </el-form-item>
|
|
|
<el-form-item label="宠物名" prop="name">
|
|
|
<el-input v-model="form.name" />
|
|
|
</el-form-item>
|
|
|
+ <el-form-item label="物种" prop="species">
|
|
|
+ <el-select v-model="form.species" placeholder="请选择物种" style="width: 100%">
|
|
|
+ <el-option label="狗" value="DOG" />
|
|
|
+ <el-option label="猫" value="CAT" />
|
|
|
+ <el-option label="兔子" value="RABBIT" />
|
|
|
+ <el-option label="鸟" value="BIRD" />
|
|
|
+ <el-option label="鱼" value="FISH" />
|
|
|
+ <el-option label="其他" value="OTHER" />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
<el-form-item label="品种" prop="breed">
|
|
|
- <el-input v-model="form.breed" />
|
|
|
+ <el-input v-model="form.breed" placeholder="如:金毛、布偶猫" />
|
|
|
</el-form-item>
|
|
|
- <el-form-item label="年龄" prop="age">
|
|
|
- <el-input-number v-model="form.age" :min="0" />
|
|
|
+ <el-form-item label="出生日期" prop="birthDate">
|
|
|
+ <el-date-picker v-model="form.birthDate" type="date" placeholder="选择出生日期" value-format="YYYY-MM-DD" style="width: 100%" />
|
|
|
</el-form-item>
|
|
|
<el-form-item label="体重(kg)" prop="weight">
|
|
|
<el-input-number v-model="form.weight" :min="0" :precision="1" :step="0.5" />
|
|
|
@@ -22,7 +48,7 @@
|
|
|
</el-radio-group>
|
|
|
</el-form-item>
|
|
|
<el-form-item label="备注">
|
|
|
- <el-input v-model="form.notes" type="textarea" />
|
|
|
+ <el-input v-model="form.remark" type="textarea" />
|
|
|
</el-form-item>
|
|
|
<el-form-item>
|
|
|
<el-button type="primary" @click="handleSubmit">保存</el-button>
|
|
|
@@ -36,30 +62,53 @@
|
|
|
import { reactive, ref, onMounted } from 'vue'
|
|
|
import { useRouter, useRoute } from 'vue-router'
|
|
|
import { ElMessage } from 'element-plus'
|
|
|
-import type { FormInstance, FormRules } from 'element-plus'
|
|
|
+import type { FormInstance, FormRules, UploadFile } from 'element-plus'
|
|
|
import { getPetController } from '@/api/pet-controller'
|
|
|
+import { getImageController } from '@/api/image-controller'
|
|
|
import type { PetDto } from '@/api/models'
|
|
|
|
|
|
const router = useRouter()
|
|
|
const route = useRoute()
|
|
|
|
|
|
const formRef = ref<FormInstance>()
|
|
|
+const avatarUrl = ref('')
|
|
|
+const uploading = ref(false)
|
|
|
|
|
|
const form = reactive({
|
|
|
name: '',
|
|
|
+ species: '',
|
|
|
breed: '',
|
|
|
- age: 0,
|
|
|
+ birthDate: '',
|
|
|
weight: 0,
|
|
|
gender: 'MALE' as 'MALE' | 'FEMALE',
|
|
|
- notes: ''
|
|
|
+ remark: ''
|
|
|
})
|
|
|
|
|
|
const rules: FormRules = {
|
|
|
name: [{ required: true, message: '请输入宠物名', trigger: 'blur' }],
|
|
|
- breed: [{ required: true, message: '请输入品种', trigger: 'blur' }],
|
|
|
+ species: [{ required: true, message: '请选择物种', trigger: 'change' }],
|
|
|
weight: [{ type: 'number', min: 0, message: '体重必须大于 0', trigger: 'blur' }]
|
|
|
}
|
|
|
|
|
|
+const handleAvatarChange = async (uploadFile: UploadFile) => {
|
|
|
+ const file = uploadFile.raw
|
|
|
+ if (!file) return
|
|
|
+ uploading.value = true
|
|
|
+ try {
|
|
|
+ const api = getImageController()
|
|
|
+ const res = await api.upload({ imageFile: file as Blob })
|
|
|
+ if (res.code === 200 && res.data) {
|
|
|
+ avatarUrl.value = res.data
|
|
|
+ } else {
|
|
|
+ ElMessage.error(res.message || '头像上传失败')
|
|
|
+ }
|
|
|
+ } catch (err: any) {
|
|
|
+ ElMessage.error(err.message || '头像上传失败')
|
|
|
+ } finally {
|
|
|
+ uploading.value = false
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
const fetchPet = async () => {
|
|
|
try {
|
|
|
const api = getPetController()
|
|
|
@@ -67,10 +116,13 @@ const fetchPet = async () => {
|
|
|
if (res.code === 200 && res.data) {
|
|
|
const p = res.data
|
|
|
form.name = p.name ?? ''
|
|
|
+ form.species = p.species ?? ''
|
|
|
form.breed = p.breed ?? ''
|
|
|
+ form.birthDate = p.birthDate ?? ''
|
|
|
form.weight = p.weight ?? 0
|
|
|
form.gender = (p.gender as 'MALE' | 'FEMALE') ?? 'MALE'
|
|
|
- form.notes = p.remark ?? ''
|
|
|
+ form.remark = p.remark ?? ''
|
|
|
+ avatarUrl.value = p.avatar ?? ''
|
|
|
}
|
|
|
} catch (err: any) {
|
|
|
ElMessage.error(err.message || '加载失败')
|
|
|
@@ -84,11 +136,13 @@ const handleSubmit = async () => {
|
|
|
const api = getPetController()
|
|
|
const dto: PetDto = {
|
|
|
name: form.name,
|
|
|
- species: form.breed,
|
|
|
- breed: form.breed,
|
|
|
+ species: form.species,
|
|
|
+ breed: form.breed || undefined,
|
|
|
+ birthDate: form.birthDate || undefined,
|
|
|
gender: form.gender,
|
|
|
- weight: form.weight,
|
|
|
- remark: form.notes
|
|
|
+ weight: form.weight > 0 ? form.weight : undefined,
|
|
|
+ remark: form.remark || undefined,
|
|
|
+ avatar: avatarUrl.value || undefined
|
|
|
}
|
|
|
const res = await api.update(Number(route.params.id), dto)
|
|
|
if (res.code === 200) {
|
|
|
@@ -115,4 +169,10 @@ onMounted(fetchPet)
|
|
|
.form {
|
|
|
margin-top: 20px;
|
|
|
}
|
|
|
+
|
|
|
+.avatar-uploader {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 12px;
|
|
|
+}
|
|
|
</style>
|