chore: release v1.0.18
Deploy / build-linux-web (push) Successful in 53s
Deploy / build-windows (push) Successful in 1m48s
Deploy / build-macos (push) Successful in 1m17s
Deploy / build-android (push) Successful in 4m13s
Deploy / build-ios (push) Successful in 9s
Deploy / release-deploy (push) Successful in 1m37s

移动端响应式适配(抽屉导航/列表卡片/弹窗自适应)、Android 正式签名与 APK 发布、
iOS(TestFlight) 工程与 CI、多平台构建流水线、相关文档同步。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
wangjia
2026-06-07 07:55:33 +08:00
parent 94f0fb2095
commit 480ce836bb
81 changed files with 3096 additions and 366 deletions
@@ -1,9 +1,11 @@
import '../../core/utils/dialog_util.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../core/responsive/responsive.dart';
import '../../core/theme/app_theme.dart';
import '../../providers/product_option_provider.dart';
import '../../widgets/data_table_card.dart';
import '../../widgets/mobile_list_card.dart';
import '../../widgets/page_scaffold.dart';
import '../../core/utils/export_util.dart';
@@ -84,6 +86,23 @@ class _ProductsScreenState extends ConsumerState<ProductsScreen> {
rows: items.map((it) => [it.code ?? '', it.name, it.remark ?? '']).toList(),
),
),
mobileCards: paged
.map((it) => _optionCard(
code: it.code,
name: it.name,
remark: it.remark,
onEdit: () => _showOptionDialog(
title: '编辑商品名称',
hasQuantity: false,
initial: {'code': it.code ?? '', 'name': it.name, 'remark': it.remark ?? ''},
onSave: (data) => ref.read(productNameListProvider.notifier).updateItem(it.id, data),
),
onDelete: () => _confirmDelete(
'删除名称「${it.name}」?',
() => ref.read(productNameListProvider.notifier).delete(it.id),
),
))
.toList(),
columns: const [
DataColumn(label: Text('编号')),
DataColumn(label: Text('名称')),
@@ -156,6 +175,23 @@ class _ProductsScreenState extends ConsumerState<ProductsScreen> {
rows: items.map((it) => [it.code ?? '', it.name, it.remark ?? '']).toList(),
),
),
mobileCards: paged
.map((it) => _optionCard(
code: it.code,
name: it.name,
remark: it.remark,
onEdit: () => _showOptionDialog(
title: '编辑系列',
hasQuantity: false,
initial: {'code': it.code ?? '', 'name': it.name, 'remark': it.remark ?? ''},
onSave: (data) => ref.read(productSeriesListProvider.notifier).updateItem(it.id, data),
),
onDelete: () => _confirmDelete(
'删除系列「${it.name}」?',
() => ref.read(productSeriesListProvider.notifier).delete(it.id),
),
))
.toList(),
columns: const [
DataColumn(label: Text('编号')),
DataColumn(label: Text('系列名称')),
@@ -228,6 +264,24 @@ class _ProductsScreenState extends ConsumerState<ProductsScreen> {
rows: items.map((it) => [it.code ?? '', it.name, it.quantity, it.remark ?? '']).toList(),
),
),
mobileCards: paged
.map((it) => _optionCard(
code: it.code,
name: it.name,
remark: it.remark,
quantity: it.quantity,
onEdit: () => _showOptionDialog(
title: '编辑规格',
hasQuantity: true,
initial: {'code': it.code ?? '', 'name': it.name, 'quantity': it.quantity, 'remark': it.remark ?? ''},
onSave: (data) => ref.read(productSpecListProvider.notifier).updateItem(it.id, data),
),
onDelete: () => _confirmDelete(
'删除规格「${it.name}」?',
() => ref.read(productSpecListProvider.notifier).delete(it.id),
),
))
.toList(),
columns: const [
DataColumn(label: Text('编号')),
DataColumn(label: Text('规格名称')),
@@ -321,6 +375,37 @@ class _ProductsScreenState extends ConsumerState<ProductsScreen> {
);
}
/// 基础数据:窄屏卡片
Widget _optionCard({
required String? code,
required String name,
required String? remark,
int? quantity,
required VoidCallback onEdit,
required VoidCallback onDelete,
}) {
return MobileListCard(
title: Text(name),
subtitle: (code?.isNotEmpty == true) ? Text(code!) : null,
fields: [
if (quantity != null && quantity > 0)
MobileCardField('单品数量', '$quantity'),
if (remark?.isNotEmpty == true) MobileCardField('备注', remark),
],
actions: [
TextButton(
onPressed: onEdit,
child: const Text('编辑', style: TextStyle(fontSize: 13)),
),
TextButton(
onPressed: onDelete,
child: const Text('删除',
style: TextStyle(fontSize: 13, color: AppTheme.danger)),
),
],
);
}
Widget _actionButtons({required VoidCallback onEdit, required VoidCallback onDelete}) {
return Row(
mainAxisSize: MainAxisSize.min,
@@ -386,7 +471,7 @@ class _ProductsScreenState extends ConsumerState<ProductsScreen> {
builder: (ctx) => AlertDialog(
title: Text(title),
content: SizedBox(
width: 360,
width: context.dialogWidth(360),
child: Form(
key: formKey,
child: Column(