This commit is contained in:
wzp 2024-08-31 17:44:33 +08:00
parent bd875adc24
commit c3c64c620b
2 changed files with 553 additions and 1 deletions

View File

@ -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,
);
}
}

View File

@ -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<Response> 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<MePage> {
List<Map<String, dynamic>> 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<Widget> 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<AddFamilyPerson> createState() => _AddFamilyPersonState();
}
class _AddFamilyPersonState extends State<AddFamilyPerson> {
final _formKey = GlobalKey<FormState>();
String? _selectedHouseId;
String? _name;
String? _gender;
String? _phone;
String? _idCard;
String? _memberType;
DateTime? _startDate;
DateTime? _endDate;
List<Map<String, dynamic>> _houseList = [];
@override
void initState() {
super.initState();
_fetchHouseList();
}
Future<void> _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<Map<String, dynamic>>.from(data['data']);
});
} else {
if (mounted){
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('获取房屋列表失败')),
);
}
}
}
Future<void> _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<String>(
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<String>(
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<String>(
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<FamilyPersonInformation> createState() => _FamilyPersonInformationState();
}
class _FamilyPersonInformationState extends State<FamilyPersonInformation> {
final _formKey = GlobalKey<FormState>();
String? _selectedHouseId;
String? _name;
String? _gender;
String? _phone;
String? _idCard;
String? _memberType;
List<Map<String, dynamic>> _houseList = [];
bool _isLoading = true;
@override
void initState() {
super.initState();
_fetchFamilyMemberDetails();
_fetchHouseList();
}
Future<void> _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<void> _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<Map<String, dynamic>>.from(data['data']);
});
} else {
if (mounted){
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('获取房屋列表失败')),
);
}
}
}
Future<void> _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<void> _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<String>(
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<String>(
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<String>(
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('保存'),
),
],
),
],
),
),
),
);
}
}