Files
jiu/client/lib/widgets/wheel_date_picker.dart
T
wangjia a3a722689e feat(client): 出入库列表按原型重建(KPI/详情抽屉/详细搜索/工具栏/选中复制/窗口尺寸)
- 列表重建:KPI 卡、状态+时间列、操作改眼睛开右侧详情抽屉、重置右置
- 详情抽屉(order_detail_drawer) 100% 还原原型 + SelectionArea 可选中复制
- 详细搜索弹窗:ComboSearchField/滚轮日期、字段重构、白底盒子按钮
- 工具栏:搜索框×清除+占位精简、供应商/客户下拉取全部、状态菜单收窄
- 加载不白屏(半透明遮罩)、输入框与下拉等高、windows/macOS 默认窗口尺寸调大

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 08:48:01 +08:00

134 lines
4.6 KiB
Dart

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import '../core/theme/context_tokens.dart';
import '../core/theme/app_dims.g.dart';
import '../core/responsive/responsive.dart';
import '../core/utils/dialog_util.dart';
/// 年/月/日 滚轮日期选择器(对齐原型 .wheel-pop)。选中返回 DateTime,取消返回 null。
/// 「今天」快速跳到今天;「确定」确认。范围选择由调用方调两次(起/止)拼成。
Future<DateTime?> showWheelDatePicker(
BuildContext context, {
DateTime? initial,
String title = '选择日期',
}) {
return showAppDialog<DateTime>(
context: context,
builder: (_) => _WheelDateDialog(initial: initial ?? DateTime.now(), title: title),
);
}
class _WheelDateDialog extends StatefulWidget {
final DateTime initial;
final String title;
const _WheelDateDialog({required this.initial, required this.title});
@override
State<_WheelDateDialog> createState() => _WheelDateDialogState();
}
class _WheelDateDialogState extends State<_WheelDateDialog> {
late DateTime _value;
@override
void initState() {
super.initState();
_value = DateTime(widget.initial.year, widget.initial.month, widget.initial.day);
}
@override
Widget build(BuildContext context) {
final t = context.tokens;
return Dialog(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(AppDims.rXl)),
child: SizedBox(
width: context.dialogWidth(320),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Padding(
padding: const EdgeInsets.fromLTRB(16, 14, 16, 4),
child: Row(
children: [
Text(widget.title,
style: TextStyle(
fontSize: AppDims.fsTitle,
fontWeight: FontWeight.w600,
color: t.heading)),
],
),
),
// 三列滚轮(年/月/日),中间高亮行由 CupertinoDatePicker 提供。
SizedBox(
height: 200,
child: CupertinoTheme(
data: CupertinoThemeData(
textTheme: CupertinoTextThemeData(
dateTimePickerTextStyle: TextStyle(fontSize: 18, color: t.text),
),
),
child: CupertinoDatePicker(
mode: CupertinoDatePickerMode.date,
initialDateTime: _value,
minimumYear: 2015,
maximumYear: 2035,
onDateTimeChanged: (d) =>
_value = DateTime(d.year, d.month, d.day),
),
),
),
const Divider(height: 1),
Padding(
padding: const EdgeInsets.fromLTRB(12, 8, 12, 10),
child: Row(
children: [
TextButton(
onPressed: () {
final now = DateTime.now();
setState(() => _value = DateTime(now.year, now.month, now.day));
},
child: Text('今天', style: TextStyle(color: t.muted)),
),
const Spacer(),
TextButton(
onPressed: () => Navigator.of(context).pop(),
child: Text('取消', style: TextStyle(color: t.muted)),
),
const SizedBox(width: 4),
ElevatedButton(
onPressed: () => Navigator.of(context).pop(_value),
style: ElevatedButton.styleFrom(
backgroundColor: t.primary,
foregroundColor: t.onPrimary,
elevation: 0,
),
child: const Text('确定'),
),
],
),
),
],
),
),
);
}
}
/// 范围选择:先选起始日、再选结束日;任一取消则返回 null。
Future<DateTimeRange?> showWheelDateRange(
BuildContext context, {
DateTimeRange? initial,
}) async {
final start = await showWheelDatePicker(context,
initial: initial?.start, title: '起始日期');
if (start == null || !context.mounted) return null;
final end = await showWheelDatePicker(context,
initial: initial?.end ?? start, title: '结束日期');
if (end == null) return null;
// 保证 start <= end
return end.isBefore(start)
? DateTimeRange(start: end, end: start)
: DateTimeRange(start: start, end: end);
}