From c3c64c620b8cdda58502509e98b8f070facd0e6f Mon Sep 17 00:00:00 2001 From: wzp Date: Sat, 31 Aug 2024 17:44:33 +0800 Subject: [PATCH] day 4 --- lib/views/common/full_page_struct.dart | 26 ++ lib/views/me.dart | 528 ++++++++++++++++++++++++- 2 files changed, 553 insertions(+), 1 deletion(-) create mode 100644 lib/views/common/full_page_struct.dart diff --git a/lib/views/common/full_page_struct.dart b/lib/views/common/full_page_struct.dart new file mode 100644 index 0000000..d9fdf50 --- /dev/null +++ b/lib/views/common/full_page_struct.dart @@ -0,0 +1,26 @@ +import 'package:flutter/material.dart'; + +class FullPageStruct extends StatelessWidget { + final String title; + final Widget child; + final Color? color; + const FullPageStruct({super.key, required this.title, required this.child, this.color}); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text(title), + centerTitle: true, + leading: IconButton( + onPressed: () { + Navigator.pop(context); + }, + icon: const Icon(Icons.keyboard_arrow_left), + ), + ), + body: child, + backgroundColor: color, + ); + } +} diff --git a/lib/views/me.dart b/lib/views/me.dart index 9f968a3..92f5125 100644 --- a/lib/views/me.dart +++ b/lib/views/me.dart @@ -1,4 +1,82 @@ +import 'dart:convert'; + +import 'package:environmental_protection/common/user_information.dart'; import 'package:flutter/material.dart'; +import 'package:http/http.dart'; + +import 'common/full_page_struct.dart'; + +Future removePerson(int id) { + return GlobalInformation.getInstance().requester.delete(resolve("/api/family/member/$id")); +} + +class PersonCard extends StatelessWidget { + final String name; + final String phone; + final DateTime? endDate; + final int id; + final String type; + final Function fetchFunction; + const PersonCard({super.key, required this.name, required this.phone, required this.endDate, required this.id, required this.fetchFunction, required this.type}); + + @override + Widget build(BuildContext context) { + return Card( + child: Padding( + padding: const EdgeInsetsDirectional.all(10), + child: ListTile( + title: Row( + children: [ + Text(name), + Container( + decoration: BoxDecoration( + color: const Color.fromRGBO(210, 246, 231, 1), + borderRadius: BorderRadiusDirectional.circular(10) + ), + child: Padding( + padding: const EdgeInsetsDirectional.only(start: 10, end: 10, top: 2, bottom: 2), + child: Text(type, style: const TextStyle(color: Color.fromRGBO(31, 204, 143, 1))) + ), + ) + ], + ), + leading: const SizedBox( + width: 50, + height: 100, + child: Placeholder(), + ), + subtitle: Flex( + direction: Axis.vertical, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(phone.replaceRange(3, 7, "****")), + Text(endDate == null ? "有效期:长期有效": "有效期:${endDate!.year}-${endDate!.month}-${endDate!.day}") + ], + ), + trailing: OutlinedButton( + onPressed: () { + removePerson(id).then((e){fetchFunction();}); + }, + style: const ButtonStyle( + foregroundColor: WidgetStatePropertyAll(Colors.red), + side: WidgetStatePropertyAll(BorderSide(color: Colors.red)) + ), + child: const Text( + "删除", + ), + ), + onTap: (){ + Navigator.push(context, MaterialPageRoute(builder: (context) { + return FamilyPersonInformation(id: id, fetchFunction: fetchFunction); + })); + }, + ), + ) + ); + } +} + + class MePage extends StatefulWidget { const MePage({super.key}); @@ -8,8 +86,456 @@ class MePage extends StatefulWidget { } class _MePageState extends State { + List> persons = []; + @override + void initState() { + super.initState(); + _fetchFamilyData(); + } + void _fetchFamilyData() async { + var data = await GlobalInformation().requester.get(resolve("/api/family/member/list")); + var jsonData = jsonDecode(data.body); + if (jsonData['code'] != 200){ + return; + } + setState(() { + persons.clear(); + jsonData['rows'].forEach((e){ + persons.add(e); + }); + }); + } @override Widget build(BuildContext context) { - return const Text("me"); + var personsCard = persons.map((e){return PersonCard(name: e['name'], phone: e['telephone'], endDate: e['endDate'] == null ? null : DateTime.parse(e['endDate']), id: e['id'], fetchFunction: _fetchFamilyData, type: e['memberType'] == "1" ? "家属" : "租户");}).toList(); + List items = []; + items.addAll(personsCard); + items.add(Center( + child: ElevatedButton( + onPressed: (){ + Navigator.push(context, MaterialPageRoute(builder: (context){ + return AddFamilyPerson(fetchFunction: _fetchFamilyData); + })); + }, + style: const ButtonStyle( + backgroundColor: WidgetStatePropertyAll(Colors.blueGrey) + ), + child: const Padding( + padding: EdgeInsetsDirectional.only(start: 20, end: 20, top: 10, bottom: 10), + child: Text( + "+ 新增家庭成员", + style: TextStyle( + color: Colors.white + ), + ) + ) + ), + )); + return FullPageStruct( + title: '家庭成员管理', + color: Colors.lightBlue, + child: ListView( + children: items, + ), + ); } } + +class AddFamilyPerson extends StatefulWidget { + final Function fetchFunction; + const AddFamilyPerson({super.key, required this.fetchFunction}); + + @override + State createState() => _AddFamilyPersonState(); +} + +class _AddFamilyPersonState extends State { + final _formKey = GlobalKey(); + String? _selectedHouseId; + String? _name; + String? _gender; + String? _phone; + String? _idCard; + String? _memberType; + DateTime? _startDate; + DateTime? _endDate; + List> _houseList = []; + + @override + void initState() { + super.initState(); + _fetchHouseList(); + } + + Future _fetchHouseList() async { + // 获取房屋列表数据 + final response = await GlobalInformation.getInstance().requester.get(resolve("/api/house/list")); + if (response.statusCode == 200) { + final data = jsonDecode(response.body); + setState(() { + _houseList = List>.from(data['data']); + }); + } else { + if (mounted){ + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar(content: Text('获取房屋列表失败')), + ); + } + } + } + + Future _submit() async { + if (_formKey.currentState?.validate() ?? false) { + _formKey.currentState?.save(); + + // 发送添加家属请求 + final response = await GlobalInformation.getInstance().requester.post( + resolve("/api/family/member"), + body: jsonEncode({ + "houseId": _selectedHouseId, + "name": _name, + "sex": _gender, + "telephone": _phone, + "idCard": _idCard, + "memberType": _memberType, + "startDate": _startDate?.toIso8601String(), + "endDate": _endDate?.toIso8601String(), + }), + headers: {"Content-Type": "application/json"}, + ); + if (mounted){ + if (response.statusCode == 200) { + // 处理成功逻辑 + Navigator.of(context).pop(); + widget.fetchFunction(); + } else { + // 处理错误逻辑 + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar(content: Text('添加家属失败,请稍后再试')), + ); + } + } + } + } + + @override + Widget build(BuildContext context) { + return FullPageStruct( + title: "新增家庭成员", + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Form( + key: _formKey, + child: ListView( + children: [ + DropdownButtonFormField( + decoration: const InputDecoration(labelText: '选择房屋'), + value: _selectedHouseId, + onChanged: (value) { + setState(() { + _selectedHouseId = value; + }); + }, + items: _houseList.map((house) { + return DropdownMenuItem( + value: house['id'].toString(), + child: Text(house['address'] ?? '未知地址'), + ); + }).toList(), + validator: (value) => + value == null ? '请选择房屋' : null, + ), + TextFormField( + decoration: const InputDecoration(labelText: '姓名'), + onSaved: (value) => _name = value, + validator: (value) => value == null || value.isEmpty + ? '请输入姓名' + : null, + ), + DropdownButtonFormField( + decoration: const InputDecoration(labelText: '性别'), + value: _gender, + onChanged: (value) { + setState(() { + _gender = value; + }); + }, + items: const [ + DropdownMenuItem(value: "0", child: Text('男')), + DropdownMenuItem(value: "1", child: Text('女')), + ], + validator: (value) => value == null ? '请选择性别' : null, + ), + TextFormField( + decoration: const InputDecoration(labelText: '手机号'), + keyboardType: TextInputType.phone, + onSaved: (value) => _phone = value, + validator: (value) => value == null || value.isEmpty + ? '请输入手机号' + : null, + ), + TextFormField( + decoration: const InputDecoration(labelText: '身份证号'), + onSaved: (value) => _idCard = value, + validator: (value) => value == null || value.isEmpty + ? '请输入身份证号' + : null, + ), + DropdownButtonFormField( + decoration: const InputDecoration(labelText: '住户类型'), + value: _memberType, + onChanged: (value) { + setState(() { + _memberType = value; + }); + }, + items: const [ + DropdownMenuItem(value: "1", child: Text('业主')), + DropdownMenuItem(value: "2", child: Text('租户')), + ], + validator: (value) => + value == null ? '请选择住户类型' : null, + ), + ElevatedButton( + onPressed: _submit, + child: const Text('保存'), + ), + ], + ), + ), + ), + ); + } +} + + +class FamilyPersonInformation extends StatefulWidget { + final int id; + final Function fetchFunction; + const FamilyPersonInformation({super.key, required this.id, required this.fetchFunction}); + + @override + State createState() => _FamilyPersonInformationState(); +} + +class _FamilyPersonInformationState extends State { + final _formKey = GlobalKey(); + String? _selectedHouseId; + String? _name; + String? _gender; + String? _phone; + String? _idCard; + String? _memberType; + List> _houseList = []; + bool _isLoading = true; + + @override + void initState() { + super.initState(); + _fetchFamilyMemberDetails(); + _fetchHouseList(); + } + + Future _fetchFamilyMemberDetails() async { + // 获取家庭成员详情 + final response = await GlobalInformation.getInstance().requester.get(resolve("/api/family/member/${widget.id}")); + if (response.statusCode == 200) { + final data = jsonDecode(response.body)['data']; + setState(() { + _selectedHouseId = data['houseId'].toString(); + _name = data['name']; + _gender = data['sex']; + _phone = data['telephone']; + _idCard = data['idCard']; + _memberType = data['memberType']; + _isLoading = false; + }); + } else { + if (mounted){ + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar(content: Text('获取家庭成员详情失败')), + ); + } + setState(() { + _isLoading = false; + }); + } + } + + Future _fetchHouseList() async { + // 获取房屋列表 + final response = await GlobalInformation.getInstance().requester.get(resolve("/api/house/list")); + if (response.statusCode == 200) { + final data = jsonDecode(response.body); + setState(() { + _houseList = List>.from(data['data']); + }); + } else { + if (mounted){ + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar(content: Text('获取房屋列表失败')), + ); + } + } + } + + Future _submit() async { + if (_formKey.currentState?.validate() ?? false) { + _formKey.currentState?.save(); + + // 发送保存家庭成员修改请求 + final response = await GlobalInformation.getInstance().requester.put( + resolve("/api/family/member"), + body: jsonEncode({ + "id": widget.id, + "houseId": _selectedHouseId, + "name": _name, + "sex": _gender, + "telephone": _phone, + "idCard": _idCard, + "memberType": _memberType, + }), + headers: {"Content-Type": "application/json"}, + ); + if (mounted){ + if (response.statusCode == 200) { + // 处理成功逻辑 + Navigator.of(context).pop(); + widget.fetchFunction(); + } else { + // 处理错误逻辑 + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar(content: Text('保存失败,请稍后再试')), + ); + } + } + } + } + + Future _deleteMember() async { + final response = await GlobalInformation.getInstance().requester.delete( + resolve("/api/family/member/${widget.id}"), + ); + if (mounted){ + if (response.statusCode == 200) { + Navigator.of(context).pop(); + widget.fetchFunction(); + } else { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar(content: Text('删除失败,请稍后再试')), + ); + } + } + } + + @override + Widget build(BuildContext context) { + if (_isLoading) { + return const FullPageStruct( + title: "家庭成员详情", + child: Center(child: CircularProgressIndicator()), + ); + } + + return FullPageStruct( + title: "家庭成员详情", + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Form( + key: _formKey, + child: ListView( + children: [ + DropdownButtonFormField( + decoration: const InputDecoration(labelText: '选择房屋'), + value: _selectedHouseId, + onChanged: (value) { + setState(() { + _selectedHouseId = value; + }); + }, + items: _houseList.map((house) { + return DropdownMenuItem( + value: house['id'].toString(), + child: Text(house['address'] ?? '未知地址'), + ); + }).toList(), + validator: (value) => + value == null ? '请选择房屋' : null, + ), + TextFormField( + initialValue: _name, + decoration: const InputDecoration(labelText: '姓名'), + onSaved: (value) => _name = value, + validator: (value) => value == null || value.isEmpty + ? '请输入姓名' + : null, + ), + DropdownButtonFormField( + decoration: const InputDecoration(labelText: '性别'), + value: _gender, + onChanged: (value) { + setState(() { + _gender = value; + }); + }, + items: const [ + DropdownMenuItem(value: "0", child: Text('男')), + DropdownMenuItem(value: "1", child: Text('女')), + ], + validator: (value) => value == null ? '请选择性别' : null, + ), + TextFormField( + initialValue: _phone, + decoration: const InputDecoration(labelText: '手机号'), + keyboardType: TextInputType.phone, + onSaved: (value) => _phone = value, + validator: (value) => value == null || value.isEmpty + ? '请输入手机号' + : null, + ), + TextFormField( + initialValue: _idCard, + decoration: const InputDecoration(labelText: '身份证号'), + onSaved: (value) => _idCard = value, + validator: (value) => value == null || value.isEmpty + ? '请输入身份证号' + : null, + ), + DropdownButtonFormField( + decoration: const InputDecoration(labelText: '住户类型'), + value: _memberType, + onChanged: (value) { + setState(() { + _memberType = value; + }); + }, + items: const [ + DropdownMenuItem(value: "1", child: Text('业主')), + DropdownMenuItem(value: "2", child: Text('租户')), + ], + validator: (value) => + value == null ? '请选择住户类型' : null, + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + OutlinedButton( + onPressed: _deleteMember, + style: OutlinedButton.styleFrom( + foregroundColor: Colors.red, + ), + child: const Text('删除家庭成员'), + ), + ElevatedButton( + onPressed: _submit, + child: const Text('保存'), + ), + ], + ), + ], + ), + ), + ), + ); + } +} \ No newline at end of file