HarmonyOS开辟 - 餐饮APP首页开辟实例

打印 上一主题 下一主题

主题 810|帖子 810|积分 2430

        一个餐饮APP开辟,主要包括以下几个核心步骤和功能:

  • 需求和功能规划:首先必要确定APP的基本功能,如商品展示、在线点餐、订单管理、付出结算、扫码核销等。同时必要实现多门店特色功能,如门店切换与定位、库存管理和销售数据统计等。别的,另有营销功能、如优惠券发放、会员制度、积分兑换等,以吸引顾客和进步用户的粘性。
  • 选择开辟方式:如企业有本身的技术团队,可以选择自主研发,以实现高度定制化。如没有,则可以选择第三方开辟平台或外包给专业的软件公司,以低落本钱和进步效率。
  • 申请账号和认证:注册相关的账号并进行企业主体认证,以确保可以利用APP的更多功能,如付出接口等。
  • 计划与开辟:计划简洁、美观、易用的界面,确保各个功能模块的正常运行和数据的准确传输。特别是多门店管理体系的开辟,必要创建一个集中的管理后台,用于管理各个门店的信息、菜品、库存、订单等,以使总部可以统一管理和监控。
  • 测试与优化:在开辟完成后,进行功能测试和优化,确保APP的稳定性和用户体验。测试内容包括订单处理、付出功能、用户界面等方面。
  • 多门店管理:实现多门店的统一管理和调试,实时监控各门店的运营情况,确保高效顺畅。
  • 营销工具:支持优惠券、满减活动、会员积会等多种促销方式,提升客户黏性和销售额。
  • 付出功能:支持多种付出方式,确保付出案例,提升顾客满足度。
        首先我们先完成APP的首页开辟,其中包含商品展示轮播图、应用分类、商品列表、底部导航等功能。
 一、情况搭建

1.1 DevEco Studio

        如果DevEco Studio应用已安装,则直接打开并创建项目即可。

        如体系中未安装DevEco Studio开辟工具,可前云官方网站下载,地址:DevEco Studio-HarmonyOS Next Beta版-华为开辟者同盟
        安装步骤地址:HarmonyOS开辟之DevEco Studio安装_select the directory where ohpm has been installed-CSDN博客

2.2 仿真机安装

        如果你没有华为体系手机,可以点击并打开Device Manager管理界面,选择“Local Emulator”本地仿真器的创建。

        在Device Manager管理界面的右下角,点击“New Emulator”新仿真器创建按钮,选择您必要创建的仿真装备即可,这里选择“Huawei_Phone”。

        然后点击下一步,进入假造装备的配置界面,选择您必要的版本即可。这里选择最新版本(注意:在点击”下一步“按钮前,必要点击Name列中下载图标,将必要安装的对应版本先下载,否则会提示“Download the system image first”错误),如下图:

        点击“下一步”后,会进入新界面,自定义装备名称后,点击“完成”即可。如下图:

        当仿真装备创建完成后,最初管理界面会多出新创建仿真装备信息,如下图:

        此时,点击右侧“播放”按钮,则可以启动仿真装备了。如下图:


二、创建APP应用

        创建项目应用,首先打开DevEco Studio开辟工具,点击“File” -> “New” -> “Create Project”,打开

        选择创建一个空应用,点击“下一步”。

        修改项目名称后,点击“完成”即可。

        此时项目则已创建乐成,如下图:

2.1 Previewer预览        

        点击右侧的“previewer”即可检察界面结果,如下图:

2.2 仿真装备预览

        当仿真装备启动后,在DevEco Studio中会显示创建的仿真装备的名称,此时点击右侧“Run”或“Debug”即可在仿真装备中预览界面结果了。

        点击“Run”后,刚创建的项目界面,则在仿真装备中显示了,如下图:


三、餐饮APP首页

        在介绍完HarmonyOS项目开辟中,对DevEco Studio安装、仿真装备创建后,接下来将通过HarmonyOS完成如下图的首页的搭建工作。

       上图原型已上传到资源中,必要的朋友可以前去下载,地址:https://download.csdn.net/download/jiciqiang/89906021
        图片资源,可下载原型资源包后,打开压缩包并解压,在image目录中检察。如下图:


3.1 自定义组件 - 低代码开辟

        在创建顶部导航前,我们先在ets目录中新建components目录,用于存放自定义组件。


        当components创建乐成后,在其内部创建Header.ets文件,用于自定义顶部导航组件。

        选中components目录并右击,创建组件,如下图:

        此操作会创建出一个低代码操作界面,可以帮助开辟人员快速搭建界面结构及样式设置。如果您照旧风俗于手动代码搭建,可以直接在components目录中创建ets文件,定义Header组件。低代码界面如下图:

        当我们点击“天生est文件”转换按钮后,会弹出要天生的代码弹框,如下图:

        进行转换后再打开Header.ets文件,则代码已经天生。此时各人会发现,低代码文件自动删除了,这操作是不可逆的过程。

   说明:利用低代码开辟界面过程中,如果界面必要利用到其他暂时不支持可视化结构的控件,可以在低代码界面开辟完成后,单独“转换”按钮,将低代码界面转换为ets文件。
  
  注意:代码转换操作会删除visual文件及其父目录,且为不可逆过程,代码转换后不能通过html/css或ets文件反向天生visual文件。多装备开辟的场景,可以单击界面画布query模式,可以为组件设置不同的样式和属性。当前media query模式仅针对不同装备类型和不同屏幕状态(横屏/竖屏)有用。
          DevEco低代码文档地址:文档中央
3.2 自定义组件 - 顶部导航       

        顶部导航组件开内容和样式开辟完成后,可以打开pages目录下的index.ets文件,将Header组件引入进去后,再来检察下结果。
        代码如下:
  1. import Header from '../components/Header'
  2. @Entry
  3. @Component
  4. struct Index {
  5.   @State message: string = 'Hello World'
  6.   build() {
  7.     Row() {
  8.       Column() {
  9.         Header()
  10.         Text(this.message)
  11.           .fontSize(50)
  12.           .fontWeight(FontWeight.Bold)
  13.       }
  14.       .width('100%')
  15.     }
  16.     .height('100%').alignItems(VerticalAlign.Top)
  17.   }
  18. }
复制代码
        界面结果如下图:

        界面内容和样式虽然已完成了,但是当搜刮内容改变时,必要将输入文本上报给父组件,从而做出相应操作及跳转动作。所以我们在Header.ets文件添加相应变量、方法和事件,将信息传递给父组件。
components/Header.ets代码如下:
  1. @Preview
  2. @Component
  3. export default struct Header {
  4.   // 搜索关键词
  5.   @State keyword: string = ''
  6.   // 关键词内容改变时回调函数
  7.   private onSearchChange: (data: string) => void
  8.   build() {
  9.     Row() {
  10.       Image($rawfile('position_u5.png'))
  11.         .width("16vp")
  12.         .height("25vp")
  13.         .margin({ top: "0vp", bottom: "0vp", left: "0vp", right: "0vp" })
  14.       Text("门店信息\n")
  15.         .width("65vp")
  16.         .height("40vp")
  17.         .fontSize("12fp")
  18.       TextInput({ text: this.keyword, placeholder: "请输入搜索关键词" })
  19.         .width("170vp")
  20.         .height("40vp")
  21.         .placeholderColor("#262626")
  22.         .placeholderFont({ size: 12 })
  23.         .onChange((e) => this.keyword = e)
  24.       Button("搜索")
  25.         .width("70vp")
  26.         .height("40vp")
  27.         .onClick(() => {
  28.           this.onSearchChange(this.keyword) // 点击查询事件,将信息传递给父组件
  29.         })
  30.     }   
  31.     .width("100%")
  32.     .padding({ top: "10vp", bottom: "10vp", left: "15vp", right: "15vp" })
  33.     .justifyContent(FlexAlign.SpaceBetween)
  34.   }
  35. }
复制代码
pages/Index.ets代码如下:
  1. import Header from '../components/Header'
  2. @Entry
  3. @Component
  4. struct Index {
  5.   @State keyword: string = ''
  6.   build() {
  7.     Row() {
  8.       Column() {
  9.         Header({onSearchChange: this.onSearchChange.bind(this)})
  10.       }
  11.       .width('100%')
  12.     }
  13.     .height('100%').alignItems(VerticalAlign.Top)
  14.   }
  15.   /**
  16.    * 搜索内容改变事件
  17.    * @param data
  18.    */
  19.   onSearchChange(data: string){
  20.     console.log('search', data)
  21.   }
  22. }
复制代码
        此时点击顶部导航栏中“搜刮”按钮,则可以在父组件中输出输入框中的内容了。如下图:


        该篇现在只讲首页搭建部分内容,所以搜刮功能后续操作暂时不再详说,后续偶然机或者各人自行追加即可。

3.3 自定义组件 - 底部菜单


        接下来我们来完善下底部菜单导航的开辟工作,这里将利用到UI界面的Tabs组件。
3.3.1 Tabs组件

        Tabs组件的页面组成包含两个部分,分别是TabContent和TabBar。TabContent是内容页,TabBar是导航页签栏,页面结构如下图所示,根据不同的导航类型,结构会有区别,可以分为底部导航、顶部导航、侧边导航,其导航栏分别位于底部、顶部和侧边。

   说明:
  

  • TabContent组件不支持设置通用宽度属性,其宽度默认撑满Tabs父组件。
  • TabContent组件不支持设置通用高度属性,其高度由Tabs父组件高度与TabBar组件高度决定。
          Tabs利用花括号包裹TabContent,如下图,其中TabContent显示相应的内容页。

        官方文档地址:文档中央
3.3.2 实现Tabs菜单

        了解了Tabs结构后,我们利用它完成底部导航菜单代码部分。visual低代码模式中也有Tabs组件,由于这里没有复杂的样式结构,直接在页面中定义即可。
        pages/index.ets代码如下:
  1. import Header from '../components/Header'
  2. @Entry
  3. @Component
  4. struct Index {
  5.   @State keyword: string = ''
  6.   build() {
  7.     Row() {
  8.       Column() {
  9.         Tabs({
  10.           barPosition: BarPosition.End
  11.         }){
  12.           TabContent(){
  13.             Header({onSearchChange: this.onSearchChange.bind(this)})
  14.           }.tabBar({icon: $rawfile('u48.png'), text: '首页'})
  15.           TabContent(){
  16.             Text('待开发中...')
  17.           }.tabBar({icon: $rawfile('u43.png'), text: '订单'})
  18.           TabContent(){
  19.             Text('待开发中...')
  20.           }.tabBar({icon: $rawfile('u53.png'), text: '我的'})
  21.         }
  22.         .barMode(BarMode.Fixed)
  23.         .barHeight(60)
  24.       }
  25.       .width('100%')
  26.     }
  27.     .height('100%').alignItems(VerticalAlign.Top)
  28.   }
  29.   /**
  30.    * 搜索内容改变事件
  31.    * @param data
  32.    */
  33.   onSearchChange(data: string){
  34.     console.log('search value:', data)
  35.   }
  36. }
复制代码
        页面结果如下图:

3.4 自定义构建函数 - 轮播图

        Swiper组件提供滑动轮播显示的本领。Swiper本身是一个容器组件,当设置了多个子组件后,可以对这些子组件进行轮播显示。通常,在一些应用首页显示推荐的内容时,必要用到轮播显示的本领。
        在components/Index目录中创建轮播图组件,文件结构如下图:

        代码如下:
  1. @Preview
  2. @Component
  3. export default struct CarouselMap {
  4.   private swiperController: SwiperController = new SwiperController()
  5.   build() {
  6.     Row() {
  7.       Swiper(this.swiperController){
  8.           Image($rawfile('u13.png')).borderRadius(10)
  9.           Image($rawfile('u13.png')).borderRadius(10)
  10.         }
  11.         .width("100%")
  12.         .height("200vp")
  13.         .padding(10)
  14.         .index(0)         // 默认索引
  15.         .autoPlay(true)   // 自动播放
  16.         .loop(true)       // 循环播放
  17.         .itemSpace(10)    // 图片的间隙
  18.         .onChange((index: number) => {
  19.           console.log('testTag swiper index:', index)
  20.         })
  21.     }
  22.   }
  23. }
复制代码
        当轮播图组件定义好后,将期引入到首页中,pages/index.ets代码如下:
  1. import Header from '../components/Header'
  2. import CarouseMap from '../components/Index/CarouselMap'
  3. @Entry
  4. @Component
  5. struct Index {
  6.   @State keyword: string = ''
  7.   build() {
  8.     Row() {
  9.       Column() {
  10.         Tabs({
  11.           barPosition: BarPosition.End
  12.         }){
  13.           TabContent(){
  14.             // 增加Column原因是因为TabContent中只有一个子组件,否则会报错
  15.             Column(){
  16.               Header({onSearchChange: this.onSearchChange.bind(this)})
  17.               CarouseMap()
  18.             }.width('100%').height('100%').alignItems(HorizontalAlign.Start)
  19.           }.tabBar({icon: $rawfile('u48.png'), text: '首页'})
  20.           TabContent(){
  21.             Text('待开发中...')
  22.           }.tabBar({icon: $rawfile('u43.png'), text: '订单'})
  23.           TabContent(){
  24.             Text('待开发中...')
  25.           }.tabBar({icon: $rawfile('u53.png'), text: '我的'})
  26.         }
  27.         .barMode(BarMode.Fixed)
  28.         .barHeight(60)
  29.       }
  30.       .width('100%')
  31.     }
  32.     .height('100%').alignItems(VerticalAlign.Top)
  33.   }
  34.   /**
  35.    * 搜索内容改变事件
  36.    * @param data
  37.    */
  38.   onSearchChange(data: string){
  39.     console.log('search value:', data)
  40.   }
  41. }
复制代码
        页面结果如下图:


3.5 自定义构建函数 - 分类列表

       接下来完身分类列表信息,在components/Index目录中创建CategoryList.ets组件。

        创建后visual低代码编辑界面,如下图:

        当界面内容搭建完后,通过转换按钮,生身分类列表的组件代码。代码如下:
  1. @Preview
  2. @Component
  3. export default struct MiddleMenu {
  4.   build() {
  5.     Row() {
  6.       Column() {
  7.         Image($rawfile('u27.png'))
  8.           .width("64vp")
  9.           .height("64vp")
  10.         Text("门店")
  11.           .height("32vp")
  12.           .textAlign(TextAlign.Center)
  13.           .fontSize("16fp")
  14.           .fontWeight(FontWeight.Bold)
  15.       }
  16.       Column() {
  17.         Image($rawfile('u25.png'))
  18.           .width("64vp")
  19.           .height("64vp")
  20.         Text("水果")
  21.           .height("32vp")
  22.           .textAlign(TextAlign.Center)
  23.           .fontSize("16fp")
  24.           .fontWeight(FontWeight.Bold)
  25.       }
  26.       Column() {
  27.         Image($rawfile('u27.png'))
  28.           .width("64vp")
  29.           .height("64vp")
  30.         Text("美食")
  31.           .height("32vp")
  32.           .textAlign(TextAlign.Center)
  33.           .fontSize("16fp")
  34.           .fontWeight(FontWeight.Bold)
  35.       }
  36.       Column() {
  37.         Image($rawfile('u29.png'))
  38.           .width("64vp")
  39.           .height("64vp")
  40.         Text("包厢")
  41.           .height("32vp")
  42.           .textAlign(TextAlign.Center)
  43.           .fontSize("16fp")
  44.           .fontWeight(FontWeight.Bold)
  45.       }
  46.     }   
  47.     .width("100%")
  48.     .padding({ top: 10, bottom: 10, left: 20, right: 20 })
  49.     .justifyContent(FlexAlign.SpaceBetween)
  50.   }
  51. }
复制代码
        再将分类列表组件引入到首页中,代码如下:
  1. import Header from '../components/Header'
  2. import CarouseMap from '../components/Index/CarouselMap'
  3. import CategoryList from '../components/Index/CategoryList'
  4. @Entry
  5. @Component
  6. struct Index {
  7.   @State keyword: string = ''
  8.   build() {
  9.     Row() {
  10.       Column() {
  11.         Tabs({
  12.           barPosition: BarPosition.End
  13.         }){
  14.           TabContent(){
  15.             // 增加Column原因是因为TabContent中只有一个子组件,否则会报错
  16.             Column(){
  17.               Header({onSearchChange: this.onSearchChange.bind(this)})    // 顶部导航
  18.               CarouseMap()        // 轮播图
  19.               CategoryList()      // 分类列表
  20.             }.width('100%').height('100%').alignItems(HorizontalAlign.Start)
  21.           }.tabBar({icon: $rawfile('u48.png'), text: '首页'})
  22.           TabContent(){
  23.             Text('待开发中...')
  24.           }.tabBar({icon: $rawfile('u43.png'), text: '订单'})
  25.           TabContent(){
  26.             Text('待开发中...')
  27.           }.tabBar({icon: $rawfile('u53.png'), text: '我的'})
  28.         }
  29.         .barMode(BarMode.Fixed)
  30.         .barHeight(60)
  31.       }
  32.       .width('100%')
  33.     }
  34.     .height('100%').alignItems(VerticalAlign.Top)
  35.   }
  36.   /**
  37.    * 搜索内容改变事件
  38.    * @param data
  39.    */
  40.   onSearchChange(data: string){
  41.     console.log('search value:', data)
  42.   }
  43. }
复制代码
        页面结果如下图:


3.6 自定义构建函数 - 产物列表

        最后,再创建一个产物列表,在components/Index目录中创建ProductList组件。

3.6.1 visual低代码编辑

        这部分样式结构会稍微复杂点,所以在visual文件的低代码模式下,先画出基本表面和第一个产物信息,其他等转换为代码模式时,通过列表循环输出即可。如下图:

3.6.2 转换为代码

        转换后的代码,只是基本结构和部分产物样式,代码如下:
  1. @Preview
  2. @Component
  3. export default struct ProductList {
  4.   build() {
  5.     Row({ space: "0vp" }) {
  6.       Column() {
  7.         Text("精品特卖")
  8.           .width("100%")
  9.           .height("50vp")
  10.           .fontSize("16fp")
  11.           .fontWeight(FontWeight.Bold)
  12.         Row() {
  13.           Row() {
  14.             Column() {
  15.               Column() {
  16.                 Image($rawfile('u62.png'))
  17.                   .width("150vp")
  18.                   .height("65vp")
  19.                 Text("啫啫鱼头")
  20.                   .width("150vp")
  21.                   .height("26vp")
  22.                   .textOverflow({ overflow: TextOverflow.Ellipsis })
  23.                   .fontSize("10fp")
  24.                 Row() {
  25.                   Text("¥52")
  26.                     .width("60vp")
  27.                     .height("30vp")
  28.                     .fontColor("#ff0000")
  29.                     .fontSize("12fp")
  30.                     .fontWeight(FontWeight.Bold)
  31.                   Text("原价:55元")
  32.                     .width("90vp")
  33.                     .height("30vp")
  34.                     .fontColor("#575757")
  35.                     .decoration({ type: TextDecorationType.LineThrough, color: "#313030" })
  36.                 }               
  37.                 .width("150vp")
  38.               }
  39.             }
  40.             Column()
  41.           }
  42.         }
  43.         Row() {
  44.           Column()
  45.           Column()
  46.         }
  47.       }      
  48.       .width("100%")
  49.     }   
  50.     .width("100%")
  51.     .padding({ top: "10vp", bottom: "10vp", left: "15vp", right: "15vp" })
  52.   }
  53. }
复制代码
        此时将其引入到首页中结果是这样的,如下图:

        产物信息是通过接口获取的列表数据,然后通过GridRow组件和GridCol组件组合利用,将产物渲染成两列。这里暂时未调用接口,所以先将数据定义在组件中,通过ForEach遍历数组。
        components/Index/ProductList.ets代码如下:
  1. type ProductType = {
  2.   title: string
  3.   thumb: Resource
  4.   price: number
  5.   originPrice: number
  6. }
  7. @Preview
  8. @Component
  9. export default struct ProductList {
  10.   @State productList: Array<ProductType> = [
  11.     { title: '啫啫鱼头', thumb: $rawfile('u62.png'), price: 52, originPrice: 55 },
  12.     { title: '黑椒汁啫牛肉', thumb: $rawfile('u76.png'), price: 55, originPrice: 60 },
  13.     { title: '啫啫田鸡', thumb: $rawfile('u90.png'), price: 52, originPrice: 55 },
  14.     { title: '咸蛋黄啫苦瓜', thumb: $rawfile('u104.png'), price: 26, originPrice: 30 }
  15.   ]
  16.   // 定义内联构建函数
  17.   @Builder ImageItems(item: ProductType){
  18.     Row(){
  19.       Column(){
  20.         Image(item.thumb)
  21.           .width("100%")
  22.           .height("100vp")
  23.           .borderRadius(8)
  24.         Text(item.title)
  25.           .width("100%")
  26.           .height("36vp")
  27.           .textOverflow({ overflow: TextOverflow.Ellipsis })
  28.           .fontSize("18fp")
  29.         Row() {
  30.           Text("¥" + item.price)
  31.             .width("40%")
  32.             .fontColor("#ff0000")
  33.             .fontSize("18fp")
  34.             .fontWeight(FontWeight.Bold)
  35.           Text("原价:" + item.originPrice + "元")
  36.             .width("60%")
  37.             .fontColor("#575757")
  38.             .fontSize("12fp")
  39.             .decoration({ type: TextDecorationType.LineThrough, color: "#313030" })
  40.         }
  41.         .width("100%").alignItems(VerticalAlign.Center)
  42.       }
  43.     }.width('100%').padding(10)
  44.   }
  45.   build() {
  46.     Row({ space: "0vp" }) {
  47.       Column() {
  48.         Text("精品特卖")
  49.           .width("100%")
  50.           .height("50vp")
  51.           .fontSize("16fp")
  52.           .fontWeight(FontWeight.Bold)
  53.           .padding(10)
  54.         // 每行分两列展示
  55.         GridRow({columns: 2}){
  56.           ForEach(this.productList, (item: ProductType, index) => {
  57.             GridCol(){
  58.               this.ImageItems(item)
  59.             }
  60.           })
  61.         }
  62.       }.padding(5)
  63.     }
  64.     .width("100%")
  65.   }
  66. }
复制代码
        此时首页就已完成了,结果如下图:

3.6.3 滚动条

        不外此时,各人可能会发现内容超出来屏幕可见地区,无法上拉显示。这个问题比力简单,可以利用List和ListItem组件办理。
        pages/index.ets最终代码如下:
  1. import Header from '../components/Header'
  2. import CarouseMap from '../components/Index/CarouselMap'
  3. import CategoryList from '../components/Index/CategoryList'
  4. import ProductList from '../components/Index/ProductList'
  5. @Entry
  6. @Component
  7. struct Index {
  8.   @State keyword: string = ''
  9.   build() {
  10.     Row() {
  11.       Column() {
  12.         Tabs({
  13.           barPosition: BarPosition.End
  14.         }){
  15.           TabContent(){
  16.             // 增加Column原因是因为TabContent中只有一个子组件,否则会报错
  17.             Column(){
  18.               Header({onSearchChange: this.onSearchChange.bind(this)})    // 顶部导航
  19.               List(){
  20.                 ListItem(){
  21.                   Column(){
  22.                     CarouseMap()        // 轮播图
  23.                     CategoryList()      // 分类列表
  24.                     ProductList()       // 产品列表
  25.                   }
  26.                 }
  27.               }.layoutWeight(1)
  28.             }.width('100%').height('100%').alignItems(HorizontalAlign.Start)
  29.           }.tabBar({icon: $rawfile('u48.png'), text: '首页'})
  30.           TabContent(){
  31.             Text('待开发中...')
  32.           }.tabBar({icon: $rawfile('u43.png'), text: '订单'})
  33.           TabContent(){
  34.             Text('待开发中...')
  35.           }.tabBar({icon: $rawfile('u53.png'), text: '我的'})
  36.         }
  37.         .barMode(BarMode.Fixed)
  38.         .barHeight(60)
  39.       }
  40.       .width('100%')
  41.     }
  42.     .height('100%').alignItems(VerticalAlign.Top)
  43.   }
  44.   /**
  45.    * 搜索内容改变事件
  46.    * @param data
  47.    */
  48.   onSearchChange(data: string){
  49.     console.log('search value:', data)
  50.   }
  51. }
复制代码
        此时页面超出部分则可以上拉检察了,如下图:

        这就是首页全部静态代码了,后期须根据接口数据动态渲染及增长交互功能,这期就不解说了。渴望对各人有所帮助~

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

没腿的鸟

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表