266 lines
9.4 KiB
JavaScript
266 lines
9.4 KiB
JavaScript
// 旅行结伴功能JavaScript
|
||
|
||
class TravelPlanManager {
|
||
constructor() {
|
||
this.apiBaseUrl = 'https://api.jiebanke.com/api/travel';
|
||
this.plansContainer = document.getElementById('travel-plans-container');
|
||
this.travelForm = document.getElementById('travel-plan-form');
|
||
this.init();
|
||
}
|
||
|
||
async init() {
|
||
await this.loadTravelPlans();
|
||
this.bindEvents();
|
||
}
|
||
|
||
async loadTravelPlans() {
|
||
try {
|
||
// 模拟API调用,实际项目中替换为真实API
|
||
const mockPlans = [
|
||
{
|
||
id: 1,
|
||
destination: "西藏拉萨",
|
||
travelDate: "2025-03-15",
|
||
duration: 10,
|
||
budget: "5000-10000",
|
||
description: "寻找志同道合的伙伴一起探索西藏的神秘与美丽,计划游览布达拉宫、大昭寺、纳木错等景点。",
|
||
requirements: "年龄25-35岁,有高原旅行经验者优先",
|
||
participants: 3,
|
||
maxParticipants: 6,
|
||
creator: "旅行达人小李",
|
||
createdAt: "2025-01-15"
|
||
},
|
||
{
|
||
id: 2,
|
||
destination: "云南大理",
|
||
travelDate: "2025-02-20",
|
||
duration: 7,
|
||
budget: "2000-5000",
|
||
description: "大理古城、洱海、苍山七日游,体验白族文化和自然风光。",
|
||
requirements: "喜欢摄影、热爱自然",
|
||
participants: 2,
|
||
maxParticipants: 4,
|
||
creator: "摄影师小王",
|
||
createdAt: "2025-01-10"
|
||
},
|
||
{
|
||
id: 3,
|
||
destination: "海南三亚",
|
||
travelDate: "2025-04-01",
|
||
duration: 5,
|
||
budget: "3000-6000",
|
||
description: "阳光沙滩度假之旅,潜水、冲浪、海鲜美食一网打尽。",
|
||
requirements: "性格开朗,喜欢水上运动",
|
||
participants: 4,
|
||
maxParticipants: 8,
|
||
creator: "阳光少年小张",
|
||
createdAt: "2025-01-08"
|
||
}
|
||
];
|
||
|
||
this.displayPlans(mockPlans);
|
||
} catch (error) {
|
||
console.error('加载旅行计划失败:', error);
|
||
this.showError('加载旅行计划失败,请刷新页面重试');
|
||
}
|
||
}
|
||
|
||
displayPlans(plans) {
|
||
if (plans.length === 0) {
|
||
this.plansContainer.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 plansHTML = plans.map(plan => `
|
||
<div class="col-md-6 col-lg-4 mb-4" data-aos="fade-up">
|
||
<div class="card travel-plan-card h-100">
|
||
<div class="card-body">
|
||
<div class="d-flex justify-content-between align-items-start mb-3">
|
||
<h5 class="destination">${plan.destination}</h5>
|
||
<span class="budget-badge">${plan.budget}元</span>
|
||
</div>
|
||
|
||
<div class="mb-3">
|
||
<div class="travel-date mb-2">
|
||
<i class="fa fa-calendar-alt me-2"></i>
|
||
出发日期: ${new Date(plan.travelDate).toLocaleDateString('zh-CN')}
|
||
</div>
|
||
<div class="travel-date">
|
||
<i class="fa fa-clock me-2"></i>
|
||
行程天数: ${plan.duration}天
|
||
</div>
|
||
</div>
|
||
|
||
<p class="card-text text-muted mb-3" style="font-size: 0.9rem;">
|
||
${plan.description}
|
||
</p>
|
||
|
||
<div class="mb-3">
|
||
<small class="text-muted">
|
||
<i class="fa fa-user me-1"></i>
|
||
伙伴要求: ${plan.requirements || '无特殊要求'}
|
||
</small>
|
||
</div>
|
||
|
||
<div class="d-flex justify-content-between align-items-center">
|
||
<div class="participants">
|
||
<i class="fa fa-users"></i>
|
||
<span>${plan.participants}/${plan.maxParticipants}人</span>
|
||
</div>
|
||
<small class="text-muted">发布者: ${plan.creator}</small>
|
||
</div>
|
||
|
||
<div class="action-buttons mt-3">
|
||
<button class="btn btn-primary btn-sm" onclick="travelManager.joinPlan(${plan.id})">
|
||
加入计划
|
||
</button>
|
||
<button class="btn btn-outline-secondary btn-sm" onclick="travelManager.viewPlanDetail(${plan.id})">
|
||
查看详情
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
`).join('');
|
||
|
||
this.plansContainer.innerHTML = plansHTML;
|
||
}
|
||
|
||
bindEvents() {
|
||
if (this.travelForm) {
|
||
this.travelForm.addEventListener('submit', this.handleFormSubmit.bind(this));
|
||
}
|
||
}
|
||
|
||
async handleFormSubmit(event) {
|
||
event.preventDefault();
|
||
|
||
const formData = new FormData(this.travelForm);
|
||
const planData = {
|
||
destination: document.getElementById('destination').value,
|
||
travelDate: document.getElementById('travel-date').value,
|
||
duration: parseInt(document.getElementById('duration').value),
|
||
budget: document.getElementById('budget').value,
|
||
description: document.getElementById('description').value,
|
||
requirements: document.getElementById('requirements').value
|
||
};
|
||
|
||
// 表单验证
|
||
if (!this.validateForm(planData)) {
|
||
return;
|
||
}
|
||
|
||
try {
|
||
// 模拟API调用
|
||
console.log('发布旅行计划:', planData);
|
||
|
||
// 显示成功消息
|
||
this.showSuccess('旅行计划发布成功!');
|
||
|
||
// 清空表单
|
||
this.travelForm.reset();
|
||
|
||
// 重新加载计划列表
|
||
await this.loadTravelPlans();
|
||
|
||
} catch (error) {
|
||
console.error('发布旅行计划失败:', error);
|
||
this.showError('发布失败,请稍后重试');
|
||
}
|
||
}
|
||
|
||
validateForm(data) {
|
||
if (!data.destination.trim()) {
|
||
this.showError('请输入目的地');
|
||
return false;
|
||
}
|
||
|
||
if (!data.travelDate) {
|
||
this.showError('请选择出发日期');
|
||
return false;
|
||
}
|
||
|
||
if (data.duration < 1) {
|
||
this.showError('行程天数必须大于0');
|
||
return false;
|
||
}
|
||
|
||
if (!data.budget) {
|
||
this.showError('请选择预算范围');
|
||
return false;
|
||
}
|
||
|
||
if (!data.description.trim()) {
|
||
this.showError('请输入行程描述');
|
||
return false;
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
async joinPlan(planId) {
|
||
try {
|
||
// 模拟加入计划
|
||
console.log('加入旅行计划:', planId);
|
||
this.showSuccess('已申请加入旅行计划,等待创建者确认');
|
||
} catch (error) {
|
||
console.error('加入计划失败:', error);
|
||
this.showError('加入失败,请稍后重试');
|
||
}
|
||
}
|
||
|
||
viewPlanDetail(planId) {
|
||
// 在实际项目中,这里可以跳转到详情页或显示模态框
|
||
console.log('查看旅行计划详情:', planId);
|
||
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 travelManager = new TravelPlanManager();
|
||
|
||
// 页面加载完成后初始化
|
||
document.addEventListener('DOMContentLoaded', function() {
|
||
// AOS动画初始化
|
||
if (typeof AOS !== 'undefined') {
|
||
AOS.init({
|
||
duration: 1000,
|
||
once: true
|
||
});
|
||
}
|
||
}); |