diff --git a/src/service/system/user.lua b/src/service/system/user.lua index ab3c94e..a573bbd 100644 --- a/src/service/system/user.lua +++ b/src/service/system/user.lua @@ -1,131 +1,146 @@ ---- ---- Generated by EmmyLua(https://github.com/EmmyLua) ---- Created by . ---- DateTime: 2025/9/25 08:19 ---- 业务逻辑 对用户数据表进行数据表业务处理 -local cjson = require('cjson') -local pgmoon = require('pgmoon') -local dbconf = require("config.database") -local status = require("config.status") - -local _M = {} - ---获取一个数据库操作连接 -local function get_con(cfg) - local code = 0 - -- 创建一个新的连接 - local conn = pgmoon.new(cfg); - ---- 连接到数据库 - local ok, err = conn:connect() - if not ok then - print("Connection failed: " .. err) - code = 0x000002 - end - --ngx.say("Connection success") - return code,conn -end - --- 查询数据表中的所有用户信息 -function _M.getAllUser() - --组装sql语句 - local sql = "select * from \"T_Users\"" - --获取数据库连接 - local code,conn = get_con(dbconf.postgres) - --设置数据库的编码格式 - --conn:exec("SET NAMES UTF8") - --执行数据库操作 - local res = conn:query(sql) - if not res then - print("get all users Query failed: "..sql) - return 0x000003,res - end - --整理数据库结果返回值 - --for _, row in ipairs(res) do - -- for key, value in pairs(row) do - -- ngx.say(key .. ":" .. tostring(value)) - -- end - --end - --关闭数据库 - conn:disconnect() - return code,res -end - ---根据用户id获取用户信息 -function _M.getUser(id) - --组装sql语句 - local sql = "select * from \"T_Users\" where id="..id - --获取数据库连接 - local code,conn = get_con(dbconf.postgres) - --设置数据库的编码格式 - --conn:exec("SET NAMES UTF8") - --执行数据库操作 - local res = conn:query(sql) - if not res then - print("Query failed: "..sql) - return 0x000003,res - end - --关闭数据库 - conn:disconnect() - return code,res -end - ---增加用户信息到数据表 -function _M.addUser(jsonData) - --ngx.say(jsonData) - local success, result = pcall(function() - return cjson.decode(jsonData) - end) - local res = nil - if success == false then - return 0x000001,res - end - --解析json中的键和数据值 - local keys = "" - local values = "" - for key, value in pairs(result) do - keys = keys..key - local val = type(value) - if val == "string" then - values = values.."\'"..value.."\'" - else - values = values..value - end - keys = keys.."," - values = values.."," - end - local newKeys = keys:sub(1, #keys -1) - local newValues = values:sub(1, #values -1) - --组装sql语句 - local sql = string.format("insert into \"T_Users\"(%s)values(%s)", newKeys, newValues) - --ngx.say(sql) - --获取数据库连接 - local code,conn = get_con(dbconf.postgres) - --执行数据库操作 - res = conn:query(sql) - if not res then - print("adduser sql failed: "..sql) - return 0x000003,res - end - --关闭数据库 - conn:disconnect() - return code,res -end - ---增加用户信息到数据表 -function _M.delete_user(id) - --组装sql语句 - local sql = "delete from \"T_Users\" where id="..id - --获取数据库连接 - local code,conn = get_con(dbconf.postgres) - --执行数据库操作 - local res = conn:query(sql) - if not res then - print("delete exec sql failed: "..sql) - return 0x000003,res - end - --关闭数据库 - conn:disconnect() - return code,res -end - -return _M +--- +--- Generated by EmmyLua(https://github.com/EmmyLua) +--- Created by . +--- DateTime: 2025/9/25 08:19 +--- 业务逻辑 对用户数据表进行数据表业务处理 +local cjson = require('cjson') +local pgmoon = require('pgmoon') +local dbconf = require("config.database") +local status = require("config.status") +local snowflake = require("util.snowflake") + +local _M = {} + +--获取一个数据库操作连接 +local function get_con(cfg) + local code = 0 + -- 创建一个新的连接 + local conn = pgmoon.new(cfg); + ---- 连接到数据库 + local ok, err = conn:connect() + if not ok then + print("Connection failed: " .. err) + code = 0x000002 + end + --ngx.say("Connection success") + return code,conn +end + +local function getUuid() + local workerId = 0 -- 假设当前机器的ID是1,范围在[0, 31]之间 + local datacenterId = 0 -- 数据中心ID,范围在[0, 31]之间 + local snow = snowflake.new(workerId, datacenterId) + local id = snow:generateUniqueId()-- 生成ID + --print("Generated ID:", snow.int64_to_string(id)) + return snow.int64_to_string(id) +end + +-- 查询数据表中的所有用户信息 +function _M.getAllUser() + --组装sql语句 + local sql = "select * from \"T_Users\"" + --获取数据库连接 + local code,conn = get_con(dbconf.postgres) + --设置数据库的编码格式 + --conn:exec("SET NAMES UTF8") + --执行数据库操作 + local res = conn:query(sql) + if not res then + print("get all users Query failed: "..sql) + return 0x000003,res + end + --整理数据库结果返回值 + --for _, row in ipairs(res) do + -- for key, value in pairs(row) do + -- ngx.say(key .. ":" .. tostring(value)) + -- end + --end + --关闭数据库 + conn:disconnect() + return code,res +end + +--根据用户id获取用户信息 +function _M.getUser(id) + --组装sql语句 + local sql = "select * from \"T_Users\" where id="..id + --获取数据库连接 + local code,conn = get_con(dbconf.postgres) + --设置数据库的编码格式 + --conn:exec("SET NAMES UTF8") + --执行数据库操作 + local res = conn:query(sql) + if not res then + print("Query failed: "..sql) + return 0x000003,res + end + --关闭数据库 + conn:disconnect() + return code,res +end + +--增加用户信息到数据表 +function _M.addUser(jsonData) + --ngx.say(jsonData) + local success, result = pcall(function() + return cjson.decode(jsonData) + end) + local res = nil + if success == false then + return 0x000001,res + end + --解析json中的键和数据值 + local keys = "" + local values = "" + for key, value in pairs(result) do + keys = keys..key + local val = type(value) + if val == "string" then + values = values.."\'"..value.."\'" + else + values = values..value + end + keys = keys.."," + values = values.."," + end + --去掉组装最后一位逗号(,) + --local newKeys = keys:sub(1, #keys -1) + --local newValues = values:sub(1, #values -1) + --自己增加对应的uuid数据值 + local newKeys = keys.."uuid" + local uuid = getUuid() + local newValues = values.."\'"..uuid.."\'" + --组装sql语句 + local sql = string.format("insert into \"T_Users\"(%s)values(%s)", newKeys, newValues) + --ngx.say(sql) + --获取数据库连接 + local code,conn = get_con(dbconf.postgres) + --执行数据库操作 + res = conn:query(sql) + if not res then + print("adduser sql failed: "..sql) + return 0x000003,res + end + --关闭数据库 + conn:disconnect() + return code,res +end + +--增加用户信息到数据表 +function _M.delete_user(id) + --组装sql语句 + local sql = "delete from \"T_Users\" where id="..id + --获取数据库连接 + local code,conn = get_con(dbconf.postgres) + --执行数据库操作 + local res = conn:query(sql) + if not res then + print("delete exec sql failed: "..sql) + return 0x000003,res + end + --关闭数据库 + conn:disconnect() + return code,res +end + +return _M diff --git a/src/test/test.lua b/src/test/test.lua index ff3203e..7fd26b5 100644 --- a/src/test/test.lua +++ b/src/test/test.lua @@ -1,51 +1,52 @@ ---- ---- Generated by EmmyLua(https://github.com/EmmyLua) ---- Created by admin. ---- DateTime: 2025/10/15 09:12 ---- - -local calc = require("util.snowalgorithm") -local dataCenterId = 1 -- 根据实际情况配置数据中心 ID 和机器 ID -local machineId = 1 -- 同理配置机器 ID,确保在所有机器中唯一且不超过最大值。 -local id = calc.generateUuid(dataCenterId, machineId) -print("Generated UUID:", id) - ---读取请求体的数据 -ngx.req.read_body() - ---获取请求数据 -local body_data = ngx.req.get_body_data() - ---if not body_data then --- ngx.say("read file error:", err) --- return ngx.exit(400) ---end -local len = #body_data - ---local file_name = ngx.req.get_body_file() -ngx.say("file length:", len) - ---ngx.req.read_body_in_buffer(ngx.var.request_body_file) - ---ngx.say(body_data) - - ---local cjson = require("cjson") ---local file_path = "/home/frankly/work/test.dat" ---local file_length = 1024 * 1024 * 400 ---local f, err = io.input(file_path, "r") ---if not f then --- ngx.say("read file error:"..err) --- return ---end ---local content = f:read(file_length) --读取文件内容 ---f:close() --关闭文件 -----ngx.say(content) ---local res = { --- key = "data", --- value = content ---} -----ngx.header["Length"] = #content ---ngx.header["Content-Type"] = 'application/json; charset=UTF-8' ---ngx.say(cjson.encode(res)) +--- +--- Generated by EmmyLua(https://github.com/EmmyLua) +--- Created by admin. +--- DateTime: 2025/10/15 09:12 +--- +local snowflake = require("util.snowflake") + +local workerId = 0 -- 假设当前机器的ID是1,范围在[0, 31]之间 +local datacenterId = 0 -- 数据中心ID,范围在[0, 31]之间 +local snow = snowflake.new(workerId, datacenterId) +local id = snow:generateUniqueId()-- 生成ID +ngx.say("Generated ID:"..snow.int64_to_string(id)) + +--读取请求体的数据 +--ngx.req.read_body() + +--获取请求数据 +--local body_data = ngx.req.get_body_data() + +--if not body_data then +-- ngx.say("read file error:", err) +-- return ngx.exit(400) +--end +--local len = #body_data + +--local file_name = ngx.req.get_body_file() +--ngx.say("file length:", len) + +--ngx.req.read_body_in_buffer(ngx.var.request_body_file) + +--ngx.say(body_data) + + +--local cjson = require("cjson") +--local file_path = "/home/frankly/work/test.dat" +--local file_length = 1024 * 1024 * 400 +--local f, err = io.input(file_path, "r") +--if not f then +-- ngx.say("read file error:"..err) +-- return +--end +--local content = f:read(file_length) --读取文件内容 +--f:close() --关闭文件 +----ngx.say(content) +--local res = { +-- key = "data", +-- value = content +--} +----ngx.header["Length"] = #content +--ngx.header["Content-Type"] = 'application/json; charset=UTF-8' +--ngx.say(cjson.encode(res)) --ngx.log(ngx.INFO, "send data success") \ No newline at end of file diff --git a/src/util/snowalgorithm.lua b/src/util/snowalgorithm.lua deleted file mode 100644 index 94fbb80..0000000 --- a/src/util/snowalgorithm.lua +++ /dev/null @@ -1,47 +0,0 @@ ---- ---- Generated by EmmyLua(https://github.com/EmmyLua) ---- Created by admin. ---- DateTime: 2025/10/21 10:58 ---- 雪花算法生成唯一的 ID ---具体使用方法 ---local dataCenterId = 1 -- 根据实际情况配置数据中心 ID 和机器 ID ---local machineId = 1 -- 同理配置机器 ID,确保在所有机器中唯一且不超过最大值。 ---local id = generateUuid(dataCenterId, machineId) ---print("Generated ID:", id) - -local _M = {} - -local config = { - epoch = 1609459200000, -- 例如:2021-01-01 的毫秒时间戳 - dataCenterIdBits = 5, - machineIdBits = 5, - sequenceBits = 12, -- 序列号在毫秒内的唯一性 - maxDataCenterId = -1 * math.pow(2, dataCenterIdBits), - maxMachineId = -1 * math.pow(2, machineIdBits), - maxSequence = -1 * math.pow(2, sequenceBits) -} - -local function calculateOffsets() - local timestampShift = config.sequenceBits + config.machineIdBits + config.dataCenterIdBits - local dataCenterIdShift = config.sequenceBits + config.machineIdBits - local machineIdShift = config.sequenceBits - return {timestampShift = timestampShift, dataCenterIdShift = dataCenterIdShift, machineIdShift = machineIdShift} -end - -local function currentTimeMillis() - return math.floor(os.time() * 1000) - config.epoch -end - -function _M.generateUuid(dataCenterId, machineId) - local offsets = calculateOffsets() - local timestamp = currentTimeMillis() - local sequence = 0 -- 在实际应用中,你可能需要一个线程安全的序列号生成器来确保同一毫秒内的唯一性。 - if sequence > config.maxSequence then return nil end -- 检查序列号是否溢出 - local id = bit32.bor(bit32.lshift(timestamp, offsets.timestampShift), - bit32.lshift(dataCenterId, offsets.dataCenterIdShift), - bit32.lshift(machineId, offsets.machineIdShift), - sequence) - return id -end - -return _M \ No newline at end of file diff --git a/src/util/snowflake.lua b/src/util/snowflake.lua new file mode 100644 index 0000000..e0287a8 --- /dev/null +++ b/src/util/snowflake.lua @@ -0,0 +1,193 @@ +local bit = require("bit") + +--创建一个雪花算法的类 +local snowflake = {} +snowflake.__index = snowflake + +local sequence = 0 --序列号 + +-- 基础配置 +local twepoch = 1420041600 -- 时间戳起点(2015-01-01) +local workerIdBits = 5 -- 机器ID位数 +local datacenterIdBits = 5 -- 数据中心ID位数 +local timestampBits = 41 -- 时间戳位数 +local sequenceBits = 12 -- 序列号位数 +local max = math.pow(2, 32) --4294967296 + +local max_workerId = bit.lshift(1 , workerIdBits) - 1 +local max_datacenterId = bit.lshift(1 , datacenterIdBits) - 1 + +-- 位移偏移量 +local timestampShift = sequenceBits + workerIdBits + datacenterIdBits -- 时间戳左移22位 +local datacenterIdShift = sequenceBits + datacenterIdBits -- 机器ID左移位数12位 +local workerIdShift = sequenceBits -- 数据中心ID左移位数17位 +-- 生成序列的掩码,这里为4095 (0b111111111111=0xfff=4095) +local sequenceMask = bit.lshift(1, sequenceBits) - 1; +--print("sequenceMask:", sequenceMask) +local lastTimestamp = -1; --上次生成ID的时间戳 + +--大数据数据左移 +local function bit_lshift(x, n) + if n == 0 then return x end + return x * (2 ^ n) +end + +--大数据数据右移 +local function bit_rshift(x, n) + if n == 0 then return x end + x = x % 2^32 -- 处理负数问题 + local res = x / 2^n + return res - res % 1 -- 取整操作,处理小数部分 +end + +-- 将一个大整数转换为32位整数数组 +local function split_into_32bit_chunks(n) + local chunks = {} + while n > 0 do + table.insert(chunks, 1, n % 0x100000000) -- 取32位部分 + n = math.floor(n / 0x100000000) -- 移除已处理的32位 + end + return chunks +end + +-- 执行按位与操作 +local function bitwise_and(a, b) + local chunks_a = split_into_32bit_chunks(a) + local chunks_b = split_into_32bit_chunks(b) + local result = 0 + local max_len = math.max(#chunks_a, #chunks_b) + print("max_len:", max_len) + for i = 0, max_len do + local chunk_a = chunks_a[i] or 0 + local chunk_b = chunks_b[i] or 0 + result = result * 0x100000000 + bit.band(chunk_a, chunk_b) + end + return result +end + +local function bitwise_or(num1, num2) + local tmp1 = num1 + local tmp2 = num2 + local str = "" + while (tmp1 ~= 0 or tmp2 ~= 0) + do + local bit1 = tmp1 % 2 + local bit2 = tmp2 % 2 + if bit1 == 0 and bit2 == 0 then + str = "0" .. str + elseif bit1 == 1 or bit2 == 1 then + str = "1" .. str + else + str = "0" .. str + end + tmp1 = math.modf(tmp1 / 2) + tmp2 = math.modf(tmp2 / 2) + --print("tmp1:", tmp1) + --print("tmp2:", tmp2) + end + return tonumber(str, 2) +end + +local function format_number(n, base) + local str = tostring(n) + --print("str:", str) + if base == 16 then -- 十六进制处理示例 + return str:gsub("^0[xX]0*", "0x") -- 处理前导零和可能的'0x' + elseif base == 10 then -- 十进制处理示例 + --print("value11:", str:gsub("^%-0*", "")) + --return str:gsub("^%-0*", "") -- 处理负数和前导零 + return str:gsub("^0*([1-9]%d*)$", "%1") + else -- 其他基数可以按需添加处理逻辑 + return str -- 或者根据需要返回其他格式化结果 + end +end + +function snowflake.int64_to_string(n) + local result = "" + local base = 100000000 -- 选择一个基数,例如10^8 + while n > 0 do + local part = n % base + result = string.format("%08d", part) .. result + n = math.floor(n / base) + end + local value = format_number(result, 10) + --print("value:", value) + return value +end + +--构造函数 +function snowflake.new(workerId, datacenterId) + if workerId < 0 then workerId = 0 end + if workerId > max_workerId then workerId = max_workerId end + if datacenterId < 0 then datacenterId = 0 end + if datacenterId > max_datacenterId then datacenterId = max_datacenterId end + local instance = {workerId = workerId, datacenterId = datacenterId} + return setmetatable(instance, snowflake) +end + +--获取当前时间戳(毫秒) +function snowflake:getCurrentTimestamp() + local timestamp = os.time() + return timestamp +end + +--获取新的时间戳 +function snowflake:getNextTimestamp(lastTimestamp) + local timestamp = math.floor(os.time()); + while (timestamp <= lastTimestamp) + do + timestamp = math.floor(os.time()); + end + return timestamp; +end + +-- 雪花算法的实现 +function snowflake:generateUniqueId() + --local curtime = os.time() + --print("current time: ", curtime) + local timestamp = self.getCurrentTimestamp() -- 当前时间戳(毫秒) + -- 如果是同一时间生成的,则进行毫秒内序列 + if lastTimestamp == timestamp then + sequence = bit.band((sequence + 1), sequenceMask); + -- 毫秒内序列溢出 + if sequence == 0 then + --阻塞到下一个毫秒,获得新的时间戳 + timestamp = self.getNextTimestamp(lastTimestamp) + end + else + sequence = 0 + end + lastTimestamp = timestamp; + --print("sequence:", sequence) + --print("lastTimestamp:", lastTimestamp) + + local current_time = lastTimestamp - twepoch + --print("current time: ", current_time) + -- 位运算生成ID + --((timestamp - twepoch) << timestampLeftShift) + local timeNew = bit_lshift(current_time, timestampShift) + --print("timeNew: ", timeNew) + --(datacenterId << datacenterIdShift) + local centerIdNew = bit_lshift(self.datacenterId, datacenterIdShift) + --print("centerIdNew: ", centerIdNew) + --(workerId << workerIdShift) + local workerIdNew = bit_lshift(self.workerId, workerIdShift) + --print("workerIdNew: ", workerIdNew) + --((timestamp - twepoch) << timestampLeftShift) + --| (datacenterId << datacenterIdShift) + --| (workerId << workerIdShift) | sequence + --将相关数据值进行位或操作 + local tmp1 = bitwise_or(timeNew, centerIdNew) + local tmp2 = bitwise_or(tmp1, workerIdNew) + local id = bitwise_or(tmp2, sequence) + return id +end + +return snowflake + +--使用方法示例 +--local workerId = 0 -- 假设当前机器的ID是1,范围在[0, 31]之间 +--local datacenterId = 0 -- 数据中心ID,范围在[0, 31]之间 +--local test = snowflake.new(workerId, datacenterId) +--local id = test:generateUniqueId()-- 生成ID +--print("Generated ID:", test:int64_to_string(id))