一、 前言

随着HarmonyOS生态的不断发展,越来越多的开发者开始投入到鸿蒙原生应用的开发中。本文将详细介绍一个完整的电影购票应用的开发过程,涵盖用户管理、电影展示、影院选择、座位预订、订单处理等多个功能模块,帮助开发者快速掌握HarmonyOS应用开发的核心技术和最佳实践。

二、项目概述

这个电影购票应用基于HarmonyOS开发框架,使用ArkTS语言和声明式UI语法,实现了从用户注册登录到购票评价的完整业务流程。项目采用模块化架构设计,具有良好的可维护性和扩展性。

三、 项目结构

├── AppScope # 应用全局资源
├── entry # 应用主模块
│ ├── src/main/ets/ # 源代码目录
│ │ ├── api/ # API接口配置
│ │ ├── component/ # UI组件
│ │ ├── pages/ # 页面组件
│ │ ├── model/ # 数据模型
│ │ └── http/ # 网络请求封装
│ └── resources/ # 资源文件

四、 功能模块分析

1. 页面组件
  • SplashPage.ets - 启动页
  • Index.ets - 主页/导航页
  • LoginPage.ets - 登录页
  • RegisterPage.ets - 注册页
  • MovieDetailsPage.ets - 电影详情页
  • CinemaListPage.ets - 影院列表页
  • SelectedDatePage.ets - 日期选择页
  • SeatTablePage.ets - 座位选择页
  • OrderListPage.ets - 订单列表页
  • PaySuccessPage.ets - 支付成功页
  • CommentPage.ets - 影评页
  • EditInfoPage.ets - 编辑信息页
  • SearchPage.ets - 搜索页
2. 底部导航栏
  • HomeComponent.ets - 首页组件,包含轮播图和推荐电影列表
  • HotComponent.ets - 热门电影组件,展示评分高于8.5的电影
  • CategoryComponent.ets - 分类电影库组件,按类型分类展示电影
  • MineComponent.ets - 我的页面组件,包含用户信息和个人功能入口
  • TopBarComponent.ets - 通用顶部导航栏组件

五、核心业务功能模块总结

1. 用户管理模块
  • 注册功能:RegisterPage.ets - 提供用户注册功能,包含用户名、手机号、密码等字段验证
  • 登录功能:LoginPage.ets - 提供用户登录功能,支持记住密码
  • 个人信息管理:EditInfoPage.ets - 用户可编辑个人资料,包括用户名、昵称、手机号等
  • 退出登录:在MineComponent.ets中实现
2. 电影展示模块
  • 首页推荐:HomeComponent.ets - 包含轮播图和推荐电影列表
  • 热门电影:HotComponent.ets - 展示评分高于8.5的热门电影
  • 电影分类:CategoryComponent.ets - 按类型分类展示电影
  • 电影详情:MovieDetailsPage.ets - 展示电影详细信息,包括海报、评分、演员、简介和用户评论
  • 电影搜索:SearchPage.ets - 提供按电影名称模糊搜索功能
3. 影院管理模块
  • 影院列表:CinemaListPage.ets - 展示所有影院信息,包括影院名称、地址和特色
  • 日期选择:SelectedDatePage.ets - 允许用户选择观影日期和场次
  • 座位选择:SeatTablePage.ets - 提供可视化座位选择功能,区分可选、已售、已选状态
4. 订单处理模块
  • 订单创建:在SeatTablePage.ets中调用API创建订单
  • 订单列表:OrderListPage.ets - 展示用户的订单历史,包含取消订单功能
  • 支付成功:PaySuccessPage.ets - 订单支付成功后的确认页面
  • 影评功能:CommentPage.ets - 用户可以对已完成的订单进行评价和评分
5. 功能模块关系图

启动页(Splash) -> 主页(Index) -> 首页(Home)/热门(Hot)/影库(Category)/我的(Mine)
|
v
登录/注册 -> 电影详情 -> 影院列表 -> 日期选择 -> 座位选择 -> 订单确认 -> 支付成功
|
v
我的页面 -> 订单列表 -> 写影评/取消订单

六、 技术特点

  • 基于OpenHarmony开发:使用ArkTS语言和声明式UI语法
  • 模块化架构:页面、组件、模型、API等分离设计
  • 响应式UI:使用@State、@StorageLink等装饰器实现数据驱动
  • HTTP客户端:集成API接口调用功能(springBoot+MyBaits框架搭建后端,编写API接口)
  • 路由管理:页面间导航和参数传递
  • 本地存储:用户信息持久化存储
  • 动画效果:启动页动画、UI过渡效果等

七、 部分核心功能模块详解

1. 登录页面实现

用户管理是应用的基础功能,包括注册、登录、个人信息管理等。

// LoginPage.ets
import { ApiConfig } from '../api/ApiConfig';
import { get } from '../http/HttpClient';
import { UserInfo } from '../model/UserInfo';

@Entry
@Component
struct LoginPage {
  @State username: string = '';
  @State password: string = '';
  @State rememberMe: boolean = false;
  @State isInputValid: boolean = false;

  // 登录处理函数
  async onLogin() {
    this.isInputValid = false;
    const res = await get(ApiConfig.LOGIN_URL, { 
      params: { "username": this.username, "password": this.password } 
    });
    
    if (res.success) {
      const userInfo = res.data as UserInfo;
      // 存储用户信息到本地存储
      AppStorage.setOrCreate('userInfo', userInfo);
      
      // 保存密码(如果勾选记住密码)
      if (this.rememberMe) {
        // 保存到数据偏好
      }
      
      // 跳转到主页
      this.getUIContext().getRouter().back();
    } else {
      // 显示错误信息
      this.getUIContext().getPromptAction().showToast({
        message: res.msg,
      });
    }
  }
  
  build() {
    // UI构建
  }
}
2. 电影展示系统

电影展示系统包括首页推荐、热门电影、分类浏览等功能。

首页组件实现

// HomeComponent.ets
@Component
export struct HomeComponent {
  @State bannerList: BannerInfo[] = [];
  @State movieList: MovieInfo[] = [];

  aboutToAppear(): void {
    // 获取首页轮播图
    this.getHomeBanner();
    // 获取首页推荐电影
    this.getHomeRecommend();
  }

  /**
   * 获取首页轮播图
   */
  async getHomeBanner() {
    const res = await get(ApiConfig.GET_BANNER_URL);
    if (res && res.businessCode === 200) {
      const bannerResult = res.data as BannerResult;
      this.bannerList = bannerResult.list;
    }
  }

  build() {
    Column() {
      TopBarComponent({
        title: "首页",
        isBack: false
      })
      
      // 轮播图
      Swiper() {
        ForEach(this.bannerList, (item: BannerInfo) => {
          Image(item.banner_img)
            .width('100%')
            .height('100%')
            .objectFit(ImageFit.Cover)
        })
      }
      .height(200)
      .loop(true)
      .autoPlay(true)
      .interval(3000)
      .borderRadius(12)

      // 推荐电影列表
      Grid() {
        ForEach(this.movieList, (item: MovieInfo) => {
          GridItem() {
            GridItemComponent({ movieInfo: item });
          }
          .onClick(() => {
            this.getUIContext().getRouter().pushUrl({
              url: 'pages/MovieDetailsPage',
              params: item
            })
          })
        })
      }
      .columnsTemplate('1fr 1fr 1fr')
    }
  }
}
3. 影院选择与座位预订

这是应用的核心功能之一,涉及复杂的交互逻辑。

座位选择页面实现

// SeatTablePage.ets
enum SeatStatus {
  AVAILABLE = 0, // 可选
  SOLD = 1,      // 已售
  SELECTED = 2   // 已选
}

interface SeatInfo {
  row: number;     // 排数
  column: number;  // 列数
  status: SeatStatus; // 座位状态
}

@Entry
@Component
struct SeatTablePage {
  @State seats: SeatInfo[][] = [];
  @State selectedSeats: SeatInfo[] = [];
  private maxSelectCount: number = 3;

  /**
   * 处理座位点击事件
   */
  private handleSeatClick(seat: SeatInfo) {
    // 如果座位已售,则不能选择
    if (this.isSeatStatusEqual(seat.status, SeatStatus.SOLD)) {
      return;
    }

    // 如果座位已经被选中,则取消选择
    if (this.isSeatStatusEqual(seat.status, SeatStatus.SELECTED)) {
      // 更新座位状态
      const newSeats = [...this.seats];
      newSeats[seat.row - 1][seat.column - 1].status = SeatStatus.AVAILABLE;
      this.seats = newSeats;

      // 从已选座位数组中移除
      this.selectedSeats = this.selectedSeats.filter(
        s => !(s.row === seat.row && s.column === seat.column)
      );
      return;
    }

    // 如果当前已选座位数量达到最大限制,则不能再选择
    if (this.selectedSeats.length >= this.maxSelectCount) {
      this.getUIContext().getPromptAction().showToast({
        message: `最多只能选择${this.maxSelectCount}个座位`
      });
      return;
    }

    // 选择座位
    const newSeats = [...this.seats];
    newSeats[seat.row - 1][seat.column - 1].status = SeatStatus.SELECTED;
    this.seats = newSeats;

    this.selectedSeats.push({...seat, status: SeatStatus.SELECTED});
  }

  build() {
    Column() {
      // 座位图
      Scroll() {
        Column() {
          ForEach(this.seats, (row: SeatInfo[], rowIndex: number) => {
            Row() {
              // 排号标签
              Text(`${rowIndex + 1}`)
                .fontSize(10)
                .fontColor('#999999')

              // 座位
              ForEach(row, (seat: SeatInfo, colIndex: number) => {
                Column() {
                  Text(`${colIndex + 1}`)
                    .width(24)
                    .height(24)
                    .borderRadius(3)
                    .backgroundColor(this.getSeatColorByStatus(seat.status))
                    .onClick(() => {
                      this.handleSeatClick(seat);
                    })
                }
              })
            }
          })
        }
      }

      // 底部信息栏
      Column() {
        // 已选座位信息
        if (this.selectedSeats.length > 0) {
          Text(`已选座位: ${this.selectedSeats.map(seat => `${seat.row}${seat.column}`).join('、 ')}`)
            .fontColor('#e22418')
        }
        
        // 确认按钮
        Button('确认选座')
          .enabled(this.selectedSeats.length > 0)
          .onClick(() => {
            // 处理确认选座
          })
      }
    }
  }
}
4. 订单管理系统

订单管理涉及订单创建、查询、取消等功能。

订单列表页面实现

// OrderListPage.ets
@Entry
@Component
struct OrderListPage {
  @StorageLink('userInfo') userInfo: UserInfo;
  @State orderList: OrderInfo[] = [];

  aboutToAppear(): void {
    // 查询订单列表
    this.queryOrderList();
  }

  /**
   * 查询订单列表
   */
  async queryOrderList() {
    const res = await get(ApiConfig.GET_ORDER_LIST_URL, { 
      params: { "username": this.userInfo.username } 
    });
    if (res.success) {
      const orderResult = res.data as OrderResult;
      this.orderList = orderResult.list;
    }
  }

  /**
   * 格式化座位显示
   */
  formatSeats(seats: string) {
    if (seats) {
      const seatArr = seats.split('-');
      return seatArr.map(seat => {
        const [row, col] = seat.split(',');
        return `${row}${col}`;
      }).join('、');
    }
    return '';
  }

  build() {
    Column() {
      TopBarComponent({
        title: '我的订单',
      })

      if (this.orderList.length == 0) {
        // 空订单提示
        EmptyComponent({
          title: '暂无订单',
          subTitle: '赶紧去下单吧~'
        })
      } else {
        List() {
          ForEach(this.orderList, (item: OrderInfo) => {
            ListItem() {
              Column() {
                // 订单头部 - 电影信息
                Row() {
                  Image(item.movie_cover ?? $r('app.media.img_logo'))
                    .width(90)
                    .height(110)
                  
                  Column() {
                    Text(item.movie_name)
                      .fontSize(16)
                      .fontWeight(FontWeight.Bold)
                    
                    Text(`${item.movie_date} ${item.movie_time}`)
                      .fontSize(14)
                      .fontColor('#666666')
                      
                    Text(this.formatSeats(item.seat_num))
                      .fontSize(14)
                      .fontColor('#333333')
                  }
                }

                // 订单底部 - 操作按钮
                Row() {
                  Text(`订单号: ${item.order_number}`)
                    .fontSize(12)
                    .fontColor('#999999')
                  
                  Row() {
                    // 取消订单按钮
                    Text('取消订单')
                      .onClick(() => {
                        // 显示确认对话框
                      })
                    
                    // 写影评按钮
                    Text('写影评')
                      .onClick(() => {
                        this.getUIContext().getRouter().pushUrl({
                          url: `pages/CommentPage`,
                          params: item
                        });
                      })
                  }
                }
              }
            }
          })
        }
      }
    }
  }
}

八、总结

通过本文的介绍,我们详细展示了如何使用HarmonyOS开发一个功能完整的电影购票应用。项目涵盖了现代移动应用开发的主要技术点,包括状态管理、网络请求、路由导航、UI设计等。希望这篇文章能够帮助开发者更好地理解和掌握HarmonyOS应用开发技术,为构建更优秀的鸿蒙应用贡献力量。

HarmonyOS作为新一代操作系统,其分布式特性和流畅的用户体验为开发者提供了广阔的创新空间。随着生态的不断完善,相信会有更多优秀的鸿蒙原生应用涌现,为用户带来更好的服务体验。

作者注:本文所展示的代码片段仅为示例,实际项目中包含更多细节和错误处理逻辑。

九、 项目效果截图

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐