Files
tuiche/lib/pages/person/person_page.dart
2025-05-23 14:51:09 +08:00

884 lines
48 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:ef/ef.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutterflow_ui/flutterflow_ui.dart';
import 'package:vbvs_app/common/color/appConstants.dart';
import 'package:vbvs_app/common/color/app_uri_status.dart';
import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/common/util/MyUtils.dart';
import 'package:vbvs_app/component/tool/CustomCard.dart';
import 'package:vbvs_app/component/tool/SelectableTagButton.dart';
import 'package:vbvs_app/component/tool/TopSlideNotification.dart';
import 'package:vbvs_app/controller/device/blueteeth_bind_controller.dart';
import 'package:vbvs_app/controller/main_bottom/global_controller.dart';
import 'package:vbvs_app/controller/person/person_controller.dart';
import 'package:vbvs_app/controller/theme_controller/ThemeController.dart';
import 'package:vbvs_app/controller/user_info_controller.dart';
import 'package:vbvs_app/model/api_response.dart';
import 'package:vbvs_app/pages/person/select_time.dart';
class PersonPage extends StatefulWidget {
const PersonPage({super.key});
@override
State<PersonPage> createState() => _EPageState();
}
class _EPageState extends State<PersonPage> {
GlobalController globalController = Get.find();
UserInfoController userInfoController = Get.find();
BlueteethBindController blueteethBindController = Get.find();
PersonController personController = Get.find();
ThemeController themeController = Get.find();
@override
void initState() {
super.initState();
personController.getDiseaseData().then((apiResponse) {
WidgetsBinding.instance.addPostFrameCallback((_) {
if (apiResponse.code != HttpStatusCodes.ok) {
TopSlideNotification.show(
context,
text: apiResponse.msg ?? '',
textColor: themeController.currentColor.sc9,
);
}
});
});
personController.selectedDiseaseIds.value = [];
personController.name.value = '';
personController.gender.value = 1;
personController.birthday.value = "";
personController.weight.value = "";
personController.dateTime = null;
}
@override
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (context, bodySize) => GestureDetector(
onTap: () => FocusScope.of(context).unfocus(),
child: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/img/bgNoImg.png'), // 本地图片
fit: BoxFit.fill, // 填满整个 Container
),
),
child: Scaffold(
backgroundColor: Colors.transparent, // 加上这一行
appBar: AppBar(
backgroundColor: themeController.currentColor.sc17,
automaticallyImplyLeading: false,
iconTheme: IconThemeData(
color: themeController.currentColor.sc3,
),
titleSpacing: 0,
// leading: returnIconButtom,
title: Container(
width: double.infinity,
height: 180.rpx,
child: Stack(
alignment: Alignment.center,
children: [
/// 居中标题
Text(
'人员资料.标题'.tr,
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Readex Pro',
color: themeController.currentColor.sc3,
letterSpacing: 0,
fontSize: 30.rpx,
),
),
/// 左边返回按钮
Positioned(
left: 0,
child: returnIconButtom,
),
Positioned(
right: 20.rpx,
child: CustomCard(
borderRadius: 20.rpx,
onTap: () async {
ApiResponse apiRespons =
await personController.savePersonData();
if (apiRespons.code == HttpStatusCodes.ok) {
TopSlideNotification.show(context,
text: apiRespons.msg!);
Get.offAllNamed("/bindDeviceSuccess");
// Get.toNamed("/wifiPage");
} else {
TopSlideNotification.show(context,
text: apiRespons.msg!,
textColor: themeController.currentColor.sc9);
}
},
colors: [
themeController.currentColor.sc1,
themeController.currentColor.sc2,
],
child: Container(
width: 100.rpx,
height: 60.rpx,
alignment: Alignment.center,
padding: EdgeInsetsDirectional.fromSTEB(
16.rpx, 0, 16.rpx, 0),
child: Text(
'人员资料.保存'.tr,
style: FlutterFlowTheme.of(context)
.titleSmall
.override(
fontFamily: 'Inter Tight',
color: themeController.currentColor.sc3,
letterSpacing: 0.0,
),
),
),
),
),
],
),
),
actions: [],
centerTitle: false,
),
body: SafeArea(
top: true,
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(30.rpx, 0, 30.rpx, 0),
child: Column(
children: [
Expanded(
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
70.rpx, 141.rpx, 70.rpx, 0),
child: Container(
width: double.infinity,
height: 100.rpx,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(50.rpx),
border: Border.all(
color: themeController.currentColor.sc4
.withOpacity(0.5),
width: AppConstants().border_width,
),
),
child: Align(
alignment: AlignmentDirectional(0, 0),
child: TextFormField(
// controller: _model.textController1,
// focusNode: _model.textFieldFocusNode1,
initialValue: personController.name.value,
onChanged: (Value) {
personController.name.value = Value;
},
autofocus: false,
obscureText: false,
decoration: InputDecoration(
fillColor: Colors.transparent,
isDense: true,
labelStyle: FlutterFlowTheme.of(context)
.labelMedium
.override(
fontFamily: 'Inter',
letterSpacing: 0.0,
color: themeController
.currentColor.sc3,
),
hintText: '人员资料.名字输入提示'.tr,
hintStyle: FlutterFlowTheme.of(context)
.labelMedium
.override(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.0,
color: themeController.currentColor.sc4,
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Color(0x00000000),
width: 1.rpx,
),
borderRadius:
BorderRadius.circular(8.rpx),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Color(0x00000000),
width: 1.rpx,
),
borderRadius:
BorderRadius.circular(8.rpx),
),
errorBorder: OutlineInputBorder(
borderSide: BorderSide(
color: FlutterFlowTheme.of(context)
.error,
width: 1.rpx,
),
borderRadius:
BorderRadius.circular(8.rpx),
),
focusedErrorBorder: OutlineInputBorder(
borderSide: BorderSide(
color: FlutterFlowTheme.of(context)
.error,
width: 1.rpx,
),
borderRadius:
BorderRadius.circular(8.rpx),
),
filled: true,
),
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
letterSpacing: 0.0,
color:
themeController.currentColor.sc3,
),
textAlign: TextAlign.center,
cursorColor:
themeController.currentColor.sc3,
// validator: _model.textController1Validator
// .asValidator(context),
),
),
),
),
Align(
alignment: AlignmentDirectional(0, 0),
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(
0, 90.rpx, 0, 0),
child: Container(
width: double.infinity,
decoration: BoxDecoration(),
child: Align(
alignment: AlignmentDirectional(-1, 0),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment:
MainAxisAlignment.center,
children: [
Obx(
() {
bool isMaleGreyed =
personController.gender.value ==
0; // gender == 0 时男生部分变灰
return GestureDetector(
onTap: () {
personController.gender.value =
1; // 点击时将 gender 设置为 1女生部分被选中
},
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Container(
width: 90.rpx,
height: 90.rpx,
decoration: BoxDecoration(),
child: Container(
clipBehavior:
Clip.antiAlias,
decoration: BoxDecoration(
shape: BoxShape.circle,
),
child: ColorFiltered(
colorFilter: isMaleGreyed
? ColorFilter.mode(
Colors.grey
.withOpacity(
0.6),
BlendMode
.saturation)
: ColorFilter.mode(
Colors
.transparent,
BlendMode
.saturation),
child: Image.asset(
"assets/img/man.png",
fit: BoxFit.cover,
),
),
),
),
Text(
''.tr,
style: FlutterFlowTheme.of(
context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.0,
color: isMaleGreyed
? themeController
.currentColor
.sc4
: themeController
.currentColor
.sc3,
),
),
].divide(
SizedBox(height: 14.rpx)),
),
);
},
),
// 女性部分
Obx(
() {
bool isFemaleGreyed =
personController.gender.value ==
1; // gender == 1 时女生部分变灰
return GestureDetector(
onTap: () {
personController.gender.value =
0; // 点击时将 gender 设置为 0男生部分被选中
},
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Container(
width: 90.rpx,
height: 90.rpx,
decoration: BoxDecoration(),
child: Container(
clipBehavior:
Clip.antiAlias,
decoration: BoxDecoration(
shape: BoxShape.circle,
),
child: ColorFiltered(
colorFilter: isFemaleGreyed
? ColorFilter.mode(
Colors.grey
.withOpacity(
0.6),
BlendMode
.saturation)
: ColorFilter.mode(
Colors
.transparent,
BlendMode
.saturation),
child: Image.asset(
"assets/img/woman.png",
fit: BoxFit.cover,
),
),
),
),
Text(
''.tr,
style: FlutterFlowTheme.of(
context)
.bodyMedium
.override(
fontFamily: 'Inter',
color: isFemaleGreyed
? themeController
.currentColor
.sc4
: themeController
.currentColor
.sc3,
fontSize: 26.rpx,
letterSpacing: 0.0,
),
),
].divide(
SizedBox(height: 14.rpx)),
),
);
},
),
].divide(SizedBox(width: 170.rpx)),
),
),
),
),
),
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
70.rpx, 50.rpx, 70.rpx, 0),
child: Container(
height: 100.rpx,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(50.rpx),
border: Border.all(
color: themeController.currentColor.sc4
.withOpacity(0.5),
width: AppConstants().border_width,
),
),
child: InkWell(
onTap: () {
FocusScope.of(context)
.requestFocus(FocusNode());
Future.delayed(Duration(milliseconds: 250),
() {
showDateSelectionDialog(
context,
checkDate: personController.dateTime ??
DateTime.now(),
checkChange: (DateTime d) {
personController.birthday.value =
MyUtils.formatBindTime(d);
personController.dateTime = d;
personController.updateAll();
},
title: "生日".tr
);
});
},
child: Center(
child: Text(
personController.dateTime != null
? DateFormat("yyyy年MM月dd日").format(
personController.dateTime!)
: '人员资料.生日输入提示'.tr,
textAlign: TextAlign.right,
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Readex Pro',
color: personController.dateTime !=
null
? themeController
.currentColor.sc3
: themeController
.currentColor.sc4,
fontSize: AppConstants()
.normal_text_fontSize,
letterSpacing: 0,
),
),
),
),
),
),
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
70.rpx, 18.rpx, 70.rpx, 0),
child: Container(
width: double.infinity,
height: 100.rpx,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(50.rpx),
border: Border.all(
color: themeController.currentColor.sc4
.withOpacity(0.5),
width: AppConstants().border_width,
),
),
child: Align(
alignment: AlignmentDirectional(0, 0),
child: Stack(
alignment: Alignment.center,
children: [
// 实际输入框(输入逻辑保留)
TextFormField(
keyboardType: TextInputType.number,
inputFormatters: [
FilteringTextInputFormatter
.digitsOnly,
],
initialValue: personController
.height.value
.toString(),
onChanged: (value) {
personController.height.value = value;
},
autofocus: false,
obscureText: false,
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
color:
Colors.transparent, // 隐藏输入文字
letterSpacing: 0.0,
),
textAlign: TextAlign.center,
cursorColor:
themeController.currentColor.sc3,
decoration: InputDecoration(
fillColor: Colors.transparent,
isDense: true,
hintText: '身高输入提示'.tr,
hintStyle:
FlutterFlowTheme.of(context)
.labelMedium
.override(
fontFamily: 'Inter',
color: themeController
.currentColor.sc4,
fontSize: AppConstants()
.normal_text_fontSize,
letterSpacing: 0.0,
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Color(0x00000000),
width: 1.rpx,
),
borderRadius:
BorderRadius.circular(8.rpx),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Color(0x00000000),
width: 1.rpx,
),
borderRadius:
BorderRadius.circular(8.rpx),
),
errorBorder: OutlineInputBorder(
borderSide: BorderSide(
color:
FlutterFlowTheme.of(context)
.error,
width: 1.rpx,
),
borderRadius:
BorderRadius.circular(8.rpx),
),
focusedErrorBorder:
OutlineInputBorder(
borderSide: BorderSide(
color:
FlutterFlowTheme.of(context)
.error,
width: 1.rpx,
),
borderRadius:
BorderRadius.circular(8.rpx),
),
filled: true,
),
),
Obx(() {
final height =
personController.height.value;
return (height == null ||
height.isEmpty)
? const SizedBox.shrink() // 不显示任何内容
: Text(
'${height}cm',
textAlign: TextAlign.center,
style:
FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
color: themeController
.currentColor.sc3,
fontSize: AppConstants()
.normal_text_fontSize,
),
);
}),
],
),
),
),
),
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
70.rpx, 18.rpx, 70.rpx, 0),
child: Container(
width: double.infinity,
height: 100.rpx,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(50.rpx),
border: Border.all(
color: themeController.currentColor.sc4
.withOpacity(0.5),
width: AppConstants().border_width,
),
),
child: Align(
alignment: AlignmentDirectional(0, 0),
child: Stack(
alignment: Alignment.center,
children: [
// 实际输入框(输入逻辑保留)
TextFormField(
keyboardType: TextInputType.number,
inputFormatters: [
FilteringTextInputFormatter
.digitsOnly,
],
initialValue:
personController.weight.value,
onChanged: (value) {
personController.weight.value = value;
},
autofocus: false,
obscureText: false,
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
color:
Colors.transparent, // 隐藏输入文字
letterSpacing: 0.0,
),
textAlign: TextAlign.center,
cursorColor:
themeController.currentColor.sc3,
decoration: InputDecoration(
fillColor: Colors.transparent,
isDense: true,
hintText: '人员资料.体重输入提示'.tr,
hintStyle:
FlutterFlowTheme.of(context)
.labelMedium
.override(
fontFamily: 'Inter',
color: themeController
.currentColor.sc4,
fontSize: AppConstants()
.normal_text_fontSize,
letterSpacing: 0.0,
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Color(0x00000000),
width: 1.rpx,
),
borderRadius:
BorderRadius.circular(8.rpx),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Color(0x00000000),
width: 1.rpx,
),
borderRadius:
BorderRadius.circular(8.rpx),
),
errorBorder: OutlineInputBorder(
borderSide: BorderSide(
color:
FlutterFlowTheme.of(context)
.error,
width: 1.rpx,
),
borderRadius:
BorderRadius.circular(8.rpx),
),
focusedErrorBorder:
OutlineInputBorder(
borderSide: BorderSide(
color:
FlutterFlowTheme.of(context)
.error,
width: 1.rpx,
),
borderRadius:
BorderRadius.circular(8.rpx),
),
filled: true,
),
),
Obx(() {
final weight =
personController.weight.value;
return (weight == null ||
weight.isEmpty)
? const SizedBox.shrink() // 不显示任何内容
: Text(
'${weight}kg',
textAlign: TextAlign.center,
style:
FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
color: themeController
.currentColor.sc3,
fontSize: AppConstants()
.normal_text_fontSize,
),
);
}),
],
),
),
),
),
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
0, 117.rpx, 0, 0),
child: Container(
width: double.infinity,
decoration: BoxDecoration(),
child: Align(
alignment: AlignmentDirectional(0, 0),
child: Text(
'人员资料.疾病标题'.tr,
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
color: Color(0xFFF3F4F5),
fontSize: 30.rpx,
letterSpacing: 0.0,
),
),
),
),
),
Obx(() {
final selectedIds =
personController.selectedDiseaseIds;
final diseases = personController.diseaseList;
return Padding(
padding: EdgeInsetsDirectional.fromSTEB(
70.rpx, 70.rpx, 70.rpx, 0),
child: Wrap(
spacing: 20.rpx,
runSpacing: 20.rpx,
children: diseases.map<Widget>((disease) {
final id = disease['_id'];
final name = disease['disease_type_name'];
final isSelected = selectedIds.contains(id);
return SelectableTagButton(
label: name,
selected: isSelected,
onTap: () {
if (isSelected) {
selectedIds.remove(id);
} else {
selectedIds.add(id);
}
personController.model.read = 0;
personController.updateAll();
},
);
}).toList(),
),
);
}),
],
),
),
),
Padding(
padding: EdgeInsetsDirectional.fromSTEB(0, 52.rpx, 0, 0),
child: Container(
width: double.infinity,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20.rpx),
border: Border.all(
color: themeController.currentColor.sc4
.withOpacity(0.5),
width: AppConstants().border_width,
),
),
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(
30.rpx, 30.rpx, 30.rpx, 30.rpx),
child: Row(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
0, 8.rpx, 0, 0),
child: Icon(
Icons.arrow_back,
color: themeController.currentColor.sc4,
size: 24.rpx,
),
),
Expanded(
child: Text(
'人员资料.提示'.tr,
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
color: themeController.currentColor.sc4,
fontSize: 26.rpx,
letterSpacing: 0.0,
),
),
),
].divide(SizedBox(width: 23.rpx)),
),
),
),
),
],
),
),
),
),
),
),
);
}
Widget _buildDeviceCard(BuildContext context,
{required String title, required String imageUrl, required String type}) {
return CustomCard(
borderRadius: 20.rpx, // 圆角大小
onTap: () {
if (type != null) {
if (type == '1') {
Get.toNamed("/blueteethDevice");
}
}
},
colors: [themeController.currentColor.sc17], // 背景色
child: Container(
width: double.infinity,
height: MediaQuery.sizeOf(context).height * 0.135,
constraints: BoxConstraints(
minHeight: 220.rpx,
),
padding: EdgeInsetsDirectional.fromSTEB(77.rpx, 0, 21.rpx, 0),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
title,
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Inter',
color: const Color(0xFFC2CED7),
fontSize: 30.rpx,
letterSpacing: 0.0,
),
),
ClipRRect(
borderRadius: BorderRadius.circular(8.rpx),
child: Image.asset(
imageUrl,
width: 212.rpx,
height: 168.rpx,
),
),
],
),
),
);
}
}