Browse Source

忘记密码功能和密码修改短信提醒

laiguoran 5 years ago
parent
commit
9d942ad224

+ 48 - 0
app/controller/login_controller.js

@@ -98,6 +98,54 @@ module.exports = app => {
             ctx.body = response;
         }
 
+        /**
+         * 忘记密码-重置密码
+         * @param ctx
+         * @returns {Promise<void>}
+         */
+        async resetPassword(ctx) {
+            const response = {
+                err: 0,
+                index: 0,
+                msg: '',
+            };
+            const code = ctx.request.body.code;
+            const name = ctx.request.body.name;
+            try {
+                const data = await ctx.service.project.getProjectByCode(code);
+                if (data) {
+                    const pa = await ctx.service.projectAccount.getDataByCondition({ account: name, project_id: data.id });
+                    if (!pa) {
+                        response.index = 2;
+                        throw '登录账号不存在,请检查是否输入错误。';
+                    }
+                    if (!pa.auth_mobile) {
+                        response.index = 2;
+                        throw '登录账号还没有认证手机,请联系项目管理员。';
+                    }
+                    // 重置密码并发短信
+                    const newpwd = ctx.helper.generateRandomString(6, 2);
+                    console.log(newpwd);
+                    const result = await ctx.service.projectAccount.resetPassword(pa.id, newpwd);
+                    if (!result) {
+                        throw '修改密码失败';
+                    }
+                    response.data = {
+                        pName: data.name,
+                        name: pa.name,
+                        mobile: pa.auth_mobile.substr(0, 3) + '****' + pa.auth_mobile.substr(7),
+                        account: pa.account,
+                    };
+                } else {
+                    response.index = 1;
+                    throw '项目不存在,请检查是否输入有误。';
+                }
+            } catch (err) {
+                response.err = 1;
+                response.msg = err;
+            }
+            ctx.body = response;
+        }
     }
 
     return LoginController;

+ 1 - 1
app/extend/helper.js

@@ -802,5 +802,5 @@ module.exports = {
             const content = '【纵横计量支付】' + tenderName + msg;
             sms.send(mobiles, content);
         }
-    }
+    },
 };

+ 121 - 0
app/public/js/login.js

@@ -0,0 +1,121 @@
+$(document).ready(function() {
+    const lSPName = getLocalCache('project_name');
+    const lSPCode = getLocalCache('project_code');
+    if (lSPName !== null) {
+        $('#project_name').text(lSPName);
+        $('#project').val(lSPCode);
+        $('#forget-project').val(lSPCode);
+        $('#account').focus();
+    }
+    $("#login-tab a[data-toggle='tab']").on('shown.bs.tab', function () {
+        let type = $(this).data('type');
+        type = parseInt(type);
+        type = isNaN(type) || type <= 0 ? 1 : type;
+        $("input[name='type']:hidden").val(type);
+    });
+    // $('#username').blur(function () {
+    //     let account = $(this).val();
+    //     // 判断输入的邮箱/手机是否格式正确
+    //     if(/^1[3456789]\d{9}$/.test(account) || /^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$/.test(account)) {
+    //         $('#error-msg').hide();
+    //     } else {
+    //         $('#error-msg').show();
+    //         $('#error-msg').text('账号格式有误');
+    //     }
+    // })
+    $('#project').blur(function () {
+        if ($(this).val() == '') {
+            $('#project_name').text('');
+            $('#forget-project').val('');
+            removeLocalCache('project_code');
+            removeLocalCache('project_name');
+        } else {
+            const pcode = getLocalCache('project_code');
+            if ($(this).val() !== pcode) {
+                const pc = $(this).val();
+                $.ajax({
+                    type: 'get',
+                    url: '/project/name',
+                    data: { code: pc },
+                    dataType: 'json',
+                    success: function (result) {
+                        setLocalCache('project_code', pc);
+                        if (result.err === 1) {
+                            $('#project_name').text('');
+                            $('#forget-project').val('');
+                            console.log(result.msg);
+                            toast(result.msg, 'error', 'exclamation-circle');
+                            removeLocalCache('project_name');
+                        } else {
+                            setLocalCache('project_name', result.data);
+                            $('#project_name').text(result.data);
+                            $('#forget-project').val(pc);
+                        }
+                    }
+                })
+            }
+        }
+    });
+
+    $('#forget-btn').click(function () {
+        let flag = true;
+        if ($('#forget-project').val() == '') {
+            $('#forget-project').addClass('is-invalid');
+            $('#forget-project').siblings('div.invalid-feedback').html('项目编号不能为空。');
+            flag = false;
+        }
+        if ($('#forget-name').val() == '') {
+            $('#forget-name').addClass('is-invalid');
+            $('#forget-name').siblings('div.invalid-feedback').html('登录账号不能为空。');
+            flag = false;
+        }
+        if(flag) {
+            $.ajax({
+                type: 'post',
+                url: '/reset/password',
+                data: { code: $('#forget-project').val(), name: $('#forget-name').val() },
+                dataType: 'json',
+                beforeSend: function(xhr) {
+                    let csrfToken = csrf;
+                    xhr.setRequestHeader('x-csrf-token', csrfToken);
+                },
+                success: function (result) {
+                    if (result.err === 1) {
+                        if (result.index === 1) {
+                            $('#forget-project').addClass('is-invalid');
+                            $('#forget-project').siblings('div.invalid-feedback').html(result.msg);
+                        } else if (result.index === 2) {
+                            $('#forget-name').addClass('is-invalid');
+                            $('#forget-name').siblings('div.invalid-feedback').html(result.msg);
+                        } else {
+                            toast(result.msg, 'error');
+                        }
+                    } else {
+                        $('#fg-password-done').find('b').eq(0).text(result.data.name);
+                        $('#fg-password-done').find('b').eq(1).text(result.data.account);
+                        $('#fg-password-done').find('b').eq(2).text(result.data.mobile);
+                        setLocalCache('project_name', result.data.pName);
+                        setLocalCache('project_code', $('#forget-project').val());
+                        $('#fg-password').modal('hide');
+                        $('#fg-password-done').modal('show');
+                        $('#account').val($('#forget-name').val());
+                        $('#project').val($('#forget-project').val());
+                        $('#project_name').text(result.data.pName);
+                        $('#forget-name').val('');
+                    }
+                }
+            })
+        }
+    })
+
+    $('input').focus(function () {
+        if($(this).hasClass('is-invalid')) {
+            $(this).removeClass('is-invalid');
+            $(this).siblings('div.invalid-feedback').html('');
+        }
+    });
+
+    $('#focus-pwd').click(function () {
+        $('#project-password').focus();
+    })
+});

+ 1 - 0
app/router.js

@@ -24,6 +24,7 @@ module.exports = app => {
 
     app.get('/sign', 'signController.index');
     app.post('/sign/save', 'signController.save');
+    app.post('/reset/password', 'loginController.resetPassword');
 
     // 用户信息初始化相关
     app.get('/boot', sessionAuth, 'bootController.index');

+ 7 - 2
app/service/project_account.js

@@ -390,14 +390,12 @@ module.exports = app => {
             if (accountData.password === 'SSO password') {
                 throw 'SSO用户请到SSO系统修改密码';
             }
-
             // 加密密码
             const encryptPassword = crypto.createHmac('sha1', accountData.account).update(password)
                 .digest().toString('base64');
             if (encryptPassword !== accountData.password) {
                 throw '密码错误';
             }
-
             // 通过密码验证后修改数据
             const encryptNewPassword = crypto.createHmac('sha1', accountData.account).update(newPassword)
                 .digest().toString('base64');
@@ -405,6 +403,13 @@ module.exports = app => {
             // const result = await this.save(updateData, accountId);
             const operate = await this.db.update(this.tableName, updateData);
 
+            // 发送短信
+            if (accountData.auth_mobile) {
+                const sms = new SMS(this.ctx);
+                const content = '【纵横计量支付】账号:' + accountData.account + ',密码重置为:' + newPassword;
+                sms.send(accountData.auth_mobile, content);
+            }
+
             const result = operate.affectedRows > 0;
             return result;
         }

+ 49 - 60
app/view/login/login.ejs

@@ -51,14 +51,56 @@
             <input type="hidden" name="_csrf" value="<%= ctx.csrf %>" />
             <input type="hidden" name="type" value="2" />
         </div>
-        <!--<div class="pt-1 d-flex justify-content-center">-->
-            <!--<a href="http://sso.smartcost.com.cn/getpasswd" target="_blank" class="mr-3">忘记密码</a>-->
-            <!--<a href="http://sso.smartcost.com.cn/reg" target="_blank">免费注册</a>-->
-        <!--</div>-->
+        <div class="pt-1 d-flex justify-content-end">
+            <a href="#fg-password" data-toggle="modal" data-target="#fg-password"  class="mr-3">忘记密码?</a>
+        </div>
     </form>
     <!--项目版-->
     <div class="text-white fixed-bottom"><p class="text-center mb-1">Copyright © 2018 <a href="https://smartcost.com.cn" target="_blank" class="text-white">珠海纵横创新软件有限公司</a>.All Rights Reserved.<a class="text-white ml-2" href="http://www.miitbeian.gov.cn" target="_blank">粤ICP备14032472号</a></p></div>
 </div>
+<!--忘记项目版密码-->
+<div class="modal fade" id="fg-password" data-backdrop="static">
+    <div class="modal-dialog" role="document">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title">找回密码</h5>
+            </div>
+            <div class="modal-body">
+                <div class="form-group">
+                    <label>项目编号</label>
+                    <input class="form-control" id="forget-project" placeholder="输入项目编号">
+                    <div class="invalid-feedback"></div>
+                </div>
+                <div class="form-group">
+                    <label>登录账号</label>
+                    <input class="form-control" id="forget-name" placeholder="输入登录账号">
+                    <div class="invalid-feedback"></div>
+                </div>
+            </div>
+            <div class="modal-footer">
+                <button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button>
+                <button type="button" class="btn btn-primary" id="forget-btn">重置密码</button>
+            </div>
+        </div>
+    </div>
+</div>
+<!--忘记项目版密码-->
+<div class="modal fade" id="fg-password-done" data-backdrop="static">
+    <div class="modal-dialog" role="document">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title">密码发送成功</h5>
+            </div>
+            <div class="modal-body">
+                <h5>尊敬的 <b></b>,您的账号 <b></b>,新密码已经发送至 <b></b>,注意查收。</h5>
+            </div>
+            <div class="modal-footer">
+                <button type="button" class="btn btn-secondary" data-dismiss="modal" id="focus-pwd">关闭</button>
+            </div>
+        </div>
+    </div>
+</div>
+<!-- JS. -->
 <div class="toast" style="text-align: center">
     <i class="icon fa"></i>
     <span class="message"></span>
@@ -68,63 +110,10 @@
 <script src="/public/js/popper/popper.min.js"></script>
 <script src="/public/js/bootstrap/bootstrap.min.js"></script>
 <script src="/public/js/global.js"></script>
-<script type="text/javascript">
-$(document).ready(function() {
-    const lSPName = getLocalCache('project_name');
-    const lSPCode = getLocalCache('project_code');
-    if (lSPName !== null) {
-        $('#project_name').text(lSPName);
-        $('#project').val(lSPCode);
-        $('#account').focus();
-    }
-    $("#login-tab a[data-toggle='tab']").on('shown.bs.tab', function () {
-        let type = $(this).data('type');
-        type = parseInt(type);
-        type = isNaN(type) || type <= 0 ? 1 : type;
-        $("input[name='type']:hidden").val(type);
-    });
-    // $('#username').blur(function () {
-    //     let account = $(this).val();
-    //     // 判断输入的邮箱/手机是否格式正确
-    //     if(/^1[3456789]\d{9}$/.test(account) || /^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$/.test(account)) {
-    //         $('#error-msg').hide();
-    //     } else {
-    //         $('#error-msg').show();
-    //         $('#error-msg').text('账号格式有误');
-    //     }
-    // })
-    $('#project').blur(function () {
-        if ($(this).val() == '') {
-            $('#project_name').text('');
-            removeLocalCache('project_code');
-            removeLocalCache('project_name');
-        } else {
-            const pcode = getLocalCache('project_code');
-            if ($(this).val() !== pcode) {
-                const pc = $(this).val();
-                $.ajax({
-                    type: 'get',
-                    url: '/project/name',
-                    data: { code: pc },
-                    dataType: 'json',
-                    success: function (result) {
-                        setLocalCache('project_code', pc);
-                        if (result.err === 1) {
-                            $('#project_name').text('');
-                            console.log(result.msg);
-                            toast(result.msg, 'error', 'exclamation-circle');
-                            removeLocalCache('project_name');
-                        } else {
-                            setLocalCache('project_name', result.data);
-                            $('#project_name').text(result.data);
-                        }
-                    }
-                })
-            }
-        }
-    })
-});
+<script>
+    const csrf = '<%= ctx.csrf %>'
 </script>
+<script src="/public/js/login.js"></script>
 </body>
 
 </html>