1083 lines
24 KiB
Vue
1083 lines
24 KiB
Vue
<template>
|
||
<view class="publish-container page-container-with-bg">
|
||
<!-- 表单内容 -->
|
||
<view class="form-container">
|
||
<!-- 宠物照片上传 -->
|
||
<view class="photo-section">
|
||
<view class="section-header">
|
||
<text class="section-title">宠物照片</text>
|
||
<text class="section-desc">最多上传6张照片,第一张为封面</text>
|
||
</view>
|
||
<view class="photo-grid">
|
||
<view
|
||
class="photo-item"
|
||
v-for="(photo, index) in formData.photos"
|
||
:key="index"
|
||
@click="previewPhoto(index)"
|
||
>
|
||
<image class="photo-image" :src="photo" mode="aspectFill" />
|
||
<view class="photo-delete" @click.stop="deletePhoto(index)">
|
||
<text class="delete-icon">×</text>
|
||
</view>
|
||
<view class="photo-cover" v-if="index === 0">
|
||
<text class="cover-text">封面</text>
|
||
</view>
|
||
</view>
|
||
<view
|
||
class="photo-add"
|
||
v-if="formData.photos.length < 6"
|
||
@click="addPhoto"
|
||
>
|
||
<text class="add-icon">+</text>
|
||
<text class="add-text">添加照片</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 基本信息 -->
|
||
<view class="info-section">
|
||
<view class="section-header">
|
||
<text class="section-title">基本信息</text>
|
||
</view>
|
||
<view class="form-group">
|
||
<text class="form-label">宠物名称 *</text>
|
||
<u-input
|
||
v-model="formData.name"
|
||
placeholder="请输入宠物名称"
|
||
border="none"
|
||
:custom-style="inputStyle"
|
||
></u-input>
|
||
</view>
|
||
<view class="form-group">
|
||
<text class="form-label">品种 *</text>
|
||
<view class="picker-field" @click="showBreedPicker">
|
||
<text class="picker-text" :class="{ placeholder: !formData.breed }">
|
||
{{ formData.breed || '请选择品种' }}
|
||
</text>
|
||
<text class="picker-arrow">→</text>
|
||
</view>
|
||
</view>
|
||
<view class="form-group">
|
||
<text class="form-label">性别 *</text>
|
||
<view class="radio-group">
|
||
<view
|
||
class="radio-item"
|
||
:class="{ active: formData.gender === '公' }"
|
||
@click="setGender('公')"
|
||
>
|
||
<text class="radio-text">公</text>
|
||
</view>
|
||
<view
|
||
class="radio-item"
|
||
:class="{ active: formData.gender === '母' }"
|
||
@click="setGender('母')"
|
||
>
|
||
<text class="radio-text">母</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="form-group">
|
||
<text class="form-label">年龄 *</text>
|
||
<view class="picker-field" @click="showAgePicker">
|
||
<text class="picker-text" :class="{ placeholder: !formData.age }">
|
||
{{ formData.age || '请选择年龄' }}
|
||
</text>
|
||
<text class="picker-arrow">→</text>
|
||
</view>
|
||
</view>
|
||
<view class="form-group">
|
||
<text class="form-label">体重</text>
|
||
<u-input
|
||
v-model="formData.weight"
|
||
placeholder="请输入体重(如:3.5kg)"
|
||
border="none"
|
||
:custom-style="inputStyle"
|
||
></u-input>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 健康状况 -->
|
||
<view class="health-section">
|
||
<view class="section-header">
|
||
<text class="section-title">健康状况</text>
|
||
</view>
|
||
<view class="checkbox-group">
|
||
<view
|
||
class="checkbox-item"
|
||
:class="{ active: formData.vaccinated }"
|
||
@click="toggleVaccinated"
|
||
>
|
||
<view class="checkbox">
|
||
<text class="check-icon" v-if="formData.vaccinated">✓</text>
|
||
</view>
|
||
<text class="checkbox-text">已接种疫苗</text>
|
||
</view>
|
||
<view
|
||
class="checkbox-item"
|
||
:class="{ active: formData.sterilized }"
|
||
@click="toggleSterilized"
|
||
>
|
||
<view class="checkbox">
|
||
<text class="check-icon" v-if="formData.sterilized">✓</text>
|
||
</view>
|
||
<text class="checkbox-text">已绝育</text>
|
||
</view>
|
||
<view
|
||
class="checkbox-item"
|
||
:class="{ active: formData.dewormed }"
|
||
@click="toggleDewormed"
|
||
>
|
||
<view class="checkbox">
|
||
<text class="check-icon" v-if="formData.dewormed">✓</text>
|
||
</view>
|
||
<text class="checkbox-text">已驱虫</text>
|
||
</view>
|
||
</view>
|
||
<view class="form-group">
|
||
<text class="form-label">健康说明</text>
|
||
<u-textarea
|
||
v-model="formData.healthNote"
|
||
placeholder="请描述宠物的健康状况、疾病史等"
|
||
:maxlength="200"
|
||
count
|
||
:custom-style="textareaStyle"
|
||
></u-textarea>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 性格特点 -->
|
||
<view class="personality-section">
|
||
<view class="section-header">
|
||
<text class="section-title">性格特点</text>
|
||
</view>
|
||
<view class="tag-group">
|
||
<view
|
||
class="tag-item"
|
||
v-for="tag in personalityTags"
|
||
:key="tag"
|
||
:class="{ active: formData.personality.includes(tag) }"
|
||
@click="togglePersonality(tag)"
|
||
>
|
||
<text class="tag-text">{{ tag }}</text>
|
||
</view>
|
||
</view>
|
||
<view class="form-group">
|
||
<text class="form-label">性格描述</text>
|
||
<u-textarea
|
||
v-model="formData.personalityNote"
|
||
placeholder="详细描述宠物的性格特点、生活习惯等"
|
||
:maxlength="300"
|
||
count
|
||
:custom-style="textareaStyle"
|
||
></u-textarea>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 领养要求 -->
|
||
<view class="requirements-section">
|
||
<view class="section-header">
|
||
<text class="section-title">领养要求</text>
|
||
</view>
|
||
<view class="form-group">
|
||
<text class="form-label">领养条件</text>
|
||
<u-textarea
|
||
v-model="formData.requirements"
|
||
placeholder="请描述对领养人的要求,如:有养宠经验、有固定住所、经济稳定等"
|
||
:maxlength="300"
|
||
count
|
||
:custom-style="textareaStyle"
|
||
></u-textarea>
|
||
</view>
|
||
<view class="checkbox-group">
|
||
<view
|
||
class="checkbox-item"
|
||
:class="{ active: formData.needVisit }"
|
||
@click="toggleNeedVisit"
|
||
>
|
||
<view class="checkbox">
|
||
<text class="check-icon" v-if="formData.needVisit">✓</text>
|
||
</view>
|
||
<text class="checkbox-text">需要上门家访</text>
|
||
</view>
|
||
<view
|
||
class="checkbox-item"
|
||
:class="{ active: formData.needContract }"
|
||
@click="toggleNeedContract"
|
||
>
|
||
<view class="checkbox">
|
||
<text class="check-icon" v-if="formData.needContract">✓</text>
|
||
</view>
|
||
<text class="checkbox-text">需要签署领养协议</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 联系方式 -->
|
||
<view class="contact-section">
|
||
<view class="section-header">
|
||
<text class="section-title">联系方式</text>
|
||
</view>
|
||
<view class="form-group">
|
||
<text class="form-label">联系人 *</text>
|
||
<u-input
|
||
v-model="formData.contactName"
|
||
placeholder="请输入联系人姓名"
|
||
border="none"
|
||
:custom-style="inputStyle"
|
||
></u-input>
|
||
</view>
|
||
<view class="form-group">
|
||
<text class="form-label">联系电话 *</text>
|
||
<u-input
|
||
v-model="formData.contactPhone"
|
||
placeholder="请输入联系电话"
|
||
border="none"
|
||
:custom-style="inputStyle"
|
||
></u-input>
|
||
</view>
|
||
<view class="form-group">
|
||
<text class="form-label">微信号</text>
|
||
<u-input
|
||
v-model="formData.contactWechat"
|
||
placeholder="请输入微信号(可选)"
|
||
border="none"
|
||
:custom-style="inputStyle"
|
||
></u-input>
|
||
</view>
|
||
<view class="form-group">
|
||
<text class="form-label">所在地区 *</text>
|
||
<view class="picker-field" @click="showLocationPicker">
|
||
<text class="picker-text" :class="{ placeholder: !formData.location }">
|
||
{{ formData.location || '请选择所在地区' }}
|
||
</text>
|
||
<text class="picker-arrow">→</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 其他说明 -->
|
||
<view class="note-section">
|
||
<view class="section-header">
|
||
<text class="section-title">其他说明</text>
|
||
</view>
|
||
<view class="form-group">
|
||
<u-textarea
|
||
v-model="formData.note"
|
||
placeholder="其他需要说明的情况(可选)"
|
||
:maxlength="500"
|
||
count
|
||
:custom-style="textareaStyle"
|
||
></u-textarea>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 提交按钮 -->
|
||
<view class="submit-section">
|
||
<u-button
|
||
type="primary"
|
||
:custom-style="buttonStyle"
|
||
@click="submitForm"
|
||
:loading="submitting"
|
||
>
|
||
{{ submitting ? '发布中...' : (isEdit ? '保存修改' : '发布领养信息') }}
|
||
</u-button>
|
||
</view>
|
||
|
||
<!-- 选择器 -->
|
||
<u-picker
|
||
:show="showBreed"
|
||
:columns="breedColumns"
|
||
@confirm="onBreedConfirm"
|
||
@cancel="showBreed = false"
|
||
></u-picker>
|
||
|
||
<u-picker
|
||
:show="showAge"
|
||
:columns="ageColumns"
|
||
@confirm="onAgeConfirm"
|
||
@cancel="showAge = false"
|
||
></u-picker>
|
||
|
||
<u-picker
|
||
:show="showLocation"
|
||
:columns="locationColumns"
|
||
@confirm="onLocationConfirm"
|
||
@cancel="showLocation = false"
|
||
></u-picker>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
import { reactive, ref, onMounted } from 'vue'
|
||
|
||
export default {
|
||
name: 'PublishPage',
|
||
setup() {
|
||
// 响应式数据
|
||
const formData = reactive({
|
||
photos: [],
|
||
name: '',
|
||
breed: '',
|
||
gender: '',
|
||
age: '',
|
||
weight: '',
|
||
vaccinated: false,
|
||
sterilized: false,
|
||
dewormed: false,
|
||
healthNote: '',
|
||
personality: [],
|
||
personalityNote: '',
|
||
requirements: '',
|
||
needVisit: false,
|
||
needContract: false,
|
||
contactName: '',
|
||
contactPhone: '',
|
||
contactWechat: '',
|
||
location: '',
|
||
note: ''
|
||
})
|
||
|
||
const submitting = ref(false)
|
||
const isEdit = ref(false)
|
||
const editId = ref('')
|
||
|
||
// 选择器状态
|
||
const showBreed = ref(false)
|
||
const showAge = ref(false)
|
||
const showLocation = ref(false)
|
||
|
||
// 选择器数据
|
||
const breedColumns = ref([
|
||
['橘猫', '英短', '美短', '布偶', '暹罗', '波斯', '缅因', '折耳', '田园猫', '其他猫咪', '金毛', '拉布拉多', '哈士奇', '萨摩耶', '柯基', '泰迪', '比熊', '博美', '田园犬', '其他犬类']
|
||
])
|
||
|
||
const ageColumns = ref([
|
||
['2个月', '3个月', '4个月', '5个月', '6个月', '7个月', '8个月', '9个月', '10个月', '11个月', '1岁', '2岁', '3岁', '4岁', '5岁', '6岁', '7岁', '8岁', '9岁', '10岁以上']
|
||
])
|
||
|
||
const locationColumns = ref([
|
||
['北京市', '上海市', '广州市', '深圳市', '杭州市', '成都市', '武汉市', '西安市', '南京市', '重庆市', '天津市', '苏州市', '长沙市', '郑州市', '青岛市', '大连市', '宁波市', '厦门市']
|
||
])
|
||
|
||
const personalityTags = ref([
|
||
'温顺', '活泼', '安静', '粘人', '独立', '聪明', '胆小', '勇敢', '爱玩', '懒散', '好奇', '友善'
|
||
])
|
||
|
||
// 样式配置
|
||
const inputStyle = {
|
||
fontSize: '28rpx',
|
||
color: '#333333',
|
||
backgroundColor: 'rgba(255, 138, 128, 0.05)',
|
||
borderRadius: '12rpx',
|
||
padding: '20rpx'
|
||
}
|
||
|
||
const textareaStyle = {
|
||
fontSize: '26rpx',
|
||
color: '#333333',
|
||
backgroundColor: 'rgba(255, 138, 128, 0.05)',
|
||
borderRadius: '12rpx',
|
||
padding: '20rpx'
|
||
}
|
||
|
||
const buttonStyle = {
|
||
background: 'linear-gradient(135deg, #FF8A80, #FFB6C1)',
|
||
borderRadius: '24rpx',
|
||
height: '88rpx',
|
||
fontSize: '32rpx'
|
||
}
|
||
|
||
// 生命周期
|
||
onMounted(() => {
|
||
checkEditMode()
|
||
loadUserInfo()
|
||
})
|
||
|
||
// 方法定义
|
||
const checkEditMode = () => {
|
||
// 检查是否为编辑模式
|
||
const pages = getCurrentPages()
|
||
const currentPage = pages[pages.length - 1]
|
||
const options = currentPage.options
|
||
|
||
if (options.id && options.mode === 'edit') {
|
||
isEdit.value = true
|
||
editId.value = options.id
|
||
loadEditData(options.id)
|
||
}
|
||
}
|
||
|
||
const loadEditData = (id) => {
|
||
try {
|
||
const publishedList = uni.getStorageSync('myPublishedAdoptions') || []
|
||
const item = publishedList.find(p => p.id === id)
|
||
|
||
if (item) {
|
||
Object.assign(formData, {
|
||
photos: item.photos || [],
|
||
name: item.name || '',
|
||
breed: item.breed || '',
|
||
gender: item.gender || '',
|
||
age: item.age || '',
|
||
weight: item.weight || '',
|
||
vaccinated: item.vaccinated || false,
|
||
sterilized: item.sterilized || false,
|
||
dewormed: item.dewormed || false,
|
||
healthNote: item.healthNote || '',
|
||
personality: item.personality || [],
|
||
personalityNote: item.personalityNote || '',
|
||
requirements: item.requirements || '',
|
||
needVisit: item.needVisit || false,
|
||
needContract: item.needContract || false,
|
||
contactName: item.contactName || '',
|
||
contactPhone: item.contactPhone || '',
|
||
contactWechat: item.contactWechat || '',
|
||
location: item.location || '',
|
||
note: item.note || ''
|
||
})
|
||
}
|
||
} catch (error) {
|
||
console.error('加载编辑数据失败:', error)
|
||
}
|
||
}
|
||
|
||
const loadUserInfo = () => {
|
||
try {
|
||
const userInfo = uni.getStorageSync('userInfo') || {}
|
||
if (!formData.contactName && userInfo.nickName) {
|
||
formData.contactName = userInfo.nickName
|
||
}
|
||
} catch (error) {
|
||
console.error('加载用户信息失败:', error)
|
||
}
|
||
}
|
||
|
||
const addPhoto = () => {
|
||
uni.chooseImage({
|
||
count: 6 - formData.photos.length,
|
||
sizeType: ['compressed'],
|
||
sourceType: ['album', 'camera'],
|
||
success: (res) => {
|
||
formData.photos.push(...res.tempFilePaths)
|
||
},
|
||
fail: (err) => {
|
||
console.error('选择照片失败:', err)
|
||
uni.showToast({
|
||
title: '选择照片失败',
|
||
icon: 'none'
|
||
})
|
||
}
|
||
})
|
||
}
|
||
|
||
const deletePhoto = (index) => {
|
||
formData.photos.splice(index, 1)
|
||
}
|
||
|
||
const previewPhoto = (index) => {
|
||
uni.previewImage({
|
||
urls: formData.photos,
|
||
current: index
|
||
})
|
||
}
|
||
|
||
const setGender = (gender) => {
|
||
formData.gender = gender
|
||
}
|
||
|
||
const toggleVaccinated = () => {
|
||
formData.vaccinated = !formData.vaccinated
|
||
}
|
||
|
||
const toggleSterilized = () => {
|
||
formData.sterilized = !formData.sterilized
|
||
}
|
||
|
||
const toggleDewormed = () => {
|
||
formData.dewormed = !formData.dewormed
|
||
}
|
||
|
||
const togglePersonality = (tag) => {
|
||
const index = formData.personality.indexOf(tag)
|
||
if (index > -1) {
|
||
formData.personality.splice(index, 1)
|
||
} else {
|
||
formData.personality.push(tag)
|
||
}
|
||
}
|
||
|
||
const toggleNeedVisit = () => {
|
||
formData.needVisit = !formData.needVisit
|
||
}
|
||
|
||
const toggleNeedContract = () => {
|
||
formData.needContract = !formData.needContract
|
||
}
|
||
|
||
const showBreedPicker = () => {
|
||
showBreed.value = true
|
||
}
|
||
|
||
const showAgePicker = () => {
|
||
showAge.value = true
|
||
}
|
||
|
||
const showLocationPicker = () => {
|
||
showLocation.value = true
|
||
}
|
||
|
||
const onBreedConfirm = (e) => {
|
||
formData.breed = e.value[0]
|
||
showBreed.value = false
|
||
}
|
||
|
||
const onAgeConfirm = (e) => {
|
||
formData.age = e.value[0]
|
||
showAge.value = false
|
||
}
|
||
|
||
const onLocationConfirm = (e) => {
|
||
formData.location = e.value[0]
|
||
showLocation.value = false
|
||
}
|
||
|
||
const validateForm = () => {
|
||
if (formData.photos.length === 0) {
|
||
uni.showToast({
|
||
title: '请至少上传一张照片',
|
||
icon: 'none'
|
||
})
|
||
return false
|
||
}
|
||
|
||
if (!formData.name.trim()) {
|
||
uni.showToast({
|
||
title: '请输入宠物名称',
|
||
icon: 'none'
|
||
})
|
||
return false
|
||
}
|
||
|
||
if (!formData.breed) {
|
||
uni.showToast({
|
||
title: '请选择宠物品种',
|
||
icon: 'none'
|
||
})
|
||
return false
|
||
}
|
||
|
||
if (!formData.gender) {
|
||
uni.showToast({
|
||
title: '请选择宠物性别',
|
||
icon: 'none'
|
||
})
|
||
return false
|
||
}
|
||
|
||
if (!formData.age) {
|
||
uni.showToast({
|
||
title: '请选择宠物年龄',
|
||
icon: 'none'
|
||
})
|
||
return false
|
||
}
|
||
|
||
if (!formData.contactName.trim()) {
|
||
uni.showToast({
|
||
title: '请输入联系人姓名',
|
||
icon: 'none'
|
||
})
|
||
return false
|
||
}
|
||
|
||
if (!formData.contactPhone.trim()) {
|
||
uni.showToast({
|
||
title: '请输入联系电话',
|
||
icon: 'none'
|
||
})
|
||
return false
|
||
}
|
||
|
||
if (!formData.location) {
|
||
uni.showToast({
|
||
title: '请选择所在地区',
|
||
icon: 'none'
|
||
})
|
||
return false
|
||
}
|
||
|
||
return true
|
||
}
|
||
|
||
const submitForm = async () => {
|
||
if (!validateForm()) {
|
||
return
|
||
}
|
||
|
||
submitting.value = true
|
||
|
||
try {
|
||
// 模拟网络请求延迟
|
||
await new Promise(resolve => setTimeout(resolve, 2000))
|
||
|
||
const publishData = {
|
||
...formData,
|
||
id: isEdit.value ? editId.value : 'pub_' + Date.now(),
|
||
status: 'active',
|
||
publishTime: isEdit.value ? undefined : new Date().toISOString(),
|
||
updateTime: new Date().toISOString(),
|
||
applicationCount: 0,
|
||
viewCount: 0
|
||
}
|
||
|
||
// 保存到本地存储
|
||
let publishedList = uni.getStorageSync('myPublishedAdoptions') || []
|
||
|
||
if (isEdit.value) {
|
||
const index = publishedList.findIndex(p => p.id === editId.value)
|
||
if (index > -1) {
|
||
publishedList[index] = { ...publishedList[index], ...publishData }
|
||
}
|
||
} else {
|
||
publishedList.unshift(publishData)
|
||
}
|
||
|
||
uni.setStorageSync('myPublishedAdoptions', publishedList)
|
||
|
||
uni.showToast({
|
||
title: isEdit.value ? '修改成功' : '发布成功',
|
||
icon: 'success'
|
||
})
|
||
|
||
// 返回上一页
|
||
setTimeout(() => {
|
||
uni.navigateBack()
|
||
}, 1500)
|
||
|
||
} catch (error) {
|
||
console.error('提交失败:', error)
|
||
uni.showToast({
|
||
title: '提交失败',
|
||
icon: 'none'
|
||
})
|
||
} finally {
|
||
submitting.value = false
|
||
}
|
||
}
|
||
|
||
return {
|
||
formData,
|
||
submitting,
|
||
isEdit,
|
||
showBreed,
|
||
showAge,
|
||
showLocation,
|
||
breedColumns,
|
||
ageColumns,
|
||
locationColumns,
|
||
personalityTags,
|
||
inputStyle,
|
||
textareaStyle,
|
||
buttonStyle,
|
||
addPhoto,
|
||
deletePhoto,
|
||
previewPhoto,
|
||
setGender,
|
||
toggleVaccinated,
|
||
toggleSterilized,
|
||
toggleDewormed,
|
||
togglePersonality,
|
||
toggleNeedVisit,
|
||
toggleNeedContract,
|
||
showBreedPicker,
|
||
showAgePicker,
|
||
showLocationPicker,
|
||
onBreedConfirm,
|
||
onAgeConfirm,
|
||
onLocationConfirm,
|
||
submitForm
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.publish-container {
|
||
background: linear-gradient(135deg, #FF8A80 0%, #FFB6C1 25%, #FECFEF 50%, #F8BBD9 100%);
|
||
min-height: 100vh;
|
||
padding-bottom: 120rpx;
|
||
}
|
||
|
||
/* 表单容器 */
|
||
.form-container {
|
||
margin: 0 30rpx;
|
||
}
|
||
|
||
/* 通用区块样式 */
|
||
.photo-section,
|
||
.info-section,
|
||
.health-section,
|
||
.personality-section,
|
||
.requirements-section,
|
||
.contact-section,
|
||
.note-section {
|
||
background: rgba(255, 255, 255, 0.95);
|
||
backdrop-filter: blur(20rpx);
|
||
border-radius: 24rpx;
|
||
padding: 32rpx;
|
||
margin-bottom: 24rpx;
|
||
box-shadow: 0 8rpx 32rpx rgba(255, 138, 128, 0.2);
|
||
border: 1rpx solid rgba(255, 255, 255, 0.3);
|
||
|
||
.section-header {
|
||
margin-bottom: 24rpx;
|
||
|
||
.section-title {
|
||
font-size: 32rpx;
|
||
font-weight: 600;
|
||
color: #333333;
|
||
margin-bottom: 8rpx;
|
||
}
|
||
|
||
.section-desc {
|
||
font-size: 22rpx;
|
||
color: #666666;
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 照片上传区域 */
|
||
.photo-section {
|
||
.photo-grid {
|
||
display: grid;
|
||
grid-template-columns: 1fr 1fr 1fr;
|
||
gap: 16rpx;
|
||
|
||
.photo-item {
|
||
position: relative;
|
||
aspect-ratio: 1;
|
||
border-radius: 16rpx;
|
||
overflow: hidden;
|
||
|
||
.photo-image {
|
||
width: 100%;
|
||
height: 100%;
|
||
}
|
||
|
||
.photo-delete {
|
||
position: absolute;
|
||
top: 8rpx;
|
||
right: 8rpx;
|
||
width: 32rpx;
|
||
height: 32rpx;
|
||
background: rgba(0, 0, 0, 0.6);
|
||
border-radius: 50%;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
|
||
.delete-icon {
|
||
color: white;
|
||
font-size: 24rpx;
|
||
font-weight: bold;
|
||
}
|
||
}
|
||
|
||
.photo-cover {
|
||
position: absolute;
|
||
bottom: 0;
|
||
left: 0;
|
||
right: 0;
|
||
background: linear-gradient(135deg, #FF8A80, #FFB6C1);
|
||
padding: 6rpx 0;
|
||
text-align: center;
|
||
|
||
.cover-text {
|
||
color: white;
|
||
font-size: 20rpx;
|
||
font-weight: 500;
|
||
}
|
||
}
|
||
}
|
||
|
||
.photo-add {
|
||
aspect-ratio: 1;
|
||
border: 2rpx dashed #FF8A80;
|
||
border-radius: 16rpx;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: center;
|
||
background: rgba(255, 138, 128, 0.05);
|
||
transition: all 0.3s ease;
|
||
|
||
&:active {
|
||
background: rgba(255, 138, 128, 0.1);
|
||
transform: scale(0.98);
|
||
}
|
||
|
||
.add-icon {
|
||
font-size: 48rpx;
|
||
color: #FF8A80;
|
||
margin-bottom: 8rpx;
|
||
}
|
||
|
||
.add-text {
|
||
font-size: 22rpx;
|
||
color: #FF8A80;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 表单组件 */
|
||
.form-group {
|
||
margin-bottom: 32rpx;
|
||
|
||
&:last-child {
|
||
margin-bottom: 0;
|
||
}
|
||
|
||
.form-label {
|
||
display: block;
|
||
font-size: 28rpx;
|
||
font-weight: 500;
|
||
color: #333333;
|
||
margin-bottom: 16rpx;
|
||
}
|
||
}
|
||
|
||
/* 选择器字段 */
|
||
.picker-field {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
padding: 20rpx;
|
||
background: rgba(255, 138, 128, 0.05);
|
||
border-radius: 12rpx;
|
||
transition: all 0.3s ease;
|
||
|
||
&:active {
|
||
background: rgba(255, 138, 128, 0.1);
|
||
}
|
||
|
||
.picker-text {
|
||
font-size: 28rpx;
|
||
color: #333333;
|
||
|
||
&.placeholder {
|
||
color: #CCCCCC;
|
||
}
|
||
}
|
||
|
||
.picker-arrow {
|
||
font-size: 24rpx;
|
||
color: #FF8A80;
|
||
}
|
||
}
|
||
|
||
/* 单选组 */
|
||
.radio-group {
|
||
display: flex;
|
||
gap: 20rpx;
|
||
|
||
.radio-item {
|
||
flex: 1;
|
||
padding: 20rpx;
|
||
border: 2rpx solid rgba(255, 138, 128, 0.2);
|
||
border-radius: 12rpx;
|
||
text-align: center;
|
||
transition: all 0.3s ease;
|
||
|
||
&.active {
|
||
border-color: #FF8A80;
|
||
background: rgba(255, 138, 128, 0.1);
|
||
|
||
.radio-text {
|
||
color: #FF8A80;
|
||
font-weight: 600;
|
||
}
|
||
}
|
||
|
||
.radio-text {
|
||
font-size: 28rpx;
|
||
color: #666666;
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 复选框组 */
|
||
.checkbox-group {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 16rpx;
|
||
margin-bottom: 24rpx;
|
||
|
||
.checkbox-item {
|
||
display: flex;
|
||
align-items: center;
|
||
padding: 16rpx 20rpx;
|
||
border: 2rpx solid rgba(255, 138, 128, 0.2);
|
||
border-radius: 12rpx;
|
||
transition: all 0.3s ease;
|
||
|
||
&.active {
|
||
border-color: #FF8A80;
|
||
background: rgba(255, 138, 128, 0.1);
|
||
|
||
.checkbox-text {
|
||
color: #FF8A80;
|
||
}
|
||
}
|
||
|
||
.checkbox {
|
||
width: 32rpx;
|
||
height: 32rpx;
|
||
border: 2rpx solid #CCCCCC;
|
||
border-radius: 6rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
margin-right: 12rpx;
|
||
transition: all 0.3s ease;
|
||
}
|
||
|
||
&.active .checkbox {
|
||
border-color: #FF8A80;
|
||
background: #FF8A80;
|
||
|
||
.check-icon {
|
||
color: white;
|
||
font-size: 20rpx;
|
||
font-weight: bold;
|
||
}
|
||
}
|
||
|
||
.checkbox-text {
|
||
font-size: 26rpx;
|
||
color: #666666;
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 标签组 */
|
||
.tag-group {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 12rpx;
|
||
margin-bottom: 24rpx;
|
||
|
||
.tag-item {
|
||
padding: 12rpx 20rpx;
|
||
border: 2rpx solid rgba(255, 138, 128, 0.2);
|
||
border-radius: 20rpx;
|
||
transition: all 0.3s ease;
|
||
|
||
&.active {
|
||
border-color: #FF8A80;
|
||
background: linear-gradient(135deg, #FF8A80, #FFB6C1);
|
||
|
||
.tag-text {
|
||
color: white;
|
||
}
|
||
}
|
||
|
||
.tag-text {
|
||
font-size: 24rpx;
|
||
color: #666666;
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 提交按钮 */
|
||
.submit-section {
|
||
position: fixed;
|
||
bottom: 0;
|
||
left: 0;
|
||
right: 0;
|
||
background: rgba(255, 255, 255, 0.95);
|
||
backdrop-filter: blur(20rpx);
|
||
padding: 20rpx 30rpx;
|
||
border-top: 1rpx solid rgba(255, 255, 255, 0.3);
|
||
z-index: 100;
|
||
}
|
||
|
||
/* 响应式设计 */
|
||
@media (max-width: 375px) {
|
||
.publish-container {
|
||
.form-container {
|
||
margin: 0 20rpx;
|
||
}
|
||
|
||
.photo-section,
|
||
.info-section,
|
||
.health-section,
|
||
.personality-section,
|
||
.requirements-section,
|
||
.contact-section,
|
||
.note-section {
|
||
padding: 24rpx;
|
||
margin-bottom: 20rpx;
|
||
}
|
||
|
||
.photo-grid {
|
||
gap: 12rpx;
|
||
}
|
||
|
||
.submit-section {
|
||
padding: 16rpx 20rpx;
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 动画效果 */
|
||
@keyframes fadeIn {
|
||
from {
|
||
opacity: 0;
|
||
transform: translateY(20rpx);
|
||
}
|
||
to {
|
||
opacity: 1;
|
||
transform: translateY(0);
|
||
}
|
||
}
|
||
|
||
.form-container > view {
|
||
animation: fadeIn 0.5s ease-out;
|
||
}
|
||
|
||
.form-container > view:nth-child(1) { animation-delay: 0.1s; }
|
||
.form-container > view:nth-child(2) { animation-delay: 0.2s; }
|
||
.form-container > view:nth-child(3) { animation-delay: 0.3s; }
|
||
.form-container > view:nth-child(4) { animation-delay: 0.4s; }
|
||
.form-container > view:nth-child(5) { animation-delay: 0.5s; }
|
||
.form-container > view:nth-child(6) { animation-delay: 0.6s; }
|
||
.form-container > view:nth-child(7) { animation-delay: 0.7s; }
|
||
|
||
/* 交互反馈 */
|
||
.photo-add:active,
|
||
.picker-field:active,
|
||
.radio-item:active,
|
||
.checkbox-item:active,
|
||
.tag-item:active {
|
||
transform: scale(0.98);
|
||
}
|
||
|
||
/* 表单验证状态 */
|
||
.form-group.error {
|
||
.form-label {
|
||
color: #FF5722;
|
||
}
|
||
|
||
.picker-field {
|
||
border: 2rpx solid #FF5722;
|
||
}
|
||
}
|
||
|
||
/* 加载状态 */
|
||
.submit-section .u-button[loading] {
|
||
opacity: 0.7;
|
||
}
|
||
</style>
|