feat:回退版本报错的问题
This commit is contained in:
1 parent
383ea2ad4b
commit
2d6603dfd5
10 files changed
+424
-241
No files matched your search
@@ -7,7 +7,7 @@ flutter pub run build_runner build --delete-conflicting-outputs~
|
||||
## flutter打包
|
||||
|
||||
```
|
||||
flutter build apk --build-name 1.5.0 --build-number 150
|
||||
flutter build apk --build-name 1.5.1 --build-number 151
|
||||
--build-name为版本号(展示)
|
||||
--build-number为版本号(内部比较)
|
||||
```
|
||||
|
||||
@@ -413,9 +413,15 @@ abstract class DatabaseMigration {
|
||||
/// 版本14为打印任务补充后端指令流列,指令打印模式可离线重试且不改变出纸内容。
|
||||
///
|
||||
/// 列可空且不回填:旧任务与旧后端无指令,指令模式下回退 invoiceUrl 图片打印。
|
||||
/// 外部存储旧库可能已带该列(中间态构建建库、降级重建),重复 ALTER 会中断启动,
|
||||
/// 因此先查列再添加,保证跨版本安装可重入。
|
||||
static Migration migration13To14 = Migration(13, 14, (database) async {
|
||||
await database
|
||||
.execute('ALTER TABLE print_history ADD COLUMN printCmd TEXT');
|
||||
final columns = await database.rawQuery('PRAGMA table_info(print_history)');
|
||||
final hasPrintCmd = columns.any((column) => column['name'] == 'printCmd');
|
||||
if (!hasPrintCmd) {
|
||||
await database
|
||||
.execute('ALTER TABLE print_history ADD COLUMN printCmd TEXT');
|
||||
}
|
||||
});
|
||||
|
||||
/// 按起始版本升序返回全部迁移,Floor 打开旧数据库时据此连续升级到当前版本。
|
||||
|
||||
@@ -15,8 +15,8 @@ class Constants {
|
||||
static const pwdEncKey = 'pigxpigxpigxpigx';
|
||||
|
||||
/// 服务 url 线上
|
||||
static const apiUrl = 'https://dzc-test-1.fy.takin.cc';
|
||||
// static const apiUrl = 'https://www.zianxin.com/api';
|
||||
// static const apiUrl = 'https://dzc-test-1.fy.takin.cc';
|
||||
static const apiUrl = 'https://www.zianxin.com/api';
|
||||
|
||||
// static const apiUrl = 'https://dzc-test-1.fy.takin.cc';
|
||||
|
||||
|
||||
@@ -1686,7 +1686,7 @@ class _CheckoutCartItemSummary extends StatelessWidget {
|
||||
/// 套餐展开/收起回调;其热区与右侧数量步进器相互独立。
|
||||
final VoidCallback? onComboToggle;
|
||||
|
||||
/// 构建固定图片、商品信息和右对齐小计金额。
|
||||
/// 构建整行名称、固定图片、商品信息和右对齐小计金额。
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = FTheme.of(context);
|
||||
@@ -1697,6 +1697,30 @@ class _CheckoutCartItemSummary extends StatelessWidget {
|
||||
: 'x${item.productNumber}';
|
||||
final stockText = item.stock == null ? '库存未知' : '库存 ${item.stock}';
|
||||
final stockUnavailable = item.stock == 0;
|
||||
// 名称+类型标签独占卡片一整行(左缘到右缘),不再与图片、步进器同行
|
||||
// 抢宽度;超长名称等比缩小兜底(与食堂商品卡一致),保证永远单行。
|
||||
final nameRow = <Widget>[
|
||||
LayoutBuilder(
|
||||
builder: (context, constraints) => FittedBox(
|
||||
fit: BoxFit.scaleDown,
|
||||
alignment: Alignment.centerLeft,
|
||||
child: SizedBox(
|
||||
width: constraints.maxWidth,
|
||||
child: Text(
|
||||
item.productName,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: theme.typography.base.copyWith(
|
||||
color: XfjDesignTokens.ink,
|
||||
fontWeight: FontWeight.w700,
|
||||
height: 1.3,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
).expanded(),
|
||||
ProductTypeTag(isCombo: combo),
|
||||
].toRowSpace(space: 8.w);
|
||||
final productDetails = <Widget>[
|
||||
_CheckoutProductImage(
|
||||
key: ValueKey(
|
||||
@@ -1708,20 +1732,6 @@ class _CheckoutCartItemSummary extends StatelessWidget {
|
||||
height: 64.h,
|
||||
),
|
||||
<Widget>[
|
||||
<Widget>[
|
||||
Text(
|
||||
item.productName,
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: theme.typography.base.copyWith(
|
||||
color: XfjDesignTokens.ink,
|
||||
fontWeight: FontWeight.w700,
|
||||
height: 1.3,
|
||||
),
|
||||
).expanded(),
|
||||
ProductTypeTag(isCombo: combo),
|
||||
].toRowSpace(space: 8.w),
|
||||
SizedBox(height: 7.h),
|
||||
<Widget>[
|
||||
Text(
|
||||
'单价 ${_paymentMoney(item.productPrice)}',
|
||||
@@ -1822,16 +1832,43 @@ class _CheckoutCartItemSummary extends StatelessWidget {
|
||||
),
|
||||
);
|
||||
return <Widget>[
|
||||
productDetailsAction.expanded(),
|
||||
if (editable)
|
||||
<Widget>[
|
||||
_CheckoutQuantityStepper(
|
||||
controller: controller,
|
||||
item: item,
|
||||
updating: updating,
|
||||
onChanged: (value) => onQuantityChanged!(item, value),
|
||||
pendingQuantity: pendingQuantity,
|
||||
),
|
||||
nameRow,
|
||||
SizedBox(height: 7.h),
|
||||
<Widget>[
|
||||
productDetailsAction.expanded(),
|
||||
if (editable)
|
||||
<Widget>[
|
||||
_CheckoutQuantityStepper(
|
||||
controller: controller,
|
||||
item: item,
|
||||
updating: updating,
|
||||
onChanged: (value) => onQuantityChanged!(item, value),
|
||||
pendingQuantity: pendingQuantity,
|
||||
),
|
||||
<Widget>[
|
||||
Text(
|
||||
_paymentMoney(item.totalPrice),
|
||||
key: ValueKey(
|
||||
'checkout-item-total-${item.productServiceUniqueCode}',
|
||||
),
|
||||
textAlign: TextAlign.right,
|
||||
style: theme.typography.base.copyWith(
|
||||
color: XfjDesignTokens.ink,
|
||||
fontWeight: FontWeight.w800,
|
||||
fontFeatures: const [FontFeature.tabularFigures()],
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'商品小计',
|
||||
style: theme.typography.xs.copyWith(
|
||||
color: XfjDesignTokens.muted,
|
||||
),
|
||||
),
|
||||
].toColumn(crossAxisAlignment: CrossAxisAlignment.end).width(
|
||||
88.w < 88 ? 88 : 88.w,
|
||||
),
|
||||
].toRowSpace(space: 8.w).width(240.w < 240 ? 240 : 240.w)
|
||||
else
|
||||
<Widget>[
|
||||
Text(
|
||||
_paymentMoney(item.totalPrice),
|
||||
@@ -1847,35 +1884,12 @@ class _CheckoutCartItemSummary extends StatelessWidget {
|
||||
),
|
||||
Text(
|
||||
'商品小计',
|
||||
style: theme.typography.xs.copyWith(
|
||||
color: XfjDesignTokens.muted,
|
||||
),
|
||||
style: theme.typography.xs.copyWith(color: XfjDesignTokens.muted),
|
||||
),
|
||||
].toColumn(crossAxisAlignment: CrossAxisAlignment.end).width(
|
||||
88.w < 88 ? 88 : 88.w,
|
||||
),
|
||||
].toRowSpace(space: 8.w).width(240.w < 240 ? 240 : 240.w)
|
||||
else
|
||||
<Widget>[
|
||||
Text(
|
||||
_paymentMoney(item.totalPrice),
|
||||
key: ValueKey(
|
||||
'checkout-item-total-${item.productServiceUniqueCode}',
|
||||
),
|
||||
textAlign: TextAlign.right,
|
||||
style: theme.typography.base.copyWith(
|
||||
color: XfjDesignTokens.ink,
|
||||
fontWeight: FontWeight.w800,
|
||||
fontFeatures: const [FontFeature.tabularFigures()],
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'商品小计',
|
||||
style: theme.typography.xs.copyWith(color: XfjDesignTokens.muted),
|
||||
),
|
||||
].toColumn(crossAxisAlignment: CrossAxisAlignment.end).width(104.w),
|
||||
].toColumn(crossAxisAlignment: CrossAxisAlignment.end).width(104.w),
|
||||
].toRowSpace(space: 12.w, crossAxisAlignment: CrossAxisAlignment.center),
|
||||
]
|
||||
.toRowSpace(space: 12.w, crossAxisAlignment: CrossAxisAlignment.center)
|
||||
.toColumn(crossAxisAlignment: CrossAxisAlignment.stretch)
|
||||
.padding(horizontal: 8.w, vertical: 12.h);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -163,7 +163,7 @@ mixin ReservationMenuQueryShortcutActions {
|
||||
return;
|
||||
}
|
||||
unawaited(
|
||||
shortcutSpeaker('已切换为${target.title},再次点击开始${target.title}'),
|
||||
shortcutSpeaker('已切换为${target.title}再次点击开始${target.title}识别'),
|
||||
);
|
||||
unawaited(selectMethod(target));
|
||||
}
|
||||
|
||||
+182
-182
File diff suppressed because it is too large.
Load diff
+1
-1
@@ -1,7 +1,7 @@
|
||||
name: pj_supermarket_cloud
|
||||
description: "资安信智慧后勤-测试"
|
||||
publish_to: "none"
|
||||
version: 1.5.0+150
|
||||
version: 1.5.1+151
|
||||
|
||||
environment:
|
||||
sdk: ^3.6.0
|
||||
|
||||
@@ -143,4 +143,34 @@ void main() {
|
||||
throwsA(isA<DatabaseException>()),
|
||||
);
|
||||
});
|
||||
|
||||
test('13到14迁移补指令列且列已存在时可重入', () async {
|
||||
final database =
|
||||
await databaseFactoryFfi.openDatabase(inMemoryDatabasePath);
|
||||
addTearDown(database.close);
|
||||
await database.execute('''
|
||||
CREATE TABLE print_history (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
orderId TEXT NOT NULL,
|
||||
serviceOrderId TEXT NOT NULL,
|
||||
servicePrintId TEXT NOT NULL,
|
||||
invoiceUrl TEXT NOT NULL,
|
||||
status TEXT NOT NULL,
|
||||
printTime TEXT,
|
||||
syncTime TEXT,
|
||||
createTime TEXT NOT NULL
|
||||
)
|
||||
''');
|
||||
|
||||
await DatabaseMigration.migration13To14.migrate(database);
|
||||
|
||||
final columns = await database.rawQuery('PRAGMA table_info(print_history)');
|
||||
expect(
|
||||
columns.map((column) => column['name']),
|
||||
contains('printCmd'),
|
||||
);
|
||||
|
||||
// 外部存储旧库可能已带该列(中间态构建建库、降级重建),重复迁移不得抛 duplicate column。
|
||||
await DatabaseMigration.migration13To14.migrate(database);
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
import 'dart:io';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:ducafe_ui_core/ducafe_ui_core.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart' show FontLoader;
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:forui/forui.dart';
|
||||
|
||||
import 'package:pj_supermarket_cloud/common/index.dart';
|
||||
|
||||
Future<void> _loadCjkFont() async {
|
||||
final file = File('/System/Library/Fonts/Supplemental/Arial Unicode.ttf');
|
||||
final bytes = await file.readAsBytes();
|
||||
final loader = FontLoader('PreviewCJK')
|
||||
..addFont(Future.value(ByteData.view(bytes.buffer)));
|
||||
await loader.load();
|
||||
}
|
||||
|
||||
/// 以结算弹框购物车列的真实宽度预算复刻商品卡两行结构:
|
||||
/// 名称+类型标签独占整卡一行,图片/单价/步进器/小计在第二行,
|
||||
/// 固化"名称行不被步进器挤压"的布局契约。
|
||||
void main() {
|
||||
setUpAll(_loadCjkFont);
|
||||
|
||||
testWidgets('结算条目名称行单行缩放布局', (tester) async {
|
||||
tester.view.physicalSize = const Size(1920, 1080);
|
||||
tester.view.devicePixelRatio = 1.0;
|
||||
addTearDown(tester.view.reset);
|
||||
|
||||
await tester.pumpWidget(
|
||||
ScreenUtilInit(
|
||||
designSize: const Size(1920, 1080),
|
||||
minTextAdapt: true,
|
||||
builder: (_, __) {
|
||||
final theme = FThemeData.inherit(
|
||||
colorScheme: FThemes.zinc.light.colorScheme,
|
||||
typography: const FTypography(),
|
||||
);
|
||||
return FTheme(
|
||||
data: theme,
|
||||
child: MaterialApp(
|
||||
theme: ThemeData(fontFamily: 'PreviewCJK'),
|
||||
home: Scaffold(
|
||||
backgroundColor: XfjDesignTokens.surface,
|
||||
body: Center(
|
||||
child: Container(
|
||||
// 结算弹框 42% 购物车列下的单条卡片内容宽
|
||||
width: 640,
|
||||
padding: const EdgeInsets.all(8),
|
||||
decoration: BoxDecoration(
|
||||
color: XfjDesignTokens.primarySoft,
|
||||
border: Border.all(
|
||||
color: XfjDesignTokens.primary.withValues(alpha: 0.45),
|
||||
),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
child: <Widget>[
|
||||
// 名称行:整卡宽,左名称右标签
|
||||
<Widget>[
|
||||
LayoutBuilder(
|
||||
builder: (context, constraints) => FittedBox(
|
||||
fit: BoxFit.scaleDown,
|
||||
alignment: Alignment.centerLeft,
|
||||
child: SizedBox(
|
||||
width: constraints.maxWidth,
|
||||
child: Text(
|
||||
'D套餐-葱油鸡腿饭套餐',
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: theme.typography.base.copyWith(
|
||||
color: XfjDesignTokens.ink,
|
||||
fontWeight: FontWeight.w700,
|
||||
height: 1.3,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
).expanded(),
|
||||
const ProductTypeTag(isCombo: true),
|
||||
].toRowSpace(space: 8.w),
|
||||
SizedBox(height: 7.h),
|
||||
// 详情行:图片 + 单价信息 + 步进器/小计
|
||||
Row(
|
||||
children: [
|
||||
Container(
|
||||
width: 64.w,
|
||||
height: 64.w,
|
||||
color: XfjDesignTokens.control,
|
||||
),
|
||||
SizedBox(width: 12.w),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'单价 ¥9.20 库存 999+ 套餐 4 样',
|
||||
style: theme.typography.xs.copyWith(
|
||||
color: XfjDesignTokens.muted,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(width: 12.w),
|
||||
Container(
|
||||
width: 240.w,
|
||||
height: 64.w,
|
||||
alignment: Alignment.center,
|
||||
color: XfjDesignTokens.canvas,
|
||||
child: Text(
|
||||
'步进器+小计区 240.w',
|
||||
style: theme.typography.xs,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
].toColumn(crossAxisAlignment: CrossAxisAlignment.stretch),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
await expectLater(
|
||||
find.byType(Scaffold),
|
||||
matchesGoldenFile('goldens/checkout_name_row.png'),
|
||||
);
|
||||
});
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 25 KiB |
Reference in new issue
Block a user