2025.7.16 备份
parent
d0307e7f09
commit
102b5b7011
|
|
@ -221,4 +221,62 @@ U6Hzm1ninpWeE+awIDAQAB
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///TODO -------------–-------------------- 我的 -------------–--------------------
|
||||||
|
|
||||||
|
/// 问题反馈
|
||||||
|
static Future<Map<String, dynamic>> setFeedBack(String backTitle,String backContent,String backType,String imgPaths) {
|
||||||
|
return HttpManager().request(
|
||||||
|
basePath,
|
||||||
|
'/app/feedback/upload',
|
||||||
|
method: Method.post,
|
||||||
|
data: {
|
||||||
|
"FEEDBACK_TITLE":backTitle,
|
||||||
|
"FEEDBACK_CONTENT":backContent,
|
||||||
|
"FEEDBACK_TYPE":backType,
|
||||||
|
"FEEDBACK_IMG" :imgPaths,
|
||||||
|
"loginUserId":SessionService.instance.loginUserId,
|
||||||
|
"CORPINFO_ID":SessionService.instance.corpinfoId,
|
||||||
|
"USER_ID":SessionService.instance.loginUserId,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 修改密码
|
||||||
|
static Future<Map<String, dynamic>> changePassWord(String oldPwd,String confirmPwd) {
|
||||||
|
return HttpManager().request(
|
||||||
|
basePath,
|
||||||
|
'/app/user/editUserPwd',
|
||||||
|
method: Method.post,
|
||||||
|
data: {
|
||||||
|
"USERNAME": SessionService.instance.loginUser?["USERNAME"]??"",
|
||||||
|
"PASSWORD": oldPwd,
|
||||||
|
"NOWPASSWORD": confirmPwd,
|
||||||
|
"CORPINFO_ID":SessionService.instance.corpinfoId,
|
||||||
|
"USER_ID":SessionService.instance.loginUserId,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 获取离岗管理列表
|
||||||
|
static Future<Map<String, dynamic>> getDutyManagement(int showCount, int currentPage) {
|
||||||
|
return HttpManager().request(
|
||||||
|
basePath,
|
||||||
|
'/app/user/editUserPwd?showCount=$showCount¤tPage=$currentPage',
|
||||||
|
method: Method.post,
|
||||||
|
data: {
|
||||||
|
"CORPINFO_ID":SessionService.instance.corpinfoId,
|
||||||
|
"USER_ID":SessionService.instance.loginUserId,
|
||||||
|
// ISMAIN:loginUser.ISMAIN,
|
||||||
|
// ISSUPERVISE:loginUser.ISSUPERVISE,
|
||||||
|
"DEPARTMENT_ID":SessionService.instance.deptId,
|
||||||
|
"TYPE": 'edit'
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,61 @@
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:qhd_prevention/pages/my_appbar.dart';
|
||||||
|
import 'package:qhd_prevention/tools/h_colors.dart';
|
||||||
|
|
||||||
|
import '../../tools/tools.dart';
|
||||||
|
import 'mine_departure_record.dart';
|
||||||
|
import 'mine_duty_management.dart';
|
||||||
|
|
||||||
|
|
||||||
|
class MineDepartureListPage extends StatelessWidget {
|
||||||
|
const MineDepartureListPage({super.key});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: MyAppbar(title: "离岗"),
|
||||||
|
backgroundColor: h_backGroundColor(),
|
||||||
|
body: Column(
|
||||||
|
children: [
|
||||||
|
GestureDetector(
|
||||||
|
child: _setItemWidget("离岗管理"),
|
||||||
|
onTap: () {
|
||||||
|
pushPage(MineDutyManagementPage(), context);
|
||||||
|
|
||||||
|
},
|
||||||
|
),
|
||||||
|
|
||||||
|
Divider(height: 1, color: Colors.black12),
|
||||||
|
GestureDetector(
|
||||||
|
child: _setItemWidget("离岗记录"),
|
||||||
|
onTap: () {
|
||||||
|
// pushPage(MineSignPage(), context);
|
||||||
|
pushPage(MineDepartureRecordPage(), context);
|
||||||
|
}
|
||||||
|
),
|
||||||
|
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _setItemWidget(final String text) {
|
||||||
|
return Container(
|
||||||
|
height: 55,
|
||||||
|
color: Colors.white,
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.all(15),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Text(text, style: TextStyle(fontSize: 16)),
|
||||||
|
Icon(Icons.chevron_right),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,249 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
|
import 'package:qhd_prevention/pages/my_appbar.dart';
|
||||||
|
|
||||||
|
import '../../tools/tools.dart';
|
||||||
|
import 'mine_duty_application.dart';
|
||||||
|
import 'mine_duty_detail.dart';
|
||||||
|
|
||||||
|
class LeaveRecord {
|
||||||
|
final String applicant;
|
||||||
|
final String department;
|
||||||
|
final String position;
|
||||||
|
final DateTime startDate;
|
||||||
|
final DateTime endDate;
|
||||||
|
final String status;
|
||||||
|
final Color statusColor;
|
||||||
|
|
||||||
|
LeaveRecord({
|
||||||
|
required this.applicant,
|
||||||
|
required this.department,
|
||||||
|
required this.position,
|
||||||
|
required this.startDate,
|
||||||
|
required this.endDate,
|
||||||
|
required this.status,
|
||||||
|
required this.statusColor,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
class MineDepartureRecordPage extends StatefulWidget {
|
||||||
|
const MineDepartureRecordPage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<MineDepartureRecordPage> createState() => _MineDepartureRecordPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _MineDepartureRecordPage extends State<MineDepartureRecordPage> {
|
||||||
|
|
||||||
|
Future<void> _onRefresh() async {
|
||||||
|
// 模拟网络请求
|
||||||
|
await Future.delayed(const Duration(seconds: 2));
|
||||||
|
// 刷新数据逻辑,如 fetchData()
|
||||||
|
setState(() {
|
||||||
|
// TODO: 更新数据源
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
|
||||||
|
// 模拟数据
|
||||||
|
final leaveRecords = [
|
||||||
|
LeaveRecord(
|
||||||
|
applicant: "王轩",
|
||||||
|
department: "测试部",
|
||||||
|
position: "测试员",
|
||||||
|
startDate: DateTime(2025, 7, 18),
|
||||||
|
endDate: DateTime(2025, 7, 18),
|
||||||
|
status: "无需审批",
|
||||||
|
statusColor: const Color(0xFF4CAF50),
|
||||||
|
),
|
||||||
|
LeaveRecord(
|
||||||
|
applicant: "王轩",
|
||||||
|
department: "测试部",
|
||||||
|
position: "测试员",
|
||||||
|
startDate: DateTime(2025, 7, 16),
|
||||||
|
endDate: DateTime(2025, 7, 16),
|
||||||
|
status: "无需审批",
|
||||||
|
statusColor: const Color(0xFF4CAF50),
|
||||||
|
),
|
||||||
|
LeaveRecord(
|
||||||
|
applicant: "李思",
|
||||||
|
department: "开发部",
|
||||||
|
position: "高级工程师",
|
||||||
|
startDate: DateTime(2025, 7, 20),
|
||||||
|
endDate: DateTime(2025, 7, 22),
|
||||||
|
status: "待审批",
|
||||||
|
statusColor: const Color(0xFFF57C00),
|
||||||
|
),
|
||||||
|
LeaveRecord(
|
||||||
|
applicant: "张伟",
|
||||||
|
department: "产品部",
|
||||||
|
position: "产品经理",
|
||||||
|
startDate: DateTime(2025, 7, 15),
|
||||||
|
endDate: DateTime(2025, 7, 17),
|
||||||
|
status: "已拒绝",
|
||||||
|
statusColor: const Color(0xFFF44336),
|
||||||
|
),
|
||||||
|
];
|
||||||
|
|
||||||
|
return Scaffold(
|
||||||
|
backgroundColor: const Color(0xFFF5F7FA),
|
||||||
|
appBar: MyAppbar(title: "离岗记录"),
|
||||||
|
body:
|
||||||
|
RefreshIndicator(
|
||||||
|
onRefresh: _onRefresh,
|
||||||
|
child:
|
||||||
|
// 记录列表
|
||||||
|
Expanded(
|
||||||
|
child: ListView.builder(
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 16),
|
||||||
|
itemCount: leaveRecords.length,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
final record = leaveRecords[index];
|
||||||
|
return _buildRecordCard(record,context);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
// ),
|
||||||
|
// ],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildRecordCard(LeaveRecord record, BuildContext context) {
|
||||||
|
final dateFormat = DateFormat('yyyy-MM-dd');
|
||||||
|
final isSameDay = record.startDate == record.endDate;
|
||||||
|
final dateRange = isSameDay
|
||||||
|
? dateFormat.format(record.startDate)
|
||||||
|
: "${dateFormat.format(record.startDate)} 至 ${dateFormat.format(record.endDate)}";
|
||||||
|
|
||||||
|
return
|
||||||
|
// GestureDetector(
|
||||||
|
// onTap: () {
|
||||||
|
// pushPage(MineDutyDetailPage(), context);
|
||||||
|
// },
|
||||||
|
// child:
|
||||||
|
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),
|
||||||
|
spreadRadius: 1,
|
||||||
|
blurRadius: 6,
|
||||||
|
offset: const Offset(0, 2),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(16),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
// 申请人信息
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
// Container(
|
||||||
|
// width: 40,
|
||||||
|
// height: 40,
|
||||||
|
// decoration: BoxDecoration(
|
||||||
|
// color: const Color(0xFFE3F2FD),
|
||||||
|
// shape: BoxShape.circle,
|
||||||
|
// ),
|
||||||
|
// child: const Icon(Icons.person, color: Color(0xFF1976D2)),
|
||||||
|
// ),
|
||||||
|
// const SizedBox(width: 12),
|
||||||
|
Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
"申请人:${record.applicant}",
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 4),
|
||||||
|
Text(
|
||||||
|
"部门:${record.department} \n岗位:${record.position}",
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 13,
|
||||||
|
color: Colors.grey[600],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const Spacer(),
|
||||||
|
Container(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: record.statusColor.withOpacity(0.1),
|
||||||
|
borderRadius: BorderRadius.circular(20),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
record.status,
|
||||||
|
style: TextStyle(
|
||||||
|
color: record.statusColor,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
|
||||||
|
// 离岗时间
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
const Icon(Icons.calendar_today, size: 18, color: Colors.grey),
|
||||||
|
const SizedBox(width: 8),
|
||||||
|
Text(
|
||||||
|
"离岗时间: $dateRange",
|
||||||
|
style: const TextStyle(color: Colors.grey),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
|
||||||
|
// 操作按钮
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
|
children: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: () {
|
||||||
|
pushPage(MineDutyDetailPage(), context);
|
||||||
|
},
|
||||||
|
style: TextButton.styleFrom(
|
||||||
|
foregroundColor: const Color(0xFF1976D2),
|
||||||
|
),
|
||||||
|
child: const Text("查看详情"),
|
||||||
|
),
|
||||||
|
// const SizedBox(width: 16),
|
||||||
|
// if (record.status == "待审批")
|
||||||
|
// ElevatedButton(
|
||||||
|
// onPressed: () {},
|
||||||
|
// style: ElevatedButton.styleFrom(
|
||||||
|
// backgroundColor: const Color(0xFF1976D2),
|
||||||
|
// padding: const EdgeInsets.symmetric(horizontal: 20),
|
||||||
|
// ),
|
||||||
|
// child: const Text("审批", style: TextStyle(color: Colors.white)),
|
||||||
|
// )
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
// ),
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,264 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
|
import 'package:qhd_prevention/pages/my_appbar.dart';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class MineDutyApplicationPage extends StatefulWidget {
|
||||||
|
const MineDutyApplicationPage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<MineDutyApplicationPage> createState() => _MineDutyApplicationPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _MineDutyApplicationPage extends State<MineDutyApplicationPage> {
|
||||||
|
DateTime? _startDate;
|
||||||
|
DateTime? _endDate;
|
||||||
|
final TextEditingController _reasonController = TextEditingController();
|
||||||
|
final String _applicant = "王轩";
|
||||||
|
|
||||||
|
Future<void> _selectDate(BuildContext context, bool isStartDate) async {
|
||||||
|
final DateTime? picked = await showDatePicker(
|
||||||
|
context: context,
|
||||||
|
initialDate: DateTime.now(),
|
||||||
|
firstDate: DateTime(2000),
|
||||||
|
lastDate: DateTime(2100),
|
||||||
|
builder: (BuildContext context, Widget? child) {
|
||||||
|
return Theme(
|
||||||
|
data: ThemeData.light().copyWith(
|
||||||
|
colorScheme: const ColorScheme.light(
|
||||||
|
primary: Color(0xFF1976D2),
|
||||||
|
// buttonTheme: ButtonThemeData(
|
||||||
|
// textTheme: ButtonTextTheme.primary,
|
||||||
|
// ),
|
||||||
|
),
|
||||||
|
|
||||||
|
),
|
||||||
|
child: child!,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
if (picked != null) {
|
||||||
|
setState(() {
|
||||||
|
if (isStartDate) {
|
||||||
|
_startDate = picked;
|
||||||
|
// 如果结束日期早于开始日期,自动更新结束日期
|
||||||
|
if (_endDate == null || _endDate!.isBefore(picked)) {
|
||||||
|
_endDate = picked;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 确保结束日期不早于开始日期
|
||||||
|
if (_startDate != null && picked.isBefore(_startDate!)) {
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
const SnackBar(content: Text('结束日期不能早于开始日期'))
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
_endDate = picked;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _submitApplication() {
|
||||||
|
if (_startDate == null || _endDate == null) {
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
const SnackBar(content: Text('请选择离岗时间'))
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_reasonController.text.isEmpty) {
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
const SnackBar(content: Text('请输入离岗原因'))
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提交申请逻辑
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => AlertDialog(
|
||||||
|
title: const Text('申请提交成功'),
|
||||||
|
content: const Text('您的离岗申请已成功提交,请等待审批'),
|
||||||
|
actions: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.pop(context); // 关闭对话框
|
||||||
|
Navigator.pop(context); // 返回上一页
|
||||||
|
},
|
||||||
|
child: const Text("确定"),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
backgroundColor: const Color(0xFFF5F7FA),
|
||||||
|
appBar:MyAppbar(title: "离岗申请"),
|
||||||
|
body: SingleChildScrollView(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 20),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
// 离岗开始时间
|
||||||
|
_buildDateField(
|
||||||
|
label: "离岗开始时间",
|
||||||
|
date: _startDate,
|
||||||
|
onTap: () => _selectDate(context, true),
|
||||||
|
),
|
||||||
|
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
|
||||||
|
// 离岗结束时间
|
||||||
|
_buildDateField(
|
||||||
|
label: "离岗结束时间",
|
||||||
|
date: _endDate,
|
||||||
|
onTap: () => _selectDate(context, false),
|
||||||
|
),
|
||||||
|
|
||||||
|
const SizedBox(height: 24),
|
||||||
|
|
||||||
|
// 离岗原因标题
|
||||||
|
const Text(
|
||||||
|
"离岗原因",
|
||||||
|
style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
|
||||||
|
// 原因输入框
|
||||||
|
Container(
|
||||||
|
padding: const EdgeInsets.all(16),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
boxShadow: [
|
||||||
|
BoxShadow(
|
||||||
|
color: Colors.grey.withOpacity(0.1),
|
||||||
|
spreadRadius: 1,
|
||||||
|
blurRadius: 6,
|
||||||
|
offset: const Offset(0, 2),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
child: TextField(
|
||||||
|
controller: _reasonController,
|
||||||
|
maxLines: 5,
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
hintText: "请输入离岗原因",
|
||||||
|
hintStyle: TextStyle(color: Color(0xFF9E9E9E)),
|
||||||
|
border: InputBorder.none,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const SizedBox(height: 24),
|
||||||
|
|
||||||
|
// 申请人信息
|
||||||
|
_buildInfoRow("申请人", _applicant),
|
||||||
|
|
||||||
|
const SizedBox(height: 40),
|
||||||
|
|
||||||
|
// 提交按钮
|
||||||
|
SizedBox(
|
||||||
|
width: double.infinity,
|
||||||
|
child: TextButton(
|
||||||
|
onPressed: _submitApplication,
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
backgroundColor: const Color(0xFF1976D2),
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 16),
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
"提交",
|
||||||
|
style: TextStyle(fontSize: 16, color: Colors.white),
|
||||||
|
),
|
||||||
|
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildDateField({
|
||||||
|
required String label,
|
||||||
|
required DateTime? date,
|
||||||
|
required VoidCallback onTap,
|
||||||
|
}) {
|
||||||
|
return GestureDetector(
|
||||||
|
onTap: onTap,
|
||||||
|
child: Container(
|
||||||
|
padding: const EdgeInsets.all(16),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
boxShadow: [
|
||||||
|
BoxShadow(
|
||||||
|
color: Colors.grey.withOpacity(0.1),
|
||||||
|
spreadRadius: 1,
|
||||||
|
blurRadius: 6,
|
||||||
|
offset: const Offset(0, 2),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
label,
|
||||||
|
style: const TextStyle(fontSize: 16),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
date != null ? DateFormat('yyyy-MM-dd').format(date) : "请选择日期",
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
color: date != null ? Colors.black : const Color(0xFF9E9E9E),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildInfoRow(String title, String value) {
|
||||||
|
return Container(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
boxShadow: [
|
||||||
|
BoxShadow(
|
||||||
|
color: Colors.grey.withOpacity(0.1),
|
||||||
|
spreadRadius: 1,
|
||||||
|
blurRadius: 6,
|
||||||
|
offset: const Offset(0, 2),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
title,
|
||||||
|
style: const TextStyle(fontSize: 16),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
value,
|
||||||
|
style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w500),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,203 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
|
import 'package:qhd_prevention/pages/my_appbar.dart';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class MineDutyDetailPage extends StatefulWidget {
|
||||||
|
const MineDutyDetailPage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<MineDutyDetailPage> createState() => _MineDutyDetailPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _MineDutyDetailPage extends State<MineDutyDetailPage> {
|
||||||
|
DateTime? _startDate;
|
||||||
|
DateTime? _endDate;
|
||||||
|
final TextEditingController _reasonController = TextEditingController();
|
||||||
|
final String _applicant = "王轩";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
backgroundColor: const Color(0xFFF5F7FA),
|
||||||
|
appBar:MyAppbar(title: "离岗详情"),
|
||||||
|
body: SingleChildScrollView(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 20),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
|
||||||
|
|
||||||
|
// 申请人信息
|
||||||
|
_buildInfoRow("申请人", _applicant),
|
||||||
|
const SizedBox(height: 24),
|
||||||
|
|
||||||
|
// 离岗开始时间
|
||||||
|
_buildDateField(
|
||||||
|
label: "离岗开始时间",
|
||||||
|
date: _startDate,
|
||||||
|
onTap: () {
|
||||||
|
|
||||||
|
}
|
||||||
|
// () => _selectDate(context, true),
|
||||||
|
),
|
||||||
|
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
|
||||||
|
// 离岗结束时间
|
||||||
|
_buildDateField(
|
||||||
|
label: "离岗结束时间",
|
||||||
|
date: _endDate,
|
||||||
|
onTap: () {
|
||||||
|
|
||||||
|
},
|
||||||
|
// () => _selectDate(context, false),
|
||||||
|
),
|
||||||
|
|
||||||
|
const SizedBox(height: 24),
|
||||||
|
|
||||||
|
// 离岗原因标题
|
||||||
|
const Text(
|
||||||
|
"离岗原因",
|
||||||
|
style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
|
||||||
|
// 原因输入框
|
||||||
|
Container(
|
||||||
|
width: double.infinity,
|
||||||
|
padding: const EdgeInsets.all(16),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
boxShadow: [
|
||||||
|
BoxShadow(
|
||||||
|
color: Colors.grey.withOpacity(0.1),
|
||||||
|
spreadRadius: 1,
|
||||||
|
blurRadius: 6,
|
||||||
|
offset: const Offset(0, 2),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
"原因",style: TextStyle(color: Colors.black),
|
||||||
|
// controller: _reasonController,
|
||||||
|
// maxLines: 5,
|
||||||
|
// decoration: const InputDecoration(
|
||||||
|
// hintText: "请输入离岗原因",
|
||||||
|
// hintStyle: TextStyle(color: Color(0xFF9E9E9E)),
|
||||||
|
// border: InputBorder.none,
|
||||||
|
// ),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
|
||||||
|
const SizedBox(height: 24),
|
||||||
|
// 申请人信息
|
||||||
|
_buildInfoRow("审批状态", "无需审批"),
|
||||||
|
|
||||||
|
|
||||||
|
const SizedBox(height: 40),
|
||||||
|
|
||||||
|
// 提交按钮
|
||||||
|
SizedBox(
|
||||||
|
width: double.infinity,
|
||||||
|
child: TextButton(
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.pop(context);
|
||||||
|
},
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
backgroundColor: const Color(0xFF1976D2),
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 16),
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
"返回",
|
||||||
|
style: TextStyle(fontSize: 16, color: Colors.white),
|
||||||
|
),
|
||||||
|
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildDateField({
|
||||||
|
required String label,
|
||||||
|
required DateTime? date,
|
||||||
|
required VoidCallback onTap,
|
||||||
|
}) {
|
||||||
|
return GestureDetector(
|
||||||
|
onTap: onTap,
|
||||||
|
child: Container(
|
||||||
|
padding: const EdgeInsets.all(16),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
boxShadow: [
|
||||||
|
BoxShadow(
|
||||||
|
color: Colors.grey.withOpacity(0.1),
|
||||||
|
spreadRadius: 1,
|
||||||
|
blurRadius: 6,
|
||||||
|
offset: const Offset(0, 2),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
label,
|
||||||
|
style: const TextStyle(fontSize: 16),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
date != null ? DateFormat('yyyy-MM-dd').format(date) : "请选择日期",
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
color: date != null ? Colors.black : const Color(0xFF9E9E9E),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildInfoRow(String title, String value) {
|
||||||
|
return Container(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
boxShadow: [
|
||||||
|
BoxShadow(
|
||||||
|
color: Colors.grey.withOpacity(0.1),
|
||||||
|
spreadRadius: 1,
|
||||||
|
blurRadius: 6,
|
||||||
|
offset: const Offset(0, 2),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
title,
|
||||||
|
style: const TextStyle(fontSize: 16),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
value,
|
||||||
|
style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w500),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,331 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
|
import 'package:qhd_prevention/pages/my_appbar.dart';
|
||||||
|
|
||||||
|
import '../../http/ApiService.dart';
|
||||||
|
import '../../tools/tools.dart';
|
||||||
|
import 'mine_duty_application.dart';
|
||||||
|
import 'mine_duty_detail.dart';
|
||||||
|
|
||||||
|
class LeaveRecord {
|
||||||
|
final String applicant;
|
||||||
|
final String department;
|
||||||
|
final String position;
|
||||||
|
final DateTime startDate;
|
||||||
|
final DateTime endDate;
|
||||||
|
final String status;
|
||||||
|
final Color statusColor;
|
||||||
|
|
||||||
|
LeaveRecord({
|
||||||
|
required this.applicant,
|
||||||
|
required this.department,
|
||||||
|
required this.position,
|
||||||
|
required this.startDate,
|
||||||
|
required this.endDate,
|
||||||
|
required this.status,
|
||||||
|
required this.statusColor,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
class MineDutyManagementPage extends StatefulWidget {
|
||||||
|
const MineDutyManagementPage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<MineDutyManagementPage> createState() => _MineDutyManagementPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _MineDutyManagementPageState extends State<MineDutyManagementPage> {
|
||||||
|
|
||||||
|
int showCount=-1;
|
||||||
|
int currentPage=1;
|
||||||
|
|
||||||
|
Future<void> _onRefresh() async {
|
||||||
|
// 模拟网络请求
|
||||||
|
await Future.delayed(const Duration(seconds: 2));
|
||||||
|
// 刷新数据逻辑,如 fetchData()
|
||||||
|
setState(() {
|
||||||
|
// TODO: 更新数据源
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
_getListData();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
|
||||||
|
// 模拟数据
|
||||||
|
final leaveRecords = [
|
||||||
|
LeaveRecord(
|
||||||
|
applicant: "王轩",
|
||||||
|
department: "测试部",
|
||||||
|
position: "测试员",
|
||||||
|
startDate: DateTime(2025, 7, 18),
|
||||||
|
endDate: DateTime(2025, 7, 18),
|
||||||
|
status: "无需审批",
|
||||||
|
statusColor: const Color(0xFF4CAF50),
|
||||||
|
),
|
||||||
|
LeaveRecord(
|
||||||
|
applicant: "王轩",
|
||||||
|
department: "测试部",
|
||||||
|
position: "测试员",
|
||||||
|
startDate: DateTime(2025, 7, 16),
|
||||||
|
endDate: DateTime(2025, 7, 16),
|
||||||
|
status: "无需审批",
|
||||||
|
statusColor: const Color(0xFF4CAF50),
|
||||||
|
),
|
||||||
|
LeaveRecord(
|
||||||
|
applicant: "李思",
|
||||||
|
department: "开发部",
|
||||||
|
position: "高级工程师",
|
||||||
|
startDate: DateTime(2025, 7, 20),
|
||||||
|
endDate: DateTime(2025, 7, 22),
|
||||||
|
status: "待审批",
|
||||||
|
statusColor: const Color(0xFFF57C00),
|
||||||
|
),
|
||||||
|
LeaveRecord(
|
||||||
|
applicant: "张伟",
|
||||||
|
department: "产品部",
|
||||||
|
position: "产品经理",
|
||||||
|
startDate: DateTime(2025, 7, 15),
|
||||||
|
endDate: DateTime(2025, 7, 17),
|
||||||
|
status: "已拒绝",
|
||||||
|
statusColor: const Color(0xFFF44336),
|
||||||
|
),
|
||||||
|
];
|
||||||
|
|
||||||
|
return Scaffold(
|
||||||
|
backgroundColor: const Color(0xFFF5F7FA),
|
||||||
|
appBar: MyAppbar(title: "离岗管理",actions: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: () {
|
||||||
|
pushPage(MineDutyApplicationPage(), context);
|
||||||
|
},
|
||||||
|
child: Text("申请",style: TextStyle(color: Colors.white,fontSize: 16,fontWeight:FontWeight.bold),))
|
||||||
|
],),
|
||||||
|
body:
|
||||||
|
RefreshIndicator(
|
||||||
|
onRefresh: _onRefresh,
|
||||||
|
child:
|
||||||
|
// Column(
|
||||||
|
// children: [
|
||||||
|
// 顶部信息栏
|
||||||
|
// Container(
|
||||||
|
// padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
||||||
|
// color: const Color(0xFFE3F2FD),
|
||||||
|
// child: const Row(
|
||||||
|
// children: [
|
||||||
|
// Icon(Icons.info_outline, color: Color(0xFF1976D2)),
|
||||||
|
// SizedBox(width: 8),
|
||||||
|
// Text(
|
||||||
|
// "离岗记录显示最近30天内的申请记录",
|
||||||
|
// style: TextStyle(color: Color(0xFF1976D2), fontSize: 14),
|
||||||
|
// ),
|
||||||
|
// ],
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
|
||||||
|
// 记录列表
|
||||||
|
Expanded(
|
||||||
|
child: ListView.builder(
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 16),
|
||||||
|
itemCount: leaveRecords.length,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
final record = leaveRecords[index];
|
||||||
|
return _buildRecordCard(record,context);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
// ),
|
||||||
|
// ],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildRecordCard(LeaveRecord record, BuildContext context) {
|
||||||
|
final dateFormat = DateFormat('yyyy-MM-dd');
|
||||||
|
final isSameDay = record.startDate == record.endDate;
|
||||||
|
final dateRange = isSameDay
|
||||||
|
? dateFormat.format(record.startDate)
|
||||||
|
: "${dateFormat.format(record.startDate)} 至 ${dateFormat.format(record.endDate)}";
|
||||||
|
|
||||||
|
return
|
||||||
|
// GestureDetector(
|
||||||
|
// onTap: () {
|
||||||
|
// pushPage(MineDutyDetailPage(), context);
|
||||||
|
// },
|
||||||
|
// child:
|
||||||
|
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),
|
||||||
|
spreadRadius: 1,
|
||||||
|
blurRadius: 6,
|
||||||
|
offset: const Offset(0, 2),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(16),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
// 申请人信息
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
// Container(
|
||||||
|
// width: 40,
|
||||||
|
// height: 40,
|
||||||
|
// decoration: BoxDecoration(
|
||||||
|
// color: const Color(0xFFE3F2FD),
|
||||||
|
// shape: BoxShape.circle,
|
||||||
|
// ),
|
||||||
|
// child: const Icon(Icons.person, color: Color(0xFF1976D2)),
|
||||||
|
// ),
|
||||||
|
// const SizedBox(width: 12),
|
||||||
|
Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
"申请人:${record.applicant}",
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 4),
|
||||||
|
Text(
|
||||||
|
"部门:${record.department} \n岗位:${record.position}",
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 13,
|
||||||
|
color: Colors.grey[600],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const Spacer(),
|
||||||
|
Container(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: record.statusColor.withOpacity(0.1),
|
||||||
|
borderRadius: BorderRadius.circular(20),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
record.status,
|
||||||
|
style: TextStyle(
|
||||||
|
color: record.statusColor,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
|
||||||
|
// 离岗时间
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
const Icon(Icons.calendar_today, size: 18, color: Colors.grey),
|
||||||
|
const SizedBox(width: 8),
|
||||||
|
Text(
|
||||||
|
"离岗时间: $dateRange",
|
||||||
|
style: const TextStyle(color: Colors.grey),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
|
||||||
|
// 操作按钮
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
|
children: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: () {
|
||||||
|
pushPage(MineDutyDetailPage(), context);
|
||||||
|
},
|
||||||
|
style: TextButton.styleFrom(
|
||||||
|
foregroundColor: const Color(0xFF1976D2),
|
||||||
|
),
|
||||||
|
child: const Text("查看详情"),
|
||||||
|
),
|
||||||
|
// const SizedBox(width: 16),
|
||||||
|
// if (record.status == "待审批")
|
||||||
|
// ElevatedButton(
|
||||||
|
// onPressed: () {},
|
||||||
|
// style: ElevatedButton.styleFrom(
|
||||||
|
// backgroundColor: const Color(0xFF1976D2),
|
||||||
|
// padding: const EdgeInsets.symmetric(horizontal: 20),
|
||||||
|
// ),
|
||||||
|
// child: const Text("审批", style: TextStyle(color: Colors.white)),
|
||||||
|
// )
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
// ),
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _getListData() async {
|
||||||
|
try {
|
||||||
|
|
||||||
|
final raw = await ApiService.getDutyManagement(showCount,currentPage);
|
||||||
|
|
||||||
|
// print(raw);
|
||||||
|
// setState(() {
|
||||||
|
// workInfos = [
|
||||||
|
// {
|
||||||
|
// "icon": "assets/icon-apps/jobico1.png",
|
||||||
|
// "index": 1,
|
||||||
|
// "detail": "待排查",
|
||||||
|
// "num": (hidCount['dpc'] ?? 0).toString(),
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// "icon": "assets/icon-apps/jobico2.png",
|
||||||
|
// "index": 2,
|
||||||
|
// "detail": "待整改",
|
||||||
|
// "num": (hidCount['dzg'] ?? 0).toString(),
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// "icon": "assets/icon-apps/jobico3.png",
|
||||||
|
// "index": 3,
|
||||||
|
// "detail": "已超期",
|
||||||
|
// "num": (hidCount['ycq'] ?? 0).toString(),
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// "icon": "assets/icon-apps/jobico4.png",
|
||||||
|
// "index": 4,
|
||||||
|
// "detail": "待验收",
|
||||||
|
// "num": (hidCount['dys'] ?? 0).toString(),
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// "icon": "assets/icon-apps/jobico5.png",
|
||||||
|
// "index": 5,
|
||||||
|
// "detail": "已验收",
|
||||||
|
// "num": (hidCount['yys'] ?? 0).toString(),
|
||||||
|
// },
|
||||||
|
// ];
|
||||||
|
//
|
||||||
|
// });
|
||||||
|
|
||||||
|
} catch (e) {
|
||||||
|
// 出错时可以 Toast 或者在页面上显示错误状态
|
||||||
|
print('加载首页数据失败:$e');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -19,14 +19,22 @@ class FirstSignPage extends StatefulWidget {
|
||||||
|
|
||||||
class _SignatureUpdatePageState extends State<FirstSignPage> {
|
class _SignatureUpdatePageState extends State<FirstSignPage> {
|
||||||
String imagePath="";
|
String imagePath="";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: MyAppbar(title: "更新签字信息"),
|
appBar: MyAppbar(title: "更新签字信息"),
|
||||||
body: Column(
|
body:
|
||||||
|
Container(
|
||||||
|
margin: EdgeInsets.all(16),
|
||||||
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Row(
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
GestureDetector(
|
GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
|
|
@ -35,30 +43,36 @@ class _SignatureUpdatePageState extends State<FirstSignPage> {
|
||||||
child: Text("用户",style: TextStyle(color: Colors.black,fontSize: 16)),
|
child: Text("用户",style: TextStyle(color: Colors.black,fontSize: 16)),
|
||||||
),
|
),
|
||||||
|
|
||||||
// _buildConfirmButton(),
|
_buildConfirmButton(),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
|
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
|
if (imagePath.isNotEmpty)
|
||||||
Text('签字照片:',
|
Text('签字照片:',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 16,
|
fontSize: 14,
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
color: Colors.grey,
|
color: Colors.grey,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
const SizedBox(width: 15),
|
||||||
if (imagePath.isNotEmpty)
|
if (imagePath.isNotEmpty)
|
||||||
Image.file(File(imagePath)),
|
Image.file(File(imagePath),width: 230,height: 150,fit: BoxFit.cover,),
|
||||||
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
||||||
|
const SizedBox(height: 8),
|
||||||
// 确认按钮
|
// 确认按钮
|
||||||
// const Spacer(),
|
// const Spacer(),
|
||||||
// _buildConfirmButton(),
|
_buildTrueButton(),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -73,32 +87,58 @@ class _SignatureUpdatePageState extends State<FirstSignPage> {
|
||||||
|
|
||||||
Widget _buildConfirmButton() {
|
Widget _buildConfirmButton() {
|
||||||
return SizedBox(
|
return SizedBox(
|
||||||
width: double.infinity,
|
width: 80,
|
||||||
|
height: 30,
|
||||||
|
child: ElevatedButton(
|
||||||
|
onPressed: () async {
|
||||||
|
final path = await Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(builder: (context) => MineSignPage()),
|
||||||
|
);
|
||||||
|
// 更新状态(当子页面关闭时)
|
||||||
|
setState(() {
|
||||||
|
imagePath = path ?? '';
|
||||||
|
});
|
||||||
|
|
||||||
|
},
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
backgroundColor: const Color(0xFF4285F4),
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 5),
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
'手写签字',
|
||||||
|
style: TextStyle(fontSize: 12, color: Colors.white),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Widget _buildTrueButton() {
|
||||||
|
return Center(
|
||||||
|
|
||||||
child: ElevatedButton(
|
child: ElevatedButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
|
|
||||||
},
|
},
|
||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
backgroundColor: const Color(0xFF4285F4),
|
backgroundColor: const Color(0xFF4285F4),
|
||||||
padding: const EdgeInsets.symmetric(vertical: 16),
|
padding: const EdgeInsets.symmetric(vertical:5,horizontal: 80),
|
||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.circular(8),
|
borderRadius: BorderRadius.circular(8),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
child: imagePath.isNotEmpty
|
child: Text(
|
||||||
? const SizedBox(
|
|
||||||
width: 24,
|
|
||||||
height: 24,
|
|
||||||
child: CircularProgressIndicator(
|
|
||||||
strokeWidth: 2,
|
|
||||||
color: Colors.white,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
: const Text(
|
|
||||||
'确认',
|
'确认',
|
||||||
style: TextStyle(fontSize: 18, color: Colors.white),
|
style: TextStyle(fontSize: 14, color: Colors.white),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
|
|
||||||
);
|
);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
@ -5,6 +5,8 @@ import 'package:qhd_prevention/pages/mine/mine_about_page.dart';
|
||||||
import 'package:qhd_prevention/pages/mine/mine_set_page.dart';
|
import 'package:qhd_prevention/pages/mine/mine_set_page.dart';
|
||||||
import 'package:qhd_prevention/tools/tools.dart';
|
import 'package:qhd_prevention/tools/tools.dart';
|
||||||
|
|
||||||
|
import 'mine_departure_List.dart';
|
||||||
|
|
||||||
class MinePage extends StatefulWidget {
|
class MinePage extends StatefulWidget {
|
||||||
const MinePage({super.key});
|
const MinePage({super.key});
|
||||||
|
|
||||||
|
|
@ -50,7 +52,15 @@ class _MinePageState extends State<MinePage> {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
SizedBox(height: 10,),
|
SizedBox(height: 10,),
|
||||||
|
GestureDetector(
|
||||||
|
child: _setItemWidget("离岗"),
|
||||||
|
onTap: () {
|
||||||
|
pushPage(MineDepartureListPage(), context);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Divider(height: 1,color: Colors.black12,),
|
||||||
GestureDetector(
|
GestureDetector(
|
||||||
child: _setItemWidget("设置"),
|
child: _setItemWidget("设置"),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,15 @@
|
||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:qhd_prevention/customWidget/custom_button.dart';
|
import 'package:qhd_prevention/customWidget/custom_button.dart';
|
||||||
import 'package:qhd_prevention/pages/my_appbar.dart';
|
import 'package:qhd_prevention/pages/my_appbar.dart';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:qhd_prevention/tools/h_colors.dart';
|
import 'package:qhd_prevention/tools/h_colors.dart';
|
||||||
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
|
||||||
|
import '../../http/ApiService.dart';
|
||||||
|
import '../login_page.dart';
|
||||||
|
|
||||||
class MineSetPwdPage extends StatefulWidget {
|
class MineSetPwdPage extends StatefulWidget {
|
||||||
const MineSetPwdPage({super.key});
|
const MineSetPwdPage({super.key});
|
||||||
|
|
@ -40,13 +46,23 @@ class _MineSetPwdPageState extends State<MineSetPwdPage> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 示例验证:密码复杂度(实际可用正则加强)
|
final RegExp regex = RegExp(r'^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[a-zA-Z\d]{6,18}$');
|
||||||
if (newPwd.length < 8 || newPwd.length > 20) {
|
if (regex.hasMatch(newPwd)) {
|
||||||
_showMessage('密码长度需在8-20位之间');
|
_showMessage('密码长度为6-18位,必须包含大小字母,小写字母数字和特殊符号。');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_showMessage('密码修改成功'); // 这里换成实际调用接口逻辑
|
// 示例验证:密码复杂度(实际可用正则加强)
|
||||||
|
if (newPwd.length < 8 || newPwd.length > 18) {
|
||||||
|
_showMessage('密码长度需在8-18位之间');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
_changePass(oldPwd,newPwd);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _showMessage(String msg) {
|
void _showMessage(String msg) {
|
||||||
|
|
@ -93,14 +109,18 @@ class _MineSetPwdPageState extends State<MineSetPwdPage> {
|
||||||
_buildPwdField('确认新密码', _confirmPwdController),
|
_buildPwdField('确认新密码', _confirmPwdController),
|
||||||
const SizedBox(height: 15),
|
const SizedBox(height: 15),
|
||||||
const Text(
|
const Text(
|
||||||
'需8-20位字母大小写、数字、字符混合',
|
'需8-18位字母大小写、数字、字符混合',
|
||||||
style: TextStyle(color: Colors.grey, fontSize: 13),
|
style: TextStyle(color: Colors.grey, fontSize: 13),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 30,),
|
const SizedBox(height: 30,),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
height: 48,
|
height: 48,
|
||||||
child: CustomButton(text: "提交", backgroundColor: Colors.blue),
|
child: CustomButton(
|
||||||
|
onPressed: () {
|
||||||
|
_handleSubmit();
|
||||||
|
},
|
||||||
|
text: "提交", backgroundColor: Colors.blue),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
@ -108,4 +128,44 @@ class _MineSetPwdPageState extends State<MineSetPwdPage> {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Future<void> _changePass(String oldPwd, String newPwd) async {
|
||||||
|
try {
|
||||||
|
// “我的工作” 数量
|
||||||
|
final raw = await ApiService.changePassWord(oldPwd, newPwd);
|
||||||
|
|
||||||
|
// final hidCount = raw['hidCount'] as Map<String, dynamic>;
|
||||||
|
// print(hidCount);
|
||||||
|
if (raw['result'] == 'success') {
|
||||||
|
_showMessage('密码修改成功'); // 这里换成实际调用接口逻辑
|
||||||
|
Navigator.pop(context,true);
|
||||||
|
|
||||||
|
// 清除用户登录状态
|
||||||
|
await _clearUserSession();
|
||||||
|
// 跳转到登录页并清除所有历史路由
|
||||||
|
Navigator.pushAndRemoveUntil(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(builder: (context) => LoginPage()),
|
||||||
|
(Route<dynamic> route) => false, // 移除所有历史路由
|
||||||
|
);
|
||||||
|
|
||||||
|
}else{
|
||||||
|
_showMessage('密码修改失败');
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (e) {
|
||||||
|
// 出错时可以 Toast 或者在页面上显示错误状态
|
||||||
|
print('加载首页数据失败:$e');
|
||||||
|
_showMessage('密码修改失败');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _clearUserSession() async {
|
||||||
|
final prefs = await SharedPreferences.getInstance();
|
||||||
|
await prefs.remove('isLoggedIn'); // 清除登录状态
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -89,6 +89,7 @@ class _SignatureConfirmPageState extends State<SignatureConfirmPage> {
|
||||||
imagepath = file.path;
|
imagepath = file.path;
|
||||||
Future.delayed(const Duration(milliseconds: 500), () {
|
Future.delayed(const Duration(milliseconds: 500), () {
|
||||||
Navigator.pop(context,imagepath);
|
Navigator.pop(context,imagepath);
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
14
pubspec.lock
14
pubspec.lock
|
|
@ -14,7 +14,7 @@ packages:
|
||||||
description:
|
description:
|
||||||
name: asn1lib
|
name: asn1lib
|
||||||
sha256: "9a8f69025044eb466b9b60ef3bc3ac99b4dc6c158ae9c56d25eeccf5bc56d024"
|
sha256: "9a8f69025044eb466b9b60ef3bc3ac99b4dc6c158ae9c56d25eeccf5bc56d024"
|
||||||
url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.6.5"
|
version: "1.6.5"
|
||||||
async:
|
async:
|
||||||
|
|
@ -78,7 +78,7 @@ packages:
|
||||||
description:
|
description:
|
||||||
name: convert
|
name: convert
|
||||||
sha256: b30acd5944035672bc15c6b7a8b47d773e41e2f17de064350988c5d02adb1c68
|
sha256: b30acd5944035672bc15c6b7a8b47d773e41e2f17de064350988c5d02adb1c68
|
||||||
url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.2"
|
version: "3.1.2"
|
||||||
cross_file:
|
cross_file:
|
||||||
|
|
@ -126,7 +126,7 @@ packages:
|
||||||
description:
|
description:
|
||||||
name: dio
|
name: dio
|
||||||
sha256: "253a18bbd4851fecba42f7343a1df3a9a4c1d31a2c1b37e221086b4fa8c8dbc9"
|
sha256: "253a18bbd4851fecba42f7343a1df3a9a4c1d31a2c1b37e221086b4fa8c8dbc9"
|
||||||
url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "5.8.0+1"
|
version: "5.8.0+1"
|
||||||
dio_web_adapter:
|
dio_web_adapter:
|
||||||
|
|
@ -134,7 +134,7 @@ packages:
|
||||||
description:
|
description:
|
||||||
name: dio_web_adapter
|
name: dio_web_adapter
|
||||||
sha256: "7586e476d70caecaf1686d21eee7247ea43ef5c345eab9e0cc3583ff13378d78"
|
sha256: "7586e476d70caecaf1686d21eee7247ea43ef5c345eab9e0cc3583ff13378d78"
|
||||||
url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.1"
|
version: "2.1.1"
|
||||||
encrypt:
|
encrypt:
|
||||||
|
|
@ -142,7 +142,7 @@ packages:
|
||||||
description:
|
description:
|
||||||
name: encrypt
|
name: encrypt
|
||||||
sha256: "62d9aa4670cc2a8798bab89b39fc71b6dfbacf615de6cf5001fb39f7e4a996a2"
|
sha256: "62d9aa4670cc2a8798bab89b39fc71b6dfbacf615de6cf5001fb39f7e4a996a2"
|
||||||
url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "5.0.3"
|
version: "5.0.3"
|
||||||
extended_image:
|
extended_image:
|
||||||
|
|
@ -253,7 +253,7 @@ packages:
|
||||||
description:
|
description:
|
||||||
name: fluttertoast
|
name: fluttertoast
|
||||||
sha256: "25e51620424d92d3db3832464774a6143b5053f15e382d8ffbfd40b6e795dcf1"
|
sha256: "25e51620424d92d3db3832464774a6143b5053f15e382d8ffbfd40b6e795dcf1"
|
||||||
url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "8.2.12"
|
version: "8.2.12"
|
||||||
html:
|
html:
|
||||||
|
|
@ -581,7 +581,7 @@ packages:
|
||||||
description:
|
description:
|
||||||
name: pointycastle
|
name: pointycastle
|
||||||
sha256: "4be0097fcf3fd3e8449e53730c631200ebc7b88016acecab2b0da2f0149222fe"
|
sha256: "4be0097fcf3fd3e8449e53730c631200ebc7b88016acecab2b0da2f0149222fe"
|
||||||
url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.9.1"
|
version: "3.9.1"
|
||||||
provider:
|
provider:
|
||||||
|
|
|
||||||
|
|
@ -58,6 +58,11 @@ dependencies:
|
||||||
encrypt: ^5.0.3
|
encrypt: ^5.0.3
|
||||||
pointycastle: ^3.6.2
|
pointycastle: ^3.6.2
|
||||||
|
|
||||||
|
|
||||||
|
#网页页面加载
|
||||||
|
webview_flutter: ^4.4.0
|
||||||
|
path_provider: ^2.0.1
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue