优化用户端首页服务归属展示
This commit is contained in:
25
apps/user_app/design-qa.md
Normal file
25
apps/user_app/design-qa.md
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
# 用户端首页服务归属视觉验收
|
||||||
|
|
||||||
|
## 验收基线
|
||||||
|
|
||||||
|
- 视觉事实源:`D:\5k\platforms\docs\设计参考\用户端首页_服务归属方案1.png`
|
||||||
|
- 实现截图:`D:\5k\platforms\apps\user_app\design-qa\用户端首页_服务归属实现.png`
|
||||||
|
- 验收视口:390 × 844 CSS 像素,设备像素比 1
|
||||||
|
- 页面状态:固定示例数据;所属气站“和气城南气站”,服务配送点“安顺路配送点”,公告 6 条
|
||||||
|
- 事实源像素尺寸:853 × 1844;按 390 × 844 归一化后与实现截图比较
|
||||||
|
- 实现截图像素尺寸:390 × 844;截图尺寸与 CSS 视口一致,无额外密度换算
|
||||||
|
|
||||||
|
## 对照证据
|
||||||
|
|
||||||
|
- 全页对照:`D:\5k\platforms\apps\user_app\design-qa\对照_全页.png`,左侧为归一化事实源,右侧为实现
|
||||||
|
- 服务归属局部对照:`D:\5k\platforms\apps\user_app\design-qa\对照_服务归属卡片.png`,截取相同视口区域,左侧为事实源,右侧为实现
|
||||||
|
|
||||||
|
## 比较记录
|
||||||
|
|
||||||
|
1. 第一轮发现 P1:实现卡片使用 20 像素内边距和 72 像素图标底座,导致标题与两行字段整体比事实源右移约 12 像素,卡片高度也偏高约 7 像素。
|
||||||
|
2. 修正为 16 像素内边距和 64 像素图标底座后重新截图;标题、标签、值、分隔线与图标的相对位置已与事实源对齐。
|
||||||
|
3. 第二轮未发现 P0、P1 或 P2 视觉问题。页面无横向溢出,底部导航无遮挡,卡片边框、圆角、行距和信息层级一致。
|
||||||
|
|
||||||
|
## 最终结果
|
||||||
|
|
||||||
|
passed
|
||||||
BIN
apps/user_app/design-qa/对照_全页.png
Normal file
BIN
apps/user_app/design-qa/对照_全页.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 440 KiB |
BIN
apps/user_app/design-qa/对照_服务归属卡片.png
Normal file
BIN
apps/user_app/design-qa/对照_服务归属卡片.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 94 KiB |
BIN
apps/user_app/design-qa/用户端首页_服务归属实现.png
Normal file
BIN
apps/user_app/design-qa/用户端首页_服务归属实现.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 31 KiB |
@@ -1,9 +1,13 @@
|
|||||||
|
// 功能描述:展示用户端首页的安全内容、服务归属与公告列表。
|
||||||
|
// 版本:1.1.0
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import '../../../data/repositories/client_repository.dart';
|
import '../../../data/repositories/client_repository.dart';
|
||||||
import '../../../domain/models/client_models.dart';
|
import '../../../domain/models/client_models.dart';
|
||||||
import '../../core/widgets.dart';
|
import '../../core/widgets.dart';
|
||||||
|
import 'service_relation_card.dart';
|
||||||
|
|
||||||
|
/// 用户端首页。
|
||||||
class HomePage extends StatefulWidget {
|
class HomePage extends StatefulWidget {
|
||||||
const HomePage({required this.repository, super.key});
|
const HomePage({required this.repository, super.key});
|
||||||
|
|
||||||
@@ -13,6 +17,7 @@ class HomePage extends StatefulWidget {
|
|||||||
State<HomePage> createState() => _HomePageState();
|
State<HomePage> createState() => _HomePageState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 管理首页远端数据加载与下拉刷新状态。
|
||||||
class _HomePageState extends State<HomePage> {
|
class _HomePageState extends State<HomePage> {
|
||||||
late Future<(List<ClientRecord>, Map<String, Object?>?)> _future;
|
late Future<(List<ClientRecord>, Map<String, Object?>?)> _future;
|
||||||
|
|
||||||
@@ -22,9 +27,11 @@ class _HomePageState extends State<HomePage> {
|
|||||||
_future = _load();
|
_future = _load();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 并行语义上聚合公告和当前服务归属数据。
|
||||||
Future<(List<ClientRecord>, Map<String, Object?>?)> _load() async =>
|
Future<(List<ClientRecord>, Map<String, Object?>?)> _load() async =>
|
||||||
(await widget.repository.contents(), await widget.repository.serviceRelation());
|
(await widget.repository.contents(), await widget.repository.serviceRelation());
|
||||||
|
|
||||||
|
/// 重新加载首页数据并等待刷新完成。
|
||||||
Future<void> _refresh() async {
|
Future<void> _refresh() async {
|
||||||
setState(() => _future = _load());
|
setState(() => _future = _load());
|
||||||
await _future;
|
await _future;
|
||||||
@@ -59,43 +66,7 @@ class _HomePageState extends State<HomePage> {
|
|||||||
description: '设备控制能力尚未开放,本页只展示真实服务与安全内容。',
|
description: '设备控制能力尚未开放,本页只展示真实服务与安全内容。',
|
||||||
),
|
),
|
||||||
AppGutter(
|
AppGutter(
|
||||||
child: SurfaceSection(
|
child: ServiceRelationCard(relation: relation),
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
Container(
|
|
||||||
width: 52,
|
|
||||||
height: 52,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: Theme.of(context).colorScheme.primaryContainer,
|
|
||||||
borderRadius: BorderRadius.circular(16),
|
|
||||||
),
|
|
||||||
child: Icon(
|
|
||||||
Icons.store_mall_directory_outlined,
|
|
||||||
color: Theme.of(context).colorScheme.primary,
|
|
||||||
semanticLabel: '服务归属',
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(width: 16),
|
|
||||||
Expanded(
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Text('当前服务归属', style: Theme.of(context).textTheme.titleMedium),
|
|
||||||
const SizedBox(height: 4),
|
|
||||||
Text(
|
|
||||||
relation == null
|
|
||||||
? '尚未建立服务关系'
|
|
||||||
: '${relation['gas_name'] ?? ''} ${relation['delivery_name'] ?? ''}',
|
|
||||||
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
|
||||||
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
const SizedBox(height: 32),
|
const SizedBox(height: 32),
|
||||||
const AppGutter(
|
const AppGutter(
|
||||||
|
|||||||
112
apps/user_app/lib/ui/features/home/service_relation_card.dart
Normal file
112
apps/user_app/lib/ui/features/home/service_relation_card.dart
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
// 功能描述:展示用户当前所属气站与服务配送点,并处理无配送点和无归属状态。
|
||||||
|
// 版本:1.0.0
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:heqi_design_system/heqi_design_system.dart';
|
||||||
|
|
||||||
|
/// 服务归属信息卡片,负责清晰区分气站主体与配送履约网点。
|
||||||
|
class ServiceRelationCard extends StatelessWidget {
|
||||||
|
const ServiceRelationCard({required this.relation, super.key});
|
||||||
|
|
||||||
|
/// 服务端返回的当前有效服务关系;为空表示尚未建立归属。
|
||||||
|
final Map<String, Object?>? relation;
|
||||||
|
|
||||||
|
/// 提取并清理指定关系字段,空字符串按无值处理。
|
||||||
|
String? _relationValue(String key) {
|
||||||
|
final value = relation?[key]?.toString().trim() ?? '';
|
||||||
|
return value.isEmpty ? null : value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final gasName = _relationValue('gas_name');
|
||||||
|
final deliveryName = _relationValue('delivery_name');
|
||||||
|
final hasRelation = relation != null && gasName != null;
|
||||||
|
|
||||||
|
return HeqiSurfaceSection(
|
||||||
|
padding: const EdgeInsets.all(HeqiSpacing.x4),
|
||||||
|
child: Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
width: 64,
|
||||||
|
height: 64,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Theme.of(context).colorScheme.primaryContainer,
|
||||||
|
borderRadius: BorderRadius.circular(HeqiRadius.extraLarge),
|
||||||
|
),
|
||||||
|
child: Icon(
|
||||||
|
Icons.store_mall_directory_outlined,
|
||||||
|
size: HeqiSize.iconLarge,
|
||||||
|
color: Theme.of(context).colorScheme.primary,
|
||||||
|
semanticLabel: '服务归属',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(width: HeqiSpacing.x4),
|
||||||
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text('当前服务归属', style: Theme.of(context).textTheme.titleMedium),
|
||||||
|
const SizedBox(height: HeqiSpacing.x3),
|
||||||
|
if (!hasRelation)
|
||||||
|
Text(
|
||||||
|
'尚未建立服务关系',
|
||||||
|
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
||||||
|
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
else ...[
|
||||||
|
_RelationLine(label: '所属气站', value: gasName),
|
||||||
|
const Padding(
|
||||||
|
padding: EdgeInsets.symmetric(vertical: HeqiSpacing.x3),
|
||||||
|
child: Divider(height: 1),
|
||||||
|
),
|
||||||
|
_RelationLine(
|
||||||
|
label: deliveryName == null ? '服务方式' : '服务配送点',
|
||||||
|
value: deliveryName ?? '气站直接服务',
|
||||||
|
),
|
||||||
|
],
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 服务归属中的单行标签和值,名称最多展示两行。
|
||||||
|
class _RelationLine extends StatelessWidget {
|
||||||
|
const _RelationLine({required this.label, required this.value});
|
||||||
|
|
||||||
|
final String label;
|
||||||
|
final String value;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) => Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
width: 76,
|
||||||
|
child: Text(
|
||||||
|
label,
|
||||||
|
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
||||||
|
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(width: HeqiSpacing.x2),
|
||||||
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
value,
|
||||||
|
maxLines: 2,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
||||||
|
color: Theme.of(context).colorScheme.onSurface,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
66
apps/user_app/test/ui/service_relation_card_test.dart
Normal file
66
apps/user_app/test/ui/service_relation_card_test.dart
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
// 功能描述:验证服务归属卡片的信息层级、空值状态和长名称约束。
|
||||||
|
// 版本:1.0.0
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
import 'package:user_app/ui/features/home/service_relation_card.dart';
|
||||||
|
|
||||||
|
/// 验证服务归属卡片的三类核心展示状态。
|
||||||
|
void main() {
|
||||||
|
/// 构建统一测试宿主,提供 Material 主题和稳定宽度。
|
||||||
|
Widget testHost(Map<String, Object?>? relation) => MaterialApp(
|
||||||
|
home: Scaffold(
|
||||||
|
body: SizedBox(
|
||||||
|
width: 390,
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(24),
|
||||||
|
child: ServiceRelationCard(relation: relation),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
testWidgets('气站与配送点使用独立标签展示', (tester) async {
|
||||||
|
await tester.pumpWidget(
|
||||||
|
testHost({
|
||||||
|
'gas_name': '和气城南气站',
|
||||||
|
'delivery_name': '安顺路配送点',
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(find.text('当前服务归属'), findsOneWidget);
|
||||||
|
expect(find.text('所属气站'), findsOneWidget);
|
||||||
|
expect(find.text('和气城南气站'), findsOneWidget);
|
||||||
|
expect(find.text('服务配送点'), findsOneWidget);
|
||||||
|
expect(find.text('安顺路配送点'), findsOneWidget);
|
||||||
|
expect(find.text('和气城南气站 安顺路配送点'), findsNothing);
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('没有配送点时明确显示气站直接服务', (tester) async {
|
||||||
|
await tester.pumpWidget(testHost({'gas_name': '和气城南气站'}));
|
||||||
|
|
||||||
|
expect(find.text('服务方式'), findsOneWidget);
|
||||||
|
expect(find.text('气站直接服务'), findsOneWidget);
|
||||||
|
expect(find.text('服务配送点'), findsNothing);
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('没有服务关系时显示明确空状态', (tester) async {
|
||||||
|
await tester.pumpWidget(testHost(null));
|
||||||
|
|
||||||
|
expect(find.text('尚未建立服务关系'), findsOneWidget);
|
||||||
|
expect(find.text('所属气站'), findsNothing);
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('较长组织名称最多显示两行', (tester) async {
|
||||||
|
const longName = '和气城市综合能源安全服务城南中心气站';
|
||||||
|
await tester.pumpWidget(
|
||||||
|
testHost({
|
||||||
|
'gas_name': longName,
|
||||||
|
'delivery_name': '安顺路配送点',
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
final nameText = tester.widget<Text>(find.text(longName));
|
||||||
|
expect(nameText.maxLines, 2);
|
||||||
|
expect(nameText.overflow, TextOverflow.ellipsis);
|
||||||
|
});
|
||||||
|
}
|
||||||
62
apps/user_app/tool/home_visual_preview.dart
Normal file
62
apps/user_app/tool/home_visual_preview.dart
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
// 功能描述:使用固定示例数据启动用户端首页,供本地视觉验收使用。
|
||||||
|
// 版本:1.0.0
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:user_app/data/repositories/client_repository.dart';
|
||||||
|
import 'package:user_app/data/services/api_client.dart';
|
||||||
|
import 'package:user_app/domain/models/client_models.dart';
|
||||||
|
import 'package:user_app/ui/core/app_theme.dart';
|
||||||
|
import 'package:user_app/ui/features/home/home_page.dart';
|
||||||
|
|
||||||
|
/// 启动不依赖账号和网络的首页视觉预览。
|
||||||
|
void main() {
|
||||||
|
runApp(const _HomeVisualPreviewApp());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 首页视觉预览应用。
|
||||||
|
class _HomeVisualPreviewApp extends StatelessWidget {
|
||||||
|
const _HomeVisualPreviewApp();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) => MaterialApp(
|
||||||
|
debugShowCheckedModeBanner: false,
|
||||||
|
theme: AppTheme.light(),
|
||||||
|
home: Scaffold(
|
||||||
|
body: HomePage(repository: _VisualClientRepository()),
|
||||||
|
bottomNavigationBar: NavigationBar(
|
||||||
|
selectedIndex: 0,
|
||||||
|
destinations: const [
|
||||||
|
NavigationDestination(
|
||||||
|
icon: Icon(Icons.home_outlined),
|
||||||
|
selectedIcon: Icon(Icons.home),
|
||||||
|
label: '首页',
|
||||||
|
),
|
||||||
|
NavigationDestination(icon: Icon(Icons.shopping_bag_outlined), label: '商城'),
|
||||||
|
NavigationDestination(icon: Icon(Icons.receipt_long_outlined), label: '订单'),
|
||||||
|
NavigationDestination(icon: Icon(Icons.person_outline), label: '我的'),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 提供稳定首页数据,避免视觉预览依赖真实账号和服务接口。
|
||||||
|
class _VisualClientRepository extends ClientRepository {
|
||||||
|
_VisualClientRepository() : super(ApiClient(() => ''));
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<List<ClientRecord>> contents() async => List.generate(
|
||||||
|
6,
|
||||||
|
(index) => ClientRecord(
|
||||||
|
identity: 'notice-${9 - index}',
|
||||||
|
title: '模拟公告 ${9 - index}',
|
||||||
|
subtitle: 'notice',
|
||||||
|
raw: const {},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<Map<String, Object?>> serviceRelation() async => const {
|
||||||
|
'gas_name': '和气城南气站',
|
||||||
|
'delivery_name': '安顺路配送点',
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -18,6 +18,7 @@
|
|||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| 定位 | 获取当前位置并允许手动选择地址/气站服务区域 | 授权失败有手动入口,不以定位失败阻塞设备使用 |
|
| 定位 | 获取当前位置并允许手动选择地址/气站服务区域 | 授权失败有手动入口,不以定位失败阻塞设备使用 |
|
||||||
| 内容 | 轮播图、公告、安全宣传、安全视频列表 | 后台上下架后按缓存策略刷新;外链有风险提示 |
|
| 内容 | 轮播图、公告、安全宣传、安全视频列表 | 后台上下架后按缓存策略刷新;外链有风险提示 |
|
||||||
|
| 当前服务归属 | 分开显示“所属气站”和“服务配送点”,气站为主要信息、配送点为次要信息 | 不拼接组织名称;没有配送点时显示“服务方式:气站直接服务”;没有服务关系时显示明确空状态;组织名称最多两行 |
|
||||||
| 智能瓶阀列表 | 显示名称、地址、在线状态、开关状态、最近告警、设备数量 | 可按地址/状态筛选;离线状态显著可见 |
|
| 智能瓶阀列表 | 显示名称、地址、在线状态、开关状态、最近告警、设备数量 | 可按地址/状态筛选;离线状态显著可见 |
|
||||||
| 扫码添加 | 扫码或输入设备码,选择安装地址和设备昵称 | 校验设备归属、激活、服务区域和重复绑定 |
|
| 扫码添加 | 扫码或输入设备码,选择安装地址和设备昵称 | 校验设备归属、激活、服务区域和重复绑定 |
|
||||||
| 设备接入 | 扫码添加、手动输入、蓝牙连接与设备校验 | 展示设备 ID、名称、安装位置;绑定前需用户确认,蓝牙权限失败有明确引导 |
|
| 设备接入 | 扫码添加、手动输入、蓝牙连接与设备校验 | 展示设备 ID、名称、安装位置;绑定前需用户确认,蓝牙权限失败有明确引导 |
|
||||||
|
|||||||
47
docs/操作日志_用户端首页服务归属展示优化_20260902.md
Normal file
47
docs/操作日志_用户端首页服务归属展示优化_20260902.md
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
# 用户端首页服务归属展示优化操作日志
|
||||||
|
|
||||||
|
操作时间:2026-09-02
|
||||||
|
|
||||||
|
操作类型:修改、扩展
|
||||||
|
|
||||||
|
影响模块:用户端 Flutter App 首页
|
||||||
|
|
||||||
|
## 操作前状态
|
||||||
|
|
||||||
|
首页将接口返回的气站名称与配送点名称直接拼接在“当前服务归属”下方,例如“薛海 1”。用户无法判断两个值分别代表气站还是配送点;无配送点与无服务关系也缺少明确说明。
|
||||||
|
|
||||||
|
## 具体操作
|
||||||
|
|
||||||
|
1. 根据确认的视觉方案一新增独立服务归属卡片,沿用现有安全蓝、白色卡片、圆角和间距令牌。
|
||||||
|
2. 将气站和配送点拆分为“所属气站”“服务配送点”两行,气站名称使用主要信息字重。
|
||||||
|
3. 无配送点时显示“服务方式:气站直接服务”;无服务关系时显示“尚未建立服务关系”。
|
||||||
|
4. 组织名称限制为最多两行,超出部分使用省略号,避免破坏移动端布局。
|
||||||
|
5. 新增固定数据的本地视觉预览入口,并在 390 × 844 视口完成两轮截图对照。
|
||||||
|
6. 新增组件测试,覆盖完整关系、气站直服、无关系和长名称四种情况。
|
||||||
|
|
||||||
|
## 操作后状态
|
||||||
|
|
||||||
|
首页能够明确区分服务主体与履约网点,不再展示难以理解的拼接名称。功能仍只读,不新增点击、状态或接口字段,原有公告加载、刷新和底部导航行为保持不变。
|
||||||
|
|
||||||
|
## 代码变更
|
||||||
|
|
||||||
|
- `apps/user_app/lib/ui/features/home/home_page.dart`:替换旧的拼接展示,接入独立服务归属卡片。
|
||||||
|
- `apps/user_app/lib/ui/features/home/service_relation_card.dart`:新增服务归属组件及空值处理。
|
||||||
|
- `apps/user_app/test/ui/service_relation_card_test.dart`:新增四类组件测试。
|
||||||
|
- `apps/user_app/tool/home_visual_preview.dart`:新增不依赖账号和网络的视觉验收入口。
|
||||||
|
- `apps/user_app/design-qa.md` 与 `apps/user_app/design-qa/`:记录视觉验收基线、截图和对照结果。
|
||||||
|
- `docs/03-用户端App需求.md`:补充首页服务归属展示规则。
|
||||||
|
|
||||||
|
## 验证结果
|
||||||
|
|
||||||
|
- `flutter analyze`:通过,无问题。
|
||||||
|
- `flutter test`:通过,共 8 项测试。
|
||||||
|
- `flutter build web --release --dart-define=API_BASE_URL=http://rest.heqiapp.com`:通过,已生成 Web 发布构建。
|
||||||
|
- 390 × 844 页面视觉验收:通过;第二轮未发现 P0、P1、P2 问题。
|
||||||
|
- 边界案例:已覆盖无配送点、无服务关系、长组织名称最多两行。
|
||||||
|
|
||||||
|
## 风险评估
|
||||||
|
|
||||||
|
- 影响范围仅限用户端首页展示层,不修改 API、数据模型、登录态或服务关系业务规则。
|
||||||
|
- 组织名称超过两行时会省略尾部内容,这是为保证移动端布局稳定的预期行为。
|
||||||
|
- 视觉预览使用固定示例数据,仅用于开发验收,不会进入生产路由或伪造业务状态。
|
||||||
BIN
docs/设计参考/用户端首页_服务归属方案1.png
Normal file
BIN
docs/设计参考/用户端首页_服务归属方案1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 989 KiB |
Reference in New Issue
Block a user