2025.7.17 离岗完成
parent
9e64c43dd0
commit
af81885441
|
@ -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<Map<String, dynamic>> loginCheck(String keydataVal) {
|
||||
return HttpManager().request(
|
||||
|
@ -403,6 +426,29 @@ U6Hzm1ninpWeE+awIDAQAB
|
|||
);
|
||||
}
|
||||
|
||||
/// 问题反馈图片
|
||||
static Future<Map<String, dynamic>> 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<Map<String, dynamic>> changePassWord(String oldPwd,String confirmPwd) {
|
||||
return HttpManager().request(
|
||||
|
@ -423,7 +469,7 @@ U6Hzm1ninpWeE+awIDAQAB
|
|||
static Future<Map<String, dynamic>> 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<Map<String, dynamic>> getAiAlarmList(String showCount, String currentPage,String keyWord) {
|
||||
|
||||
return HttpManager().request(
|
||||
|
@ -555,5 +601,75 @@ U6Hzm1ninpWeE+awIDAQAB
|
|||
}
|
||||
|
||||
|
||||
/// 离岗申请
|
||||
static Future<Map<String, dynamic>> 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<Map<String, dynamic>> 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<Map<String, dynamic>> 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<Map<String, dynamic>> 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'
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -86,7 +86,7 @@ class _FaceRecognitionPageState extends State<FaceRecognitionPage> {
|
|||
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 {
|
||||
|
|
|
@ -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<MineDepartureRecordPage> {
|
||||
|
||||
int showCount=-1;
|
||||
int currentPage=1;
|
||||
late List<dynamic> _list = [];
|
||||
|
||||
|
||||
Future<void> _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<MineDepartureRecordPage> {
|
|||
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<MineDepartureRecordPage> {
|
|||
);
|
||||
}
|
||||
|
||||
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<void> _getListData() async {
|
||||
try {
|
||||
|
||||
final result = await ApiService.getDepartureRecordList(showCount,currentPage);
|
||||
if (result['result'] == 'success') {
|
||||
final List<dynamic> 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<DutyDialog> createState() => _DutyDialogState();
|
||||
}
|
||||
|
||||
class _DutyDialogState extends State<DutyDialog> {
|
||||
|
||||
final TextEditingController _reasonController = TextEditingController();
|
||||
// 反馈类型
|
||||
FeedbackType? _selectedType = FeedbackType.tongGuo;
|
||||
|
||||
// 获取反馈类型名称
|
||||
String _getTypeName(FeedbackType type) {
|
||||
switch (type) {
|
||||
case FeedbackType.tongGuo:
|
||||
return '通过';
|
||||
case FeedbackType.Dahui:
|
||||
return '打回';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Future<void> _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<void> _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),),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -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<MineDutyApplicationPage> createState() => _MineDutyApplicationPage();
|
||||
|
@ -15,7 +19,27 @@ class _MineDutyApplicationPage extends State<MineDutyApplicationPage> {
|
|||
DateTime? _startDate;
|
||||
DateTime? _endDate;
|
||||
final TextEditingController _reasonController = TextEditingController();
|
||||
final String _applicant = "王轩";
|
||||
|
||||
|
||||
|
||||
Future<void> _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<void> _selectDate(BuildContext context, bool isStartDate) async {
|
||||
final DateTime? picked = await showDatePicker(
|
||||
|
@ -42,19 +66,30 @@ class _MineDutyApplicationPage extends State<MineDutyApplicationPage> {
|
|||
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<MineDutyApplicationPage> {
|
|||
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<MineDutyApplicationPage> {
|
|||
const SizedBox(height: 24),
|
||||
|
||||
// 申请人信息
|
||||
_buildInfoRow("申请人", _applicant),
|
||||
// _buildInfoRow("申请人", _applicant),
|
||||
_buildInfoRow("申请人", SessionService.instance.username.toString()),
|
||||
|
||||
const SizedBox(height: 40),
|
||||
|
||||
|
|
|
@ -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<MineDutyDetailPage> createState() => _MineDutyDetailPage();
|
||||
}
|
||||
|
||||
class _MineDutyDetailPage extends State<MineDutyDetailPage> {
|
||||
DateTime? _startDate;
|
||||
DateTime? _endDate;
|
||||
|
||||
final TextEditingController _reasonController = TextEditingController();
|
||||
final String _applicant = "王轩";
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -32,13 +32,13 @@ class _MineDutyDetailPage extends State<MineDutyDetailPage> {
|
|||
|
||||
|
||||
// 申请人信息
|
||||
_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<MineDutyDetailPage> {
|
|||
// 离岗结束时间
|
||||
_buildDateField(
|
||||
label: "离岗结束时间",
|
||||
date: _endDate,
|
||||
date: widget.item["ENDTIME"],
|
||||
onTap: () {
|
||||
|
||||
},
|
||||
|
@ -83,7 +83,8 @@ class _MineDutyDetailPage extends State<MineDutyDetailPage> {
|
|||
],
|
||||
),
|
||||
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<MineDutyDetailPage> {
|
|||
|
||||
|
||||
const SizedBox(height: 24),
|
||||
|
||||
|
||||
// 申请人信息
|
||||
_buildInfoRow("审批状态", "无需审批"),
|
||||
_buildInfoRow("审批状态", _getTypeReturn(widget.item)),
|
||||
|
||||
|
||||
const SizedBox(height: 40),
|
||||
|
@ -131,7 +134,7 @@ class _MineDutyDetailPage extends State<MineDutyDetailPage> {
|
|||
|
||||
Widget _buildDateField({
|
||||
required String label,
|
||||
required DateTime? date,
|
||||
required String? date,
|
||||
required VoidCallback onTap,
|
||||
}) {
|
||||
return GestureDetector(
|
||||
|
@ -158,10 +161,11 @@ class _MineDutyDetailPage extends State<MineDutyDetailPage> {
|
|||
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<MineDutyDetailPage> {
|
|||
),
|
||||
);
|
||||
}
|
||||
|
||||
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 "审批错误";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -27,6 +27,7 @@ class LeaveRecord {
|
|||
});
|
||||
}
|
||||
|
||||
///离岗管理列表
|
||||
class MineDutyManagementPage extends StatefulWidget {
|
||||
const MineDutyManagementPage({super.key});
|
||||
|
||||
|
@ -38,6 +39,8 @@ class _MineDutyManagementPageState extends State<MineDutyManagementPage> {
|
|||
|
||||
int showCount=-1;
|
||||
int currentPage=1;
|
||||
late List<dynamic> _list = [];
|
||||
|
||||
|
||||
Future<void> _onRefresh() async {
|
||||
// 模拟网络请求
|
||||
|
@ -45,6 +48,7 @@ class _MineDutyManagementPageState extends State<MineDutyManagementPage> {
|
|||
// 刷新数据逻辑,如 fetchData()
|
||||
setState(() {
|
||||
// TODO: 更新数据源
|
||||
refreshData();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -54,56 +58,74 @@ class _MineDutyManagementPageState extends State<MineDutyManagementPage> {
|
|||
|
||||
}
|
||||
|
||||
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<MineDutyManagementPage> {
|
|||
|
||||
// 记录列表
|
||||
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<MineDutyManagementPage> {
|
|||
);
|
||||
}
|
||||
|
||||
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<MineDutyManagementPage> {
|
|||
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<MineDutyManagementPage> {
|
|||
),
|
||||
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<MineDutyManagementPage> {
|
|||
Future<void> _getListData() async {
|
||||
try {
|
||||
|
||||
final raw = await ApiService.getDutyManagement(showCount,currentPage);
|
||||
|
||||
|
||||
|
||||
final result = await ApiService.getDutyManagement(showCount,currentPage);
|
||||
if (result['result'] == 'success') {
|
||||
final List<dynamic> 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<DutyDialog> createState() => _DutyDialogState();
|
||||
}
|
||||
|
||||
class _DutyDialogState extends State<DutyDialog> {
|
||||
|
||||
final TextEditingController _reasonController = TextEditingController();
|
||||
// 反馈类型
|
||||
FeedbackType? _selectedType = FeedbackType.tongGuo;
|
||||
|
||||
// 获取反馈类型名称
|
||||
String _getTypeName(FeedbackType type) {
|
||||
switch (type) {
|
||||
case FeedbackType.tongGuo:
|
||||
return '通过';
|
||||
case FeedbackType.Dahui:
|
||||
return '打回';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Future<void> _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<void> _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),),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ enum FeedbackType {
|
|||
other,
|
||||
}
|
||||
|
||||
///问题反馈
|
||||
class FeedbackApp extends StatelessWidget {
|
||||
const FeedbackApp({super.key});
|
||||
|
||||
|
@ -185,8 +186,11 @@ class _FeedbackPageState extends State<FeedbackPage> {
|
|||
mediaType: MediaType.image,
|
||||
onChanged: (files) {
|
||||
// 上传 files 到服务器
|
||||
|
||||
},
|
||||
onAiIdentify: () {
|
||||
|
||||
},
|
||||
onAiIdentify: () {},
|
||||
),
|
||||
|
||||
// GridView.builder(
|
||||
|
@ -304,10 +308,12 @@ class _FeedbackPageState extends State<FeedbackPage> {
|
|||
|
||||
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<FeedbackPage> {
|
|||
// }
|
||||
}
|
||||
|
||||
Future<String> _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<void> _setFeedBack(String title, String text, String imagePaths, String num) async {
|
||||
try {
|
||||
|
|
26
pubspec.lock
26
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:
|
||||
|
|
Loading…
Reference in New Issue