flutter_integrated_whb/lib/customWidget/promise/promise_page.dart

349 lines
11 KiB
Dart
Raw 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: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()),
);
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,
fit: BoxFit.cover,
);
} else if (signImagePath.isNotEmpty && File(signImagePath).existsSync()) {
signPreview = Image.file(
File(signImagePath),
width: 100,
height: 50,
fit: BoxFit.cover,
);
} 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,
),
),
],
),
),
),
);
}
}