无尘阁日记

无尘阁日记

我们如何把一堆中文动作定义,落地成“可维护的 MySQL + PHP Traits”:完整复盘(含可复用套路)
2025-08-20

这是一篇把我们今天从“需求口头描述 ➜ 规则敲定 ➜ SQL 重写 ➜ PHP 代码骨架生成”完整走通的实战复盘。风格尽量接地气,细节到位,拿走就能用。

一、背景与目标

  • 输入:一份 INSERT INTO TJ_SysActionCode (ActionCode, ActionName, ActionCnName, Download) 的 SQL,ActionName 多为中文、重复严重;ActionCnName 是全称描述。

  • 输出

    1. 基于 ActionCnName 全称 生成**英文大驼峰(PascalCase)**的 ActionName唯一不超过指定长度);

    2. 若 ActionCnName 含 “(形式为链接,点击直接下载底稿文件)”,则 Download=1,否则 0;

    3. 将动作按 4xxx / 5xxx / 6xxx 拆分为 3 个 PHP trait方法名=SQL 里的英文 ActionName,全部 public static,带注释骨架可直接实现。


二、规则敲定(关键点)

  1. 命名来源ActionName 必须由 ActionCnName 全称推导(而不是短语),确保唯一性与可追溯。

  2. 括号简写(资产基础法)→ AB(新收益法)→ IN(单项资产)→ SA(可扩展)。

  3. 下载标记ActionCnName 含 “(形式为链接,点击直接下载底稿文件)” ➜ Download=1

  4. 长度上限:不超过字符串 CopiedSourceProjectAndCompanyCopyNewABProject 的长度(我们用它当上限标尺)。

  5. 冲突处理:若生成的 ActionName 仍重复,追加数字后缀(仍不超长)。

  6. 分组生成 traits

    • 4xxx ➜ ActionABTrait

    • 5xxx ➜ ActionINTrait

    • 6xxx ➜ ActionSATrait
      方法名 = 英文 ActionName(必要时追加数字)。

三、落地方案(可复用)

1)解析原始 SQL

  • 用正则抓 (ActionCode, 'ActionName', 'ActionCnName', Download) 四元组。

  • 注意:中文全角括号中文逗号都要原样保留;字符串引号要安全转义。

2)生成英文 ActionName(核心算法)

  • 主体词:取 ActionCnName 第一个中文括号  前的部分,映射为英文词(如 “下载的申报表底稿” → DownloadDeclarationDraft)。

  • Link 规则:若 ActionCnName 包含 下载链接短语,在英文名中追加 WithLink 并将 Download=1

  • 上下文短语:取各层括号里的业务短语(如 “下载部分科目,手动选择科目”、“保存底稿”等),映射为 短英文 token(最多保留 1~2 个,避免过长)。

  • 方法简写:将括号里的方法论简写为 AB/IN/SA 等附加到尾部(如 ...AB)。

  • 长度控制:若超长,按“先砍上下文 → 保留 WithLink 与简写 → 仍长则只留主体 + 简写 → 最后必要时截断”的顺序降级。

  • 唯一性:若仍与已有英文名重复,按 Name2/Name3… 方式追加数字(加后缀前判断长度,必要时对主体尾部做裁剪以适配)。

实战数据:本次 234 条记录,分组后 4xxx=90、5xxx=91、6xxx=53Download=1 共 18 条(用于核验)。

3)回写成 MySQL INSERT

  • 仍然是 INSERT INTO TJ_SysActionCode (...) VALUES 多值插入。

  • 字符串 单引号转义

  • 建议另存为新文件(保留原始文件),便于 git diff 审查。

4)生成 3 个 PHP traits(可直接用)

  • 每个 trait 内,每条记录一个静态方法
    public static function <ActionName>(array $payload = []): void

  • DocBlock 注释包含:ActionCode / ActionName / ActionCnName / Download,方便实现方快速了解上下文。

  • 处理方法名冲突:如英文名完全一致,则自动在方法名尾部追加 _ActionCode 或数字(我们用数字后缀,保持简短)。

四、细节坑点与规避

  1. 中文括号是  (全角),不能误写成半角 ()规则匹配要对准

  2. 下载标记要用完整短语匹配:“(形式为链接,点击直接下载底稿文件)”,避免误伤其它“链接”描述。

  3. MySQL 与 SQL Server 差异

    • MySQL 无 N'...' 前缀;

    • 编码统一 UTF-8

    • 大批量多值 INSERT 没问题,但要注意行长度与 max_allowed_packet(非常大时可拆批)。

  4. 命名长度控制:先保核心语义,再保 WithLink 与方法简写,最后才截断。

  5. 唯一性策略:先尝试语义上的 disambiguation(上下文 token),仍冲突再追加数字;追加后仍要检查长度。

  6. PHP 文件编码UTF-8(无 BOM);命名空间固定;方法签名统一,方便 IDE 跳转和后续代码生成替换。

  7. 团队约定:把简写表(AB/IN/SA…)、上下文 token 映射表,落成 README,后续新增词统一维护,避免“越长越乱”。

五、交付与核验清单(拿去就跑)

SQL 侧

  • ✅ 总数一致SELECT COUNT(*) FROM TJ_SysActionCode;(应等于 234 或你的实际条数)

  • ✅ Download=1 核验


    1. SELECT COUNT(*) FROM TJ_SysActionCode

    2. WHERE ActionCnName LIKE '%%(形式为链接,点击直接下载底稿文件)%%';

  • ✅ 长度校验


    1. SELECT ActionCode, ActionName, LENGTH(ActionName) AS len

    2. FROM TJ_SysActionCode

    3. WHERE LENGTH(ActionName) > LENGTH('CopiedSourceProjectAndCompanyCopyNewABProject');

  • ✅ 唯一性校验


    1. SELECT ActionName, COUNT(*) c

    2. FROM TJ_SysActionCode

    3. GROUP BY ActionName

    4. HAVING c > 1;

PHP 侧

  • ✅ trait 能被加载:


    1. require 'ActionABTrait.php';

    2. require 'ActionINTrait.php';

    3. require 'ActionSATrait.php';

    4. class Actions {

    5.    use \App\Actions\ActionABTrait;

    6.    use \App\Actions\ActionINTrait;

    7.    use \App\Actions\ActionSATrait;

    8. }

    9. // smoke test: 调一个静态方法

    10. Actions::SomeActionName(['operator' => '张三']);

  • ✅ 静态分析:

    • php -l ActionABTrait.php(语法检查)

    • phpstan analyse(如使用 PHPStan)

    • phpcs(如使用 PHPCS 统一风格)

六、可复用“生成器”思路(伪代码)

# 1) 解析 SQL -> rows: [(code, action_name_original, action_cn, download)]# 2) 对每行:#   a. has_link = '(形式为链接,点击直接下载底稿文件)' in action_cn#   b. main_cn = action_cn.split('(')[0]      # 主体#   c. main_en = CN_MAIN_MAP[main_cn]         # 主体映射#   d. contexts = PAREN(...) 提取业务短语 -> 映射短token(最多取2个)#   e. methods = 资产基础法/新收益法/单项资产 -> AB/IN/SA#   f. 拼 ActionName = main_en + (WithLink)? + contexts + methods#   g. 若超长 -> 逐级裁剪(先 contexts,后 WithLink),仍超 -> 截断#   h. 若重名 -> 追加数字(考虑长度)#   i. Download = 1 if has_link else 0# 3) 写 MySQL INSERT 新文件# 4) 按 4xxx/5xxx/6xxx 划分,生成 3 个 PHP traits 文件(方法名=ActionName)

七、团队落地与持续改进

  • 版本管理:SQL 与 traits 统一入库(git),PR 审核看 diff。

  • CI 校验

    • 脚本自动校验“长度 / 唯一性 / Download 规则”;

    • PHP 语法与静态分析不过则阻断合并。

  • 枚举与映射表:将主体中文 → 英文上下文中文 → 英文 token括号简写 AB/IN/SA放入共享配置(JSON/YAML),后续派生自动同步。

  • 用例回放:给每个关键方法留最小化 payload 的 demo case,便于新人快速介入。

八、附:常用简写 / 词汇映射(可扩展)

中文简写/英文
资产基础法AB
新收益法IN
单项资产SA
下载测算底稿 / 保存底稿 / 上传底稿DownloadCalculationDraft / SaveDraft / UploadDraft
下载完整申报表DownloadFullDeclarationForms
下载部分科目,手动选择科目DownloadSelectedSubjectsManuallySelectSubjects
导入申报表 / 导入盘点表 / 下载勘查表ImportDeclarationForms / ImportInventoryForms / DownloadSurveyForms

建议把此表固化到 config/action_name_map.json,后面加词只改配置。

九、工具与资料

  • 工具:VS Code / PhpStorm、DataGrip / MySQL Workbench、PHPStan、PHPCS、Prettier(或 EditorConfig)

  • 书/文档(上手即用的那种):

    • SQL Antipatterns(Bill Karwin)

    • Clean Code(Robert C. Martin)

    • PHP Objects, Patterns, and Practice(M. Zandstra)

最后一句

这套流程的价值在于:把“命名规则、长度约束、唯一性、下载判定、代码骨架”规范化,让“下一轮批量新增/改动”只需改配置就能 一键重生 SQL 与 PHP 代码。
如果你接下来想把规则做成团队级“小工具”(CLI),我可以把我们用的脚本整合成 make actions 的一条命令,配好 CI 自动校验,一步到位。

如夜话,至此。