befly 3.8.32 → 3.8.34

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.
package/lib/dbHelper.ts CHANGED
@@ -595,8 +595,11 @@ export class DbHelper {
595
595
  // 转换表名:小驼峰 → 下划线
596
596
  const snakeTable = snakeCase(table);
597
597
 
598
- // 批量生成 ID(一次性从 Redis 获取 N 个 ID)
599
- const ids = await this.befly.redis.genTimeIDBatch(dataList.length);
598
+ // 批量生成 ID(逐个获取)
599
+ const ids: number[] = [];
600
+ for (let i = 0; i < dataList.length; i++) {
601
+ ids.push(await this.befly.redis.genTimeID());
602
+ }
600
603
  const now = Date.now();
601
604
 
602
605
  // 处理所有数据(自动添加系统字段)
@@ -80,62 +80,28 @@ export class RedisHelper {
80
80
  }
81
81
 
82
82
  // ==================== ID 生成 ====================
83
- // 注意:ID 生成功能强依赖 Redis 原子操作(INCR/INCRBY)保证分布式唯一性
84
- // 主要被 DbHelper.insData/insBatch 使用
85
- // 如未来有其他 ID 生成需求,可考虑提取到独立模块
83
+ // 注意:ID 生成功能强依赖 Redis 原子操作(INCR)保证分布式唯一性
84
+ // 主要被 DbHelper.insData 使用
86
85
 
87
86
  /**
88
87
  * 生成基于时间的唯一 ID
89
- * 格式: 秒级时间戳(10位) + 4位自增 = 14位纯数字
90
- * 容量: 10000/秒 = 864,000,000/天
91
- * 范围: 2286年9月
92
- * @returns 唯一 ID (14位纯数字)
88
+ * 格式: 毫秒时间戳(13位) + 3位后缀(100-999) = 16位纯数字
89
+ * 每毫秒起点基于时间戳偏移,后缀分布更均匀
90
+ * @returns 唯一 ID (16位纯数字)
93
91
  */
94
92
  async genTimeID(): Promise<number> {
95
- const timestamp = Math.floor(Date.now() / 1000); // 秒级时间戳
96
- const key = `${this.prefix}time_id_counter:${timestamp}`;
93
+ const timestamp = Date.now();
94
+ const key = `${this.prefix}time_id:${timestamp}`;
97
95
 
98
96
  const counter = await this.client.incr(key);
99
- await this.client.expire(key, 1);
100
-
101
- const counterSuffix = (counter % 10000).toString().padStart(4, '0');
102
-
103
- return Number(`${timestamp}${counterSuffix}`);
104
- }
105
-
106
- /**
107
- * 批量生成基于时间的唯一 ID
108
- * 格式: 秒级时间戳(10位) + 4位自增 = 14位纯数字
109
- * @param count - 需要生成的 ID 数量
110
- * @returns ID 数组 (14位纯数字)
111
- */
112
- async genTimeIDBatch(count: number): Promise<number[]> {
113
- if (count <= 0) {
114
- return [];
115
- }
116
-
117
- // 限制单次批量生成数量(每秒最多10000个)
118
- const MAX_BATCH_SIZE = 10000;
119
- if (count > MAX_BATCH_SIZE) {
120
- throw new Error(`批量大小 ${count} 超过最大限制 ${MAX_BATCH_SIZE}`);
97
+ if (counter === 1) {
98
+ await this.client.expire(key, 1);
121
99
  }
122
100
 
123
- const timestamp = Math.floor(Date.now() / 1000); // 秒级时间戳
124
- const key = `${this.prefix}time_id_counter:${timestamp}`;
125
-
126
- // 使用 INCRBY 一次性获取 N 个连续计数
127
- const startCounter = await this.client.incrby(key, count);
128
- await this.client.expire(key, 1);
129
-
130
- // 生成 ID 数组
131
- const ids: number[] = [];
132
- for (let i = 0; i < count; i++) {
133
- const counter = startCounter - count + i + 1; // 计算每个 ID 的计数值
134
- const counterSuffix = (counter % 10000).toString().padStart(4, '0');
135
- ids.push(Number(`${timestamp}${counterSuffix}`));
136
- }
101
+ // 基于时间戳偏移起点,后缀 100-999 循环
102
+ const suffix = 100 + (((timestamp % 900) + counter - 1) % 900);
137
103
 
138
- return ids;
104
+ return Number(`${timestamp}${suffix}`);
139
105
  }
140
106
 
141
107
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "befly",
3
- "version": "3.8.32",
3
+ "version": "3.8.34",
4
4
  "description": "Befly - 为 Bun 专属打造的 TypeScript API 接口框架核心引擎",
5
5
  "type": "module",
6
6
  "private": false,
@@ -67,13 +67,13 @@
67
67
  "befly-shared": "^1.1.2",
68
68
  "chalk": "^5.6.2",
69
69
  "es-toolkit": "^1.42.0",
70
- "fast-jwt": "^6.0.2",
70
+ "fast-jwt": "^6.1.0",
71
71
  "fast-xml-parser": "^5.3.2",
72
72
  "pathe": "^2.0.3",
73
73
  "pino": "^10.1.0",
74
74
  "pino-roll": "^4.0.0"
75
75
  },
76
- "gitHead": "a8cabbfa7932aabed195d53dc79b256b6c88602d",
76
+ "gitHead": "e6528128e0532df2c2f0ad96e32bc73e167aac84",
77
77
  "devDependencies": {
78
78
  "typescript": "^5.9.3"
79
79
  }
@@ -124,7 +124,7 @@ export async function modifyTable(sql: SQL, tableName: string, fields: Record<st
124
124
  }
125
125
  } else {
126
126
  const lenPart = isStringOrArrayType(fieldDef.type) ? ` 长度:${parseInt(String(fieldDef.max))}` : '';
127
- Logger.debug(` + 新增字段 ${dbFieldName} (${fieldDef.type}${lenPart})`);
127
+ // Logger.debug(` + 新增字段 ${dbFieldName} (${fieldDef.type}${lenPart})`);
128
128
  addClauses.push(generateDDLClause(fieldKey, fieldDef, true));
129
129
  changed = true;
130
130
  }
@@ -461,34 +461,26 @@ describe('RedisHelper - ID 生成', () => {
461
461
  expect(typeof id1).toBe('number');
462
462
  expect(typeof id2).toBe('number');
463
463
  expect(id1).not.toBe(id2);
464
- expect(id1.toString().length).toBe(14);
465
- });
464
+ expect(id1.toString().length).toBe(16);
466
465
 
467
- test('genTimeIDBatch - 批量生成 ID', async () => {
468
- const ids = await redis.genTimeIDBatch(10);
466
+ // 验证后缀在 100-999 范围内
467
+ const suffix1 = id1 % 1000;
468
+ const suffix2 = id2 % 1000;
469
+ expect(suffix1).toBeGreaterThanOrEqual(100);
470
+ expect(suffix1).toBeLessThan(1000);
471
+ expect(suffix2).toBeGreaterThanOrEqual(100);
472
+ expect(suffix2).toBeLessThan(1000);
473
+ });
469
474
 
470
- expect(ids.length).toBe(10);
471
- expect(ids.every((id) => typeof id === 'number')).toBe(true);
472
- expect(ids.every((id) => id.toString().length === 14)).toBe(true);
475
+ test('genTimeID - 多次生成保持唯一', async () => {
476
+ const ids: number[] = [];
477
+ for (let i = 0; i < 10; i++) {
478
+ ids.push(await redis.genTimeID());
479
+ }
473
480
 
474
- // 验证 ID 唯一性
475
481
  const uniqueIds = new Set(ids);
476
482
  expect(uniqueIds.size).toBe(10);
477
483
  });
478
-
479
- test('genTimeIDBatch - 空数组', async () => {
480
- const ids = await redis.genTimeIDBatch(0);
481
- expect(ids.length).toBe(0);
482
- });
483
-
484
- test('genTimeIDBatch - 超过最大限制', async () => {
485
- try {
486
- await redis.genTimeIDBatch(10001);
487
- expect(true).toBe(false); // 不应该执行到这里
488
- } catch (error: any) {
489
- expect(error.message).toContain('超过最大限制');
490
- }
491
- });
492
484
  });
493
485
 
494
486
  describe('RedisHelper - 连接测试', () => {
package/types/redis.d.ts CHANGED
@@ -46,10 +46,8 @@ export interface RedisHelper {
46
46
  ping(): Promise<string>;
47
47
 
48
48
  // ==================== ID 生成 ====================
49
- /** 生成基于时间的唯一 ID (14位纯数字) */
49
+ /** 生成基于时间的唯一 ID (16位纯数字: 13位毫秒时间戳 + 3位后缀100-999) */
50
50
  genTimeID(): Promise<number>;
51
- /** 批量生成基于时间的唯一 ID */
52
- genTimeIDBatch(count: number): Promise<number[]>;
53
51
 
54
52
  // ==================== Set 操作 ====================
55
53
  /** 向 Set 中添加一个或多个成员 */