feat(client): 登录/注册页照原型重建,ds 真相源组件族统一全部屏
- 登录/注册(login.html/register.html 1:1):两栏卡片+品牌渐变面板+主题小衣服 pill(onSurface 变体)+记住我(记录并预填最近账号)+原型式 toast 校验; 登录 fidelity 1.4–2.1% 三主题全绿;注册暂不入闸(少 门店编号/兑换券 字段, 已记 CONTRACT,screens.mjs 留存根) - ds 原子补齐:DsToast(.toast 单例)/DsCheck(.check/.agree)/DsButton lg 档/ DsSelect 替换全部旧 DropdownButton/DsField label 在上/DsInput 后缀与密码形态 - 全屏统一:对话框按钮全 DsButton、盒式输入主题钉死(visualDensity.standard、 h38、InputDecorationTheme 渗漏修复)、图标全 lucide、JetBrains Mono 三端同源、 BrandMark 真相源 logo、只读模式写操作全量守卫(WriteGuard+DsToast) - 出入库列表:版式对齐原型(卡片对齐+搜索框居中)、KPI 近30天滚动、结清后 失效财务应收应付表;商品编辑抽屉介绍库改搜索下拉、图片双击全屏预览 - 删除旧 UI 死代码:DataTableCard/FormDialog/PageScaffold/SearchChip/ SelectProductDialog/tabStateProvider - golden/fidelity:stock-in/out 补注册(9%)、login 入册(8%)、goldens 全量重打; 修复 pubspec flutter_web_plugins 非法声明(CI pub get 阻断) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JJ1g8XV1YhhmHRzhwWEW7o
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import 'package:lucide_icons_flutter/lucide_icons.dart';
|
||||
import 'dart:typed_data';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
@@ -5,7 +6,7 @@ import '../core/errors/error_reporter.dart';
|
||||
import '../core/theme/context_tokens.dart';
|
||||
import '../core/responsive/responsive.dart';
|
||||
import '../core/utils/print_util.dart';
|
||||
import '../core/utils/label_data.dart';
|
||||
import 'ds/ds_atoms.dart';
|
||||
|
||||
const _kPrinterKey = 'label_printer';
|
||||
|
||||
@@ -42,8 +43,8 @@ class _LabelPreviewDialogState extends State<LabelPreviewDialog> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_previews = List<Uint8List?>.filled(widget.labels.length, null,
|
||||
growable: false);
|
||||
_previews =
|
||||
List<Uint8List?>.filled(widget.labels.length, null, growable: false);
|
||||
_include = List<bool>.filled(widget.labels.length, true, growable: false);
|
||||
_init();
|
||||
}
|
||||
@@ -203,11 +204,9 @@ class _LabelPreviewDialogState extends State<LabelPreviewDialog> {
|
||||
'${i + 1}',
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: isSelected
|
||||
? context.tokens.primary
|
||||
: context.tokens.muted,
|
||||
fontWeight:
|
||||
isSelected ? FontWeight.w600 : FontWeight.normal,
|
||||
color:
|
||||
isSelected ? context.tokens.primary : context.tokens.muted,
|
||||
fontWeight: isSelected ? FontWeight.w600 : FontWeight.normal,
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -230,7 +229,7 @@ class _LabelPreviewDialogState extends State<LabelPreviewDialog> {
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(color: context.tokens.border),
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
color: Colors.white,
|
||||
color: Colors.white, // ds-ignore: 打印纸面模拟固定色
|
||||
),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(3),
|
||||
@@ -248,7 +247,7 @@ class _LabelPreviewDialogState extends State<LabelPreviewDialog> {
|
||||
children: [
|
||||
const Text('打印份数:', style: TextStyle(fontSize: 13)),
|
||||
IconButton(
|
||||
icon: const Icon(Icons.remove_circle_outline, size: 20),
|
||||
icon: const Icon(LucideIcons.circleMinus, size: 20),
|
||||
onPressed: (_printing || label.copies <= 1)
|
||||
? null
|
||||
: () => setState(() => label.copies--),
|
||||
@@ -261,13 +260,13 @@ class _LabelPreviewDialogState extends State<LabelPreviewDialog> {
|
||||
child: Text(
|
||||
'${label.copies}',
|
||||
textAlign: TextAlign.center,
|
||||
style: const TextStyle(
|
||||
fontSize: 15, fontWeight: FontWeight.w600),
|
||||
style:
|
||||
const TextStyle(fontSize: 15, fontWeight: FontWeight.w600),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
IconButton(
|
||||
icon: const Icon(Icons.add_circle_outline, size: 20),
|
||||
icon: const Icon(LucideIcons.circlePlus, size: 20),
|
||||
onPressed:
|
||||
_printing ? null : () => setState(() => label.copies++),
|
||||
padding: EdgeInsets.zero,
|
||||
@@ -295,8 +294,7 @@ class _LabelPreviewDialogState extends State<LabelPreviewDialog> {
|
||||
children: [
|
||||
// ── 顶栏 ──────────────────────────────────────────────────────────
|
||||
Container(
|
||||
padding:
|
||||
const EdgeInsets.symmetric(horizontal: 20, vertical: 14),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 14),
|
||||
decoration: BoxDecoration(
|
||||
color: context.tokens.primary,
|
||||
borderRadius: const BorderRadius.only(
|
||||
@@ -310,10 +308,11 @@ class _LabelPreviewDialogState extends State<LabelPreviewDialog> {
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.white)),
|
||||
color: Colors.white)), // ds-ignore: 打印纸面模拟固定色
|
||||
const Spacer(),
|
||||
IconButton(
|
||||
icon: const Icon(Icons.close, color: Colors.white),
|
||||
icon: const Icon(LucideIcons.x,
|
||||
color: Colors.white), // ds-ignore: 打印纸面模拟固定色
|
||||
onPressed: () => Navigator.of(context).pop(),
|
||||
padding: EdgeInsets.zero,
|
||||
constraints: const BoxConstraints(),
|
||||
@@ -327,51 +326,24 @@ class _LabelPreviewDialogState extends State<LabelPreviewDialog> {
|
||||
padding: const EdgeInsets.fromLTRB(16, 12, 16, 0),
|
||||
child: Row(
|
||||
children: [
|
||||
const Text('打印机:',
|
||||
style: TextStyle(fontSize: 13)),
|
||||
const Text('打印机:', style: TextStyle(fontSize: 13)),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(
|
||||
child: _printers.isEmpty
|
||||
? Text(
|
||||
_printersChecked ? '无打印机可用' : '正在检测打印机...',
|
||||
? Text(_printersChecked ? '无打印机可用' : '正在检测打印机...',
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: context.tokens.muted))
|
||||
: DropdownButtonHideUnderline(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 10, vertical: 4),
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(color: context.tokens.border),
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
),
|
||||
child: DropdownButton<String>(
|
||||
value: _printer,
|
||||
isExpanded: true,
|
||||
isDense: true,
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: context.tokens.text),
|
||||
items: _printers
|
||||
.map((p) => DropdownMenuItem(
|
||||
value: p,
|
||||
child: Text(p,
|
||||
overflow:
|
||||
TextOverflow.ellipsis),
|
||||
))
|
||||
.toList(),
|
||||
onChanged: _printing
|
||||
? null
|
||||
: (v) async {
|
||||
if (v == null) return;
|
||||
setState(() => _printer = v);
|
||||
final prefs = await SharedPreferences
|
||||
.getInstance();
|
||||
await prefs.setString(
|
||||
_kPrinterKey, v);
|
||||
},
|
||||
),
|
||||
),
|
||||
fontSize: 13, color: context.tokens.muted))
|
||||
: DsSelect<String>(
|
||||
value: _printer,
|
||||
options: [for (final p in _printers) (p, p)],
|
||||
onChanged: _printing
|
||||
? null
|
||||
: (v) async {
|
||||
setState(() => _printer = v);
|
||||
final prefs =
|
||||
await SharedPreferences.getInstance();
|
||||
await prefs.setString(_kPrinterKey, v);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -423,11 +395,11 @@ class _LabelPreviewDialogState extends State<LabelPreviewDialog> {
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
FilledButton(
|
||||
onPressed: (_printing || totalCount == 0 || _printer == null)
|
||||
? null
|
||||
: _doPrint,
|
||||
child: Text(
|
||||
_printing ? '打印中...' : '打印 $totalCount 张'),
|
||||
onPressed:
|
||||
(_printing || totalCount == 0 || _printer == null)
|
||||
? null
|
||||
: _doPrint,
|
||||
child: Text(_printing ? '打印中...' : '打印 $totalCount 张'),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user