flutter_integrated_whb/lib/pages/home/SafetyCommitment/other_promise_page.dart

356 lines
12 KiB
Dart
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:qhd_prevention/customWidget/custom_button.dart';
import 'package:qhd_prevention/customWidget/single_image_viewer.dart';
import 'package:qhd_prevention/pages/main_tab.dart';
import 'package:qhd_prevention/pages/mine/mine_sign_page.dart';
import 'package:qhd_prevention/pages/my_appbar.dart';
import 'package:qhd_prevention/customWidget/toast_util.dart';
import 'package:qhd_prevention/http/ApiService.dart';
import 'package:qhd_prevention/tools/tools.dart';
/// 完整翻译自你提供的 uniapp 页面逻辑。
/// 注意:下面的 ApiService 方法名goEditII / editIsReadII / submitCorppromiseSign
/// 仅为示例占位,与你项目中实际的方法名若不同请替换。
class OtherPromisePage extends StatefulWidget {
const OtherPromisePage({
super.key,
required this.TabCur,
required this.PROMISE_ID,
required this.PROMISEPEOPLE_ID,
});
final int TabCur;
final String PROMISE_ID;
final String PROMISEPEOPLE_ID;
@override
State<OtherPromisePage> createState() => _OtherPromisePageState();
}
class _OtherPromisePageState extends State<OtherPromisePage> {
bool _loading = true;
Map<String, dynamic> info = {};
String? baseImgPath = ApiService.baseImgPath;
@override
void initState() {
super.initState();
// 按照原 uniapp 的 onLoad先获取数据
_loadData();
// 如果来自 TabCur == 1需要标记为已读uniapp 中是if(option.TabCur=='1') this.setPromiseIsRead
if (widget.TabCur == 1) {
_setPromiseIsRead();
}
}
Future<void> _loadData() async {
setState(() => _loading = true);
try {
// 请将下面的方法替换为你项目中实际的 ApiService 调用并传入 widget.PROMISE_ID / PROMISEPEOPLE_ID
final res = await ApiService.getWorkshopSafetyOtherCommitmen(
widget.PROMISE_ID,
widget.PROMISEPEOPLE_ID,
);
final coll = (res['promistDetail'] as List?) ?? (res['promistdetail'] as List?) ?? [];
final DETAIL = coll
.map((e) => {
'value': e?['COLLATERAL']?.toString() ?? e?['collateral']?.toString() ?? '',
'id': e?['PROMISEDETAIL_ID']?.toString() ?? e?['promiseDetail_id']?.toString() ?? '',
})
.toList();
final Map<String, dynamic> merged = {};
if (res['varList'] is Map) merged.addAll(Map<String, dynamic>.from(res['varList']));
if (res['people'] is Map) merged.addAll(Map<String, dynamic>.from(res['people']));
merged['TEXT'] = res['TEXT']?.toString() ?? res['text']?.toString() ?? merged['TEXT'] ?? '';
merged['DETAIL'] = DETAIL;
if (res['coverpeople'] is List && (res['coverpeople'] as List).isNotEmpty) {
merged['COVERPEOPLE'] = (res['coverpeople'][0]['USERNAME'] ?? res['coverpeople'][0]['username'])?.toString() ?? '';
} else if (res['coverpeople'] is String) {
merged['COVERPEOPLE'] = res['coverpeople'];
}
res.forEach((k, v) {
if (!merged.containsKey(k)) merged[k] = v;
});
merged['PROMISEPEOPLE_ID'] = res['PROMISEPEOPLE_ID'] ?? widget.PROMISEPEOPLE_ID;
merged['SIGNTIME'] = merged['SIGNTIME'] ?? merged['signtime'] ?? '';
merged['CREATTIME'] = merged['CREATTIME'] ?? merged['creattime'] ?? merged['CREATTIME'] ?? '';
setState(() {
info = merged;
_loading = false;
});
} catch (e, st) {
debugPrint('加载承诺详情失败:$e\n$st');
setState(() => _loading = false);
ToastUtil.showNormal(context, '加载失败,请稍后重试');
}
}
Future<void> _setPromiseIsRead() async {
try {
await ApiService.getWorkshopSafetyOthercorppromise(widget.PROMISEPEOPLE_ID);
} catch (e) {
debugPrint('标记已读失败: $e');
// 不打断用户流程uniapp 中也是静默处理失败
}
}
String _formatDateShort(dynamic s) {
if (s == null) return '';
final str = s.toString();
if (str.length >= 10) return str.substring(0, 10);
return str;
}
Future<void> _sign() async {
// 如果你的签字页面需要横屏,请在 MineSignPage 内或调用签字前后处理屏幕方向。
// 下面直接跳转并等待返回签名图片路径String与原 uniapp 的行为一致。
final result = await Navigator.push<String>(
context,
MaterialPageRoute(builder: (_) => const MineSignPage()),
);
if (result != null && result.isNotEmpty) {
setState(() {
info['FILEPATH'] = result;
});
// 清除焦点,防止键盘/输入问题
FocusScope.of(context).unfocus();
}
}
Future<void> submitSignedPromise() async {
final filePath = (info['FILEPATH'] ?? '').toString();
if (filePath.isEmpty) {
ToastUtil.showNormal(context, '请签字');
return;
}
try {
LoadingDialogHelper.show();
// 请替换为你项目的实际提交方法和参数;下面示例使用 submitCorppromiseSign(filePath, info)
final res = await ApiService.submitCorppromiseSign(filePath, info);
LoadingDialogHelper.hide();
if (res is Map && (res['result'] == 'success' || res['code'] == 0 || res['status'] == 'success')) {
ToastUtil.showSuccess(context, '提交成功');
// 和 uniapp 行为类似:提交后导航回主页面
Navigator.pushReplacement(context, MaterialPageRoute(builder: (_) => const MainPage()));
} else {
final msg = (res is Map) ? (res['message'] ?? res['msg'] ?? '提交失败') : '提交失败';
ToastUtil.showNormal(context, msg.toString());
}
} catch (e, st) {
LoadingDialogHelper.hide();
debugPrint('提交签字失败:$e\n$st');
ToastUtil.showNormal(context, '提交失败,请重试');
}
}
Widget _buildTitle() {
final type = (info['TYPE'] ?? '').toString();
final title = type == '0' ? '安全生产承诺书' : '安全生产责任状';
return Padding(
padding: const EdgeInsets.symmetric(vertical: 12.0),
child: Text(
title,
style: const TextStyle(fontSize: 22, fontWeight: FontWeight.bold),
textAlign: TextAlign.center,
),
);
}
Widget _buildHeaderName() {
final type = (info['TYPE'] ?? '').toString();
if (type == '0') {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: Text(
'${info['COVERPEOPLE'] ?? ''}',
style: const TextStyle(fontSize: 16),
),
);
}
return const SizedBox.shrink();
}
Widget _buildParagraph(String text) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 8.0),
child: RichText(
textAlign: TextAlign.justify,
text: TextSpan(
style: const TextStyle(
height: 1.6,
letterSpacing: 0.5,
color: Colors.black,
),
children: [
const WidgetSpan(child: SizedBox(width: 28)),
TextSpan(text: text),
],
),
),
);
}
Widget _buildCollateralList() {
final detail = (info['DETAIL'] as List?) ?? [];
if (detail.isEmpty) return const SizedBox.shrink();
return Padding(
padding: const EdgeInsets.only(left: 0, right: 8.0, top: 6.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: detail.map<Widget>((e) {
return _buildParagraph(e['value']?.toString() ?? '');
}).toList(),
),
);
}
Widget _buildFooter() {
final type = (info['TYPE'] ?? '').toString();
final signImagePath = (info['FILEPATH'] ?? '').toString();
final signTime = (info['SIGNTIME'] ?? '').toString();
final creatTime = (info['CREATTIME'] ?? '').toString();
Widget signPreview;
if (signImagePath.isNotEmpty && (signImagePath.startsWith('http') || signImagePath.startsWith('https'))) {
signPreview = Image.network(
signImagePath,
width: 100,
height: 50,
fit: BoxFit.cover,
);
} else if (signImagePath.isNotEmpty && File(signImagePath).existsSync()) {
signPreview = Image.file(
File(signImagePath),
width: 100,
height: 50,
fit: BoxFit.cover,
);
} else if (signImagePath.isNotEmpty && baseImgPath != null) {
// 如果后端只给了相对路径,前端需要拼接 baseImgPath
signPreview = Image.network(
'${baseImgPath!}$signImagePath',
width: 100,
height: 50,
fit: BoxFit.cover,
);
} else {
signPreview = const SizedBox(width: 100, height: 50);
}
return Padding(
padding: const EdgeInsets.only(top: 12.0, left: 8.0, right: 8.0, bottom: 20.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
if (type == '0')
const Align(alignment: Alignment.centerRight, child: Text('承诺单位(盖章)')),
if (type == '1')
Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text('发状人:${info['COVERPEOPLE'] ?? ''}'),
const SizedBox(height: 6),
Text(creatTime.isNotEmpty ? _formatDateShort(creatTime) : ''),
],
),
const SizedBox(height: 12),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Row(
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisAlignment: MainAxisAlignment.end,
children: [
Text(type == '0' ? '主要负责人签字:' : '受状人:'),
const SizedBox(width: 8),
GestureDetector(
onTap: () {
if ((info['FILEPATH'] ?? '').toString().isNotEmpty) {
presentOpaque(
SingleImageViewer(imageUrl: info['FILEPATH'] ?? ''),
context,
);
}
},
child: signPreview,
),
],
),
),
],
),
const SizedBox(height: 10),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const SizedBox(),
Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [Text(signTime.isNotEmpty ? _formatDateShort(signTime) : '')],
),
],
),
],
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: const MyAppbar(title: '安全承诺'),
body: _loading
? const Center(child: CircularProgressIndicator())
: SingleChildScrollView(
child: Container(
color: Colors.white,
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 5),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Center(child: _buildTitle()),
_buildHeaderName(),
_buildParagraph(info['TEXT']?.toString() ?? ''),
_buildCollateralList(),
if ((info['TYPE'] ?? '').toString() == '0') ...[
_buildParagraph(
'若违反上述承诺和未履行安全生产职责,或发生责任事故的,接受政府或公司事故调查组做出的处罚决定。',
),
_buildParagraph(
'承诺期限自${_formatDateShort(info['PROMISE_TERM_START'])}${_formatDateShort(info['PROMISE_TERM_END'])}',
),
] else ...[
_buildParagraph(
'若未履行安全生产职责,或发生生产安全事故的,接受公司或政府事故调查组做出的处罚。',
),
_buildParagraph(
'责任期限自${_formatDateShort(info['PROMISE_TERM_START'])}${_formatDateShort(info['PROMISE_TERM_END'])}',
),
],
const SizedBox(height: 8),
_buildFooter(),
],
),
),
),
);
}
}