2025.7.9 我的功能都完成了
parent
11a6f1627d
commit
4c10dce1a8
|
@ -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)),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
|
|||
import 'package:flutter_html/flutter_html.dart';
|
||||
|
||||
|
||||
|
||||
class HomePage extends StatefulWidget {
|
||||
const HomePage({Key? key}) : super(key: key);
|
||||
|
||||
|
@ -98,7 +99,8 @@ class _HomePageState extends State<HomePage> {
|
|||
alignment: const FractionalOffset(0.5, 1),
|
||||
children: [
|
||||
Padding(
|
||||
padding: EdgeInsetsGeometry.fromLTRB(0, 0, 0, 150),
|
||||
// padding: EdgeInsetsGeometry.fromLTRB(0, 0, 0, 150),
|
||||
padding: EdgeInsets.only(bottom: 150),
|
||||
child: Image.asset(
|
||||
"assets/images/banner.png",
|
||||
width: MediaQuery.of(context).size.width, // 获取屏幕宽度
|
||||
|
@ -137,12 +139,12 @@ class _HomePageState extends State<HomePage> {
|
|||
mainAxisSpacing: 16,
|
||||
// childAspectRatio: 1.5,
|
||||
children: [
|
||||
_buildStatCard('企业信息', "assets/images/ico1.png"),
|
||||
_buildStatCard('双重预防', "assets/images/ico2.png"),
|
||||
_buildStatCard('重点安全', "assets/images/ico4.png"),
|
||||
_buildStatCard('监管帮扶', "assets/images/ico9.png"),
|
||||
_buildStatCard('专项检查', "assets/images/ico8.png"),
|
||||
_buildStatCard('防灾减灾', "assets/images/ico10.png"),
|
||||
_buildStatCard(1,'企业信息', "assets/images/ico1.png"),
|
||||
_buildStatCard(2,'双重预防', "assets/images/ico2.png"),
|
||||
_buildStatCard(3,'重点安全', "assets/images/ico4.png"),
|
||||
_buildStatCard(4,'监管帮扶', "assets/images/ico9.png"),
|
||||
_buildStatCard(5,'专项检查', "assets/images/ico8.png"),
|
||||
_buildStatCard(6,'防灾减灾', "assets/images/ico10.png"),
|
||||
],
|
||||
|
||||
|
||||
|
@ -150,8 +152,28 @@ class _HomePageState extends State<HomePage> {
|
|||
);
|
||||
}
|
||||
|
||||
Widget _buildStatCard(String title, String icon ){
|
||||
return Column(
|
||||
Widget _buildStatCard(int id,String title, String icon ){
|
||||
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,
|
||||
children: [
|
||||
// Container(
|
||||
|
@ -165,13 +187,14 @@ class _HomePageState extends State<HomePage> {
|
|||
// ),
|
||||
// const SizedBox(height: 12),
|
||||
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))
|
||||
)
|
||||
|
||||
],
|
||||
|
||||
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
// ),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -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),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
|
@ -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),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,4 +1,8 @@
|
|||
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 {
|
||||
const MinePage({super.key});
|
||||
|
@ -7,31 +11,7 @@ class MinePage extends StatefulWidget {
|
|||
State<MinePage> createState() => _MinePageState();
|
||||
}
|
||||
|
||||
|
||||
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 passwordChanged = false;
|
||||
|
@ -186,6 +166,7 @@ class _SafetySettingsPageState extends State<SafetySettingsPage> {
|
|||
title: "通知提醒",
|
||||
icon: "assets/images/i2.png",
|
||||
value: notificationsEnabled,
|
||||
num:1,
|
||||
onChanged: (value) => setState(() => notificationsEnabled = value!),
|
||||
),
|
||||
// const Divider(height: 1, indent: 60),
|
||||
|
@ -195,6 +176,7 @@ class _SafetySettingsPageState extends State<SafetySettingsPage> {
|
|||
title: "修改密码",
|
||||
icon: "assets/images/i3.png",
|
||||
value: passwordChanged,
|
||||
num:2,
|
||||
onChanged: (value) => setState(() => passwordChanged = value!),
|
||||
),
|
||||
// const Divider(height: 1, indent: 60),
|
||||
|
@ -204,6 +186,7 @@ class _SafetySettingsPageState extends State<SafetySettingsPage> {
|
|||
title: "版本更新",
|
||||
icon: "assets/images/i5.png",
|
||||
value: updateAvailable,
|
||||
num:3,
|
||||
onChanged: (value) => setState(() => updateAvailable = value!),
|
||||
),
|
||||
// const Divider(height: 1, indent: 60),
|
||||
|
@ -213,11 +196,12 @@ class _SafetySettingsPageState extends State<SafetySettingsPage> {
|
|||
title: "退出登录",
|
||||
icon: "assets/images/i4.png",
|
||||
value: logoutSelected,
|
||||
num:4,
|
||||
onChanged: (value) {
|
||||
setState(() => logoutSelected = value!);
|
||||
if (value == true) {
|
||||
_showLogoutConfirmation();
|
||||
}
|
||||
// if (value == true) {
|
||||
// _showLogoutConfirmation();
|
||||
// }
|
||||
},
|
||||
),
|
||||
],
|
||||
|
@ -229,33 +213,55 @@ class _SafetySettingsPageState extends State<SafetySettingsPage> {
|
|||
required String title,
|
||||
required String icon,
|
||||
required bool value,
|
||||
required int num,
|
||||
required ValueChanged<bool?> onChanged,
|
||||
}) {
|
||||
return 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),
|
||||
),
|
||||
return
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
switch(num){
|
||||
case 1:
|
||||
pushPage(MessagePage(), context);
|
||||
break;
|
||||
case 2:
|
||||
pushPage(ChangePassPage(), context);
|
||||
break;
|
||||
case 3:
|
||||
|
||||
trailing: Transform.scale(
|
||||
scale: 1.2,
|
||||
child: Image.asset(
|
||||
"assets/images/right.png",
|
||||
fit: BoxFit.cover,
|
||||
width: 15,
|
||||
height: 15,
|
||||
break;
|
||||
case 4:
|
||||
_showLogoutConfirmation();
|
||||
break;
|
||||
|
||||
}
|
||||
},
|
||||
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() {
|
||||
|
@ -301,15 +307,19 @@ class _SafetySettingsPageState extends State<SafetySettingsPage> {
|
|||
context: context,
|
||||
builder: (context) => AlertDialog(
|
||||
title: const Text("退出登录"),
|
||||
content: const Text("确定要退出当前账号吗?"),
|
||||
content: const Text("确定要退出登录吗?"),
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
|
||||
actions: [
|
||||
TextButton(
|
||||
ElevatedButton(
|
||||
onPressed: () {
|
||||
setState(() => logoutSelected = false);
|
||||
Navigator.pop(context);
|
||||
},
|
||||
child: const Text("取消"),
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Colors.grey[400],
|
||||
foregroundColor: Colors.white,
|
||||
),
|
||||
child: const Text(" 取消 "),
|
||||
),
|
||||
ElevatedButton(
|
||||
onPressed: () {
|
||||
|
|
|
@ -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),
|
||||
),
|
||||
);
|
||||
}
|
|
@ -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)];
|
||||
}
|
|
@ -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!,
|
||||
),
|
||||
)
|
||||
];
|
||||
}
|
||||
}
|
|
@ -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',
|
||||
);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue