zpms_business_num
v1.0.8
Published
这是一个高性能、高并发、分布式的业务编号生成系统。基于 TypeScript、Sequelize (MySQL) 和 Redis 实现,支持自定义规则模板、自动自增、雪花算法等多种生成策略。
Readme
系统业务编号生成服务 (zpms_business_num)
这是一个高性能、高并发、分布式的业务编号生成系统。基于 TypeScript、Sequelize (MySQL) 和 Redis 实现,支持自定义规则模板、自动自增、雪花算法等多种生成策略。
特性
- 高并发安全:使用 Redis 分布式锁 (Redlock) 确保在分布式环境下的编号唯一性和递增性。
- 灵活的规则模板:支持通过枚举或自定义字符串模板定义编号格式。
- 多层级支持:内置支持租户 (Tenant)、酒店 (Hotel) 和业务 (Business) 多层级维度。
- 持久化存储:使用 MySQL 持久化存储编号当前值和规则,Redis 作为高性能缓存。
- 自动初始化:首次请求时自动初始化业务编号记录。
安装
npm install zpms_business_num快速开始
1. 初始化依赖
你需要准备好 Sequelize (MySQL) 和 Redis 实例。
import { Sequelize } from 'sequelize';
import Redis from 'ioredis';
import SysBusinessNumLogic from 'zpms_business_num';
// 初始化数据库连接
const sequelize = new Sequelize('database', 'username', 'password', {
host: 'localhost',
dialect: 'mysql'
});
// 初始化 Redis 连接
const redis = new Redis({
host: 'localhost',
port: 6379
});
// 实例化业务编号逻辑类
// 第三个参数可选,用于指定数据库名称(如果无法从 sequelize 实例自动获取)
const sysNumLogic = new SysBusinessNumLogic(sequelize, redis, 'my_database_name');2. 生成编号
const result = await sysNumLogic.generate({
tenant_id: 8888,
hotel_id: 1,
business_prefix: 'ORDER'
});
console.log(result.number); // 输出示例: 88881ORDER1001
console.log(result.value); // 输出示例: 1001API 文档
generate(params: GenerateParams, options?: GenerateOptions)
生成新的业务编号。这是核心方法,根据传入参数的不同,会有不同的行为。
参数说明
GenerateParams
| 参数名 | 类型 | 必填 | 默认值 | 说明 |
| :--- | :--- | :--- | :--- | :--- |
| tenant_id | number | 是 | - | 租户 ID |
| hotel_id | number | 是 | - | 酒店 ID |
| business_prefix | string | 是 | - | 业务前缀,用于区分不同业务类型(如 ORDER, USER 等) |
| business_name | string | 否 | Business {prefix} | 业务名称,仅在自动初始化时使用 |
| init_value | number | 否 | 1000 | 初始值,仅在自动初始化时使用 |
| rule_type | SystemRuleEnum | 否 | TENANT_HOTEL_PREFIX | 规则类型枚举,用于指定预定义的模板 |
| rule_template | string | 否 | - | 自定义规则模板,优先级高于 rule_type |
GenerateOptions
| 参数名 | 类型 | 必填 | 说明 |
| :--- | :--- | :--- | :--- |
| customCallback | (current: bigint) => Promise<bigint> \| bigint | 否 | 自定义计算下个值的回调函数。如果不传,默认为 current + 1 |
规则模板占位符
在 rule_template 中可以使用以下占位符:
{tenantId}: 租户 ID{hotelId}: 酒店 ID{businessPrefix}: 业务前缀{currentValue}: 当前流水号值{date}: 当前日期 (YYYYMMDD){time}: 当前时间 (HHmmss)
使用场景示例
场景 1:使用默认规则 (自动初始化)
如果不指定规则,默认使用 TENANT_HOTEL_PREFIX 规则:{tenantId}{hotelId}{businessPrefix}{currentValue}。
// 首次调用会自动创建记录,初始值为 1000
const res = await sysNumLogic.generate({
tenant_id: 100,
hotel_id: 1,
business_prefix: 'VIP'
});
// 假设是第一次生成
// number: "1001VIP1000" (注意:默认逻辑是 current_value 存储的是当前已使用的值,如果是初始化,可能策略会有所不同,具体取决于实现细节。通常第一次会返回 init_value + 1 或 init_value)
// 根据代码逻辑:init_value 默认为 1000。
// 1. 自动初始化 DB: current_value = 1000
// 2. 计算新值: 1000 + 1 = 1001
// 3. 格式化: 1001VIP1001场景 2:指定预定义规则类型
使用 rule_type 参数选择预定义的规则。
支持的枚举值 (SystemRuleEnum):
TENANT_HOTEL_PREFIX:{tenantId}{hotelId}{businessPrefix}{currentValue}(默认)TENANT_PREFIX:{tenantId}{businessPrefix}{currentValue}PREFIX:{businessPrefix}{currentValue}
import { SystemRuleEnum } from 'zpms_business_num';
const res = await sysNumLogic.generate({
tenant_id: 100,
hotel_id: 1,
business_prefix: 'PO',
rule_type: SystemRuleEnum.TENANT_PREFIX // 使用 租户+前缀 规则
});
// 输出示例: 100PO1001 (省略了 hotel_id)场景 3:使用自定义模板
通过 rule_template 参数完全自定义生成格式,例如加入日期。
const res = await sysNumLogic.generate({
tenant_id: 100,
hotel_id: 1,
business_prefix: 'PAY',
rule_template: 'PAY-{date}-{currentValue}' // 自定义格式
});
// 假设今天是 2024-05-20
// 输出示例: PAY-20240520-1001场景 4:自定义自增逻辑
通过 customCallback 实现非线性的自增逻辑(例如每次加 10,或者基于当前值做特殊运算)。
const res = await sysNumLogic.generate({
tenant_id: 100,
hotel_id: 1,
business_prefix: 'TEST'
}, {
// 自定义回调:下个值 = 当前值 + 10
customCallback: async (currentVal) => {
return currentVal + 10n;
}
});其他辅助方法
generateBySnowflake(): 生成雪花算法 IDgenerateByUUID(): 生成 UUIDgenerateByMd5(content): 生成 MD5
注意事项
- 数据库表创建:服务启动时会自动检查并创建
zpms_business_num表(如果不存在)。 - Redis 依赖:必须提供可用的 Redis 实例,用于分布式锁和缓存,以保证高性能和数据一致性。
- 规则优先级:
rule_template>rule_type> 默认规则。一旦业务记录创建,规则会被持久化到数据库,后续修改需要更新数据库记录。
