cashier_reserve_app/lib/home/reserve_left_content_view.dart

822 lines
26 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'package:cashier_reserve/common/base/ui.dart';
import 'package:cashier_reserve/common/channel/model/call_log_model.dart';
import 'package:cashier_reserve/common/print/print.dart';
import 'package:cashier_reserve/data_model/reserve/reserve_log_model.dart';
import 'package:cashier_reserve/home/reserve_view_model.dart';
import 'package:easy_refresh/easy_refresh.dart';
import 'package:flutter/cupertino.dart';
class ReserveLeftContentView extends StatelessWidget {
final double contentWidth = 430;
final double inputItemHeight = 36;
final ReserveViewModel provider;
const ReserveLeftContentView({super.key, required this.provider});
@override
Widget build(BuildContext context) {
return SizedBox(
width: contentWidth,
// height: MediaQuery.of(context).size.height,
child: Stack(
children: [
_buildCallLog(context),
_buildBookingWidget(context),
],
),
);
}
Widget _buildBookingWidget(BuildContext context) {
return SizeTransition(
sizeFactor: provider.animationSizeFactor!,
axis: Axis.vertical,
axisAlignment: -1, // 设置为 -1使动画从下往上开始
child: Container(
color: const Color(0xfff5f5f5),
height: MediaQuery.of(context).size.height,
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(
height: 5,
),
Container(
margin: const EdgeInsets.only(left: 15),
child: const Text(
'创建订单',
style: TextStyle(fontSize: 15, color: Color(0xff333333)),
),
),
const SizedBox(
height: 5,
),
_buildNumAndTable(context),
const SizedBox(
height: 10,
),
_buildBookingInfo(context),
const SizedBox(
height: 10,
),
_buildBookingActions(context),
],
),
),
));
}
Widget _buildCallLog(BuildContext context) {
return Column(
children: [
Expanded(
child: SizedBox(
width: contentWidth,
child: EasyRefresh(
onRefresh: () async {
provider.loadCallLog();
yjPrint("onRefresh");
},
child: ListView.builder(
itemCount: provider.callLogs?.length ?? 0,
itemBuilder: (context, index) {
return _buildCallRecordItem(context, provider.callLogs?[index]);
},
),
),
)),
Container(
padding: const EdgeInsets.fromLTRB(20, 10, 20, 15),
child: InkWell(
onTap: () {
provider.showReserveInfoView();
},
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
color: const Color(0xff318AFE),
),
width: 300,
height: inputItemHeight,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Image.asset(
'images/reserve/create.png',
width: 20,
height: 20,
),
const SizedBox(
width: 5,
),
const Text(
"创建订单",
style: TextStyle(color: Colors.white, fontSize: 14),
),
],
),
),
),
)
],
);
}
/// _buildCallRecordItem 通话记录item
Widget _buildCallRecordItem(BuildContext context, CallLogModel? model) {
ReserveLogModel? reserveLogModel =
provider.getReserveLogModel(model?.number ?? "");
return Container(
padding: const EdgeInsets.fromLTRB(15, 15, 15, 5),
child: Column(
children: [
Row(
children: [
Column(
children: [
Image.asset(
(model?.type ?? 0) == 3
? "images/reserve/phone_fail.png"
: "images/reserve/phone_suc.png",
width: 24,
height: 24,
),
const SizedBox(height: 2),
Text(
model?.time ?? "",
style:
const TextStyle(color: Color(0xff999999), fontSize: 12),
),
],
),
const SizedBox(width: 10),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
model?.name ?? "未知电话",
style:
const TextStyle(color: Color(0xff333333), fontSize: 14),
),
const SizedBox(height: 5),
Row(
children: [
Text(
model?.number ?? "",
style: const TextStyle(
color: Color(0xff333333), fontSize: 14),
),
const SizedBox(
width: 15,
),
Text(
"已消费${reserveLogModel?.consumeOrders ?? '0'}",
style: const TextStyle(
color: Color(0xff333333), fontSize: 14),
),
const SizedBox(
width: 15,
),
Text(
"已撤${reserveLogModel?.cancelOrders ?? '0'}",
style: const TextStyle(
color: Color(0xff333333), fontSize: 14),
),
],
),
],
),
const Expanded(child: SizedBox()),
InkWell(
onTap: () {
provider.execCallLog(model);
},
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
border:
Border.all(color: const Color(0xff318AFE), width: 1),
),
padding: const EdgeInsets.fromLTRB(20, 7, 20, 7),
child: const Text(
"处理",
style: TextStyle(color: Color(0xff318AFE), fontSize: 14),
),
),
)
],
),
const SizedBox(
height: 10,
),
Container(
height: 1,
color: const Color(0xffededed),
),
],
),
);
}
/// _buildNumAndTable 就餐人数和桌台
Widget _buildNumAndTable(BuildContext context) {
return Container(
color: Colors.white,
padding: const EdgeInsets.fromLTRB(15, 15, 15, 15),
child: Column(
children: [
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
border: Border.all(color: const Color(0xffededed), width: 1),
),
padding: const EdgeInsets.fromLTRB(10, 5, 10, 5),
height: inputItemHeight,
child: Row(
children: [
const Text(
"就餐人数",
style: TextStyle(color: Color(0xff333333), fontSize: 14),
),
const SizedBox(
width: 10,
),
Expanded(
child: TextField(
controller: provider.bookingNumController,
decoration: InputDecoration(
hintText: "请输入就餐人数",
hintStyle: const TextStyle(
fontSize: 14,
color: Color(0xff999999),
),
contentPadding: EdgeInsets.zero,
border: OutlineInputBorder(
borderSide: BorderSide.none,
borderRadius: BorderRadius.circular(5),
),
),
keyboardType: TextInputType.number,
textAlign: TextAlign.right,
),
),
const SizedBox(
width: 10,
),
const Text(
"",
style: TextStyle(color: Color(0xff333333), fontSize: 14),
),
],
),
),
const SizedBox(
height: 10,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Text(
"请选择桌台",
style: TextStyle(color: Color(0xff333333), fontSize: 14),
),
Text(provider.showTableName,
style:
const TextStyle(color: Color(0xff333333), fontSize: 14)),
],
),
const SizedBox(
height: 5,
),
],
),
);
}
/// _buildBookingInfo 预订信息
Widget _buildBookingInfo(BuildContext context) {
return Container(
color: Colors.white,
padding: const EdgeInsets.fromLTRB(15, 15, 15, 15),
child: Column(
children: [
_buildBookingPhone(context),
const SizedBox(
height: 5,
),
_buildBookingName(context),
const SizedBox(
height: 5,
),
_buildBookingTimeAndType(context),
const SizedBox(
height: 5,
),
_buildBookingAttribute(context),
const SizedBox(
height: 5,
),
_buildBookingTableNum(context),
const SizedBox(
height: 5,
),
_buildBookingStandard(context),
const SizedBox(
height: 5,
),
_buildBookingRemark(context),
],
),
);
}
/// _buildBookingActions 预订操作
Widget _buildBookingActions(BuildContext context) {
return Container(
color: Colors.white,
padding: const EdgeInsets.fromLTRB(15, 5, 15, 15),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
_buildBookingActionBtn(context, "预约", () {
provider.commitReserveInfo();
}),
_buildBookingActionBtn(context, "预约并短信", () {
provider.commitReserveInfo(sendSms: true);
}),
_buildBookingActionBtn(context, "发路线", () {}),
_buildBookingActionBtn(context, "取消", () {
provider.hideReserveInfoView();
}),
],
),
);
}
/// _buildBookingPhone 预订电话
Widget _buildBookingPhone(BuildContext context) {
return Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
border: Border.all(color: const Color(0xffededed), width: 1),
),
padding: const EdgeInsets.fromLTRB(10, 5, 10, 5),
height: inputItemHeight,
child: Row(
children: [
const Text(
"电话",
style: TextStyle(color: Color(0xff333333), fontSize: 14),
),
const SizedBox(
width: 10,
),
Expanded(
child: TextField(
controller: provider.bookingPhoneController,
decoration: InputDecoration(
hintText: "请输入电话",
hintStyle: const TextStyle(
fontSize: 14,
color: Color(0xff999999),
),
contentPadding: EdgeInsets.zero,
border: OutlineInputBorder(
borderSide: BorderSide.none,
borderRadius: BorderRadius.circular(5),
),
),
keyboardType: TextInputType.number,
textAlign: TextAlign.left,
),
),
const SizedBox(
width: 10,
),
],
),
);
}
/// _buildBookingName 预订人
Widget _buildBookingName(BuildContext context) {
return SizedBox(
width: contentWidth - 30,
child: Row(
children: [
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
border: Border.all(color: const Color(0xffededed), width: 1),
),
padding: const EdgeInsets.fromLTRB(10, 5, 10, 5),
height: inputItemHeight,
width: contentWidth - 160,
child: Row(
children: [
const Text(
"姓名",
style: TextStyle(color: Color(0xff333333), fontSize: 14),
),
const SizedBox(
width: 10,
),
Expanded(
child: TextField(
controller: provider.bookingNameController,
decoration: InputDecoration(
hintText: "请输入姓名",
hintStyle: const TextStyle(
fontSize: 14,
color: Color(0xff999999),
),
contentPadding: EdgeInsets.zero,
border: OutlineInputBorder(
borderSide: BorderSide.none,
borderRadius: BorderRadius.circular(5),
),
),
textAlign: TextAlign.left,
),
),
const SizedBox(
width: 10,
),
],
),
),
const SizedBox(
width: 10,
),
// 先生、女士
SizedBox(
width: 120,
child: CupertinoSegmentedControl(
//子标签
children: {
1: Container(
width: 60,
height: inputItemHeight,
alignment: Alignment.center,
child: const Text(
"先生",
style: TextStyle(
fontSize: 14,
// color: Color(0xff333333),
decoration: TextDecoration.none),
),
),
2: Container(
width: 60,
height: inputItemHeight,
alignment: Alignment.center,
child: const Text(
"女士",
style: TextStyle(
fontSize: 14,
// color: Color(0xff333333),
decoration: TextDecoration.none),
),
),
},
//当前选中的索引
groupValue: provider.bookingGender,
//点击回调
onValueChanged: (int index) {
provider.updateBookingGender(index);
},
selectedColor: Colors.blue,
borderColor: Colors.blue,
unselectedColor: Colors.white,
),
),
],
),
);
}
/// _buildBookingTimeAndType 预订时间和类型
Widget _buildBookingTimeAndType(BuildContext context) {
final itemWidth = (contentWidth - 40) / 2;
return Row(
children: [
Container(
width: itemWidth,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
border: Border.all(color: const Color(0xffededed), width: 1),
),
height: inputItemHeight,
padding: const EdgeInsets.fromLTRB(10, 5, 10, 5),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Text("时间",
style: TextStyle(color: Color(0xff666666), fontSize: 14)),
InkWell(
onTap: () async {
TimeOfDay? t = await showTimePicker(
context: context,
initialTime: TimeOfDay.now(),
);
yjPrint(t);
provider.updateBookingTime(t?.hour ?? 0, t?.minute ?? 0);
},
child: (provider.bookingSelectedTime == "")
? const Text(
"请选择时间",
style:
TextStyle(color: Color(0xff999999), fontSize: 14),
)
: Text(
provider.bookingSelectedTime,
style: const TextStyle(
color: Color(0xff333333), fontSize: 14),
),
)
],
),
),
const SizedBox(
width: 10,
),
Container(
width: itemWidth,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
border: Border.all(color: const Color(0xffededed), width: 1),
),
height: inputItemHeight,
padding: const EdgeInsets.fromLTRB(10, 5, 10, 5),
child: Row(
children: [
const Text("类型",
style: TextStyle(color: Color(0xff666666), fontSize: 14)),
const SizedBox(
width: 10,
),
Expanded(
child: TextField(
controller: provider.bookingTypeController,
decoration: InputDecoration(
hintText: "请输入类型",
hintStyle: const TextStyle(
fontSize: 14,
color: Color(0xff999999),
),
contentPadding: EdgeInsets.zero,
border: OutlineInputBorder(
borderSide: BorderSide.none,
borderRadius: BorderRadius.circular(5),
),
),
textAlign: TextAlign.right,
),
),
const SizedBox(
width: 10,
),
],
),
),
],
);
}
/// _buildBookingAttribute 预订属性
Widget _buildBookingAttribute(BuildContext context) {
return Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
border: Border.all(color: const Color(0xffededed), width: 1),
),
padding: const EdgeInsets.fromLTRB(10, 5, 10, 5),
height: inputItemHeight,
width: contentWidth - 30,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
_buildBookingAttrItem(context, "重点关注", provider.bookingFocus,
(value) {
provider.updateBookingAttr("focus", value);
}),
_buildBookingAttrItem(context, "接收营销短信", provider.bookingSms,
(value) {
provider.updateBookingAttr("sms", value);
}),
],
),
);
}
Widget _buildBookingAttrItem(BuildContext context, String name, bool isOpen,
Function(bool) onChanged) {
return Row(
children: [
Text(name,
style: const TextStyle(color: Color(0xff999999), fontSize: 14)),
const SizedBox(width: 5),
Transform.scale(
scale: 0.8, // 调整这个值来改变大小大于1放大小于1缩小
child: CupertinoSwitch(
value: isOpen, onChanged: onChanged, activeColor: Colors.blue),
),
],
);
}
/// _buildBookingTableNum 预订桌台数量
Widget _buildBookingTableNum(BuildContext context) {
return Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
border: Border.all(color: const Color(0xffededed), width: 1),
),
padding: const EdgeInsets.fromLTRB(10, 5, 10, 5),
height: inputItemHeight,
// width: contentWidth - 30,
child: Row(
children: [
const Text(
"摆台桌数(桌)",
style: TextStyle(color: Color(0xff333333), fontSize: 14),
),
const SizedBox(
width: 10,
),
Expanded(
child: TextField(
controller: provider.bookingTableNumController,
decoration: InputDecoration(
hintText: "请输入台桌数",
hintStyle: const TextStyle(
fontSize: 14,
color: Color(0xff999999),
),
contentPadding: EdgeInsets.zero,
border: OutlineInputBorder(
borderSide: BorderSide.none,
borderRadius: BorderRadius.circular(5),
),
),
textAlign: TextAlign.left,
),
),
const SizedBox(
width: 10,
),
],
),
);
}
Widget _buildBookingStandard(BuildContext context) {
final itemWidth = (contentWidth - 40) / 2;
return Row(
children: [
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
border: Border.all(color: const Color(0xffededed), width: 1),
),
padding: const EdgeInsets.fromLTRB(10, 5, 10, 5),
width: itemWidth,
height: inputItemHeight,
child: Row(
children: [
const Text(
"餐标",
style: TextStyle(color: Color(0xff333333), fontSize: 14),
),
const SizedBox(
width: 10,
),
Expanded(
child: TextField(
controller: provider.bookingStandardController,
decoration: InputDecoration(
hintText: "请输入标准",
hintStyle: const TextStyle(
fontSize: 14,
color: Color(0xff999999),
),
contentPadding: EdgeInsets.zero,
border: OutlineInputBorder(
borderSide: BorderSide.none,
borderRadius: BorderRadius.circular(5),
),
),
textAlign: TextAlign.left,
),
),
const SizedBox(
width: 10,
),
],
),
),
const SizedBox(
width: 10,
),
SizedBox(
height: inputItemHeight,
width: itemWidth,
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Radio<String>(
value: "table",
groupValue: provider.bookingStandardType,
onChanged: (String? value) {
provider.updateBookingStandard(value ?? "table");
},
),
const Text(
'元/桌',
style: TextStyle(fontSize: 12, color: Color(0xff666666)),
),
Radio<String>(
value: "person",
groupValue: provider.bookingStandardType,
onChanged: (String? value) {
provider.updateBookingStandard(value ?? "person");
},
),
const Text(
'元/人',
style: TextStyle(fontSize: 12, color: Color(0xff666666)),
),
],
),
)
],
);
}
/// _buildBookingRemark 备注
Widget _buildBookingRemark(BuildContext context) {
return Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
border: Border.all(color: const Color(0xffededed), width: 1),
),
padding: const EdgeInsets.fromLTRB(10, 5, 10, 5),
height: inputItemHeight,
child: Row(
children: [
const Text(
"备注",
style: TextStyle(color: Color(0xff333333), fontSize: 14),
),
const SizedBox(
width: 10,
),
Expanded(
child: TextField(
controller: provider.bookingRemarkController,
decoration: InputDecoration(
hintText: "请输入备注",
hintStyle: const TextStyle(
fontSize: 14,
color: Color(0xff999999),
),
contentPadding: EdgeInsets.zero,
border: OutlineInputBorder(
borderSide: BorderSide.none,
borderRadius: BorderRadius.circular(5),
),
),
textAlign: TextAlign.left,
),
),
const SizedBox(
width: 10,
),
],
),
);
}
Widget _buildBookingActionBtn(
BuildContext context, String title, Function() onTap) {
return InkWell(
onTap: onTap,
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
color: Colors.blue,
),
padding: const EdgeInsets.fromLTRB(20, 5, 20, 5),
child: Text(
title,
style: const TextStyle(color: Colors.white, fontSize: 14),
),
),
);
}
}