From af81885441b7645cc2ddd4708f2029fd5642303b Mon Sep 17 00:00:00 2001 From: xufei <727302827@qq.com> Date: Thu, 17 Jul 2025 17:58:04 +0800 Subject: [PATCH] =?UTF-8?q?2025.7.17=20=E7=A6=BB=E5=B2=97=E5=AE=8C?= =?UTF-8?q?=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/http/ApiService.dart | 122 +++- .../home/study/face_ecognition_page.dart | 2 +- lib/pages/mine/mine_departure_record.dart | 575 +++++++++++++----- lib/pages/mine/mine_duty_application.dart | 80 ++- lib/pages/mine/mine_duty_detail.dart | 55 +- lib/pages/mine/mine_duty_management.dart | 470 +++++++++++--- lib/pages/mine/mine_feedback_page.dart | 29 +- pubspec.lock | 26 +- 8 files changed, 1046 insertions(+), 313 deletions(-) diff --git a/lib/http/ApiService.dart b/lib/http/ApiService.dart index 02a009f..bd22864 100644 --- a/lib/http/ApiService.dart +++ b/lib/http/ApiService.dart @@ -17,12 +17,31 @@ class ApiService { // static const String adminPath = "https://qaaqwh.qhdsafety.com/integrated_whb/"; // static const String projectManagerUrl = 'https://pm.qhdsafety.com/zy-projectManage/'; // static const String publicKey = 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDUoHAavCikaZxjlDM6Km8cX+ye78F4oF39AcEfnE1p2Yn9pJ9WFxYZ4Vkh6F8SKMi7k4nYsKceqB1RwG996SvHQ5C3pM3nbXCP4K15ad6QhN4a7lzlbLhiJcyIKszvvK8ncUDw8mVQ0j/2mwxv05yH6LN9OKU6Hzm1ninpWeE+awIDAQAB' + // /// 人脸识别服务 + // static const String baseFacePath = + // "https://qaaqwh.qhdsafety.com/whb_stu_face/"; + // + // /// 登录及其他管理后台接口 + // static const String basePath = "https://qaaqwh.qhdsafety.com/integrated_whb"; + // + // /// 图片文件服务 + // static const String baseImgPath = "https://file.zcloudchina.com/YTHFile"; + // + // /// 管理后台统一路径 + // static const String adminPath = + // "https://qaaqwh.qhdsafety.com/integrated_whb/"; + // + // /// 项目管理系统 + // static const String projectManagerUrl = + // 'https://pm.qhdsafety.com/zy-projectManage'; + + /// 人脸识别服务 static const String baseFacePath = "https://qaaqwh.qhdsafety.com/whb_stu_face/"; /// 登录及其他管理后台接口 - static const String basePath = "https://qaaqwh.qhdsafety.com/integrated_whb"; + static const String basePath = "http://192.168.20.240:8500/integrated_whb/"; /// 图片文件服务 static const String baseImgPath = "https://file.zcloudchina.com/YTHFile"; @@ -35,6 +54,7 @@ class ApiService { static const String projectManagerUrl = 'https://pm.qhdsafety.com/zy-projectManage'; + /// RSA 公钥 static const publicKey = ''' -----BEGIN PUBLIC KEY----- @@ -45,6 +65,9 @@ U6Hzm1ninpWeE+awIDAQAB -----END PUBLIC KEY----- '''; + + + /// 登录验证接口 static Future> loginCheck(String keydataVal) { return HttpManager().request( @@ -403,6 +426,29 @@ U6Hzm1ninpWeE+awIDAQAB ); } + /// 问题反馈图片 + static Future> reloadFeedBack(String imagePath) async { + final file = File(imagePath); + if (!await file.exists()) { + throw ApiException('file_not_found', '图片不存在:$imagePath'); + } + final fileName = file.path.split(Platform.pathSeparator).last; + + return HttpManager().uploadFaceImage( + baseUrl: basePath, + path: '/app/feedback/upload', + fromData: { + "corpUserId":"", + 'CORPINFO_ID': SessionService.instance.corpinfoId, + 'USER_ID': SessionService.instance.loginUserId, + 'FFILE': await MultipartFile.fromFile( + file.path, + filename: fileName + ), + } + ); + } + /// 修改密码 static Future> changePassWord(String oldPwd,String confirmPwd) { return HttpManager().request( @@ -423,7 +469,7 @@ U6Hzm1ninpWeE+awIDAQAB static Future> getDutyManagement(int showCount, int currentPage) { return HttpManager().request( basePath, - '/app/user/editUserPwd?showCount=$showCount¤tPage=$currentPage', + '/app/offduty/list?showCount=$showCount¤tPage=$currentPage', method: Method.post, data: { "CORPINFO_ID":SessionService.instance.corpinfoId, @@ -538,7 +584,7 @@ U6Hzm1ninpWeE+awIDAQAB ); } - /// 获取离岗管理列表 + /// 获取AI预警列表 static Future> getAiAlarmList(String showCount, String currentPage,String keyWord) { return HttpManager().request( @@ -555,5 +601,75 @@ U6Hzm1ninpWeE+awIDAQAB } + /// 离岗申请 + static Future> submitApplicationLeaving(String startTime, String endTime,String text) { + return HttpManager().request( + basePath, + '/app/offduty/add', + method: Method.post, + data: { + "OFFDUTY_ID":"", + "STARTTIME": startTime, + "ENDTIME": endTime, + "DESCR": text, + "REVIEW_USER_ID": "", + "CREATOR": SessionService.instance.loginUserId, + "OPERATOR": SessionService.instance.loginUserId, + "CORPINFO_ID": SessionService.instance.corpinfoId, + "USER_ID": SessionService.instance.loginUserId, + }, + ); + } + + /// 离岗审批 + static Future> dutyApproval(String type, String text,String itemNum) { + return HttpManager().request( + basePath, + '/app/offduty/review', + method: Method.post, + data: { + "OFFDUTY_ID":itemNum, + "REVIEW_STATUS":type, + "REVIEW_DESC":text, + "OPERATOR":SessionService.instance.loginUserId + }, + ); + } + + /// 离岗取消 + static Future> dutyReturned(String type, String text,String itemNum) { + return HttpManager().request( + basePath, + '/app/offduty/cancel', + method: Method.post, + data: { + "OFFDUTY_ID":itemNum, + "REVIEW_STATUS":type, + "REVIEW_DESC":text, + "OPERATOR":SessionService.instance.loginUserId + }, + ); + } + + + /// 获取离岗记录列表 + static Future> getDepartureRecordList(int showCount, int currentPage) { + + return HttpManager().request( + basePath, + '/app/offduty/list?showCount=$showCount¤tPage=$currentPage', + method: Method.post, + data: { + "CORPINFO_ID": SessionService.instance.corpinfoId, + "USER_ID":SessionService.instance.loginUserId, + "ISMAIN":0, + "ISSUPERVISE":0, + "DEPARTMENT_ID": SessionService.instance.corpinfoId, + "TYPE": 'show' + }, + ); + } + + } diff --git a/lib/pages/home/study/face_ecognition_page.dart b/lib/pages/home/study/face_ecognition_page.dart index 60226f0..cf1516a 100644 --- a/lib/pages/home/study/face_ecognition_page.dart +++ b/lib/pages/home/study/face_ecognition_page.dart @@ -86,7 +86,7 @@ class _FaceRecognitionPageState extends State { setState(() => _message = '上传中...'); try { final pic = await _cameraController!.takePicture(); - final res = await ApiService.reloadMyFace(pic.path,); + final res = await ApiService.reloadMyFace(pic.path); if (res['result'] == 'success') { _onSuccess(); } else { diff --git a/lib/pages/mine/mine_departure_record.dart b/lib/pages/mine/mine_departure_record.dart index 41eaa0c..235fecd 100644 --- a/lib/pages/mine/mine_departure_record.dart +++ b/lib/pages/mine/mine_departure_record.dart @@ -2,6 +2,7 @@ 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'; @@ -35,58 +36,37 @@ class MineDepartureRecordPage extends StatefulWidget { class _MineDepartureRecordPage extends State { + int showCount=-1; + int currentPage=1; + late List _list = []; + + Future _onRefresh() async { // 模拟网络请求 await Future.delayed(const Duration(seconds: 2)); // 刷新数据逻辑,如 fetchData() setState(() { // TODO: 更新数据源 + refreshData(); }); } + @override + void initState() { + _getListData(); + + } + + void refreshData(){ + currentPage=1; + _list.clear(); + _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), @@ -95,13 +75,17 @@ class _MineDepartureRecordPage extends State { RefreshIndicator( onRefresh: _onRefresh, child: + // 记录列表 Expanded( - child: ListView.builder( + child: + _list.isEmpty + ? Center(child: Text('暂无数据')) + : ListView.builder( padding: const EdgeInsets.symmetric(vertical: 16), - itemCount: leaveRecords.length, + itemCount: _list.length, itemBuilder: (context, index) { - final record = leaveRecords[index]; + final record = _list[index]; return _buildRecordCard(record,context); }, ), @@ -112,138 +96,399 @@ class _MineDepartureRecordPage extends State { ); } - 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)}"; + Widget _buildRecordCard(final item , 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)}"; + final dateRange ="${item['STARTTIME']} 至 ${item['ENDTIME']}"; 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)), - // ) - ], - ), + GestureDetector( + onTap: () { + pushPage(MineDutyDetailPage(item), 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( + "申请人:${item['USER_NAME']}", + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + ), + ), + const SizedBox(height: 4), + Text( + "部门:${item['DEPARTMENTNAME']} \n岗位:${item['POSTNAME']}", + style: TextStyle( + fontSize: 13, + color: Colors.grey[600], + ), + ), + + ], + ), + // const Spacer(), + + ], + ), + + const SizedBox(height: 8), + + // 离岗时间 + Row( + children: [ + const Icon(Icons.calendar_today, size: 18, color: Colors.grey), + const SizedBox(width: 8), + Expanded( + child: Text( + "离岗时间: $dateRange", + style: const TextStyle(color: Colors.grey), + ), + ), + + ], + ), + + const SizedBox(height: 4), + // Container( + // padding: const EdgeInsets.symmetric( vertical: 6), + // // decoration: BoxDecoration( + // // color: record.statusColor.withOpacity(0.1), + // // borderRadius: BorderRadius.circular(20), + // // ), + // child: + Text( + "审核状态:${_getTypeReturn(item)}", + // record.status, + style: TextStyle( + color: Colors.black, + fontWeight: FontWeight.w500, + ), + ), + // ), + + const SizedBox(height: 4), + + // 操作按钮 + // if( item["REVIEW_STATUS"]=="0"&&DateTime.now().isBefore(item["ENDTIME"])&& + // (item["REVIEW_USER_ID"]==SessionService.instance.loginUserId)&& + // SessionService.instance.loginUser?["USERNAME"]=="1"&&item['REVIEW_STATUS']=="0") + Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + ElevatedButton( + onPressed: () { + showDialog( + context: context, + builder: (context) => DutyDialog( + item,1, + onClose: (result) { + // print('详情页面已关闭,返回结果: $result'); + refreshData(); + }, + + ), + ); + }, + style: ElevatedButton.styleFrom( + backgroundColor: const Color(0xFF1976D2), + // padding: const EdgeInsets.symmetric(horizontal: 10), + ), + child: const Text("关 闭", style: TextStyle(color: Colors.white,fontSize: 12)), + ), + + const SizedBox(width: 16), + + ElevatedButton( + onPressed: () { + showDialog( + context: context, + builder: (context) => DutyDialog( + item,2, + onClose: (result) { + // print('详情页面已关闭,返回结果: $result'); + refreshData(); + }, + + ), + ); + }, + style: ElevatedButton.styleFrom( + backgroundColor: Colors.red, + // padding: const EdgeInsets.symmetric(horizontal: 10), + ), + child: const Text("提 交", style: TextStyle(color: Colors.white,fontSize: 12)), + ) + + ], + ), + ], + ), + ), ), - // ), ); } + Future _getListData() async { + try { + + final result = await ApiService.getDepartureRecordList(showCount,currentPage); + if (result['result'] == 'success') { + final List newList = result['varList'] ?? []; + setState(() { + _list.addAll(newList); + }); + } + } catch (e) { + print('加载出错: $e'); + } + } + + + String _getTypeReturn(final item) { + String type=item['REVIEW_STATUS']; + if("0"==type){ + return "待审批"; + }else if("1"==type){ + return "审批通过"; + }else if("2"==type){ + return "无需审批"; + }else if("-1"==type){ + String type2=item['ISDELETE']; + if("1"==type2){ + if(item['CREATOR']==item['OPERATOR']){ + return "申请人取消"; + }else{ + return "审批人取消"; + } + }else{ + return "审批打回"; + } + }else{ + return "审批错误"; + } + } + } + + +enum FeedbackType { + tongGuo, + Dahui, +} + +class DutyDialog extends StatefulWidget { + const DutyDialog(this.item,this.type, {super.key,required this.onClose}); + + final Function(String) onClose; // 回调函数 + final item; + final int type; + + + @override + State createState() => _DutyDialogState(); +} + +class _DutyDialogState extends State { + + final TextEditingController _reasonController = TextEditingController(); + // 反馈类型 + FeedbackType? _selectedType = FeedbackType.tongGuo; + + // 获取反馈类型名称 + String _getTypeName(FeedbackType type) { + switch (type) { + case FeedbackType.tongGuo: + return '通过'; + case FeedbackType.Dahui: + return '打回'; + } + } + + + Future _dutyApproval() async { + try { + + String typeString; + if(FeedbackType.tongGuo==_selectedType){ + typeString="1"; + }else{ + typeString="-1"; + } + + final result = await ApiService.dutyApproval(typeString,_reasonController.text,widget.item["OFFDUTY_ID"]); + if (result['result'] == 'success') { + widget.onClose('关闭提交'); // 触发回调 + } + } catch (e) { + print('加载出错: $e'); + } + } + + Future _dutyReturned() async { + try { + + final result = await ApiService.dutyReturned("-1",_reasonController.text,widget.item["OFFDUTY_ID"]); + if (result['result'] == 'success') { + widget.onClose('关闭提交'); // 触发回调 + } + } catch (e) { + print('加载出错: $e'); + } + } + + @override + Widget build(BuildContext context) { + return Dialog( + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), + child: Container( + padding: const EdgeInsets.all(20), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // 标题 + const Center( + child: Text( + '离岗审批', + style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold), + ), + ), + + const SizedBox(height: 20), + + // 操作按钮行 + // Row( + // mainAxisAlignment: MainAxisAlignment.spaceEvenly, + // children: [ + // _buildActionButton('通过', Colors.green), + // _buildActionButton('打印', Colors.blue), + // ], + // ), + if(1==widget.type) + Center( + child: Wrap( + spacing: 16, + children: + FeedbackType.values.map((type) { + return ChoiceChip( + label: Text(_getTypeName(type)), + selected: _selectedType == type, + onSelected: (selected) { + setState(() { + if (selected) { + _selectedType = type; + } + }); + }, + ); + }).toList(), + ), + ), + + + const SizedBox(height: 20), + + // 输入框 + TextField( + controller: _reasonController, + decoration: InputDecoration( + border: OutlineInputBorder(), + hintText: widget.type==1?'请输入审批意见':'请输入原因', + contentPadding: EdgeInsets.symmetric(horizontal: 12, vertical: 16), + ), + maxLines: 4, + ), + + const SizedBox(height: 20), + + // 底部按钮 + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Expanded( + child: ElevatedButton( + onPressed: (){ + if(_reasonController.text.isEmpty){ + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text(widget.type==1?'请输入审批意见':'请输入原因')) + ); + return; + } + + if(1==widget.type){ + _dutyApproval();//审批 + }else{ + _dutyReturned();//打回 + } + Navigator.pop(context); + } , + style: ElevatedButton.styleFrom( + backgroundColor: Colors.blue, + padding: const EdgeInsets.symmetric(vertical: 14), + ), + child: const Text('提交',style: TextStyle(color: Colors.white),), + ), + ), + const SizedBox(width: 15), + Expanded( + child: ElevatedButton( + onPressed: (){ + Navigator.pop(context); + } , + style: ElevatedButton.styleFrom( + backgroundColor: Colors.grey, + padding: const EdgeInsets.symmetric(vertical: 14), + ), + child: const Text('关闭',style: TextStyle(color: Colors.white),), + ), + ), + ], + ), + ], + ), + ), + ); + } + + +} \ No newline at end of file diff --git a/lib/pages/mine/mine_duty_application.dart b/lib/pages/mine/mine_duty_application.dart index e648fcd..39fca81 100644 --- a/lib/pages/mine/mine_duty_application.dart +++ b/lib/pages/mine/mine_duty_application.dart @@ -2,10 +2,14 @@ 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'; + class MineDutyApplicationPage extends StatefulWidget { - const MineDutyApplicationPage({super.key}); + const MineDutyApplicationPage({super.key,required this.onClose}); + final Function(String) onClose; // 回调函数 @override State createState() => _MineDutyApplicationPage(); @@ -15,7 +19,27 @@ class _MineDutyApplicationPage extends State { DateTime? _startDate; DateTime? _endDate; final TextEditingController _reasonController = TextEditingController(); - final String _applicant = "王轩"; + + + + Future _submitApplicationLeaving() async { + try { + + var formatter = DateFormat('yyyy-MM-dd'); // 或者使用 'dd-MM-yyyy' 取决于你的需求 + String startTime= formatter.format(_startDate!); + String endTime= formatter.format(_endDate!); + + final result = await ApiService.submitApplicationLeaving(startTime,endTime,_reasonController.text); + if (result['result'] == 'success') { + ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('提交成功'))); + widget.onClose('关闭提交'); // 触发回调 + Navigator.pop(context); // 关闭页面 + } + } catch (e) { + print('加载出错: $e'); + } + } + Future _selectDate(BuildContext context, bool isStartDate) async { final DateTime? picked = await showDatePicker( @@ -42,19 +66,30 @@ class _MineDutyApplicationPage extends State { if (picked != null) { setState(() { if (isStartDate) { - _startDate = picked; - // 如果结束日期早于开始日期,自动更新结束日期 - if (_endDate == null || _endDate!.isBefore(picked)) { - _endDate = picked; + if(picked.isBefore(DateTime.now().subtract(Duration(days: 1)))){ + ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('开始日期不能早于当前日期'))); + + }else { + _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; + if(picked.isBefore(DateTime.now().subtract(Duration(days: 1)))){ + ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('结束日期不能早于当前日期'))); + + }else { + // 确保结束日期不早于开始日期 + if (_startDate != null && picked.isBefore(_startDate!)) { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar(content: Text('结束日期不能早于开始日期')) + ); + } else { + _endDate = picked; + } } } }); @@ -80,16 +115,24 @@ class _MineDutyApplicationPage extends State { showDialog( context: context, builder: (context) => AlertDialog( - title: const Text('申请提交成功'), - content: const Text('您的离岗申请已成功提交,请等待审批'), + title: const Text('申请提交'), + content: const Text('您确定提交离岗申请吗?'), actions: [ TextButton( onPressed: () { Navigator.pop(context); // 关闭对话框 - Navigator.pop(context); // 返回上一页 + }, + child: const Text("取消"), + ), + TextButton( + onPressed: () { + Navigator.pop(context); // 关闭对话框 + // Navigator.pop(context); // 返回上一页 + _submitApplicationLeaving(); }, child: const Text("确定"), - ) + ), + ], ), ); @@ -161,7 +204,8 @@ class _MineDutyApplicationPage extends State { const SizedBox(height: 24), // 申请人信息 - _buildInfoRow("申请人", _applicant), + // _buildInfoRow("申请人", _applicant), + _buildInfoRow("申请人", SessionService.instance.username.toString()), const SizedBox(height: 40), diff --git a/lib/pages/mine/mine_duty_detail.dart b/lib/pages/mine/mine_duty_detail.dart index e498be3..2581011 100644 --- a/lib/pages/mine/mine_duty_detail.dart +++ b/lib/pages/mine/mine_duty_detail.dart @@ -3,19 +3,19 @@ import 'package:intl/intl.dart'; import 'package:qhd_prevention/pages/my_appbar.dart'; - +///岗位详情 class MineDutyDetailPage extends StatefulWidget { - const MineDutyDetailPage({super.key}); + const MineDutyDetailPage(this.item, {super.key}); + final item; @override State createState() => _MineDutyDetailPage(); } class _MineDutyDetailPage extends State { - DateTime? _startDate; - DateTime? _endDate; + final TextEditingController _reasonController = TextEditingController(); - final String _applicant = "王轩"; + @@ -32,13 +32,13 @@ class _MineDutyDetailPage extends State { // 申请人信息 - _buildInfoRow("申请人", _applicant), + _buildInfoRow("申请人", widget.item["USER_NAME"]), const SizedBox(height: 24), // 离岗开始时间 _buildDateField( label: "离岗开始时间", - date: _startDate, + date: widget.item["STARTTIME"], onTap: () { } @@ -50,7 +50,7 @@ class _MineDutyDetailPage extends State { // 离岗结束时间 _buildDateField( label: "离岗结束时间", - date: _endDate, + date: widget.item["ENDTIME"], onTap: () { }, @@ -83,7 +83,8 @@ class _MineDutyDetailPage extends State { ], ), child: Text( - "原因",style: TextStyle(color: Colors.black), + widget.item["DESCR"], + style: TextStyle(color: Colors.black), // controller: _reasonController, // maxLines: 5, // decoration: const InputDecoration( @@ -96,8 +97,10 @@ class _MineDutyDetailPage extends State { const SizedBox(height: 24), + + // 申请人信息 - _buildInfoRow("审批状态", "无需审批"), + _buildInfoRow("审批状态", _getTypeReturn(widget.item)), const SizedBox(height: 40), @@ -131,7 +134,7 @@ class _MineDutyDetailPage extends State { Widget _buildDateField({ required String label, - required DateTime? date, + required String? date, required VoidCallback onTap, }) { return GestureDetector( @@ -158,10 +161,11 @@ class _MineDutyDetailPage extends State { style: const TextStyle(fontSize: 16), ), Text( - date != null ? DateFormat('yyyy-MM-dd').format(date) : "请选择日期", + // date != null ? DateFormat('yyyy-MM-dd').format(date) : "请选择日期", + date! , style: TextStyle( fontSize: 16, - color: date != null ? Colors.black : const Color(0xFF9E9E9E), + color: Colors.black , ), ), ], @@ -200,4 +204,29 @@ class _MineDutyDetailPage extends State { ), ); } + + String _getTypeReturn(final item) { + String type=item['REVIEW_STATUS']; + if("0"==type){ + return "待审批"; + }else if("1"==type){ + return "审批通过"; + }else if("2"==type){ + return "无需审批"; + }else if("-1"==type){ + String type2=item['ISDELETE']; + if("1"==type2){ + if(item['CREATOR']==item['OPERATOR']){ + return "申请人取消"; + }else{ + return "审批人取消"; + } + }else{ + return "审批打回"; + } + }else{ + return "审批错误"; + } + } + } \ No newline at end of file diff --git a/lib/pages/mine/mine_duty_management.dart b/lib/pages/mine/mine_duty_management.dart index 8770294..322b88b 100644 --- a/lib/pages/mine/mine_duty_management.dart +++ b/lib/pages/mine/mine_duty_management.dart @@ -27,6 +27,7 @@ class LeaveRecord { }); } +///离岗管理列表 class MineDutyManagementPage extends StatefulWidget { const MineDutyManagementPage({super.key}); @@ -38,6 +39,8 @@ class _MineDutyManagementPageState extends State { int showCount=-1; int currentPage=1; + late List _list = []; + Future _onRefresh() async { // 模拟网络请求 @@ -45,6 +48,7 @@ class _MineDutyManagementPageState extends State { // 刷新数据逻辑,如 fetchData() setState(() { // TODO: 更新数据源 + refreshData(); }); } @@ -54,56 +58,74 @@ class _MineDutyManagementPageState extends State { } + void refreshData(){ + currentPage=1; + _list.clear(); + _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), - ), - ]; + // 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); + + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => MineDutyApplicationPage( + onClose: (result) { + // print('详情页面已关闭,返回结果: $result'); + refreshData(); + }, + ), + ), + ); + // pushPage(MineDutyApplicationPage(), context); }, child: Text("申请",style: TextStyle(color: Colors.white,fontSize: 16,fontWeight:FontWeight.bold),)) ],), @@ -131,11 +153,14 @@ class _MineDutyManagementPageState extends State { // 记录列表 Expanded( - child: ListView.builder( + child: + _list.isEmpty + ? Center(child: Text('暂无数据')) + : ListView.builder( padding: const EdgeInsets.symmetric(vertical: 16), - itemCount: leaveRecords.length, + itemCount: _list.length, itemBuilder: (context, index) { - final record = leaveRecords[index]; + final record = _list[index]; return _buildRecordCard(record,context); }, ), @@ -146,19 +171,20 @@ class _MineDutyManagementPageState extends State { ); } - 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)}"; + Widget _buildRecordCard(final item , 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)}"; + final dateRange ="${item['STARTTIME']} 至 ${item['ENDTIME']}"; return - // GestureDetector( - // onTap: () { - // pushPage(MineDutyDetailPage(), context); - // }, - // child: + GestureDetector( + onTap: () { + pushPage(MineDutyDetailPage(item), context); + }, + child: Container( margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), decoration: BoxDecoration( @@ -195,7 +221,7 @@ class _MineDutyManagementPageState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - "申请人:${record.applicant}", + "申请人:${item['USER_NAME']}", style: const TextStyle( fontSize: 16, fontWeight: FontWeight.w600, @@ -203,77 +229,114 @@ class _MineDutyManagementPageState extends State { ), const SizedBox(height: 4), Text( - "部门:${record.department} \n岗位:${record.position}", + "部门:${item['DEPARTMENTNAME']} \n岗位:${item['POSTNAME']}", 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 Spacer(), + ], ), - const SizedBox(height: 16), + const SizedBox(height: 8), // 离岗时间 Row( children: [ const Icon(Icons.calendar_today, size: 18, color: Colors.grey), const SizedBox(width: 8), - Text( - "离岗时间: $dateRange", - style: const TextStyle(color: Colors.grey), + Expanded( + child: Text( + "离岗时间: $dateRange", + style: const TextStyle(color: Colors.grey), + ), ), + ], ), - const SizedBox(height: 8), + const SizedBox(height: 4), + // Container( + // padding: const EdgeInsets.symmetric( vertical: 6), + // // decoration: BoxDecoration( + // // color: record.statusColor.withOpacity(0.1), + // // borderRadius: BorderRadius.circular(20), + // // ), + // child: + Text( + "审核状态:${_getTypeReturn(item)}", + // record.status, + style: TextStyle( + color: Colors.black, + fontWeight: FontWeight.w500, + ), + ), + // ), + + const SizedBox(height: 4), // 操作按钮 + if( item["REVIEW_STATUS"]=="0"&&DateTime.now().isBefore(item["ENDTIME"])&& + (item["REVIEW_USER_ID"]==SessionService.instance.loginUserId)&& + SessionService.instance.loginUser?["USERNAME"]=="1"&&item['REVIEW_STATUS']=="0") Row( mainAxisAlignment: MainAxisAlignment.end, children: [ - TextButton( + ElevatedButton( onPressed: () { - pushPage(MineDutyDetailPage(), context); + showDialog( + context: context, + builder: (context) => DutyDialog( + item,1, + onClose: (result) { + // print('详情页面已关闭,返回结果: $result'); + refreshData(); + }, + + ), + ); }, - style: TextButton.styleFrom( - foregroundColor: const Color(0xFF1976D2), + style: ElevatedButton.styleFrom( + backgroundColor: const Color(0xFF1976D2), + // padding: const EdgeInsets.symmetric(horizontal: 10), ), - child: const Text("查看详情"), + child: const Text("审 批", style: TextStyle(color: Colors.white,fontSize: 12)), ), - // 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)), - // ) + + const SizedBox(width: 16), + + ElevatedButton( + onPressed: () { + showDialog( + context: context, + builder: (context) => DutyDialog( + item,2, + onClose: (result) { + // print('详情页面已关闭,返回结果: $result'); + refreshData(); + }, + + ), + ); + }, + style: ElevatedButton.styleFrom( + backgroundColor: Colors.red, + // padding: const EdgeInsets.symmetric(horizontal: 10), + ), + child: const Text("取 消", style: TextStyle(color: Colors.white,fontSize: 12)), + ) + ], ), ], ), ), - // ), + ), ); } @@ -281,16 +344,229 @@ class _MineDutyManagementPageState extends State { Future _getListData() async { try { - final raw = await ApiService.getDutyManagement(showCount,currentPage); - - - + final result = await ApiService.getDutyManagement(showCount,currentPage); + if (result['result'] == 'success') { + final List newList = result['varList'] ?? []; + setState(() { + _list.addAll(newList); + }); + } } catch (e) { - // 出错时可以 Toast 或者在页面上显示错误状态 - print('加载首页数据失败:$e'); + print('加载出错: $e'); } } + String _getTypeReturn(final item) { + String type=item['REVIEW_STATUS']; + if("0"==type){ + return "待审批"; + }else if("1"==type){ + return "审批通过"; + }else if("2"==type){ + return "无需审批"; + }else if("-1"==type){ + String type2=item['ISDELETE']; + if("1"==type2){ + if(item['CREATOR']==item['OPERATOR']){ + return "申请人取消"; + }else{ + return "审批人取消"; + } + }else{ + return "审批打回"; + } + }else{ + return "审批错误"; + } + } + + } + + +enum FeedbackType { + tongGuo, + Dahui, +} + +class DutyDialog extends StatefulWidget { + const DutyDialog(this.item,this.type, {super.key,required this.onClose}); + + final Function(String) onClose; // 回调函数 + final item; + final int type; + + + @override + State createState() => _DutyDialogState(); +} + +class _DutyDialogState extends State { + + final TextEditingController _reasonController = TextEditingController(); + // 反馈类型 + FeedbackType? _selectedType = FeedbackType.tongGuo; + + // 获取反馈类型名称 + String _getTypeName(FeedbackType type) { + switch (type) { + case FeedbackType.tongGuo: + return '通过'; + case FeedbackType.Dahui: + return '打回'; + } + } + + + Future _dutyApproval() async { + try { + + String typeString; + if(FeedbackType.tongGuo==_selectedType){ + typeString="1"; + }else{ + typeString="-1"; + } + + final result = await ApiService.dutyApproval(typeString,_reasonController.text,widget.item["OFFDUTY_ID"]); + if (result['result'] == 'success') { + widget.onClose('关闭提交'); // 触发回调 + } + } catch (e) { + print('加载出错: $e'); + } + } + + Future _dutyReturned() async { + try { + + final result = await ApiService.dutyReturned("-1",_reasonController.text,widget.item["OFFDUTY_ID"]); + if (result['result'] == 'success') { + widget.onClose('关闭提交'); // 触发回调 + } + } catch (e) { + print('加载出错: $e'); + } + } + + @override + Widget build(BuildContext context) { + return Dialog( + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), + child: Container( + padding: const EdgeInsets.all(20), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // 标题 + const Center( + child: Text( + '离岗审批', + style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold), + ), + ), + + const SizedBox(height: 20), + + // 操作按钮行 + // Row( + // mainAxisAlignment: MainAxisAlignment.spaceEvenly, + // children: [ + // _buildActionButton('通过', Colors.green), + // _buildActionButton('打印', Colors.blue), + // ], + // ), + if(1==widget.type) + Center( + child: Wrap( + spacing: 16, + children: + FeedbackType.values.map((type) { + return ChoiceChip( + label: Text(_getTypeName(type)), + selected: _selectedType == type, + onSelected: (selected) { + setState(() { + if (selected) { + _selectedType = type; + } + }); + }, + ); + }).toList(), + ), + ), + + + const SizedBox(height: 20), + + // 输入框 + TextField( + controller: _reasonController, + decoration: InputDecoration( + border: OutlineInputBorder(), + hintText: widget.type==1?'请输入审批意见':'请输入原因', + contentPadding: EdgeInsets.symmetric(horizontal: 12, vertical: 16), + ), + maxLines: 4, + ), + + const SizedBox(height: 20), + + // 底部按钮 + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Expanded( + child: ElevatedButton( + onPressed: (){ + if(_reasonController.text.isEmpty){ + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text(widget.type==1?'请输入审批意见':'请输入原因')) + ); + return; + } + + if(1==widget.type){ + _dutyApproval();//审批 + }else{ + _dutyReturned();//打回 + } + Navigator.pop(context); + } , + style: ElevatedButton.styleFrom( + backgroundColor: Colors.blue, + padding: const EdgeInsets.symmetric(vertical: 14), + ), + child: const Text('提交',style: TextStyle(color: Colors.white),), + ), + ), + const SizedBox(width: 15), + Expanded( + child: ElevatedButton( + onPressed: (){ + Navigator.pop(context); + } , + style: ElevatedButton.styleFrom( + backgroundColor: Colors.grey, + padding: const EdgeInsets.symmetric(vertical: 14), + ), + child: const Text('关闭',style: TextStyle(color: Colors.white),), + ), + ), + ], + ), + ], + ), + ), + ); + } + + +} + + + diff --git a/lib/pages/mine/mine_feedback_page.dart b/lib/pages/mine/mine_feedback_page.dart index 81d4ddf..eaac566 100644 --- a/lib/pages/mine/mine_feedback_page.dart +++ b/lib/pages/mine/mine_feedback_page.dart @@ -16,6 +16,7 @@ enum FeedbackType { other, } +///问题反馈 class FeedbackApp extends StatelessWidget { const FeedbackApp({super.key}); @@ -185,8 +186,11 @@ class _FeedbackPageState extends State { mediaType: MediaType.image, onChanged: (files) { // 上传 files 到服务器 + + }, + onAiIdentify: () { + }, - onAiIdentify: () {}, ), // GridView.builder( @@ -304,10 +308,12 @@ class _FeedbackPageState extends State { String imagePaths=""; for(int i=0;i<_images.length;i++){ + String imagePath=_reloadFeedBack(_images[i]) as String; + if(0==i){ - imagePaths=_images[i]; + imagePaths=imagePath; }else { - imagePaths = "$imagePaths,${_images[i]}"; + imagePaths = "$imagePaths;$imagePath"; } } @@ -339,6 +345,23 @@ class _FeedbackPageState extends State { // } } + Future _reloadFeedBack(String imagePath) async { + try { + + final raw = await ApiService.reloadFeedBack(imagePath); + if (raw['result'] == 'success') { + return raw['imgPath']; + }else{ + // _showMessage('反馈提交失败'); + return ""; + } + + } catch (e) { + // 出错时可以 Toast 或者在页面上显示错误状态 + print('加载首页数据失败:$e'); + return ""; + } + } Future _setFeedBack(String title, String text, String imagePaths, String num) async { try { diff --git a/pubspec.lock b/pubspec.lock index acada0f..9a61f8e 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: @@ -38,7 +38,7 @@ packages: description: name: camera sha256: d6ec2cbdbe2fa8f5e0d07d8c06368fe4effa985a4a5ddade9cc58a8cd849557d - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "0.11.2" camera_android_camerax: @@ -46,7 +46,7 @@ packages: description: name: camera_android_camerax sha256: "4b6c1bef4270c39df96402c4d62f2348c3bb2bbaefd0883b9dbd58f426306ad0" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "0.6.19" camera_avfoundation: @@ -54,7 +54,7 @@ packages: description: name: camera_avfoundation sha256: "9e02b36c9c09a01edcb0f2bfc58a94ed38bbbf37907759d651707bb0f327a365" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "0.9.20+3" camera_platform_interface: @@ -62,7 +62,7 @@ packages: description: name: camera_platform_interface sha256: "2f757024a48696ff4814a789b0bd90f5660c0fb25f393ab4564fb483327930e2" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "2.10.0" camera_web: @@ -70,7 +70,7 @@ packages: description: name: camera_web sha256: "595f28c89d1fb62d77c73c633193755b781c6d2e0ebcd8dc25b763b514e6ba8f" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "0.3.5" characters: @@ -118,7 +118,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: @@ -166,7 +166,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: @@ -174,7 +174,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: @@ -182,7 +182,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: @@ -301,7 +301,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: @@ -637,7 +637,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: @@ -746,7 +746,7 @@ packages: description: name: stream_transform sha256: ad47125e588cfd37a9a7f86c7d6356dde8dfe89d071d293f80ca9e9273a33871 - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "2.1.1" string_scanner: