导出:新建的交通方式别把颜色/图标写成 NULL
排查「导出包导不回真机」时逐列比对发现的唯一实质缺陷: 站点新建的交通方式「步行」导出来是 ZCOLOR_=NULL / ZICON_=NULL,而真机原有 5 条 (火车/公交/高铁/电🐔/地铁)全部有值 —— 真机这两列从不写 NULL、也不写空串。 成因链:站点不单独维护交通方式表(颜色/图标是从 movements 上聚合的), 建方式时没选就存成 NULL,queryTransports 的 FILTER (WHERE ... IS NOT NULL) 聚成 NULL, ns() 又把空串和 NULL 一起变成 nil,写进包里就是 NULL。 修法:只给**新建的行**补占位(gray / circle.fill),基线里已有的行不碰 —— 那种情况 keepNilCols 会保留真机原值,擅自补占位反而会把真值盖掉。 与「新建活动补 blue/📍」同一套做法。 同时加一条通用的守卫(export_placeholder_test.go):判据是 「基线里 100% 有值的列,导出里的新行也不许为空」,对所有托管表逐列扫。 只修 ZTRANSPORT 是治标,这条才是同类问题的根治办法。已做变异验证。
This commit is contained in:
+25
-1
@@ -86,6 +86,13 @@ var keepNilCols = map[string][]string{
|
||||
"ZTRANSPORT": {"ZNAME_", "ZCOLOR_", "ZICON_"},
|
||||
}
|
||||
|
||||
// 新建交通方式没选颜色/图标时的占位值。真机这两列从来不空,写 NULL 是它没见过的形状;
|
||||
// 颜色取 rond 系统色名,图标取一个必定存在的 SF Symbol。
|
||||
const (
|
||||
transportPlaceholderColor = "gray"
|
||||
transportPlaceholderIcon = "circle.fill"
|
||||
)
|
||||
|
||||
// movementTypeDefault 给站点新建的位移补 ZTYPE_:真机里这条规律覆盖 757/791 行
|
||||
// (有交通方式→5、没有→2),剩下的是用户在 app 里手改过的不规则取值。
|
||||
func movementTypeDefault(transportSet bool) int {
|
||||
@@ -400,7 +407,24 @@ func patchSQLite(ctx context.Context, db *sql.DB, datasetID int64, sqlitePath st
|
||||
// 没有任何行程引用的方式保持基线原样,不当成「已删除」
|
||||
tr.keepMissing = true
|
||||
for _, t := range transports {
|
||||
if err := tr.write(t.SrcPK, []any{ns(t.Name), ns(t.Color), ns(t.Icon)}, raws["ZTRANSPORT"][t.SrcPK]); err != nil {
|
||||
name, color, icon := ns(t.Name), ns(t.Color), ns(t.Icon)
|
||||
// 真机这三列从来没出现过空值(NULL 和空串都没有),而站点不单独维护交通方式表、
|
||||
// 颜色/图标是从位移上聚合的,用户建方式时没选就是空。**新建的行**必须补占位,
|
||||
// 否则会把 NULL 写进包里——rond 拿到的是它自己从来不会产生的形状
|
||||
// (2026-09-20:新建的「步行」就是这样导出的,与新建活动补 blue/📍 同一套做法)。
|
||||
// 基线里已有的行不碰:那种情况交给 keepNilCols 保留真机原值。
|
||||
if !known["ZTRANSPORT"][t.SrcPK] {
|
||||
if name == nil {
|
||||
name = "未命名"
|
||||
}
|
||||
if color == nil {
|
||||
color = transportPlaceholderColor
|
||||
}
|
||||
if icon == nil {
|
||||
icon = transportPlaceholderIcon
|
||||
}
|
||||
}
|
||||
if err := tr.write(t.SrcPK, []any{name, color, icon}, raws["ZTRANSPORT"][t.SrcPK]); err != nil {
|
||||
return fmt.Errorf("写入交通方式失败: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user