Files
tuiche/lib/pages/person/update_person_page.dart

784 lines
40 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:flutter_svg/svg.dart';
import 'package:flutterflow_ui/flutterflow_ui.dart';
import 'package:vbvs_app/common/color/ServiceConstant.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/common/util/requestWithLog.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/device/body_device_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/enum/BindType.dart';
import 'package:vbvs_app/model/api_response.dart';
import 'package:vbvs_app/pages/person/select_time.dart';
class UpdatePersonPage extends StatefulWidget {
var status;
UpdatePersonPage({super.key, required this.status});
@override
State<UpdatePersonPage> createState() => _UpdatePageState();
}
class _UpdatePageState extends State<UpdatePersonPage> {
GlobalController globalController = Get.find();
UserInfoController userInfoController = Get.find();
BlueteethBindController blueteethBindController = Get.find();
PersonController personController = Get.find();
BodyDeviceController bodyDeviceController = Get.find();
ThemeController themeController = Get.find();
@override
void initState() {
super.initState();
// personController.dateTime = null;
personController.getDiseaseData().then((apiResponse) {
if (apiResponse.code != HttpStatusCodes.ok) {
TopSlideNotification.show(
context,
text: apiResponse.msg ?? '',
textColor: themeController.currentColor.sc9,
);
}
});
}
@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: TextStyle(
fontFamily: 'Readex Pro',
color: themeController.currentColor.sc3,
letterSpacing: 0,
fontSize: 30.rpx,
),
),
/// 左边返回按钮
Positioned(
left: 0,
child: returnIconButtomAddCallback(() {
bodyDeviceController.getDeviceList();
bodyDeviceController.updateAll();
}),
),
Visibility(
// visible: widget.status == BindType.active.code,
visible: true,
child: Positioned(
right: 20.rpx,
child: CustomCard(
borderRadius: 20.rpx,
onTap: () async {
ApiResponse apiRespons =
await personController.savePersonData();
if (apiRespons.code == HttpStatusCodes.ok) {
updateDeviceBindStatus(
personController.update_person_mac.value);
TopSlideNotification.show(context,
text: apiRespons.msg!);
} 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: TextStyle(
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: TextStyle(
fontFamily: 'Inter',
letterSpacing: 0.0,
color: themeController.currentColor.sc3,
),
hintText: '人员资料.名字输入提示'.tr,
hintStyle: TextStyle(
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(
width: 1.rpx,
),
borderRadius:
BorderRadius.circular(8.rpx),
),
focusedErrorBorder: OutlineInputBorder(
borderSide: BorderSide(
width: 1.rpx,
),
borderRadius:
BorderRadius.circular(8.rpx),
),
filled: true,
),
style: TextStyle(
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: () {
if (widget.status ==
BindType.share.code) {
TopSlideNotification.show(
context,
text: "被分享用户只能修改用户名称",
textColor: themeController
.currentColor.sc9);
return;
}
personController.gender.value =
1; // 点击时将 gender 设置为 1女生部分被选中
},
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Container(
width: 90.rpx,
height: 90.rpx,
child: ClipOval(
child: Opacity(
opacity: isMaleGreyed
? 0.4
: 1.0, // 控制透明度
child: Image.asset(
"assets/img/man.png",
fit: BoxFit.cover,
),
),
),
),
Text(
''.tr,
style: TextStyle(
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: () {
if (widget.status ==
BindType.share.code) {
TopSlideNotification.show(
context,
text: "被分享用户只能修改用户名称",
textColor: themeController
.currentColor.sc9);
return;
}
personController.gender.value =
0; // 点击时将 gender 设置为 0男生部分被选中
},
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Container(
width: 90.rpx,
height: 90.rpx,
child: ClipOval(
child: Opacity(
opacity: isFemaleGreyed
? 0.4
: 1.0, // 控制透明度
child: Image.asset(
"assets/img/man.png",
fit: BoxFit.cover,
),
),
),
),
Text(
''.tr,
style: TextStyle(
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: () {
if (widget.status == BindType.share.code) {
TopSlideNotification.show(context,
text: "被分享用户只能修改用户名称",
textColor:
themeController.currentColor.sc9);
return;
}
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: TextStyle(
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, 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: () {
if (widget.status == BindType.share.code) {
TopSlideNotification.show(context,
text: "被分享用户只能修改用户名称",
textColor:
themeController.currentColor.sc9);
return;
}
final currentHeight =
personController.height.value;
final initialHeight = currentHeight != null
? int.tryParse(
currentHeight.toString()) ??
170
: 170;
FocusScope.of(context)
.requestFocus(FocusNode());
Future.delayed(
const Duration(milliseconds: 250), () {
showHeightPickerDialog(
context,
title: "选择身高".tr,
initialHeight: initialHeight,
onConfirm: (int selectedHeight) {
personController.height.value =
selectedHeight.toString();
personController.updateAll();
print("身高: $selectedHeight cm");
},
);
});
},
child: Center(
child: Text(
personController.height.value != ""
? personController.height.value
: '身高输入提示'.tr,
textAlign: TextAlign.right,
style: TextStyle(
fontFamily: 'Readex Pro',
color: personController.height.value !=
""
? themeController.currentColor.sc3
: themeController.currentColor.sc4,
fontSize:
AppConstants().normal_text_fontSize,
letterSpacing: 0,
),
),
),
),
),
),
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: () {
if (widget.status == BindType.share.code) {
TopSlideNotification.show(context,
text: "被分享用户只能修改用户名称",
textColor:
themeController.currentColor.sc9);
return;
}
FocusScope.of(context)
.requestFocus(FocusNode());
Future.delayed(
const Duration(milliseconds: 250), () {
showWeightPickerDialog(
context,
title: "选择体重".tr,
initialWeight:
personController.weight.value ?? "",
onConfirm: (int selectedWeight) {
personController.weight.value =
selectedWeight
.toString(); // ✅ 转成字符串
personController.updateAll();
},
);
});
},
child: Center(
child: Text(
personController.weight.value != ""
? personController.weight.value
: '人员资料.体重输入提示'.tr,
textAlign: TextAlign.right,
style: TextStyle(
fontFamily: 'Readex Pro',
color: personController.weight.value !=
""
? themeController.currentColor.sc3
: themeController.currentColor.sc4,
fontSize:
AppConstants().normal_text_fontSize,
letterSpacing: 0,
),
),
),
),
),
),
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: TextStyle(
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 (widget.status ==
BindType.share.code) {
TopSlideNotification.show(context,
text: "被分享用户只能修改用户名称",
textColor: themeController
.currentColor.sc9);
return;
}
if (isSelected) {
selectedIds.remove(id);
} else {
selectedIds.add(id);
}
personController.model.read = 0;
personController.updateAll();
//切换语言
// Get.updateLocale(Locale("en", "us"));
},
);
}).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: Container(
width: 23.rpx,
height: 23.rpx,
// width: double.infinity,
decoration: BoxDecoration(),
child: SvgPicture.asset(
'assets/img/icon/tips.svg',
fit: BoxFit.cover,
color: themeController.currentColor.sc4,
),
),
),
Expanded(
child: Text(
'人员资料.提示'.tr,
style: TextStyle(
fontFamily: 'Inter',
color: themeController.currentColor.sc4,
fontSize: 26.rpx,
letterSpacing: 0.0,
),
),
),
].divide(SizedBox(width: 23.rpx)),
),
),
),
),
SizedBox(
height: 20.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: TextStyle(
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,
),
),
],
),
),
);
}
void updateDeviceBindStatus(String mac) {
String serviceAddress = ServiceConstant.service_address;
String serviceName = ServiceConstant.server_service;
String serviceApi = ServiceConstant.user_setting;
String type = "device_bind_status_$mac";
String queryUrl =
"${serviceAddress}${serviceName}${serviceApi}?type=${type}";
requestWithLog(
logTitle: "查询绑定流程",
method: MyHttpMethod.get,
queryUrl: queryUrl,
onSuccess: (res) {
print(res);
Map<String, dynamic> data = {
"type": type,
"mac": mac,
"wifi": res.data['wifi'],
"celibration": res.data['celibration'],
"person_info": true,
"time": DateTime.now().millisecondsSinceEpoch,
};
requestWithLog(
logTitle: "更新绑定流程",
method: MyHttpMethod.put,
queryUrl: queryUrl,
data: data,
onSuccess: (res) {},
onFailure: (res) {},
);
},
onFailure: (res) {},
);
}
}