Flutter Templates
如何使用Flutter和Back4App构建事件预订应用程序
32 分
介绍 在当今快节奏的世界中,通过移动应用程序管理活动和预订变得越来越重要。活动预订应用程序允许用户浏览即将举行的活动、预订门票、选择座位并无缝管理他们的预订。在本教程中,您将学习如何使用flutter创建一个完整的活动预订应用程序,并使用back4app作为后端服务。 在本教程结束时,您将构建一个功能齐全的应用程序,能够 显示带有详细信息的活动列表。 允许用户查看活动时间表和场地信息。 支持选择座位的门票预订。 安全处理支付(与支付网关集成)。 管理用户个人资料,包括预订历史和偏好。 让我们开始吧! 先决条件 要完成本教程,您需要: flutter sdk 安装在您的本地机器上。请遵循官方 flutter 安装指南 https //flutter dev/docs/get started/install dart 和 flutter 的基本知识 。如果您是 flutter 新手,请考虑查看 flutter 的入门教程 https //flutter dev/docs/get started/codelab 一个 back4app 账户 。在 back4app https //www back4app com/ 注册一个免费账户。 back4app flutter sdk 集成到您的项目中。您可以通过遵循 back4app flutter 指南 https //www back4app com/docs/flutter/parse sdk/flutter setup 来了解如何设置它。 一个代码编辑器 ,如 visual studio code 或 android studio。 node js 和 npm 安装以运行 back4app 云函数。从 官方 node js 网站 https //nodejs org/ 安装它们。 步骤 1 – 设置 back4app 后端 在此步骤中,您将设置您的 back4app 项目,创建必要的类(表),并配置后端以存储事件数据、票务信息和用户资料。 1 1 创建一个新的 back4app 应用程序 登录到您的 back4app 账户。 点击 "创建新应用" 输入一个 应用名称 (例如,"eventbookingapp")并选择您的 应用图标 点击 "创建" 1 2 配置应用密钥 导航到您的应用的 仪表板 点击 "应用设置" > "安全与密钥" 记下 应用 id 和 客户端密钥 。您将需要这些来初始化 flutter 应用中的 parse sdk。 1 3 定义数据模型 您需要在 back4app 中创建以下类: 事件 存储事件详细信息。 场地 存储场地信息。 票务 管理票务可用性和预订。 用户 管理用户档案(默认类)。 创建事件类 在左侧边栏中,点击 "数据库" 以打开数据浏览器。 点击 "创建一个类" 。 选择 "自定义" , 输入 "事件" 作为类名,然后点击 "创建类" 。 向 事件 类添加以下列: 名称 (字符串) 描述 (字符串) 日期 (日期) 图片 (文件) 场地 (指向场地) 价格 (数字) 创建场地类 重复步骤以创建一个名为 "场地" 的新类。 添加以下列: 名称 (字符串) 地址 (字符串) 容量 (数字) 座位图 (文件) 创建票务类 创建一个名为 "ticket" 的新类。 添加以下列: 事件 (指向事件的指针) 用户 (指向用户的指针) 座位号 (字符串) 价格 (数字) 是否已预订 (布尔值) 1 4 启用用户身份验证 在左侧边栏中,点击 "服务器设置" > "常规设置" 在 "身份验证" , 确保 "启用类级权限" 被选中。 配置 用户 类权限,以允许用户注册和登录。 1 5 设置云函数(可选用于支付处理) 对于支付集成,您可能需要编写云函数。此步骤将取决于您选择的支付网关(例如,stripe,paypal)。请参考 back4app 的文档,了解 云代码函数 https //www back4app com/docs/platform/parse cloudcode 步骤 2 – 初始化 flutter 项目 在此步骤中,您将设置 flutter 项目并集成 back4app parse sdk。 2 1 创建一个新的 flutter 项目 打开终端并运行 flutter create event booking app 导航到项目目录 cd event booking app 2 2 添加依赖项 打开 pubspec yaml 并添加以下依赖项 dependencies flutter sdk flutter cupertino icons ^1 0 2 parse server sdk flutter ^4 0 1 provider ^6 0 0 \# add any additional packages you need, e g , http, image picker, etc 运行 flutter pub get 来安装这些包。 2 3 初始化 parse sdk 在 lib/main dart , 导入必要的包并初始化 parse import 'package\ flutter/material dart'; import 'package\ parse server sdk flutter/parse server sdk dart'; void main() async { widgetsflutterbinding ensureinitialized(); const keyapplicationid = 'your back4app application id'; const keyclientkey = 'your back4app client key'; const keyparseserverurl = 'https //parseapi back4app com'; await parse() initialize( keyapplicationid, keyparseserverurl, clientkey keyclientkey, debug true, autosendsessionid true, ); runapp(myapp()); } class myapp extends statelesswidget { // build your app's ui here } 替换 'your back4app application id' 和 'your back4app client key' 为您在 back4app 上的实际密钥。 步骤 3 – 实现用户认证 用户需要注册和登录才能预订活动和管理他们的个人资料。 3 1 创建认证界面 在 lib/ 创建两个新的 dart 文件。 login screen dart signup screen dart 登录屏幕 dart import 'package\ flutter/material dart'; import 'package\ parse server sdk flutter/parse server sdk dart'; class loginscreen extends statefulwidget { @override loginscreenstate createstate() => loginscreenstate(); } class loginscreenstate extends state\<loginscreen> { final texteditingcontroller usernamecontroller = texteditingcontroller(); final texteditingcontroller passwordcontroller = texteditingcontroller(); void douserlogin() async { final username = usernamecontroller text trim(); final password = passwordcontroller text trim(); final user = parseuser(username, password, null); var response = await user login(); if (response success) { // navigate to home screen navigator pushreplacementnamed(context, '/home'); } else { // show error message showerror(response error! message); } } void showerror(string message) { // implement a method to show error messages } @override widget build(buildcontext context) { // build your login ui here } } 注册屏幕 dart import 'package\ flutter/material dart'; import 'package\ parse server sdk flutter/parse server sdk dart'; class signupscreen extends statefulwidget { @override signupscreenstate createstate() => signupscreenstate(); } class signupscreenstate extends state\<signupscreen> { final texteditingcontroller usernamecontroller = texteditingcontroller(); final texteditingcontroller passwordcontroller = texteditingcontroller(); void douserregistration() async { final username = usernamecontroller text trim(); final password = passwordcontroller text trim(); final user = parseuser(username, password, null); var response = await user signup(); if (response success) { // navigate to home screen navigator pushreplacementnamed(context, '/home'); } else { // show error message showerror(response error! message); } } void showerror(string message) { // implement a method to show error messages } @override widget build(buildcontext context) { // build your sign up ui here } } 3 2 更新 main dart 以添加路由 class myapp extends statelesswidget { @override widget build(buildcontext context) { return materialapp( title 'event booking app', initialroute '/login', routes { '/login' (context) => loginscreen(), '/signup' (context) => signupscreen(), '/home' (context) => homescreen(), // add other routes as needed }, ); } } 3 3 实现主屏幕 创建一个 home screen dart 文件,已认证用户将被重定向到该文件。 import 'package\ flutter/material dart'; class homescreen extends statelesswidget { @override widget build(buildcontext context) { // build your home screen ui here } } 步骤 4 – 显示事件 从 back4app 获取事件并将其显示在列表中。 4 1 创建事件模型 创建一个 dart 类 event dart 在 lib/models/ 中。 import 'package\ parse server sdk flutter/parse server sdk dart'; class event extends parseobject implements parsecloneable { event() super( keytablename); event clone() this(); static const string keytablename = 'event'; static const string keyname = 'name'; static const string keydescription = 'description'; static const string keydate = 'date'; static const string keyimage = 'image'; static const string keyvenue = 'venue'; static const string keyprice = 'price'; @override clone(map\<string, dynamic> map) => event clone() fromjson(map); string? get name => get\<string>(keyname); string? get description => get\<string>(keydescription); datetime? get date => get\<datetime>(keydate); parsefilebase? get image => get\<parsefilebase>(keyimage); parseobject? get venue => get\<parseobject>(keyvenue); double? get price => get\<double>(keyprice); } 4 2 在主页屏幕中获取事件 在 home screen dart , 获取事件并显示它们。 import 'package\ flutter/material dart'; import 'models/event dart'; import 'package\ parse server sdk flutter/parse server sdk dart'; class homescreen extends statefulwidget { @override homescreenstate createstate() => homescreenstate(); } class homescreenstate extends state\<homescreen> { future\<list\<event>> getevents() async { querybuilder\<event> queryevents = querybuilder\<event>(event()) orderbydescending('date'); final parseresponse apiresponse = await queryevents query(); if (apiresponse success && apiresponse results != null) { return apiresponse results as list\<event>; } else { return \[]; } } @override widget build(buildcontext context) { return scaffold( appbar appbar( title text('events'), ), body futurebuilder\<list\<event>>( future getevents(), builder (context, snapshot) { if (snapshot hasdata) { list\<event> events = snapshot data!; return listview\ builder( itemcount events length, itembuilder (context, index) { event event = events\[index]; return listtile( title text(event name ?? 'no title'), subtitle text(event date? tolocal() tostring() ?? ''), ontap () { // navigate to event details navigator push( context, materialpageroute( builder (context) => eventdetailsscreen(event event), ), ); }, ); }, ); } else if (snapshot haserror) { return center(child text('error loading events')); } else { return center(child circularprogressindicator()); } }, ), ); } } 4 3 创建事件详情屏幕 创建 event details screen dart import 'package\ flutter/material dart'; import 'models/event dart'; class eventdetailsscreen extends statelesswidget { final event event; eventdetailsscreen({required this event}); void bookticket(buildcontext context) { // implement ticket booking logic navigator push( context, materialpageroute( builder (context) => seatselectionscreen(event event), ), ); } @override widget build(buildcontext context) { // build ui to display event details return scaffold( appbar appbar( title text(event name ?? 'event details'), ), body column( children \[ // display event image, description, date, venue, etc text(event description ?? ''), elevatedbutton( onpressed () => bookticket(context), child text('book ticket'), ), ], ), ); } } 步骤 5 – 实施座位选择 允许用户在预订之前选择座位。 5 1 创建座位选择屏幕 创建 seat selection screen dart import 'package\ flutter/material dart'; import 'models/event dart'; class seatselectionscreen extends statelesswidget { final event event; seatselectionscreen({required this event}); // mock data for seats final list\<string> seats = list generate(100, (index) => 'seat ${index + 1}'); @override widget build(buildcontext context) { // build ui for seat selection return scaffold( appbar appbar( title text('select seats'), ), body gridview\ builder( griddelegate slivergriddelegatewithfixedcrossaxiscount( crossaxiscount 5, ), itemcount seats length, itembuilder (context, index) { string seat = seats\[index]; return gesturedetector( ontap () { // handle seat selection // navigate to payment screen navigator push( context, materialpageroute( builder (context) => paymentscreen(event event, seat seat), ), ); }, child card( child center(child text(seat)), ), ); }, ), ); } } 步骤 6 – 处理支付 集成支付网关以安全处理票务支付。 6 1 选择支付网关 在本教程中,我们将假设使用 stripe https //stripe com/docs/payments 6 2 设置 stripe 账户并获取 api 密钥 注册一个 stripe 账户 https //dashboard stripe com/register 获取你的 可发布密钥 和 秘密密钥 6 3 添加 stripe 依赖 将 stripe payment 包添加到你的 pubspec yaml dependencies stripe payment ^1 0 9 运行 flutter pub get 6 4 实现支付界面 创建 payment screen dart import 'package\ flutter/material dart'; import 'package\ stripe payment/stripe payment dart'; import 'models/event dart'; class paymentscreen extends statefulwidget { final event event; final string seat; paymentscreen({required this event, required this seat}); @override paymentscreenstate createstate() => paymentscreenstate(); } class paymentscreenstate extends state\<paymentscreen> { void initstate() { super initstate(); stripepayment setoptions( stripeoptions( publishablekey 'your stripe publishable key', // optionally set other options ), ); } void startpayment() async { // implement payment logic // create payment method paymentmethod paymentmethod = await stripepayment paymentrequestwithcardform( cardformpaymentrequest(), ); // process the payment using a cloud function or your server // for simplicity, we'll assume payment is successful saveticket(); } void saveticket() async { // save ticket information to back4app final ticket = parseobject('ticket') set('event', widget event) set('user', await parseuser currentuser()) set('seatnumber', widget seat) set('price', widget event price) set('isbooked', true); await ticket save(); // navigate to confirmation screen or display success message } @override widget build(buildcontext context) { // build payment ui return scaffold( appbar appbar( title text('payment'), ), body center( child elevatedbutton( onpressed startpayment, child text('pay \\$${widget event price}'), ), ), ); } } 注意 支付处理需要安全处理敏感数据。在生产应用中,您应该使用自己的服务器或云函数安全地处理支付。 步骤 7 – 管理用户资料 允许用户查看和管理他们的预订和偏好。 7 1 创建个人资料屏幕 创建 profile screen dart import 'package\ flutter/material dart'; import 'package\ parse server sdk flutter/parse server sdk dart'; class profilescreen extends statelesswidget { future\<list\<parseobject>> getusertickets() async { final user = await parseuser currentuser(); querybuilder\<parseobject> querytickets = querybuilder\<parseobject>(parseobject('ticket')) whereequalto('user', user) includeobject(\['event']); final parseresponse apiresponse = await querytickets query(); if (apiresponse success && apiresponse results != null) { return apiresponse results as list\<parseobject>; } else { return \[]; } } @override widget build(buildcontext context) { // build profile ui return scaffold( appbar appbar( title text('my profile'), ), body futurebuilder\<list\<parseobject>>( future getusertickets(), builder (context, snapshot) { if (snapshot hasdata) { list\<parseobject> tickets = snapshot data!; return listview\ builder( itemcount tickets length, itembuilder (context, index) { parseobject ticket = tickets\[index]; parseobject event = ticket get('event'); return listtile( title text(event get\<string>('name') ?? 'no event name'), subtitle text('seat ${ticket get\<string>('seatnumber')}'), ); }, ); } else if (snapshot haserror) { return center(child text('error loading tickets')); } else { return center(child circularprogressindicator()); } }, ), ); } } 7 2 向个人资料屏幕添加导航 在你的 home screen dart 或主导航抽屉中,添加一个指向个人资料屏幕的链接。 iconbutton( icon icon(icons person), onpressed () { navigator push( context, materialpageroute(builder (context) => profilescreen()), ); }, ), 第8步 – 测试应用程序 使用以下命令运行您的应用程序 flutter run 测试以下功能 注册和登录 查看事件列表 查看事件详情 选择座位并继续付款 处理付款(如果可能,使用测试模式)。 在个人资料中查看预订 结论 恭喜!您已经使用 flutter 和 back4app 构建了一个完整的事件预订应用程序。该应用程序允许用户浏览事件、选择座位预订票、处理支付以及管理他们的个人资料和预订。 从这里开始,您可以通过以下方式增强您的应用程序: 添加推送通知以提醒事件。 实现事件的搜索和过滤。 通过更好的设计和动画增强 ui/ux。 通过服务器端验证确保支付处理的安全性。 有关 flutter 和 back4app 功能的更多信息,请查看: flutter 文档 https //flutter dev/docs back4app 文档 https //www back4app com/docs parse server 云代码指南 https //docs parseplatform org/cloudcode/guide/ 通过将 flutter 与 back4app 集成,您可以高效地利用强大的组合来构建可扩展、功能丰富的移动应用程序。