周到安排商家(one_key)开发技术文档
本文件供后续协助开发时快速理解项目结构、代码习惯与开发约定。 最后更新:2026-08-21
0. 开发约定(重要,优先遵守)
以下是后续开发必须沿用的约定:
-
屏幕适配
- 新建页面一律使用
w()/font()(来自lib/utils/screen_util.dart),不要直接写ScreenUtil().setWidth()/ScreenUtil().setSp()。 -
w()/font()的入参就是 375 设计稿的数值:w(375)= 整屏宽,font(14)= 14 号字。 -
同一个文件内绝不混用两种写法:新文件用
w()/font();修改老文件时跟随该文件已有风格(老文件多为ScreenUtil().setWidth(x),其数值是 750 口径,不用改)。
- 新建页面一律使用
-
间距:一律用
VEmptyView(高度)/HEmptyView(宽度)。- 注意口径:这两个组件内部直接
setWidth(数值)(未 ×2),传 750 口径数值 = 375 设计稿数值 ×2。详见 §6.2。
- 注意口径:这两个组件内部直接
-
分割线:一律用
MyDivider(宽, 高, {color}),默认色MyColours.color_dbe3e3。 -
颜色:一律从
MyColours(lib/res/colors.dart)取,不要写裸Color(0x...)。 - 页面导航:新页面三步注册(Routes 常量 → route_handles Handler → NavigatorUtil 方法),见 §7。
-
状态管理:
ChangeNotifier + provider,页面数据放 Provider,路由级用ChangeNotifierProvider包裹,见 §8。 -
网络请求:接口地址加在
HttpUrl,请求统一走DioUtil().request<T>(),返回BaseResp,成功码code == 200(Constant.status_success),见 §9。
1. 项目概览
- 项目名:
one_key,App 显示名「周到安排商家」,面向餐厅/商家的预订与经营管理系统。 - Android 包名:
com.naji.one_key;iOS Bundle ID:com.naji.reserveLine。 - Flutter:
3.27.3(通过 fvm 管理,见.fvmrc);Dart SDK>=3.0.0。 - 服务端地址:
http://xt04.colorcun.com/(lib/net/http_url.dart),请求统一Method.post,参数作为 query 拼在 URL 上,接口名形如?service=Android.X.Y/?service=App.X.Y。 - 双版本:正常版 + 极速版(
Constant.normalApp控制,当前为false即双版本共存;极速版页面在lib/pages_sim/,路由名带_sim)。 - 微信:AppId
wx4d105e36a36a6139,UniversalLinkhttps://xt04.colorcun.com/link/OneKey/。 - 文案:UI 文案基本硬编码中文,
lib/generated/l10n实际使用很少。 - 代码规模:
lib/pages/322 个页面文件、lib/pages_sim/80 个、Provider 44 个、模型 202 个(其中 53 个.g.dart)、公共组件 42 个、路由常量 244 个。
2. 环境与常用命令
fvm flutter run # 运行
fvm flutter pub run build_runner build --delete-conflicting-outputs # 生成 model 的 .g.dart
fvm flutter analyze # 静态检查
fvm flutter test # 测试(当前 test/widget_test.dart 基本为注释,暂无有效用例)
3. 目录结构
| 目录 | 说明 |
|---|---|
lib/main.dart |
入口:初始化路由、SharedPreferences、全局 Provider、ScreenUtilInit、MaterialApp |
lib/app.dart |
App 全局静态类:App.sp(SharedPreferences)、App.router、App.navigatorKey、屏幕/状态栏信息 |
lib/pages/ |
业务页面,按模块分子目录(home、login、message、notebook、table、feast、my、detail、coupon、order_advance、create_store 等) |
lib/pages_sim/ |
极速版页面副本,与正常版同名页面需同步维护 |
lib/provider/ |
状态管理:ChangeNotifier 子类,命名 XxxProvider / XxxModel
|
lib/models/ |
数据模型:json_serializable + .g.dart,常见命名 XxxSunModel
|
lib/net/ |
网络层:dio_util.dart(DioUtil 单例)、base_resp.dart(BaseResp)、http_url.dart(接口地址常量) |
lib/route/ |
fluro 路由:routes.dart(路径常量 + 注册)、route_handles.dart(Handler)、navigator_util.dart(跳转方法) |
lib/res/ |
colors.dart(MyColours 色板)、dimens.dart(Dimens 字号/间距常量)、styles.dart、strings.dart
|
lib/utils/ |
screen_util.dart(w/h/font 等适配函数)、utils.dart(Utils 工具大集合)、dialog_util.dart、event_bus.dart、misc.dart(权限)等 |
lib/widgets/ |
公共组件:SystemAppBar、RoundButton、CommonButton、VEmptyView、HEmptyView、MyDivider、ExceptionPage 等 |
lib/constant/ |
constant.dart(全局常量、权限配置)、state.dart(PageState 等枚举)、error.dart(MyError) |
assets/ |
图片与音频资源,已在 pubspec 全量声明 |
library/ |
本地依赖插件(webview_flutter 修改版、sendsms、table_calendar 等) |
android/ ios/ macos/ ohos/ |
原生平台工程;ohos/ 为鸿蒙适配目录 |
test/ |
仅默认 widget_test.dart,基本全注释,暂无有效测试 |
3.1 业务模块地图
| 业务模块 | 页面目录 | 主要 Provider / Model |
|---|---|---|
| 登录 / 开店 / 店铺资料 |
pages/login/、pages/create_store/、pages/enter/
|
OtherLoginProvider、CreateStoreModel、EnterModel、HomeEnterModel、StoreBaseIndoProvider、BaseIndoProvider
|
| 首页 / Tab / 消息角标 | pages/home/ |
MessageModel、MyTableManageHomeModel
|
| 消息中心 / 在线订单 |
pages/message/、pages/online_check/、pages/home_enter_order/
|
MessageModel、MessageDialogModel、OnlineCheckEditProvider、OrderFoodProvider
|
| 预订本 / 预订详情 / 变更预订 |
pages/notebook/、pages/detail/
|
NoteBookModel、NotebookDetailModel、NotebookDetailChangeModel*、RemarkManagerModel、BookSetTimeModel、ChooseTableModel
|
| 桌位 / 桌位照片 / 区域 |
pages/table/、pages/my/table_manage/、pages/my/photo_type/
|
TableManagerModel、TableManagerModelOrReserve、MyTableManageHomeModel、TablePhotoManagerModel
|
| 宴会 |
pages/feast/、pages/my/feast_manage/
|
FeastModel |
| 客情 / 客户 / 营销记录 | pages/my/customer_type/ |
CustomerProvider、CustomerMakingProvider、MarketingCenterProvider、StatisticsProvider、ContactModel
|
| 营销中心(预约通知、短信、充值、设置) | pages/my/marketing_center/ |
MarketingCenterProvider、SmsModel、SmsRechargeModel、CouponProvider、FinanceProvider
|
| 优惠券 | pages/coupon/ |
CouponProvider |
| 消费金 / 会员充值 / 收银 |
pages/my/consume/、pages/my/finance_manage/
|
FinanceProvider |
| 菜单 / 排菜 / 预点菜 |
pages/my/menu_type/、pages/my/plan_dish/、pages/order_advance/
|
MenuManageProvider、PlanDishProvider、OrderFoodProvider
|
| 员工 / 权限 / 包间类型 / 存酒 |
pages/my/personnel_type/、pages/my/room_type/、pages/my/store_wine_manage/
|
PersonnelProvider、StoreWineProvider
|
| 评价管理 | pages/my/comment_manage/ |
CommentManageProvider |
| 统计 |
pages/notebook/statistics_page.dart、pages/my/customer_type/store_customer/
|
StatisticsProvider、FinanceProvider
|
| 我的 / 个人信息 |
pages/my/my_page.dart、pages/my/base_info*.dart
|
MyModel、UserModel、UpdateModelMy
|
3.2 平台工程与本地依赖
- 原生目录:
android/(包名com.naji.one_key)、ios/(Bundle IDcom.naji.reserveLine)、macos/、ohos/(鸿蒙适配,含oh_modules生成物)。 - pubspec 中实际引用的本地路径依赖:
webview_flutter、sendsms、device_utils_my、calendar_date_picker2、table_calendar、azlistview_plus、flutter_lunar_datetime_picker(均在library/)。 -
library/下还保留了高德地图、扫码、语音、TPNS 等插件副本/历史版本;改插件前先确认 pubspec 与.flutter-plugins-dependencies是否实际引用,避免改错副本。 - 语音播报资源:
assets/tts_*.mp3(Android/通用)与ios/tts_*.caf(iOS);新增语音需在 pubspec 声明对应 mp3。
4. 启动流程(main.dart)
-
FluroRouter创建并调用Routes.configureRoutes(router)注册全部路由,赋给App.router。 -
App.initSp()初始化SharedPreferences(全局通过App.sp访问)。 -
runApp(MultiProvider(...))注册全局 Provider:MessageModel、UserModel、MessageDialogModel、OrderFoodProvider、NotebookDetailModel、CouponProvider、UploadImageProvider、CreateStoreModel、RemarkManagerModel、CustomerMakingProvider、MyTableManageHomeModel。其余 Provider 在路由 Handler 里按页注册。 -
ScreenUtilInit(designSize: Size(750, 1334), minTextAdapt: true, splitScreenMode: true)初始化屏幕适配,注意 设计尺寸是 750×1334。 -
MaterialApp:主题useMaterial3: false,primaryColor: Colors.white,iOS 转场用PopScopePageTransitionsBuilder,home由本地状态决定:- 首次打开(
isFirst)→FirstPage(初始化微信/网络等后跳登录); - 已登录 →
HomePage(initialIndex: 1); - 未登录 →
LoginPage。
- 首次打开(
- 主页等高频路由在
route_handles.dart的 Handler 中额外包裹页面级 Provider(HomePage会包TableManagerModel、StoreBaseIndoProvider、CollectStoreProvider、BaseIndoProvider、PersonnelProvider)。
5. 整体架构与数据流
页面 (pages/) ── Provider.of / Consumer ──> Provider (provider/)
Provider ── DioUtil().request() ──> HttpUrl 接口 ──> 服务端 (xt04.colorcun.com)
页面状态:PageState 枚举 → ExceptionPage 统一渲染 加载中/网络错误/超时/空页面
关键点:
- 页面通过
Provider.of<XxxProvider>(context, listen: true/false)或Consumer<XxxProvider>拿数据;Provider 内部notifyListeners()驱动刷新。 - 每个 Provider 通常维护若干
PageState字段(Loading / ConnectivityError / ConnectivityTimeOut / Empty / Success等,见lib/constant/state.dart),页面据此渲染ExceptionPage或列表内容。 - 用户信息:
UserModel(全局注册),登录后用户对象 JSON 存App.sp(key:user),通过Provider.of<UserModel>(context, listen: false).user!获取sellerid/openid/token等。 - 权限控制:
Constant.authorityConfig(模块 → 角色数组)+Utils.getAuthority(context, '模块名')判断当前角色是否有权。
6. UI 规范(重点)
6.1 屏幕适配:w() / font() 与 375 设计稿
lib/utils/screen_util.dart 提供顶层函数(新页面直接 import 使用):
double w(num width) => ScreenUtil().setWidth(width * 2); // 宽(宽度等比缩放)
double h(num height) => ScreenUtil().setWidth(height * 2); // 高(也是 setWidth!按宽度缩放)
double h2(num height) => ScreenUtil().setHeight(height * 2); // 高(按高度缩放,少用)
double r(num radius) => ScreenUtil().radius(radius * 2); // 圆角
double font(num size) => ScreenUtil().setSp(size * 2); // 字号
由于 ScreenUtilInit 的设计尺寸是 750×1334,而上述函数内部把入参 ×2,所以:
-
w()/font()的入参即 375 设计稿数值:w(375)= 整屏宽,w(20)= 20 逻辑像素,font(16)= 16 号字,r(8)= 8 圆角。 - 后续设计稿按 375 宽,新页面直接把稿子上的数值填进
w()/font()/r()即可,不需要自己换算。 -
h()实际按宽度等比缩放(与w()一致),保证横向适配时高度不溢出;h2()才是按高度缩放。
老文件大量使用
ScreenUtil().setWidth(40)、ScreenUtil().setSp(28)这种 750 口径写法(数值 ≈ 375 值 ×2)。修改老文件时保持该文件原有写法,不要混入w()/font();新建文件则统一用w()/font()。
6.2 间距:VEmptyView / HEmptyView
-
VEmptyView(高度)→SizedBox(height: ScreenUtil().setWidth(高度)) -
HEmptyView(宽度)→SizedBox(width: ScreenUtil().setWidth(宽度))
⚠️ 口径注意:这两个组件内部直接 setWidth(数值),没有 ×2,所以传的是 750 口径数值。换算关系:
| 375 设计稿间距 | 代码写法 |
|---|---|
| 6px |
VEmptyView(12) / HEmptyView(12)
|
| 12px | VEmptyView(24) |
| 24px | VEmptyView(48) |
也就是说:375 设计稿上的间距数值 ×2 后传给 VEmptyView/HEmptyView。已有代码都是这个口径(例如 w() 风格文件中 VEmptyView(24) 与 w(12) 实际渲染尺寸一致)。
6.3 分割线:MyDivider
MyDivider(宽, 高, {color});
// 例如:MyDivider(w(375), w(1)) 默认颜色 MyColours.color_dbe3e3
// 自定义颜色:MyDivider(w(375), w(1), color: MyColours.color_DBDBDB)
新页面分割线一律用 MyDivider,不要用 Divider() / Container(color:...) 代替。
6.4 颜色:MyColours
色板集中在 lib/res/colors.dart(MyColours 类),命名 color_<十六进制>。常用色:
| 用途 | 常量 | 值 |
|---|---|---|
| 主色(App 主题青绿色) | MyColours.app_main |
0xFF24A4A8 |
| 主操作色(按钮/选中/链接) | MyColours.color_199095 |
0xFF199095 |
| 辅助青绿(强调/标签) | MyColours.color_438E93 |
0xFF438E93 |
| 正文深色 |
MyColours.color_333333 / color_353535 / color_515151
|
0xFF333333 等 |
| 次要文字 |
MyColours.color_666666 / color_777777
|
0xFF666666 等 |
| 弱化文字/占位 |
MyColours.color_999999 / color_bfbfbf
|
0xFF999999 等 |
| 页面背景 |
MyColours.color_f5f5f5 / color_f7f7f7 / color_f8f9fd
|
浅灰 |
| 白色 | MyColours.color_ffffff |
0xFFFFFFFF |
| 红色(错误/删除/未读角标) |
MyColours.color_E34D59 / color_fa5151 / color_E95750
|
红系 |
| 分割线默认 | MyColours.color_dbe3e3 |
0xFFdbe3e3 |
6.5 字号与文字
- 新页面统一
font(数值):常用font(10) / font(12) / font(14) / font(16) / font(18) / font(22)。 -
lib/res/dimens.dart中有Dimens.font_sp10~24等常量,但页面里使用较少,新代码不强制使用。 - 文字样式一般直接
TextStyle(fontSize: font(14), color: MyColours.color_333333);不需要ThemeData.textTheme。
6.6 图片资源
- 图片在
assets/,pubspec 已声明- assets/,新图直接放入即可。 - 加载方式:
Image.asset(Utils.getImgPath('xxx'))(自动补assets/xxx.png),或网络图CachedNetworkImage。
6.7 常用公共组件
| 组件 | 文件 | 说明 |
|---|---|---|
SystemAppBar |
lib/widgets/system_app_bar.dart |
标准导航栏(AppBar 实现),标题居中,返回键 assets/icon_back.png,可配右侧文字/图片按钮 |
MyAppBar |
lib/widgets/app_bar.dart |
自绘导航栏,可自定义背景/字体色/右侧按钮 |
RoundButton |
lib/widgets/round_button.dart |
圆角渐变按钮,常用参数 text/width/height/radius/fontSize/onPressed;w 风格文件里 width: w(48), height: h(18), radius: r(7)
|
CommonButton |
lib/widgets/common_button.dart |
状态按钮,state:-1 灰禁、0 描边、1 实心主色、-3 红色 |
GradientButton |
lib/widgets/gradient_button.dart |
纯渐变容器按钮 |
ExceptionPage |
lib/widgets/page_exception.dart |
按 PageState 渲染 加载中/网络错误/超时/空页面,带重试回调 |
LoadingPage / EmptyPage / ErrorPage |
lib/widgets/ |
状态页基础组件 |
Loading |
lib/widgets/loading.dart |
全局 loading 弹层:Loading.showLoading(context) / hideLoading
|
MyItem |
lib/widgets/my_item.dart |
「标题 + 内容 + 右箭头」列表行 |
RowMultiText |
lib/widgets/row_multi_text.dart |
左右两段文字行 |
TextInputFieldWidget |
lib/widgets/text_input_field_widget.dart |
无边框输入框 |
FixedText |
lib/widgets/fixed_text.dart |
固定字号文本(textScaleFactor: 1.0) |
CustomTabIndicator |
lib/widgets/custom_tab_indicator.dart |
自定义 Tab 指示器 |
6.8 页面骨架模板(新页面按此写)
import 'package:flutter/material.dart';
import 'package:one_key/res/colors.dart';
import 'package:one_key/utils/screen_util.dart'; // w()/font()
import 'package:one_key/widgets/MyDivider.dart'; // 分割线
import 'package:one_key/widgets/h_empty_view.dart'; // 水平间距
import 'package:one_key/widgets/v_empty_view.dart'; // 垂直间距
import 'package:one_key/widgets/system_app_bar.dart'; // 导航栏
class DemoPage extends StatefulWidget {
const DemoPage({super.key});
@override
State<DemoPage> createState() => _DemoPageState();
}
class _DemoPageState extends State<DemoPage> {
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
// 初始化请求
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: MyColours.color_f5f5f5,
appBar: SystemAppBar('页面标题'),
body: Column(
children: [
Container(
width: w(375), // 375 设计稿直接填
height: w(48),
padding: EdgeInsets.symmetric(horizontal: w(20)),
alignment: Alignment.centerLeft,
child: Text('内容',
style: TextStyle(
fontSize: font(16), color: MyColours.color_333333)),
),
MyDivider(w(375), w(1)), // 分割线
VEmptyView(24), // 间距 = 375稿 12px
Row(children: [
HEmptyView(20), // 水平间距 = 375稿 10px
const Text('另一段'),
]),
],
),
);
}
}
6.9 首页 Tab 结构
HomePage(lib/pages/home/home_page.dart):PageView(NeverScrollableScrollPhysics)+ BottomNavigationBar,共 5 个 Tab:
| index | 页面 | 底部图标 |
|---|---|---|
| 0 | 消息 MessagePage
|
message_default/selected.png |
| 1 | 预订本 NoteBookPage(默认页) |
notebook_default/selected.png |
| 2 | 桌位 TableManagerPage
|
tablemanage_default/selected.png |
| 3 | 宴会 FeastPage
|
y_feast_un/sel.png |
| 4 | 我的 MyPage
|
my_default/selected.png |
7. 路由规范(fluro)
当前规模:routes.dart 244 个路径常量;route_handles.dart 248 个 Handler;navigator_util.dart 245 个跳转方法。Routes.configureRoutes(router) 位于 routes.dart 文件底部,统一执行 router.define(...)。
新增页面三步:
-
lib/route/routes.dart:定义路径常量,如static String demo_page = "/demo_page";。 -
lib/route/route_handles.dart:定义Handler,构造页面并包上需要的ChangeNotifierProvider;然后在Routes.configureRoutes里router.define(Routes.demo_page, handler: xxxHandler);。 -
lib/route/navigator_util.dart:写static void goDemoPage(BuildContext context, {参数}),内部App.router.navigateTo(context, "...")。
传参规则:
- 简单参数拼在路径 query 上,如
${Routes.demo_page}?id=$id,Handler 里params["id"]!.first取。 - 复杂对象先
json.encode+FluroConvertUtils.fluroCnParamsDecode编码,Handler 里FluroConvertUtils.fluroCnParamsDecode(...)解码后XxxModel.fromJson。 - 跳转前
NavigatorUtil内部会先Utils.changeStatusColor(color: MyColours.color_ffffff)。
8. 状态管理规范(provider)
- 全局状态:
main.dart的MultiProvider注册(共 11 个,见 §4)。 - 页面级状态:路由 Handler 里用
ChangeNotifierProvider<XxxProvider>(create: (_) => XxxProvider(), child: XxxPage())包裹(可多层嵌套)。 - 页面取数据:
Provider.of<XxxProvider>(context, listen: true)(监听)或listen: false(不监听,如请求方法内);列表用Consumer<XxxProvider>更清晰。 - Provider 内请求完成后
notifyListeners();页面setState一般只在页面自身状态变化时调用。 - 页面初始化请求放在
initState+WidgetsBinding.instance.addPostFrameCallback中(避免 build 前请求)。
9. 网络请求规范
9.1 接口定义
lib/net/http_url.dart:static const String xxx = "?service=App.X.Y"; // 注释。
基础地址 HttpUrl.server_address = "http://xt04.colorcun.com/",请求统一 Method.post,data 参数会作为 query 拼在 URL 上(DioUtil 内部 queryParameters: data)。
9.2 发起请求
BaseResp<dynamic> baseResp = await DioUtil().request<dynamic>(
context, Method.post, HttpUrl.xxx,
data: params, // Map<String, String?>,会作为 queryParameters
showLoading: true, // 是否显示全局 loading
);
if (baseResp.code == Constant.status_success) { // 200
// baseResp.data / baseResp.responseData
} else {
Utils.showToast(baseResp.msg ?? "");
}
要点:
-
BaseResp字段:status / code / msg / data / responseData;响应结构{ret, msg, data},ret == 200为成功(HttpConfig在main.dart的initDio()里配置:status: "ret", code: "ret", msg: "msg", data: "data")。 - 常见参数:
sellerid/openid从Provider.of<UserModel>(context, listen: false).user!取;部分接口要sid、uid、token。 - 错误处理:请求抛
MyError(lib/constant/error.dart),type: 1= 网络错误,type: 2= 超时;Provider 里通常据此把pageState置为PageState.ConnectivityError / ConnectivityTimeOut,再notifyListeners()。 - 断网时
DioUtil内部会Utils.showToast("网络错误,请稍后重试")。 - 上传文件(FormData)可参考
FinanceProvider.upLoadApplyments/UploadImageProvider(七牛上传)。
10. 数据模型规范
- 文件在
lib/models/,类名多为Xxx/XxxSunModel;当前约 202 个模型文件、53 个.g.dart。命名不统一,新增时按同类模块现有命名。 - 使用
json_serializable:类上加@JsonSerializable(),文件末尾part 'xxx.g.dart';,提供factory Xxx.fromJson(...)与toJson()。 - 修改模型字段后运行 build_runner 重新生成
.g.dart:fvm flutter pub run build_runner build --delete-conflicting-outputs
11. 常用工具速查
-
Utils(lib/utils/utils.dart):-
Utils.showToast(msg):Toast 提示; -
Utils.changeStatusColor({color}):状态栏颜色; -
Utils.getImgPath(name):拼assets/name.png; -
Utils.getAuthority(context, key):角色权限判断; -
Utils.keySort(map):参数签名排序(部分接口需要); -
Utils.compressImage / compressImageToFile:图片压缩; - 时间/农历/正则/手机号脱敏等大量工具方法。
-
-
DialogUtil(lib/utils/dialog_util.dart):标签选择、滚轮选择器、消息弹窗、日历选择等。 -
EventBus(lib/utils/event_bus.dart):全局bus.on(事件名, cb)/bus.emit(事件名, arg)。 - 权限:
lib/utils/misc.dart的requestPermission(Permission.xxx)(带使用目的说明弹窗)。 - 全局存储:
App.sp!.getString / setString / getBool ...(SharedPreferences 单例)。
12. 注意事项与常见坑
-
适配写法不要混用:
w()是 375 口径、ScreenUtil().setWidth()是 750 口径,混用会直接导致尺寸差一倍。同一文件保持一种风格。 - VEmptyView/HEmptyView 是 750 口径:按 375 稿子写间距要 ×2(§6.2 有对照表)。
-
h()是宽度等比缩放:不要用它做需要按屏幕高度伸缩的布局;需要高度适配用h2()。 -
极速版同步:
lib/pages_sim/是极速版副本,修改正常版核心页面时注意是否需要在 sim 版同步;路由常量带_sim后缀。 -
老页面是状态机:列表页先判
PageState再渲染ExceptionPage/ListView,不要绕过直接写列表。 - 接口地址都在 HttpUrl:不要在新代码里硬编码 URL。
-
模型改了记得跑 build_runner,否则
fromJson不会更新。 -
打包注意事项(
lib/constant/constant.dart注释):Constant.normalApp控制极速版是否打包;测试账号已由0001换成0019;微信小程序类型Constant.wxMiniProgramType分正式/体验/开发。 -
新建图片记得放
assets/(目录已全量声明,无需改 pubspec,除非新增音频 mp3 需单独声明)。 -
请求里传
sellerid/openid前判空,UserModel 未登录时user可能为 null。
13. 高频改动定位
| 目标 | 入口 |
|---|---|
| 新增接口 | lib/net/http_url.dart |
| 新增页面/跳转 |
lib/route/routes.dart + route_handles.dart + navigator_util.dart
|
| 用户登录/微信/店铺绑定 |
lib/pages/login/、lib/provider/user_model.dart
|
| 首页 Tab、底部导航、消息角标 |
lib/pages/home/home_page.dart、lib/provider/message_model.dart
|
| 预订本列表 |
lib/pages/notebook/notebook_page.dart、lib/provider/notebook_model.dart
|
| 订单详情/变更预订/处理在线预订 |
lib/pages/detail/、lib/provider/notebook_detail_model.dart、notebook_detail_change_model*.dart
|
| 桌位/区域/照片 |
lib/pages/table/、lib/pages/my/table_manage/、lib/pages/my/photo_type/
|
| 宴会 |
lib/pages/feast/、lib/pages/my/feast_manage/、lib/provider/feast_model.dart
|
| 客情/客户/营销 |
lib/pages/my/customer_type/、lib/provider/customer_provider.dart
|
| 营销中心/预约通知/短信 |
lib/pages/my/marketing_center/、lib/provider/marketing_center_provider.dart
|
| 优惠券 |
lib/pages/coupon/、lib/provider/coupon_provider.dart
|
| 消费金/会员充值/收银 |
lib/pages/my/consume/、lib/pages/my/finance_manage/、lib/provider/finance_provider.dart
|
| 我的页面/个人信息 |
lib/pages/my/my_page.dart、lib/pages/my/base_info.dart、lib/provider/my_model.dart
|
| 权限配置 |
lib/constant/constant.dart 的 Constant.authorityConfig
|
| 极速版 | 对应页面在 lib/pages_sim/,路由带 _sim
|
14. 新页面开发 Checklist
-
页面文件放对应业务目录(
lib/pages/模块/xxx_page.dart),类名XxxPage; -
import
utils/screen_util.dart,全程用w()/font()/r(),不写ScreenUtil().setWidth; -
间距用
VEmptyView/HEmptyView(375 稿数值 ×2),分割线用MyDivider; -
颜色只从
MyColours取; -
导航栏用
SystemAppBar(普通页)/MyAppBar(自定义样式); -
请求方法放对应 Provider,
HttpUrl加接口,成功判断code == Constant.status_success; -
页面状态用
PageState + ExceptionPage; -
在
routes.dart、route_handles.dart、navigator_util.dart完成三步注册; -
需要权限的入口用
Utils.getAuthority(context, key)过滤; -
涉及正常版/极速版双端时,检查
pages_sim是否需要同步。