Compare commits

..

No commits in common. "6d737adce3a4657cce382310a579d50d2610f3d8" and "b04ca72eec581dcab4a9f74cc9bcaf977ff07259" have entirely different histories.

16 changed files with 134 additions and 216 deletions

View File

@ -184,14 +184,14 @@ U6Hzm1ninpWeE+awIDAQAB
); );
} }
static Future<Map<String, dynamic>> getUpdateInfo() { static Future<Map<String, dynamic>> getUpdateInfo() {
return HttpManager().request( return HttpManager().request(
basePath, projectManagerUrl,
'/app/versionmanager/getVersion', '/projectDetails/findUpdate?code=cloud&type=APP',
method: Method.post, method: Method.post,
data: { data: {},
'FILETYPE':Platform.pathSeparator
},
); );
} }
@ -533,10 +533,14 @@ U6Hzm1ninpWeE+awIDAQAB
); );
} }
/// ///
static Future<Map<String, dynamic>> getStudyUserFace( static Future<Map<String, dynamic>> getUserFace(
String imagePath, String imagePath,
Map data String studentId,
String VIDEOCOURSEWARE_ID,
String CURRICULUM_ID,
String CHAPTER_ID,
String CLASS_ID,
) async { ) async {
final file = File(imagePath); final file = File(imagePath);
if (!await file.exists()) { if (!await file.exists()) {
@ -546,53 +550,17 @@ U6Hzm1ninpWeE+awIDAQAB
return HttpManager().uploadFaceImage( return HttpManager().uploadFaceImage(
baseUrl: baseFacePath, baseUrl: baseFacePath,
path: '/app/user/compareFaceV2',
fromData: {
...data,
'USER_ID': SessionService.instance.loginUserId,
'CORPINFO_ID': SessionService.instance.corpinfoId,
'FFILE': await MultipartFile.fromFile(file.path, filename: fileName),
},
);
}
static Future<Map<String, dynamic>> getUpdataUserFace(
String imagePath,
Map data
) 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/user/editUserFaceV2',
fromData: {
...data,
'USER_ID': SessionService.instance.loginUserId,
'CORPINFO_ID': SessionService.instance.corpinfoId,
'FFILE': await MultipartFile.fromFile(file.path, filename: fileName),
},
);
}
static Future<Map<String, dynamic>> getScanUserFace(
String imagePath,
Map data
) 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/user/compareFaceForH5V2', path: '/app/user/compareFaceForH5V2',
fromData: { fromData: {
...data,
'USER_ID': SessionService.instance.loginUserId, 'USER_ID': SessionService.instance.loginUserId,
'STUDENT_ID': studentId,
'CORPINFO_ID': SessionService.instance.corpinfoId, 'CORPINFO_ID': SessionService.instance.corpinfoId,
"CLASS_ID":CLASS_ID,
"VIDEOCOURSEWARE_ID": VIDEOCOURSEWARE_ID,
"CURRICULUM_ID": CURRICULUM_ID,
"CHAPTER_ID": CHAPTER_ID,
'FFILE': await MultipartFile.fromFile(file.path, filename: fileName), 'FFILE': await MultipartFile.fromFile(file.path, filename: fileName),
}, },
); );

View File

@ -14,9 +14,7 @@ import 'package:qhd_prevention/tools/tools.dart';
class ScanPage extends StatefulWidget { class ScanPage extends StatefulWidget {
// const ScanPage({Key? key}) : super(key: key,); // const ScanPage({Key? key}) : super(key: key,);
const ScanPage({super.key, required this.totalList}); const ScanPage({super.key, required this.totalList});
final List totalList; final List totalList;
@override @override
State<ScanPage> createState() => _ScanPageState(); State<ScanPage> createState() => _ScanPageState();
} }
@ -101,9 +99,9 @@ class _ScanPageState extends State<ScanPage> {
} catch (e, st) { } catch (e, st) {
// //
print('handleScanResult error: $e\n$st'); print('handleScanResult error: $e\n$st');
ScaffoldMessenger.of( ScaffoldMessenger.of(context).showSnackBar(
context, SnackBar(content: Text('扫码处理失败: ${e.toString()}')),
).showSnackBar(SnackBar(content: Text('扫码处理失败: ${e.toString()}'))); );
} }
} }
@ -111,17 +109,10 @@ class _ScanPageState extends State<ScanPage> {
void goToFace(Map<String, dynamic> stuInfo) async { void goToFace(Map<String, dynamic> stuInfo) async {
print('navigate to face with $stuInfo'); print('navigate to face with $stuInfo');
final passed = await pushPage<bool>( final passed = await pushPage<bool>(
FaceRecognitionPage( FaceRecognitionPage(studentId: stuInfo['STUDENT_ID'],
studentId: stuInfo['STUDENT_ID'], VIDEOCOURSEWARE_ID: stuInfo['VIDEOCOURSEWARE_ID'],CURRICULUM_ID: stuInfo['CURRICULUM_ID'],
data: { CHAPTER_ID: stuInfo['CHAPTER_ID'],CLASS_ID: stuInfo['CLASS_ID'],
'VIDEOCOURSEWARE_ID': stuInfo['VIDEOCOURSEWARE_ID'], mode: FaceMode.auto),
'CURRICULUM_ID': stuInfo['CURRICULUM_ID'],
'CHAPTER_ID': stuInfo['CHAPTER_ID'],
'CLASS_ID': stuInfo['CLASS_ID'],
'STUDENT_ID':stuInfo['STUDENT_ID'],
},
mode: FaceMode.scan,
),
context, context,
); );
if (passed == true) { if (passed == true) {
@ -184,20 +175,15 @@ class _ScanPageState extends State<ScanPage> {
// //
// 1. // 1.
Positioned( Positioned(
left: 0, left: 0, right: 0, top: 0,
right: 0, height: top, //
top: 0,
height: top,
//
child: Container(color: Colors.black54), child: Container(color: Colors.black54),
), ),
// 2. // 2.
Positioned( Positioned(
left: 0, left: 0, right: 0,
right: 0, top: top + scanSize, //
top: top + scanSize,
//
bottom: 0, bottom: 0,
child: Container(color: Colors.black54), child: Container(color: Colors.black54),
), ),
@ -206,10 +192,8 @@ class _ScanPageState extends State<ScanPage> {
Positioned( Positioned(
left: 0, left: 0,
top: top, top: top,
width: left, width: left, //
// height: scanSize, //
height: scanSize,
//
child: Container(color: Colors.black54), child: Container(color: Colors.black54),
), ),
@ -218,8 +202,7 @@ class _ScanPageState extends State<ScanPage> {
left: left + scanSize, left: left + scanSize,
top: top, top: top,
right: 0, right: 0,
height: scanSize, height: scanSize, //
//
child: Container(color: Colors.black54), child: Container(color: Colors.black54),
), ),
@ -256,11 +239,7 @@ class _ScanPageState extends State<ScanPage> {
child: IconButton( child: IconButton(
iconSize: 32, iconSize: 32,
color: Colors.white, color: Colors.white,
icon: Icon( icon: Icon(_torchOn ? Icons.flashlight_off_outlined : Icons.flashlight_on_outlined),
_torchOn
? Icons.flashlight_off_outlined
: Icons.flashlight_on_outlined,
),
onPressed: () { onPressed: () {
_controller.toggleTorch(); _controller.toggleTorch();
setState(() { setState(() {
@ -294,4 +273,5 @@ class _ScanPageState extends State<ScanPage> {
), ),
); );
} }
} }

View File

@ -17,18 +17,28 @@ import 'package:qhd_prevention/tools/tools.dart';
const MethodChannel _platformChan = MethodChannel('qhd_prevention/permissions'); const MethodChannel _platformChan = MethodChannel('qhd_prevention/permissions');
/// ///
enum FaceMode { setUpdata, study, scan } enum FaceMode { auto, manual }
class FaceRecognitionPage extends StatefulWidget { class FaceRecognitionPage extends StatefulWidget {
final String studentId; final String studentId;
final Map data;
final String VIDEOCOURSEWARE_ID;
final String CURRICULUM_ID;
final String CHAPTER_ID;
final String CLASS_ID;
final FaceMode mode; final FaceMode mode;
const FaceRecognitionPage({ const FaceRecognitionPage({
Key? key, Key? key,
required this.studentId, required this.studentId,
required this.data,
this.mode = FaceMode.study, required this.VIDEOCOURSEWARE_ID,
required this.CURRICULUM_ID,
required this.CHAPTER_ID,
required this.CLASS_ID,
this.mode = FaceMode.auto,
}) : super(key: key); }) : super(key: key);
@override @override
@ -45,7 +55,7 @@ class _FaceRecognitionPageState extends State<FaceRecognitionPage>
static const Duration _interval = Duration(seconds: 2); static const Duration _interval = Duration(seconds: 2);
String _errMsg = ''; String _errMsg = '';
bool get _isManualMode => widget.mode == FaceMode.setUpdata; bool get _isManualMode => widget.mode == FaceMode.manual;
bool _isInitializing = false; bool _isInitializing = false;
bool _isTaking = false; bool _isTaking = false;
@ -261,18 +271,9 @@ class _FaceRecognitionPageState extends State<FaceRecognitionPage>
} catch (_) {} } catch (_) {}
final XFile pic = await _cameraController!.takePicture(); final XFile pic = await _cameraController!.takePicture();
var res = {}; final res = await ApiService.getUserFace(pic.path, widget.studentId,
switch(widget.mode) { widget.VIDEOCOURSEWARE_ID,widget.CURRICULUM_ID,widget.CHAPTER_ID,widget.CLASS_ID,);
case FaceMode.study:
res = await ApiService.getStudyUserFace(pic.path, widget.data);
break;
case FaceMode.setUpdata:
res = await ApiService.getUpdataUserFace(pic.path, widget.data);
break;
case FaceMode.scan:
res = await ApiService.getScanUserFace(pic.path, widget.data);
break;
}
if (res['result'] == 'success') { if (res['result'] == 'success') {
_onSuccess(); _onSuccess();
} else { } else {
@ -334,7 +335,7 @@ class _FaceRecognitionPageState extends State<FaceRecognitionPage>
void _onSuccess() { void _onSuccess() {
_timer?.cancel(); _timer?.cancel();
if (widget.mode == FaceMode.setUpdata) { if (widget.mode == FaceMode.manual) {
ToastUtil.showSuccess(context, '已更新人脸信息'); ToastUtil.showSuccess(context, '已更新人脸信息');
Future.delayed(const Duration(milliseconds: 800), () { Future.delayed(const Duration(milliseconds: 800), () {
if (mounted) Navigator.of(context).pop(true); if (mounted) Navigator.of(context).pop(true);

View File

@ -236,7 +236,7 @@ class _StudyDetailPageState extends State<StudyDetailPage>
} }
} catch (_) {} } catch (_) {}
await _navigateFaceIfNeeded(data,() async { await _navigateFaceIfNeeded(() async {
if ((data['IS_VIDEO'] ?? 0) == 1) { if ((data['IS_VIDEO'] ?? 0) == 1) {
// //
if (data['VIDEOFILES'] != null) { if (data['VIDEOFILES'] != null) {
@ -289,7 +289,7 @@ class _StudyDetailPageState extends State<StudyDetailPage>
}); });
} }
Future<void> _navigateFaceIfNeeded(Map data, FutureOr<void> Function() onPass) async { Future<void> _navigateFaceIfNeeded(FutureOr<void> Function() onPass) async {
if (!_isFace) { if (!_isFace) {
await onPass(); await onPass();
return; return;
@ -305,14 +305,11 @@ class _StudyDetailPageState extends State<StudyDetailPage>
final passed = await pushPage<bool>( final passed = await pushPage<bool>(
FaceRecognitionPage( FaceRecognitionPage(
studentId: widget.studentId, studentId: widget.studentId,
data: { VIDEOCOURSEWARE_ID: "",
'CLASS_ID': widget.studyData['CLASS_ID'], CURRICULUM_ID: "",
'STUDENT_ID': widget.studyData['STUDENT_ID'], CHAPTER_ID: "",
'CURRICULUM_ID': data['CURRICULUM_ID'], CLASS_ID: "",
'CHAPTER_ID': data['CHAPTER_ID'], mode: FaceMode.auto,
'VIDEOCOURSEWARE_ID': data['VIDEOCOURSEWARE_ID']
},
mode: FaceMode.study,
), ),
context, context,
); );
@ -335,17 +332,17 @@ class _StudyDetailPageState extends State<StudyDetailPage>
if (ok) { if (ok) {
await _exitTopRouteAndWait(); await _exitTopRouteAndWait();
await _lockPortrait(); await _lockPortrait();
await pushPage(FaceRecognitionPage ( await pushPage(
studentId: widget.studentId, const FaceRecognitionPage(
data: { studentId: '',
'CLASS_ID': widget.studyData['CLASS_ID'], VIDEOCOURSEWARE_ID: '',
'STUDENT_ID': widget.studyData['STUDENT_ID'], CURRICULUM_ID: '',
'CURRICULUM_ID': data['CURRICULUM_ID'], CHAPTER_ID: '',
'CHAPTER_ID': data['CHAPTER_ID'], CLASS_ID: '',
'VIDEOCOURSEWARE_ID': data['VIDEOCOURSEWARE_ID'] mode: FaceMode.manual,
}, ),
mode: FaceMode.study, context,
), context); );
await _restoreDefaultOrientations(); await _restoreDefaultOrientations();
} }
} }
@ -700,14 +697,11 @@ class _StudyDetailPageState extends State<StudyDetailPage>
final passed = await pushPage<bool>( final passed = await pushPage<bool>(
FaceRecognitionPage( FaceRecognitionPage(
studentId: widget.studentId, studentId: widget.studentId,
data: { VIDEOCOURSEWARE_ID: "",
'CLASS_ID': widget.studyData['CLASS_ID'], CURRICULUM_ID: "",
'STUDENT_ID': widget.studyData['STUDENT_ID'], CHAPTER_ID: "",
'CURRICULUM_ID': _currentVideoData?['CURRICULUM_ID'], CLASS_ID: "",
'CHAPTER_ID': _currentVideoData?['CHAPTER_ID'], mode: FaceMode.auto,
'VIDEOCOURSEWARE_ID': _currentVideoData?['VIDEOCOURSEWARE_ID']
},
mode: FaceMode.study,
), ),
context, context,
); );

View File

@ -146,7 +146,6 @@ class ItemListWidget {
bool isRequired = true, bool isRequired = true,
String hintText = '请输入', String hintText = '请输入',
ValueChanged<String>? onChanged, ValueChanged<String>? onChanged,
bool showMaxLength = false,
}) { }) {
return Container( return Container(
// padding线 // padding线
@ -180,7 +179,6 @@ class ItemListWidget {
maxLines: null, maxLines: null,
expands: true, expands: true,
onChanged: onChanged, onChanged: onChanged,
maxLength: showMaxLength ? 120 : null,
// //
textAlignVertical: TextAlignVertical.top, textAlignVertical: TextAlignVertical.top,
style: TextStyle(fontSize: fontSize), style: TextStyle(fontSize: fontSize),

View File

@ -187,6 +187,7 @@ class _HotworkSafeFuncSureState extends State<HotworkSafeFuncSure> {
/// 1 0 /// 1 0
Future<void> _submit(String status) async { Future<void> _submit(String status) async {
if (imagePaths.isEmpty) { if (imagePaths.isEmpty) {
ToastUtil.showNormal(context, '请签字'); ToastUtil.showNormal(context, '请签字');
return; return;
@ -207,7 +208,7 @@ class _HotworkSafeFuncSureState extends State<HotworkSafeFuncSure> {
title: '作废原因', title: '作废原因',
hintText: '请输入作废原因', hintText: '请输入作废原因',
cancelText: '取消', cancelText: '取消',
confirmText: '确定', confirmText: '确定'
); );
// //
if (reasonText == null) { if (reasonText == null) {
@ -376,11 +377,11 @@ class _HotworkSafeFuncSureState extends State<HotworkSafeFuncSure> {
), ),
], ],
), ),
ItemListWidget.multiLineTitleTextField( ItemListWidget.singleLineTitleText(
label: '其他安全措施:', label: '其他安全措施:',
showMaxLength:true, showMaxLength:true,
isEditable: true, isEditable: true,
isRequired: true,
hintText: '请输入其他安全措施', hintText: '请输入其他安全措施',
controller: _otherController, controller: _otherController,
), ),

View File

@ -430,11 +430,11 @@ if (reasonText.isEmpty) {
), ),
], ],
), ),
ItemListWidget.multiLineTitleTextField( ItemListWidget.singleLineTitleText(
label: '其他安全措施:', label: '其他安全措施:',
showMaxLength:true, showMaxLength:true,
isEditable: true, isEditable: true,
isRequired: true,
hintText: '请输入其他安全措施', hintText: '请输入其他安全措施',
controller: _otherController, controller: _otherController,
), ),

View File

@ -389,11 +389,11 @@ if (reasonText.isEmpty) {
), ),
], ],
), ),
ItemListWidget.multiLineTitleTextField( ItemListWidget.singleLineTitleText(
label: '其他安全措施:', label: '其他安全措施:',
showMaxLength:true, showMaxLength:true,
isEditable: true, isEditable: true,
isRequired: true,
hintText: '请输入其他安全措施', hintText: '请输入其他安全措施',
controller: _otherController, controller: _otherController,
), ),

View File

@ -388,11 +388,11 @@ if (reasonText.isEmpty) {
), ),
], ],
), ),
ItemListWidget.multiLineTitleTextField( ItemListWidget.singleLineTitleText(
label: '其他安全措施:', label: '其他安全措施:',
showMaxLength:true, showMaxLength:true,
isEditable: true, isEditable: true,
isRequired: true,
hintText: '请输入其他安全措施', hintText: '请输入其他安全措施',
controller: _otherController, controller: _otherController,
), ),

View File

@ -376,11 +376,11 @@ if (reasonText.isEmpty) {
), ),
], ],
), ),
ItemListWidget.multiLineTitleTextField( ItemListWidget.singleLineTitleText(
label: '其他安全措施:', label: '其他安全措施:',
showMaxLength: true,
isEditable: true, isEditable: true,
isRequired: true, showMaxLength:true,
hintText: '请输入其他安全措施', hintText: '请输入其他安全措施',
controller: _otherController, controller: _otherController,
), ),

View File

@ -378,11 +378,11 @@ if (reasonText.isEmpty) {
), ),
], ],
), ),
ItemListWidget.multiLineTitleTextField( ItemListWidget.singleLineTitleText(
label: '其他安全措施:', label: '其他安全措施:',
showMaxLength:true, showMaxLength:true,
isEditable: true, isEditable: true,
isRequired: true,
hintText: '请输入其他安全措施', hintText: '请输入其他安全措施',
controller: _otherController, controller: _otherController,
), ),

View File

@ -391,11 +391,11 @@ if (reasonText.isEmpty) {
), ),
], ],
), ),
ItemListWidget.multiLineTitleTextField( ItemListWidget.singleLineTitleText(
label: '其他安全措施:', label: '其他安全措施:',
showMaxLength:true, showMaxLength:true,
isEditable: true, isEditable: true,
isRequired: true,
hintText: '请输入其他安全措施', hintText: '请输入其他安全措施',
controller: _otherController, controller: _otherController,
), ),

View File

@ -376,11 +376,11 @@ if (reasonText.isEmpty) {
), ),
], ],
), ),
ItemListWidget.multiLineTitleTextField( ItemListWidget.singleLineTitleText(
label: '其他安全措施:', label: '其他安全措施:',
showMaxLength:true, showMaxLength:true,
isEditable: true, isEditable: true,
isRequired: true,
hintText: '请输入其他安全措施', hintText: '请输入其他安全措施',
controller: _otherController, controller: _otherController,
), ),

View File

@ -5,8 +5,6 @@ import 'package:fluttertoast/fluttertoast.dart';
import 'package:qhd_prevention/customWidget/toast_util.dart'; import 'package:qhd_prevention/customWidget/toast_util.dart';
import 'package:qhd_prevention/pages/mine/mine_set_pwd_page.dart'; import 'package:qhd_prevention/pages/mine/mine_set_pwd_page.dart';
import 'package:qhd_prevention/services/auth_service.dart'; import 'package:qhd_prevention/services/auth_service.dart';
import 'package:qhd_prevention/tools/tools.dart';
import 'package:qhd_prevention/tools/update/update_dialogs.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import '../tools/tools.dart'; import '../tools/tools.dart';
import 'main_tab.dart'; import 'main_tab.dart';
@ -99,26 +97,20 @@ class _LoginPageState extends State<LoginPage> {
try{ try{
final result = await AuthService.checkUpdate(); final result = await AuthService.checkUpdate();
if (FormUtils.hasValue(result, 'pd')) { if (FormUtils.hasValue(result, 'pd')) {
Map pd = result['pd'];
final versionInfo = await getAppVersion();
bool isWifi = await checkNetworkWifi();
if (versionInfo.versionName != pd['VERSION']) {
// //
final ok = await CustomAlertDialog.showConfirm( Map pd = result['pd'];
CustomAlertDialog.showConfirm(
context, context,
title: '更新通知', title: '更新通知',
content: isWifi ? '发现新版本,是否更新?为了更好的体验,请更新到最新版本。' : '发现新版本,检查到您当前使用的是移动网络,是否更新?更新时请注意流量消耗。为了更好的体验,请更新到最新版本。', cancelText: '',
cancelText: pd['ISUPDATE'] == '1' ? '' : '稍后更新', confirmText: '我知道了',
confirmText: '立即更新' content: pd['UPLOAD_CONTENT'] ?? '',
onConfirm: () {
ToastUtil.showNormal(context, '更新去吧!');
},
); );
if (ok) {
// await showUpdateConfirmDialog(context, apkUrl: apkUrl);
}
return; return;
} }
}
}catch(_) {} }catch(_) {}
} }

View File

@ -26,7 +26,6 @@ class _MineSetPageState extends State<MineSetPage> {
final result = await AuthService.checkUpdate(); final result = await AuthService.checkUpdate();
LoadingDialogHelper.hide(); LoadingDialogHelper.hide();
if (FormUtils.hasValue(result, 'pd')) { if (FormUtils.hasValue(result, 'pd')) {
// //
Map pd = result['pd']; Map pd = result['pd'];
CustomAlertDialog.showConfirm( CustomAlertDialog.showConfirm(
@ -69,8 +68,10 @@ class _MineSetPageState extends State<MineSetPage> {
child: _setItemWidget("更新人脸信息"), child: _setItemWidget("更新人脸信息"),
onTap: () { onTap: () {
pushPage( pushPage(
const FaceRecognitionPage(studentId: '',data: {}, const FaceRecognitionPage(studentId: '',
mode: FaceMode.setUpdata), VIDEOCOURSEWARE_ID: '',CURRICULUM_ID: '',
CHAPTER_ID: '',CLASS_ID: '',
mode: FaceMode.manual),
context, context,
); );
}, },

View File

@ -7,7 +7,6 @@ import 'package:flutter/services.dart';
import 'dart:io'; import 'dart:io';
import 'package:image_picker/image_picker.dart'; import 'package:image_picker/image_picker.dart';
import 'package:permission_handler/permission_handler.dart'; import 'package:permission_handler/permission_handler.dart';
import 'package:connectivity_plus/connectivity_plus.dart';
int getRandomWithNum(int min, int max) { int getRandomWithNum(int min, int max) {
if (max < min) { if (max < min) {
@ -595,19 +594,3 @@ class CameraPermissionHelper {
} }
} }
Future<bool> checkNetworkWifi() async {
final connectivityResult = await Connectivity().checkConnectivity();
if (connectivityResult == ConnectivityResult.mobile) {
print("当前是移动网络(可能是 2G/3G/4G/5G");
} else if (connectivityResult == ConnectivityResult.wifi) {
return true;
print("当前是 WiFi");
} else if (connectivityResult == ConnectivityResult.ethernet) {
print("当前是有线网络");
} else if (connectivityResult == ConnectivityResult.none) {
print("当前无网络连接");
}
return false;
}