---------------------------线上2.2.0

main
hs 2025-09-19 09:36:32 +08:00
parent 2850a9d49b
commit d6cdc92c78
42 changed files with 307 additions and 211 deletions

View File

@ -33,9 +33,6 @@ class _RemoteFilePageState extends State<RemoteFilePage> {
late PdfControllerPinch _pdfController;
int _totalPages = 0;
// (<=3)
Timer? _pageViewTimer;
@override
void initState() {
super.initState();
@ -96,36 +93,12 @@ class _RemoteFilePageState extends State<RemoteFilePage> {
@override
void dispose() {
_countdownTimer?.cancel();
_pageViewTimer?.cancel();
if (!_isLoading) {
_pdfController.dispose();
}
super.dispose();
}
// pdfx page 1-based
void _onPageChanged(int page) {
//
_pageViewTimer?.cancel();
// 1
if (_totalPages > 0 && page >= _totalPages) {
//
setState(() => _hasScrolledToBottom = true);
return;
}
// <=3
if (_totalPages > 0 && _totalPages <= 3) {
// page == _totalPages
if (page == _totalPages) {
_pageViewTimer = Timer(const Duration(seconds: 1), () {
if (mounted) setState(() => _hasScrolledToBottom = true);
});
}
}
}
@override
Widget build(BuildContext context) {
final isButtonEnabled = _timerFinished && _hasScrolledToBottom;
@ -142,16 +115,16 @@ class _RemoteFilePageState extends State<RemoteFilePage> {
controller: _pdfController,
scrollDirection: Axis.vertical,
onDocumentLoaded: (document) {
setState(() {
_totalPages = document.pagesCount;
// 1
if (_totalPages <= 1) {
_hasScrolledToBottom = true;
}
});
_totalPages = document.pagesCount;
// 1
if (_totalPages <= 1) {
_hasScrolledToBottom = true;
}
},
onPageChanged: (page) {
_onPageChanged(page);
if (page == _totalPages - 1) {
setState(() => _hasScrolledToBottom = true);
}
},
),
),

View File

@ -190,7 +190,7 @@ U6Hzm1ninpWeE+awIDAQAB
'/app/versionmanager/getVersion',
method: Method.post,
data: {
'FILETYPE':Platform.pathSeparator
'FILETYPE':Platform.isIOS ? 'iOS' : 'Android'
},
);
}

View File

@ -1,5 +1,6 @@
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:qhd_prevention/customWidget/custom_alert_dialog.dart';
@ -192,6 +193,7 @@ class HomePageState extends State<HomePage> {
Future<void> _initialLoad() async {
final result = await AuthService.checkUpdate();
try{
if (FormUtils.hasValue(result, 'pd')) {
Map pd = result['pd'];
final versionInfo = await getAppVersion();
@ -207,8 +209,13 @@ class HomePageState extends State<HomePage> {
confirmText: '立即更新'
);
if (ok) {
final apkUrl = pd['FILEURL'] ?? '';
await showUpdateConfirm(context, apkUrl: apkUrl);
if (Platform.isIOS) {
openAppStore();
}else{
final apkUrl = pd['FILEURL'] ?? '';
await showUpdateConfirm(context, apkUrl: apkUrl);
}
}
return;
}

View File

@ -24,13 +24,16 @@ class ImageData {
class SignImageData {
String SIGNER_TIME;
String? filePath;
String? localPath;
int? key;
SignImageData({required this.SIGNER_TIME, this.filePath, this.key});
SignImageData({required this.SIGNER_TIME, this.filePath,this.localPath, this.key});
Map<String, dynamic> toJson() => {
'SIGNER_TIME': SIGNER_TIME,
'filePath': filePath,
'localPath': localPath,
'key': key,
};
@ -38,13 +41,14 @@ class SignImageData {
return SignImageData(
SIGNER_TIME: m['SIGNER_TIME'] ?? '',
filePath: m['filePath'],
localPath: m['localPath'],
key: m['key'] != null ? int.tryParse(m['key'].toString()) : null,
);
}
@override
String toString() =>
'SignImageData(key:$key, filePath:$filePath, SIGNER_TIME:$SIGNER_TIME)';
'SignImageData(key:$key, filePath:$filePath, localPath:$localPath,SIGNER_TIME:$SIGNER_TIME)';
}
class DangerousOptionsPage extends StatefulWidget {
@ -131,44 +135,46 @@ class _DangerousOptionsPageState extends State<DangerousOptionsPage> {
return;
}
LoadingDialogHelper.show();
List<SignImageData> filePaths = [];
// List<SignImageData> filePaths = [];
List severImageList = [];
for (SignImageData data in signImgList) {
String path = data.filePath ?? '';
if (!path.contains('uploadFiles')) {
filePaths.add(data);
} else {
severImageList.add({
'filePath': data.filePath,
'SIGNER_TIME': data.SIGNER_TIME,
'key': data.key,
});
}
}
if (filePaths.length == 0) {
//
setState(() => buttonLoading = true);
LoadingDialogHelper.hide();
Navigator.pop(context, {
'imgList':
imgList
.map((e) => {'local': e.localPath, 'remote': e.serverPath})
.toList(),
'signImgList': signImgList,
'index': index,
'status': status,
});
return;
}
final result = await ApiService.saveDangerousOptionsFile(filePaths.map((item) => item.filePath).toList());
// for (SignImageData data in signImgList) {
// String path = data.filePath ?? '';
// if (!path.contains('uploadFiles')) {
// filePaths.add(data);
// } else {
// severImageList.add({
// 'filePath': '',
// 'localPath':data.filePath,
// 'SIGNER_TIME': data.SIGNER_TIME,
// 'key': data.key,
// });
// }
// }
// if (filePaths.length == 0) {
// //
// setState(() => buttonLoading = true);
// LoadingDialogHelper.hide();
// Navigator.pop(context, {
// 'imgList':
// imgList
// .map((e) => {'local': e.localPath, 'remote': e.serverPath})
// .toList(),
// 'signImgList': signImgList,
// 'index': index,
// 'status': status,
// });
// return;
// }
final result = await ApiService.saveDangerousOptionsFile(signImgList.map((item) => item.localPath).toList());
final List<dynamic> signList = result['FILE_PATH_LIST'];
for (SignImageData data in filePaths) {
for (SignImageData data in signImgList) {
for (Map<String, dynamic> img in signList) {
String imgName = 'file${data.key}';
if (imgName == img['key']) {
final idata = {
'localPath':data.localPath,
'filePath': img['filePath'] ?? '',
'SIGNER_TIME': data.SIGNER_TIME,
'key': data.key,
@ -203,7 +209,8 @@ class _DangerousOptionsPageState extends State<DangerousOptionsPage> {
setState(() {
final imageData = SignImageData(
SIGNER_TIME: now,
filePath: path,
filePath: '',
localPath: path,
key: signImgList.length,
);
signImgList.add(imageData);
@ -237,7 +244,7 @@ class _DangerousOptionsPageState extends State<DangerousOptionsPage> {
'${ApiService.baseImgPath}${imgData.filePath}',
)
: Image.file(
File(imgData.filePath ?? ''),
File(imgData.localPath ?? ''),
fit: BoxFit.contain,
),
),

View File

@ -218,7 +218,7 @@ class _HotWorkDetailFormWidgetState extends State<HotWorkDetailFormWidget> {
},
hintText: '请输入关联的其他特殊作业及安全作业票编号',
controller: widget.relatedController,
text: pd['SPECIAL_WORK'] ?? '',
text: pd['SPECIAL_WORK'] ?? '',
),
const Divider(),
ItemListWidget.twoRowButtonTitleText(

View File

@ -480,7 +480,40 @@ class _HotworkApplyDetailState extends State<HotworkApplyDetail> {
//FocusHelper.clearFocus(context);
});
}
bool checkWorkTime(Map<String, dynamic> pd, BuildContext context) {
//
final start = DateTime.parse(pd['WORK_EXPECTED_START_TIME'] as String);
final end = DateTime.parse(pd['WORK_EXPECTED_END_TIME'] as String);
//
if (end.isAtSameMomentAs(start) || end.isBefore(start)) {
ToastUtil.showNormal(context, '作业开始时间不能晚于或等于结束时间,请重新选择');
return false;
}
// 8 8 * 60 * 60 * 1000 ms
if (pd['WORK_LEVEL'] == '特级' || pd['WORK_LEVEL'] == '一级') {
final diffMs = end.difference(start).inMilliseconds;
const max8h = 8 * 60 * 60 * 1000;
if (diffMs >= max8h) {
ToastUtil.showNormal(context, '动火级别为特级或一级时动火作业开始时间与结束时间应不超过8小时请重新选择');
return false;
}
}
// 72 72 * 60 * 60 * 1000 ms
if (pd['WORK_LEVEL'] == '二级') {
final diffMs = end.difference(start).inMilliseconds;
const max72h = 72 * 60 * 60 * 1000;
if (diffMs >= max72h) {
ToastUtil.showNormal(context, '动火级别为二级时动火作业开始时间与结束时间应不超过72小时请重新选择');
return false;
}
}
return true;
}
/// 1 0
Future<void> _submit(String status) async {
//
@ -540,6 +573,9 @@ class _HotworkApplyDetailState extends State<HotworkApplyDetail> {
ToastUtil.showNormal(context, '请选择预计作业结束时间');
return;
}
if (!checkWorkTime(pd, context)) {
return;
}
if (pd['IS_CONTRACTOR_WORK'] == '1' &&
!FormUtils.hasValue(pd, 'UNITS_ID')) {

View File

@ -65,7 +65,7 @@ class _HotworkKszyDetailState extends State<HotworkKszyDetail> {
final intervalMs = workStart.difference(analyzeTime).inMilliseconds;
const thresholdMs = 30 * 60 * 1000;
if (intervalMs >= thresholdMs) {
if (intervalMs.abs() >= thresholdMs) {
ToastUtil.showNormal(context, '气体分析时间与开始时间间隔超过30分钟请重新上传气体检测结果');
return;
}

View File

@ -104,7 +104,6 @@ class _HotworkGasListState extends State<HotworkGasList> {
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('检测值: ${item['GAS_VALUE'] ?? ''}'),
Text('计量单位: ${item['GAS_UNIT'] ?? ''}'),
],
),

View File

@ -202,7 +202,7 @@ class _HotworkYsgdDetailState extends State<HotworkYsgdDetail> {
final intervalMs = endTime.difference(acceptTime).inMilliseconds;
const thresholdMs = 30 * 60 * 1000;
if (intervalMs >= thresholdMs) {
if (intervalMs.abs() >= thresholdMs) {
ToastUtil.showNormal(context, '请在作业结束30分钟内完成验收');
return;
}

View File

@ -191,7 +191,7 @@ class _CutroadDetailFormWidgetState extends State<CutroadDetailFormWidget> {
},
hintText: '请输入关联的其他特殊作业及安全作业票编号',
controller: widget.relatedController,
text: pd['SPECIAL_WORK'] ?? '',
text: pd['SPECIAL_WORK'] ?? '',
),
const Divider(),
if (FormUtils.hasValue(signs, 'PROJECT_MANAGER') &&

View File

@ -201,7 +201,7 @@ class _CutroadYsgdDetailState extends State<CutroadYsgdDetail> {
final intervalMs = endTime.difference(acceptTime).inMilliseconds;
const thresholdMs = 30 * 60 * 1000;
if (intervalMs >= thresholdMs) {
if (intervalMs.abs() >= thresholdMs) {
ToastUtil.showNormal(context, '请在作业结束30分钟内完成验收');
return;
}

View File

@ -161,16 +161,16 @@ class _CutroadZyrDetailState extends State<CutroadZyrDetail> {
confirmText: '确定',
);
//
if (reasonText == null) {
//
return;
}
if (reasonText == null) {
//
return;
}
//
if (reasonText.isEmpty) {
ToastUtil.showNormal(context, '请填写作废原因');
return;
}
//
if (reasonText.isEmpty) {
ToastUtil.showNormal(context, '请填写作废原因');
return;
}
}
final serverPathString = imgList
.map((e) => e.serverPath)

View File

@ -188,7 +188,7 @@ class _BreakgroundDetailFormWidgetState
},
hintText: '请输入关联的其他特殊作业及安全作业票编号',
controller: widget.relatedController,
text: pd['SPECIAL_WORK'] ?? '',
text: pd['SPECIAL_WORK'] ?? '',
),
const Divider(),

View File

@ -202,7 +202,7 @@ class _BreakgroundYsgdDetailState extends State<BreakgroundYsgdDetail> {
final intervalMs = endTime.difference(acceptTime).inMilliseconds;
const thresholdMs = 30 * 60 * 1000;
if (intervalMs >= thresholdMs) {
if (intervalMs.abs() >= thresholdMs) {
ToastUtil.showNormal(context, '请在作业结束30分钟内完成验收');
return;
}

View File

@ -256,7 +256,7 @@ class _HoistworkDetailFormWidgetState extends State<HoistWorkDetailFormWidget> {
},
hintText: '请输入关联的其他特殊作业及安全作业票编号',
controller: widget.relatedController,
text: pd['SPECIAL_WORK'] ?? '',
text: pd['SPECIAL_WORK'] ?? '',
),
const Divider(),
ItemListWidget.twoRowButtonTitleText(

View File

@ -202,7 +202,7 @@ class _HoistworkYsgdDetailState extends State<HoistworkYsgdDetail> {
final intervalMs = endTime.difference(acceptTime).inMilliseconds;
const thresholdMs = 30 * 60 * 1000;
if (intervalMs >= thresholdMs) {
if (intervalMs.abs() >= thresholdMs) {
ToastUtil.showNormal(context, '请在作业结束30分钟内完成验收');
return;
}

View File

@ -236,7 +236,7 @@ class _HighWorkDetailFormWidgetState extends State<HighWorkDetailFormWidget> {
},
hintText: '请输入关联的其他特殊作业及安全作业票编号',
controller: widget.relatedController,
text: pd['SPECIAL_WORK'] ?? '',
text: pd['SPECIAL_WORK'] ?? '',
),
const Divider(),
ItemListWidget.twoRowButtonTitleText(

View File

@ -505,6 +505,9 @@ class _HighworkApplyDetailState extends State<HighworkApplyDetail> {
ToastUtil.showNormal(context, '请选择预计作业结束时间');
return;
}
if (!checkWorkTime(pd, context)) {
return;
}
if (pd['IS_CONTRACTOR_WORK'] == '1' &&
!FormUtils.hasValue(pd, 'UNITS_ID')) {

View File

@ -202,7 +202,7 @@ class _HighworkYsgdDetailState extends State<HighworkYsgdDetail> {
final intervalMs = endTime.difference(acceptTime).inMilliseconds;
const thresholdMs = 30 * 60 * 1000;
if (intervalMs >= thresholdMs) {
if (intervalMs.abs() >= thresholdMs) {
ToastUtil.showNormal(context, '请在作业结束30分钟内完成验收');
return;
}

View File

@ -43,7 +43,6 @@ class _HomeGasTestPageState extends State<HomeGasTestPage> {
{"name": 'UPPER_LIMIT', "message": '请输入量程上限'},
{"name": 'LOWER_LIMIT', "message": '请输入量程下限'},
{"name": 'GAS_UNIT', "message": '请输入计量单位'},
{"name": 'GAS_VALUE', "message": '请输入检测值'},
{"name": 'ANALYZE_TIME', "message": '请输入分析时间'},
{"name": 'ANALYZE_GAS', "message": '请输入代表性气体'},
{"name": 'ANALYZE_RESULT', "message": '请输入分析结果'},
@ -336,19 +335,19 @@ class _HomeGasTestPageState extends State<HomeGasTestPage> {
});
},
),
const Divider(),
ItemListWidget.singleLineTitleText(
label: '检测值:',
isEditable: true,
isNumericInput: true,
hintText: '请输入数字保留两位小数',
text: pd['GAS_VALUE'] ?? '',
onChanged: (v) {
setState(() {
pd['GAS_VALUE'] = v;
});
},
),
// const Divider(),
// ItemListWidget.singleLineTitleText(
// label: '检测值:',
// isEditable: true,
// isNumericInput: true,
// hintText: '请输入数字保留两位小数',
// text: pd['GAS_VALUE'] ?? '',
// onChanged: (v) {
// setState(() {
// pd['GAS_VALUE'] = v;
// });
// },
// ),
const Divider(),
ItemListWidget.singleLineTitleText(
label: '分析结果:',

View File

@ -239,7 +239,7 @@ class _ElectricityDetailFormWidgetState extends State<ElectricityDetailFormWidge
},
hintText: '请输入关联的其他特殊作业及安全作业票编号',
controller: widget.relatedController,
text: pd['SPECIAL_WORK'] ?? '',
text: pd['SPECIAL_WORK'] ?? '',
),
const Divider(),
ItemListWidget.twoRowButtonTitleText(

View File

@ -62,7 +62,12 @@ class _ElectricityJszyDetailState extends State<ElectricityJszyDetail> {
return false;
}
final diffMs = end.difference(start).inMilliseconds;
const max8h = 30 * 24 * 60 * 60 * 1000;
if (diffMs >= max8h) {
ToastUtil.showNormal(context, '临时用电时间一般不超过15天特殊情况不应超过30天请重新选择');
return false;
}
return true;
}

View File

@ -66,7 +66,7 @@ class _ElectricityKszyDetailState extends State<ElectricityKszyDetail> {
final intervalMs = workStart.difference(analyzeTime).inMilliseconds;
const thresholdMs = 30 * 60 * 1000;
if (intervalMs >= thresholdMs) {
if (intervalMs.abs() >= thresholdMs) {
ToastUtil.showNormal(context, '气体分析时间与开始时间间隔超过30分钟请重新上传气体检测结果');
return;
}

View File

@ -28,7 +28,7 @@ enum EditUserType {
ELECTRICITY('用电单位', '用电人', true),//
CONFESS('安全交底人单位', '安全交底人', true),
ACCEPT_CONFESS('接受交底人单位', '接受交底人', true),
WORK('作业人单位', '作业人', true), //
WORK_USER('作业人单位', '作业人', true), //
CONFIRM('作业负责人单位', '作业负责人', true),
AUDIT('用电单位', '用电单位负责人', true),
APPROVE('配送电单位', '配送电单负责人', true),
@ -132,7 +132,7 @@ class _ElectricityApplyDetailState extends State<ElectricityApplyDetail> {
pd['WORK_VOLTAGE'] = _VController.text.trim();
});
_fzCardController.addListener(() {
pd['LEADER_CARD_NO'] = _VController.text.trim();
pd['LEADER_CARD_NO'] = _fzCardController.text.trim();
});
_relatedController.addListener(() {
pd['SPECIAL_WORK'] = _relatedController.text.trim();
@ -255,11 +255,22 @@ class _ElectricityApplyDetailState extends State<ElectricityApplyDetail> {
}
void set_pd_USER_ID(EditUserType type, String id) {
pd['${type.name}_USER_ID'] = id;
if (type == EditUserType.WORK_USER) {
pd['${type.name}_ID'] = id;
}else{
pd['${type.name}_USER_ID'] = id;
}
}
void set_pd_USER_Name(EditUserType type, String name) {
pd['${type.name}_USER_NAME'] = name;
if (type == EditUserType.WORK_USER) {
pd['${type.name}_NAME'] = name;
}else{
pd['${type.name}_USER_NAME'] = name;
}
}
String get_pd_DEPARTMENT_ID(EditUserType type) {
@ -268,17 +279,24 @@ class _ElectricityApplyDetailState extends State<ElectricityApplyDetail> {
String get_pd_DEPARTMENT_NAME(EditUserType type) {
return pd['${type.name}_DEPARTMENT_NAME'] ?? '';
}
String get_pd_USER_ID(EditUserType type) {
return pd['${type.name}_USER_ID'] ?? '';
if (type == EditUserType.WORK_USER) {
return pd['${type.name}_ID'] ?? '';
} else {
return pd['${type.name}_USER_ID'] ?? '';
}
}
String get_pd_USER_Name(EditUserType type) {
if (type == EditUserType.WORK) {
return pd['${type.name}_USER_USER_NAME'] ?? '';
if (type == EditUserType.WORK_USER) {
return pd['${type.name}_NAME'] ?? '';
}else{
return pd['${type.name}_USER_NAME'] ?? '';
}
return pd['${type.name}_USER_NAME'] ?? '';
}
@ -323,7 +341,7 @@ class _ElectricityApplyDetailState extends State<ElectricityApplyDetail> {
isRequired: isRequired,
label: type.personName,
isEditable: isEditable,
text: pd['${type.name}_USER_NAME'] ?? '请选择',
text: type == EditUserType.WORK_USER ? (pd['${type.name}_NAME'] ??'') : (pd['${type.name}_USER_NAME']??'') ?? '请选择',
onTap: () => choosePersonHandle(type),
),
if (type == EditUserType.CONFIRM)
@ -422,7 +440,25 @@ class _ElectricityApplyDetailState extends State<ElectricityApplyDetail> {
//FocusHelper.clearFocus(context);
});
}
bool checkWorkTime(Map<String, dynamic> pd, BuildContext context) {
//
final start = DateTime.parse(pd['WORK_EXPECTED_START_TIME'] as String);
final end = DateTime.parse(pd['WORK_EXPECTED_END_TIME'] as String);
//
if (end.isAtSameMomentAs(start) || end.isBefore(start)) {
ToastUtil.showNormal(context, '作业开始时间不能晚于或等于结束时间,请重新选择');
return false;
}
final diffMs = end.difference(start).inMilliseconds;
const max8h = 30 * 24 * 60 * 60 * 1000;
if (diffMs >= max8h) {
ToastUtil.showNormal(context, '临时用电时间一般不超过15天特殊情况不应超过30天请重新选择');
return false;
}
return true;
}
/// 1 0
Future<void> _submit(String status) async {
//
@ -457,7 +493,7 @@ class _ElectricityApplyDetailState extends State<ElectricityApplyDetail> {
EditUserType.ELECTRICITY,
EditUserType.CONFESS,
EditUserType.ACCEPT_CONFESS,
EditUserType.WORK,
EditUserType.WORK_USER,
EditUserType.CONFIRM,
EditUserType.AUDIT,
EditUserType.APPROVE,
@ -542,7 +578,7 @@ class _ElectricityApplyDetailState extends State<ElectricityApplyDetail> {
ToastUtil.showSuccess(context, status == '1' ? '提交成功' : '操作成功');
Navigator.of(context).pop(true);
} else {
ToastUtil.showSuccess(context, '提交失败');
ToastUtil.showError(context, '提交失败');
}
} catch (e) {
LoadingDialogHelper.hide();
@ -559,6 +595,9 @@ class _ElectricityApplyDetailState extends State<ElectricityApplyDetail> {
);
setState(() {
pd = data['pd'];
if (FormUtils.hasValue(pd, 'ANALYZE_DEPARTMENT_ID')) {
_isGasAnalyze = true;
}
if (pd['STEP_ID'] == 0) {
isEditable = true;
} else {
@ -568,12 +607,14 @@ class _ElectricityApplyDetailState extends State<ElectricityApplyDetail> {
//
_contentController.text = pd['WORK_CONTENT'] ?? '';
_locationController.text = pd['WORK_PLACE'] ?? '';
_cardController.text = pd['WORK_FUNCTION'] ?? '';
_powerController.text = pd['WORK_USER'] ?? '';
_ratedPowerController.text = pd['SPECIAL_WORK'] ?? '';
_cardController.text = pd['CARD_NO'] ?? '';
_powerController.text = pd["ALLOW_POWER"] ?? '';
_ratedPowerController.text = pd['RATED_POWER'] ?? '';
_VController.text = pd['WORK_VOLTAGE'] ?? '';
_relatedController.text = pd['SPECIAL_WORK'] ?? '';
_riskController.text = pd['RISK_IDENTIFICATION'] ?? '';
_fzCardController.text = pd["LEADER_CARD_NO"] ?? '';
});
// final data = await ApiService.getHomeworkFindById('electricity', widget.ELECTRICITY_ID);
// setState(() {
@ -674,7 +715,7 @@ class _ElectricityApplyDetailState extends State<ElectricityApplyDetail> {
SizedBox(height: 15),
_card(_chooseItem(EditUserType.ACCEPT_CONFESS)),
SizedBox(height: 15),
_card(_chooseItem(EditUserType.WORK)),
_card(_chooseItem(EditUserType.WORK_USER)),
SizedBox(height: 15),
_card(_chooseItem(EditUserType.CONFIRM)),
SizedBox(height: 15),

View File

@ -96,7 +96,6 @@ class _ElectricityGasListState extends State<ElectricityGasList> {
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('检测值: ${item['GAS_VALUE'] ?? ''}'),
Text('计量单位: ${item['GAS_UNIT'] ?? ''}'),
],
),

View File

@ -48,7 +48,6 @@ class _ElectricityGasTestPageState extends State<ElectricityGasTestPage> {
{'name': 'UPPER_LIMIT', 'message': '请输入量程上限'},
{'name': 'LOWER_LIMIT', 'message': '请输入量程下限'},
{'name': 'GAS_UNIT', 'message': '请输入计量单位'},
{'name': 'GAS_VALUE', 'message': '请输入检测值'},
{'name': 'ANALYZE_TIME', 'message': '请输入分析时间'},
{'name': 'ANALYZE_PLACE', 'message': '请输入分析点'},
{'name': 'ANALYZE_RESULT', 'message': '请输入分析结果'},
@ -338,19 +337,7 @@ if (reasonText.isEmpty) {
});
},
),
const Divider(),
ItemListWidget.singleLineTitleText(
label: '检测值:',
isEditable: true,
isNumericInput: true,
hintText: '请输入检测值,数字保留两位小数',
text: pd['GAS_VALUE'] ?? '',
onChanged: (v) {
setState(() {
pd['GAS_VALUE'] = v;
});
},
),
const Divider(),
ItemListWidget.singleLineTitleText(
label: '分析点:',

View File

@ -202,7 +202,7 @@ class _ElectricityYsgdDetailState extends State<ElectricityYsgdDetail> {
final intervalMs = endTime.difference(acceptTime).inMilliseconds;
const thresholdMs = 30 * 60 * 1000;
if (intervalMs >= thresholdMs) {
if (intervalMs.abs() >= thresholdMs) {
ToastUtil.showNormal(context, '请在作业结束30分钟内完成验收');
return;
}

View File

@ -637,7 +637,7 @@ class _BlindboardDetailFormWidgetState
},
hintText: '请输入关联的其他特殊作业及安全作业票编号',
controller: widget.relatedController,
text: pd['SPECIAL_WORK'] ?? '',
text: pd['SPECIAL_WORK'] ?? '',
),
const Divider(),
ItemListWidget.twoRowButtonTitleText(

View File

@ -249,7 +249,7 @@ class _SpaceWorkDetailFormWidgetState extends State<SpaceWorkDetailFormWidget> {
},
hintText: '请输入关联的其他特殊作业及安全作业票编号',
controller: widget.relatedController,
text: pd['SPECIAL_WORK'] ?? '',
text: pd['SPECIAL_WORK'] ?? '',
),
const Divider(),
ItemListWidget.twoRowButtonTitleText(

View File

@ -62,7 +62,12 @@ class _SpaceworkJszyDetailState extends State<SpaceworkJszyDetail> {
return false;
}
final diffMs = end.difference(start).inMilliseconds;
const max8h = 24 * 60 * 60 * 1000;
if (diffMs >= max8h) {
ToastUtil.showNormal(context, '作业开始时间与结束时间应不超过24小时请重新选择');
return false;
}
return true;
}

View File

@ -68,7 +68,7 @@ class _SpaceworkKszyDetailState extends State<SpaceworkKszyDetail> {
final intervalMs = workStart.difference(analyzeTime).inMilliseconds;
const thresholdMs = 30 * 60 * 1000;
if (intervalMs >= thresholdMs) {
if (intervalMs.abs() >= thresholdMs) {
ToastUtil.showNormal(context, '气体分析时间与开始时间间隔超过30分钟请重新上传气体检测结果');
return;
}

View File

@ -121,8 +121,6 @@ class _SpaceworkGasListState extends State<SpaceworkGasList> {
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('含氧量: ${item['OXYGEN_CONTENT'] ?? ''}'),
if ((item['ANALYZE_PLACE'] ?? '').toString().isNotEmpty)
Text('分析地点: ${item['ANALYZE_PLACE']}'),
],
),
const SizedBox(height: 6),

View File

@ -36,8 +36,6 @@ class _SpaceworkGasTestPageState extends State<SpaceworkGasTestPage> {
Map<String, dynamic> pd = {};
final TextEditingController _PartController = TextEditingController(); //
final TextEditingController _O2Controller = TextEditingController(); //
final TextEditingController _addressController =
TextEditingController(); //
List<Map<String, dynamic>> RESULTS_UNIT_LIST = [
{"NAME": "%", "VALUE": "1"},
@ -48,7 +46,6 @@ class _SpaceworkGasTestPageState extends State<SpaceworkGasTestPage> {
{'name': 'ANALYZE_TIME', 'message': '请输入取样分析时间'},
{'name': 'ANALYZE_PART', 'message': '请输入分析部位'},
{'name': 'OXYGEN_CONTENT', 'message': '请输入氧气含量'},
{'name': 'ANALYZE_PLACE', 'message': '请输入分析地点'},
];
bool _loading = false;
@ -57,7 +54,6 @@ class _SpaceworkGasTestPageState extends State<SpaceworkGasTestPage> {
pd['ANALYZE_USER'] = SessionService.instance.username;
pd['CONFINEDSPACE_ID'] = widget.CONFINEDSPACE_ID;
super.initState();
}
Future<void> _chooseDatePicker() async {
@ -69,6 +65,7 @@ class _SpaceworkGasTestPageState extends State<SpaceworkGasTestPage> {
});
}
}
List<Map<String, dynamic>> _gas_new_rules(String type) {
String name = widget.saveParams['GAS_NAME$type'];
return [
@ -79,7 +76,6 @@ class _SpaceworkGasTestPageState extends State<SpaceworkGasTestPage> {
];
}
Future<void> _sign() async {
await NativeOrientation.setLandscape();
final path = await Navigator.push(
@ -164,9 +160,7 @@ class _SpaceworkGasTestPageState extends State<SpaceworkGasTestPage> {
ToastUtil.showNormal(context, '请选择取样分析时间');
return;
}
if (_PartController.text.isEmpty ||
_O2Controller.text.isEmpty ||
_addressController.text.isEmpty) {
if (_PartController.text.isEmpty || _O2Controller.text.isEmpty) {
ToastUtil.showNormal(context, '请完善所有字段');
return;
}
@ -174,7 +168,6 @@ class _SpaceworkGasTestPageState extends State<SpaceworkGasTestPage> {
...pd,
'ANALYZE_PART': _PartController.text,
'OXYGEN_CONTENT': _O2Controller.text,
'ANALYZE_PLACE': _addressController.text,
};
bool required = true;
List<Map<String, dynamic>> rule = [];
@ -207,7 +200,6 @@ class _SpaceworkGasTestPageState extends State<SpaceworkGasTestPage> {
}
}
String? reasonText = '';
if (status != 1) {
reasonText = await CustomAlertDialog.showInput(
@ -218,16 +210,16 @@ class _SpaceworkGasTestPageState extends State<SpaceworkGasTestPage> {
confirmText: '确定',
);
//
if (reasonText == null) {
//
return;
}
if (reasonText == null) {
//
return;
}
//
if (reasonText.isEmpty) {
ToastUtil.showNormal(context, '请填写作废原因');
return;
}
//
if (reasonText.isEmpty) {
ToastUtil.showNormal(context, '请填写作废原因');
return;
}
}
setState(() => _loading = true);
@ -236,7 +228,6 @@ if (reasonText.isEmpty) {
...pd,
'ANALYZE_PART': _PartController.text,
'OXYGEN_CONTENT': _O2Controller.text,
'ANALYZE_PLACE': _addressController.text,
'APPLY_STATUS': status,
'STEP_REASON': reasonText ?? '',
'SIGNTIME': signTimes.join(','),
@ -309,7 +300,7 @@ if (reasonText.isEmpty) {
},
),
const SizedBox(height: 2,),
const SizedBox(height: 2),
ItemListWidget.selectableLineTitleTextRightButton(
label: '计量单位',
isEditable: true,
@ -319,7 +310,6 @@ if (reasonText.isEmpty) {
},
),
const Divider(),
],
);
}
@ -358,11 +348,11 @@ if (reasonText.isEmpty) {
isNumericInput: true,
isRequired: true,
strongRequired: false,
onChanged: (v) {
setState(() {
pd['DATA1'] = v;
});
}
onChanged: (v) {
setState(() {
pd['DATA1'] = v;
});
},
),
_gas_new_widget('1'),
],
@ -380,11 +370,11 @@ if (reasonText.isEmpty) {
isNumericInput: true,
isRequired: true,
strongRequired: false,
onChanged: (v) {
setState(() {
pd['DATA2'] = v;
});
}
onChanged: (v) {
setState(() {
pd['DATA2'] = v;
});
},
),
_gas_new_widget('2'),
],
@ -402,11 +392,11 @@ if (reasonText.isEmpty) {
isNumericInput: true,
isRequired: true,
strongRequired: false,
onChanged: (v) {
setState(() {
pd['DATA3'] = v;
});
}
onChanged: (v) {
setState(() {
pd['DATA3'] = v;
});
},
),
_gas_new_widget('3'),
],
@ -428,7 +418,7 @@ if (reasonText.isEmpty) {
setState(() {
pd['DATA4'] = v;
});
}
},
),
_gas_new_widget('4'),
],
@ -455,14 +445,6 @@ if (reasonText.isEmpty) {
isEditable: true,
controller: _O2Controller,
),
const Divider(),
ItemListWidget.singleLineTitleText(
label: '分析地点:',
hintText: '请输入分析地点',
isEditable: true,
controller: _addressController,
),
const Divider(),
ItemListWidget.singleLineTitleText(
label: '分析人:',

View File

@ -430,7 +430,25 @@ class _SpaceworkApplyDetailState extends State<SpaceworkApplyDetail> {
//FocusHelper.clearFocus(context);
});
}
bool checkWorkTime(Map<String, dynamic> pd, BuildContext context) {
//
final start = DateTime.parse(pd['WORK_EXPECTED_START_TIME'] as String);
final end = DateTime.parse(pd['WORK_EXPECTED_END_TIME'] as String);
//
if (end.isAtSameMomentAs(start) || end.isBefore(start)) {
ToastUtil.showNormal(context, '作业开始时间不能晚于或等于结束时间,请重新选择');
return false;
}
final diffMs = end.difference(start).inMilliseconds;
const max8h = 24 * 60 * 60 * 1000;
if (diffMs >= max8h) {
ToastUtil.showNormal(context, '作业开始时间与结束时间应不超过24小时请重新选择');
return false;
}
return true;
}
/// 1 0
Future<void> _submit(String status) async {
//
@ -475,7 +493,9 @@ class _SpaceworkApplyDetailState extends State<SpaceworkApplyDetail> {
ToastUtil.showNormal(context, '请选择预计作业结束时间');
return;
}
if (!checkWorkTime(pd, context)) {
return;
}
if (pd['IS_CONTRACTOR_WORK'] == '1' &&
!FormUtils.hasValue(pd, 'UNITS_ID')) {
ToastUtil.showNormal(context, '请选择承包商');

View File

@ -203,7 +203,7 @@ class _SpaceworkYsgdDetailState extends State<SpaceworkYsgdDetail> {
final intervalMs = endTime.difference(acceptTime).inMilliseconds;
const thresholdMs = 30 * 60 * 1000;
if (intervalMs >= thresholdMs) {
if (intervalMs.abs() >= thresholdMs) {
ToastUtil.showNormal(context, '请在作业结束30分钟内完成验收');
return;
}

View File

@ -1,3 +1,5 @@
import 'dart:io';
import 'package:qhd_prevention/customWidget/custom_alert_dialog.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
@ -113,8 +115,12 @@ class _LoginPageState extends State<LoginPage> {
confirmText: '立即更新'
);
if (ok) {
final apkUrl = pd['FILEURL'] ?? '';
await showUpdateConfirm(context, apkUrl: apkUrl);
if (Platform.isIOS) {
openAppStore();
}else{
final apkUrl = pd['FILEURL'] ?? '';
await showUpdateConfirm(context, apkUrl: apkUrl);
}
}
return;
}
@ -428,10 +434,10 @@ class _LoginPageState extends State<LoginPage> {
}
if (data['result'] == 'success') {
if(data['WEAK_PASSWORD']=='1'){
if(FormUtils.hasValue(data, 'WEAK_PASSWORD') && data['WEAK_PASSWORD'] == '1'){
pushPage(const MineSetPwdPage("1"), context);
}else if(data['LONG_TERM_PASSWORD_NOT_CHANGED']=='1'){
}else if(FormUtils.hasValue(data, 'LONG_TERM_PASSWORD_NOT_CHANGED') && data['LONG_TERM_PASSWORD_NOT_CHANGED']=='1'){
pushPage(const MineSetPwdPage("2"), context);
}else{

View File

@ -21,9 +21,10 @@ class _MineAboutPageState extends State<MineAboutPage> {
}
Future<void> _loadAppVersion() async {
final versionInfo = await getAppVersion();
setState(() {
appVersion = versionInfo.fullVersion;
appVersion = versionInfo.versionName;
});
}

View File

@ -40,7 +40,7 @@ class _MineDutyApplicationPage extends State<MineDutyApplicationPage> {
widget.onClose('关闭提交'); //
Navigator.pop(context); //
}else{
ToastUtil.showSuccess(context, '提交失败');
ToastUtil.showError(context, '提交失败');
}
} catch (e) {
print('加载出错: $e');

View File

@ -1,3 +1,5 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:qhd_prevention/customWidget/custom_alert_dialog.dart';
import 'package:qhd_prevention/customWidget/toast_util.dart';
@ -41,10 +43,16 @@ class _MineSetPageState extends State<MineSetPage> {
confirmText: '立即更新'
);
if (ok) {
final apkUrl = pd['FILEURL'] ?? '';
await showUpdateConfirm(context, apkUrl: apkUrl);
if (Platform.isIOS) {
openAppStore();
}else{
final apkUrl = pd['FILEURL'] ?? '';
await showUpdateConfirm(context, apkUrl: apkUrl);
}
}
return;
}else{
_loadAppVersion();
}
}else{
@ -54,7 +62,7 @@ class _MineSetPageState extends State<MineSetPage> {
}
Future<void> _loadAppVersion() async {
final versionInfo = await getAppVersion();
ToastUtil.showNormal(context, '已经是最新版本!当前版本号:${versionInfo.fullVersion}');
ToastUtil.showNormal(context, '已经是最新版本!当前版本号:${versionInfo.versionName}');
}

View File

@ -48,12 +48,12 @@ class AuthService {
await prefs.setBool(_keyIsLoggedIn, true);
SessionService.instance
..setLoginUserId(data['USER_ID'] as String)
..setCorpinfoId(data['CORPINFO_ID'] as String)
..setDeptId(data['DEPARTMENT_ID'] as String)
..setDeptLevel(data['DEPARTMENT_LEVEL'] as String)
..setIsRest(data['ISREST'] as String)
..setUsername(data['NAME'] as String)
..setLoginUserId(data['USER_ID'] ?? '' )
..setCorpinfoId(data['CORPINFO_ID'] ?? '' )
..setDeptId(data['DEPARTMENT_ID'] ?? '' )
..setDeptLevel(data['DEPARTMENT_LEVEL'] ?? '' )
..setIsRest(data['ISREST'] ?? '' )
..setUsername(data['NAME'] ?? '' )
..setLoginUser(data);
return data;

View File

@ -8,6 +8,7 @@ import 'dart:io';
import 'package:image_picker/image_picker.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:url_launcher/url_launcher.dart';
int getRandomWithNum(int min, int max) {
if (max < min) {
@ -611,4 +612,23 @@ Future<bool> checkNetworkWifi() async {
}
return false;
}
Future<void> openAppStore() async {
String appId = '6739233192';
// 使 itms-apps App Store iOS
final Uri uri = Uri.parse('itms-apps://itunes.apple.com/app/id$appId');
//
// final Uri uri = Uri.parse('itms-apps://itunes.apple.com/app/id$appId?action=write-review');
if (await canLaunchUrl(uri)) {
await launchUrl(uri, mode: LaunchMode.externalApplication);
} else {
// 退 https App Store
final Uri webUri = Uri.parse('https://itunes.apple.com/app/id$appId');
if (await canLaunchUrl(webUri)) {
await launchUrl(webUri, mode: LaunchMode.externalApplication);
} else {
throw 'Could not launch App Store for app id $appId';
}
}
}

View File

@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
# In Windows, build-name is used as the major, minor, and patch parts
# of the product and file versions while build-number is used as the build suffix.
version: 2.1.2+59
version: 2.2.0+59
environment:
sdk: ^3.7.0