【发布时间】:2020-07-23 19:14:20
【问题描述】:
在我有时间回答之前再次发布!
我一直在想这个问题!....我以为我已经破解了它,但似乎没有。所以我正在制作一个简单的预订系统,需要防止重复预订。
所以我使用 Date TicketType Place Plot 之类的变量创建了一个文档,我将这些变量结合起来并插入到 firebase 中。因此,在给定的日期和情节上,一个人可以预订类型为 Day Night,24 小时的票。我已经做到了,所以代码检查了我上面提到的创建的文档。这很有效,因为您无法预订任何同类型的机票。所以我的问题是,如果用户选择日票或夜票,我仍然可以在同一天预订 24 小时票。任何人都可以帮助我一些逻辑或示例代码如何防止这种情况发生。
一些代码
import 'dart:ui';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:intl/intl.dart';
import 'package:swimfinder/Models/swimlakes.dart';
import 'package:swimfinder/common_widgets/provider_widget.dart';
class Booking extends StatefulWidget {
@override
_Booking createState() => _Booking();
final String name;
const Booking({
Key key,
@required this.name,
}) : super(key: key);
}
class _Booking extends State<Booking> {
SwimLake lake = SwimLake();
@override
void initState() {
_loadCurrentUser();
getLakeData();
super.initState();
}
void _loadCurrentUser() {
FirebaseAuth.instance.currentUser().then((FirebaseUser user) {
setState(() {
this.currentUser = user;
});
});
}
getLakeData() async {
await Firestore.instance
.collection('swimfinderlakes')
.document(widget.name)
.get()
.then((result) {
//lake.active = result.data['active'];
lake.address = result.data['address'];
//lake.advert = result.data['advert'];
lake.description = result.data['description'];
lake.email = result.data['email'];
lake.id = result.data['id'];;
lake.name = result.data['name'];
lake.swimplots = result.data['swimplots'];
lake.telephone = result.data['telephone'];
lake.website = result.data['website'];
});
}
FirebaseUser currentUser;
var data;
bool autoValidate = true;
bool readOnly = false;
bool showSegmentedControl = true;
final GlobalKey<FormBuilderState> _fbKey = GlobalKey<FormBuilderState>();
List<String> plots = [];
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: Provider.of(context).auth.getCurrentUser(),
builder: (context, snapshot) {
if (snapshot.hasError) {
return Center(child: CircularProgressIndicator());
} else if (snapshot.connectionState == ConnectionState.done) {
return lakebookingage(context, snapshot);
} else {
return Center(child: CircularProgressIndicator());
}
},
);
}
Widget lakebookingage(context, snapshot) {
return FutureBuilder(
future: getLakeData(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
plots = lake.swimplots.split(',');
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text(
lake.name,
style: TextStyle(
fontSize: 18.0,
fontWeight: FontWeight.w700,
color: Colors.white,
),
),
backgroundColor: Color.fromRGBO(70, 109, 69, 1.0),
automaticallyImplyLeading: false,
leading: IconButton(
icon: Icon(
Icons.keyboard_backspace,
),
onPressed: () => Navigator.pop(context),
),
),
body: Stack(children: <Widget>[
Container(
constraints: BoxConstraints.expand(),
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage(lake.mainimage),
fit: BoxFit.cover,
),
),
child: ClipRRect(
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 1, sigmaY: 1),
child: Container(
alignment: Alignment.center,
color: Colors.white.withOpacity(0.6),
),
),
),
),
Center(
child: FormBuilder(
key: _fbKey,
initialValue: {
'bookedondata': DateTime.now(),
'emailaddr': currentUser.email,
'lake': lake.name,
'mainimage': lake.mainimage,
'dismissed': false,
'reviewed': false,
'uid': currentUser.uid,
//'accept_terms': false,
},
autovalidate: true,
child: Padding(
padding: const EdgeInsets.all(10.0),
child: Column(
children: <Widget>[
Container(height: 20),
FormBuilderDateTimePicker(
attribute: "bookedfordate",
firstDate: DateTime.now(),
resetIcon: null,
inputType: InputType.date,
validators: [
FormBuilderValidators.required()
],
format: DateFormat("dd-MM-yyyy"),
decoration: InputDecoration(
labelText: "Reservation Date",
labelStyle: TextStyle(
color: Colors.black,
fontSize: 15,
fontWeight: FontWeight.w900,
),
),
),
Container(height: 20),
FormBuilderDropdown(
attribute: "tickettype",
decoration: InputDecoration(
labelText: "Ticket Type",
labelStyle: TextStyle(
color: Colors.black,
fontSize: 20,
fontWeight: FontWeight.w900,
),
),
// initialValue: 'Male',
hint: Text('Day/Night/24Hour'),
validators: [
FormBuilderValidators.required()
],
items: ['Day', 'Night', '24Hour']
.map((ticket) => DropdownMenuItem(
value: ticket,
child: Text("$ticket")))
.toList(),
),
Container(height: 20),
FormBuilderDropdown(
attribute: "swimplot",
decoration: InputDecoration(
labelText: "Select Swim",
labelStyle: TextStyle(
color: Colors.black,
fontSize: 20,
fontWeight: FontWeight.w900,
),
),
// initialValue: 'Male',
hint:
Text('Which pitch do you wish to choose'),
validators: [
FormBuilderValidators.required()
],
items: plots
.map((ticket) => DropdownMenuItem(
value: ticket,
child: Text("$ticket")))
.toList(),
),
Container(height: 20),
RaisedButton.icon(
icon: Icon(
Icons.search,
color: Colors.white,
size: 30,
),
label: Text("Book",
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 20,
)),
onPressed: () {
_bookswim();
},
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(10.0))),
color: Color.fromRGBO(70, 109, 69, 1.0),
),
],
),
),
),
),
])));
} else {
return CircularProgressIndicator();
}
});
}
void getDocument() {
Firestore.instance
.collection('bookings')
.where("bookedfordate", isEqualTo: DateTime.now())
.limit(1)
.getDocuments()
.then(
(value) {
if (value.documents.length > 0) {
//return _myClassFromSnapshot(value.documents[0]);
} else {
//return _bookswim
return null;
}
},
);
}
void _bookswim() {
//getDocument();
_fbKey.currentState.save();
if (_fbKey.currentState.validate()) {
String combine = ((DateFormat('yyyyMMdd')
.format(_fbKey.currentState.value['bookedfordate'])) +
(_fbKey.currentState.value['swimplot']) +
(_fbKey.currentState.value['tickettype']) +
(widget.name.replaceAll(RegExp(' '), '')));
Firestore.instance
.collection("bookings")
.document(combine)
.get()
.then((doc) {
if (!doc.exists) {
Firestore.instance.collection('bookings').document(combine).setData({
'bookedfordate': _fbKey.currentState.value['bookedfordate'],
'emailaddr': _fbKey.currentState.value['emailaddr'],
'lake': _fbKey.currentState.value['lake'],
'mainimage': _fbKey.currentState.value['mainimage'],
'dismissed': _fbKey.currentState.value['dismissed'],
'reviewed': _fbKey.currentState.value['reviewed'],
'uid': _fbKey.currentState.value['uid'],
'bookedondata': _fbKey.currentState.value['bookedondata'],
'tickettype': _fbKey.currentState.value['tickettype'],
'swimplot': _fbKey.currentState.value['swimplot']
});
_showDialog();
} else {
_showMyDialog();
}
});
}
}
Future<void> _showMyDialog() async {
return showDialog<void>(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return AlertDialog(
title: Text('SwimFinder'),
content: SingleChildScrollView(
child: ListBody(
children: <Widget>[
Text('Sorry this Swim in already booked!'),
],
),
),
actions: <Widget>[
FlatButton(
child: Text('close'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
void _showDialog() {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: new Text("SwimFinder",
style: TextStyle(
color: Color.fromRGBO(70, 109, 69, 1.0),
fontSize: 20,
)),
content: new Text("Thank you for your booking!",
style: TextStyle(
color: Color.fromRGBO(70, 109, 69, 1.0),
fontSize: 20,
)),
actions: <Widget>[
new FlatButton(
child: new Text("Close"),
onPressed: () {
Navigator.popUntil(context, ModalRoute.withName('/'));
},
),
],
);
},
);
}
}
因此,如果用户选择 24 小时票,则在某次游泳和某个情节中使用 1 天。在此之后 Day 和 Night 票应该告诉用户不可用。日票和夜票可以在同一天预订,因为这是 24 小时,但可以为 2 个不同的用户。
我希望我的代码更有意义
【问题讨论】:
-
请不要再问一个封闭的问题。对您现有的封闭式问题进行编辑。如果您的修改解决了原始问题,它将重新打开。
-
它不是没有意义的代码,你的话,我显然无法理解这个想法
-
好的,想象一下有一家有 5 间客房的酒店。客房仅可预订白天、夜间或 24 小时。从我的代码中,您可以看到如果我预订白天,我不能再次预订白天,晚上和 24 小时也一样。但是,如果用户先预订白天或晚上,仍然可以预订 24 小时......我希望这是有道理的
-
@neuromancer 你有什么建议吗?
-
给定一天中的 24 小时,定义您认为白天和黑夜的一天中的什么时间