From 102b5b701136b5a4978f537066d2004ff8034036 Mon Sep 17 00:00:00 2001 From: xufei <727302827@qq.com> Date: Wed, 16 Jul 2025 08:38:10 +0800 Subject: [PATCH] =?UTF-8?q?2025.7.16=20=E5=A4=87=E4=BB=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/http/ApiService.dart | 58 ++++ lib/pages/mine/mine_departure_List.dart | 61 ++++ lib/pages/mine/mine_departure_record.dart | 249 ++++++++++++++++ lib/pages/mine/mine_duty_application.dart | 264 +++++++++++++++++ lib/pages/mine/mine_duty_detail.dart | 203 +++++++++++++ lib/pages/mine/mine_duty_management.dart | 331 ++++++++++++++++++++++ lib/pages/mine/mine_first_sign_page.dart | 102 +++++-- lib/pages/mine/mine_page.dart | 10 + lib/pages/mine/mine_set_pwd_page.dart | 70 ++++- lib/pages/mine/mine_sign_page.dart | 1 + pubspec.lock | 14 +- pubspec.yaml | 5 + 12 files changed, 1325 insertions(+), 43 deletions(-) create mode 100644 lib/pages/mine/mine_departure_List.dart create mode 100644 lib/pages/mine/mine_departure_record.dart create mode 100644 lib/pages/mine/mine_duty_application.dart create mode 100644 lib/pages/mine/mine_duty_detail.dart create mode 100644 lib/pages/mine/mine_duty_management.dart diff --git a/lib/http/ApiService.dart b/lib/http/ApiService.dart index 3106bb6..93dde62 100644 --- a/lib/http/ApiService.dart +++ b/lib/http/ApiService.dart @@ -221,4 +221,62 @@ U6Hzm1ninpWeE+awIDAQAB ); } + + +///TODO -------------–-------------------- 我的 -------------–-------------------- + + /// 问题反馈 + static Future> 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> 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> 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' + }, + ); + } + + + + } diff --git a/lib/pages/mine/mine_departure_List.dart b/lib/pages/mine/mine_departure_List.dart new file mode 100644 index 0000000..a84c047 --- /dev/null +++ b/lib/pages/mine/mine_departure_List.dart @@ -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), + ], + ), + ), + ); + } +} diff --git a/lib/pages/mine/mine_departure_record.dart b/lib/pages/mine/mine_departure_record.dart new file mode 100644 index 0000000..41eaa0c --- /dev/null +++ b/lib/pages/mine/mine_departure_record.dart @@ -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 createState() => _MineDepartureRecordPage(); +} + +class _MineDepartureRecordPage extends State { + + Future _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)), + // ) + ], + ), + ], + ), + ), + // ), + ); + + } + + +} + diff --git a/lib/pages/mine/mine_duty_application.dart b/lib/pages/mine/mine_duty_application.dart new file mode 100644 index 0000000..e648fcd --- /dev/null +++ b/lib/pages/mine/mine_duty_application.dart @@ -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 createState() => _MineDutyApplicationPage(); +} + +class _MineDutyApplicationPage extends State { + DateTime? _startDate; + DateTime? _endDate; + final TextEditingController _reasonController = TextEditingController(); + final String _applicant = "王轩"; + + Future _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), + ), + ], + ), + ); + } +} \ No newline at end of file diff --git a/lib/pages/mine/mine_duty_detail.dart b/lib/pages/mine/mine_duty_detail.dart new file mode 100644 index 0000000..e498be3 --- /dev/null +++ b/lib/pages/mine/mine_duty_detail.dart @@ -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 createState() => _MineDutyDetailPage(); +} + +class _MineDutyDetailPage extends State { + 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), + ), + ], + ), + ); + } +} \ No newline at end of file diff --git a/lib/pages/mine/mine_duty_management.dart b/lib/pages/mine/mine_duty_management.dart new file mode 100644 index 0000000..b6b511e --- /dev/null +++ b/lib/pages/mine/mine_duty_management.dart @@ -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 createState() => _MineDutyManagementPageState(); +} + +class _MineDutyManagementPageState extends State { + + int showCount=-1; + int currentPage=1; + + Future _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 _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'); + } + } + + +} + diff --git a/lib/pages/mine/mine_first_sign_page.dart b/lib/pages/mine/mine_first_sign_page.dart index 0e77355..5d60d1d 100644 --- a/lib/pages/mine/mine_first_sign_page.dart +++ b/lib/pages/mine/mine_first_sign_page.dart @@ -19,14 +19,22 @@ class FirstSignPage extends StatefulWidget { class _SignatureUpdatePageState extends State { String imagePath=""; + + + + @override Widget build(BuildContext context) { return Scaffold( appBar: MyAppbar(title: "更新签字信息"), - body: Column( + body: + Container( + margin: EdgeInsets.all(16), + child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ GestureDetector( onTap: () { @@ -35,30 +43,36 @@ class _SignatureUpdatePageState extends State { child: Text("用户",style: TextStyle(color: Colors.black,fontSize: 16)), ), - // _buildConfirmButton(), + _buildConfirmButton(), ], ), const SizedBox(height: 8), - Row( - children: [ - Text('签字照片:', - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.bold, - color: Colors.grey, - ), - ), - if (imagePath.isNotEmpty) - Image.file(File(imagePath)), - ], - ), + Row( + children: [ + if (imagePath.isNotEmpty) + Text('签字照片:', + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.bold, + color: Colors.grey, + ), + ), + const SizedBox(width: 15), + if (imagePath.isNotEmpty) + Image.file(File(imagePath),width: 230,height: 150,fit: BoxFit.cover,), + ], + ), + + const SizedBox(height: 8), // 确认按钮 // const Spacer(), - // _buildConfirmButton(), + _buildTrueButton(), ], ), + ), + ); } @@ -73,32 +87,58 @@ class _SignatureUpdatePageState extends State { Widget _buildConfirmButton() { return SizedBox( - width: double.infinity, + width: 80, + height: 30, child: ElevatedButton( - onPressed: () { + 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: 16), + padding: const EdgeInsets.symmetric(vertical: 5), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), ), ), - child: imagePath.isNotEmpty - ? const SizedBox( - width: 24, - height: 24, - child: CircularProgressIndicator( - strokeWidth: 2, - color: Colors.white, - ), - ) - : const Text( - '确认', - style: TextStyle(fontSize: 18, color: Colors.white), + child: Text( + '手写签字', + style: TextStyle(fontSize: 12, color: Colors.white), ), ), ); } +} + + +Widget _buildTrueButton() { + return Center( + + child: ElevatedButton( + onPressed: () { + + }, + style: ElevatedButton.styleFrom( + backgroundColor: const Color(0xFF4285F4), + padding: const EdgeInsets.symmetric(vertical:5,horizontal: 80), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8), + ), + ), + child: Text( + '确认', + style: TextStyle(fontSize: 14, color: Colors.white), + ), + ), + + + ); + } \ No newline at end of file diff --git a/lib/pages/mine/mine_page.dart b/lib/pages/mine/mine_page.dart index ac6b557..09a0348 100644 --- a/lib/pages/mine/mine_page.dart +++ b/lib/pages/mine/mine_page.dart @@ -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/tools/tools.dart'; +import 'mine_departure_List.dart'; + class MinePage extends StatefulWidget { const MinePage({super.key}); @@ -50,7 +52,15 @@ class _MinePageState extends State { ), ), ), + SizedBox(height: 10,), + GestureDetector( + child: _setItemWidget("离岗"), + onTap: () { + pushPage(MineDepartureListPage(), context); + }, + ), + Divider(height: 1,color: Colors.black12,), GestureDetector( child: _setItemWidget("设置"), onTap: () { diff --git a/lib/pages/mine/mine_set_pwd_page.dart b/lib/pages/mine/mine_set_pwd_page.dart index 98f0733..d2c75a7 100644 --- a/lib/pages/mine/mine_set_pwd_page.dart +++ b/lib/pages/mine/mine_set_pwd_page.dart @@ -1,9 +1,15 @@ +import 'dart:convert'; + import 'package:flutter/material.dart'; import 'package:qhd_prevention/customWidget/custom_button.dart'; import 'package:qhd_prevention/pages/my_appbar.dart'; import 'package:flutter/material.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 { const MineSetPwdPage({super.key}); @@ -40,13 +46,23 @@ class _MineSetPwdPageState extends State { return; } + final RegExp regex = RegExp(r'^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[a-zA-Z\d]{6,18}$'); + if (regex.hasMatch(newPwd)) { + _showMessage('密码长度为6-18位,必须包含大小字母,小写字母数字和特殊符号。'); + return; + } + // 示例验证:密码复杂度(实际可用正则加强) - if (newPwd.length < 8 || newPwd.length > 20) { - _showMessage('密码长度需在8-20位之间'); + if (newPwd.length < 8 || newPwd.length > 18) { + _showMessage('密码长度需在8-18位之间'); return; } - _showMessage('密码修改成功'); // 这里换成实际调用接口逻辑 + + + _changePass(oldPwd,newPwd); + + } void _showMessage(String msg) { @@ -93,14 +109,18 @@ class _MineSetPwdPageState extends State { _buildPwdField('确认新密码', _confirmPwdController), const SizedBox(height: 15), const Text( - '需8-20位字母大小写、数字、字符混合', + '需8-18位字母大小写、数字、字符混合', style: TextStyle(color: Colors.grey, fontSize: 13), ), const SizedBox(height: 30,), SizedBox( width: double.infinity, height: 48, - child: CustomButton(text: "提交", backgroundColor: Colors.blue), + child: CustomButton( + onPressed: () { + _handleSubmit(); + }, + text: "提交", backgroundColor: Colors.blue), ), ], ), @@ -108,4 +128,44 @@ class _MineSetPwdPageState extends State { ), ); } + + + Future _changePass(String oldPwd, String newPwd) async { + try { + // “我的工作” 数量 + final raw = await ApiService.changePassWord(oldPwd, newPwd); + + // final hidCount = raw['hidCount'] as Map; + // print(hidCount); + if (raw['result'] == 'success') { + _showMessage('密码修改成功'); // 这里换成实际调用接口逻辑 + Navigator.pop(context,true); + + // 清除用户登录状态 + await _clearUserSession(); + // 跳转到登录页并清除所有历史路由 + Navigator.pushAndRemoveUntil( + context, + MaterialPageRoute(builder: (context) => LoginPage()), + (Route route) => false, // 移除所有历史路由 + ); + + }else{ + _showMessage('密码修改失败'); + } + + } catch (e) { + // 出错时可以 Toast 或者在页面上显示错误状态 + print('加载首页数据失败:$e'); + _showMessage('密码修改失败'); + } + } + + Future _clearUserSession() async { + final prefs = await SharedPreferences.getInstance(); + await prefs.remove('isLoggedIn'); // 清除登录状态 + } + } + + diff --git a/lib/pages/mine/mine_sign_page.dart b/lib/pages/mine/mine_sign_page.dart index 7cd950b..6a38e5b 100644 --- a/lib/pages/mine/mine_sign_page.dart +++ b/lib/pages/mine/mine_sign_page.dart @@ -89,6 +89,7 @@ class _SignatureConfirmPageState extends State { imagepath = file.path; Future.delayed(const Duration(milliseconds: 500), () { Navigator.pop(context,imagepath); + }); }); diff --git a/pubspec.lock b/pubspec.lock index 1f1a7d9..922d589 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -14,7 +14,7 @@ packages: description: name: asn1lib sha256: "9a8f69025044eb466b9b60ef3bc3ac99b4dc6c158ae9c56d25eeccf5bc56d024" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "1.6.5" async: @@ -78,7 +78,7 @@ packages: description: name: convert sha256: b30acd5944035672bc15c6b7a8b47d773e41e2f17de064350988c5d02adb1c68 - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "3.1.2" cross_file: @@ -126,7 +126,7 @@ packages: description: name: dio sha256: "253a18bbd4851fecba42f7343a1df3a9a4c1d31a2c1b37e221086b4fa8c8dbc9" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "5.8.0+1" dio_web_adapter: @@ -134,7 +134,7 @@ packages: description: name: dio_web_adapter sha256: "7586e476d70caecaf1686d21eee7247ea43ef5c345eab9e0cc3583ff13378d78" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "2.1.1" encrypt: @@ -142,7 +142,7 @@ packages: description: name: encrypt sha256: "62d9aa4670cc2a8798bab89b39fc71b6dfbacf615de6cf5001fb39f7e4a996a2" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "5.0.3" extended_image: @@ -253,7 +253,7 @@ packages: description: name: fluttertoast sha256: "25e51620424d92d3db3832464774a6143b5053f15e382d8ffbfd40b6e795dcf1" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "8.2.12" html: @@ -581,7 +581,7 @@ packages: description: name: pointycastle sha256: "4be0097fcf3fd3e8449e53730c631200ebc7b88016acecab2b0da2f0149222fe" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "3.9.1" provider: diff --git a/pubspec.yaml b/pubspec.yaml index 169eab7..75f90fe 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -58,6 +58,11 @@ dependencies: encrypt: ^5.0.3 pointycastle: ^3.6.2 + + #网页页面加载 + webview_flutter: ^4.4.0 + path_provider: ^2.0.1 + dev_dependencies: flutter_test: sdk: flutter