Files
tuiche/lib/pages/mh_page/device/mht_people_info.dart
2025-07-30 16:48:48 +08:00

661 lines
31 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 'dart:async';
import 'package:ef/ef.dart';
import 'package:flutter/material.dart';
import 'package:flutterflow_ui/flutterflow_ui.dart';
import 'package:intl/intl.dart';
import 'package:vbvs_app/common/color/ServiceConstant.dart';
import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/common/util/MyUtils.dart';
import 'package:vbvs_app/common/util/requestWithLog.dart';
import 'package:vbvs_app/component/tool/CustomCard.dart';
import 'package:vbvs_app/component/tool/TopSlideNotification.dart';
import 'package:vbvs_app/pages/common/selectDialog.dart';
import 'package:vbvs_app/pages/mh_page/device/controller/mht_bluetooth_controller.dart';
import 'package:vbvs_app/pages/mh_page/homepage/controller/mht_home_controller.dart';
class MHTPeopleInfoPage extends StatefulWidget {
const MHTPeopleInfoPage({Key? key}) : super(key: key);
@override
State<MHTPeopleInfoPage> createState() => _MHTPeopleInfoPageState();
}
class _MHTPeopleInfoPageState extends State<MHTPeopleInfoPage> {
final MHTBlueToothController bluetoothController = Get.find();
final List<TextEditingController> _nameControllers = [];
final List<TextEditingController> _contactControllers = [];
List<Map<String, dynamic>> peopleList = [];
bool isLoading = true;
@override
void initState() {
super.initState();
_initializeData();
}
void _initializeData() async {
final device = bluetoothController.currentFullDevice;
//todo 初始化传感器id
// Initialize person A
peopleList.add({
'mac'.tr: device?.macA,
'gender': 1,
'id': device!.macAID,
});
// Initialize person B if exists
if (device?.macB != null && device!.macB!.isNotEmpty) {
peopleList.add({
'mac'.tr: device.macB,
'gender': 1,
'id': device!.macBID,
});
}
// Initialize controllers after data is loaded
_initializeControllers();
setState(() => isLoading = false);
}
void _initializeControllers() {
for (var person in peopleList) {
_nameControllers.add(TextEditingController(text: person["name"] ?? ""));
_contactControllers
.add(TextEditingController(text: person["contact"] ?? ""));
}
}
@override
void dispose() {
for (var controller in _nameControllers) {
controller.dispose();
}
for (var controller in _contactControllers) {
controller.dispose();
}
super.dispose();
}
Widget getLine() {
return Divider(
color: Color(0XFF929699),
thickness: 0.5.rpx,
height: 0,
);
}
String time_08_Formatter_pattern(dynamic date, String pattern) {
if (date == null || date.toString().isEmpty) return "-";
try {
String normalized = date.toString().replaceAll("/", "-");
DateTime dt = DateTime.parse(normalized);
return DateFormat(pattern).format(dt);
} catch (e) {
return "-";
}
}
Future<void> _savePersonData(
Map<String, dynamic> personData, BuildContext context) async {
String serviceAddress = ServiceConstant.service_address;
String serviceName = ServiceConstant.server_service;
String serviceApi = ServiceConstant.personnel_info;
String type = "user_message_setting";
String queryUrl = "${serviceAddress}${serviceName}${serviceApi}";
try {
var body = {
'mac'.tr: personData['mac'.tr],
'name': personData['name'],
'gender': personData['gender'],
'height': personData['height'],
'weight': personData['weight'],
'birthday': personData['birthday'] is DateTime
? DateFormat('yyyy-MM-dd').format(personData['birthday'])
: personData['birthday'],
'contact': personData['contact'],
'id': personData['id'],
};
await requestWithLog(
logTitle: "保存用户信息".tr,
method: MyHttpMethod.put,
queryUrl: queryUrl,
data: body,
onSuccess: (res) {
print(res);
},
onFailure: (res) {
TopSlideNotification.show(context,
text: res.msg!, textColor: themeController.currentColor.sc9);
print(res);
},
);
// showToast("保存成功(${personData['mac']}", color: color_success);
} catch (e) {
print("Error saving person data: $e");
showToast("保存失败(${personData['mac']}");
}
}
@override
Widget build(BuildContext context) {
if (isLoading) {
return Center(child: CircularProgressIndicator());
}
return LayoutBuilder(
builder: (context, boxConstraints) => GestureDetector(
onTap: () {
FocusScope.of(context).requestFocus(FocusNode());
},
child: Container(
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images/new_background.png'),
fit: BoxFit.fill,
),
),
child: Scaffold(
backgroundColor: Colors.transparent,
appBar: AppBar(
elevation: 0,
surfaceTintColor: Colors.transparent,
backgroundColor: Colors.transparent,
automaticallyImplyLeading: false,
iconTheme: IconThemeData(color: Colors.white),
titleSpacing: 0,
title: SizedBox(
width: double.infinity,
height: 180.rpx,
child: Stack(
alignment: Alignment.center,
children: [
Text(
'人员资料'.tr,
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 30.rpx,
),
),
Positioned(
left: 20.rpx,
child: returnIconButtomNew(),
),
Positioned(
right: 30.rpx,
child: CustomCard(
borderRadius: 16.rpx,
gradientDirection: GradientDirection.vertical,
onTap: () async {
// Save all people data
for (var person in peopleList) {
await _savePersonData(person, context);
}
TopSlideNotification.show(context, text: "保存成功".tr);
MHTHomeController mhtHomeController = Get.find();
mhtHomeController.getPersonList();
// Get.offNamed("/bindDeviceSuccess");
Map data = {};
final device = bluetoothController.currentFullDevice;
data['_id'] = device!.deviceID;
data['isNextStep'] = true;
Get.toNamed("/editBedPage", arguments: data);
},
colors: const [
Color(0xFFFCFCFC),
Color(0xFFF8FAF9),
Color(0XFFECF6F3),
Color(0XFFD9F0E9),
Color(0xFFCEECE3)
],
child: Container(
width: 120.rpx,
height: 60.rpx,
alignment: Alignment.center,
child: Text(
"下一步".tr,
style: TextStyle(
fontFamily: 'Readex Pro',
color: Color(0XFF011D33),
letterSpacing: 0,
fontSize: 30.rpx,
),
),
),
),
)
],
),
),
centerTitle: false,
),
body: SafeArea(
top: true,
child: Container(
padding: EdgeInsets.only(left: 30.rpx, right: 30.rpx),
width: MediaQuery.sizeOf(context).width,
height: MediaQuery.sizeOf(context).height * 1.123,
child: SingleChildScrollView(
child: Column(
children: [
...List.generate(peopleList.length, (index) {
final person = peopleList[index];
return Column(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
margin: EdgeInsets.only(
left: 18.rpx,
top: index == 0 ? 30.rpx : 90.rpx,
bottom: 20.rpx),
child: Text(
index == 0
? 'person_info_A'.tr
: 'person_info_B'.tr,
style: TextStyle(
color: Colors.white, fontSize: 30.rpx),
),
),
Container(
child: Column(
children: [
getLine(),
Container(
width: double.infinity,
height: 90.rpx,
margin: EdgeInsets.only(
left: 40.rpx, right: 35.rpx),
decoration: BoxDecoration(),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(
'姓名'.tr,
style: TextStyle(
fontFamily: 'Readex Pro',
color: Color(0xFF9EA4B7),
fontSize: 30.rpx,
letterSpacing: 0,
),
),
Container(
width: 300.rpx,
child: TextField(
controller: _nameControllers[index],
obscureText: false,
textAlign: TextAlign.right,
style: TextStyle(
fontSize: 30.rpx,
color: Colors.white),
decoration: InputDecoration(
fillColor: Colors.transparent,
filled: true,
hintText: "请输入姓名".tr,
hintStyle: TextStyle(
color: Colors.white),
border: InputBorder.none,
contentPadding:
EdgeInsets.all(0)),
onChanged: (value) {
setState(() {
peopleList[index]["name"] = value;
});
},
),
),
],
),
),
getLine(),
Container(
margin: EdgeInsets.only(
left: 40.rpx, right: 35.rpx),
width: double.infinity,
height: 90.rpx,
decoration: BoxDecoration(),
child: InkWell(
onTap: () {
FocusScope.of(context)
.requestFocus(FocusNode());
Future.delayed(
const Duration(milliseconds: 250),
() {
showOneSelectionDialog(context,
title: "选择性别".tr,
arr: ["".tr, "".tr],
checkIndex: peopleList[index]
['gender'],
checkChange: (sindex) {
setState(() {
peopleList[index]['gender'] =
sindex;
});
}).then((d) {});
});
},
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(
'性别'.tr,
style: TextStyle(
fontFamily: 'Readex Pro',
color: Color(0xFF9EA4B7),
fontSize: 30.rpx,
letterSpacing: 0,
),
),
Row(
mainAxisSize: MainAxisSize.max,
children: [
Container(
width: 200.rpx,
child: Text(
'${peopleList[index]['gender'] == 1 ? ''.tr : ''.tr}',
textAlign: TextAlign.right,
style: TextStyle(
fontFamily: 'Readex Pro',
color: Colors.white,
fontSize: 30.rpx,
letterSpacing: 0,
),
),
),
SizedBox(width: 16.rpx),
Icon(
Icons.expand_more,
color: Colors.white,
size: 48.rpx,
),
],
),
],
),
),
),
getLine(),
Container(
width: double.infinity,
height: 90.rpx,
margin: EdgeInsets.only(
left: 40.rpx, right: 35.rpx),
decoration: BoxDecoration(),
child: InkWell(
onTap: () {
FocusScope.of(context)
.requestFocus(FocusNode());
Future.delayed(
const Duration(milliseconds: 250),
() {
showHeightPickerDialog(
context,
initialHeight: int.tryParse(
peopleList[index]['height'] ??
'170') ??
170,
onConfirm: (int selectedHeight) {
setState(() {
peopleList[index]['height'] =
selectedHeight.toString();
});
},
);
});
},
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(
'身高(cm)'.tr,
style: TextStyle(
fontFamily: 'Readex Pro',
color: Color(0xFF9EA4B7),
fontSize: 30.rpx,
letterSpacing: 0,
),
),
Row(
children: [
Text(
peopleList[index]['height'] !=
null
? "${peopleList[index]['height']} cm"
: '',
style: TextStyle(
fontFamily: 'Readex Pro',
color: Colors.white,
fontSize: 30.rpx,
),
),
SizedBox(width: 16.rpx),
Icon(Icons.expand_more,
color: Colors.white,
size: 48.rpx),
],
),
],
),
),
),
getLine(),
Container(
width: double.infinity,
height: 90.rpx,
margin: EdgeInsets.only(
left: 40.rpx, right: 35.rpx),
decoration: BoxDecoration(),
child: InkWell(
onTap: () {
FocusScope.of(context)
.requestFocus(FocusNode());
Future.delayed(
const Duration(milliseconds: 250),
() {
showWeightPickerDialog(
context,
initialWeight: "50",
onConfirm: (int selectedWeight) {
setState(() {
peopleList[index]['weight'] =
selectedWeight.toString();
});
},
);
});
},
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(
'体重(kg)'.tr,
style: TextStyle(
fontFamily: 'Readex Pro',
color: Color(0xFF9EA4B7),
fontSize: 30.rpx,
letterSpacing: 0,
),
),
Row(
children: [
Text(
peopleList[index]['weight'] !=
null
? "${peopleList[index]['weight']} kg"
: '',
style: TextStyle(
fontFamily: 'Readex Pro',
color: Colors.white,
fontSize: 30.rpx,
),
),
SizedBox(width: 16.rpx),
Icon(Icons.expand_more,
color: Colors.white,
size: 48.rpx),
],
),
],
),
),
),
getLine(),
Container(
width: double.infinity,
height: 90.rpx,
margin: EdgeInsets.only(
left: 40.rpx, right: 35.rpx),
decoration: BoxDecoration(),
child: InkWell(
onTap: () {
FocusScope.of(context)
.requestFocus(FocusNode());
Future.delayed(
const Duration(milliseconds: 250),
() {
showDateSelectionDialog(context,
checkDate: peopleList[index]
['birthday'] is DateTime
? peopleList[index]['birthday']
: DateTime.tryParse(
peopleList[index]
['birthday'] ??
'') ??
DateTime.now(),
checkChange: (DateTime d) {
setState(() {
peopleList[index]['birthday'] = d;
});
}).then((d) {});
});
},
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(
'生日'.tr,
style: TextStyle(
fontFamily: 'Readex Pro',
color: Color(0xFF9EA4B7),
fontSize: 30.rpx,
letterSpacing: 0,
),
),
Row(
mainAxisSize: MainAxisSize.max,
children: [
Container(
constraints: BoxConstraints(
minWidth: 200.rpx),
child: Text(
peopleList[index]['birthday'] !=
null
? time_08_Formatter_pattern(
peopleList[index]
['birthday'],
"yyyy年MM月dd日".tr)
: '',
textAlign: TextAlign.right,
style: TextStyle(
fontFamily: 'Readex Pro',
color: Colors.white,
fontSize: 30.rpx,
letterSpacing: 0,
),
),
),
SizedBox(width: 16.rpx),
Icon(
Icons.expand_more,
color: Colors.white,
size: 48.rpx,
),
],
),
],
),
),
),
getLine(),
Container(
width: double.infinity,
height: 90.rpx,
margin: EdgeInsets.only(
left: 40.rpx, right: 35.rpx),
decoration: BoxDecoration(),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(
'联系方式'.tr,
style: TextStyle(
fontFamily: 'Readex Pro',
color: Color(0xFF9EA4B7),
fontSize: 30.rpx,
letterSpacing: 0,
),
),
Container(
width: 300.rpx,
child: TextField(
controller:
_contactControllers[index],
obscureText: false,
keyboardType: TextInputType.number,
textInputAction: TextInputAction.done,
textAlign: TextAlign.right,
style: TextStyle(
fontSize: 30.rpx,
color: Colors.white),
decoration: InputDecoration(
fillColor: Colors.transparent,
filled: true,
hintText: "请输入联系方式".tr,
hintStyle: TextStyle(
color: Colors.white),
border: InputBorder.none,
contentPadding:
EdgeInsets.all(0)),
onChanged: (value) {
setState(() {
peopleList[index]['contact'] =
value;
});
},
),
),
],
),
),
getLine(),
],
))
],
);
}),
SizedBox(height: 100.rpx),
],
),
),
),
),
),
),
),
);
}
}