完善宠物管理功能
✨ 新增功能: - 宠物详情页面:展示完整的宠物信息和最近记录 - 添加宠物页面:支持头像上传、基本信息录入、表单验证 - 添加记录页面:支持多种记录类型、照片上传、日期选择 - 本地存储集成:宠物数据和记录数据持久化存储 🎨 界面优化: - 使用uView组件构建现代化表单界面 - 支持图片选择和预览功能 - 响应式网格布局展示信息 - 完善的空状态和加载状态 📱 用户体验: - 表单验证和错误提示 - 图片上传和预览 - 日期选择器集成 - 数据持久化存储 🔧 技术改进: - 页面路由配置完善 - 自定义导航栏样式 - 组件化开发模式
This commit is contained in:
@@ -0,0 +1,244 @@
|
||||
<template>
|
||||
<view class="add-record-container">
|
||||
<u-navbar title="添加记录" left-icon="arrow-left" @left-click="goBack"></u-navbar>
|
||||
|
||||
<u-form :model="recordForm" ref="recordFormRef" :rules="rules" label-width="120">
|
||||
<u-card :padding="20" margin="20">
|
||||
<u-form-item label="记录类型" prop="type" required>
|
||||
<u-radio-group v-model="recordForm.type" placement="row">
|
||||
<u-radio label="日常" name="daily"></u-radio>
|
||||
<u-radio label="喂食" name="feeding"></u-radio>
|
||||
<u-radio label="健康" name="health"></u-radio>
|
||||
<u-radio label="其他" name="other"></u-radio>
|
||||
</u-radio-group>
|
||||
</u-form-item>
|
||||
|
||||
<u-form-item label="记录日期" prop="date" required>
|
||||
<u-input v-model="recordForm.date" placeholder="请选择日期" readonly @click="showDatePicker = true"></u-input>
|
||||
</u-form-item>
|
||||
|
||||
<u-form-item label="记录内容" prop="content" required>
|
||||
<u-textarea v-model="recordForm.content" placeholder="记录宠物的状态、行为或其他信息..." maxlength="500" :count="true"></u-textarea>
|
||||
</u-form-item>
|
||||
|
||||
<u-form-item label="添加照片" prop="photos">
|
||||
<view class="photo-section">
|
||||
<view class="photo-list">
|
||||
<view class="photo-item" v-for="(photo, index) in recordForm.photos" :key="index">
|
||||
<image :src="photo" mode="aspectFill" @click="previewImage(photo)"></image>
|
||||
<u-icon name="close-circle-fill" color="#ff4757" size="16" @click="removePhoto(index)"></u-icon>
|
||||
</view>
|
||||
<view class="add-photo-btn" @click="choosePhotos" v-if="recordForm.photos.length < 9">
|
||||
<u-icon name="camera" size="24" color="#999"></u-icon>
|
||||
<text class="add-text">添加照片</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</u-form-item>
|
||||
</u-card>
|
||||
</u-form>
|
||||
|
||||
<view class="submit-section">
|
||||
<u-button type="primary" text="保存记录" @click="submitForm" :loading="loading"></u-button>
|
||||
</view>
|
||||
|
||||
<!-- 日期选择器 -->
|
||||
<u-datetime-picker
|
||||
:show="showDatePicker"
|
||||
v-model="selectedDate"
|
||||
mode="date"
|
||||
@confirm="confirmDate"
|
||||
@cancel="showDatePicker = false">
|
||||
</u-datetime-picker>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
petId: '',
|
||||
loading: false,
|
||||
showDatePicker: false,
|
||||
selectedDate: new Date().getTime(),
|
||||
recordForm: {
|
||||
type: 'daily',
|
||||
date: this.formatDate(new Date()),
|
||||
content: '',
|
||||
photos: []
|
||||
},
|
||||
rules: {
|
||||
type: [
|
||||
{
|
||||
required: true,
|
||||
message: '请选择记录类型',
|
||||
trigger: 'change'
|
||||
}
|
||||
],
|
||||
date: [
|
||||
{
|
||||
required: true,
|
||||
message: '请选择记录日期',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
content: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入记录内容',
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
onLoad(options) {
|
||||
this.petId = options.petId
|
||||
},
|
||||
methods: {
|
||||
formatDate(date) {
|
||||
return `${date.getFullYear()}-${(date.getMonth() + 1).toString().padStart(2, '0')}-${date.getDate().toString().padStart(2, '0')}`
|
||||
},
|
||||
|
||||
goBack() {
|
||||
uni.navigateBack()
|
||||
},
|
||||
|
||||
confirmDate(e) {
|
||||
const date = new Date(e.value)
|
||||
this.recordForm.date = this.formatDate(date)
|
||||
this.showDatePicker = false
|
||||
},
|
||||
|
||||
choosePhotos() {
|
||||
const remainingCount = 9 - this.recordForm.photos.length
|
||||
uni.chooseImage({
|
||||
count: remainingCount,
|
||||
sizeType: ['compressed'],
|
||||
sourceType: ['album', 'camera'],
|
||||
success: (res) => {
|
||||
this.recordForm.photos.push(...res.tempFilePaths)
|
||||
},
|
||||
fail: (err) => {
|
||||
console.error('选择图片失败', err)
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
removePhoto(index) {
|
||||
this.recordForm.photos.splice(index, 1)
|
||||
},
|
||||
|
||||
previewImage(src) {
|
||||
uni.previewImage({
|
||||
urls: this.recordForm.photos,
|
||||
current: src
|
||||
})
|
||||
},
|
||||
|
||||
submitForm() {
|
||||
this.$refs.recordFormRef.validate().then(valid => {
|
||||
if (valid) {
|
||||
this.saveRecord()
|
||||
}
|
||||
}).catch(errors => {
|
||||
console.log('表单验证失败', errors)
|
||||
})
|
||||
},
|
||||
|
||||
saveRecord() {
|
||||
this.loading = true
|
||||
|
||||
const recordData = {
|
||||
...this.recordForm,
|
||||
id: Date.now(),
|
||||
petId: this.petId,
|
||||
createTime: new Date().toISOString()
|
||||
}
|
||||
|
||||
// 模拟保存到本地存储
|
||||
setTimeout(() => {
|
||||
try {
|
||||
let records = uni.getStorageSync('petRecords') || []
|
||||
records.unshift(recordData) // 最新记录在前
|
||||
uni.setStorageSync('petRecords', records)
|
||||
|
||||
this.loading = false
|
||||
uni.showToast({
|
||||
title: '保存成功',
|
||||
icon: 'success'
|
||||
})
|
||||
|
||||
setTimeout(() => {
|
||||
uni.navigateBack()
|
||||
}, 1500)
|
||||
} catch (error) {
|
||||
this.loading = false
|
||||
uni.showToast({
|
||||
title: '保存失败',
|
||||
icon: 'error'
|
||||
})
|
||||
}
|
||||
}, 1000)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.add-record-container {
|
||||
background-color: #f8f9fa;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.photo-section {
|
||||
.photo-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 20rpx;
|
||||
|
||||
.photo-item {
|
||||
position: relative;
|
||||
width: 150rpx;
|
||||
height: 150rpx;
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 10rpx;
|
||||
}
|
||||
|
||||
/deep/ .u-icon {
|
||||
position: absolute;
|
||||
top: -8rpx;
|
||||
right: -8rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.add-photo-btn {
|
||||
width: 150rpx;
|
||||
height: 150rpx;
|
||||
border: 2rpx dashed #ddd;
|
||||
border-radius: 10rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 10rpx;
|
||||
|
||||
.add-text {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.submit-section {
|
||||
padding: 40rpx 30rpx;
|
||||
}
|
||||
|
||||
/deep/ .u-form-item {
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user