day 4
This commit is contained in:
parent
bd875adc24
commit
c3c64c620b
26
lib/views/common/full_page_struct.dart
Normal file
26
lib/views/common/full_page_struct.dart
Normal 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,
|
||||
);
|
||||
}
|
||||
}
|
@ -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('保存'),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user