Files
jiebanke/website/js/animal.js

435 lines
17 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 动物认领功能JavaScript
class AnimalManager {
constructor() {
this.apiBaseUrl = 'https://api.jiebanke.com/api/animals';
this.animalsContainer = document.getElementById('animals-container');
this.init();
}
async init() {
await this.loadAnimals();
this.bindFilterEvents();
}
async loadAnimals() {
try {
// 模拟API调用实际项目中替换为真实API
const mockAnimals = [
{
id: 1,
name: "小白",
type: "sheep",
typeName: "绵羊",
age: "baby",
ageText: "3个月",
gender: "female",
description: "温顺可爱的小绵羊,喜欢和人亲近,非常适合初次认领者。",
status: "available",
image: "images/sheep1.svg",
price: 800,
location: "绿野农场",
health: "健康",
personality: "温顺、亲人"
},
{
id: 2,
name: "小黑",
type: "goat",
typeName: "山羊",
age: "young",
ageText: "1岁",
gender: "male",
description: "活泼好动的小山羊,喜欢探索新环境,精力充沛。",
status: "available",
image: "images/goat1.svg",
price: 600,
location: "阳光牧场",
health: "健康",
personality: "活泼、好奇"
},
{
id: 3,
name: "雪球",
type: "rabbit",
typeName: "兔子",
age: "baby",
ageText: "2个月",
gender: "female",
description: "洁白如雪的小兔子,性格温和,非常适合家庭认领。",
status: "reserved",
image: "images/rabbit1.svg",
price: 300,
location: "爱心农场",
health: "健康",
personality: "温和、安静"
},
{
id: 4,
name: "金蛋",
type: "chicken",
typeName: "鸡",
age: "adult",
ageText: "2岁",
gender: "female",
description: "产蛋能力强的母鸡,每天都能提供新鲜鸡蛋。",
status: "available",
image: "images/chicken1.svg",
price: 200,
location: "丰收农场",
health: "健康",
personality: "勤劳、温顺"
},
{
id: 5,
name: "花花",
type: "duck",
typeName: "鸭子",
age: "young",
ageText: "8个月",
gender: "female",
description: "可爱的鸭子,喜欢在水中嬉戏,性格活泼开朗。",
status: "available",
image: "images/duck1.svg",
price: 250,
location: "水乡农场",
health: "健康",
personality: "活泼、友善"
},
{
id: 6,
name: "大角",
type: "goat",
typeName: "山羊",
age: "adult",
ageText: "3岁",
gender: "male",
description: "强壮的公山羊,有着漂亮的角,性格独立但温顺。",
status: "available",
image: "images/goat2.svg",
price: 900,
location: "山野牧场",
health: "健康",
personality: "独立、温顺"
}
];
this.displayAnimals(mockAnimals);
} catch (error) {
console.error('加载动物列表失败:', error);
this.showError('加载动物列表失败,请刷新页面重试');
}
}
displayAnimals(animals) {
if (animals.length === 0) {
this.animalsContainer.innerHTML = `
<div class="col-12 text-center">
<div class="alert alert-info">
<i class="fa fa-info-circle me-2"></i>
暂无可用动物,请稍后再来查看
</div>
</div>
`;
return;
}
const animalsHTML = animals.map(animal => `
<div class="col-md-6 col-lg-4 mb-4" data-aos="fade-up">
<div class="card animal-card h-100">
<img src="${animal.image}" class="card-img-top" alt="${animal.name}">
<div class="card-body">
<div class="d-flex justify-content-between align-items-start mb-3">
<h5 class="animal-name">${animal.name}</h5>
<span class="status-badge status-${animal.status}">
${animal.status === 'available' ? '可认领' : '已被认领'}
</span>
</div>
<div class="animal-type">
<i class="fa fa-paw me-2"></i>
${animal.typeName}
</div>
<div class="animal-age">
<i class="fa fa-birthday-cake me-2"></i>
${animal.ageText}
</div>
<p class="animal-description">
${animal.description}
</p>
<div class="d-flex justify-content-between align-items-center mb-3">
<span class="text-primary fw-bold">¥${animal.price}</span>
<small class="text-muted">${animal.location}</small>
</div>
<div class="action-buttons">
<button class="btn btn-primary btn-sm"
onclick="animalManager.viewAnimalDetail(${animal.id})"
${animal.status !== 'available' ? 'disabled' : ''}>
${animal.status === 'available' ? '立即认领' : '已被认领'}
</button>
<button class="btn btn-outline-secondary btn-sm"
onclick="animalManager.showAnimalInfo(${animal.id})">
查看详情
</button>
</div>
</div>
</div>
</div>
`).join('');
this.animalsContainer.innerHTML = animalsHTML;
}
bindFilterEvents() {
const filterType = document.getElementById('filter-type');
const filterAge = document.getElementById('filter-age');
const filterStatus = document.getElementById('filter-status');
if (filterType) filterType.addEventListener('change', () => this.filterAnimals());
if (filterAge) filterAge.addEventListener('change', () => this.filterAnimals());
if (filterStatus) filterStatus.addEventListener('change', () => this.filterAnimals());
}
async filterAnimals() {
const type = document.getElementById('filter-type').value;
const age = document.getElementById('filter-age').value;
const status = document.getElementById('filter-status').value;
try {
// 模拟筛选功能
const mockAnimals = await this.loadAnimals(); // 重新加载数据
let filteredAnimals = mockAnimals;
if (type) {
filteredAnimals = filteredAnimals.filter(animal => animal.type === type);
}
if (age) {
filteredAnimals = filteredAnimals.filter(animal => animal.age === age);
}
if (status) {
filteredAnimals = filteredAnimals.filter(animal => animal.status === status);
}
this.displayAnimals(filteredAnimals);
} catch (error) {
console.error('筛选动物失败:', error);
this.showError('筛选失败,请刷新页面重试');
}
}
viewAnimalDetail(animalId) {
// 在实际项目中,这里可以跳转到详情页或显示认领表单
console.log('查看动物详情:', animalId);
// 显示认领表单模态框
this.showClaimForm(animalId);
}
showAnimalInfo(animalId) {
// 显示动物详细信息模态框
console.log('显示动物信息:', animalId);
// 这里可以显示一个包含动物详细信息的模态框
alert('动物详细信息功能开发中,即将上线');
}
showClaimForm(animalId) {
// 创建认领表单模态框
const modalHTML = `
<div class="modal fade" id="claimModal" tabindex="-1">
<div class="modal-dialog modal-lg">
<div class="modal-content animal-modal">
<div class="modal-header">
<h5 class="modal-title">认领申请</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<form id="claimForm" class="claim-form">
<input type="hidden" id="animalId" value="${animalId}">
<div class="row">
<div class="col-md-6 mb-3">
<label for="fullName" class="form-label">姓名</label>
<input type="text" class="form-control" id="fullName" required>
</div>
<div class="col-md-6 mb-3">
<label for="phone" class="form-label">手机号</label>
<input type="tel" class="form-control" id="phone" required>
</div>
</div>
<div class="mb-3">
<label for="email" class="form-label">邮箱</label>
<input type="email" class="form-control" id="email" required>
</div>
<div class="mb-3">
<label for="purpose" class="form-label">认领目的</label>
<textarea class="form-control" id="purpose" rows="3" required></textarea>
</div>
<div class="mb-3">
<label for="experience" class="form-label">饲养经验</label>
<select class="form-select" id="experience" required>
<option value="">请选择饲养经验</option>
<option value="none">无经验</option>
<option value="little">少量经验</option>
<option value="rich">丰富经验</option>
</select>
</div>
<div class="form-check mb-3">
<input class="form-check-input" type="checkbox" id="agreeTerms" required>
<label class="form-check-label" for="agreeTerms">
我已阅读并同意<a href="#" onclick="animalManager.showTerms()">认领协议</a>
</label>
</div>
<button type="submit" class="btn btn-primary btn-lg w-100">
提交认领申请
</button>
</form>
</div>
</div>
</div>
</div>
`;
// 添加模态框到页面
document.body.insertAdjacentHTML('beforeend', modalHTML);
// 显示模态框
const modal = new bootstrap.Modal(document.getElementById('claimModal'));
modal.show();
// 绑定表单提交事件
document.getElementById('claimForm').addEventListener('submit', this.handleClaimSubmit.bind(this));
// 模态框关闭时清理
document.getElementById('claimModal').addEventListener('hidden.bs.modal', function () {
this.remove();
});
}
async handleClaimSubmit(event) {
event.preventDefault();
const formData = {
animalId: document.getElementById('animalId').value,
fullName: document.getElementById('fullName').value,
phone: document.getElementById('phone').value,
email: document.getElementById('email').value,
purpose: document.getElementById('purpose').value,
experience: document.getElementById('experience').value
};
// 表单验证
if (!this.validateClaimForm(formData)) {
return;
}
try {
// 模拟API调用
console.log('提交认领申请:', formData);
// 显示成功消息
this.showSuccess('认领申请提交成功!我们会尽快联系您');
// 关闭模态框
bootstrap.Modal.getInstance(document.getElementById('claimModal')).hide();
// 重新加载动物列表
await this.loadAnimals();
} catch (error) {
console.error('提交认领申请失败:', error);
this.showError('提交失败,请稍后重试');
}
}
validateClaimForm(data) {
if (!data.fullName.trim()) {
this.showError('请输入姓名');
return false;
}
if (!data.phone.trim() || !/^1[3-9]\d{9}$/.test(data.phone)) {
this.showError('请输入正确的手机号');
return false;
}
if (!data.email.trim() || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(data.email)) {
this.showError('请输入正确的邮箱地址');
return false;
}
if (!data.purpose.trim()) {
this.showError('请输入认领目的');
return false;
}
if (!data.experience) {
this.showError('请选择饲养经验');
return false;
}
if (!document.getElementById('agreeTerms').checked) {
this.showError('请同意认领协议');
return false;
}
return true;
}
showTerms() {
alert('认领协议功能开发中,即将上线');
}
showSuccess(message) {
this.showAlert(message, 'success');
}
showError(message) {
this.showAlert(message, 'danger');
}
showAlert(message, type) {
const alertDiv = document.createElement('div');
alertDiv.className = `alert alert-${type} alert-dismissible fade show`;
alertDiv.innerHTML = `
${message}
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
`;
// 插入到页面顶部
const container = document.querySelector('.container');
container.insertBefore(alertDiv, container.firstChild);
// 5秒后自动消失
setTimeout(() => {
if (alertDiv.parentNode) {
alertDiv.remove();
}
}, 5000);
}
}
// 初始化动物管理器
const animalManager = new AnimalManager();
// 页面加载完成后初始化
document.addEventListener('DOMContentLoaded', function() {
// AOS动画初始化
if (typeof AOS !== 'undefined') {
AOS.init({
duration: 1000,
once: true
});
}
});