作者:糖果

Openresty China是饭总之前创建,现在由我来维护一个线上的版本。最开始的时候,对于orchina.org的用户来说的,是有三天内不能发贴的限制的,但之后我们想用一个用户激活的标志来控制是否允许用户发帖,从路由和视图几角度来看,如下:

1.Login登陆模块。

Openresty China用的是Lor框架,封装出了Session功能:

/app/routes/auth.lua 这个文件中,集中处理了登陆登出的功能, 在登陆时,在session保存了一个变量,用于之后是否可发贴的判断逻辑。

auth_router:post("/login", function(req, res, next)
    local username = req.body.username 
    local password = req.body.password
    if not username or not password or username == "" or password == "" then
        return res:json({
            success = false,
            msg = "用户名和密码不得为空."
        })
    end
    local isExist = false
    local userid = 0
    password = utils.encode(password .. "#" .. pwd_secret)
    local result, err = user_model:query(username, password)
    local user = {}
    if result and not err then
        if result and #result == 1 then
            isExist = true
            user = result[1] 
            userid = user.id
        end
    else
        isExist = false
    end
    if isExist == true then
        req.session.set("user", {
            username = username,
            userid = userid,
            create_time = user.create_time or "",
            is_active = user.is_active

        })
        return res:json({
            success = true,
            msg = "登录成功."
        })
    else
        return res:json({
            success = false,
            msg = "用户名或密码错误,请检查!"
        })
    end
end)

首先是判断是否有登陆这个用户的ID,如果的确存在这个用户,就把这个用户的用户名,id,和create_time 用户创建时间保存到session中,这个数据的种子就是这这个时机埋的。 之后我们不用时间计算是否可以发展,引入is_active字段。

local result, err = user_model:query(username, password)

整个发贴限制的流程中,只有这么一句从数据库中,读出数据的处理,然后设定到session。

/app/model/user.lua

function user_model:query(username, password)
   local res, err =  db:query("select * from user where username=? and password=?", {username, password})
   return res, err
end

2.发表新文章的模块。
发表新文章的一个地方,是在导航条上, /app/views/header.html

<ul class="dropdown-menu" role="menu">
    <li class=""><a href="/user/{{locals.username}}/index">我的主页</a></li>
    <li class=""><div class="divider"></div></li>
    <li class=""><a href="/settings">个人设置</a></li>
    <li class=""><a href="/topic/new">发布新文章</a></li>
    <li class=""><div class="divider"></div></li>
    <li class=""><a rel="nofollow" href="/auth/logout">退出</a></li>
</ul>

“发布新文章”直接跳转的路由是/topic/new:

app/routes/topic.lua

topic_router:get("/new", function(req, res, next)
    local diff_days, diff, is_active  = utils.days_after_registry(req)
--[[    
    if diff_days<3 then
        return res:render("error", {
            errMsg = "注册时间不到3天,不允许发布文章"
        })
    end
--]]
---[[
    if  is_active == 0 then
        return res:render("error", {
            errMsg = "用户未激活,不能发布文章! 加入QQ群:522410959 进行激活。"
        })
    end
--]]    
    res:render("topic/new")
end)

最开始的逻辑,是用/app/libs/utils.lua中的days_after_registry,求出用户创建用户的天数,如果超过了三天,才可以发布文章,如果天数不够,就调用/app/views/error.html模板,把错误信息显示出来 。

utils.lua

function _M.days_after_registry(req)
    local diff = 0
    local diff_days = 0 -- default value, days after registry
    local is_active= 0
    if req and req.session then
        local user = req.session.get("user")
        local create_time = user.create_time
---[[
        if create_time then
            local now = date() -- seconds
            create_time = date(create_time)
            diff = date.diff(now, create_time):spandays()
            diff_days = mfloor(diff)
        end
--]]
        is_active = user.is_active
        --diff_days = is_active 
    end

    return diff_days, diff, is_active
end

days_after_registry函数中,取是session中的user信息,然后取得create_time和当前系统时间比较,返回差的天数。因为我们在数据库中新建了一个is_active字段单独存放用户是否要激活的状态数据,就不要进行这种时是计算了,直接取出is_active字段进行判断。

if  is_active == 0 then
    return res:render("error", {
        errMsg = "用户未激活,不能发布文章! 加入QQ群:522410959 进行激活。"
    })
end

res:render("topic/new")

3.最后一步,显示出错信息。
调用/app/views/error.html模板,把错误信息显示出来 。


<body data-controller-name="sessions">
{(header.html)}

<div id="main" class="main-container container">
    <div class="row" style="margin-top:30px;">
        <div class="col-md-12">
            <div class="panel panel-default">
                <div class="panel-heading">错误</div>
                <div class="panel-body">
                   <div class="panel-body markdown">
                        {{ errMsg }}
                    </div>
                </div>
            </div>
        </div>

    </div>
</div>
<script type="text/javascript">
    $(document).ready(function(){
        
    });
</script>
{(footer.html)}
</body>

到此,这个机能调整完毕。