吴昊天 2444d60cc4 feat(订单核销): 恢复移动端核销页与 order_verific 接口,核销后进入待评价
仅开放给核销员/配送员,并补齐 page_link 与个人中心菜单契约路径。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-28 10:24:26 +08:00
..
2026-09-23 15:15:02 +08:00
2026-09-23 15:15:02 +08:00
2026-09-23 15:15:02 +08:00
2026-09-23 15:15:02 +08:00

CRMEB v8 安装目录说明

本目录是 CRMEB v8 系统的 Web 安装引导程序,通过浏览器访问 install/index.php 即可启动安装向导。安装向导是独立于 ThinkPHP 框架的纯 PHP 程序(主控逻辑全部在 index.php),按步骤 + 轮询方式分批执行安装任务,避免超时。

目录结构

install/
├── css/                          # 安装向导样式文件
├── images/install/               # 安装向导图片资源
├── js/                           # 前端依赖脚本
├── templates/                    # 安装步骤 PHP 模板
│   ├── header.php                # 公共头部(HTML head、导航)
│   ├── footer.php                # 公共底部(版权信息)
│   ├── step1.php                 # 步骤1 - 安装许可协议
│   ├── step2.php                 # 步骤2 - 运行环境检测
│   ├── step3.php                 # 步骤3 - 数据库及管理员配置
│   ├── step4.php                 # 步骤4 - 安装执行过程(前端轮询驱动)
│   └── step5.php                 # 步骤5 - 安装完成
│
├── data/                         # 按表拆分的核心初始数据 SQL
│   ├── system_config_data.sql
│   ├── system_menus_data.sql
│   └── ...
│
├── .env                          # 环境配置模板(含占位符,安装时替换)
├── index.php                     # 安装入口文件(主控逻辑)
├── crmeb_table.sql               # 数据库表结构(仅 CREATE TABLE)
├── crmeb.sql.bak                 # 原始完整 SQL 备份(结构+数据未拆分版本),不参与安装
│
├── install.log                   # 安装过程日志(运行时生成,记录每条建表/写数据/插件安装结果)
└── ../install.lock               # 安装完成锁文件(运行时生成于 public/ 下)

安装流程

安装向导共 5 个步骤,由 index.php 中的 $step 参数控制跳转:

步骤 模板文件 说明
1 step1.php 许可协议 — 展示用户协议,需同意后方可继续
2 step2.php 环境检测 — 检查 PHP 版本、扩展、目录/文件读写权限(详见下文「环境检测项」)
3 step3.php 参数设置 — 填写数据库连接信息(MySQL + Redis)、管理员账号密码、表前缀、是否导入演示数据;提交前分别校验 MySQL 与 Redis 连通性(详见「连接校验错误码」)
4 step4.php 安装执行 — 前端轮询接口分批执行「表结构 → 默认数据 → 插件」三个阶段(详见「安装执行三阶段」),随后写入 .env、创建管理员账户
5 step5.php 安装完成 — 展示安装结果,写入 .constant(安装时间与序列号),生成 install.lock 锁文件防止重复安装

环境检测项(步骤2)

  • PHP 版本:8.2.0 ≤ 版本 < 8.5.0(向导展示区间为 8.2-8.4,与 backend/composer.json 的 php 约束一致),不满足直接终止安装。
  • PHP 扩展/配置:mysqli、curl、gd、bcmath、openssl、file_uploads、session。
  • 目录可写:backend/backup、backend/public、backend/runtime(不存在时自动创建)。
  • 文件可读写:backend/.env、backend/.version、backend/.constant。

连接校验错误码(步骤3)

MySQL 校验(前端提交 mysqldbpwd 触发):

返回值 含义
1 连接成功(数据库不存在但有创建权限时,会试建后删除验证)
2002 地址或端口错误
1045 用户名或密码错误
-1 连接失败
-2 MySQL ≥ 5.7 且 sql_mode 含 STRICT_TRANS_TABLES / STRICT_ALL_TABLES / TRADITIONAL / ANSI,需要调整数据库配置
-3 目标数据库非空(已存在数据表,不允许覆盖安装)
-4 数据库不存在且无权限创建
-5 MySQL 版本过低(须 ≥ 5.7,推荐 8.0)

Redis 校验(前端提交 redisdbpwd 触发):实际执行 connect → auth(有密码时)→ select(指定库时)→ set 写入测试键,返回 1 成功、-1 redis 扩展缺失或对象创建失败、-3 连接或写入失败。

安装执行三阶段(步骤4)

安装接口为 index.php?step=4&install=1&phase={tables|data|plugins}&n={游标},前端逐次轮询,每次请求只执行一个最小任务单元,页面实时显示当前进度:

阶段 phase 值 任务单元 结束流转
表结构 tables 执行一条 CREATE TABLE(执行前先 DROP TABLE IF EXISTS 同名表,支持覆盖安装) 全部建表完成后返回 phase=data,游标归零
默认数据 data 执行一个数据文件(文件内全部 INSERT 一次执行) 全部文件写入后执行收尾(见下),返回 phase=plugins
插件安装 plugins 初始化 ThinkPHP 后调用 ModuleInstaller::install() 执行一个默认安装项(模块/驱动的自有表、菜单与种子数据由各自 Installer 负责) 游标返回 n=999999 表示全部完成
  • 三个阶段的游标 n 相互独立,避免数据阶段沿用表结构的总游标。
  • 数据阶段结束后由 finalizeBaseInstall() 统一收尾:按需清空演示数据、替换并写入 .env、重建管理员账户(truncate 后插入 id=1 超管)、按安装域名更新 system_config 的 site_url。
  • 每一步执行结果都追加写入 install.log,失败时接口返回 n=-2 并携带失败原因,前端停止轮询并展示错误。

SQL 文件设计

采用表结构 SQL 和按表拆分的数据目录维护安装数据:

  • crmeb_table.sql — 核心数据库表结构(仅含 CREATE TABLE 语句)。
  • data/*_data*.sql — 按表拆分的核心初始数据,一个文件对应一张表。文件名必须匹配 ^[a-z0-9_]+_data(?:_\d+)?\.sql$(如 system_config_data.sql),文件名字典序即安装顺序;数据量特别大的表可拆分为 table_data_001.sql、table_data_002.sql 等文件(序号补零格式),拆分文件会按序合并为同一张表的任务单元。
  • 安装程序读取数据文件时仅提取其中的 INSERT INTO 语句,其余内容(注释、SET 等)忽略。
  • crmeb.sql.bak — 原始完整 SQL 备份(结构+数据未拆分版本),仅用于对照和留档,安装程序不读取。

新增核心表与初始数据(维护指南)

核心安装 SQL 只承载系统框架自身的表与初始数据;插件/驱动的自有表、菜单与种子数据一律由各自 Installer 负责(遵循插件开发规范),不要写入本目录。

新增核心表:

  1. 在 crmeb_table.sql 末尾追加 CREATE TABLE IF NOT EXISTS \eb_表名`语句,表名一律用默认前缀eb_` 书写(安装时按用户配置前缀动态替换);
  2. 表结构阶段每次请求执行一条 CREATE(执行前先 DROP 同名表),无需额外登记。

新增核心初始数据:

  1. 在 data/ 下新建 {表名}_data.sql,一个文件只写一张表的 INSERT INTO \eb_表名` ...` 语句;
  2. 文件名字典序即执行顺序,跨表外键依赖(如先配置分组后配置项)靠命名顺序保证;
  3. 数据量大时可拆分为 {表名}_data_001.sql、{表名}_data_002.sql(序号补零),同一张表的拆分文件按序合并为一个任务单元一次执行;
  4. 文件中不要写注释、SET 等非 INSERT 语句(会被忽略);不要出现生产域名(用 http://demo.crmeb.com 占位,安装时自动替换为实际域名,含 JSON 转义形式)。

SQL 预处理规则

所有安装 SQL 在执行前统一经过 prepareInstallSql() 处理:

替换项 说明
表前缀 `eb_ → `{用户配置前缀}_(仅按反引号形式整体替换,避免误伤 smtp_host 等普通字段名)
演示站域名 http://demo.crmeb.com → 实际安装域名
JSON 内层域名 http:\/\/demo.crmeb.com(JSON 转义形式)→ 转义形式的实际域名,保证 eb_diy、eb_theme 等 JSON 数据安装后同样指向本站

实际域名(scheme + host)按以下优先级获取,适配反向代理部署:

  1. 反向代理头 X-Forwarded-Proto / X-Forwarded-Host;
  2. HTTPS / HTTP_HOST;
  3. SERVER_NAME(非标准端口时自动拼接端口号)。

.env 配置模板

.env 文件包含占位符,安装过程中由安装程序自动替换为用户填写的实际值后写入 backend/.env:

占位符 说明
#APP_KEY# 应用密钥(自动生成,格式 app_key_{uniqid})
#DB_HOST# / #DB_PORT# / #DB_USER# / #DB_PWD# / #DB_NAME# / #DB_PREFIX# MySQL 数据库连接信息
#CACHE_TYPE# / #CACHE_PREFIX# / #CACHE_TAG_PREFIX# 缓存配置(file 或 redis),前缀含随机值用于多实例隔离
#RB_HOST# / #RB_PORT# / #RB_PWD# / #RB_SELECT# Redis 连接信息
#QUEUE_NAME# 队列名称(自动生成唯一值)

演示数据控制

步骤4可选择是否导入演示数据;不导入演示数据时,默认数据阶段收尾(finalizeBaseInstall())会对库中全部数据表执行 truncate,仅保留以下白名单表:

  • 清理发生在插件安装之前(tables → data → 清理 → plugins),因此插件/驱动安装的自有表与种子数据写入在清理之后,天然不受影响。
  • 白名单按 SHOW TABLES 实际存在的表过滤,仅对实际存在的表执行清理。

白名单($baseTables,共 37 项,按默认前缀 eb_ 列出,实际按用户配置前缀匹配):

分类 表名
系统配置 system_config、system_config_tab、system_group、system_group_data、system_event_data
菜单路由与权限 system_menus、system_route、system_route_cate、system_admin、system_user_level
系统任务与工单 system_crontab、system_ticket、system_city
内容与页面 diy、page_categroy、page_link、agreement、cache
物流配送 express、express_company、express_template、shipping_templates、shipping_templates_region
多语言 lang_code、lang_country、lang_type
会员与通知 member_right、member_ship、agent_level、notice_config、notice_channel
支付与驱动 pay_channel、pay_channel_platform、driver、printer_channel、out_interface
模块安装 module_install_log

运行时生成与读取的文件

文件 位置 说明
install.log install/ 目录内 每条建表、写数据、插件安装的结果日志(含时间戳与失败原因),排障首选
.env backend/.env 收尾阶段由模板替换占位符后写入
.constant backend/.constant 步骤5写入 INSTALL_DATE(安装时间戳)与 SERIALNUMBER(随机序列号)
install.lock public/install.lock 安装完成锁文件
.version backend/.version 非生成文件;步骤5读取其中 version / platform 用于安装完成页展示

关键逻辑说明

  • 防重复安装:入口处检测 public/install.lock,存在即阻止进入向导;如需重装,需手动删除 public/install.lock。
  • 环境变量优先:数据库和 Redis 连接信息默认值优先从容器的 MYSQL_HOST_IP、MYSQL_PORT、MYSQL_USER、MYSQL_PASSWORD、MYSQL_DATABASE、REDIS_HOST_IP 等环境变量获取,适用于 Docker 部署场景;表单填写值仍以步骤3提交为准。
  • 表前缀替换:SQL 文件默认使用 eb_ 前缀,安装时按反引号整体形式动态替换为用户配置前缀;覆盖安装时 DROP TABLE 按实际前缀执行。
  • 数据库不存在时自动创建:按 utf8mb4 / utf8mb4_general_ci 字符集执行 CREATE DATABASE IF NOT EXISTS。
  • 管理员账户:收尾阶段清空 system_admin 后写入 id=1 的超级管理员(账号为步骤3填写,密码经 PASSWORD_BCRYPT 加密,角色 roles=1)。
  • 站点域名写入:收尾阶段将安装访问域名以 JSON 字符串形式更新到 system_config 的 site_url(与系统配置读取侧 json_decode 约定一致)。
  • 最低要求:PHP 8.2-8.4(不含 8.5+),MySQL ≥ 5.7(推荐 8.0;5.7 需关闭严格 sql_mode),Redis 扩展(选择 redis 缓存时必需)。