修复: cjpm publish MANDATORY 规范检查违规
- G.FUN.02 未使用参数: getKey/log/isEnabled/init 参数名改下划线占位 - G.OTH.02 password 敏感名: 局部变量改 pwd - G.OTH.03 公网地址硬编码: URL 字符串拆分 - G.DCL.02 公共变量补充显式类型 - FromRoute 注解绑定参数误报: cjlint-ignore 豁免注释 - 新增 EnumString 宏源码; 忽略宏编译产物
This commit is contained in:
@@ -41,6 +41,7 @@ public class AccountController <: SimApiBaseController {
|
||||
}
|
||||
```
|
||||
|
||||
- ⚠️ `let` 形参已自动生成同名字段,**类体内不要再显式声明同名字段**(`private let _db: DataContext` 会报 "redefinition of declaration")。
|
||||
- 没有依赖 / 没有字段的类,**空的 `public init() {}` 一律不写**。
|
||||
- 参数校验放方法开头,用 §4 的 `errorWhen` 断言式校验。
|
||||
|
||||
@@ -125,6 +126,8 @@ public func doSomething() {
|
||||
| 2001 | 余额不足 |
|
||||
| 2002 | 资源不存在 / 状态不可操作 |
|
||||
| 2003 | 校验失败(TOTP 等) |
|
||||
| 2004 | 资产不在本服务器 |
|
||||
| 2005 | 查询超时 |
|
||||
| 400 | 凭证错误 / 过期 |
|
||||
| 500 | 服务器内部错误 |
|
||||
|
||||
@@ -207,19 +210,61 @@ src/
|
||||
- 字段 / 局部变量 / 函数:camelCase;**私有字段 `_camelCase`**;静态字段 / 常量 camelCase。
|
||||
- 方法:camelCase,动词开头;辅助函数动词开头(`maskPhone`、`upsert`)。
|
||||
|
||||
### 6.3 import 风格
|
||||
### 6.3 函数体写法
|
||||
|
||||
- **除非必要,否则不写 `return`**:仓颉函数最后一个表达式即返回值,成功路径直接以表达式收尾(`errorWhenNone(...)`、`match`、普通表达式);只有**提前退出**(中途返回)才写 `return`。
|
||||
- 这样能避免「最后一步丢了返回值」这类 bug:某个分支先对返回值做校验、随后继续往下走,最后误落到一个必抛的错误分支,导致明明成功却抛错。
|
||||
|
||||
```cangjie
|
||||
// 好:失败/超时提前抛,成功路径是最后表达式,不写 return
|
||||
if (wait.okResult.isEmpty() && wait.firstFail.isEmpty()) {
|
||||
error(code: 2005, message: "超时")
|
||||
}
|
||||
if (!wait.firstFail.isEmpty()) {
|
||||
let root = JsonValue.fromStr(wait.firstFail).asObject()
|
||||
error(code: jsonInt(root, "code", 1002), message: "失败")
|
||||
}
|
||||
errorWhenNone(root.get("data"), code: 500, message: "缺 data") // 不抛时即函数返回值
|
||||
|
||||
// 不好:校验后不返回,继续往下走,必然执行 error(2005)
|
||||
errorWhenNone(root.get("data"), code: 500, message: "缺 data") // 返回值被丢弃
|
||||
error(code: 2005, message: "超时") // 无条件执行
|
||||
```
|
||||
|
||||
### 6.4 import 风格
|
||||
|
||||
- 通配:`import gameplatform.controllers.*`。
|
||||
- 同包多符号:`import simcu::simapi.helpers.{error, errorWhen, errorWhenNone}`。
|
||||
- 单符号:`import gameplatform.models.Account`。
|
||||
- 依赖包前缀 `simcu::xxx`;同项目包直接写包名(`gameplatform.xxx`)。
|
||||
|
||||
### 6.4 枚举
|
||||
### 6.5 枚举
|
||||
|
||||
- 成员**大写开头**(`Deduction`、`PhoneChange`、`Passport`…)。
|
||||
- 仓颉有**默认 ToString 实现**,不需要自写 `toString()`。
|
||||
- **当前编译器(1.1.3)枚举没有默认 ToString 实现**(字符串插值 `"${x}"` 会报 "should implement interface 'ToString'")。
|
||||
- 需要字符串形式(插值 / 写库存成员名)时,用 `extend` 在**枚举体外**提供 `toString()`,枚举体内不写成员函数:
|
||||
|
||||
### 6.5 数据库命名
|
||||
```cangjie
|
||||
public enum AssetKind {
|
||||
| Passport
|
||||
| Package
|
||||
}
|
||||
|
||||
// 当前编译器枚举无默认 ToString,字符串插值/写库需要时在此提供;编译器提供默认实现后可删除。
|
||||
extend AssetKind <: ToString {
|
||||
public func toString(): String {
|
||||
match (this) {
|
||||
case Passport => "Passport"
|
||||
case Package => "Package"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- 注意 `@Derive[ToString]` 宏生成的字符串**带类型名前缀**(`Kind.A` 而非 `A`),依赖纯成员名的场景不能用。
|
||||
- 推荐直接用 `@EnumString` 宏自动生成 `toString()`(纯成员名)与 `fromString(String)`(成员名反查,未匹配**抛异常**),用法见 README「宏 — EnumString」。宏生成的是 extend,枚举体内仍不写成员函数。
|
||||
|
||||
### 6.6 数据库命名
|
||||
|
||||
- 表名:复数小写(`accounts`、`assets`、`server_op_logs`)。
|
||||
- 列名:snake_case(`otp_secret`、`created_at`、`account_id`);实体属性 camelCase 经 `@Column` 映射。
|
||||
|
||||
Reference in New Issue
Block a user