2025.7.9 我的功能都完成了

main
xufei 2025-07-09 14:27:53 +08:00
parent 11a6f1627d
commit 4c10dce1a8
10 changed files with 953 additions and 458 deletions

View File

@ -1,394 +0,0 @@
import 'dart:ui';
import 'package:flutter/material.dart';
class DangerPage extends StatefulWidget {
const DangerPage({super.key});
@override
_DangerPageState createState() => _DangerPageState();
}
class _DangerPageState extends State<DangerPage> {
String _selectedOption = '全部';
final TextEditingController _searchController = TextEditingController();
final List<Map<String, String>> enterprises = [
{
'name': '泰安安全',
'type': '冶金行业',
'unit': '执法一中队',
'status': '已划分'
},
{
'name': '秦皇岛杰瑞科技有限公司',
'type': '轻工行业',
'unit': '执法一中队',
'status': '已划分'
},
{
'name': '秦皇岛异特机械设备有限公司',
'type': '机械行业',
'unit': '执法一中队',
'status': '已划分'
},
{
'name': '秦皇岛利华德科技有限公司',
'type': '机械行业',
'unit': '执法一中队',
'status': '已划分'
},
{
'name': '广东胜捷消防科技有限公司秦皇岛分公司',
'type': '机械行业',
'unit': '执法一中队',
'status': '未划分'
},
{
'name': '河北联技安全系统有限公司',
'type': '轻工行业',
'unit': '执法一中队',
'status': '已划分'
},
{
'name': '秦皇岛市万天科技有限公司',
'type': '轻工行业',
'unit': '执法一中队',
'status': '未划分'
},
{
'name': '秦皇岛市非晶科技有限公司',
'type': '轻工行业',
'unit': '执法一中队',
'status': '已划分'
},
{
'name': '海湾安全技术有限公司',
'type': '轻工行业',
'unit': '执法一中队,西区消防大队',
'status': '已划分'
},
{
'name': '秦皇岛海湾塑胶金属制品有限公司',
'type': '轻工行业',
'unit': '执法一中队',
'status': '未划分'
},
];
List<Map<String, String>> get filteredEnterprises {
if (_searchController.text.isNotEmpty) {
return enterprises
.where((e) => e['name']!.contains(_searchController.text))
.toList();
}
if (_selectedOption == '全部') {
return enterprises;
} else {
return enterprises
.where((e) => e['status'] == _selectedOption)
.toList();
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('企业信息'),
centerTitle: true,
actions: [
IconButton(
icon: const Icon(Icons.filter_alt),
onPressed: () {
//
},
),
],
),
body: Column(
children: [
_buildFunctionButtons(),
_buildSearchSection(),
_buildFilterSection(),
_buildEnterpriseList(),
],
),
);
}
Widget _buildFunctionButtons() {
return Container(
padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 24),
color: Colors.white,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
_buildFunctionButton('监管划分', Icons.assignment),
_buildFunctionButton('信息审核', Icons.verified),
_buildFunctionButton('持证人员', Icons.badge),
],
),
);
}
Widget _buildFunctionButton(String label, IconData icon) {
return Column(
children: [
Container(
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
color: const Color(0xFF0D47A1).withOpacity(0.1),
borderRadius: BorderRadius.circular(12),
),
child: Icon(icon, size: 30, color: const Color(0xFF0D47A1)),
),
const SizedBox(height: 8),
Text(label, style: const TextStyle(fontSize: 14)),
],
);
}
Widget _buildSearchSection() {
return Container(
padding: const EdgeInsets.all(16),
color: Colors.white,
child: Row(
children: [
Expanded(
child: TextField(
controller: _searchController,
decoration: InputDecoration(
hintText: '请输入关键字',
prefixIcon: const Icon(Icons.search),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(30),
borderSide: BorderSide.none,
),
filled: true,
fillColor: Colors.grey[100],
contentPadding: const EdgeInsets.symmetric(
vertical: 12, horizontal: 20),
),
onChanged: (value) {
setState(() {});
},
),
),
const SizedBox(width: 8),
Container(
decoration: BoxDecoration(
color: const Color(0xFF0D47A1),
borderRadius: BorderRadius.circular(30),
),
child: IconButton(
icon: const Icon(Icons.search, color: Colors.white),
onPressed: () {
setState(() {});
},
),
),
],
),
);
}
Widget _buildFilterSection() {
return Container(
padding: const EdgeInsets.all(16),
color: Colors.white,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text('请选择部门', style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)),
const SizedBox(height: 12),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
_buildFilterOption('全部'),
_buildFilterOption('已划分'),
_buildFilterOption('未划分'),
],
),
],
),
);
}
Widget _buildFilterOption(String text) {
final isSelected = _selectedOption == text;
return GestureDetector(
onTap: () {
setState(() {
_selectedOption = text;
});
},
child: Row(
children: [
Container(
width: 20,
height: 20,
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(
color: isSelected ? const Color(0xFF0D47A1) : Colors.grey,
width: 2,
),
),
child: isSelected
? Center(
child: Container(
width: 12,
height: 12,
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: Color(0xFF0D47A1),
),
),
)
: null,
),
const SizedBox(width: 8),
Text(text, style: TextStyle(
fontSize: 16,
color: isSelected ? const Color(0xFF0D47A1) : Colors.grey,
fontWeight: isSelected ? FontWeight.bold : FontWeight.normal,
)),
],
),
);
}
Widget _buildEnterpriseList() {
return Expanded(
child: ListView.builder(
padding: const EdgeInsets.only(top: 8),
itemCount: filteredEnterprises.length,
itemBuilder: (context, index) {
final enterprise = filteredEnterprises[index];
return _buildEnterpriseCard(enterprise);
},
),
);
}
Widget _buildEnterpriseCard(Map<String, String> enterprise) {
return Container(
margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.1),
blurRadius: 8,
offset: const Offset(0, 4),
)
],
),
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
enterprise['name']!,
style: const TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
Container(
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
decoration: BoxDecoration(
color: enterprise['status'] == '已划分'
? const Color(0xFF4CAF50).withOpacity(0.1)
: const Color(0xFFF44336).withOpacity(0.1),
borderRadius: BorderRadius.circular(4),
border: Border.all(
color: enterprise['status'] == '已划分'
? const Color(0xFF4CAF50)
: const Color(0xFFF44336),
width: 1,
),
),
child: Text(
enterprise['status']!,
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.bold,
color: enterprise['status'] == '已划分'
? const Color(0xFF4CAF50)
: const Color(0xFFF44336),
),
),
),
],
),
const SizedBox(height: 12),
Row(
children: [
const Icon(Icons.business, size: 16, color: Colors.grey),
const SizedBox(width: 8),
Text(
'安全监管类型: ${enterprise['type']}',
style: const TextStyle(fontSize: 14, color: Colors.grey),
),
],
),
const SizedBox(height: 8),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Icon(Icons.people, size: 16, color: Colors.grey),
const SizedBox(width: 8),
Expanded(
child: Text(
'管理单位: ${enterprise['unit']}',
style: const TextStyle(fontSize: 14, color: Colors.grey),
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
),
],
),
const SizedBox(height: 8),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
TextButton(
onPressed: () {
//
},
style: TextButton.styleFrom(
foregroundColor: const Color(0xFF0D47A1),
),
child: const Text('查看详情'),
),
const SizedBox(width: 8),
ElevatedButton(
onPressed: () {
//
},
style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFF0D47A1),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
),
child: const Text('处理', style: TextStyle(color: Colors.white)),
),
],
),
],
),
),
);
}
}

View File

@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_html/flutter_html.dart'; import 'package:flutter_html/flutter_html.dart';
class HomePage extends StatefulWidget { class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key); const HomePage({Key? key}) : super(key: key);
@ -98,7 +99,8 @@ class _HomePageState extends State<HomePage> {
alignment: const FractionalOffset(0.5, 1), alignment: const FractionalOffset(0.5, 1),
children: [ children: [
Padding( Padding(
padding: EdgeInsetsGeometry.fromLTRB(0, 0, 0, 150), // padding: EdgeInsetsGeometry.fromLTRB(0, 0, 0, 150),
padding: EdgeInsets.only(bottom: 150),
child: Image.asset( child: Image.asset(
"assets/images/banner.png", "assets/images/banner.png",
width: MediaQuery.of(context).size.width, // width: MediaQuery.of(context).size.width, //
@ -137,12 +139,12 @@ class _HomePageState extends State<HomePage> {
mainAxisSpacing: 16, mainAxisSpacing: 16,
// childAspectRatio: 1.5, // childAspectRatio: 1.5,
children: [ children: [
_buildStatCard('企业信息', "assets/images/ico1.png"), _buildStatCard(1,'企业信息', "assets/images/ico1.png"),
_buildStatCard('双重预防', "assets/images/ico2.png"), _buildStatCard(2,'双重预防', "assets/images/ico2.png"),
_buildStatCard('重点安全', "assets/images/ico4.png"), _buildStatCard(3,'重点安全', "assets/images/ico4.png"),
_buildStatCard('监管帮扶', "assets/images/ico9.png"), _buildStatCard(4,'监管帮扶', "assets/images/ico9.png"),
_buildStatCard('专项检查', "assets/images/ico8.png"), _buildStatCard(5,'专项检查', "assets/images/ico8.png"),
_buildStatCard('防灾减灾', "assets/images/ico10.png"), _buildStatCard(6,'防灾减灾', "assets/images/ico10.png"),
], ],
@ -150,8 +152,28 @@ class _HomePageState extends State<HomePage> {
); );
} }
Widget _buildStatCard(String title, String icon ){ Widget _buildStatCard(int id,String title, String icon ){
return Column( return GestureDetector(
onTap: () {
if(1==id){
// Navigator.pushReplacement(
// context,
// MaterialPageRoute(builder: (context) => const DangerPage()),
// );
}else if(2==id){
}else if(3==id){
}else if(4==id){
}else if(5==id){
}else if(6==id){
}
},
child: Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
// Container( // Container(
@ -165,13 +187,14 @@ class _HomePageState extends State<HomePage> {
// ), // ),
// const SizedBox(height: 12), // const SizedBox(height: 12),
Padding( Padding(
padding: EdgeInsetsGeometry.fromLTRB(0,5,0,0), // padding: EdgeInsetsGeometry.fromLTRB(0,5,0,0),
padding: EdgeInsets.only(top: 5),
child: Text(title, style: const TextStyle(fontSize: 16)) child: Text(title, style: const TextStyle(fontSize: 16))
) )
], ],
),
); );
} }

View File

@ -0,0 +1,232 @@
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:qhdkfq_regulatory_flutter/tools/my_appbar.dart';
class ChangePassPage extends StatefulWidget {
const ChangePassPage({super.key});
@override
_ChangePassPageState createState() => _ChangePassPageState();
}
class _ChangePassPageState extends State<ChangePassPage>
with SingleTickerProviderStateMixin {
final _formKey = GlobalKey<FormState>();
bool _obscureCurrentPassword = true;
bool _obscureNewPassword = true;
bool _obscureConfirmPassword = true;
final TextEditingController _currentPasswordController = TextEditingController();
final TextEditingController _newPasswordController = TextEditingController();
final TextEditingController _confirmPasswordController = TextEditingController();
@override
void dispose() {
_currentPasswordController.dispose();
_newPasswordController.dispose();
_confirmPasswordController.dispose();
super.dispose();
}
void _submitForm() {
if (_formKey.currentState!.validate()) {
//
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('密码修改成功!'),
backgroundColor: Colors.green,
),
);
//
Future.delayed(const Duration(seconds: 1), () {
Navigator.pop(context);
});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: MyAppbar(title: "修改密码"),
body: Padding(
padding: const EdgeInsets.all(10.0),
child: SingleChildScrollView(
padding: const EdgeInsets.all(10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(height: 10),
//
Form(
key: _formKey,
child: Column(
children: [
//
_buildPasswordField(
label: '原密码',
controller: _currentPasswordController,
obscureText: _obscureCurrentPassword,
onToggleVisibility: () {
setState(() {
_obscureCurrentPassword = !_obscureCurrentPassword;
});
},
validator: (value) {
if (value == null || value.isEmpty) {
return '请输入原密码';
}
if (value.length < 6) {
return '密码长度至少为6位';
}
return null;
},
),
const SizedBox(height: 35),
//
_buildPasswordField(
label: '新密码',
controller: _newPasswordController,
obscureText: _obscureNewPassword,
onToggleVisibility: () {
setState(() {
_obscureNewPassword = !_obscureNewPassword;
});
},
validator: (value) {
if (value == null || value.isEmpty) {
return '请输入新密码';
}
if (value.length < 6) {
return '密码长度至少为6位';
}
if (!RegExp(r'[A-Z]').hasMatch(value)) {
return '需包含大写字母';
}
if (!RegExp(r'[0-9]').hasMatch(value)) {
return '需包含数字';
}
return null;
},
),
const SizedBox(height: 35),
//
_buildPasswordField(
label: '确认新密码',
controller: _confirmPasswordController,
obscureText: _obscureConfirmPassword,
onToggleVisibility: () {
setState(() {
_obscureConfirmPassword = !_obscureConfirmPassword;
});
},
validator: (value) {
if (value == null || value.isEmpty) {
return '请确认新密码';
}
if (value != _newPasswordController.text) {
return '两次输入的密码不一致';
}
return null;
},
),
const SizedBox(height: 40),
//
SizedBox(
width: double.infinity,
height: 54,
child: ElevatedButton(
onPressed: _submitForm,
style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFF2196F3),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
elevation: 0,
),
child: const Text(
'确定',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: Colors.white),
),
),
),
],
),
),
],
),
),
),
);
}
Widget _buildPasswordField({
required String label,
required TextEditingController controller,
required bool obscureText,
required VoidCallback onToggleVisibility,
required String? Function(String?)? validator,
}) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
//
Row(
children: [
const Text(
'*',
style: TextStyle(
fontSize: 16,
color: Colors.red,
),
),
const SizedBox(width: 4),
Text(
label,
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.w500,
color: Color(0xFF333333)),
),
],
),
// const SizedBox(height: 8),
//
TextFormField(
controller: controller,
obscureText: obscureText,
validator: validator,
decoration: InputDecoration(
hintText: '请输入$label',
hintStyle: const TextStyle(color: Color(0xFF999999)),
contentPadding: EdgeInsets.symmetric(vertical: 0, horizontal: 12),
// suffixIcon: IconButton(
// icon: Icon(
// obscureText ? Icons.visibility_off : Icons.visibility,
// color: const Color(0xFF999999),
// ),
// onPressed: onToggleVisibility,
// ),
),
),
],
);
}
}

View File

@ -0,0 +1,115 @@
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:qhdkfq_regulatory_flutter/tools/my_appbar.dart';
class MessageDetailPage extends StatefulWidget {
const MessageDetailPage({super.key});
@override
_MessageDetailPageState createState() => _MessageDetailPageState();
}
class _MessageDetailPageState extends State<MessageDetailPage>
with SingleTickerProviderStateMixin {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: MyAppbar(title: "通知详情"),
body: Padding(
padding: const EdgeInsets.all(16.0),
// child: Center(
child: NotificationDetailCard(),
// ),
),
);
}
}
class NotificationDetailCard extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Card(
elevation: 4,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
child: Padding(
padding: const EdgeInsets.all(24),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
//
const Text(
'会议任务下发提醒',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: Color(0xFF333333),
),
),
const SizedBox(height: 16),
//
_buildInfoRow('提醒时间:', '2025-05-30 10:07:42'),
const SizedBox(height: 12),
//
_buildInfoRow('提醒人:', '王朋'),
const SizedBox(height: 12),
// // 线
// const Divider(height: 1, color: Color(0xFFEEEEEE)),
// const SizedBox(height: 24),
//
const Text(
'提醒内容:',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
color: Color(0xFF333333),
),
),
const SizedBox(height: 12),
//
const Text(
'温馨提示任务名称为阿斯顿行动周期2025-05-01至2025-05-31的会议任务已下发请及时进行会议反馈。',
style: TextStyle(
fontSize: 16,
height: 1.5,
color: Color(0xFF666666),
),
),
const SizedBox(height: 32),
],
),
),
);
}
Widget _buildInfoRow(String label, String value) {
return Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
label,
style: const TextStyle(fontSize: 16, color: Color(0xFF666666)),
),
const SizedBox(width: 8),
Expanded(
child: Text(
value,
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
color: Color(0xFF333333),
),
),
),
],
);
}
}

252
lib/mine/message_page.dart Normal file
View File

@ -0,0 +1,252 @@
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:flutter_html/flutter_html.dart';
import 'package:qhdkfq_regulatory_flutter/mine/message_detail_page.dart';
import 'package:qhdkfq_regulatory_flutter/tools/my_appbar.dart';
import 'package:qhdkfq_regulatory_flutter/tools/tools.dart';
class MessagePage extends StatefulWidget {
const MessagePage({super.key});
@override
_MessagePageState createState() => _MessagePageState();
}
class _MessagePageState extends State<MessagePage>
with SingleTickerProviderStateMixin {
final List<NotificationItem> notifications = [
NotificationItem(
type: '会议任务下发提醒',
isRead: false,
time: '2025-05-30 10:07:42',
title: '阿斯顿',
period: '行动周期2025-05-...',
),
NotificationItem(
type: '学习任务下发提醒',
isRead: false,
time: '2025-05-30 10:05:30',
title: '测试附件',
period: '行动周期2025-0-...',
),
NotificationItem(
type: '学习任务下发提醒',
isRead: false,
time: '2025-05-26 14:07:46',
title: '0526-1',
period: '行动周期2025-05-...',
),
NotificationItem(
type: '会议任务下发提醒',
isRead: false,
time: '2025-04-23 17:43:35',
title: '测试423',
period: '行动周期2025-0-...',
),
NotificationItem(
type: '学习任务下发提醒',
isRead: false,
time: '2025-04-23 17:40:44',
title: '测试4.23',
period: '行动周期2025-0-...',
),
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: MyAppbar(title: "通知提醒"),
body:
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const SizedBox(height: 10,),
Container(
width: MediaQuery.of(context).size.width, //
margin: EdgeInsets.only(left: 15,right: 15),
decoration: BoxDecoration(
color: Colors.green,
borderRadius: BorderRadius.circular(6),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.1),
spreadRadius: 2,
blurRadius: 8,
offset: const Offset(0, 4),
),
],
),
padding: EdgeInsets.all(10),
child:
GestureDetector(
onTap: () {
setState(() {
for (int i = 0; i < notifications.length; i++) {
notifications[i].isRead = true;
}
});
},
child: Text(
"一键已读",
textAlign:TextAlign.center,
style: TextStyle(
fontSize: 13,
color: Colors.white,
) ,
),
)
),
Expanded(
child: ListView.builder(
itemCount: notifications.length,
itemBuilder: (context, index) {
final notification = notifications[index];
return NotificationCard(item: notification);
},
),
)
],
),
);
}
}
class NotificationItem {
String type;
bool isRead;
String time;
String title;
String period;
NotificationItem({
required this.type,
required this.isRead,
required this.time,
required this.title,
required this.period,
});
}
class NotificationCard extends StatelessWidget {
final NotificationItem item;
const NotificationCard({super.key, required this.item});
@override
Widget build(BuildContext context) {
return Card(
margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
elevation: 0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
side: const BorderSide(color: Color(0xFFEEEEEE), width: 1),
),
child: Padding(
padding: const EdgeInsets.only(left: 16,top: 16,right: 16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
item.type,
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 16,
),
),
Container(
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2),
decoration: BoxDecoration(
color: item.isRead ? const Color(0xFFF5F5F5) : Colors.blue[50],
borderRadius: BorderRadius.circular(10),
),
child: Text(
item.isRead ? '已读' : '未读',
style: TextStyle(
color: item.isRead ? Colors.grey : Colors.blue,
fontSize: 12,
),
),
),
],
),
const SizedBox(height: 8),
Text(
'提醒时间: ${item.time}',
style: const TextStyle(color: Colors.grey, fontSize: 14),
),
const SizedBox(height: 12),
RichText(
text: TextSpan(
style: DefaultTextStyle.of(context).style,
children: [
const TextSpan(
text: '温馨提示,任务名称为',
style: TextStyle(fontSize: 14),
),
TextSpan(
text: item.title,
style: const TextStyle(
fontSize: 14,
fontWeight: FontWeight.bold,
color: Colors.black
),
),
TextSpan(
text: item.period,
style: const TextStyle(fontSize: 14),
),
],
),
),
// const SizedBox(height: 8),
Align(
alignment: Alignment.centerRight,
child: TextButton(
onPressed: () {
pushPage(MessageDetailPage(), context);
},
style: TextButton.styleFrom(
// padding: EdgeInsets.only(bottom: 0),
minimumSize: Size.zero,
),
child: const Text(
'查看详情',
style: TextStyle(color: Colors.blue),
),
),
),
],
),
),
);
}
}

View File

@ -1,4 +1,8 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:qhdkfq_regulatory_flutter/mine/change_pass_page.dart';
import 'package:qhdkfq_regulatory_flutter/mine/message_page.dart';
import 'package:qhdkfq_regulatory_flutter/tools/tools.dart';
class MinePage extends StatefulWidget { class MinePage extends StatefulWidget {
const MinePage({super.key}); const MinePage({super.key});
@ -7,31 +11,7 @@ class MinePage extends StatefulWidget {
State<MinePage> createState() => _MinePageState(); State<MinePage> createState() => _MinePageState();
} }
class _MinePageState extends State<MinePage> { class _MinePageState extends State<MinePage> {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: '安全设置',
theme: ThemeData(
primarySwatch: Colors.blue,
scaffoldBackgroundColor: const Color(0xFFF5F7FA),
),
home: const SafetySettingsPage(),
);
}
}
class SafetySettingsPage extends StatefulWidget {
const SafetySettingsPage({super.key});
@override
State<SafetySettingsPage> createState() => _SafetySettingsPageState();
}
class _SafetySettingsPageState extends State<SafetySettingsPage> {
// //
bool notificationsEnabled = false; bool notificationsEnabled = false;
bool passwordChanged = false; bool passwordChanged = false;
@ -186,6 +166,7 @@ class _SafetySettingsPageState extends State<SafetySettingsPage> {
title: "通知提醒", title: "通知提醒",
icon: "assets/images/i2.png", icon: "assets/images/i2.png",
value: notificationsEnabled, value: notificationsEnabled,
num:1,
onChanged: (value) => setState(() => notificationsEnabled = value!), onChanged: (value) => setState(() => notificationsEnabled = value!),
), ),
// const Divider(height: 1, indent: 60), // const Divider(height: 1, indent: 60),
@ -195,6 +176,7 @@ class _SafetySettingsPageState extends State<SafetySettingsPage> {
title: "修改密码", title: "修改密码",
icon: "assets/images/i3.png", icon: "assets/images/i3.png",
value: passwordChanged, value: passwordChanged,
num:2,
onChanged: (value) => setState(() => passwordChanged = value!), onChanged: (value) => setState(() => passwordChanged = value!),
), ),
// const Divider(height: 1, indent: 60), // const Divider(height: 1, indent: 60),
@ -204,6 +186,7 @@ class _SafetySettingsPageState extends State<SafetySettingsPage> {
title: "版本更新", title: "版本更新",
icon: "assets/images/i5.png", icon: "assets/images/i5.png",
value: updateAvailable, value: updateAvailable,
num:3,
onChanged: (value) => setState(() => updateAvailable = value!), onChanged: (value) => setState(() => updateAvailable = value!),
), ),
// const Divider(height: 1, indent: 60), // const Divider(height: 1, indent: 60),
@ -213,11 +196,12 @@ class _SafetySettingsPageState extends State<SafetySettingsPage> {
title: "退出登录", title: "退出登录",
icon: "assets/images/i4.png", icon: "assets/images/i4.png",
value: logoutSelected, value: logoutSelected,
num:4,
onChanged: (value) { onChanged: (value) {
setState(() => logoutSelected = value!); setState(() => logoutSelected = value!);
if (value == true) { // if (value == true) {
_showLogoutConfirmation(); // _showLogoutConfirmation();
} // }
}, },
), ),
], ],
@ -229,33 +213,55 @@ class _SafetySettingsPageState extends State<SafetySettingsPage> {
required String title, required String title,
required String icon, required String icon,
required bool value, required bool value,
required int num,
required ValueChanged<bool?> onChanged, required ValueChanged<bool?> onChanged,
}) { }) {
return ListTile( return
leading: Container( GestureDetector(
width: 20, onTap: () {
height: 20, switch(num){
decoration: BoxDecoration( case 1:
color: Colors.white, pushPage(MessagePage(), context);
borderRadius: BorderRadius.circular(10), break;
), case 2:
child: Image.asset(icon ,fit: BoxFit.cover, ), pushPage(ChangePassPage(), context);
), break;
title: Text( case 3:
title,
style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w500),
),
trailing: Transform.scale( break;
scale: 1.2, case 4:
child: Image.asset( _showLogoutConfirmation();
"assets/images/right.png", break;
fit: BoxFit.cover,
width: 15, }
height: 15, },
child: ListTile(
leading: Container(
width: 20,
height: 20,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
),
child: Image.asset(icon ,fit: BoxFit.cover, ),
),
title: Text(
title,
style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w500),
),
trailing: Transform.scale(
scale: 1.2,
child: Image.asset(
"assets/images/right.png",
fit: BoxFit.cover,
width: 15,
height: 15,
),
),
), ),
), );
);
} }
Widget _buildActionButton() { Widget _buildActionButton() {
@ -301,15 +307,19 @@ class _SafetySettingsPageState extends State<SafetySettingsPage> {
context: context, context: context,
builder: (context) => AlertDialog( builder: (context) => AlertDialog(
title: const Text("退出登录"), title: const Text("退出登录"),
content: const Text("确定要退出当前账号吗?"), content: const Text("确定要退出登录吗?"),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
actions: [ actions: [
TextButton( ElevatedButton(
onPressed: () { onPressed: () {
setState(() => logoutSelected = false); setState(() => logoutSelected = false);
Navigator.pop(context); Navigator.pop(context);
}, },
child: const Text("取消"), style: ElevatedButton.styleFrom(
backgroundColor: Colors.grey[400],
foregroundColor: Colors.white,
),
child: const Text(" 取消 "),
), ),
ElevatedButton( ElevatedButton(
onPressed: () { onPressed: () {

View File

@ -0,0 +1,25 @@
import 'dart:ffi';
import 'package:flutter/material.dart';
import 'h_colors.dart';
/// eg:
Widget riskTagText(int level, String title) {
final List<Color> colors = riskLevelTextColors();
if (colors.length <= (level - 1)) {
return SizedBox();
}
return Container(
padding: EdgeInsets.symmetric(vertical: 3, horizontal: 5),
decoration: BoxDecoration(
color: colors[level-1],
borderRadius: const BorderRadius.all(Radius.circular(5)),
),
// color: Colors.,
child: Text(
title,
style: TextStyle(color: Colors.white, fontSize: 14),
),
);
}

11
lib/tools/h_colors.dart Normal file
View File

@ -0,0 +1,11 @@
import 'dart:ffi';
import 'dart:ui';
Color h_backGroundColor() => Color(0xFFFAFAFA);
List<Color> riskLevelTextColors() {
return [Color(0xFFE54D42),Color(0xFFF37B1D),Color(0xFFF9BD08),Color(0xFF3281FF)];
}
List<Color> riskLevelBgColors() {
return [Color(0xFFFADBD9),Color(0xFFFCE6D2),Color(0xFFFDF2CE),Color(0xFFCCE6FF)];
}

87
lib/tools/my_appbar.dart Normal file
View File

@ -0,0 +1,87 @@
import 'package:flutter/material.dart';
import 'dart:io' show Platform;
class MyAppbar extends StatelessWidget implements PreferredSizeWidget {
final String title;
final VoidCallback? onBackPressed;
final Color backgroundColor;
final Color textColor;
final List<Widget>? actions;
final bool isBack;
final bool centerTitle; //
const MyAppbar({
Key? key,
required this.title,
this.onBackPressed,
this.backgroundColor = Colors.blue,
this.textColor = Colors.white,
this.actions,
this.isBack = true,
this.centerTitle = true, //
}) : super(key: key);
//
@override
Size get preferredSize {
// iOS使(44)Android(56)
return Size.fromHeight(Platform.isIOS ? 44.0 : kToolbarHeight);
}
@override
Widget build(BuildContext context) {
return AppBar(
backgroundColor: backgroundColor,
automaticallyImplyLeading: false,
centerTitle: centerTitle,
toolbarHeight: preferredSize.height, // 使
title: Text(
title,
style: TextStyle(
color: textColor,
fontSize: Platform.isIOS ? 17.0 : 18.0, // iOS使
fontWeight: FontWeight.w600, // iOS使
),
),
leading: isBack ? _buildBackButton(context) : null,
actions: _buildActions(),
elevation: Platform.isIOS ? 0 : 4, // iOS
// iOS
shape: Platform.isIOS
? const Border(bottom: BorderSide(color: Colors.black12, width: 0.5))
: null,
);
}
//
Widget _buildBackButton(BuildContext context) {
return Padding(
padding: EdgeInsets.only(left: Platform.isIOS ? 8.0 : 16.0),
child: IconButton(
icon: Icon(
Platform.isIOS ? Icons.arrow_back_ios : Icons.arrow_back,
color: textColor,
size: Platform.isIOS ? 20.0 : 24.0, // iOS使
),
padding: EdgeInsets.zero, //
constraints: const BoxConstraints(), //
onPressed: onBackPressed ?? () => Navigator.of(context).pop(),
),
);
}
//
List<Widget>? _buildActions() {
if (actions == null) return null;
return [
Padding(
padding: EdgeInsets.only(right: Platform.isIOS ? 8.0 : 16.0),
child: Row(
mainAxisSize: MainAxisSize.min,
children: actions!,
),
)
];
}
}

134
lib/tools/tools.dart Normal file
View File

@ -0,0 +1,134 @@
import 'dart:ui';
import 'dart:math';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:package_info_plus/package_info_plus.dart';
int getRandomWithNum(int min, int max) {
final random = Random();
return random.nextInt(max) + min; //
}
double screenWidth(BuildContext context) {
double screenWidth = MediaQuery.of(context).size.width;
return screenWidth;
}
void pushPage(Widget page, BuildContext context) {
Navigator.push(context, MaterialPageRoute(builder: (context) => page));
}
void present(Widget page, BuildContext context) {
Navigator.push(
context,
MaterialPageRoute(
fullscreenDialog: true,
builder: (context) => page,
),
);
}
///
///
/// Text Widget
class HhTextStyleUtils {
/// Text
/// [text]:
/// [color]:
/// [fontSize]: 16.0
/// [bold]: true
static Text mainTitle(
String text, {
Color color = Colors.black,
double fontSize = 16.0,
bool bold = true,
}) {
return Text(
text,
style: TextStyle(
color: color,
fontSize: fontSize,
fontWeight: bold ? FontWeight.bold : FontWeight.normal,
),
);
}
static TextStyle secondaryTitleStyle = TextStyle(color:Colors.black54, fontSize: 15.0);
/// Text
/// [text]:
/// [color]:
/// [fontSize]: 14.0
/// [bold]: false
static Text secondaryTitle(
String text, {
Color color = Colors.black54,
double fontSize = 14.0,
bool bold = false,
}) {
return Text(
text,
style: TextStyle(
color: color,
fontSize: fontSize,
fontWeight: bold ? FontWeight.bold : FontWeight.normal,
),
);
}
/// Text
/// [text]:
/// [color]:
/// [fontSize]: 12.0
/// [bold]: false
static Text smallText(
String text, {
Color color = Colors.black54,
double fontSize = 12.0,
bool bold = false,
}) {
return Text(
text,
style: TextStyle(
color: color,
fontSize: fontSize,
fontWeight: bold ? FontWeight.bold : FontWeight.normal,
),
);
}
}
///
class AppVersionInfo {
final String versionName; // 1.0.0
final String buildNumber; // 1
final String fullVersion; // 1.0.0+1
AppVersionInfo({
required this.versionName,
required this.buildNumber,
required this.fullVersion,
});
@override
String toString() {
return fullVersion;
}
}
//
Future<AppVersionInfo> getAppVersion() async {
try {
final packageInfo = await PackageInfo.fromPlatform();
return AppVersionInfo(
versionName: packageInfo.version,
buildNumber: packageInfo.buildNumber,
fullVersion: '${packageInfo.version}+${packageInfo.buildNumber}',
);
} catch (e) {
//
return AppVersionInfo(
versionName: '1.0.0',
buildNumber: '1',
fullVersion: '1.0.0+0',
);
}
}