更新
This commit is contained in:
651
lib/pages/mh_page/device/mht_people_info.dart
Normal file
651
lib/pages/mh_page/device/mht_people_info.dart
Normal file
@@ -0,0 +1,651 @@
|
||||
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';
|
||||
|
||||
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': device?.macA,
|
||||
'gender': "男",
|
||||
'id':device!.macAID,
|
||||
});
|
||||
|
||||
// Initialize person B if exists
|
||||
if (device?.macB != null && device!.macB!.isNotEmpty) {
|
||||
peopleList.add({
|
||||
'mac': device.macB,
|
||||
'gender': "男",
|
||||
'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': personData['mac'],
|
||||
'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: "保存用户信息",
|
||||
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(
|
||||
'人员资料',
|
||||
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: "保存成功");
|
||||
Get.offNamed("/bindDeviceSuccess");
|
||||
},
|
||||
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(
|
||||
"下一步",
|
||||
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 ? "A" : "B"}",
|
||||
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(
|
||||
'姓名',
|
||||
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: const InputDecoration(
|
||||
fillColor: Colors.transparent,
|
||||
filled: true,
|
||||
hintText: "请输入姓名",
|
||||
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: Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
'性别',
|
||||
style: TextStyle(
|
||||
fontFamily: 'Readex Pro',
|
||||
color: Color(0xFF9EA4B7),
|
||||
fontSize: 30.rpx,
|
||||
letterSpacing: 0,
|
||||
),
|
||||
),
|
||||
InkWell(
|
||||
onTap: () {
|
||||
FocusScope.of(context)
|
||||
.requestFocus(FocusNode());
|
||||
Future.delayed(
|
||||
const Duration(milliseconds: 250),
|
||||
() {
|
||||
showOneSelectionDialog(context,
|
||||
arr: ["女", "男"],
|
||||
checkIndex: peopleList[index]
|
||||
['gender'] ==
|
||||
"女"
|
||||
? 0
|
||||
: 1, checkChange: (sindex) {
|
||||
setState(() {
|
||||
peopleList[index]['gender'] =
|
||||
sindex == 0 ? "女" : "男";
|
||||
});
|
||||
}).then((d) {});
|
||||
});
|
||||
},
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: [
|
||||
Container(
|
||||
width: 200.rpx,
|
||||
child: Text(
|
||||
'${peopleList[index]['gender']}',
|
||||
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(
|
||||
'身高(cm)',
|
||||
style: TextStyle(
|
||||
fontFamily: 'Readex Pro',
|
||||
color: Color(0xFF9EA4B7),
|
||||
fontSize: 30.rpx,
|
||||
letterSpacing: 0,
|
||||
),
|
||||
),
|
||||
InkWell(
|
||||
onTap: () {
|
||||
FocusScope.of(context).unfocus();
|
||||
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(
|
||||
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: Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
'体重(kg)',
|
||||
style: TextStyle(
|
||||
fontFamily: 'Readex Pro',
|
||||
color: Color(0xFF9EA4B7),
|
||||
fontSize: 30.rpx,
|
||||
letterSpacing: 0,
|
||||
),
|
||||
),
|
||||
InkWell(
|
||||
onTap: () {
|
||||
FocusScope.of(context).unfocus();
|
||||
Future.delayed(
|
||||
const Duration(milliseconds: 250),
|
||||
() {
|
||||
showWeightPickerDialog(
|
||||
context,
|
||||
initialWeight: "0",
|
||||
onConfirm: (int selectedWeight) {
|
||||
setState(() {
|
||||
peopleList[index]['weight'] =
|
||||
selectedWeight.toString();
|
||||
});
|
||||
},
|
||||
);
|
||||
});
|
||||
},
|
||||
child: 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: Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
'生日',
|
||||
style: TextStyle(
|
||||
fontFamily: 'Readex Pro',
|
||||
color: Color(0xFF9EA4B7),
|
||||
fontSize: 30.rpx,
|
||||
letterSpacing: 0,
|
||||
),
|
||||
),
|
||||
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,
|
||||
children: [
|
||||
Container(
|
||||
constraints: BoxConstraints(
|
||||
minWidth: 200.rpx),
|
||||
child: Text(
|
||||
peopleList[index]['birthday'] !=
|
||||
null
|
||||
? time_08_Formatter_pattern(
|
||||
peopleList[index]
|
||||
['birthday'],
|
||||
"yyyy年MM月dd日")
|
||||
: '',
|
||||
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(
|
||||
'联系人',
|
||||
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: "请输入联系人",
|
||||
hintStyle: TextStyle(
|
||||
color: Colors.white),
|
||||
border: InputBorder.none,
|
||||
contentPadding:
|
||||
EdgeInsets.all(0)),
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
peopleList[index]['contact'] =
|
||||
value;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
getLine(),
|
||||
],
|
||||
))
|
||||
],
|
||||
);
|
||||
}),
|
||||
SizedBox(height: 100.rpx),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user