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:
wangjia
2026-07-03 09:58:14 +08:00
parent ca7595b113
commit 6238b86dcb
286 changed files with 16831 additions and 11136 deletions
+35 -63
View File
@@ -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'),
),
],
),