|
@@ -5,144 +5,113 @@
|
|
|
</ion-header>
|
|
|
|
|
|
<ion-content [fullscreen]="true">
|
|
|
- <div class="container">
|
|
|
+ <!-- 新增路线表单模态框 -->
|
|
|
+ <div class="modal-overlay" *ngIf="showCreateModal" (click)="closeModal()">
|
|
|
+ <div class="create-modal" (click)="$event.stopPropagation()">
|
|
|
+ <div class="modal-header">
|
|
|
+ <h3>创建新路线</h3>
|
|
|
+ <ion-icon name="close" (click)="closeModal()"></ion-icon>
|
|
|
+ </div>
|
|
|
+ <div class="modal-body">
|
|
|
+ <div class="form-group">
|
|
|
+ <label>路线标题</label>
|
|
|
+ <input type="text" [(ngModel)]="newRouteData.title" placeholder="请输入路线标题">
|
|
|
+ </div>
|
|
|
+ <div class="form-group">
|
|
|
+ <label>位置</label>
|
|
|
+ <input type="text" [(ngModel)]="newRouteData.location" placeholder="请输入位置">
|
|
|
+ </div>
|
|
|
+ <div class="form-group">
|
|
|
+ <label>预计时长</label>
|
|
|
+ <input type="text" [(ngModel)]="newRouteData.duration" placeholder="例如:3小时">
|
|
|
+ </div>
|
|
|
+ <div class="form-group">
|
|
|
+ <label>描述</label>
|
|
|
+ <textarea [(ngModel)]="newRouteData.description" placeholder="请输入路线描述"></textarea>
|
|
|
+ </div>
|
|
|
+ <div class="form-group">
|
|
|
+ <label>缩略图URL</label>
|
|
|
+ <input type="text" [(ngModel)]="newRouteData.thumbnail"
|
|
|
+ placeholder="https://example.com/image.jpg">
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="modal-footer">
|
|
|
+ <button class="cancel-btn" (click)="closeModal()">取消</button>
|
|
|
+ <button class="confirm-btn" (click)="confirmCreate()">确定</button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="container">
|
|
|
<!-- 顶部导航栏 -->
|
|
|
<div class="header">
|
|
|
- <div class="back-btn">
|
|
|
- <i class="iconfont icon-arrow-left"></i>
|
|
|
- </div>
|
|
|
- <div class="title">路线推荐</div>
|
|
|
- <div style="width: 24px;"></div>
|
|
|
+ <div class="back-btn">
|
|
|
+ <i class="iconfont icon-arrow-left"></i>
|
|
|
+ </div>
|
|
|
+ <div class="title">路线推荐</div>
|
|
|
+ <div style="width: 24px;"></div>
|
|
|
</div>
|
|
|
-
|
|
|
+
|
|
|
+ <!-- 加载状态指示 -->
|
|
|
+ <div *ngIf="isLoading" class="loading-indicator">
|
|
|
+ 加载中...
|
|
|
+ </div>
|
|
|
+
|
|
|
<!-- 路线推荐卡片 -->
|
|
|
<div class="route-container">
|
|
|
- <!-- 路线1 -->
|
|
|
- <div class="route-card">
|
|
|
- <div class="route-thumbnail" style="background-image: url('https://picsum.photos/600/400?random=101');">
|
|
|
- <!-- 可以在缩略图上叠加路线标记 -->
|
|
|
+ <div class="route-card" *ngFor="let route of routes">
|
|
|
+ <div class="route-thumbnail" [style.background-image]="'url(' + route.get('thumbnail') + ')'"></div>
|
|
|
+ <div class="route-info">
|
|
|
+ <div class="route-title">{{ route.get('title') }}</div>
|
|
|
+ <div class="route-actions">
|
|
|
+ <button class="delete-btn" (click)="deleteRoute(route)">删除</button>
|
|
|
+ </div>
|
|
|
+ <div class="route-rating">
|
|
|
+ <span *ngFor="let star of getStars(route.get('rating'))">{{ star }}</span>
|
|
|
+ <span class="rating-value">{{ route.get('rating')?.toFixed(1) || '0.0' }}</span>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="route-meta">
|
|
|
+ <span><i class="iconfont icon-location"></i>{{ route.get('location') }}</span>
|
|
|
+ <span><i class="iconfont icon-clock"></i>{{ route.get('duration') }}</span>
|
|
|
+ <span><i class="iconfont icon-eye"></i>{{ route.get('birdCount') }}种鸟类</span>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="route-description">
|
|
|
+ {{ route.get('description') || '暂无描述' }}
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="birds-section" *ngIf="route.get('birds')?.length > 0">
|
|
|
+ <div class="section-title">
|
|
|
+ <i class="iconfont icon-bird"></i>
|
|
|
+ 沿途鸟类
|
|
|
</div>
|
|
|
- <div class="route-info">
|
|
|
- <div class="route-title">鄱阳湖冬季候鸟观赏路线</div>
|
|
|
- <div class="route-meta">
|
|
|
- <span><i class="iconfont icon-location"></i>江西九江</span>
|
|
|
- <span><i class="iconfont icon-clock"></i>3小时</span>
|
|
|
- <span><i class="iconfont icon-eye"></i>23种鸟类</span>
|
|
|
- </div>
|
|
|
-
|
|
|
- <div class="birds-section">
|
|
|
- <div class="section-title">
|
|
|
- <i class="iconfont icon-bird"></i>
|
|
|
- 沿途鸟类
|
|
|
- </div>
|
|
|
- <div class="birds-grid">
|
|
|
- <div class="bird-item">
|
|
|
- <div class="bird-avatar" style="background-image: url('https://picsum.photos/100/100?random=1');"></div>
|
|
|
- <div class="bird-name">白鹤<span class="protected-badge">一级</span></div>
|
|
|
- </div>
|
|
|
- <div class="bird-item">
|
|
|
- <div class="bird-avatar" style="background-image: url('https://picsum.photos/100/100?random=2');"></div>
|
|
|
- <div class="bird-name">小天鹅</div>
|
|
|
- </div>
|
|
|
- <div class="bird-item">
|
|
|
- <div class="bird-avatar" style="background-image: url('https://picsum.photos/100/100?random=3');"></div>
|
|
|
- <div class="bird-name">东方白鹳<span class="protected-badge">一级</span></div>
|
|
|
- </div>
|
|
|
- <div class="bird-item">
|
|
|
- <div class="bird-avatar" style="background-image: url('https://picsum.photos/100/100?random=4');"></div>
|
|
|
- <div class="bird-name">鸿雁</div>
|
|
|
- </div>
|
|
|
- <div class="bird-item">
|
|
|
- <div class="bird-avatar" style="background-image: url('https://picsum.photos/100/100?random=5');"></div>
|
|
|
- <div class="bird-name">白琵鹭</div>
|
|
|
- </div>
|
|
|
- <div class="bird-item">
|
|
|
- <div class="bird-avatar" style="background-image: url('https://picsum.photos/100/100?random=6');"></div>
|
|
|
- <div class="bird-name">灰鹤</div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
-
|
|
|
- <!-- 路线2 -->
|
|
|
- <div class="route-card">
|
|
|
- <div class="route-thumbnail" style="background-image: url('https://picsum.photos/600/400?random=102');"></div>
|
|
|
- <div class="route-info">
|
|
|
- <div class="route-title">庐山森林鸟类观察路线</div>
|
|
|
- <div class="route-meta">
|
|
|
- <span><i class="iconfont icon-location"></i>江西九江</span>
|
|
|
- <span><i class="iconfont icon-clock"></i>5小时</span>
|
|
|
- <span><i class="iconfont icon-eye"></i>18种鸟类</span>
|
|
|
- </div>
|
|
|
-
|
|
|
- <div class="birds-section">
|
|
|
- <div class="section-title">
|
|
|
- <i class="iconfont icon-bird"></i>
|
|
|
- 沿途鸟类
|
|
|
- </div>
|
|
|
- <div class="birds-grid">
|
|
|
- <div class="bird-item">
|
|
|
- <div class="bird-avatar" style="background-image: url('https://picsum.photos/100/100?random=7');"></div>
|
|
|
- <div class="bird-name">白鹇<span class="protected-badge">二级</span></div>
|
|
|
- </div>
|
|
|
- <div class="bird-item">
|
|
|
- <div class="bird-avatar" style="background-image: url('https://picsum.photos/100/100?random=8');"></div>
|
|
|
- <div class="bird-name">红嘴相思鸟</div>
|
|
|
- </div>
|
|
|
- <div class="bird-item">
|
|
|
- <div class="bird-avatar" style="background-image: url('https://picsum.photos/100/100?random=9');"></div>
|
|
|
- <div class="bird-name">画眉</div>
|
|
|
- </div>
|
|
|
- <div class="bird-item">
|
|
|
- <div class="bird-avatar" style="background-image: url('https://picsum.photos/100/100?random=10');"></div>
|
|
|
- <div class="bird-name">松鸦</div>
|
|
|
- </div>
|
|
|
- <div class="bird-item">
|
|
|
- <div class="bird-avatar" style="background-image: url('https://picsum.photos/100/100?random=11');"></div>
|
|
|
- <div class="bird-name">红嘴蓝鹊</div>
|
|
|
- </div>
|
|
|
- <div class="bird-item">
|
|
|
- <div class="bird-avatar" style="background-image: url('https://picsum.photos/100/100?random=12');"></div>
|
|
|
- <div class="bird-name">黑脸噪鹛</div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
+ <div class="birds-grid">
|
|
|
+ <div class="bird-item" *ngFor="let bird of route.get('birds')">
|
|
|
+ <div class="bird-avatar" [style.background-image]="'url(' + bird.avatar + ')'"></div>
|
|
|
+ <div class="bird-name">
|
|
|
+ {{ bird.name }}
|
|
|
+ <span class="protected-badge" *ngIf="bird.protectionLevel">{{ bird.protectionLevel }}</span>
|
|
|
</div>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="route-tags" *ngIf="route.get('tags')?.length > 0">
|
|
|
+ <span class="tag" *ngFor="let tag of route.get('tags')">{{ tag }}</span>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
|
|
|
<!-- 底部操作按钮 -->
|
|
|
<div class="action-buttons">
|
|
|
- <div class="action-btn select-btn">
|
|
|
- <i class="iconfont icon-select"></i> 路线选择
|
|
|
- </div>
|
|
|
- <div class="action-btn upload-btn">
|
|
|
- <i class="iconfont icon-upload"></i> 路线上传
|
|
|
- </div>
|
|
|
+ <div class="action-btn select-btn" (click)="importSampleRoutes()">
|
|
|
+ <i class="iconfont icon-select"></i> 导入示例
|
|
|
+ </div>
|
|
|
+ <div class="action-btn upload-btn" (click)="showCreateForm()">
|
|
|
+ <i class="iconfont icon-upload"></i> 创建路线
|
|
|
+ </div>
|
|
|
</div>
|
|
|
-</div>
|
|
|
+ </div>
|
|
|
|
|
|
-<script>
|
|
|
- // 简单的交互逻辑
|
|
|
- document.querySelector('.back-btn').addEventListener('click', function() {
|
|
|
- alert('返回上一页');
|
|
|
- });
|
|
|
-
|
|
|
- document.querySelector('.select-btn').addEventListener('click', function() {
|
|
|
- alert('打开路线选择筛选器');
|
|
|
- });
|
|
|
-
|
|
|
- document.querySelector('.upload-btn').addEventListener('click', function() {
|
|
|
- alert('打开路线上传页面');
|
|
|
- });
|
|
|
-
|
|
|
- // 鸟类头像点击效果
|
|
|
- document.querySelectorAll('.bird-avatar').forEach(avatar => {
|
|
|
- avatar.addEventListener('click', function() {
|
|
|
- const birdName = this.nextElementSibling.textContent;
|
|
|
- alert(`查看${birdName}的详细信息`);
|
|
|
- });
|
|
|
- });
|
|
|
-</script>
|
|
|
</ion-content>
|