@sfmc-bds/db-server 0.1.0 → 0.2.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. package/README.md +1 -1
  2. package/dist/db-tables.js +16 -17
  3. package/dist/db-tables.js.map +7 -1
  4. package/dist/domain/bridge.js +54 -77
  5. package/dist/domain/bridge.js.map +7 -1
  6. package/dist/domain/economy.d.ts +83 -2
  7. package/dist/domain/economy.d.ts.map +1 -1
  8. package/dist/domain/economy.js +292 -281
  9. package/dist/domain/economy.js.map +7 -1
  10. package/dist/domain/schema.js +480 -426
  11. package/dist/domain/schema.js.map +7 -1
  12. package/dist/domain/transaction.js +32 -80
  13. package/dist/domain/transaction.js.map +7 -1
  14. package/dist/env.d.ts.map +1 -1
  15. package/dist/env.js +85 -84
  16. package/dist/env.js.map +7 -1
  17. package/dist/index.d.ts +1 -1
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +218 -240
  20. package/dist/index.js.map +7 -1
  21. package/dist/lib/http.js +30 -39
  22. package/dist/lib/http.js.map +7 -1
  23. package/dist/lib/idempotency-store.js +34 -47
  24. package/dist/lib/idempotency-store.js.map +7 -1
  25. package/dist/lib/idempotency.js +8 -13
  26. package/dist/lib/idempotency.js.map +7 -1
  27. package/dist/lib/identifiers.js +18 -14
  28. package/dist/lib/identifiers.js.map +7 -1
  29. package/dist/lib/log.d.ts +3 -6
  30. package/dist/lib/log.d.ts.map +1 -1
  31. package/dist/lib/log.js +13 -14
  32. package/dist/lib/log.js.map +7 -1
  33. package/dist/lib/module-state.d.ts.map +1 -1
  34. package/dist/lib/module-state.js +32 -21
  35. package/dist/lib/module-state.js.map +7 -1
  36. package/dist/lib/order-by.d.ts +17 -0
  37. package/dist/lib/order-by.d.ts.map +1 -0
  38. package/dist/lib/order-by.js +24 -0
  39. package/dist/lib/order-by.js.map +7 -0
  40. package/dist/lib/runtime.js +16 -31
  41. package/dist/lib/runtime.js.map +7 -1
  42. package/dist/lib/sql-helpers.js +9 -27
  43. package/dist/lib/sql-helpers.js.map +7 -1
  44. package/dist/lib/sqlite.js +40 -52
  45. package/dist/lib/sqlite.js.map +7 -1
  46. package/dist/manifest-loader.d.ts.map +1 -1
  47. package/dist/manifest-loader.js +154 -195
  48. package/dist/manifest-loader.js.map +7 -1
  49. package/dist/manifest.d.ts +3 -7
  50. package/dist/manifest.d.ts.map +1 -1
  51. package/dist/manifest.js +76 -115
  52. package/dist/manifest.js.map +7 -1
  53. package/dist/module-auth.d.ts +17 -6
  54. package/dist/module-auth.d.ts.map +1 -1
  55. package/dist/module-auth.js +93 -107
  56. package/dist/module-auth.js.map +7 -1
  57. package/dist/module-runtime-sync.d.ts +37 -0
  58. package/dist/module-runtime-sync.d.ts.map +1 -0
  59. package/dist/module-runtime-sync.js +54 -0
  60. package/dist/module-runtime-sync.js.map +7 -0
  61. package/dist/permission-gate.d.ts.map +1 -1
  62. package/dist/permission-gate.js +55 -86
  63. package/dist/permission-gate.js.map +7 -1
  64. package/dist/routes/_shared.d.ts +7 -2
  65. package/dist/routes/_shared.d.ts.map +1 -1
  66. package/dist/routes/_shared.js +16 -25
  67. package/dist/routes/_shared.js.map +7 -1
  68. package/dist/routes/config.d.ts +11 -1
  69. package/dist/routes/config.d.ts.map +1 -1
  70. package/dist/routes/config.js +167 -213
  71. package/dist/routes/config.js.map +7 -1
  72. package/dist/routes/db-routes.d.ts +6 -10
  73. package/dist/routes/db-routes.d.ts.map +1 -1
  74. package/dist/routes/db-routes.js +198 -172
  75. package/dist/routes/db-routes.js.map +7 -1
  76. package/dist/routes/health.js +15 -20
  77. package/dist/routes/health.js.map +7 -1
  78. package/dist/routes/messages.d.ts.map +1 -1
  79. package/dist/routes/messages.js +56 -63
  80. package/dist/routes/messages.js.map +7 -1
  81. package/dist/routes/module-config-routes.d.ts.map +1 -1
  82. package/dist/routes/module-config-routes.js +92 -111
  83. package/dist/routes/module-config-routes.js.map +7 -1
  84. package/dist/routes/modules.d.ts.map +1 -1
  85. package/dist/routes/modules.js +82 -88
  86. package/dist/routes/modules.js.map +7 -1
  87. package/dist/routes/service-routes.d.ts.map +1 -1
  88. package/dist/routes/service-routes.js +54 -61
  89. package/dist/routes/service-routes.js.map +7 -1
  90. package/dist/runtime.test.js +248 -49
  91. package/dist/runtime.test.js.map +7 -1
  92. package/dist/schema-registry.d.ts.map +1 -1
  93. package/dist/schema-registry.js +119 -160
  94. package/dist/schema-registry.js.map +7 -1
  95. package/dist/server.js +69 -72
  96. package/dist/server.js.map +7 -1
  97. package/dist/service-registry.d.ts.map +1 -1
  98. package/dist/service-registry.js +60 -67
  99. package/dist/service-registry.js.map +7 -1
  100. package/dist/services/builtin-handlers.d.ts +4 -0
  101. package/dist/services/builtin-handlers.d.ts.map +1 -1
  102. package/dist/services/builtin-handlers.js +34 -20
  103. package/dist/services/builtin-handlers.js.map +7 -1
  104. package/dist/services/economy-handlers.js +143 -132
  105. package/dist/services/economy-handlers.js.map +7 -1
  106. package/dist/tx-runner.d.ts +35 -11
  107. package/dist/tx-runner.d.ts.map +1 -1
  108. package/dist/tx-runner.js +293 -250
  109. package/dist/tx-runner.js.map +7 -1
  110. package/dist/where.js +71 -94
  111. package/dist/where.js.map +7 -1
  112. package/package.json +4 -4
@@ -1,462 +1,516 @@
1
- /**
2
- * domain/schema.ts — 数据库 schema 初始化(唯一真源)
3
- *
4
- * 所有 CREATE TABLE / CREATE INDEX 语句集中于此。
5
- * 调用方式:initSchema(db) — 在 openDatabase 之后、createQuery 之前执行。
6
- *
7
- * 事务描述:
8
- * - 无业务 Tx(本文件只做 DDL,不涉及业务事务)
9
- *
10
- * 业务域(按文件内 db.exec 块编号):
11
- * (1) 世界备份 (2) 玩家备份 (3) 计分板
12
- * (4) 玩家行为日志 (5) 聊天频道 (6) 聊天消息
13
- * (7) 红包 (8) 合作社主体/成员/邀请/账户
14
- * (9) 合作社商店项/商店组 (10) 合作社账变流水/审计
15
- * (11) 领地主体/成员/权限 (12) 领地邀请/审计/请求幂等
16
- * (13) 玩家指令用量 (14) 价格指数
17
- * (15) 每日任务/统计 (16) 经济账户/流水/幂等
18
- *
19
- * 完整表名以 `sfmc_` 前缀,具体见下方每个 db.exec 块。
20
- *
21
- * 备注: ALTER / DROP 不在此处;如需迁移请新建 tools/migrate-*.ts,
22
- * 保持本文件只做"全新初始化"。
23
- */
24
- export function initSchema(db) {
25
- // (1 世界备份数据
26
- db.exec(/* sql */ `
1
+ function initSchema(db) {
2
+ db.exec(
3
+ /* sql */
4
+ `
27
5
  CREATE TABLE IF NOT EXISTS sfmc_world (
28
- allow_cheats INTEGER NOT NULL DEFAULT 0, -- 允许作弊的选项
29
- game_rules TEXT NOT NULL DEFAULT '', -- 世界规则(json)
30
- seed TEXT DEFAULT '', -- 种子
31
- default_spawn_location TEXT NOT NULL DEFAULT '', -- 默认出生点
32
- difficulty TEXT NOT NULL DEFAULT '', -- 难度
33
- day INTEGER NOT NULL DEFAULT 0, -- 游戏天数(世界)
34
- ticking_areas_count INTEGER DEFAULT 0, -- 常加载区域数量
35
- absolute_time INTEGER NOT NULL DEFAULT 0, -- 游戏内时间(当前)
36
- structures_from_addon TEXT DEFAULT '', -- 来自模组的结构(在对应行为包内)
37
- structures_from_world TEXT DEFAULT '', -- 来自世界的结构 包含保存在内存与磁盘中的
38
- dynamic_property_total_byte_count INTEGER DEFAULT 0, -- 动态数据(世界)字节数
39
- moon_phase INTEGER NOT NULL DEFAULT 0, -- 月相(当前)
40
- updated_at TEXT NOT NULL DEFAULT '' -- 更新时间戳
41
- )`);
42
- // (2 玩家备份数据
43
- db.exec(/* sql */ `
6
+ allow_cheats INTEGER NOT NULL DEFAULT 0, -- \u5141\u8BB8\u4F5C\u5F0A\u7684\u9009\u9879
7
+ game_rules TEXT NOT NULL DEFAULT '', -- \u4E16\u754C\u89C4\u5219(json)
8
+ seed TEXT DEFAULT '', -- \u79CD\u5B50
9
+ default_spawn_location TEXT NOT NULL DEFAULT '', -- \u9ED8\u8BA4\u51FA\u751F\u70B9
10
+ difficulty TEXT NOT NULL DEFAULT '', -- \u96BE\u5EA6
11
+ day INTEGER NOT NULL DEFAULT 0, -- \u6E38\u620F\u5929\u6570\uFF08\u4E16\u754C\uFF09
12
+ ticking_areas_count INTEGER DEFAULT 0, -- \u5E38\u52A0\u8F7D\u533A\u57DF\u6570\u91CF
13
+ absolute_time INTEGER NOT NULL DEFAULT 0, -- \u6E38\u620F\u5185\u65F6\u95F4\uFF08\u5F53\u524D\uFF09
14
+ structures_from_addon TEXT DEFAULT '', -- \u6765\u81EA\u6A21\u7EC4\u7684\u7ED3\u6784\uFF08\u5728\u5BF9\u5E94\u884C\u4E3A\u5305\u5185\uFF09
15
+ structures_from_world TEXT DEFAULT '', -- \u6765\u81EA\u4E16\u754C\u7684\u7ED3\u6784 \u5305\u542B\u4FDD\u5B58\u5728\u5185\u5B58\u4E0E\u78C1\u76D8\u4E2D\u7684
16
+ dynamic_property_total_byte_count INTEGER DEFAULT 0, -- \u52A8\u6001\u6570\u636E\uFF08\u4E16\u754C\uFF09\u5B57\u8282\u6570
17
+ moon_phase INTEGER NOT NULL DEFAULT 0, -- \u6708\u76F8\uFF08\u5F53\u524D\uFF09
18
+ updated_at TEXT NOT NULL DEFAULT '' -- \u66F4\u65B0\u65F6\u95F4\u6233
19
+ )`
20
+ );
21
+ db.exec(
22
+ /* sql */
23
+ `
44
24
  CREATE TABLE IF NOT EXISTS sfmc_players (
45
- id TEXT NOT NULL, -- 实体id标识符
46
- name TEXT NOT NULL, -- 名称
47
- permission INTEGER DEFAULT 0, -- 权限等级(0=访客,1=成员,2=OP,3=管理员)TODO: 暂未适配自定义脚本权限
48
- client_system_info_local TEXT DEFAULT '', -- 客户端系统信息->本地化语言
49
- client_system_info_maxRenderDistance INTEGER DEFAULT 0, -- 客户端系统信息->最大渲染距离
50
- client_system_info_memoryTier_level TEXT DEFAULT '', -- 客户端信息->内存等级 详细请查看官方文档
51
- client_system_info_PlatformType TEXT DEFAULT '', -- 客户端系统信息->平台类型
52
- graphicsMode TEXT DEFAULT '', -- 图形模式
53
- dynamicPropertyTotalByteCount INTEGER DEFAULT 0, -- 动态属性总字节数
54
- ping INTEGER DEFAULT 0, -- 延迟(ms)
55
- spawnPoint TEXT DEFAULT '', -- 出生点坐标
56
- tags TEXT DEFAULT '', -- 玩家标签
57
- level INTEGER DEFAULT 0, -- 等级
58
- totalXp INTEGER DEFAULT 0, -- 总经验值
59
- afk_step INTEGER DEFAULT 0, -- AFK累计步数
60
- afk_last_location TEXT DEFAULT '', -- AFK最后位置
61
- onlinetime_session INTEGER DEFAULT 0, -- 在线时间->本次会话(秒)
62
- onlinetime_today INTEGER DEFAULT 0, -- 在线时间->今日(秒)
63
- onlinetime_month INTEGER DEFAULT 0, -- 在线时间->本月(秒)
64
- onlinetime_total INTEGER DEFAULT 0, -- 在线时间->累计(秒)
65
- onlinetime_last_date INTEGER DEFAULT 0, -- 在线时间->上次记录日期
66
- onlinetime_last_month INTEGER DEFAULT 0, -- 在线时间->上次记录月份
67
- active_channel TEXT NOT NULL DEFAULT '', -- 当前活跃聊天频道
68
- subscribed_channels TEXT DEFAULT '', -- 订阅的频道列表
69
- updated_at INTEGER NOT NULL, -- 玩家数据更新时间戳
70
- PRIMARY KEY (id, name) -- 联合主键:实体id+名称
71
- )`);
72
- // 玩家表索引:按id查、按name查
73
- db.exec(/* sql */ `
25
+ id TEXT NOT NULL, -- \u5B9E\u4F53id\u6807\u8BC6\u7B26
26
+ name TEXT NOT NULL, -- \u540D\u79F0
27
+ permission INTEGER DEFAULT 0, -- \u6743\u9650\u7B49\u7EA7\uFF080=\u8BBF\u5BA2,1=\u6210\u5458,2=OP,3=\u7BA1\u7406\u5458\uFF09TODO: \u6682\u672A\u9002\u914D\u81EA\u5B9A\u4E49\u811A\u672C\u6743\u9650
28
+ client_system_info_local TEXT DEFAULT '', -- \u5BA2\u6237\u7AEF\u7CFB\u7EDF\u4FE1\u606F->\u672C\u5730\u5316\u8BED\u8A00
29
+ client_system_info_maxRenderDistance INTEGER DEFAULT 0, -- \u5BA2\u6237\u7AEF\u7CFB\u7EDF\u4FE1\u606F->\u6700\u5927\u6E32\u67D3\u8DDD\u79BB
30
+ client_system_info_memoryTier_level TEXT DEFAULT '', -- \u5BA2\u6237\u7AEF\u4FE1\u606F->\u5185\u5B58\u7B49\u7EA7 \u8BE6\u7EC6\u8BF7\u67E5\u770B\u5B98\u65B9\u6587\u6863
31
+ client_system_info_PlatformType TEXT DEFAULT '', -- \u5BA2\u6237\u7AEF\u7CFB\u7EDF\u4FE1\u606F->\u5E73\u53F0\u7C7B\u578B
32
+ graphicsMode TEXT DEFAULT '', -- \u56FE\u5F62\u6A21\u5F0F
33
+ dynamicPropertyTotalByteCount INTEGER DEFAULT 0, -- \u52A8\u6001\u5C5E\u6027\u603B\u5B57\u8282\u6570
34
+ ping INTEGER DEFAULT 0, -- \u5EF6\u8FDF\uFF08ms\uFF09
35
+ spawnPoint TEXT DEFAULT '', -- \u51FA\u751F\u70B9\u5750\u6807
36
+ tags TEXT DEFAULT '', -- \u73A9\u5BB6\u6807\u7B7E
37
+ level INTEGER DEFAULT 0, -- \u7B49\u7EA7
38
+ totalXp INTEGER DEFAULT 0, -- \u603B\u7ECF\u9A8C\u503C
39
+ afk_step INTEGER DEFAULT 0, -- AFK\u7D2F\u8BA1\u6B65\u6570
40
+ afk_last_location TEXT DEFAULT '', -- AFK\u6700\u540E\u4F4D\u7F6E
41
+ onlinetime_session INTEGER DEFAULT 0, -- \u5728\u7EBF\u65F6\u95F4->\u672C\u6B21\u4F1A\u8BDD\uFF08\u79D2\uFF09
42
+ onlinetime_today INTEGER DEFAULT 0, -- \u5728\u7EBF\u65F6\u95F4->\u4ECA\u65E5\uFF08\u79D2\uFF09
43
+ onlinetime_month INTEGER DEFAULT 0, -- \u5728\u7EBF\u65F6\u95F4->\u672C\u6708\uFF08\u79D2\uFF09
44
+ onlinetime_total INTEGER DEFAULT 0, -- \u5728\u7EBF\u65F6\u95F4->\u7D2F\u8BA1\uFF08\u79D2\uFF09
45
+ onlinetime_last_date INTEGER DEFAULT 0, -- \u5728\u7EBF\u65F6\u95F4->\u4E0A\u6B21\u8BB0\u5F55\u65E5\u671F
46
+ onlinetime_last_month INTEGER DEFAULT 0, -- \u5728\u7EBF\u65F6\u95F4->\u4E0A\u6B21\u8BB0\u5F55\u6708\u4EFD
47
+ active_channel TEXT NOT NULL DEFAULT '', -- \u5F53\u524D\u6D3B\u8DC3\u804A\u5929\u9891\u9053
48
+ subscribed_channels TEXT DEFAULT '', -- \u8BA2\u9605\u7684\u9891\u9053\u5217\u8868
49
+ updated_at INTEGER NOT NULL, -- \u73A9\u5BB6\u6570\u636E\u66F4\u65B0\u65F6\u95F4\u6233
50
+ PRIMARY KEY (id, name) -- \u8054\u5408\u4E3B\u952E\uFF1A\u5B9E\u4F53id+\u540D\u79F0
51
+ )`
52
+ );
53
+ db.exec(
54
+ /* sql */
55
+ `
74
56
  CREATE INDEX IF NOT EXISTS idx_players_id ON sfmc_players(id);
75
- CREATE INDEX IF NOT EXISTS idx_players_name ON sfmc_players(name)`);
76
- // (3 计分板数据
77
- db.exec(/* sql */ `
57
+ CREATE INDEX IF NOT EXISTS idx_players_name ON sfmc_players(name)`
58
+ );
59
+ db.exec(
60
+ /* sql */
61
+ `
78
62
  CREATE TABLE IF NOT EXISTS sfmc_scoreboards (
79
- objective_id TEXT NOT NULL, -- 计分板目标id(主键)
80
- objective_display TEXT NOT NULL DEFAULT '', -- 计分板显示名称
81
- participants TEXT DEFAULT '', -- 参与者列表(json)
82
- updated_at INTEGER NOT NULL, -- 更新时间戳
83
- PRIMARY KEY (objective_id) -- 主键
84
- )`);
85
- // (4 玩家行为日志
86
- db.exec(/* sql */ `
63
+ objective_id TEXT NOT NULL, -- \u8BA1\u5206\u677F\u76EE\u6807id\uFF08\u4E3B\u952E\uFF09
64
+ objective_display TEXT NOT NULL DEFAULT '', -- \u8BA1\u5206\u677F\u663E\u793A\u540D\u79F0
65
+ participants TEXT DEFAULT '', -- \u53C2\u4E0E\u8005\u5217\u8868\uFF08json\uFF09
66
+ updated_at INTEGER NOT NULL, -- \u66F4\u65B0\u65F6\u95F4\u6233
67
+ PRIMARY KEY (objective_id) -- \u4E3B\u952E
68
+ )`
69
+ );
70
+ db.exec(
71
+ /* sql */
72
+ `
87
73
  CREATE TABLE IF NOT EXISTS sfmc_activities (
88
- id TEXT PRIMARY KEY, -- 唯一id
89
- timestamp INTEGER NOT NULL, -- 事件发生时间戳
90
- dimension TEXT NOT NULL DEFAULT '', -- 维度(overworld/nether/end
91
- source_type TEXT NOT NULL, -- 事件源类型(如player、entity、block等)
92
- source_id TEXT DEFAULT '', -- 事件源实体/方块id
93
- source_name TEXT NOT NULL DEFAULT '', -- 事件源名称
94
- source_x REAL, -- 事件源x坐标
95
- source_y REAL, -- 事件源y坐标
96
- source_z REAL, -- 事件源z坐标
97
- event_type TEXT NOT NULL, -- 事件类型(如chat、command、death、join等)
98
- target_type TEXT DEFAULT '', -- 目标类型
99
- target_id TEXT DEFAULT '', -- 目标实体id
100
- target_name TEXT NOT NULL DEFAULT '', -- 目标名称
101
- target_x REAL, -- 目标x坐标
102
- target_y REAL, -- 目标y坐标
103
- target_z REAL, -- 目标z坐标
104
- detail TEXT DEFAULT '{}', -- 事件详细信息(json)
105
- created_at INTEGER NOT NULL -- 记录创建时间戳
106
- )`);
107
- // 活动表索引:按源id查、按事件类型查、按目标id查
108
- db.exec(/* sql */ `
74
+ id TEXT PRIMARY KEY, -- \u552F\u4E00id
75
+ timestamp INTEGER NOT NULL, -- \u4E8B\u4EF6\u53D1\u751F\u65F6\u95F4\u6233
76
+ dimension TEXT NOT NULL DEFAULT '', -- \u7EF4\u5EA6\uFF08overworld/nether/end\uFF09
77
+ source_type TEXT NOT NULL, -- \u4E8B\u4EF6\u6E90\u7C7B\u578B\uFF08\u5982player\u3001entity\u3001block\u7B49\uFF09
78
+ source_id TEXT DEFAULT '', -- \u4E8B\u4EF6\u6E90\u5B9E\u4F53/\u65B9\u5757id
79
+ source_name TEXT NOT NULL DEFAULT '', -- \u4E8B\u4EF6\u6E90\u540D\u79F0
80
+ source_x REAL, -- \u4E8B\u4EF6\u6E90x\u5750\u6807
81
+ source_y REAL, -- \u4E8B\u4EF6\u6E90y\u5750\u6807
82
+ source_z REAL, -- \u4E8B\u4EF6\u6E90z\u5750\u6807
83
+ event_type TEXT NOT NULL, -- \u4E8B\u4EF6\u7C7B\u578B\uFF08\u5982chat\u3001command\u3001death\u3001join\u7B49\uFF09
84
+ target_type TEXT DEFAULT '', -- \u76EE\u6807\u7C7B\u578B
85
+ target_id TEXT DEFAULT '', -- \u76EE\u6807\u5B9E\u4F53id
86
+ target_name TEXT NOT NULL DEFAULT '', -- \u76EE\u6807\u540D\u79F0
87
+ target_x REAL, -- \u76EE\u6807x\u5750\u6807
88
+ target_y REAL, -- \u76EE\u6807y\u5750\u6807
89
+ target_z REAL, -- \u76EE\u6807z\u5750\u6807
90
+ detail TEXT DEFAULT '{}', -- \u4E8B\u4EF6\u8BE6\u7EC6\u4FE1\u606F\uFF08json\uFF09
91
+ created_at INTEGER NOT NULL -- \u8BB0\u5F55\u521B\u5EFA\u65F6\u95F4\u6233
92
+ )`
93
+ );
94
+ db.exec(
95
+ /* sql */
96
+ `
109
97
  CREATE INDEX IF NOT EXISTS idx_sfmc_act_source ON sfmc_activities(source_id, timestamp);
110
98
  CREATE INDEX IF NOT EXISTS idx_sfmc_act_event ON sfmc_activities(event_type, timestamp);
111
- CREATE INDEX IF NOT EXISTS idx_sfmc_act_target ON sfmc_activities(target_id, timestamp)`);
112
- // (5 聊天频道配置
113
- db.exec(/* sql */ `
99
+ CREATE INDEX IF NOT EXISTS idx_sfmc_act_target ON sfmc_activities(target_id, timestamp)`
100
+ );
101
+ db.exec(
102
+ /* sql */
103
+ `
114
104
  CREATE TABLE IF NOT EXISTS sfmc_chat_channels (
115
- id TEXT NOT NULL, -- 频道唯一id
116
- name TEXT NOT NULL, -- 频道名称
117
- type TEXT NOT NULL, -- 频道类型
118
- prefix TEXT NOT NULL, -- 频道前缀符号
119
- owner_id TEXT DEFAULT '', -- 频道所有者玩家id
120
- created_at INTEGER NOT NULL, -- 频道创建时间戳
121
- config_allow_chat INTEGER NOT NULL DEFAULT 1, -- 配置->是否允许聊天
122
- config_slow_mode INTEGER NOT NULL DEFAULT 0, -- 配置->慢模式间隔(秒)
123
- config_is_broadcast INTEGER NOT NULL DEFAULT 0, -- 配置->是否为广播频道
124
- updated_at INTEGER NOT NULL, -- 频道配置更新时间戳
125
- PRIMARY KEY (id, name) -- 联合主键
126
- )`);
127
- // 频道表索引:按id查、按name+创建时间查
128
- db.exec(/* sql */ `
105
+ id TEXT NOT NULL, -- \u9891\u9053\u552F\u4E00id
106
+ name TEXT NOT NULL, -- \u9891\u9053\u540D\u79F0
107
+ type TEXT NOT NULL, -- \u9891\u9053\u7C7B\u578B
108
+ prefix TEXT NOT NULL, -- \u9891\u9053\u524D\u7F00\u7B26\u53F7
109
+ owner_id TEXT DEFAULT '', -- \u9891\u9053\u6240\u6709\u8005\u73A9\u5BB6id
110
+ created_at INTEGER NOT NULL, -- \u9891\u9053\u521B\u5EFA\u65F6\u95F4\u6233
111
+ config_allow_chat INTEGER NOT NULL DEFAULT 1, -- \u914D\u7F6E->\u662F\u5426\u5141\u8BB8\u804A\u5929
112
+ config_slow_mode INTEGER NOT NULL DEFAULT 0, -- \u914D\u7F6E->\u6162\u6A21\u5F0F\u95F4\u9694\uFF08\u79D2\uFF09
113
+ config_is_broadcast INTEGER NOT NULL DEFAULT 0, -- \u914D\u7F6E->\u662F\u5426\u4E3A\u5E7F\u64AD\u9891\u9053
114
+ updated_at INTEGER NOT NULL, -- \u9891\u9053\u914D\u7F6E\u66F4\u65B0\u65F6\u95F4\u6233
115
+ PRIMARY KEY (id, name) -- \u8054\u5408\u4E3B\u952E
116
+ )`
117
+ );
118
+ db.exec(
119
+ /* sql */
120
+ `
129
121
  CREATE INDEX IF NOT EXISTS idx_channels_id ON sfmc_chat_channels(id);
130
- CREATE INDEX IF NOT EXISTS idx_channels_name ON sfmc_chat_channels(name, created_at ASC)`);
131
- // (6 聊天消息记录
132
- db.exec(/* sql */ `
122
+ CREATE INDEX IF NOT EXISTS idx_channels_name ON sfmc_chat_channels(name, created_at ASC)`
123
+ );
124
+ db.exec(
125
+ /* sql */
126
+ `
133
127
  CREATE TABLE IF NOT EXISTS sfmc_chat_messages (
134
- id TEXT PRIMARY KEY, -- 消息唯一id
135
- channel_id TEXT NOT NULL, -- 所属频道id
136
- from_id TEXT NOT NULL, -- 发送者玩家id
137
- from_name TEXT NOT NULL, -- 发送者名称
138
- type TEXT NOT NULL DEFAULT 'text', -- 消息类型
139
- content TEXT NOT NULL, -- 消息内容
140
- attachment TEXT, -- 附件信息
141
- show_timestamp INTEGER NOT NULL DEFAULT 0, -- 是否在消息列表显示时间戳
142
- created_at INTEGER NOT NULL -- 消息发送时间戳
143
- )`);
144
- // 消息表索引:按频道+时间查
145
- db.exec(/* sql */ `
146
- CREATE INDEX IF NOT EXISTS idx_messages_channel ON sfmc_chat_messages(channel_id, created_at ASC)`);
147
- // (7 聊天红包记录
148
- db.exec(/* sql */ `
128
+ id TEXT PRIMARY KEY, -- \u6D88\u606F\u552F\u4E00id
129
+ channel_id TEXT NOT NULL, -- \u6240\u5C5E\u9891\u9053id
130
+ from_id TEXT NOT NULL, -- \u53D1\u9001\u8005\u73A9\u5BB6id
131
+ from_name TEXT NOT NULL, -- \u53D1\u9001\u8005\u540D\u79F0
132
+ type TEXT NOT NULL DEFAULT 'text', -- \u6D88\u606F\u7C7B\u578B
133
+ content TEXT NOT NULL, -- \u6D88\u606F\u5185\u5BB9
134
+ attachment TEXT, -- \u9644\u4EF6\u4FE1\u606F
135
+ show_timestamp INTEGER NOT NULL DEFAULT 0, -- \u662F\u5426\u5728\u6D88\u606F\u5217\u8868\u663E\u793A\u65F6\u95F4\u6233
136
+ created_at INTEGER NOT NULL -- \u6D88\u606F\u53D1\u9001\u65F6\u95F4\u6233
137
+ )`
138
+ );
139
+ db.exec(
140
+ /* sql */
141
+ `
142
+ CREATE INDEX IF NOT EXISTS idx_messages_channel ON sfmc_chat_messages(channel_id, created_at ASC)`
143
+ );
144
+ db.exec(
145
+ /* sql */
146
+ `
149
147
  CREATE TABLE IF NOT EXISTS sfmc_chat_redpackets (
150
- id TEXT PRIMARY KEY, -- 红包唯一id
151
- sender_id TEXT NOT NULL, -- 发红包玩家id
152
- sender_name TEXT NOT NULL, -- 发红包玩家名称
153
- total_amount REAL NOT NULL, -- 红包总金额
154
- remaining_amount REAL NOT NULL, -- 剩余金额
155
- total_count INTEGER NOT NULL, -- 红包总个数
156
- remaining_count INTEGER NOT NULL, -- 剩余个数
157
- receivers TEXT NOT NULL DEFAULT '[]', -- 已领取玩家列表(json)
158
- target_type TEXT NOT NULL, -- 红包目标类型(all/channel/player等)
159
- target_id TEXT NOT NULL, -- 红包目标id
160
- created_at INTEGER NOT NULL, -- 红包创建时间戳
161
- expires_at INTEGER NOT NULL -- 红包过期时间戳
162
- )`);
163
- // 红包表索引:按id查
164
- db.exec(/* sql */ `
165
- CREATE INDEX IF NOT EXISTS idx_redpackets_id ON sfmc_chat_redpackets(id)`);
166
- // (8 合作社核心表
167
- db.exec(/* sql */ `
148
+ id TEXT PRIMARY KEY, -- \u7EA2\u5305\u552F\u4E00id
149
+ sender_id TEXT NOT NULL, -- \u53D1\u7EA2\u5305\u73A9\u5BB6id
150
+ sender_name TEXT NOT NULL, -- \u53D1\u7EA2\u5305\u73A9\u5BB6\u540D\u79F0
151
+ total_amount REAL NOT NULL, -- \u7EA2\u5305\u603B\u91D1\u989D
152
+ remaining_amount REAL NOT NULL, -- \u5269\u4F59\u91D1\u989D
153
+ total_count INTEGER NOT NULL, -- \u7EA2\u5305\u603B\u4E2A\u6570
154
+ remaining_count INTEGER NOT NULL, -- \u5269\u4F59\u4E2A\u6570
155
+ receivers TEXT NOT NULL DEFAULT '[]', -- \u5DF2\u9886\u53D6\u73A9\u5BB6\u5217\u8868\uFF08json\uFF09
156
+ target_type TEXT NOT NULL, -- \u7EA2\u5305\u76EE\u6807\u7C7B\u578B\uFF08all/channel/player\u7B49\uFF09
157
+ target_id TEXT NOT NULL, -- \u7EA2\u5305\u76EE\u6807id
158
+ created_at INTEGER NOT NULL, -- \u7EA2\u5305\u521B\u5EFA\u65F6\u95F4\u6233
159
+ expires_at INTEGER NOT NULL -- \u7EA2\u5305\u8FC7\u671F\u65F6\u95F4\u6233
160
+ )`
161
+ );
162
+ db.exec(
163
+ /* sql */
164
+ `
165
+ CREATE INDEX IF NOT EXISTS idx_redpackets_id ON sfmc_chat_redpackets(id)`
166
+ );
167
+ db.exec(
168
+ /* sql */
169
+ `
168
170
  CREATE TABLE IF NOT EXISTS sfmc_coops (
169
- cid TEXT PRIMARY KEY, -- 合作社唯一id
170
- name TEXT NOT NULL, -- 合作社名称
171
- owner_player_id TEXT NOT NULL, -- 社长玩家id
172
- owner_name_snapshot TEXT NOT NULL DEFAULT '', -- 社长名称快照
173
- status TEXT NOT NULL DEFAULT 'active', -- 状态(active/inactive/dissolved
174
- notice TEXT DEFAULT '', -- 合作社公告
175
- created_at INTEGER NOT NULL, -- 创建时间戳
176
- updated_at INTEGER NOT NULL, -- 更新时间戳
177
- fee_bps INTEGER NOT NULL DEFAULT 500, -- 税率(基点,500=5%)
178
- version INTEGER NOT NULL DEFAULT 1 -- 乐观锁版本号
179
- )`);
180
- // 合作社成员表
181
- db.exec(/* sql */ `
171
+ cid TEXT PRIMARY KEY, -- \u5408\u4F5C\u793E\u552F\u4E00id
172
+ name TEXT NOT NULL, -- \u5408\u4F5C\u793E\u540D\u79F0
173
+ owner_player_id TEXT NOT NULL, -- \u793E\u957F\u73A9\u5BB6id
174
+ owner_name_snapshot TEXT NOT NULL DEFAULT '', -- \u793E\u957F\u540D\u79F0\u5FEB\u7167
175
+ status TEXT NOT NULL DEFAULT 'active', -- \u72B6\u6001\uFF08active/inactive/dissolved\uFF09
176
+ notice TEXT DEFAULT '', -- \u5408\u4F5C\u793E\u516C\u544A
177
+ created_at INTEGER NOT NULL, -- \u521B\u5EFA\u65F6\u95F4\u6233
178
+ updated_at INTEGER NOT NULL, -- \u66F4\u65B0\u65F6\u95F4\u6233
179
+ fee_bps INTEGER NOT NULL DEFAULT 500, -- \u7A0E\u7387\uFF08\u57FA\u70B9\uFF0C500=5%\uFF09
180
+ version INTEGER NOT NULL DEFAULT 1 -- \u4E50\u89C2\u9501\u7248\u672C\u53F7
181
+ )`
182
+ );
183
+ db.exec(
184
+ /* sql */
185
+ `
182
186
  CREATE TABLE IF NOT EXISTS sfmc_coop_members (
183
- cid TEXT NOT NULL, -- 合作社id
184
- player_id TEXT NOT NULL, -- 成员玩家id
185
- player_name_snapshot TEXT NOT NULL DEFAULT '', -- 成员名称快照
186
- role TEXT NOT NULL DEFAULT 'member', -- 角色(member/admin/owner
187
- joined_at INTEGER NOT NULL, -- 加入时间戳
188
- expires_at INTEGER, -- 成员资格过期时间戳(null=永不过期)
189
- status TEXT NOT NULL DEFAULT 'active', -- 状态(active/expired/kicked
190
- version INTEGER NOT NULL DEFAULT 1, -- 乐观锁版本号
191
- PRIMARY KEY (cid, player_id), -- 联合主键
192
- FOREIGN KEY (cid) REFERENCES sfmc_coops(cid) ON DELETE CASCADE -- 级联删除
193
- )`);
194
- // 确保每个玩家只有一个active合作社成员记录
195
- db.exec(/* sql */ `
196
- CREATE UNIQUE INDEX IF NOT EXISTS idx_sfmc_one_active_coop_member ON sfmc_coop_members(player_id) WHERE status='active'`);
197
- // 合作社邀请表
198
- db.exec(/* sql */ `
187
+ cid TEXT NOT NULL, -- \u5408\u4F5C\u793Eid
188
+ player_id TEXT NOT NULL, -- \u6210\u5458\u73A9\u5BB6id
189
+ player_name_snapshot TEXT NOT NULL DEFAULT '', -- \u6210\u5458\u540D\u79F0\u5FEB\u7167
190
+ role TEXT NOT NULL DEFAULT 'member', -- \u89D2\u8272\uFF08member/admin/owner\uFF09
191
+ joined_at INTEGER NOT NULL, -- \u52A0\u5165\u65F6\u95F4\u6233
192
+ expires_at INTEGER, -- \u6210\u5458\u8D44\u683C\u8FC7\u671F\u65F6\u95F4\u6233\uFF08null=\u6C38\u4E0D\u8FC7\u671F\uFF09
193
+ status TEXT NOT NULL DEFAULT 'active', -- \u72B6\u6001\uFF08active/expired/kicked\uFF09
194
+ version INTEGER NOT NULL DEFAULT 1, -- \u4E50\u89C2\u9501\u7248\u672C\u53F7
195
+ PRIMARY KEY (cid, player_id), -- \u8054\u5408\u4E3B\u952E
196
+ FOREIGN KEY (cid) REFERENCES sfmc_coops(cid) ON DELETE CASCADE -- \u7EA7\u8054\u5220\u9664
197
+ )`
198
+ );
199
+ db.exec(
200
+ /* sql */
201
+ `
202
+ CREATE UNIQUE INDEX IF NOT EXISTS idx_sfmc_one_active_coop_member ON sfmc_coop_members(player_id) WHERE status='active'`
203
+ );
204
+ db.exec(
205
+ /* sql */
206
+ `
199
207
  CREATE TABLE IF NOT EXISTS sfmc_coop_invites (
200
- id TEXT PRIMARY KEY, -- 邀请唯一id
201
- cid TEXT NOT NULL, -- 合作社id
202
- inviter_id TEXT NOT NULL, -- 邀请人玩家id
203
- invitee_id TEXT NOT NULL, -- 被邀请人玩家id
204
- invitee_name_snapshot TEXT NOT NULL DEFAULT '', -- 被邀请人名称快照
205
- role TEXT NOT NULL DEFAULT 'member', -- 邀请角色
206
- status TEXT NOT NULL DEFAULT 'pending', -- 状态(pending/accepted/rejected/expired
207
- expires_at INTEGER NOT NULL, -- 邀请过期时间戳
208
- created_at INTEGER NOT NULL, -- 创建时间戳
209
- FOREIGN KEY (cid) REFERENCES sfmc_coops(cid) ON DELETE CASCADE -- 级联删除
210
- )`);
211
- // 邀请表索引:按被邀请人+状态+过期时间查
212
- db.exec(/* sql */ `
213
- CREATE INDEX IF NOT EXISTS idx_sfmc_coop_invites_target ON sfmc_coop_invites(invitee_id,status,expires_at)`);
214
- // 合作社账户表(经济系统)
215
- db.exec(/* sql */ `
208
+ id TEXT PRIMARY KEY, -- \u9080\u8BF7\u552F\u4E00id
209
+ cid TEXT NOT NULL, -- \u5408\u4F5C\u793Eid
210
+ inviter_id TEXT NOT NULL, -- \u9080\u8BF7\u4EBA\u73A9\u5BB6id
211
+ invitee_id TEXT NOT NULL, -- \u88AB\u9080\u8BF7\u4EBA\u73A9\u5BB6id
212
+ invitee_name_snapshot TEXT NOT NULL DEFAULT '', -- \u88AB\u9080\u8BF7\u4EBA\u540D\u79F0\u5FEB\u7167
213
+ role TEXT NOT NULL DEFAULT 'member', -- \u9080\u8BF7\u89D2\u8272
214
+ status TEXT NOT NULL DEFAULT 'pending', -- \u72B6\u6001\uFF08pending/accepted/rejected/expired\uFF09
215
+ expires_at INTEGER NOT NULL, -- \u9080\u8BF7\u8FC7\u671F\u65F6\u95F4\u6233
216
+ created_at INTEGER NOT NULL, -- \u521B\u5EFA\u65F6\u95F4\u6233
217
+ FOREIGN KEY (cid) REFERENCES sfmc_coops(cid) ON DELETE CASCADE -- \u7EA7\u8054\u5220\u9664
218
+ )`
219
+ );
220
+ db.exec(
221
+ /* sql */
222
+ `
223
+ CREATE INDEX IF NOT EXISTS idx_sfmc_coop_invites_target ON sfmc_coop_invites(invitee_id,status,expires_at)`
224
+ );
225
+ db.exec(
226
+ /* sql */
227
+ `
216
228
  CREATE TABLE IF NOT EXISTS sfmc_coop_accounts (
217
- cid TEXT PRIMARY KEY, -- 合作社id
218
- balance INTEGER NOT NULL DEFAULT 0, -- 账户余额
219
- version INTEGER NOT NULL DEFAULT 1, -- 乐观锁版本号
220
- updated_at INTEGER NOT NULL, -- 账户更新时间戳
221
- FOREIGN KEY (cid) REFERENCES sfmc_coops(cid) ON DELETE CASCADE -- 级联删除
222
- )`);
223
- // 合作社商店物品表
224
- db.exec(/* sql */ `
229
+ cid TEXT PRIMARY KEY, -- \u5408\u4F5C\u793Eid
230
+ balance INTEGER NOT NULL DEFAULT 0, -- \u8D26\u6237\u4F59\u989D
231
+ version INTEGER NOT NULL DEFAULT 1, -- \u4E50\u89C2\u9501\u7248\u672C\u53F7
232
+ updated_at INTEGER NOT NULL, -- \u8D26\u6237\u66F4\u65B0\u65F6\u95F4\u6233
233
+ FOREIGN KEY (cid) REFERENCES sfmc_coops(cid) ON DELETE CASCADE -- \u7EA7\u8054\u5220\u9664
234
+ )`
235
+ );
236
+ db.exec(
237
+ /* sql */
238
+ `
225
239
  CREATE TABLE IF NOT EXISTS sfmc_coop_shop_items (
226
- id TEXT PRIMARY KEY, -- 物品唯一id
227
- cid TEXT NOT NULL, -- 所属合作社id
228
- name TEXT NOT NULL, -- 物品名称
229
- item_type TEXT NOT NULL, -- 物品类型标识符(如minecraft:diamond
230
- item_aux INTEGER DEFAULT 0, -- 物品附加值/数据值
231
- item_nbt TEXT DEFAULT '', -- 物品NBT数据
232
- type INTEGER NOT NULL, -- 物品交易类型(0=收购,1=出售,2=交换)
233
- groups TEXT DEFAULT '[]', -- 所属商品分组
234
- des TEXT DEFAULT '', -- 物品描述
235
- num INTEGER DEFAULT 0, -- 当前库存数量
236
- sv INTEGER DEFAULT 0, -- 销售/收购限制
237
- money INTEGER DEFAULT 0, -- 单价
238
- is_true INTEGER DEFAULT 1, -- 是否上架(1=上架,0=下架)
239
- created_at INTEGER NOT NULL, -- 创建时间戳
240
- updated_at INTEGER NOT NULL, -- 更新时间戳
241
- FOREIGN KEY (cid) REFERENCES sfmc_coops(cid) ON DELETE CASCADE -- 级联删除
242
- )`);
243
- // 合作社银行流水表
244
- db.exec(/* sql */ `
240
+ id TEXT PRIMARY KEY, -- \u7269\u54C1\u552F\u4E00id
241
+ cid TEXT NOT NULL, -- \u6240\u5C5E\u5408\u4F5C\u793Eid
242
+ name TEXT NOT NULL, -- \u7269\u54C1\u540D\u79F0
243
+ item_type TEXT NOT NULL, -- \u7269\u54C1\u7C7B\u578B\u6807\u8BC6\u7B26\uFF08\u5982minecraft:diamond\uFF09
244
+ item_aux INTEGER DEFAULT 0, -- \u7269\u54C1\u9644\u52A0\u503C/\u6570\u636E\u503C
245
+ item_nbt TEXT DEFAULT '', -- \u7269\u54C1NBT\u6570\u636E
246
+ type INTEGER NOT NULL, -- \u7269\u54C1\u4EA4\u6613\u7C7B\u578B\uFF080=\u6536\u8D2D,1=\u51FA\u552E,2=\u4EA4\u6362\uFF09
247
+ groups TEXT DEFAULT '[]', -- \u6240\u5C5E\u5546\u54C1\u5206\u7EC4
248
+ des TEXT DEFAULT '', -- \u7269\u54C1\u63CF\u8FF0
249
+ num INTEGER DEFAULT 0, -- \u5F53\u524D\u5E93\u5B58\u6570\u91CF
250
+ sv INTEGER DEFAULT 0, -- \u9500\u552E/\u6536\u8D2D\u9650\u5236
251
+ money INTEGER DEFAULT 0, -- \u5355\u4EF7
252
+ is_true INTEGER DEFAULT 1, -- \u662F\u5426\u4E0A\u67B6\uFF081=\u4E0A\u67B6,0=\u4E0B\u67B6\uFF09
253
+ created_at INTEGER NOT NULL, -- \u521B\u5EFA\u65F6\u95F4\u6233
254
+ updated_at INTEGER NOT NULL, -- \u66F4\u65B0\u65F6\u95F4\u6233
255
+ FOREIGN KEY (cid) REFERENCES sfmc_coops(cid) ON DELETE CASCADE -- \u7EA7\u8054\u5220\u9664
256
+ )`
257
+ );
258
+ db.exec(
259
+ /* sql */
260
+ `
245
261
  CREATE TABLE IF NOT EXISTS sfmc_coop_bank_log (
246
- id INTEGER PRIMARY KEY AUTOINCREMENT, -- 流水id(自增)
247
- cid TEXT NOT NULL, -- 合作社id
248
- actor_id TEXT NOT NULL, -- 操作人玩家id
249
- actor_name_snapshot TEXT NOT NULL DEFAULT '', -- 操作人名称快照
250
- type INTEGER NOT NULL, -- 流水类型(0=存入,1=取出,2=交易收入,3=交易支出)
251
- amount INTEGER NOT NULL, -- 变动金额
252
- note TEXT DEFAULT '', -- 备注
253
- transaction_id TEXT NOT NULL DEFAULT '', -- 关联事务id
254
- created_at INTEGER NOT NULL, -- 创建时间戳
255
- FOREIGN KEY (cid) REFERENCES sfmc_coops(cid) ON DELETE CASCADE -- 级联删除
256
- )`);
257
- // 合作社审计日志表
258
- db.exec(/* sql */ `
262
+ id INTEGER PRIMARY KEY AUTOINCREMENT, -- \u6D41\u6C34id\uFF08\u81EA\u589E\uFF09
263
+ cid TEXT NOT NULL, -- \u5408\u4F5C\u793Eid
264
+ actor_id TEXT NOT NULL, -- \u64CD\u4F5C\u4EBA\u73A9\u5BB6id
265
+ actor_name_snapshot TEXT NOT NULL DEFAULT '', -- \u64CD\u4F5C\u4EBA\u540D\u79F0\u5FEB\u7167
266
+ type INTEGER NOT NULL, -- \u6D41\u6C34\u7C7B\u578B\uFF080=\u5B58\u5165,1=\u53D6\u51FA,2=\u4EA4\u6613\u6536\u5165,3=\u4EA4\u6613\u652F\u51FA\uFF09
267
+ amount INTEGER NOT NULL, -- \u53D8\u52A8\u91D1\u989D
268
+ note TEXT DEFAULT '', -- \u5907\u6CE8
269
+ transaction_id TEXT NOT NULL DEFAULT '', -- \u5173\u8054\u4E8B\u52A1id
270
+ created_at INTEGER NOT NULL, -- \u521B\u5EFA\u65F6\u95F4\u6233
271
+ FOREIGN KEY (cid) REFERENCES sfmc_coops(cid) ON DELETE CASCADE -- \u7EA7\u8054\u5220\u9664
272
+ )`
273
+ );
274
+ db.exec(
275
+ /* sql */
276
+ `
259
277
  CREATE TABLE IF NOT EXISTS sfmc_coop_audit_logs (
260
- id INTEGER PRIMARY KEY AUTOINCREMENT, -- 日志id(自增)
261
- cid TEXT NOT NULL, -- 合作社id
262
- actor_id TEXT NOT NULL, -- 操作者id
263
- target_id TEXT NOT NULL DEFAULT '', -- 被操作目标id
264
- action TEXT NOT NULL, -- 操作类型(如create/update/delete/transfer等)
265
- before_state TEXT NOT NULL DEFAULT '{}', -- 操作前状态(json)
266
- after_state TEXT NOT NULL DEFAULT '{}', -- 操作后状态(json)
267
- transaction_id TEXT NOT NULL DEFAULT '', -- 关联事务id
268
- created_at INTEGER NOT NULL, -- 日志创建时间戳
269
- FOREIGN KEY (cid) REFERENCES sfmc_coops(cid) ON DELETE CASCADE -- 级联删除
270
- )`);
271
- // 合作社商店分组表
272
- db.exec(/* sql */ `
278
+ id INTEGER PRIMARY KEY AUTOINCREMENT, -- \u65E5\u5FD7id\uFF08\u81EA\u589E\uFF09
279
+ cid TEXT NOT NULL, -- \u5408\u4F5C\u793Eid
280
+ actor_id TEXT NOT NULL, -- \u64CD\u4F5C\u8005id
281
+ target_id TEXT NOT NULL DEFAULT '', -- \u88AB\u64CD\u4F5C\u76EE\u6807id
282
+ action TEXT NOT NULL, -- \u64CD\u4F5C\u7C7B\u578B\uFF08\u5982create/update/delete/transfer\u7B49\uFF09
283
+ before_state TEXT NOT NULL DEFAULT '{}', -- \u64CD\u4F5C\u524D\u72B6\u6001\uFF08json\uFF09
284
+ after_state TEXT NOT NULL DEFAULT '{}', -- \u64CD\u4F5C\u540E\u72B6\u6001\uFF08json\uFF09
285
+ transaction_id TEXT NOT NULL DEFAULT '', -- \u5173\u8054\u4E8B\u52A1id
286
+ created_at INTEGER NOT NULL, -- \u65E5\u5FD7\u521B\u5EFA\u65F6\u95F4\u6233
287
+ FOREIGN KEY (cid) REFERENCES sfmc_coops(cid) ON DELETE CASCADE -- \u7EA7\u8054\u5220\u9664
288
+ )`
289
+ );
290
+ db.exec(
291
+ /* sql */
292
+ `
273
293
  CREATE TABLE IF NOT EXISTS sfmc_coop_shop_groups (
274
- groupid TEXT PRIMARY KEY, -- 分组唯一id
275
- displayname TEXT NOT NULL, -- 分组显示名称
276
- displaydescribe TEXT DEFAULT '', -- 分组描述
277
- icon TEXT DEFAULT '', -- 分组图标
278
- type_function TEXT DEFAULT '' -- 分组功能类型
279
- )`);
280
- // (9 领地( LAND )核心表
281
- db.exec(/* sql */ `
294
+ groupid TEXT PRIMARY KEY, -- \u5206\u7EC4\u552F\u4E00id
295
+ displayname TEXT NOT NULL, -- \u5206\u7EC4\u663E\u793A\u540D\u79F0
296
+ displaydescribe TEXT DEFAULT '', -- \u5206\u7EC4\u63CF\u8FF0
297
+ icon TEXT DEFAULT '', -- \u5206\u7EC4\u56FE\u6807
298
+ type_function TEXT DEFAULT '' -- \u5206\u7EC4\u529F\u80FD\u7C7B\u578B
299
+ )`
300
+ );
301
+ db.exec(
302
+ /* sql */
303
+ `
282
304
  CREATE TABLE IF NOT EXISTS sfmc_lands (
283
- id TEXT PRIMARY KEY, -- 领地唯一id
284
- owner_player_id TEXT NOT NULL, -- 领地所有者玩家id
285
- owner_name_snapshot TEXT NOT NULL DEFAULT '', -- 所有者名称快照
286
- dimension INTEGER NOT NULL, -- 所在维度(0=主世界,1=下界,2=末地)
287
- min_x INTEGER NOT NULL, -- 领地范围最小x坐标
288
- min_y INTEGER NOT NULL, -- 领地范围最小y坐标
289
- min_z INTEGER NOT NULL, -- 领地范围最小z坐标
290
- max_x INTEGER NOT NULL, -- 领地范围最大x坐标
291
- max_y INTEGER NOT NULL, -- 领地范围最大y坐标
292
- max_z INTEGER NOT NULL, -- 领地范围最大z坐标
293
- name TEXT NOT NULL DEFAULT '', -- 领地名称
294
- status TEXT NOT NULL DEFAULT 'active', -- 领地状态(active/locked/expired/auction
295
- created_at INTEGER NOT NULL, -- 领地创建时间戳
296
- updated_at INTEGER NOT NULL, -- 领地更新时间戳
297
- expires_at INTEGER, -- 领地过期时间戳(null=永不过期)
298
- protection_profile TEXT NOT NULL DEFAULT '{}', -- 保护配置(json)
299
- version INTEGER NOT NULL DEFAULT 1, -- 乐观锁版本号
300
- purchase_price INTEGER NOT NULL DEFAULT 0, -- 购买价格
301
- refund_rate REAL NOT NULL DEFAULT 0.7, -- 退款比例(0~1
302
- tax_rate INTEGER NOT NULL DEFAULT 0, -- 税率(百分比)
303
- tax_due_at INTEGER, -- 下一个缴税时间戳
304
- tax_frozen INTEGER NOT NULL DEFAULT 0 -- 税务冻结状态(0=正常,1=冻结)
305
- )`);
306
- // 领地成员表
307
- db.exec(/* sql */ `
305
+ id TEXT PRIMARY KEY, -- \u9886\u5730\u552F\u4E00id
306
+ owner_player_id TEXT NOT NULL, -- \u9886\u5730\u6240\u6709\u8005\u73A9\u5BB6id
307
+ owner_name_snapshot TEXT NOT NULL DEFAULT '', -- \u6240\u6709\u8005\u540D\u79F0\u5FEB\u7167
308
+ dimension INTEGER NOT NULL, -- \u6240\u5728\u7EF4\u5EA6\uFF080=\u4E3B\u4E16\u754C,1=\u4E0B\u754C,2=\u672B\u5730\uFF09
309
+ min_x INTEGER NOT NULL, -- \u9886\u5730\u8303\u56F4\u6700\u5C0Fx\u5750\u6807
310
+ min_y INTEGER NOT NULL, -- \u9886\u5730\u8303\u56F4\u6700\u5C0Fy\u5750\u6807
311
+ min_z INTEGER NOT NULL, -- \u9886\u5730\u8303\u56F4\u6700\u5C0Fz\u5750\u6807
312
+ max_x INTEGER NOT NULL, -- \u9886\u5730\u8303\u56F4\u6700\u5927x\u5750\u6807
313
+ max_y INTEGER NOT NULL, -- \u9886\u5730\u8303\u56F4\u6700\u5927y\u5750\u6807
314
+ max_z INTEGER NOT NULL, -- \u9886\u5730\u8303\u56F4\u6700\u5927z\u5750\u6807
315
+ name TEXT NOT NULL DEFAULT '', -- \u9886\u5730\u540D\u79F0
316
+ status TEXT NOT NULL DEFAULT 'active', -- \u9886\u5730\u72B6\u6001\uFF08active/locked/expired/auction\uFF09
317
+ created_at INTEGER NOT NULL, -- \u9886\u5730\u521B\u5EFA\u65F6\u95F4\u6233
318
+ updated_at INTEGER NOT NULL, -- \u9886\u5730\u66F4\u65B0\u65F6\u95F4\u6233
319
+ expires_at INTEGER, -- \u9886\u5730\u8FC7\u671F\u65F6\u95F4\u6233\uFF08null=\u6C38\u4E0D\u8FC7\u671F\uFF09
320
+ protection_profile TEXT NOT NULL DEFAULT '{}', -- \u4FDD\u62A4\u914D\u7F6E\uFF08json\uFF09
321
+ version INTEGER NOT NULL DEFAULT 1, -- \u4E50\u89C2\u9501\u7248\u672C\u53F7
322
+ purchase_price INTEGER NOT NULL DEFAULT 0, -- \u8D2D\u4E70\u4EF7\u683C
323
+ refund_rate REAL NOT NULL DEFAULT 0.7, -- \u9000\u6B3E\u6BD4\u4F8B\uFF080~1\uFF09
324
+ tax_rate INTEGER NOT NULL DEFAULT 0, -- \u7A0E\u7387\uFF08\u767E\u5206\u6BD4\uFF09
325
+ tax_due_at INTEGER, -- \u4E0B\u4E00\u4E2A\u7F34\u7A0E\u65F6\u95F4\u6233
326
+ tax_frozen INTEGER NOT NULL DEFAULT 0 -- \u7A0E\u52A1\u51BB\u7ED3\u72B6\u6001\uFF080=\u6B63\u5E38,1=\u51BB\u7ED3\uFF09
327
+ )`
328
+ );
329
+ db.exec(
330
+ /* sql */
331
+ `
308
332
  CREATE TABLE IF NOT EXISTS sfmc_land_members (
309
- land_id TEXT NOT NULL, -- 领地id
310
- player_id TEXT NOT NULL, -- 成员玩家id
311
- player_name_snapshot TEXT NOT NULL DEFAULT '', -- 成员名称快照
312
- role TEXT NOT NULL DEFAULT 'admin', -- 成员角色(member/trusted/admin/owner
313
- created_at INTEGER NOT NULL, -- 加入时间戳
314
- expires_at INTEGER, -- 成员资格过期时间戳
315
- PRIMARY KEY (land_id, player_id), -- 联合主键
316
- FOREIGN KEY (land_id) REFERENCES sfmc_lands(id) ON DELETE CASCADE -- 级联删除
317
- )`);
318
- // 领地权限表
319
- db.exec(/* sql */ `
333
+ land_id TEXT NOT NULL, -- \u9886\u5730id
334
+ player_id TEXT NOT NULL, -- \u6210\u5458\u73A9\u5BB6id
335
+ player_name_snapshot TEXT NOT NULL DEFAULT '', -- \u6210\u5458\u540D\u79F0\u5FEB\u7167
336
+ role TEXT NOT NULL DEFAULT 'admin', -- \u6210\u5458\u89D2\u8272\uFF08member/trusted/admin/owner\uFF09
337
+ created_at INTEGER NOT NULL, -- \u52A0\u5165\u65F6\u95F4\u6233
338
+ expires_at INTEGER, -- \u6210\u5458\u8D44\u683C\u8FC7\u671F\u65F6\u95F4\u6233
339
+ PRIMARY KEY (land_id, player_id), -- \u8054\u5408\u4E3B\u952E
340
+ FOREIGN KEY (land_id) REFERENCES sfmc_lands(id) ON DELETE CASCADE -- \u7EA7\u8054\u5220\u9664
341
+ )`
342
+ );
343
+ db.exec(
344
+ /* sql */
345
+ `
320
346
  CREATE TABLE IF NOT EXISTS sfmc_land_permissions (
321
- land_id TEXT NOT NULL, -- 领地id
322
- permission_key TEXT NOT NULL, -- 权限键(如 buildbreak.interact 等)
323
- subject_type TEXT NOT NULL, -- 权限主体类型(player/group/role/all
324
- subject_id TEXT NOT NULL, -- 权限主体id
325
- allowed INTEGER NOT NULL DEFAULT 0, -- 是否允许(1=允许,0=拒绝,-1=未设置)
326
- updated_at INTEGER NOT NULL, -- 权限更新时间戳
327
- PRIMARY KEY (land_id, permission_key, subject_type, subject_id), -- 联合主键
328
- FOREIGN KEY (land_id) REFERENCES sfmc_lands(id) ON DELETE CASCADE -- 级联删除
329
- )`);
330
- // 领地邀请表
331
- db.exec(/* sql */ `
347
+ land_id TEXT NOT NULL, -- \u9886\u5730id
348
+ permission_key TEXT NOT NULL, -- \u6743\u9650\u952E\uFF08\u5982 buildbreak.interact \u7B49\uFF09
349
+ subject_type TEXT NOT NULL, -- \u6743\u9650\u4E3B\u4F53\u7C7B\u578B\uFF08player/group/role/all\uFF09
350
+ subject_id TEXT NOT NULL, -- \u6743\u9650\u4E3B\u4F53id
351
+ allowed INTEGER NOT NULL DEFAULT 0, -- \u662F\u5426\u5141\u8BB8\uFF081=\u5141\u8BB8,0=\u62D2\u7EDD,-1=\u672A\u8BBE\u7F6E\uFF09
352
+ updated_at INTEGER NOT NULL, -- \u6743\u9650\u66F4\u65B0\u65F6\u95F4\u6233
353
+ PRIMARY KEY (land_id, permission_key, subject_type, subject_id), -- \u8054\u5408\u4E3B\u952E
354
+ FOREIGN KEY (land_id) REFERENCES sfmc_lands(id) ON DELETE CASCADE -- \u7EA7\u8054\u5220\u9664
355
+ )`
356
+ );
357
+ db.exec(
358
+ /* sql */
359
+ `
332
360
  CREATE TABLE IF NOT EXISTS sfmc_land_invites (
333
- id TEXT PRIMARY KEY, -- 邀请唯一id
334
- land_id TEXT NOT NULL, -- 领地id
335
- inviter_id TEXT NOT NULL, -- 邀请人id
336
- invitee_id TEXT NOT NULL, -- 被邀请人id
337
- role TEXT NOT NULL, -- 邀请角色
338
- expires_at INTEGER NOT NULL, -- 邀请过期时间戳
339
- status TEXT NOT NULL DEFAULT 'pending', -- 状态(pending/accepted/rejected/expired
340
- created_at INTEGER NOT NULL, -- 创建时间戳
341
- FOREIGN KEY (land_id) REFERENCES sfmc_lands(id) ON DELETE CASCADE -- 级联删除
342
- )`);
343
- // 领地邀请表索引:按被邀请人+状态+过期时间查
344
- db.exec(/* sql */ `
345
- CREATE INDEX IF NOT EXISTS idx_sfmc_land_invites_target ON sfmc_land_invites(invitee_id, status, expires_at)`);
346
- // 领地操作审计日志表
347
- db.exec(/* sql */ `
361
+ id TEXT PRIMARY KEY, -- \u9080\u8BF7\u552F\u4E00id
362
+ land_id TEXT NOT NULL, -- \u9886\u5730id
363
+ inviter_id TEXT NOT NULL, -- \u9080\u8BF7\u4EBAid
364
+ invitee_id TEXT NOT NULL, -- \u88AB\u9080\u8BF7\u4EBAid
365
+ role TEXT NOT NULL, -- \u9080\u8BF7\u89D2\u8272
366
+ expires_at INTEGER NOT NULL, -- \u9080\u8BF7\u8FC7\u671F\u65F6\u95F4\u6233
367
+ status TEXT NOT NULL DEFAULT 'pending', -- \u72B6\u6001\uFF08pending/accepted/rejected/expired\uFF09
368
+ created_at INTEGER NOT NULL, -- \u521B\u5EFA\u65F6\u95F4\u6233
369
+ FOREIGN KEY (land_id) REFERENCES sfmc_lands(id) ON DELETE CASCADE -- \u7EA7\u8054\u5220\u9664
370
+ )`
371
+ );
372
+ db.exec(
373
+ /* sql */
374
+ `
375
+ CREATE INDEX IF NOT EXISTS idx_sfmc_land_invites_target ON sfmc_land_invites(invitee_id, status, expires_at)`
376
+ );
377
+ db.exec(
378
+ /* sql */
379
+ `
348
380
  CREATE TABLE IF NOT EXISTS sfmc_land_audit_logs (
349
- id INTEGER PRIMARY KEY AUTOINCREMENT, -- 日志id(自增)
350
- land_id TEXT NOT NULL, -- 领地id
351
- actor_id TEXT NOT NULL, -- 操作者id
352
- action TEXT NOT NULL, -- 操作类型(如 claim/release/transfer/updat 等)
353
- payload TEXT NOT NULL DEFAULT '{}', -- 操作载荷(json)
354
- created_at INTEGER NOT NULL, -- 日志创建时间戳
355
- FOREIGN KEY (land_id) REFERENCES sfmc_lands(id) ON DELETE CASCADE -- 级联删除
356
- )`);
357
- // 领地操作请求表(异步操作)
358
- db.exec(/* sql */ `
381
+ id INTEGER PRIMARY KEY AUTOINCREMENT, -- \u65E5\u5FD7id\uFF08\u81EA\u589E\uFF09
382
+ land_id TEXT NOT NULL, -- \u9886\u5730id
383
+ actor_id TEXT NOT NULL, -- \u64CD\u4F5C\u8005id
384
+ action TEXT NOT NULL, -- \u64CD\u4F5C\u7C7B\u578B\uFF08\u5982 claim/release/transfer/updat \u7B49\uFF09
385
+ payload TEXT NOT NULL DEFAULT '{}', -- \u64CD\u4F5C\u8F7D\u8377\uFF08json\uFF09
386
+ created_at INTEGER NOT NULL, -- \u65E5\u5FD7\u521B\u5EFA\u65F6\u95F4\u6233
387
+ FOREIGN KEY (land_id) REFERENCES sfmc_lands(id) ON DELETE CASCADE -- \u7EA7\u8054\u5220\u9664
388
+ )`
389
+ );
390
+ db.exec(
391
+ /* sql */
392
+ `
359
393
  CREATE TABLE IF NOT EXISTS sfmc_land_operations (
360
- request_id TEXT PRIMARY KEY, -- 请求唯一id
361
- operation_type TEXT NOT NULL, -- 操作类型(如 claim/release/upgrade 等)
362
- actor_id TEXT NOT NULL, -- 操作发起人id
363
- land_id TEXT, -- 关联领地id(可选)
364
- status TEXT NOT NULL, -- 请求状态(pending/processing/completed/failed
365
- response_json TEXT NOT NULL, -- 操作响应结果(json)
366
- created_at INTEGER NOT NULL -- 请求创建时间戳
367
- )`);
368
- // (10 玩家命令使用统计
369
- db.exec(/* sql */ `
394
+ request_id TEXT PRIMARY KEY, -- \u8BF7\u6C42\u552F\u4E00id
395
+ operation_type TEXT NOT NULL, -- \u64CD\u4F5C\u7C7B\u578B\uFF08\u5982 claim/release/upgrade \u7B49\uFF09
396
+ actor_id TEXT NOT NULL, -- \u64CD\u4F5C\u53D1\u8D77\u4EBAid
397
+ land_id TEXT, -- \u5173\u8054\u9886\u5730id\uFF08\u53EF\u9009\uFF09
398
+ status TEXT NOT NULL, -- \u8BF7\u6C42\u72B6\u6001\uFF08pending/processing/completed/failed\uFF09
399
+ response_json TEXT NOT NULL, -- \u64CD\u4F5C\u54CD\u5E94\u7ED3\u679C\uFF08json\uFF09
400
+ created_at INTEGER NOT NULL -- \u8BF7\u6C42\u521B\u5EFA\u65F6\u95F4\u6233
401
+ )`
402
+ );
403
+ db.exec(
404
+ /* sql */
405
+ `
370
406
  CREATE TABLE IF NOT EXISTS sfmc_player_command_usage (
371
- id INTEGER PRIMARY KEY AUTOINCREMENT, -- 记录id(自增)
372
- player_id TEXT NOT NULL, -- 玩家id
373
- command TEXT NOT NULL, -- 命令名称(不含/前缀)
374
- date TEXT NOT NULL, -- 统计日期(YYYY-MM-DD格式)
375
- count INTEGER DEFAULT 0, -- 当日该命令使用次数
376
- UNIQUE(player_id, command, date) -- 唯一约束:同一玩家同一命令同一天
377
- )`);
378
- // (11 经济系统
379
- db.exec(/* sql */ `
407
+ id INTEGER PRIMARY KEY AUTOINCREMENT, -- \u8BB0\u5F55id\uFF08\u81EA\u589E\uFF09
408
+ player_id TEXT NOT NULL, -- \u73A9\u5BB6id
409
+ command TEXT NOT NULL, -- \u547D\u4EE4\u540D\u79F0\uFF08\u4E0D\u542B/\u524D\u7F00\uFF09
410
+ date TEXT NOT NULL, -- \u7EDF\u8BA1\u65E5\u671F\uFF08YYYY-MM-DD\u683C\u5F0F\uFF09
411
+ count INTEGER DEFAULT 0, -- \u5F53\u65E5\u8BE5\u547D\u4EE4\u4F7F\u7528\u6B21\u6570
412
+ UNIQUE(player_id, command, date) -- \u552F\u4E00\u7EA6\u675F\uFF1A\u540C\u4E00\u73A9\u5BB6\u540C\u4E00\u547D\u4EE4\u540C\u4E00\u5929
413
+ )`
414
+ );
415
+ db.exec(
416
+ /* sql */
417
+ `
380
418
  CREATE TABLE IF NOT EXISTS sfmc_economy_price_index (
381
- item_type TEXT NOT NULL, -- 物品类型标识符
382
- item_aux INTEGER DEFAULT 0, -- 物品附加值/数据值
383
- base_buy_price INTEGER NOT NULL DEFAULT 0, -- 基础收购价格
384
- base_sell_price INTEGER NOT NULL DEFAULT 0, -- 基础出售价格
385
- current_buy_price INTEGER NOT NULL DEFAULT 0, -- 当前收购价格
386
- current_sell_price INTEGER NOT NULL DEFAULT 0, -- 当前出售价格
387
- elasticity REAL DEFAULT 0.3, -- 价格弹性系数
388
- weekly_acquisition_cap INTEGER, -- 周收购上限
389
- weekly_acquired INTEGER DEFAULT 0, -- 本周已收购数量
390
- week_start INTEGER, -- 本周开始时间戳
391
- rarity TEXT DEFAULT 'common', -- 稀有度(common/uncommon/rare/epic/legendary
392
- is_renewable INTEGER DEFAULT 1, -- 是否可再生
393
- updated_at INTEGER, -- 索引更新时间戳
394
- PRIMARY KEY (item_type, item_aux) -- 联合主键
395
- )`);
396
- // 经济日常任务表
397
- db.exec(/* sql */ `
419
+ item_type TEXT NOT NULL, -- \u7269\u54C1\u7C7B\u578B\u6807\u8BC6\u7B26
420
+ item_aux INTEGER DEFAULT 0, -- \u7269\u54C1\u9644\u52A0\u503C/\u6570\u636E\u503C
421
+ base_buy_price INTEGER NOT NULL DEFAULT 0, -- \u57FA\u7840\u6536\u8D2D\u4EF7\u683C
422
+ base_sell_price INTEGER NOT NULL DEFAULT 0, -- \u57FA\u7840\u51FA\u552E\u4EF7\u683C
423
+ current_buy_price INTEGER NOT NULL DEFAULT 0, -- \u5F53\u524D\u6536\u8D2D\u4EF7\u683C
424
+ current_sell_price INTEGER NOT NULL DEFAULT 0, -- \u5F53\u524D\u51FA\u552E\u4EF7\u683C
425
+ elasticity REAL DEFAULT 0.3, -- \u4EF7\u683C\u5F39\u6027\u7CFB\u6570
426
+ weekly_acquisition_cap INTEGER, -- \u5468\u6536\u8D2D\u4E0A\u9650
427
+ weekly_acquired INTEGER DEFAULT 0, -- \u672C\u5468\u5DF2\u6536\u8D2D\u6570\u91CF
428
+ week_start INTEGER, -- \u672C\u5468\u5F00\u59CB\u65F6\u95F4\u6233
429
+ rarity TEXT DEFAULT 'common', -- \u7A00\u6709\u5EA6\uFF08common/uncommon/rare/epic/legendary\uFF09
430
+ is_renewable INTEGER DEFAULT 1, -- \u662F\u5426\u53EF\u518D\u751F
431
+ updated_at INTEGER, -- \u7D22\u5F15\u66F4\u65B0\u65F6\u95F4\u6233
432
+ PRIMARY KEY (item_type, item_aux) -- \u8054\u5408\u4E3B\u952E
433
+ )`
434
+ );
435
+ db.exec(
436
+ /* sql */
437
+ `
398
438
  CREATE TABLE IF NOT EXISTS sfmc_economy_daily_tasks (
399
- id TEXT PRIMARY KEY, -- 任务唯一id
400
- item_type TEXT NOT NULL, -- 目标物品类型
401
- item_aux INTEGER DEFAULT 0, -- 物品附加值
402
- target_qty INTEGER NOT NULL, -- 目标数量
403
- filled_qty INTEGER DEFAULT 0, -- 已完成数量
404
- unit_reward INTEGER NOT NULL, -- 单位奖励金额
405
- created_at INTEGER, -- 任务创建时间戳
406
- expires_at INTEGER, -- 任务过期时间戳
407
- status TEXT DEFAULT 'active' -- 任务状态(active/completed/expired
408
- )`);
409
- // 经济系统全局统计表
410
- db.exec(/* sql */ `
439
+ id TEXT PRIMARY KEY, -- \u4EFB\u52A1\u552F\u4E00id
440
+ item_type TEXT NOT NULL, -- \u76EE\u6807\u7269\u54C1\u7C7B\u578B
441
+ item_aux INTEGER DEFAULT 0, -- \u7269\u54C1\u9644\u52A0\u503C
442
+ target_qty INTEGER NOT NULL, -- \u76EE\u6807\u6570\u91CF
443
+ filled_qty INTEGER DEFAULT 0, -- \u5DF2\u5B8C\u6210\u6570\u91CF
444
+ unit_reward INTEGER NOT NULL, -- \u5355\u4F4D\u5956\u52B1\u91D1\u989D
445
+ created_at INTEGER, -- \u4EFB\u52A1\u521B\u5EFA\u65F6\u95F4\u6233
446
+ expires_at INTEGER, -- \u4EFB\u52A1\u8FC7\u671F\u65F6\u95F4\u6233
447
+ status TEXT DEFAULT 'active' -- \u4EFB\u52A1\u72B6\u6001\uFF08active/completed/expired\uFF09
448
+ )`
449
+ );
450
+ db.exec(
451
+ /* sql */
452
+ `
411
453
  CREATE TABLE IF NOT EXISTS sfmc_economy_stats (
412
- id TEXT PRIMARY KEY, -- 统计项id(目前固定为'global'
413
- total_issued INTEGER DEFAULT 0, -- 累计发行货币量
414
- total_destroyed INTEGER DEFAULT 0, -- 累计销毁货币量
415
- total_supply INTEGER DEFAULT 0, -- 当前总供应量
416
- active_accounts INTEGER DEFAULT 0, -- 活跃账户数
417
- computed_at INTEGER -- 统计计算时间戳
418
- )`);
419
- // 经济账户表
420
- db.exec(/* sql */ `
454
+ id TEXT PRIMARY KEY, -- \u7EDF\u8BA1\u9879id\uFF08\u76EE\u524D\u56FA\u5B9A\u4E3A'global'\uFF09
455
+ total_issued INTEGER DEFAULT 0, -- \u7D2F\u8BA1\u53D1\u884C\u8D27\u5E01\u91CF
456
+ total_destroyed INTEGER DEFAULT 0, -- \u7D2F\u8BA1\u9500\u6BC1\u8D27\u5E01\u91CF
457
+ total_supply INTEGER DEFAULT 0, -- \u5F53\u524D\u603B\u4F9B\u5E94\u91CF
458
+ active_accounts INTEGER DEFAULT 0, -- \u6D3B\u8DC3\u8D26\u6237\u6570
459
+ computed_at INTEGER -- \u7EDF\u8BA1\u8BA1\u7B97\u65F6\u95F4\u6233
460
+ )`
461
+ );
462
+ db.exec(
463
+ /* sql */
464
+ `
421
465
  CREATE TABLE IF NOT EXISTS sfmc_economy_accounts (
422
- player_id TEXT PRIMARY KEY, -- 玩家id(主键)
423
- player_name_snapshot TEXT NOT NULL DEFAULT '', -- 玩家名称快照
424
- balance INTEGER NOT NULL DEFAULT 0 CHECK(balance >= 0), -- 账户余额(>=0
425
- version INTEGER NOT NULL DEFAULT 1, -- 乐观锁版本号
426
- created_at INTEGER NOT NULL, -- 账户创建时间戳
427
- updated_at INTEGER NOT NULL -- 账户更新时间戳
428
- )`);
429
- // 经济交易流水表
430
- db.exec(/* sql */ `
466
+ player_id TEXT PRIMARY KEY, -- \u73A9\u5BB6id\uFF08\u4E3B\u952E\uFF09
467
+ player_name_snapshot TEXT NOT NULL DEFAULT '', -- \u73A9\u5BB6\u540D\u79F0\u5FEB\u7167
468
+ balance INTEGER NOT NULL DEFAULT 0 CHECK(balance >= 0), -- \u8D26\u6237\u4F59\u989D\uFF08>=0\uFF09
469
+ version INTEGER NOT NULL DEFAULT 1, -- \u4E50\u89C2\u9501\u7248\u672C\u53F7
470
+ created_at INTEGER NOT NULL, -- \u8D26\u6237\u521B\u5EFA\u65F6\u95F4\u6233
471
+ updated_at INTEGER NOT NULL -- \u8D26\u6237\u66F4\u65B0\u65F6\u95F4\u6233
472
+ )`
473
+ );
474
+ db.exec(
475
+ /* sql */
476
+ `
431
477
  CREATE TABLE IF NOT EXISTS sfmc_economy_transactions (
432
- id TEXT PRIMARY KEY, -- 交易唯一id
433
- transaction_type TEXT NOT NULL, -- 交易类型(transfer/payment/reward/purchase等)
434
- actor_id TEXT NOT NULL, -- 交易发起人id
435
- source_player_id TEXT, -- 源玩家id(付款方)
436
- target_player_id TEXT, -- 目标玩家id(收款方)
437
- amount INTEGER NOT NULL CHECK(amount > 0), -- 交易金额(>0
438
- balance_before INTEGER, -- 交易前余额
439
- balance_after INTEGER, -- 交易后余额
440
- reference_type TEXT NOT NULL DEFAULT '', -- 关联业务类型
441
- reference_id TEXT NOT NULL DEFAULT '', -- 关联业务id
442
- reason TEXT NOT NULL DEFAULT '', -- 交易原因/备注
443
- created_at INTEGER NOT NULL -- 交易时间戳
444
- )`);
445
- // 经济幂等表(防止重复交易)
446
- db.exec(/* sql */ `
478
+ id TEXT PRIMARY KEY, -- \u4EA4\u6613\u552F\u4E00id
479
+ transaction_type TEXT NOT NULL, -- \u4EA4\u6613\u7C7B\u578B\uFF08transfer/payment/reward/purchase\u7B49\uFF09
480
+ actor_id TEXT NOT NULL, -- \u4EA4\u6613\u53D1\u8D77\u4EBAid
481
+ source_player_id TEXT, -- \u6E90\u73A9\u5BB6id\uFF08\u4ED8\u6B3E\u65B9\uFF09
482
+ target_player_id TEXT, -- \u76EE\u6807\u73A9\u5BB6id\uFF08\u6536\u6B3E\u65B9\uFF09
483
+ amount INTEGER NOT NULL CHECK(amount > 0), -- \u4EA4\u6613\u91D1\u989D\uFF08>0\uFF09
484
+ balance_before INTEGER, -- \u4EA4\u6613\u524D\u4F59\u989D
485
+ balance_after INTEGER, -- \u4EA4\u6613\u540E\u4F59\u989D
486
+ reference_type TEXT NOT NULL DEFAULT '', -- \u5173\u8054\u4E1A\u52A1\u7C7B\u578B
487
+ reference_id TEXT NOT NULL DEFAULT '', -- \u5173\u8054\u4E1A\u52A1id
488
+ reason TEXT NOT NULL DEFAULT '', -- \u4EA4\u6613\u539F\u56E0/\u5907\u6CE8
489
+ created_at INTEGER NOT NULL -- \u4EA4\u6613\u65F6\u95F4\u6233
490
+ )`
491
+ );
492
+ db.exec(
493
+ /* sql */
494
+ `
447
495
  CREATE TABLE IF NOT EXISTS sfmc_economy_idempotency (
448
- actor_id TEXT NOT NULL, -- 操作者id
449
- idempotency_key TEXT NOT NULL, -- 幂等键
450
- transaction_id TEXT NOT NULL, -- 已处理的交易id
451
- response_json TEXT NOT NULL, -- 处理结果(json)
452
- created_at INTEGER NOT NULL, -- 记录创建时间戳
453
- PRIMARY KEY (actor_id, idempotency_key) -- 联合主键
454
- )`);
455
- // 经济相关索引
456
- db.exec(/* sql */ `
496
+ actor_id TEXT NOT NULL, -- \u64CD\u4F5C\u8005id
497
+ idempotency_key TEXT NOT NULL, -- \u5E42\u7B49\u952E
498
+ transaction_id TEXT NOT NULL, -- \u5DF2\u5904\u7406\u7684\u4EA4\u6613id
499
+ response_json TEXT NOT NULL, -- \u5904\u7406\u7ED3\u679C\uFF08json\uFF09
500
+ created_at INTEGER NOT NULL, -- \u8BB0\u5F55\u521B\u5EFA\u65F6\u95F4\u6233
501
+ PRIMARY KEY (actor_id, idempotency_key) -- \u8054\u5408\u4E3B\u952E
502
+ )`
503
+ );
504
+ db.exec(
505
+ /* sql */
506
+ `
457
507
  CREATE INDEX IF NOT EXISTS idx_economy_transactions_player ON sfmc_economy_transactions(source_player_id, created_at DESC);
458
508
  CREATE INDEX IF NOT EXISTS idx_economy_transactions_target ON sfmc_economy_transactions(target_player_id, created_at DESC);
459
509
  CREATE INDEX IF NOT EXISTS idx_sfmc_lands_owner ON sfmc_lands(owner_player_id, status);
460
- CREATE INDEX IF NOT EXISTS idx_sfmc_lands_location ON sfmc_lands(dimension, min_x, max_x, min_z, max_z, status)`);
510
+ CREATE INDEX IF NOT EXISTS idx_sfmc_lands_location ON sfmc_lands(dimension, min_x, max_x, min_z, max_z, status)`
511
+ );
461
512
  }
462
- //# sourceMappingURL=schema.js.map
513
+ export {
514
+ initSchema
515
+ };
516
+ //# sourceMappingURL=schema.js.map