八项作业统一修改时间选择到秒级
parent
c75dfba154
commit
ae49b49153
|
@ -0,0 +1,380 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>特殊作业扎点</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
|
||||
<style>
|
||||
body, html, #container {
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
font-family: "微软雅黑";
|
||||
}
|
||||
#hint {
|
||||
position: absolute;
|
||||
z-index: 9999;
|
||||
left: 10px;
|
||||
top: 10px;
|
||||
padding: 6px 10px;
|
||||
background: rgba(255,255,255,0.9);
|
||||
border-radius: 4px;
|
||||
font-size: 12px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<!-- Baidu Map WebGL (保留你的 key) -->
|
||||
<script type="text/javascript"
|
||||
src="https://api.map.baidu.com/api?v=1.0&type=webgl&ak=OElqFYoKiAH8KFtph8ftLKF5NlNrbCUr"></script>
|
||||
<script src="./uni.webview.1.5.4.js"></script>
|
||||
</head>
|
||||
<body onload="onLoad()">
|
||||
<div id="container"></div>
|
||||
<div id="hint" style="display:none"></div>
|
||||
</body>
|
||||
|
||||
<script>
|
||||
// 地图与数据容器
|
||||
var map = null;
|
||||
var marker = null;
|
||||
var GSON_LON_LAT_WSG84 = []; // WGS84 多点 [[lon,lat,alt], ...]
|
||||
var GSON_LON_LAT_BD09 = []; // 转换后的 BD09 二维点 [[lng,lat],...]
|
||||
var convertor = null;
|
||||
|
||||
// ---------------------------
|
||||
// 通用通知宿主(Flutter / 原生 / web)
|
||||
// 会尝试多种桥接方式
|
||||
// data 可以是对象或字符串
|
||||
// ---------------------------
|
||||
function notifyHost(data) {
|
||||
try {
|
||||
// prefer passing object where supported
|
||||
if (window.JS && typeof window.JS.postMessage === 'function') {
|
||||
// webview_flutter JavaScriptChannel expects string
|
||||
var payload = (typeof data === 'string') ? data : JSON.stringify(data);
|
||||
window.JS.postMessage(payload);
|
||||
return;
|
||||
}
|
||||
if (window.flutter_inappwebview && typeof window.flutter_inappwebview.callHandler === 'function') {
|
||||
// flutter_inappwebview can accept objects
|
||||
window.flutter_inappwebview.callHandler('messageHandler', data);
|
||||
return;
|
||||
}
|
||||
if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.JS && typeof window.webkit.messageHandlers.JS.postMessage === 'function') {
|
||||
window.webkit.messageHandlers.JS.postMessage(data);
|
||||
return;
|
||||
}
|
||||
// fallback to uni (if present) to keep backward compatibility
|
||||
if (window.uni && typeof window.uni.postMessage === 'function') {
|
||||
window.uni.postMessage({data: data});
|
||||
return;
|
||||
}
|
||||
// last resort, console (useful for debugging)
|
||||
console.log('notifyHost:', data);
|
||||
} catch (e) {
|
||||
console.error('notifyHost error:', e);
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------
|
||||
// 尝试从 URL 初始化(如果 Flutter 把参数拼在 URL 上)
|
||||
// 支持参数: longitude, latitude, GSON (JSON string, 已 encodeURIComponent)
|
||||
// ---------------------------
|
||||
function tryInitFromUrl() {
|
||||
try {
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
const lon = params.get('longitude');
|
||||
const lat = params.get('latitude');
|
||||
const gsonRaw = params.get('GSON'); // 预期是 encodeURIComponent(JSON.stringify([...]))
|
||||
var has = false;
|
||||
if (lon && lat) has = true;
|
||||
if (gsonRaw) has = true;
|
||||
if (!has) return false;
|
||||
|
||||
var gson = null;
|
||||
if (gsonRaw) {
|
||||
try {
|
||||
gson = JSON.parse(decodeURIComponent(gsonRaw));
|
||||
} catch (e) {
|
||||
// 如果直接是未 encode 的 JSON 字符串,也尝试解析
|
||||
try { gson = JSON.parse(gsonRaw); } catch (e2) { gson = null; }
|
||||
}
|
||||
}
|
||||
|
||||
// 使用从 url 获取到的数据执行初始化
|
||||
initWithData({
|
||||
longitude: parseFloat(lon),
|
||||
latitude: parseFloat(lat),
|
||||
GSON: gson
|
||||
});
|
||||
return true;
|
||||
} catch (e) {
|
||||
console.warn('tryInitFromUrl error', e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------
|
||||
// Flutter/宿主可调用的初始化函数
|
||||
// 支持两种调用方式:
|
||||
// 1) initWithData({longitude: xx, latitude: yy, GSON: [...]})
|
||||
// 2) initWithData(longitude, latitude, GSONArray)
|
||||
// GSONArray 结构应与原来一致([[lon,lat,alt], ...])
|
||||
// ---------------------------
|
||||
window.initWithData = function() {
|
||||
var args = arguments;
|
||||
var payload = {};
|
||||
if (args.length === 1 && typeof args[0] === 'object') {
|
||||
payload = args[0];
|
||||
} else {
|
||||
// try positional
|
||||
payload.longitude = args[0];
|
||||
payload.latitude = args[1];
|
||||
payload.GSON = args[2];
|
||||
}
|
||||
|
||||
try {
|
||||
if (!payload) payload = {};
|
||||
// default safe parse
|
||||
var lon = Number(payload.longitude) || 0;
|
||||
var lat = Number(payload.latitude) || 0;
|
||||
var gson = payload.GSON || [];
|
||||
|
||||
// ensure convertor exists
|
||||
if (!convertor && window.BMapGL && typeof BMapGL.Convertor === 'function') {
|
||||
convertor = new BMapGL.Convertor();
|
||||
}
|
||||
|
||||
// set global wgs84 list (if provided)
|
||||
if (Array.isArray(gson) && gson.length > 0) {
|
||||
GSON_LON_LAT_WSG84 = gson;
|
||||
}
|
||||
|
||||
// init map & polygon
|
||||
fnInitMap(lon, lat);
|
||||
if (GSON_LON_LAT_WSG84 && GSON_LON_LAT_WSG84.length > 0) {
|
||||
fnInitConvertorData(GSON_LON_LAT_WSG84);
|
||||
}
|
||||
|
||||
showHint('地图已初始化');
|
||||
return true;
|
||||
} catch (e) {
|
||||
console.error('initWithData error', e);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
// 显示调试提示
|
||||
function showHint(text) {
|
||||
var el = document.getElementById('hint');
|
||||
if (!el) return;
|
||||
el.style.display = 'block';
|
||||
el.innerText = text;
|
||||
setTimeout(function(){ el.style.display = 'none'; }, 4000);
|
||||
}
|
||||
|
||||
// ---------------------------
|
||||
// 页面加载
|
||||
// ---------------------------
|
||||
function onLoad() {
|
||||
// create convertor if possible
|
||||
if (window.BMapGL && typeof BMapGL.Convertor === 'function') {
|
||||
convertor = new BMapGL.Convertor();
|
||||
} else {
|
||||
console.warn('BMapGL.Convertor not ready yet.');
|
||||
}
|
||||
|
||||
// 创建地图对象(延迟绑定 center,等 init 时调用)
|
||||
map = new BMapGL.Map('container');
|
||||
map.enableScrollWheelZoom(true);
|
||||
map.setDisplayOptions({ building: false });
|
||||
map.addEventListener('click', MapClick);
|
||||
|
||||
// 如果 URL 带参数则自动初始化,否则等待宿主调用 initWithData(...)
|
||||
var ok = tryInitFromUrl();
|
||||
if (!ok) {
|
||||
showHint('等待宿主调用 initWithData(...) 初始化地图');
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------
|
||||
// 点在多边形内判定(二维,只用 lon/lat)
|
||||
// polygon = [[lng,lat], ...]
|
||||
// point = [lng, lat]
|
||||
// ---------------------------
|
||||
function isPointInPolygon(point, polygon) {
|
||||
const x = point[0];
|
||||
const y = point[1];
|
||||
let inside = false;
|
||||
for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
|
||||
const xi = polygon[i][0], yi = polygon[i][1];
|
||||
const xj = polygon[j][0], yj = polygon[j][1];
|
||||
const intersect = ((yi > y) !== (yj > y))
|
||||
&& (x < (xj - xi) * (y - yi) / (yj - yi) + xi);
|
||||
if (intersect) inside = !inside;
|
||||
}
|
||||
return inside;
|
||||
}
|
||||
|
||||
// 地图点击处理
|
||||
function MapClick(e) {
|
||||
try {
|
||||
if (marker) map.removeOverlay(marker);
|
||||
marker = new BMapGL.Marker(new BMapGL.Point(e.latlng.lng, e.latlng.lat));
|
||||
const x = [e.latlng.lng, e.latlng.lat];
|
||||
let inside = (GSON_LON_LAT_BD09 && GSON_LON_LAT_BD09.length > 0) ? isPointInPolygon(x, GSON_LON_LAT_BD09) : true;
|
||||
if (!inside) {
|
||||
//alert("当前选择点位不在区域中!");
|
||||
notifyHost({type:'point_selected', ok:false, reason:'out_of_polygon', lng:e.latlng.lng, lat:e.latlng.lat});
|
||||
} else {
|
||||
map.addOverlay(marker);
|
||||
// 把 BD09 -> WGS84 转换后的点回传给宿主
|
||||
fnConvertorBd09ToWgs84Data2(e.latlng.lng, e.latlng.lat);
|
||||
notifyHost({type:'point_selected', ok:true, lng:e.latlng.lng, lat:e.latlng.lat});
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('MapClick error', err);
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------
|
||||
// 将 WGS84 多点转换为 BD09 并绘制多边形
|
||||
// arr: [[lon,lat,...], ...] 注意原 arr (GSON_LON_LAT_WSG84)顺序是 lon, lat
|
||||
// ---------------------------
|
||||
function fnInitConvertorData(arr) {
|
||||
try {
|
||||
if (!convertor) convertor = new BMapGL.Convertor();
|
||||
var points = [];
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
var xi = arr[i][0], yi = arr[i][1];
|
||||
points.push(new BMapGL.Point(xi, yi));
|
||||
}
|
||||
convertor.translate(points, 1, 5, function(res) {
|
||||
if (!res || !res.points) {
|
||||
console.warn('convertor.translate returned no points', res);
|
||||
return;
|
||||
}
|
||||
GSON_LON_LAT_BD09 = [];
|
||||
var list = [];
|
||||
for (var p = 0; p < res.points.length; p++) {
|
||||
let item = res.points[p];
|
||||
GSON_LON_LAT_BD09.push([item.lng, item.lat]);
|
||||
list.push(new BMapGL.Point(item.lng, item.lat));
|
||||
}
|
||||
var polygon = new BMapGL.Polygon(list, {
|
||||
zIndex: 999,
|
||||
strokeColor: 'blue',
|
||||
strokeWeight: 5,
|
||||
strokeOpacity: 0.5
|
||||
});
|
||||
map.addOverlay(polygon);
|
||||
});
|
||||
} catch (e) {
|
||||
console.error('fnInitConvertorData error', e);
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------
|
||||
// 初始化地图中心(longitude, latitude 为 WGS84)
|
||||
// ---------------------------
|
||||
function fnInitMap(longitude, latitude) {
|
||||
try {
|
||||
if (!convertor) convertor = new BMapGL.Convertor();
|
||||
var ponits = [ new BMapGL.Point(longitude, latitude) ];
|
||||
convertor.translate(ponits, 1, 5, function(res) {
|
||||
if (!res || !res.points || res.points.length === 0) {
|
||||
console.warn('fnInitMap: translate failed', res);
|
||||
return;
|
||||
}
|
||||
var pt = res.points[0];
|
||||
map.centerAndZoom(new BMapGL.Point(pt.lng, pt.lat), 18);
|
||||
});
|
||||
} catch (e) {
|
||||
console.error('fnInitMap error', e);
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------
|
||||
// BD09 -> WGS84 (JS 版算法),并把结果 post 给宿主
|
||||
// 注意: bdLat, bdLon 参数顺序(原函数输入顺序)
|
||||
// 返回 [wgsLat, wgsLon](跟原实现一致)
|
||||
// ---------------------------
|
||||
const bd09ToWgs84 = (bdLat, bdLon) => {
|
||||
const x_pi = (Math.PI * 3000.0) / 180.0;
|
||||
const x = bdLon - 0.0065;
|
||||
const y = bdLat - 0.006;
|
||||
const z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_pi);
|
||||
const theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_pi);
|
||||
const gcjLon = z * Math.cos(theta);
|
||||
const gcjLat = z * Math.sin(theta);
|
||||
|
||||
let dlat = transformlat(gcjLon - 105.0, gcjLat - 35.0);
|
||||
let dlng = transformlng(gcjLon - 105.0, gcjLat - 35.0);
|
||||
const radlat = (gcjLat / 180.0) * Math.PI;
|
||||
let magic = Math.sin(radlat);
|
||||
magic = 1 - 0.006693421622965943 * magic * magic;
|
||||
const sqrtmagic = Math.sqrt(magic);
|
||||
dlat = (dlat * 180.0) / (((6378245.0 * (1 - 0.006693421622965943)) / (magic * sqrtmagic)) * Math.PI);
|
||||
dlng = (dlng * 180.0) / ((6378245.0 / sqrtmagic) * Math.cos(radlat) * Math.PI);
|
||||
const mglat = gcjLat + dlat;
|
||||
const mglng = gcjLon + dlng;
|
||||
const wgsLon = gcjLon * 2 - mglng;
|
||||
const wgsLat = gcjLat * 2 - mglat;
|
||||
return [wgsLat, wgsLon];
|
||||
};
|
||||
|
||||
const transformlat = (lng, lat) => {
|
||||
let ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(lng));
|
||||
ret += ((20.0 * Math.sin(6.0 * lng * Math.PI) + 20.0 * Math.sin(2.0 * lng * Math.PI)) * 2.0) / 3.0;
|
||||
ret += ((20.0 * Math.sin(lat * Math.PI) + 40.0 * Math.sin((lat / 3.0) * Math.PI)) * 2.0) / 3.0;
|
||||
ret += ((160.0 * Math.sin((lat / 12.0) * Math.PI) + 320 * Math.sin((lat * Math.PI) / 30.0)) * 2.0) / 3.0;
|
||||
return ret;
|
||||
};
|
||||
const transformlng = (lng, lat) => {
|
||||
let ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng));
|
||||
ret += ((20.0 * Math.sin(6.0 * lng * Math.PI) + 20.0 * Math.sin(2.0 * lng * Math.PI)) * 2.0) / 3.0;
|
||||
ret += ((20.0 * Math.sin(lng * Math.PI) + 40.0 * Math.sin((lng / 3.0) * Math.PI)) * 2.0) / 3.0;
|
||||
ret += ((150.0 * Math.sin((lng / 12.0) * Math.PI) + 300.0 * Math.sin((lng / 30.0) * Math.PI)) * 2.0) / 3.0;
|
||||
return ret;
|
||||
};
|
||||
|
||||
// ---------------------------
|
||||
// 使用百度 convertor(如果可用)把 BD09 点转回 WGS84 并 postMessage 给宿主
|
||||
// 备用:也会调用 bd09ToWgs84 本地算法
|
||||
// ---------------------------
|
||||
function fnConvertorBd09ToWgs84Data2(lng, lat) {
|
||||
try {
|
||||
// first try convertor.translate from BMapGL
|
||||
if (convertor && typeof convertor.translate === 'function') {
|
||||
var pts = [ new BMapGL.Point(lng, lat) ];
|
||||
convertor.translate(pts, 5, 1, function(res) {
|
||||
if (res && res.points && res.points.length > 0) {
|
||||
var p = res.points[0];
|
||||
// res.points are in WGS84? depends on convert params; keep compatibility:
|
||||
notifyHost({type:'converted', longitue: p.lng, latitude: p.lat});
|
||||
return;
|
||||
}
|
||||
// fallback to local algorithm if convertor result absent
|
||||
var w = bd09ToWgs84(lat, lng);
|
||||
notifyHost({type:'converted', longitue: w[1], latitude: w[0]});
|
||||
});
|
||||
} else {
|
||||
var w = bd09ToWgs84(lat, lng);
|
||||
notifyHost({type:'converted', longitue: w[1], latitude: w[0]});
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('fnConvertorBd09ToWgs84Data2 error', e);
|
||||
var w = bd09ToWgs84(lat, lng);
|
||||
notifyHost({type:'converted', longitue: w[1], latitude: w[0]});
|
||||
}
|
||||
}
|
||||
|
||||
// 兼容老方法名
|
||||
window.fnInitMap = fnInitMap;
|
||||
window.fnInitConvertorData = fnInitConvertorData;
|
||||
window.fnConvertorBd09ToWgs84Data2 = fnConvertorBd09ToWgs84Data2;
|
||||
</script>
|
||||
</html>
|
|
@ -4,22 +4,22 @@ import 'package:flutter/material.dart';
|
|||
/// 调用示例:
|
||||
/// DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
/// context,
|
||||
/// mode: BottomPickerMode.date, // 或 BottomPickerMode.dateTime(默认)
|
||||
/// mode: BottomPickerMode.date, // 或 BottomPickerMode.dateTime(默认)或 BottomPickerMode.dateTimeWithSeconds
|
||||
/// allowFuture: true,
|
||||
/// allowPast: false, // 是否允许选择过去(false 表示只能选择现在或未来)
|
||||
/// minTimeStr: '2025-08-20 08:30',
|
||||
/// minTimeStr: '2025-08-20 08:30:45',
|
||||
/// );
|
||||
/// if (picked != null) {
|
||||
/// print('用户选择的时间:$picked');
|
||||
/// }
|
||||
enum BottomPickerMode { dateTime, date }
|
||||
enum BottomPickerMode { dateTime, date, dateTimeWithSeconds }
|
||||
|
||||
class BottomDateTimePicker {
|
||||
static Future<DateTime?> showDate(
|
||||
BuildContext context, {
|
||||
bool allowFuture = true,
|
||||
bool allowPast = true, // 新增:是否允许选择过去(默认允许)
|
||||
String? minTimeStr, // 可选:'yyyy-MM-dd HH:mm'
|
||||
bool allowPast = true, // 是否允许选择过去(默认允许)
|
||||
String? minTimeStr, // 可选:'yyyy-MM-dd HH:mm:ss'
|
||||
BottomPickerMode mode = BottomPickerMode.dateTime,
|
||||
}) {
|
||||
return showModalBottomSheet<DateTime>(
|
||||
|
@ -65,6 +65,7 @@ class _InlineDateTimePickerContentState
|
|||
final List<int> months = List.generate(12, (i) => i + 1);
|
||||
final List<int> hours = List.generate(24, (i) => i);
|
||||
final List<int> minutes = List.generate(60, (i) => i);
|
||||
final List<int> seconds = List.generate(60, (i) => i); // 新增秒数据源
|
||||
|
||||
// 动态天数列表(根据年月变化)
|
||||
late List<int> days;
|
||||
|
@ -75,6 +76,7 @@ class _InlineDateTimePickerContentState
|
|||
late FixedExtentScrollController dayCtrl;
|
||||
late FixedExtentScrollController hourCtrl;
|
||||
late FixedExtentScrollController minuteCtrl;
|
||||
late FixedExtentScrollController secondCtrl; // 新增秒控制器
|
||||
|
||||
// 当前选中值
|
||||
late int selectedYear;
|
||||
|
@ -82,6 +84,7 @@ class _InlineDateTimePickerContentState
|
|||
late int selectedDay;
|
||||
late int selectedHour;
|
||||
late int selectedMinute;
|
||||
late int selectedSecond; // 新增秒选中值
|
||||
|
||||
DateTime? _minTime; // 解析后的最小允许时间(如果有)
|
||||
|
||||
|
@ -111,16 +114,21 @@ class _InlineDateTimePickerContentState
|
|||
}
|
||||
}
|
||||
|
||||
// 如果是 date 模式,只保留日期部分(时分归零)
|
||||
// 根据模式调整初始值
|
||||
if (widget.mode == BottomPickerMode.date) {
|
||||
initial = DateTime(initial.year, initial.month, initial.day);
|
||||
} else if (widget.mode == BottomPickerMode.dateTime) {
|
||||
initial = DateTime(initial.year, initial.month, initial.day,
|
||||
initial.hour, initial.minute);
|
||||
}
|
||||
// dateTimeWithSeconds 模式保持完整的时间
|
||||
|
||||
selectedYear = initial.year;
|
||||
selectedMonth = initial.month;
|
||||
selectedDay = initial.day;
|
||||
selectedHour = initial.hour;
|
||||
selectedMinute = initial.minute;
|
||||
selectedSecond = initial.second;
|
||||
|
||||
// 初始化天数列表
|
||||
days = _getDaysInMonth(selectedYear, selectedMonth);
|
||||
|
@ -136,6 +144,8 @@ class _InlineDateTimePickerContentState
|
|||
initialItem: selectedHour.clamp(0, hours.length - 1));
|
||||
minuteCtrl = FixedExtentScrollController(
|
||||
initialItem: selectedMinute.clamp(0, minutes.length - 1));
|
||||
secondCtrl = FixedExtentScrollController( // 初始化秒控制器
|
||||
initialItem: selectedSecond.clamp(0, seconds.length - 1));
|
||||
|
||||
// 确保初始选择满足约束(例如 minTime 或禁止未来/禁止过去)
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
|
@ -149,7 +159,7 @@ class _InlineDateTimePickerContentState
|
|||
return List.generate(lastDay, (i) => i + 1);
|
||||
}
|
||||
|
||||
// 解析 'yyyy-MM-dd HH:mm' 返回 DateTime 或 null
|
||||
// 解析 'yyyy-MM-dd HH:mm:ss' 返回 DateTime 或 null
|
||||
DateTime? _parseMinTime(String? s) {
|
||||
if (s == null || s.trim().isEmpty) return null;
|
||||
try {
|
||||
|
@ -159,13 +169,14 @@ class _InlineDateTimePickerContentState
|
|||
parts[0].split('-').map((e) => int.parse(e)).toList();
|
||||
final timeParts = (parts.length > 1)
|
||||
? parts[1].split(':').map((e) => int.parse(e)).toList()
|
||||
: [0, 0];
|
||||
: [0, 0, 0];
|
||||
final year = dateParts[0];
|
||||
final month = dateParts[1];
|
||||
final day = dateParts[2];
|
||||
final hour = (timeParts.isNotEmpty) ? timeParts[0] : 0;
|
||||
final minute = (timeParts.length > 1) ? timeParts[1] : 0;
|
||||
return DateTime(year, month, day, hour, minute);
|
||||
final second = (timeParts.length > 2) ? timeParts[2] : 0;
|
||||
return DateTime(year, month, day, hour, minute, second);
|
||||
} catch (e) {
|
||||
debugPrint('parseMinTime failed for "$s": $e');
|
||||
return null;
|
||||
|
@ -190,30 +201,51 @@ class _InlineDateTimePickerContentState
|
|||
void _enforceConstraintsAndUpdateControllers() {
|
||||
final now = DateTime.now();
|
||||
final isDateOnly = widget.mode == BottomPickerMode.date;
|
||||
final isDateTimeOnly = widget.mode == BottomPickerMode.dateTime;
|
||||
|
||||
final DateTime picked = isDateOnly
|
||||
? DateTime(selectedYear, selectedMonth, selectedDay)
|
||||
: DateTime(
|
||||
DateTime picked;
|
||||
if (isDateOnly) {
|
||||
picked = DateTime(selectedYear, selectedMonth, selectedDay);
|
||||
} else if (isDateTimeOnly) {
|
||||
picked = DateTime(
|
||||
selectedYear, selectedMonth, selectedDay, selectedHour, selectedMinute);
|
||||
} else {
|
||||
picked = DateTime(selectedYear, selectedMonth, selectedDay,
|
||||
selectedHour, selectedMinute, selectedSecond);
|
||||
}
|
||||
|
||||
// 处理最小时间约束:结合 _minTime 与 allowPast
|
||||
DateTime? minRef;
|
||||
if (!widget.allowPast) {
|
||||
// 不允许选择过去:最小时间至少为 now(或当天 00:00)
|
||||
minRef = isDateOnly
|
||||
? DateTime(now.year, now.month, now.day)
|
||||
: now;
|
||||
if (isDateOnly) {
|
||||
minRef = DateTime(now.year, now.month, now.day);
|
||||
} else if (isDateTimeOnly) {
|
||||
minRef = DateTime(now.year, now.month, now.day, now.hour, now.minute);
|
||||
} else {
|
||||
minRef = now;
|
||||
}
|
||||
// 如果用户也指定了 _minTime 且比 now 晚,则以 _minTime 为准
|
||||
if (_minTime != null && _minTime!.isAfter(minRef)) {
|
||||
minRef = isDateOnly
|
||||
? DateTime(_minTime!.year, _minTime!.month, _minTime!.day)
|
||||
: _minTime;
|
||||
minRef = _minTime;
|
||||
// 根据模式调整精度
|
||||
if (isDateOnly) {
|
||||
minRef = DateTime(minRef!.year, minRef.month, minRef.day);
|
||||
} else if (isDateTimeOnly) {
|
||||
minRef = DateTime(minRef!.year, minRef.month, minRef.day,
|
||||
minRef.hour, minRef.minute);
|
||||
}
|
||||
}
|
||||
} else if (_minTime != null) {
|
||||
// 允许选择过去,但若指定了 _minTime,则以 _minTime 为最小参考
|
||||
minRef = isDateOnly
|
||||
? DateTime(_minTime!.year, _minTime!.month, _minTime!.day)
|
||||
: _minTime;
|
||||
minRef = _minTime;
|
||||
// 根据模式调整精度
|
||||
if (isDateOnly) {
|
||||
minRef = DateTime(minRef!.year, minRef.month, minRef.day);
|
||||
} else if (isDateTimeOnly) {
|
||||
minRef = DateTime(minRef!.year, minRef.month, minRef.day,
|
||||
minRef.hour, minRef.minute);
|
||||
}
|
||||
}
|
||||
|
||||
if (minRef != null && picked.isBefore(minRef)) {
|
||||
|
@ -224,9 +256,15 @@ class _InlineDateTimePickerContentState
|
|||
if (!isDateOnly) {
|
||||
selectedHour = minRef.hour;
|
||||
selectedMinute = minRef.minute;
|
||||
if (!isDateTimeOnly) {
|
||||
selectedSecond = minRef.second;
|
||||
} else {
|
||||
selectedSecond = 0;
|
||||
}
|
||||
} else {
|
||||
selectedHour = 0;
|
||||
selectedMinute = 0;
|
||||
selectedSecond = 0;
|
||||
}
|
||||
|
||||
_updateDays(jumpDay: false);
|
||||
|
@ -236,15 +274,24 @@ class _InlineDateTimePickerContentState
|
|||
if (!isDateOnly) {
|
||||
hourCtrl.jumpToItem(selectedHour);
|
||||
minuteCtrl.jumpToItem(selectedMinute);
|
||||
if (!isDateTimeOnly) {
|
||||
secondCtrl.jumpToItem(selectedSecond);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// 处理禁止选择未来(当 allowFuture == false)
|
||||
if (!widget.allowFuture) {
|
||||
final DateTime nowRef = isDateOnly
|
||||
? DateTime(now.year, now.month, now.day)
|
||||
: now;
|
||||
DateTime nowRef;
|
||||
if (isDateOnly) {
|
||||
nowRef = DateTime(now.year, now.month, now.day);
|
||||
} else if (isDateTimeOnly) {
|
||||
nowRef = DateTime(now.year, now.month, now.day, now.hour, now.minute);
|
||||
} else {
|
||||
nowRef = now;
|
||||
}
|
||||
|
||||
if (picked.isAfter(nowRef)) {
|
||||
selectedYear = nowRef.year;
|
||||
selectedMonth = nowRef.month;
|
||||
|
@ -252,9 +299,15 @@ class _InlineDateTimePickerContentState
|
|||
if (!isDateOnly) {
|
||||
selectedHour = nowRef.hour;
|
||||
selectedMinute = nowRef.minute;
|
||||
if (!isDateTimeOnly) {
|
||||
selectedSecond = nowRef.second;
|
||||
} else {
|
||||
selectedSecond = 0;
|
||||
}
|
||||
} else {
|
||||
selectedHour = 0;
|
||||
selectedMinute = 0;
|
||||
selectedSecond = 0;
|
||||
}
|
||||
|
||||
_updateDays(jumpDay: false);
|
||||
|
@ -264,6 +317,9 @@ class _InlineDateTimePickerContentState
|
|||
if (!isDateOnly) {
|
||||
hourCtrl.jumpToItem(selectedHour);
|
||||
minuteCtrl.jumpToItem(selectedMinute);
|
||||
if (!isDateTimeOnly) {
|
||||
secondCtrl.jumpToItem(selectedSecond);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -277,14 +333,20 @@ class _InlineDateTimePickerContentState
|
|||
dayCtrl.dispose();
|
||||
hourCtrl.dispose();
|
||||
minuteCtrl.dispose();
|
||||
secondCtrl.dispose(); // 释放秒控制器
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final isDateOnly = widget.mode == BottomPickerMode.date;
|
||||
final isDateTimeOnly = widget.mode == BottomPickerMode.dateTime;
|
||||
|
||||
// 根据模式计算高度
|
||||
final height = isDateOnly ? 280 : (isDateTimeOnly ? 330 : 380);
|
||||
|
||||
return SizedBox(
|
||||
height: isDateOnly ? 280 : 330,
|
||||
height: height.toDouble(),
|
||||
child: Column(
|
||||
children: [
|
||||
// 顶部按钮
|
||||
|
@ -299,15 +361,27 @@ class _InlineDateTimePickerContentState
|
|||
),
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
final result = isDateOnly
|
||||
? DateTime(selectedYear, selectedMonth, selectedDay)
|
||||
: DateTime(
|
||||
DateTime result;
|
||||
if (isDateOnly) {
|
||||
result = DateTime(selectedYear, selectedMonth, selectedDay);
|
||||
} else if (isDateTimeOnly) {
|
||||
result = DateTime(
|
||||
selectedYear,
|
||||
selectedMonth,
|
||||
selectedDay,
|
||||
selectedHour,
|
||||
selectedMinute,
|
||||
);
|
||||
} else {
|
||||
result = DateTime(
|
||||
selectedYear,
|
||||
selectedMonth,
|
||||
selectedDay,
|
||||
selectedHour,
|
||||
selectedMinute,
|
||||
selectedSecond,
|
||||
);
|
||||
}
|
||||
Navigator.of(context).pop(result);
|
||||
},
|
||||
child: const Text("确定", style: TextStyle(color: Colors.blue)),
|
||||
|
@ -317,7 +391,7 @@ class _InlineDateTimePickerContentState
|
|||
),
|
||||
const Divider(height: 1),
|
||||
|
||||
// 可见的滚轮列(date 模式只显示 年 月 日)
|
||||
// 可见的滚轮列
|
||||
Expanded(
|
||||
child: Row(
|
||||
children: [
|
||||
|
@ -384,6 +458,19 @@ class _InlineDateTimePickerContentState
|
|||
});
|
||||
},
|
||||
),
|
||||
|
||||
// 如果是 dateTimeWithSeconds 模式,显示秒列
|
||||
if (widget.mode == BottomPickerMode.dateTimeWithSeconds)
|
||||
_buildPicker(
|
||||
controller: secondCtrl,
|
||||
items: seconds.map((e) => e.toString().padLeft(2, '0')).toList(),
|
||||
onSelected: (idx) {
|
||||
setState(() {
|
||||
selectedSecond = seconds[idx];
|
||||
_enforceConstraintsAndUpdateControllers();
|
||||
});
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
|
@ -773,7 +773,7 @@ class _SafecheckDetailState extends State<SafecheckDetail> {
|
|||
text: form['INSPECTION_TIME_START'] ?? '',
|
||||
onTap: () async {
|
||||
DateTime? picked =
|
||||
await BottomDateTimePicker.showDate(context);
|
||||
await BottomDateTimePicker.showDate(context,mode: BottomPickerMode.dateTimeWithSeconds,);
|
||||
if (picked != null) {
|
||||
setState(() {
|
||||
form['INSPECTION_TIME_START'] = DateFormat(
|
||||
|
@ -792,7 +792,7 @@ class _SafecheckDetailState extends State<SafecheckDetail> {
|
|||
text: form['INSPECTION_TIME_END'] ?? '',
|
||||
onTap: () async {
|
||||
DateTime? picked =
|
||||
await BottomDateTimePicker.showDate(context);
|
||||
await BottomDateTimePicker.showDate(context,mode: BottomPickerMode.dateTimeWithSeconds,);
|
||||
if (picked != null) {
|
||||
setState(() {
|
||||
form['INSPECTION_TIME_END'] = DateFormat(
|
||||
|
|
|
@ -1023,6 +1023,7 @@ class _SafecheckStartDetailState extends State<SafecheckStartDetail> {
|
|||
text: form['INSPECTION_TIME_START'] ?? '',
|
||||
onTap: () async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
mode: BottomPickerMode.dateTimeWithSeconds,
|
||||
context,
|
||||
);
|
||||
if (picked != null) {
|
||||
|
@ -1043,6 +1044,7 @@ class _SafecheckStartDetailState extends State<SafecheckStartDetail> {
|
|||
text: form['INSPECTION_TIME_END'] ?? '',
|
||||
onTap: () async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
mode: BottomPickerMode.dateTimeWithSeconds,
|
||||
context,
|
||||
);
|
||||
if (picked != null) {
|
||||
|
|
|
@ -161,7 +161,7 @@ class _DangerousOptionsPageState extends State<DangerousOptionsPage> {
|
|||
MaterialPageRoute(builder: (c) => MineSignPage()),
|
||||
);
|
||||
await NativeOrientation.setPortrait();
|
||||
if (path != null) {
|
||||
if (path != null) {
|
||||
final now = DateFormat('yyyy-MM-dd HH:mm').format(DateTime.now());
|
||||
setState(() {
|
||||
final imageData = SignImageData(
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:qhd_prevention/customWidget/ItemWidgetFactory.dart';
|
||||
import 'package:qhd_prevention/customWidget/picker/CupertinoDatePicker.dart';
|
||||
|
||||
import '../../../../../../tools/tools.dart';
|
||||
import '../../../item_list_widget.dart';
|
||||
|
@ -16,11 +18,8 @@ class HotWorkDetailFormWidget extends StatefulWidget {
|
|||
|
||||
|
||||
// 新增
|
||||
final VoidCallback? onChooseVideoManager;
|
||||
/// 选择摄像头
|
||||
final VoidCallback? onWorkStartTimeHandle;
|
||||
final VoidCallback? onWorkEndTimeHandle;
|
||||
/// 承包商
|
||||
/// 选择摄像头
|
||||
final VoidCallback? onChooseVideoManager;/// 承包商
|
||||
final VoidCallback? onContractorHandle;
|
||||
/// 作业区域
|
||||
final VoidCallback? onWorkAreaHandle;
|
||||
|
@ -45,8 +44,6 @@ class HotWorkDetailFormWidget extends StatefulWidget {
|
|||
required this.onAnalyzeTap,
|
||||
/// 新增
|
||||
this.onChooseVideoManager,
|
||||
this.onWorkStartTimeHandle,
|
||||
this.onWorkEndTimeHandle,
|
||||
this.onContractorHandle,
|
||||
this.onWorkAreaHandle,
|
||||
this.onWorkAreaLocationHandle,
|
||||
|
@ -161,6 +158,7 @@ class _HotWorkDetailFormWidgetState extends State<HotWorkDetailFormWidget> {
|
|||
const Divider(),
|
||||
ItemListWidget.twoRowButtonTitleText(
|
||||
label: '关联其他特殊作业及安全作业票编号',
|
||||
isRequired: false,
|
||||
isEditable: widget.isEditable,
|
||||
onTap: () async {
|
||||
await showDialog<String>(
|
||||
|
@ -228,14 +226,49 @@ class _HotWorkDetailFormWidgetState extends State<HotWorkDetailFormWidget> {
|
|||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '预计作业开始时间:',
|
||||
isEditable: widget.isEditable,
|
||||
onTap: widget.onWorkStartTimeHandle ?? () {},
|
||||
onTap: () async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
mode: BottomPickerMode.dateTimeWithSeconds,
|
||||
context,
|
||||
allowFuture: true,
|
||||
);
|
||||
if (picked != null) {
|
||||
setState(() {
|
||||
pd['WORK_EXPECTED_START_TIME'] = DateFormat(
|
||||
'yyyy-MM-dd HH:mm:ss',
|
||||
).format(picked);
|
||||
|
||||
/// 开始时间必须早于结束时间
|
||||
if (FormUtils.hasValue(pd, 'WORK_EXPECTED_END_TIME') &&
|
||||
!isBeforeStr(
|
||||
pd['WORK_EXPECTED_START_TIME'],
|
||||
pd['WORK_EXPECTED_END_TIME'],
|
||||
)) {
|
||||
pd['WORK_EXPECTED_END_TIME'] = '';
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
text: pd['WORK_EXPECTED_START_TIME'] ?? '',
|
||||
),
|
||||
const Divider(),
|
||||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '预计作业结束时间:',
|
||||
isEditable: widget.isEditable,
|
||||
onTap: widget.onWorkEndTimeHandle ?? () {},
|
||||
onTap: () async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
context,
|
||||
minTimeStr: pd['WORK_EXPECTED_START_TIME'] ?? '',
|
||||
allowFuture: true,
|
||||
);
|
||||
if (picked != null) {
|
||||
setState(() {
|
||||
pd['WORK_EXPECTED_END_TIME'] = DateFormat(
|
||||
'yyyy-MM-dd HH:mm:ss',
|
||||
).format(picked);
|
||||
});
|
||||
}
|
||||
},
|
||||
text: pd['WORK_EXPECTED_END_TIME'] ?? '',
|
||||
),
|
||||
const Divider(),
|
||||
|
|
|
@ -265,44 +265,7 @@ class _HotworkApplyDetailState extends State<HotworkApplyDetail> {
|
|||
});
|
||||
}
|
||||
}
|
||||
/// 预计作业开始时间
|
||||
Future<void> _chooseWorkStartTime() async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
context,
|
||||
allowFuture: true,
|
||||
);
|
||||
if (picked != null) {
|
||||
setState(() {
|
||||
pd['WORK_EXPECTED_START_TIME'] = DateFormat(
|
||||
'yyyy-MM-dd HH:mm:ss',
|
||||
).format(picked);
|
||||
|
||||
/// 开始时间必须早于结束时间
|
||||
if (FormUtils.hasValue(pd, 'WORK_EXPECTED_END_TIME') &&
|
||||
!isBeforeStr(
|
||||
pd['WORK_EXPECTED_START_TIME'],
|
||||
pd['WORK_EXPECTED_END_TIME'],
|
||||
)) {
|
||||
pd['WORK_EXPECTED_END_TIME'] = '';
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
/// 预计作业结束时间
|
||||
Future<void> _chooseWorkEndTime() async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
context,
|
||||
minTimeStr: pd['WORK_EXPECTED_START_TIME'] ?? '',
|
||||
allowFuture: true,
|
||||
);
|
||||
if (picked != null) {
|
||||
setState(() {
|
||||
pd['WORK_EXPECTED_END_TIME'] = DateFormat(
|
||||
'yyyy-MM-dd HH:mm:ss',
|
||||
).format(picked);
|
||||
});
|
||||
}
|
||||
}
|
||||
/// 选择经纬度
|
||||
Future<void> _showLocationHandle() async{
|
||||
if (!FormUtils.hasValue(pd, 'ELECTRONIC_FENCE_AREA_ID')) {
|
||||
|
@ -725,8 +688,6 @@ class _HotworkApplyDetailState extends State<HotworkApplyDetail> {
|
|||
onChooseHotworkUser: _chooseHorkUser,
|
||||
// 新增
|
||||
onChooseVideoManager: _chooseVideoManager,
|
||||
onWorkStartTimeHandle: _chooseWorkStartTime,
|
||||
onWorkEndTimeHandle: _chooseWorkEndTime,
|
||||
onContractorHandle: _chooseUnitManager,
|
||||
onWorkAreaHandle: _getWorkArea,
|
||||
onWorkAreaLocationHandle: _showLocationHandle,
|
||||
|
|
|
@ -336,6 +336,7 @@ class _HotworkJszyDetailState extends State<HotworkJszyDetail> {
|
|||
),
|
||||
onTap: () async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
mode: BottomPickerMode.dateTimeWithSeconds,
|
||||
context,
|
||||
);
|
||||
if (picked != null) {
|
||||
|
|
|
@ -308,6 +308,7 @@ class _HotworkKszyDetailState extends State<HotworkKszyDetail> {
|
|||
),
|
||||
onTap: () async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
mode: BottomPickerMode.dateTimeWithSeconds,
|
||||
context,
|
||||
);
|
||||
if (picked != null) {
|
||||
|
|
|
@ -366,6 +366,7 @@ class _HotworkYsgdDetailState extends State<HotworkYsgdDetail> {
|
|||
),
|
||||
onTap: () async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
mode: BottomPickerMode.dateTimeWithSeconds,
|
||||
context,
|
||||
);
|
||||
if (picked != null) {
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
import 'dart:math' as math;
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:qhd_prevention/customWidget/ItemWidgetFactory.dart';
|
||||
import 'package:qhd_prevention/customWidget/picker/CupertinoDatePicker.dart';
|
||||
import 'package:qhd_prevention/customWidget/single_image_viewer.dart';
|
||||
import 'package:qhd_prevention/http/ApiService.dart';
|
||||
|
||||
|
@ -22,11 +24,8 @@ class CutroadDetailFormWidget extends StatefulWidget {
|
|||
final TextEditingController? riskController;
|
||||
|
||||
// 新增
|
||||
final VoidCallback? onChooseVideoManager;
|
||||
/// 选择摄像头
|
||||
final VoidCallback? onWorkStartTimeHandle;
|
||||
final VoidCallback? onWorkEndTimeHandle;
|
||||
/// 承包商
|
||||
/// 选择摄像头
|
||||
final VoidCallback? onChooseVideoManager;/// 承包商
|
||||
final VoidCallback? onContractorHandle;
|
||||
/// 作业区域
|
||||
final VoidCallback? onWorkAreaHandle;
|
||||
|
@ -43,8 +42,6 @@ class CutroadDetailFormWidget extends StatefulWidget {
|
|||
|
||||
/// 新增
|
||||
this.onChooseVideoManager,
|
||||
this.onWorkStartTimeHandle,
|
||||
this.onWorkEndTimeHandle,
|
||||
this.onContractorHandle,
|
||||
this.onWorkAreaHandle,
|
||||
this.onWorkAreaLocationHandle,
|
||||
|
@ -313,6 +310,7 @@ class _CutroadDetailFormWidgetState extends State<CutroadDetailFormWidget> {
|
|||
|
||||
ItemListWidget.twoRowButtonTitleText(
|
||||
label: '关联其他特殊作业及安全作业票编号',
|
||||
isRequired: false,
|
||||
isEditable: widget.isEditable,
|
||||
onTap: () async {
|
||||
final val = await showDialog<String>(
|
||||
|
@ -379,14 +377,49 @@ class _CutroadDetailFormWidgetState extends State<CutroadDetailFormWidget> {
|
|||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '预计作业开始时间:',
|
||||
isEditable: widget.isEditable,
|
||||
onTap: widget.onWorkStartTimeHandle ?? () {},
|
||||
onTap: () async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
mode: BottomPickerMode.dateTimeWithSeconds,
|
||||
context,
|
||||
allowFuture: true,
|
||||
);
|
||||
if (picked != null) {
|
||||
setState(() {
|
||||
pd['WORK_EXPECTED_START_TIME'] = DateFormat(
|
||||
'yyyy-MM-dd HH:mm:ss',
|
||||
).format(picked);
|
||||
|
||||
/// 开始时间必须早于结束时间
|
||||
if (FormUtils.hasValue(pd, 'WORK_EXPECTED_END_TIME') &&
|
||||
!isBeforeStr(
|
||||
pd['WORK_EXPECTED_START_TIME'],
|
||||
pd['WORK_EXPECTED_END_TIME'],
|
||||
)) {
|
||||
pd['WORK_EXPECTED_END_TIME'] = '';
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
text: pd['WORK_EXPECTED_START_TIME'] ?? '',
|
||||
),
|
||||
const Divider(),
|
||||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '预计作业结束时间:',
|
||||
isEditable: widget.isEditable,
|
||||
onTap: widget.onWorkEndTimeHandle ?? () {},
|
||||
onTap: () async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
context,
|
||||
minTimeStr: pd['WORK_EXPECTED_START_TIME'] ?? '',
|
||||
allowFuture: true,
|
||||
);
|
||||
if (picked != null) {
|
||||
setState(() {
|
||||
pd['WORK_EXPECTED_END_TIME'] = DateFormat(
|
||||
'yyyy-MM-dd HH:mm:ss',
|
||||
).format(picked);
|
||||
});
|
||||
}
|
||||
},
|
||||
text: pd['WORK_EXPECTED_END_TIME'] ?? '',
|
||||
),
|
||||
const Divider(),
|
||||
|
|
|
@ -441,44 +441,8 @@ class _CutroadApplyDetailState extends State<CutroadApplyDetail> {
|
|||
});
|
||||
}
|
||||
}
|
||||
/// 预计作业开始时间
|
||||
Future<void> _chooseWorkStartTime() async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
context,
|
||||
allowFuture: true,
|
||||
);
|
||||
if (picked != null) {
|
||||
setState(() {
|
||||
pd['WORK_EXPECTED_START_TIME'] = DateFormat(
|
||||
'yyyy-MM-dd HH:mm:ss',
|
||||
).format(picked);
|
||||
|
||||
/// 开始时间必须早于结束时间
|
||||
if (FormUtils.hasValue(pd, 'WORK_EXPECTED_END_TIME') &&
|
||||
!isBeforeStr(
|
||||
pd['WORK_EXPECTED_START_TIME'],
|
||||
pd['WORK_EXPECTED_END_TIME'],
|
||||
)) {
|
||||
pd['WORK_EXPECTED_END_TIME'] = '';
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
/// 预计作业结束时间
|
||||
Future<void> _chooseWorkEndTime() async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
context,
|
||||
minTimeStr: pd['WORK_EXPECTED_START_TIME'] ?? '',
|
||||
allowFuture: true,
|
||||
);
|
||||
if (picked != null) {
|
||||
setState(() {
|
||||
pd['WORK_EXPECTED_END_TIME'] = DateFormat(
|
||||
'yyyy-MM-dd HH:mm:ss',
|
||||
).format(picked);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// 选择经纬度
|
||||
Future<void> _showLocationHandle() async{
|
||||
if (!FormUtils.hasValue(pd, 'ELECTRONIC_FENCE_AREA_ID')) {
|
||||
|
@ -604,8 +568,6 @@ class _CutroadApplyDetailState extends State<CutroadApplyDetail> {
|
|||
onChooseLevel: (){},
|
||||
// 新增
|
||||
onChooseVideoManager: _chooseVideoManager,
|
||||
onWorkStartTimeHandle: _chooseWorkStartTime,
|
||||
onWorkEndTimeHandle: _chooseWorkEndTime,
|
||||
onContractorHandle: _chooseUnitManager,
|
||||
onWorkAreaHandle: _getWorkArea,
|
||||
onWorkAreaLocationHandle: _showLocationHandle,
|
||||
|
|
|
@ -35,6 +35,7 @@ class _CutroadJszyDetailState extends State<CutroadJszyDetail> {
|
|||
|
||||
/// 详情
|
||||
late Map<String, dynamic> pd = {};
|
||||
|
||||
/// 选择的时间
|
||||
String endTime = '';
|
||||
|
||||
|
@ -58,7 +59,7 @@ class _CutroadJszyDetailState extends State<CutroadJszyDetail> {
|
|||
MaterialPageRoute(builder: (context) => MineSignPage()),
|
||||
);
|
||||
await NativeOrientation.setPortrait();
|
||||
if (path != null) {
|
||||
if (path != null) {
|
||||
final now = DateFormat('yyyy-MM-dd HH:mm').format(DateTime.now());
|
||||
setState(() {
|
||||
signImages.add(path);
|
||||
|
@ -125,6 +126,7 @@ if (path != null) {
|
|||
}).toList(),
|
||||
);
|
||||
}
|
||||
|
||||
bool checkWorkTime(Map<String, dynamic> pd, BuildContext context) {
|
||||
// 解析开始和结束时间
|
||||
final start = DateTime.parse(pd['WORK_START_DATE'] as String);
|
||||
|
@ -137,9 +139,9 @@ if (path != null) {
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// 作废 -1 通过 1
|
||||
Future<void> _submit(String status) async {
|
||||
if (signImages.isEmpty) {
|
||||
|
@ -161,7 +163,7 @@ if (path != null) {
|
|||
title: '作废原因',
|
||||
hintText: '请输入作废原因',
|
||||
cancelText: '取消',
|
||||
confirmText: '确定'
|
||||
confirmText: '确定',
|
||||
);
|
||||
if (reasonText.isEmpty) {
|
||||
ToastUtil.showNormal(context, '请填写作废原因');
|
||||
|
@ -191,7 +193,7 @@ if (path != null) {
|
|||
LoadingDialogHelper.show();
|
||||
try {
|
||||
final result = await ApiService.saveSafeFunctionSure(
|
||||
'cutroad',
|
||||
'cutroad',
|
||||
formData,
|
||||
signImages,
|
||||
);
|
||||
|
@ -204,13 +206,15 @@ if (path != null) {
|
|||
LoadingDialogHelper.hide();
|
||||
ToastUtil.showNormal(context, '操作失败:$e');
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/// 初始化拉取数据
|
||||
Future<void> _getData() async {
|
||||
final data = await ApiService.getHomeworkFindById('cutroad', widget.CUTROAD_ID);
|
||||
final data = await ApiService.getHomeworkFindById(
|
||||
'cutroad',
|
||||
widget.CUTROAD_ID,
|
||||
);
|
||||
setState(() {
|
||||
pd = data['pd'];
|
||||
|
||||
|
@ -220,7 +224,8 @@ if (path != null) {
|
|||
}
|
||||
|
||||
Future<void> _getMeasures(String homework_id) async {
|
||||
final data = await ApiService.listSignFinishMeasures('cutroad',
|
||||
final data = await ApiService.listSignFinishMeasures(
|
||||
'cutroad',
|
||||
homework_id.length > 0 ? homework_id : widget.CUTROAD_ID,
|
||||
);
|
||||
setState(() {
|
||||
|
@ -231,7 +236,8 @@ if (path != null) {
|
|||
}
|
||||
|
||||
Future<void> _getSigns(String homework_id) async {
|
||||
final data = await ApiService.listSignFinished('cutroad',
|
||||
final data = await ApiService.listSignFinished(
|
||||
'cutroad',
|
||||
homework_id.length > 0 ? homework_id : widget.CUTROAD_ID,
|
||||
);
|
||||
setState(() {
|
||||
|
@ -294,12 +300,23 @@ if (path != null) {
|
|||
Column(
|
||||
children: [
|
||||
GestureDetector(
|
||||
child: ListItemFactory.createRowSpaceBetweenItem(leftText: '作业结束时间', rightText: endTime.isEmpty?'请选择':endTime, isRight: true, isRequired: true),
|
||||
child: ListItemFactory.createRowSpaceBetweenItem(
|
||||
leftText: '作业结束时间',
|
||||
rightText: endTime.isEmpty ? '请选择' : endTime,
|
||||
isRight: true,
|
||||
isRequired: true,
|
||||
),
|
||||
onTap: () async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(context);
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
mode: BottomPickerMode.dateTimeWithSeconds,
|
||||
context,
|
||||
);
|
||||
|
||||
if (picked != null) {
|
||||
setState(() {
|
||||
endTime = DateFormat('yyyy-MM-dd HH:mm').format(picked);
|
||||
endTime = DateFormat(
|
||||
'yyyy-MM-dd HH:mm',
|
||||
).format(picked);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
|
|
@ -298,6 +298,7 @@ setState(() {
|
|||
),
|
||||
onTap: () async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
mode: BottomPickerMode.dateTimeWithSeconds,
|
||||
context,
|
||||
);
|
||||
if (picked != null) {
|
||||
|
|
|
@ -43,8 +43,10 @@ class _CutroadYsgdDetailState extends State<CutroadYsgdDetail> {
|
|||
|
||||
/// 详情
|
||||
late Map<String, dynamic> pd = {};
|
||||
|
||||
/// 选择的时间
|
||||
String startTime = '';
|
||||
|
||||
/// 验收意见
|
||||
final TextEditingController _contentController = TextEditingController();
|
||||
late List<ImageData> imgList = [];
|
||||
|
@ -60,6 +62,7 @@ class _CutroadYsgdDetailState extends State<CutroadYsgdDetail> {
|
|||
super.initState();
|
||||
_getData();
|
||||
}
|
||||
|
||||
/// 拍照或选图后的回调
|
||||
Future<void> _onImageAdded(String localPath) async {
|
||||
// 上传到服务器
|
||||
|
@ -79,6 +82,7 @@ class _CutroadYsgdDetailState extends State<CutroadYsgdDetail> {
|
|||
imgList.remove(item);
|
||||
});
|
||||
}
|
||||
|
||||
/// 签字
|
||||
Future<void> _sign() async {
|
||||
await NativeOrientation.setLandscape();
|
||||
|
@ -89,7 +93,7 @@ class _CutroadYsgdDetailState extends State<CutroadYsgdDetail> {
|
|||
await NativeOrientation.setPortrait();
|
||||
if (path != null) {
|
||||
final now = DateFormat('yyyy-MM-dd HH:mm').format(DateTime.now());
|
||||
setState(() {
|
||||
setState(() {
|
||||
signImages.add(path);
|
||||
signTimes.add(now);
|
||||
FocusHelper.clearFocus(context);
|
||||
|
@ -195,7 +199,7 @@ setState(() {
|
|||
title: '作废原因',
|
||||
hintText: '请输入作废原因',
|
||||
cancelText: '取消',
|
||||
confirmText: '确定'
|
||||
confirmText: '确定',
|
||||
);
|
||||
if (reasonText.isEmpty) {
|
||||
ToastUtil.showNormal(context, '请填写作废原因');
|
||||
|
@ -231,7 +235,7 @@ setState(() {
|
|||
LoadingDialogHelper.show();
|
||||
try {
|
||||
final result = await ApiService.saveSafeFunctionSure(
|
||||
'cutroad',
|
||||
'cutroad',
|
||||
formData,
|
||||
signImages,
|
||||
);
|
||||
|
@ -244,13 +248,15 @@ setState(() {
|
|||
LoadingDialogHelper.hide();
|
||||
ToastUtil.showNormal(context, '操作失败:$e');
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/// 初始化拉取数据
|
||||
Future<void> _getData() async {
|
||||
final data = await ApiService.getHomeworkFindById('cutroad', widget.CUTROAD_ID);
|
||||
final data = await ApiService.getHomeworkFindById(
|
||||
'cutroad',
|
||||
widget.CUTROAD_ID,
|
||||
);
|
||||
setState(() {
|
||||
pd = data['pd'];
|
||||
|
||||
|
@ -260,7 +266,8 @@ setState(() {
|
|||
}
|
||||
|
||||
Future<void> _getMeasures(String homework_id) async {
|
||||
final data = await ApiService.listSignFinishMeasures('cutroad',
|
||||
final data = await ApiService.listSignFinishMeasures(
|
||||
'cutroad',
|
||||
homework_id.length > 0 ? homework_id : widget.CUTROAD_ID,
|
||||
);
|
||||
setState(() {
|
||||
|
@ -271,7 +278,8 @@ setState(() {
|
|||
}
|
||||
|
||||
Future<void> _getSigns(String homework_id) async {
|
||||
final data = await ApiService.listSignFinished('cutroad',
|
||||
final data = await ApiService.listSignFinished(
|
||||
'cutroad',
|
||||
homework_id.length > 0 ? homework_id : widget.CUTROAD_ID,
|
||||
);
|
||||
setState(() {
|
||||
|
@ -338,16 +346,26 @@ setState(() {
|
|||
'完工验收',
|
||||
'请输入意见',
|
||||
_contentController,
|
||||
isRequired: true
|
||||
isRequired: true,
|
||||
),
|
||||
Divider(),
|
||||
GestureDetector(
|
||||
child: ListItemFactory.createRowSpaceBetweenItem(leftText: '验收时间', rightText: startTime.isEmpty?'请选择':startTime, isRight: true, isRequired: true),
|
||||
child: ListItemFactory.createRowSpaceBetweenItem(
|
||||
leftText: '验收时间',
|
||||
rightText: startTime.isEmpty ? '请选择' : startTime,
|
||||
isRight: true,
|
||||
isRequired: true,
|
||||
),
|
||||
onTap: () async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(context);
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
mode: BottomPickerMode.dateTimeWithSeconds,
|
||||
context,
|
||||
);
|
||||
if (picked != null) {
|
||||
setState(() {
|
||||
startTime = DateFormat('yyyy-MM-dd HH:mm').format(picked);
|
||||
startTime = DateFormat(
|
||||
'yyyy-MM-dd HH:mm',
|
||||
).format(picked);
|
||||
});
|
||||
FocusHelper.clearFocus(context);
|
||||
}
|
||||
|
@ -363,10 +381,15 @@ setState(() {
|
|||
onChanged: (paths) {},
|
||||
onMediaAdded: _onImageAdded,
|
||||
onMediaTapped: (path) {
|
||||
presentOpaque(SingleImageViewer(imageUrl: path), context);
|
||||
presentOpaque(
|
||||
SingleImageViewer(imageUrl: path),
|
||||
context,
|
||||
);
|
||||
},
|
||||
onMediaRemoved: (path) {
|
||||
final item = imgList.firstWhere((e) => e.localPath == path);
|
||||
final item = imgList.firstWhere(
|
||||
(e) => e.localPath == path,
|
||||
);
|
||||
_onImageRemoved(item);
|
||||
},
|
||||
onAiIdentify: () {},
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import 'dart:math' as math;
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:qhd_prevention/customWidget/picker/CupertinoDatePicker.dart';
|
||||
import 'package:qhd_prevention/customWidget/ItemWidgetFactory.dart';
|
||||
import 'package:qhd_prevention/customWidget/single_image_viewer.dart';
|
||||
import 'package:qhd_prevention/http/ApiService.dart';
|
||||
|
@ -23,11 +25,8 @@ class BreakgroundDetailFormWidget extends StatefulWidget {
|
|||
final TextEditingController? relatedController;
|
||||
final TextEditingController? riskController;
|
||||
// 新增
|
||||
final VoidCallback? onChooseVideoManager;
|
||||
/// 选择摄像头
|
||||
final VoidCallback? onWorkStartTimeHandle;
|
||||
final VoidCallback? onWorkEndTimeHandle;
|
||||
/// 承包商
|
||||
/// 选择摄像头
|
||||
final VoidCallback? onChooseVideoManager;/// 承包商
|
||||
final VoidCallback? onContractorHandle;
|
||||
/// 作业区域
|
||||
final VoidCallback? onWorkAreaHandle;
|
||||
|
@ -42,8 +41,6 @@ class BreakgroundDetailFormWidget extends StatefulWidget {
|
|||
required this.signs,
|
||||
/// 新增
|
||||
this.onChooseVideoManager,
|
||||
this.onWorkStartTimeHandle,
|
||||
this.onWorkEndTimeHandle,
|
||||
this.onContractorHandle,
|
||||
this.onWorkAreaHandle,
|
||||
this.onWorkAreaLocationHandle,
|
||||
|
@ -358,6 +355,7 @@ class _BreakgroundDetailFormWidgetState
|
|||
],
|
||||
ItemListWidget.twoRowButtonTitleText(
|
||||
label: '关联其他特殊作业及安全作业票编号',
|
||||
isRequired: false,
|
||||
isEditable: widget.isEditable,
|
||||
onTap: () async {
|
||||
final val = await showDialog<String>(
|
||||
|
@ -426,14 +424,49 @@ class _BreakgroundDetailFormWidgetState
|
|||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '预计作业开始时间:',
|
||||
isEditable: widget.isEditable,
|
||||
onTap: widget.onWorkStartTimeHandle ?? () {},
|
||||
onTap: () async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
mode: BottomPickerMode.dateTimeWithSeconds,
|
||||
context,
|
||||
allowFuture: true,
|
||||
);
|
||||
if (picked != null) {
|
||||
setState(() {
|
||||
pd['WORK_EXPECTED_START_TIME'] = DateFormat(
|
||||
'yyyy-MM-dd HH:mm:ss',
|
||||
).format(picked);
|
||||
|
||||
/// 开始时间必须早于结束时间
|
||||
if (FormUtils.hasValue(pd, 'WORK_EXPECTED_END_TIME') &&
|
||||
!isBeforeStr(
|
||||
pd['WORK_EXPECTED_START_TIME'],
|
||||
pd['WORK_EXPECTED_END_TIME'],
|
||||
)) {
|
||||
pd['WORK_EXPECTED_END_TIME'] = '';
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
text: pd['WORK_EXPECTED_START_TIME'] ?? '',
|
||||
),
|
||||
const Divider(),
|
||||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '预计作业结束时间:',
|
||||
isEditable: widget.isEditable,
|
||||
onTap: widget.onWorkEndTimeHandle ?? () {},
|
||||
onTap: () async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
context,
|
||||
minTimeStr: pd['WORK_EXPECTED_START_TIME'] ?? '',
|
||||
allowFuture: true,
|
||||
);
|
||||
if (picked != null) {
|
||||
setState(() {
|
||||
pd['WORK_EXPECTED_END_TIME'] = DateFormat(
|
||||
'yyyy-MM-dd HH:mm:ss',
|
||||
).format(picked);
|
||||
});
|
||||
}
|
||||
},
|
||||
text: pd['WORK_EXPECTED_END_TIME'] ?? '',
|
||||
),
|
||||
const Divider(),
|
||||
|
|
|
@ -217,44 +217,8 @@ class _BreakgroundApplyDetailState extends State<BreakgroundApplyDetail> {
|
|||
});
|
||||
}
|
||||
}
|
||||
/// 预计作业开始时间
|
||||
Future<void> _chooseWorkStartTime() async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
context,
|
||||
allowFuture: true,
|
||||
);
|
||||
if (picked != null) {
|
||||
setState(() {
|
||||
pd['WORK_EXPECTED_START_TIME'] = DateFormat(
|
||||
'yyyy-MM-dd HH:mm:ss',
|
||||
).format(picked);
|
||||
|
||||
/// 开始时间必须早于结束时间
|
||||
if (FormUtils.hasValue(pd, 'WORK_EXPECTED_END_TIME') &&
|
||||
!isBeforeStr(
|
||||
pd['WORK_EXPECTED_START_TIME'],
|
||||
pd['WORK_EXPECTED_END_TIME'],
|
||||
)) {
|
||||
pd['WORK_EXPECTED_END_TIME'] = '';
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
/// 预计作业结束时间
|
||||
Future<void> _chooseWorkEndTime() async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
context,
|
||||
minTimeStr: pd['WORK_EXPECTED_START_TIME'] ?? '',
|
||||
allowFuture: true,
|
||||
);
|
||||
if (picked != null) {
|
||||
setState(() {
|
||||
pd['WORK_EXPECTED_END_TIME'] = DateFormat(
|
||||
'yyyy-MM-dd HH:mm:ss',
|
||||
).format(picked);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// 选择经纬度
|
||||
Future<void> _showLocationHandle() async{
|
||||
if (!FormUtils.hasValue(pd, 'ELECTRONIC_FENCE_AREA_ID')) {
|
||||
|
@ -629,8 +593,6 @@ class _BreakgroundApplyDetailState extends State<BreakgroundApplyDetail> {
|
|||
onChooseLevel: _chooseLevel,
|
||||
// 新增
|
||||
onChooseVideoManager: _chooseVideoManager,
|
||||
onWorkStartTimeHandle: _chooseWorkStartTime,
|
||||
onWorkEndTimeHandle: _chooseWorkEndTime,
|
||||
onContractorHandle: _chooseUnitManager,
|
||||
onWorkAreaHandle: _getWorkArea,
|
||||
onWorkAreaLocationHandle: _showLocationHandle,
|
||||
|
|
|
@ -310,6 +310,7 @@ class _BreakgroundJszyDetailState extends State<BreakgroundJszyDetail> {
|
|||
),
|
||||
onTap: () async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
mode: BottomPickerMode.dateTimeWithSeconds,
|
||||
context,
|
||||
);
|
||||
if (picked != null) {
|
||||
|
|
|
@ -299,6 +299,7 @@ class _BreakgroundKszyDetailState extends State<BreakgroundKszyDetail> {
|
|||
),
|
||||
onTap: () async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
mode: BottomPickerMode.dateTimeWithSeconds,
|
||||
context,
|
||||
);
|
||||
if (picked != null) {
|
||||
|
|
|
@ -360,6 +360,7 @@ class _BreakgroundYsgdDetailState extends State<BreakgroundYsgdDetail> {
|
|||
),
|
||||
onTap: () async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
mode: BottomPickerMode.dateTimeWithSeconds,
|
||||
context,
|
||||
);
|
||||
if (picked != null) {
|
||||
|
|
|
@ -5,7 +5,8 @@ import 'package:qhd_prevention/customWidget/ItemWidgetFactory.dart';
|
|||
import 'package:qhd_prevention/customWidget/single_image_viewer.dart';
|
||||
import 'package:qhd_prevention/http/ApiService.dart';
|
||||
import 'package:qhd_prevention/tools/h_colors.dart';
|
||||
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:qhd_prevention/customWidget/picker/CupertinoDatePicker.dart';
|
||||
import '../../../../../../tools/tools.dart';
|
||||
import '../../../item_list_widget.dart';
|
||||
import '../../special_Wrok/MeasuresListWidget.dart';
|
||||
|
@ -25,11 +26,8 @@ class HoistWorkDetailFormWidget extends StatefulWidget {
|
|||
final TextEditingController? riskController;
|
||||
|
||||
// 新增
|
||||
final VoidCallback? onChooseVideoManager;
|
||||
/// 选择摄像头
|
||||
final VoidCallback? onWorkStartTimeHandle;
|
||||
final VoidCallback? onWorkEndTimeHandle;
|
||||
/// 承包商
|
||||
/// 选择摄像头
|
||||
final VoidCallback? onChooseVideoManager;/// 承包商
|
||||
final VoidCallback? onContractorHandle;
|
||||
/// 作业区域
|
||||
final VoidCallback? onWorkAreaHandle;
|
||||
|
@ -44,8 +42,6 @@ class HoistWorkDetailFormWidget extends StatefulWidget {
|
|||
required this.signs,
|
||||
/// 新增
|
||||
this.onChooseVideoManager,
|
||||
this.onWorkStartTimeHandle,
|
||||
this.onWorkEndTimeHandle,
|
||||
this.onContractorHandle,
|
||||
this.onWorkAreaHandle,
|
||||
this.onWorkAreaLocationHandle,
|
||||
|
@ -343,6 +339,7 @@ class _HoistworkDetailFormWidgetState extends State<HoistWorkDetailFormWidget> {
|
|||
],
|
||||
ItemListWidget.twoRowButtonTitleText(
|
||||
label: '关联其他特殊作业及安全作业票编号',
|
||||
isRequired: false,
|
||||
isEditable: widget.isEditable,
|
||||
onTap: () async {
|
||||
final val = await showDialog<String>(
|
||||
|
@ -408,14 +405,49 @@ class _HoistworkDetailFormWidgetState extends State<HoistWorkDetailFormWidget> {
|
|||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '预计作业开始时间:',
|
||||
isEditable: widget.isEditable,
|
||||
onTap: widget.onWorkStartTimeHandle ?? () {},
|
||||
onTap: () async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
mode: BottomPickerMode.dateTimeWithSeconds,
|
||||
context,
|
||||
allowFuture: true,
|
||||
);
|
||||
if (picked != null) {
|
||||
setState(() {
|
||||
pd['WORK_EXPECTED_START_TIME'] = DateFormat(
|
||||
'yyyy-MM-dd HH:mm:ss',
|
||||
).format(picked);
|
||||
|
||||
/// 开始时间必须早于结束时间
|
||||
if (FormUtils.hasValue(pd, 'WORK_EXPECTED_END_TIME') &&
|
||||
!isBeforeStr(
|
||||
pd['WORK_EXPECTED_START_TIME'],
|
||||
pd['WORK_EXPECTED_END_TIME'],
|
||||
)) {
|
||||
pd['WORK_EXPECTED_END_TIME'] = '';
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
text: pd['WORK_EXPECTED_START_TIME'] ?? '',
|
||||
),
|
||||
const Divider(),
|
||||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '预计作业结束时间:',
|
||||
isEditable: widget.isEditable,
|
||||
onTap: widget.onWorkEndTimeHandle ?? () {},
|
||||
onTap: () async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
context,
|
||||
minTimeStr: pd['WORK_EXPECTED_START_TIME'] ?? '',
|
||||
allowFuture: true,
|
||||
);
|
||||
if (picked != null) {
|
||||
setState(() {
|
||||
pd['WORK_EXPECTED_END_TIME'] = DateFormat(
|
||||
'yyyy-MM-dd HH:mm:ss',
|
||||
).format(picked);
|
||||
});
|
||||
}
|
||||
},
|
||||
text: pd['WORK_EXPECTED_END_TIME'] ?? '',
|
||||
),
|
||||
const Divider(),
|
||||
|
|
|
@ -179,44 +179,8 @@ class _HoistworkApplyDetailState extends State<HoistworkApplyDetail> {
|
|||
});
|
||||
}
|
||||
}
|
||||
/// 预计作业开始时间
|
||||
Future<void> _chooseWorkStartTime() async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
context,
|
||||
allowFuture: true,
|
||||
);
|
||||
if (picked != null) {
|
||||
setState(() {
|
||||
pd['WORK_EXPECTED_START_TIME'] = DateFormat(
|
||||
'yyyy-MM-dd HH:mm:ss',
|
||||
).format(picked);
|
||||
|
||||
/// 开始时间必须早于结束时间
|
||||
if (FormUtils.hasValue(pd, 'WORK_EXPECTED_END_TIME') &&
|
||||
!isBeforeStr(
|
||||
pd['WORK_EXPECTED_START_TIME'],
|
||||
pd['WORK_EXPECTED_END_TIME'],
|
||||
)) {
|
||||
pd['WORK_EXPECTED_END_TIME'] = '';
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
/// 预计作业结束时间
|
||||
Future<void> _chooseWorkEndTime() async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
context,
|
||||
minTimeStr: pd['WORK_EXPECTED_START_TIME'] ?? '',
|
||||
allowFuture: true,
|
||||
);
|
||||
if (picked != null) {
|
||||
setState(() {
|
||||
pd['WORK_EXPECTED_END_TIME'] = DateFormat(
|
||||
'yyyy-MM-dd HH:mm:ss',
|
||||
).format(picked);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// 选择经纬度
|
||||
Future<void> _showLocationHandle() async{
|
||||
if (!FormUtils.hasValue(pd, 'ELECTRONIC_FENCE_AREA_ID')) {
|
||||
|
@ -657,8 +621,6 @@ class _HoistworkApplyDetailState extends State<HoistworkApplyDetail> {
|
|||
onChooseLevel: _chooseLevel,
|
||||
// 新增
|
||||
onChooseVideoManager: _chooseVideoManager,
|
||||
onWorkStartTimeHandle: _chooseWorkStartTime,
|
||||
onWorkEndTimeHandle: _chooseWorkEndTime,
|
||||
onContractorHandle: _chooseUnitManager,
|
||||
onWorkAreaHandle: _getWorkArea,
|
||||
onWorkAreaLocationHandle: _showLocationHandle,
|
||||
|
|
|
@ -310,6 +310,7 @@ class _HoistworkJszyDetailState extends State<HoistworkJszyDetail> {
|
|||
),
|
||||
onTap: () async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
mode: BottomPickerMode.dateTimeWithSeconds,
|
||||
context,
|
||||
);
|
||||
if (picked != null) {
|
||||
|
|
|
@ -299,6 +299,7 @@ class _HoistworkKszyDetailState extends State<HoistworkKszyDetail> {
|
|||
),
|
||||
onTap: () async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
mode: BottomPickerMode.dateTimeWithSeconds,
|
||||
context,
|
||||
);
|
||||
if (picked != null) {
|
||||
|
|
|
@ -360,6 +360,7 @@ class _HoistworkYsgdDetailState extends State<HoistworkYsgdDetail> {
|
|||
),
|
||||
onTap: () async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
mode: BottomPickerMode.dateTimeWithSeconds,
|
||||
context,
|
||||
);
|
||||
if (picked != null) {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:qhd_prevention/customWidget/ItemWidgetFactory.dart';
|
||||
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:qhd_prevention/customWidget/picker/CupertinoDatePicker.dart';
|
||||
import '../../../../../../tools/tools.dart';
|
||||
import '../../../item_list_widget.dart';
|
||||
import '../../special_Wrok/MeasuresListWidget.dart';
|
||||
|
@ -11,11 +12,8 @@ class HighWorkDetailFormWidget extends StatefulWidget {
|
|||
final bool isEditable;
|
||||
final VoidCallback onChooseLevel;
|
||||
// 新增
|
||||
final VoidCallback? onChooseVideoManager;
|
||||
/// 选择摄像头
|
||||
final VoidCallback? onWorkStartTimeHandle;
|
||||
final VoidCallback? onWorkEndTimeHandle;
|
||||
/// 承包商
|
||||
/// 选择摄像头
|
||||
final VoidCallback? onChooseVideoManager;/// 承包商
|
||||
final VoidCallback? onContractorHandle;
|
||||
/// 作业区域
|
||||
final VoidCallback? onWorkAreaHandle;
|
||||
|
@ -36,8 +34,6 @@ class HighWorkDetailFormWidget extends StatefulWidget {
|
|||
required this.onChooseLevel,
|
||||
/// 新增
|
||||
this.onChooseVideoManager,
|
||||
this.onWorkStartTimeHandle,
|
||||
this.onWorkEndTimeHandle,
|
||||
this.onContractorHandle,
|
||||
this.onWorkAreaHandle,
|
||||
this.onWorkAreaLocationHandle,
|
||||
|
@ -132,6 +128,7 @@ class _HighWorkDetailFormWidgetState extends State<HighWorkDetailFormWidget> {
|
|||
const Divider(),
|
||||
ItemListWidget.twoRowButtonTitleText(
|
||||
label: '关联其他特殊作业及安全作业票编号',
|
||||
isRequired: false,
|
||||
isEditable: widget.isEditable,
|
||||
onTap: () async {
|
||||
final val = await showDialog<String>(
|
||||
|
@ -197,14 +194,49 @@ class _HighWorkDetailFormWidgetState extends State<HighWorkDetailFormWidget> {
|
|||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '预计作业开始时间:',
|
||||
isEditable: widget.isEditable,
|
||||
onTap: widget.onWorkStartTimeHandle ?? () {},
|
||||
onTap: () async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
mode: BottomPickerMode.dateTimeWithSeconds,
|
||||
context,
|
||||
allowFuture: true,
|
||||
);
|
||||
if (picked != null) {
|
||||
setState(() {
|
||||
pd['WORK_EXPECTED_START_TIME'] = DateFormat(
|
||||
'yyyy-MM-dd HH:mm:ss',
|
||||
).format(picked);
|
||||
|
||||
/// 开始时间必须早于结束时间
|
||||
if (FormUtils.hasValue(pd, 'WORK_EXPECTED_END_TIME') &&
|
||||
!isBeforeStr(
|
||||
pd['WORK_EXPECTED_START_TIME'],
|
||||
pd['WORK_EXPECTED_END_TIME'],
|
||||
)) {
|
||||
pd['WORK_EXPECTED_END_TIME'] = '';
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
text: pd['WORK_EXPECTED_START_TIME'] ?? '',
|
||||
),
|
||||
const Divider(),
|
||||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '预计作业结束时间:',
|
||||
isEditable: widget.isEditable,
|
||||
onTap: widget.onWorkEndTimeHandle ?? () {},
|
||||
onTap: () async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
context,
|
||||
minTimeStr: pd['WORK_EXPECTED_START_TIME'] ?? '',
|
||||
allowFuture: true,
|
||||
);
|
||||
if (picked != null) {
|
||||
setState(() {
|
||||
pd['WORK_EXPECTED_END_TIME'] = DateFormat(
|
||||
'yyyy-MM-dd HH:mm:ss',
|
||||
).format(picked);
|
||||
});
|
||||
}
|
||||
},
|
||||
text: pd['WORK_EXPECTED_END_TIME'] ?? '',
|
||||
),
|
||||
const Divider(),
|
||||
|
|
|
@ -173,44 +173,8 @@ class _HighworkApplyDetailState extends State<HighworkApplyDetail> {
|
|||
});
|
||||
}
|
||||
}
|
||||
/// 预计作业开始时间
|
||||
Future<void> _chooseWorkStartTime() async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
context,
|
||||
allowFuture: true,
|
||||
);
|
||||
if (picked != null) {
|
||||
setState(() {
|
||||
pd['WORK_EXPECTED_START_TIME'] = DateFormat(
|
||||
'yyyy-MM-dd HH:mm:ss',
|
||||
).format(picked);
|
||||
|
||||
/// 开始时间必须早于结束时间
|
||||
if (FormUtils.hasValue(pd, 'WORK_EXPECTED_END_TIME') &&
|
||||
!isBeforeStr(
|
||||
pd['WORK_EXPECTED_START_TIME'],
|
||||
pd['WORK_EXPECTED_END_TIME'],
|
||||
)) {
|
||||
pd['WORK_EXPECTED_END_TIME'] = '';
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
/// 预计作业结束时间
|
||||
Future<void> _chooseWorkEndTime() async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
context,
|
||||
minTimeStr: pd['WORK_EXPECTED_START_TIME'] ?? '',
|
||||
allowFuture: true,
|
||||
);
|
||||
if (picked != null) {
|
||||
setState(() {
|
||||
pd['WORK_EXPECTED_END_TIME'] = DateFormat(
|
||||
'yyyy-MM-dd HH:mm:ss',
|
||||
).format(picked);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// 选择经纬度
|
||||
Future<void> _showLocationHandle() async{
|
||||
if (!FormUtils.hasValue(pd, 'ELECTRONIC_FENCE_AREA_ID')) {
|
||||
|
@ -659,8 +623,6 @@ class _HighworkApplyDetailState extends State<HighworkApplyDetail> {
|
|||
onChooseLevel: _chooseLevel,
|
||||
// 新增
|
||||
onChooseVideoManager: _chooseVideoManager,
|
||||
onWorkStartTimeHandle: _chooseWorkStartTime,
|
||||
onWorkEndTimeHandle: _chooseWorkEndTime,
|
||||
onContractorHandle: _chooseUnitManager,
|
||||
onWorkAreaHandle: _getWorkArea,
|
||||
onWorkAreaLocationHandle: _showLocationHandle,
|
||||
|
|
|
@ -310,6 +310,7 @@ class _HighworkJszyDetailState extends State<HighworkJszyDetail> {
|
|||
),
|
||||
onTap: () async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
mode: BottomPickerMode.dateTimeWithSeconds,
|
||||
context,
|
||||
);
|
||||
if (picked != null) {
|
||||
|
|
|
@ -299,6 +299,7 @@ class _HighworkKszyDetailState extends State<HighworkKszyDetail> {
|
|||
),
|
||||
onTap: () async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
mode: BottomPickerMode.dateTimeWithSeconds,
|
||||
context,
|
||||
);
|
||||
if (picked != null) {
|
||||
|
|
|
@ -360,6 +360,7 @@ class _HighworkYsgdDetailState extends State<HighworkYsgdDetail> {
|
|||
),
|
||||
onTap: () async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
mode: BottomPickerMode.dateTimeWithSeconds,
|
||||
context,
|
||||
);
|
||||
if (picked != null) {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:qhd_prevention/customWidget/ItemWidgetFactory.dart';
|
||||
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:qhd_prevention/customWidget/picker/CupertinoDatePicker.dart';
|
||||
import '../../../../../../tools/tools.dart';
|
||||
import '../../../item_list_widget.dart';
|
||||
import '../../special_Wrok/MeasuresListWidget.dart';
|
||||
|
@ -13,11 +14,8 @@ class ElectricityDetailFormWidget extends StatefulWidget {
|
|||
final VoidCallback onChooseHotworkUser;
|
||||
final VoidCallback onAnalyzeTap;
|
||||
// 新增
|
||||
final VoidCallback? onChooseVideoManager;
|
||||
/// 选择摄像头
|
||||
final VoidCallback? onWorkStartTimeHandle;
|
||||
final VoidCallback? onWorkEndTimeHandle;
|
||||
/// 承包商
|
||||
/// 选择摄像头
|
||||
final VoidCallback? onChooseVideoManager;/// 承包商
|
||||
final VoidCallback? onContractorHandle;
|
||||
/// 作业区域
|
||||
final VoidCallback? onWorkAreaHandle;
|
||||
|
@ -43,8 +41,6 @@ class ElectricityDetailFormWidget extends StatefulWidget {
|
|||
|
||||
/// 新增
|
||||
this.onChooseVideoManager,
|
||||
this.onWorkStartTimeHandle,
|
||||
this.onWorkEndTimeHandle,
|
||||
this.onContractorHandle,
|
||||
this.onWorkAreaHandle,
|
||||
this.onWorkAreaLocationHandle,
|
||||
|
@ -199,6 +195,7 @@ class _ElectricityDetailFormWidgetState extends State<ElectricityDetailFormWidge
|
|||
|
||||
ItemListWidget.twoRowButtonTitleText(
|
||||
label: '关联其他特殊作业及安全作业票编号',
|
||||
isRequired: false,
|
||||
isEditable: widget.isEditable,
|
||||
onTap: () async {
|
||||
final val = await showDialog<String>(
|
||||
|
@ -265,14 +262,49 @@ class _ElectricityDetailFormWidgetState extends State<ElectricityDetailFormWidge
|
|||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '预计作业开始时间:',
|
||||
isEditable: widget.isEditable,
|
||||
onTap: widget.onWorkStartTimeHandle ?? () {},
|
||||
onTap: () async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
mode: BottomPickerMode.dateTimeWithSeconds,
|
||||
context,
|
||||
allowFuture: true,
|
||||
);
|
||||
if (picked != null) {
|
||||
setState(() {
|
||||
pd['WORK_EXPECTED_START_TIME'] = DateFormat(
|
||||
'yyyy-MM-dd HH:mm:ss',
|
||||
).format(picked);
|
||||
|
||||
/// 开始时间必须早于结束时间
|
||||
if (FormUtils.hasValue(pd, 'WORK_EXPECTED_END_TIME') &&
|
||||
!isBeforeStr(
|
||||
pd['WORK_EXPECTED_START_TIME'],
|
||||
pd['WORK_EXPECTED_END_TIME'],
|
||||
)) {
|
||||
pd['WORK_EXPECTED_END_TIME'] = '';
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
text: pd['WORK_EXPECTED_START_TIME'] ?? '',
|
||||
),
|
||||
const Divider(),
|
||||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '预计作业结束时间:',
|
||||
isEditable: widget.isEditable,
|
||||
onTap: widget.onWorkEndTimeHandle ?? () {},
|
||||
onTap: () async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
context,
|
||||
minTimeStr: pd['WORK_EXPECTED_START_TIME'] ?? '',
|
||||
allowFuture: true,
|
||||
);
|
||||
if (picked != null) {
|
||||
setState(() {
|
||||
pd['WORK_EXPECTED_END_TIME'] = DateFormat(
|
||||
'yyyy-MM-dd HH:mm:ss',
|
||||
).format(picked);
|
||||
});
|
||||
}
|
||||
},
|
||||
text: pd['WORK_EXPECTED_END_TIME'] ?? '',
|
||||
),
|
||||
const Divider(),
|
||||
|
|
|
@ -316,6 +316,7 @@ class _ElectricityJszyDetailState extends State<ElectricityJszyDetail> {
|
|||
),
|
||||
onTap: () async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
mode: BottomPickerMode.dateTimeWithSeconds,
|
||||
context,
|
||||
);
|
||||
if (picked != null) {
|
||||
|
|
|
@ -308,6 +308,7 @@ class _ElectricityKszyDetailState extends State<ElectricityKszyDetail> {
|
|||
),
|
||||
onTap: () async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
mode: BottomPickerMode.dateTimeWithSeconds,
|
||||
context,
|
||||
);
|
||||
if (picked != null) {
|
||||
|
|
|
@ -191,44 +191,8 @@ class _ElectricityApplyDetailState extends State<ElectricityApplyDetail> {
|
|||
});
|
||||
}
|
||||
}
|
||||
/// 预计作业开始时间
|
||||
Future<void> _chooseWorkStartTime() async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
context,
|
||||
allowFuture: true,
|
||||
);
|
||||
if (picked != null) {
|
||||
setState(() {
|
||||
pd['WORK_EXPECTED_START_TIME'] = DateFormat(
|
||||
'yyyy-MM-dd HH:mm:ss',
|
||||
).format(picked);
|
||||
|
||||
/// 开始时间必须早于结束时间
|
||||
if (FormUtils.hasValue(pd, 'WORK_EXPECTED_END_TIME') &&
|
||||
!isBeforeStr(
|
||||
pd['WORK_EXPECTED_START_TIME'],
|
||||
pd['WORK_EXPECTED_END_TIME'],
|
||||
)) {
|
||||
pd['WORK_EXPECTED_END_TIME'] = '';
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
/// 预计作业结束时间
|
||||
Future<void> _chooseWorkEndTime() async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
context,
|
||||
minTimeStr: pd['WORK_EXPECTED_START_TIME'] ?? '',
|
||||
allowFuture: true,
|
||||
);
|
||||
if (picked != null) {
|
||||
setState(() {
|
||||
pd['WORK_EXPECTED_END_TIME'] = DateFormat(
|
||||
'yyyy-MM-dd HH:mm:ss',
|
||||
).format(picked);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// 选择经纬度
|
||||
Future<void> _showLocationHandle() async{
|
||||
if (!FormUtils.hasValue(pd, 'ELECTRONIC_FENCE_AREA_ID')) {
|
||||
|
@ -670,8 +634,6 @@ class _ElectricityApplyDetailState extends State<ElectricityApplyDetail> {
|
|||
},
|
||||
// 新增
|
||||
onChooseVideoManager: _chooseVideoManager,
|
||||
onWorkStartTimeHandle: _chooseWorkStartTime,
|
||||
onWorkEndTimeHandle: _chooseWorkEndTime,
|
||||
onContractorHandle: _chooseUnitManager,
|
||||
onWorkAreaHandle: _getWorkArea,
|
||||
onWorkAreaLocationHandle: _showLocationHandle,
|
||||
|
|
|
@ -366,6 +366,7 @@ class _ElectricityYsgdDetailState extends State<ElectricityYsgdDetail> {
|
|||
),
|
||||
onTap: () async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
mode: BottomPickerMode.dateTimeWithSeconds,
|
||||
context,
|
||||
);
|
||||
if (picked != null) {
|
||||
|
|
|
@ -4,7 +4,8 @@ import 'package:flutter/material.dart';
|
|||
import 'package:qhd_prevention/customWidget/ItemWidgetFactory.dart';
|
||||
import 'package:qhd_prevention/customWidget/custom_button.dart';
|
||||
import 'package:qhd_prevention/customWidget/single_image_viewer.dart';
|
||||
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:qhd_prevention/customWidget/picker/CupertinoDatePicker.dart';
|
||||
import '../../../../../../tools/tools.dart';
|
||||
import '../../../item_list_widget.dart';
|
||||
import '../../special_Wrok/MeasuresListWidget.dart';
|
||||
|
@ -46,11 +47,8 @@ class BlindboardDetailFormWidget extends StatefulWidget {
|
|||
final bool isEditable;
|
||||
final VoidCallback onChooseLevel;
|
||||
// 新增
|
||||
final VoidCallback? onChooseVideoManager;
|
||||
/// 选择摄像头
|
||||
final VoidCallback? onWorkStartTimeHandle;
|
||||
final VoidCallback? onWorkEndTimeHandle;
|
||||
/// 承包商
|
||||
/// 选择摄像头
|
||||
final VoidCallback? onChooseVideoManager;/// 承包商
|
||||
final VoidCallback? onContractorHandle;
|
||||
/// 作业区域
|
||||
final VoidCallback? onWorkAreaHandle;
|
||||
|
@ -74,8 +72,6 @@ class BlindboardDetailFormWidget extends StatefulWidget {
|
|||
required this.boardList,
|
||||
/// 新增
|
||||
this.onChooseVideoManager,
|
||||
this.onWorkStartTimeHandle,
|
||||
this.onWorkEndTimeHandle,
|
||||
this.onContractorHandle,
|
||||
this.onWorkAreaHandle,
|
||||
this.onWorkAreaLocationHandle,
|
||||
|
@ -308,6 +304,7 @@ class _BlindboardDetailFormWidgetState
|
|||
],
|
||||
ItemListWidget.twoRowButtonTitleText(
|
||||
label: '关联其他特殊作业及安全作业票编号',
|
||||
isRequired: false,
|
||||
isEditable: widget.isEditable,
|
||||
onTap: () async {
|
||||
final val = await showDialog<String>(
|
||||
|
@ -375,14 +372,49 @@ class _BlindboardDetailFormWidgetState
|
|||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '预计作业开始时间:',
|
||||
isEditable: widget.isEditable,
|
||||
onTap: widget.onWorkStartTimeHandle ?? () {},
|
||||
onTap: () async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
mode: BottomPickerMode.dateTimeWithSeconds,
|
||||
context,
|
||||
allowFuture: true,
|
||||
);
|
||||
if (picked != null) {
|
||||
setState(() {
|
||||
pd['WORK_EXPECTED_START_TIME'] = DateFormat(
|
||||
'yyyy-MM-dd HH:mm:ss',
|
||||
).format(picked);
|
||||
|
||||
/// 开始时间必须早于结束时间
|
||||
if (FormUtils.hasValue(pd, 'WORK_EXPECTED_END_TIME') &&
|
||||
!isBeforeStr(
|
||||
pd['WORK_EXPECTED_START_TIME'],
|
||||
pd['WORK_EXPECTED_END_TIME'],
|
||||
)) {
|
||||
pd['WORK_EXPECTED_END_TIME'] = '';
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
text: pd['WORK_EXPECTED_START_TIME'] ?? '',
|
||||
),
|
||||
const Divider(),
|
||||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '预计作业结束时间:',
|
||||
isEditable: widget.isEditable,
|
||||
onTap: widget.onWorkEndTimeHandle ?? () {},
|
||||
onTap: () async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
context,
|
||||
minTimeStr: pd['WORK_EXPECTED_START_TIME'] ?? '',
|
||||
allowFuture: true,
|
||||
);
|
||||
if (picked != null) {
|
||||
setState(() {
|
||||
pd['WORK_EXPECTED_END_TIME'] = DateFormat(
|
||||
'yyyy-MM-dd HH:mm:ss',
|
||||
).format(picked);
|
||||
});
|
||||
}
|
||||
},
|
||||
text: pd['WORK_EXPECTED_END_TIME'] ?? '',
|
||||
),
|
||||
const Divider(),
|
||||
|
|
|
@ -313,6 +313,7 @@ class _BlindboardJszyDetailState extends State<BlindboardJszyDetail> {
|
|||
),
|
||||
onTap: () async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
mode: BottomPickerMode.dateTimeWithSeconds,
|
||||
context,
|
||||
);
|
||||
if (picked != null) {
|
||||
|
|
|
@ -302,6 +302,7 @@ class _BlindboardKszyDetailState extends State<BlindboardKszyDetail> {
|
|||
),
|
||||
onTap: () async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
mode: BottomPickerMode.dateTimeWithSeconds,
|
||||
context,
|
||||
);
|
||||
if (picked != null) {
|
||||
|
|
|
@ -181,44 +181,8 @@ class _BlindboardApplyDetailState extends State<BlindboardApplyDetail> {
|
|||
});
|
||||
}
|
||||
}
|
||||
/// 预计作业开始时间
|
||||
Future<void> _chooseWorkStartTime() async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
context,
|
||||
allowFuture: true,
|
||||
);
|
||||
if (picked != null) {
|
||||
setState(() {
|
||||
pd['WORK_EXPECTED_START_TIME'] = DateFormat(
|
||||
'yyyy-MM-dd HH:mm:ss',
|
||||
).format(picked);
|
||||
|
||||
/// 开始时间必须早于结束时间
|
||||
if (FormUtils.hasValue(pd, 'WORK_EXPECTED_END_TIME') &&
|
||||
!isBeforeStr(
|
||||
pd['WORK_EXPECTED_START_TIME'],
|
||||
pd['WORK_EXPECTED_END_TIME'],
|
||||
)) {
|
||||
pd['WORK_EXPECTED_END_TIME'] = '';
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
/// 预计作业结束时间
|
||||
Future<void> _chooseWorkEndTime() async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
context,
|
||||
minTimeStr: pd['WORK_EXPECTED_START_TIME'] ?? '',
|
||||
allowFuture: true,
|
||||
);
|
||||
if (picked != null) {
|
||||
setState(() {
|
||||
pd['WORK_EXPECTED_END_TIME'] = DateFormat(
|
||||
'yyyy-MM-dd HH:mm:ss',
|
||||
).format(picked);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// 选择经纬度
|
||||
Future<void> _showLocationHandle() async{
|
||||
if (!FormUtils.hasValue(pd, 'ELECTRONIC_FENCE_AREA_ID')) {
|
||||
|
@ -659,8 +623,6 @@ class _BlindboardApplyDetailState extends State<BlindboardApplyDetail> {
|
|||
onChooseLevel: _chooseLevel,
|
||||
// 新增
|
||||
onChooseVideoManager: _chooseVideoManager,
|
||||
onWorkStartTimeHandle: _chooseWorkStartTime,
|
||||
onWorkEndTimeHandle: _chooseWorkEndTime,
|
||||
onContractorHandle: _chooseUnitManager,
|
||||
onWorkAreaHandle: _getWorkArea,
|
||||
onWorkAreaLocationHandle: _showLocationHandle,
|
||||
|
|
|
@ -353,6 +353,7 @@ class _BlindboardYsgdDetailState extends State<BlindboardYsgdDetail> {
|
|||
),
|
||||
onTap: () async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
mode: BottomPickerMode.dateTimeWithSeconds,
|
||||
context,
|
||||
);
|
||||
if (picked != null) {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:qhd_prevention/customWidget/ItemWidgetFactory.dart';
|
||||
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:qhd_prevention/customWidget/picker/CupertinoDatePicker.dart';
|
||||
import '../../../../../../tools/tools.dart';
|
||||
import '../../../item_list_widget.dart';
|
||||
import '../../special_Wrok/MeasuresListWidget.dart';
|
||||
|
@ -14,11 +15,8 @@ class SpaceWorkDetailFormWidget extends StatefulWidget {
|
|||
final VoidCallback onChooseSpaceName;
|
||||
final VoidCallback onAnalyzeTap;
|
||||
// 新增
|
||||
final VoidCallback? onChooseVideoManager;
|
||||
/// 选择摄像头
|
||||
final VoidCallback? onWorkStartTimeHandle;
|
||||
final VoidCallback? onWorkEndTimeHandle;
|
||||
/// 承包商
|
||||
/// 选择摄像头
|
||||
final VoidCallback? onChooseVideoManager;/// 承包商
|
||||
final VoidCallback? onContractorHandle;
|
||||
/// 作业区域
|
||||
final VoidCallback? onWorkAreaHandle;
|
||||
|
@ -42,8 +40,6 @@ class SpaceWorkDetailFormWidget extends StatefulWidget {
|
|||
required this.onAnalyzeTap,
|
||||
/// 新增
|
||||
this.onChooseVideoManager,
|
||||
this.onWorkStartTimeHandle,
|
||||
this.onWorkEndTimeHandle,
|
||||
this.onContractorHandle,
|
||||
this.onWorkAreaHandle,
|
||||
this.onWorkAreaLocationHandle,
|
||||
|
@ -171,7 +167,6 @@ class _SpaceWorkDetailFormWidgetState extends State<SpaceWorkDetailFormWidget> {
|
|||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '作业开始时间:',
|
||||
isEditable: false,
|
||||
onTap: widget.onChooseLevel,
|
||||
text: pd['WORK_START_DATE'] ?? '',
|
||||
),
|
||||
],
|
||||
|
@ -180,13 +175,13 @@ class _SpaceWorkDetailFormWidgetState extends State<SpaceWorkDetailFormWidget> {
|
|||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '作业结束时间:',
|
||||
isEditable: false,
|
||||
onTap: widget.onChooseLevel,
|
||||
text: pd['WORK_END_DATE'] ?? '',
|
||||
),
|
||||
],
|
||||
const Divider(),
|
||||
ItemListWidget.twoRowButtonTitleText(
|
||||
label: '关联其他特殊作业及安全作业票编号',
|
||||
isRequired: false,
|
||||
isEditable: widget.isEditable,
|
||||
onTap: () async {
|
||||
final val = await showDialog<String>(
|
||||
|
@ -254,14 +249,49 @@ class _SpaceWorkDetailFormWidgetState extends State<SpaceWorkDetailFormWidget> {
|
|||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '预计作业开始时间:',
|
||||
isEditable: widget.isEditable,
|
||||
onTap: widget.onWorkStartTimeHandle ?? () {},
|
||||
onTap: () async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
mode: BottomPickerMode.dateTimeWithSeconds,
|
||||
context,
|
||||
allowFuture: true,
|
||||
);
|
||||
if (picked != null) {
|
||||
setState(() {
|
||||
pd['WORK_EXPECTED_START_TIME'] = DateFormat(
|
||||
'yyyy-MM-dd HH:mm:ss',
|
||||
).format(picked);
|
||||
|
||||
/// 开始时间必须早于结束时间
|
||||
if (FormUtils.hasValue(pd, 'WORK_EXPECTED_END_TIME') &&
|
||||
!isBeforeStr(
|
||||
pd['WORK_EXPECTED_START_TIME'],
|
||||
pd['WORK_EXPECTED_END_TIME'],
|
||||
)) {
|
||||
pd['WORK_EXPECTED_END_TIME'] = '';
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
text: pd['WORK_EXPECTED_START_TIME'] ?? '',
|
||||
),
|
||||
const Divider(),
|
||||
ItemListWidget.selectableLineTitleTextRightButton(
|
||||
label: '预计作业结束时间:',
|
||||
isEditable: widget.isEditable,
|
||||
onTap: widget.onWorkEndTimeHandle ?? () {},
|
||||
onTap: () async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
context,
|
||||
minTimeStr: pd['WORK_EXPECTED_START_TIME'] ?? '',
|
||||
allowFuture: true,
|
||||
);
|
||||
if (picked != null) {
|
||||
setState(() {
|
||||
pd['WORK_EXPECTED_END_TIME'] = DateFormat(
|
||||
'yyyy-MM-dd HH:mm:ss',
|
||||
).format(picked);
|
||||
});
|
||||
}
|
||||
},
|
||||
text: pd['WORK_EXPECTED_END_TIME'] ?? '',
|
||||
),
|
||||
const Divider(),
|
||||
|
|
|
@ -320,6 +320,7 @@ class _SpaceworkJszyDetailState extends State<SpaceworkJszyDetail> {
|
|||
),
|
||||
onTap: () async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
mode: BottomPickerMode.dateTimeWithSeconds,
|
||||
context,
|
||||
);
|
||||
if (picked != null) {
|
||||
|
|
|
@ -313,6 +313,7 @@ class _SpaceworkKszyDetailState extends State<SpaceworkKszyDetail> {
|
|||
),
|
||||
onTap: () async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
mode: BottomPickerMode.dateTimeWithSeconds,
|
||||
context,
|
||||
);
|
||||
if (picked != null) {
|
||||
|
|
|
@ -186,45 +186,9 @@ class _SpaceworkApplyDetailState extends State<SpaceworkApplyDetail> {
|
|||
}
|
||||
}
|
||||
|
||||
/// 预计作业开始时间
|
||||
Future<void> _chooseWorkStartTime() async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
context,
|
||||
allowFuture: true,
|
||||
);
|
||||
if (picked != null) {
|
||||
setState(() {
|
||||
pd['WORK_EXPECTED_START_TIME'] = DateFormat(
|
||||
'yyyy-MM-dd HH:mm:ss',
|
||||
).format(picked);
|
||||
|
||||
/// 开始时间必须早于结束时间
|
||||
if (FormUtils.hasValue(pd, 'WORK_EXPECTED_END_TIME') &&
|
||||
!isBeforeStr(
|
||||
pd['WORK_EXPECTED_START_TIME'],
|
||||
pd['WORK_EXPECTED_END_TIME'],
|
||||
)) {
|
||||
pd['WORK_EXPECTED_END_TIME'] = '';
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// 预计作业结束时间
|
||||
Future<void> _chooseWorkEndTime() async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
context,
|
||||
minTimeStr: pd['WORK_EXPECTED_START_TIME'] ?? '',
|
||||
allowFuture: true,
|
||||
);
|
||||
if (picked != null) {
|
||||
setState(() {
|
||||
pd['WORK_EXPECTED_END_TIME'] = DateFormat(
|
||||
'yyyy-MM-dd HH:mm:ss',
|
||||
).format(picked);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// 选择经纬度
|
||||
Future<void> _showLocationHandle() async {
|
||||
|
@ -665,8 +629,6 @@ class _SpaceworkApplyDetailState extends State<SpaceworkApplyDetail> {
|
|||
onAnalyzeTap: () {},
|
||||
// 新增
|
||||
onChooseVideoManager: _chooseVideoManager,
|
||||
onWorkStartTimeHandle: _chooseWorkStartTime,
|
||||
onWorkEndTimeHandle: _chooseWorkEndTime,
|
||||
onContractorHandle: _chooseUnitManager,
|
||||
onWorkAreaHandle: _getWorkArea,
|
||||
onWorkAreaLocationHandle: _showLocationHandle,
|
||||
|
|
|
@ -370,6 +370,7 @@ class _SpaceworkYsgdDetailState extends State<SpaceworkYsgdDetail> {
|
|||
),
|
||||
onTap: () async {
|
||||
DateTime? picked = await BottomDateTimePicker.showDate(
|
||||
mode: BottomPickerMode.dateTimeWithSeconds,
|
||||
context,
|
||||
);
|
||||
if (picked != null) {
|
||||
|
|
|
@ -214,7 +214,7 @@ class _MinePageState extends State<MinePage> {
|
|||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(text, style: TextStyle(fontSize: 16),),
|
||||
Text(text, style: TextStyle(fontSize: 14),),
|
||||
Icon(Icons.chevron_right)
|
||||
],
|
||||
),
|
||||
|
|
|
@ -6,6 +6,7 @@ import 'dart:ui' as ui;
|
|||
import 'package:flutter/services.dart';
|
||||
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:qhd_prevention/tools/tools.dart';
|
||||
|
||||
class MineSignPage extends StatelessWidget {
|
||||
const MineSignPage({super.key});
|
||||
|
@ -95,6 +96,7 @@ class _SignatureConfirmPageState extends State<SignatureConfirmPage> {
|
|||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
NativeOrientation.setLandscape();
|
||||
SystemChrome.setPreferredOrientations([
|
||||
DeviceOrientation.landscapeRight,
|
||||
DeviceOrientation.landscapeLeft,
|
||||
|
@ -106,8 +108,9 @@ class _SignatureConfirmPageState extends State<SignatureConfirmPage> {
|
|||
// 不要忘记重置方向设置,以避免影响其他页面或应用。
|
||||
SystemChrome.setPreferredOrientations([
|
||||
DeviceOrientation.portraitUp,
|
||||
|
||||
]);
|
||||
NativeOrientation.setPortrait();
|
||||
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue