flutter_integrated_whb/lib/customWidget/promise/promise_page.dart

351 lines
11 KiB
Dart
Raw Normal View History

import 'dart:convert';
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';
class PromisePage extends StatefulWidget {
const PromisePage({super.key});
@override
State<PromisePage> createState() => _PromisePageState();
}
class _PromisePageState extends State<PromisePage> {
bool _loading = true;
Map<String, dynamic> info = {};
String? baseImgPath;
@override
void initState() {
super.initState();
_loadData();
}
Future<void> _loadData() async {
setState(() {
_loading = true;
});
try {
final Map<String, dynamic> payload =
await ApiService.safeCorppromiseDetail();
final coll = (payload['COLLATERAL'] as List?) ?? [];
final DETAIL =
coll.map((e) {
return {
'value': e?['COLLATERAL']?.toString() ?? '',
'id': e?['PROMISEDETAIL_ID']?.toString() ?? '',
};
}).toList();
final Map<String, dynamic> resolved = {};
if (payload['TEXT'] is Map) {
resolved.addAll(payload['TEXT'] as Map<String, dynamic>);
} else {
resolved['TEXT'] = payload['TEXT']?.toString() ?? '';
}
resolved['DETAIL'] = DETAIL;
resolved['SIGNTIME'] =
DateTime.now().millisecondsSinceEpoch.toString();
resolved['COVERPEOPLE'] =
(payload['COVERPEOPLE'] is List && payload['COVERPEOPLE'].isNotEmpty)
? payload['COVERPEOPLE'][0]['USERNAME']?.toString() ?? ''
: '';
// 合并其他顶层字段(保留现有字段)
if (payload is Map<String, dynamic>) {
payload.forEach((k, v) {
if (!resolved.containsKey(k)) resolved[k] = v;
});
}
resolved['PROMISEPEOPLE_ID'] = payload['PROMISEPEOPLE_ID'] ?? '';
setState(() {
info = resolved;
_loading = false;
});
} catch (e, st) {
debugPrint('safeCorppromiseDetail error: $e\n$st');
setState(() {
_loading = false;
});
ToastUtil.showNormal(context, '加载失败,请稍后重试');
}
}
String _formatDateShort(String? s) {
if (s == null) return '';
if (s.length >= 10) return s.substring(0, 10);
return s;
}
// 点击签字导航到你自己实现的签字页面等待返回签字路径String
Future<void> _sign() async {
await NativeOrientation.setLandscape();
final String path = await Navigator.push(
context,
MaterialPageRoute(builder: (c) => MineSignPage()),
);
2025-08-29 11:05:17 +08:00
await NativeOrientation.setPortrait();
if (path != null) {
setState(() {
info['FILEPATH'] = path;
});
FocusHelper.clearFocus(context);
}
}
// 提交:占位实现 —— 请把下面的逻辑替换为你项目的上传/提交 API例如 ApiService.editPeopleII 或类似)
Future<void> submitSignedPromise() async {
LoadingDialogHelper.show();
final filePath = (info['FILEPATH'] ?? '').toString();
if (filePath.isEmpty) {
ToastUtil.showNormal(context, '请签字');
return;
}
final result = await ApiService.submitCorppromiseSign(filePath,info);
LoadingDialogHelper.hide();
if (result['result'] == 'success') {
ToastUtil.showSuccess(context, '提交成功');
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (_) => const MainPage()),
);
}
}
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), // 缩进2个汉字宽度
),
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((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')) {
signPreview = Image.network(
(baseImgPath ?? '') + signImagePath,
width: 100,
height: 50,
2025-08-29 11:05:17 +08:00
fit: BoxFit.fill,
);
} else if (signImagePath.isNotEmpty && File(signImagePath).existsSync()) {
signPreview = Image.file(
File(signImagePath),
width: 100,
height: 50,
2025-08-29 11:05:17 +08:00
fit: BoxFit.fill,
);
} else {
signPreview = const SizedBox.shrink();
}
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(height: 8),
GestureDetector(
onTap: () {
presentOpaque(
SingleImageViewer(imageUrl: info['FILEPATH'] ?? ''),
context,
);
},
child: signPreview,
),
const SizedBox(height: 8),
CustomButton(
text:
(info['FILEPATH'] ?? '').toString().isNotEmpty
? '重签'
: '手写签字',
backgroundColor: Colors.blue,
padding: EdgeInsets.symmetric(
vertical: 0,
horizontal: 20,
),
height: 35,
onPressed: _sign,
),
],
),
),
],
),
const SizedBox(height: 10),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const SizedBox(),
Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [Text(signTime)],
),
],
),
],
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: const MyAppbar(title: '安全承诺', isBack: false),
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: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [_buildTitle()],
),
_buildHeaderName(),
_buildParagraph(info['TEXT']?.toString() ?? ''),
_buildCollateralList(),
if ((info['TYPE'] ?? '').toString() == '0') ...[
_buildParagraph(
'若违反上述承诺和未履行安全生产职责,或发生责任事故的,接受政府或公司事故调查组做出的处罚决定。',
),
_buildParagraph(
'承诺期限自${_formatDateShort(info['PROMISE_TERM_START']?.toString())}${_formatDateShort(info['PROMISE_TERM_END']?.toString())}',
),
] else ...[
_buildParagraph(
'若未履行安全生产职责,或发生生产安全事故的,接受公司或政府事故调查组做出的处罚。',
),
_buildParagraph(
'责任期限自${_formatDateShort(info['PROMISE_TERM_START']?.toString())}${_formatDateShort(info['PROMISE_TERM_END']?.toString())}',
),
],
const SizedBox(height: 8),
_buildFooter(),
const SizedBox(height: 12),
SizedBox(
width: double.infinity,
child: CustomButton(
text: '提 交',
backgroundColor: Colors.blue,
onPressed: submitSignedPromise,
),
),
],
),
),
),
);
}
}