悦 陈 před 1 týdnem
rodič
revize
088d1f6b12

+ 17 - 0
myapp/src/app/tab1/neighborhood/neighborhood-routing.module.ts

@@ -0,0 +1,17 @@
+import { NgModule } from '@angular/core';
+import { Routes, RouterModule } from '@angular/router';
+
+import { NeighborhoodPage } from './neighborhood.page';
+
+const routes: Routes = [
+  {
+    path: '',
+    component: NeighborhoodPage
+  }
+];
+
+@NgModule({
+  imports: [RouterModule.forChild(routes)],
+  exports: [RouterModule],
+})
+export class NeighborhoodPageRoutingModule {}

+ 20 - 0
myapp/src/app/tab1/neighborhood/neighborhood.module.ts

@@ -0,0 +1,20 @@
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { FormsModule } from '@angular/forms';
+
+import { IonicModule } from '@ionic/angular';
+
+import { NeighborhoodPageRoutingModule } from './neighborhood-routing.module';
+
+import { NeighborhoodPage } from './neighborhood.page';
+
+@NgModule({
+  imports: [
+    CommonModule,
+    FormsModule,
+    IonicModule,
+    NeighborhoodPageRoutingModule
+  ],
+  declarations: [NeighborhoodPage]
+})
+export class NeighborhoodPageModule {}

+ 102 - 0
myapp/src/app/tab1/neighborhood/neighborhood.page.html

@@ -0,0 +1,102 @@
+<ion-header [translucent]="true">
+  <ion-toolbar>
+    <ion-title>neighborhood</ion-title>
+  </ion-toolbar>
+</ion-header>
+
+<ion-content [fullscreen]="true">
+  <div class="container">
+        <!-- 顶部区域 -->
+        <header class="header">
+            <div class="header-content">
+                <button class="back-btn">
+                    <i class="bi bi-arrow-left"></i>
+                </button>
+                <h1 class="title">附近鸟类</h1>
+                <div style="width: 24px;"></div> <!-- 用于平衡布局 -->
+            </div>
+        </header>
+        
+        <!-- 搜索区域 -->
+        <section class="search-section">
+            <div class="search-container">
+                <button class="location-select">
+                    <i class="bi bi-geo-alt" style="margin-right: 5px;"></i>
+                    全部地区
+                    <i class="bi bi-chevron-down" style="margin-left: 5px;"></i>
+                </button>
+                <input type="text" class="search-input" placeholder="一拍即识,守护羽翼精灵">
+                <button class="import-btn" (click)="importBrid()">
+                    <i class="bi bi-upload" style="margin-right: 5px;"></i>
+                    导入数据
+                </button>
+            </div>
+        </section>
+        
+        <div *ngFor="let bird of birdList" class="bird-card">
+          <div class="bird-card-top">
+            <!-- 动态图片 -->
+            <img [src]="bird.get('image')" alt="鸟类照片" class="bird-avatar">
+
+            <div class="bird-info">
+              <!-- 名称与学名 -->
+              <h2 class="bird-name">
+                {{ bird.get('name') }}
+                <span class="scientific-name">{{ bird.get('scientificName') }}</span>
+                <span class="conservation-status">国家二级</span>
+              </h2>
+
+              <!-- 分类信息 -->
+              <p class="bird-taxonomy">
+                {{ (bird.get('taxonomy') || {}).order }} > 
+                {{ (bird.get('taxonomy') || {}).family }} > 
+                {{ (bird.get('taxonomy') || {}).genus }}
+              </p>
+
+              <!-- 星级评分 -->
+              <div class="bird-rating">
+                <span *ngFor="let star of getStars(bird.get('rating'))" class="star">{{ star }}</span>
+                <span class="rating-text">{{ bird.get('rating') }}分</span>
+              </div>
+
+              <!-- 标签 -->
+              <div class="bird-tags">
+                <span *ngFor="let tag of bird.get('tags')" class="tag">{{ tag }}</span>
+              </div>
+            </div>
+          </div>
+
+          <!-- 描述 -->
+          <p class="bird-description">{{ bird.get('description') }}</p>
+
+          <!-- 距离与观测时间 -->
+          <div class="bird-distance">
+            <i class="bi bi-geo-alt distance-icon"></i>
+            距离您约{{ bird.get('distance') }}公里 | 最佳观测: {{ (bird.get('observation')||{}).time}}/{{ (bird.get('observation')||{}).season}}
+          </div>
+        </div>
+    </div>
+
+    <script>
+
+        // 交互功能
+        document.querySelector('.back-btn').addEventListener('click', function() {
+            alert('返回上一页');
+        });
+        
+        document.querySelector('.location-select').addEventListener('click', function() {
+            alert('打开地区选择');
+        });
+        
+        // // 卡片点击事件
+        // document.querySelectorAll('.bird-card').forEach(card => {
+        //     card.addEventListener('click', function() {
+        //         const birdId = this.getAttribute('data-id');
+        //         const bird = birds.find(b => b.id === birdId);
+        //         if (bird) {
+        //             alert(`查看${bird.name}的详细信息\n保护等级: ${bird.conservationStatus || '无'}\n最佳观测时间: ${bird.observation.season}/${bird.observation.time}`);
+        //         }
+        //     });
+        // });
+    </script>
+</ion-content>

+ 242 - 0
myapp/src/app/tab1/neighborhood/neighborhood.page.scss

@@ -0,0 +1,242 @@
+ * {
+            margin: 0;
+            padding: 0;
+            box-sizing: border-box;
+            font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
+        }
+        
+        body {
+            background-color: #f5f5f5;
+            color: #333;
+            line-height: 1.5;
+        }
+        
+        .container {
+            max-width: 100%;
+            padding: 0 15px;
+        }
+        
+        /* 顶部区域 */
+        .header {
+            background-color: #4CAF50;
+            color: white;
+            padding: 15px 0;
+            position: sticky;
+            top: 0;
+            z-index: 100;
+            box-shadow: 0 2px 5px rgba(0,0,0,0.1);
+        }
+        
+        .header-content {
+            display: flex;
+            align-items: center;
+            justify-content: space-between;
+            max-width: 600px;
+            margin: 0 auto;
+        }
+        
+        .back-btn {
+            background: none;
+            border: none;
+            color: white;
+            font-size: 20px;
+            cursor: pointer;
+        }
+        
+        .title {
+            font-size: 18px;
+            font-weight: 600;
+            flex-grow: 1;
+            text-align: center;
+        }
+        
+        /* 搜索区域 */
+        .search-section {
+            background-color: white;
+            padding: 15px;
+            margin: 10px 0;
+            border-radius: 10px;
+            box-shadow: 0 1px 3px rgba(0,0,0,0.1);
+            max-width: 600px;
+            margin: 10px auto;
+        }
+        
+        .search-container {
+            display: flex;
+            align-items: center;
+            gap: 8px;
+        }
+        
+        .location-select {
+            flex: 0 0 auto;
+            background-color: #f0f0f0;
+            border: none;
+            border-radius: 20px;
+            padding: 8px 12px;
+            font-size: 14px;
+            display: flex;
+            align-items: center;
+            cursor: pointer;
+        }
+        
+        .search-input {
+            flex: 1;
+            padding: 8px 15px;
+            border: 1px solid #e0e0e0;
+            border-radius: 20px;
+            font-size: 14px;
+            outline: none;
+        }
+        
+        .import-btn {
+            flex: 0 0 auto;
+            background-color: #4CAF50;
+            color: white;
+            border: none;
+            border-radius: 20px;
+            padding: 8px 12px;
+            font-size: 14px;
+            cursor: pointer;
+        }
+        
+        /* 卡片区域 */
+        .bird-list {
+            max-width: 600px;
+            margin: 0 auto 20px;
+        }
+        
+        .bird-card {
+            background-color: white;
+            border-radius: 12px;
+            padding: 15px;
+            margin-bottom: 15px;
+            box-shadow: 0 2px 8px rgba(0,0,0,0.1);
+            transition: transform 0.2s;
+        }
+        
+        .bird-card:hover {
+            transform: translateY(-2px);
+        }
+        
+        .bird-card-top {
+            display: flex;
+            margin-bottom: 12px;
+        }
+        
+        .bird-avatar {
+            width: 80px;
+            height: 80px;
+            border-radius: 50%;
+            object-fit: cover;
+            margin-right: 15px;
+            border: 2px solid #f0f0f0;
+        }
+        
+        .bird-info {
+            flex: 1;
+        }
+        
+        .bird-name {
+            font-size: 18px;
+            font-weight: 600;
+            margin-bottom: 5px;
+            color: #333;
+            display: flex;
+            align-items: center;
+        }
+        
+        .scientific-name {
+            font-size: 12px;
+            color: #666;
+            margin-left: 8px;
+            font-style: italic;
+        }
+        
+        .bird-taxonomy {
+            font-size: 13px;
+            color: #666;
+            margin-bottom: 5px;
+        }
+        
+        .bird-rating {
+            display: flex;
+            align-items: center;
+            margin-bottom: 5px;
+        }
+        
+        .star {
+            color: #FFC107;
+            font-size: 16px;
+            margin-right: 2px;
+        }
+        
+        .rating-text {
+            font-size: 13px;
+            color: #666;
+            margin-left: 5px;
+        }
+        
+        .conservation-status {
+            display: inline-block;
+            background-color: #FFEB3B;
+            color: #333;
+            padding: 2px 6px;
+            border-radius: 4px;
+            font-size: 12px;
+            margin-left: 8px;
+        }
+        
+        .bird-tags {
+            display: flex;
+            flex-wrap: wrap;
+            gap: 6px;
+            margin-bottom: 8px;
+        }
+        
+        .tag {
+            background-color: #E0F7FA;
+            color: #00838F;
+            padding: 2px 8px;
+            border-radius: 10px;
+            font-size: 12px;
+        }
+        
+        .bird-description {
+            font-size: 14px;
+            color: #555;
+            margin-bottom: 8px;
+            line-height: 1.4;
+        }
+        
+        .bird-distance {
+            display: flex;
+            align-items: center;
+            font-size: 13px;
+            color: #4CAF50;
+        }
+        
+        .distance-icon {
+            margin-right: 5px;
+        }
+        
+        /* 响应式调整 */
+        @media (max-width: 480px) {
+            .bird-avatar {
+                width: 70px;
+                height: 70px;
+            }
+            
+            .search-container {
+                flex-wrap: wrap;
+            }
+            
+            .location-select, .import-btn {
+                flex: 1;
+            }
+            
+            .search-input {
+                flex: 100%;
+                order: 3;
+                margin-top: 8px;
+            }
+        }

+ 17 - 0
myapp/src/app/tab1/neighborhood/neighborhood.page.spec.ts

@@ -0,0 +1,17 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { NeighborhoodPage } from './neighborhood.page';
+
+describe('NeighborhoodPage', () => {
+  let component: NeighborhoodPage;
+  let fixture: ComponentFixture<NeighborhoodPage>;
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(NeighborhoodPage);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 188 - 0
myapp/src/app/tab1/neighborhood/neighborhood.page.ts

@@ -0,0 +1,188 @@
+import { Component, OnInit } from '@angular/core';
+import { CloudObject, CloudQuery } from 'src/lib/ncloud';
+
+@Component({
+  selector: 'app-neighborhood',
+  templateUrl: './neighborhood.page.html',
+  styleUrls: ['./neighborhood.page.scss'],
+  standalone:false
+})
+export class NeighborhoodPage implements OnInit {
+  
+
+  constructor() {
+    this.loadBirdType()
+
+  }
+  birdList:CloudObject[]=[]
+  async loadBirdType(){
+    let query=new CloudQuery("BirdType")
+    this.birdList=await query.find();
+  }
+  // 在组件中添加方法
+getStars(rating: number): string[] {
+  const fullStars = Math.floor(rating);
+  const halfStar = rating % 1 >= 0.5 ? 1 : 0;
+  const emptyStars = 5 - fullStars - halfStar;
+
+  return [
+    ...Array(fullStars).fill('★'),
+    ...(halfStar ? ['★'] : []),
+    ...Array(emptyStars).fill('☆')
+  ];
+}
+
+  ngOnInit() {
+    this.loadBirdType();
+  }
+  async importBrid(){
+    const birdDataset = [
+    {
+        name: "红嘴相思鸟",
+        scientificName: "Leiothrix lutea",
+        rating: 4.5,
+        distance: 1.2,
+        image: "https://example.com/birds/red-billed-leiothrix.jpg",
+        description: "红嘴相思鸟以其鲜艳的红色嘴喙和婉转的鸣叫声而闻名,是深受观鸟爱好者喜爱的鸟类。",
+        conservationStatus: "国家二级保护动物",
+        tags: ["鸣禽", "色彩鲜艳", "群居"],
+        taxonomy: {
+            order: "雀形目",
+            family: "鹟科",
+            genus: "相思鸟属"
+        },
+        characteristics: {
+            size: "体长约15厘米",
+            color: "橄榄绿色背部,橙黄色胸腹部,红色嘴喙",
+            habitat: "常绿阔叶林、竹林和灌木丛"
+        },
+        observation: {
+            season: "全年",
+            time: "清晨和黄昏"
+        }
+    },
+    {
+        name: "白鹭",
+        scientificName: "Egretta garzetta",
+        rating: 3.8,
+        distance: 0.8,
+        image: "https://example.com/birds/little-egret.jpg",
+        description: "白鹭是一种优雅的水鸟,常在湿地和浅水区觅食,飞行时颈部呈'S'形弯曲。",
+        conservationStatus: "",
+        tags: ["水鸟", "白色羽毛", "湿地"],
+        taxonomy: {
+            order: "鹈形目",
+            family: "鹭科",
+            genus: "白鹭属"
+        },
+        characteristics: {
+            size: "体长约55-65厘米",
+            color: "全身白色,喙和腿黑色,趾黄色",
+            habitat: "湿地、河流、湖泊"
+        },
+        observation: {
+            season: "春秋季",
+            time: "早晨"
+        }
+    },
+    {
+        name: "红腹锦鸡",
+        scientificName: "Chrysolophus pictus",
+        rating: 5.0,
+        distance: 3.5,
+        image: "https://example.com/birds/golden-pheasant.jpg",
+        description: "红腹锦鸡是中国特有鸟类,雄鸟羽毛色彩艳丽,是国家二级保护动物。",
+        conservationStatus: "国家二级保护动物",
+        tags: ["中国特有", "色彩艳丽", "珍稀"],
+        taxonomy: {
+            order: "鸡形目",
+            family: "雉科",
+            genus: "锦鸡属"
+        },
+        characteristics: {
+            size: "体长约100厘米",
+            color: "金色冠羽,红色胸腹部,多彩的背部羽毛",
+            habitat: "山地森林、灌木丛"
+        },
+        observation: {
+            season: "春季",
+            time: "日出后"
+        }
+    },
+    {
+        name: "黑脸琵鹭",
+        scientificName: "Platalea minor",
+        rating: 4.7,
+        distance: 2.1,
+        image: "https://example.com/birds/black-faced-spoonbill.jpg",
+        description: "黑脸琵鹭是濒危鸟类,以其独特的匙状嘴喙和黑色面部而闻名。",
+        conservationStatus: "国家一级保护动物",
+        tags: ["濒危", "湿地", "迁徙"],
+        taxonomy: {
+            order: "鹈形目",
+            family: "鹮科",
+            genus: "琵鹭属"
+        },
+        characteristics: {
+            size: "体长约60-78厘米",
+            color: "白色羽毛,黑色面部和嘴喙",
+            habitat: "沿海湿地、河口"
+        },
+        observation: {
+            season: "冬季",
+            time: "白天"
+        }
+    },
+    {
+        name: "画眉",
+        scientificName: "Garrulax canorus",
+        rating: 4.2,
+        distance: 0.5,
+        image: "https://example.com/birds/hwamei.jpg",
+        description: "画眉以其优美的鸣叫声而闻名,是中国传统的笼养鸟之一。",
+        conservationStatus: "",
+        tags: ["鸣禽", "笼养鸟", "常见"],
+        taxonomy: {
+            order: "雀形目",
+            family: "鹟科",
+            genus: "噪鹛属"
+        },
+        characteristics: {
+            size: "体长约21-25厘米",
+            color: "棕褐色,眼周有白色眉纹",
+            habitat: "灌木丛、竹林、公园"
+        },
+        observation: {
+            season: "全年",
+            time: "全天"
+        }
+    }
+    ];
+    const BirdType=new CloudObject("BirdType");
+    const query=new CloudQuery("Birdtype");
+
+    for(const bird of birdDataset){
+      try{
+        //检查是否已存在同名鸟类
+        query.equalTo("name",bird.name);
+        const existing=await query.first();
+
+        if(existing){
+          console.log(`鸟类${bird.name}"已存在,保存跳过`);
+          continue;
+        }
+        //创建新鸟类对象
+        const newBird=new CloudObject("BirdType");
+        newBird.set(bird);
+        //保存到数据库
+        await newBird.save();
+        console.log(`鸟类${bird.name}保存成功`);
+      }catch(error){
+        console.error(`保存鸟类${bird.name}时出错`,error);
+      }
+    }
+    console.log("所有鸟类数据处理完成");
+  }
+
+}
+

+ 4 - 0
myapp/src/app/tab1/tab1-routing.module.ts

@@ -14,6 +14,10 @@ const routes: Routes = [
   {
     path: 'way',
     loadChildren: () => import('./way/way.module').then( m => m.WayPageModule)
+  },
+  {
+    path: 'neighborhood',
+    loadChildren: () => import('./neighborhood/neighborhood.module').then( m => m.NeighborhoodPageModule)
   }
 ];
 

+ 1 - 1
myapp/src/app/tab1/tab1.page.html

@@ -54,7 +54,7 @@
               <div class="icon-text">鸟音</div>
           </div>
           <div class="icon-item">
-              <div class="icon-circle">
+              <div (click)="goNeighborhood('附近')" class="icon-circle">
                   <ion-icon name="radio-outline"></ion-icon>
               </div>
               <div class="icon-text">附近</div>

+ 3 - 1
myapp/src/app/tab1/tab1.page.ts

@@ -16,11 +16,13 @@ export class Tab1Page {
   ) {}
   goBridType(bridtype?:string){
     this.navCtrl.navigateForward(["tabs","tab1","page-bridtype"])
-
   }
   goWay(way?:string){
     this.navCtrl.navigateForward(["tabs","tab1","way"])
   }
+  goNeighborhood(neighborhood?:string){
+    this.navCtrl.navigateForward(["tabs","tab1","neighborhood"])
+  }
   navigateToDetail() { // 定义一个方法用于导航到详情页面
     if (this.router.url !== '/detail') { // 检查当前 URL 是否不是目标页面
       this.router.navigateByUrl('/detail').then(() => { // 如果不是,则导航到详情页面

+ 5 - 1
myapp/src/app/tabs/tabs-routing.module.ts

@@ -49,9 +49,13 @@ const routes: Routes = [
     {
       path: 'page-bridtype',
       loadChildren: () => import('../tab1/page-bridtype/page-bridtype.module').then(m => m.PageBridtypePageModule)
+    },
+    {
+        path: 'neighborhood',
+        loadComponent: () => import('../tab1/neighborhood/neighborhood.page').then(m => m.NeighborhoodPage)
     }
   ]
-  }
+  },
 ];
 
 @NgModule({

+ 25 - 1
页面设计.txt

@@ -166,4 +166,28 @@ AI咨询页面设计
 第一行从左到右信息为专家姓名:xxx  专家身份:xxx
 第二行信息为研究方向:xxxx
 ###下
-一个蓝色按钮,白字写咨询
+一个蓝色按钮,白字写咨询
+
+附近推荐鸟类页面设计
+您是一名专业的前端工程师,请帮我用纯前端实现以下产品结构。如果用到icon图标,用国内的CDN引用对应资源。整体布局以手机端为主,用flex布局。如果有更好的细节和美观优化思路,可以直接放心实现。请写在一个HTML文件中返回
+
+页面结构如下:
+#整体布局
+手机版页面,顶部介绍栏,中间是搜索栏,下面是附近鸟类卡片
+
+#顶部区域
+使用绿色,左侧为返回上级页面按钮,中间为标题“附近鸟类”
+
+#搜索区域
+从左至右分为三个部分
+##左边灰色椭圆角按钮,可以下拉选择地区
+##中间搜索栏输入区域,占位提示:一拍即识,守护羽翼精灵
+##右侧为“导入数据”按钮
+
+#卡片区域
+卡片分为上下两个部分
+##上面分为左右两个部分
+###左边为该鸟类头像,使用椭圆形
+###右边为该鸟类信息,包括他的名称,所属纲目科目著类,稀有星级,
+##下面为该鸟的一句话简介,以及距离的数据
+