Browse Source

1.提交账号资料页面
2.新增深度验证post数据

olym 7 years ago
parent
commit
339278932e

+ 71 - 0
app/controller/profile_controller.js

@@ -0,0 +1,71 @@
+'use strict';
+
+/**
+ * 账号相关控制器
+ *
+ * @author CaiAoLin
+ * @date 2018/1/26
+ * @version
+ */
+
+module.exports = app => {
+
+    class ProfileController extends app.BaseController {
+
+        /**
+         * 账号资料页面
+         *
+         * @param {Object} ctx - egg全局变量
+         * @return {void}
+         */
+        async info(ctx) {
+            // 获取当前用户数据
+            const sessionUser = ctx.session.sessionUser;
+
+            // 获取账号数据
+            const accountData = await ctx.service.projectAccount.getDataByCondition({ id: sessionUser.accountId });
+
+            // 获取基础数据的字段规则
+            let baseRule = ctx.service.projectAccount.rule('profileBase');
+            baseRule = ctx.helper.validateConvert(baseRule);
+
+            const renderData = {
+                accountData,
+                baseRule: JSON.stringify(baseRule),
+            };
+            await this.layout('profile/info.ejs', renderData);
+        }
+
+        /**
+         * 保存基本信息
+         *
+         * @param {Object} ctx - egg全局变量
+         * @return {void}
+         */
+        async saveBase(ctx) {
+            try {
+                // 获取当前用户数据
+                const sessionUser = ctx.session.sessionUser;
+
+                // 获取基础数据的字段规则
+                const baseRule = ctx.service.projectAccount.rule('profileBase');
+                ctx.helper.validate(baseRule);
+
+                const result = await ctx.service.projectAccount.save(ctx.request.body, sessionUser.accountId);
+                if (!result) {
+                    throw '保存信息失败';
+                }
+
+                this.setMessage('修改成功', this.messageType.SUCCESS);
+            } catch (error) {
+                console.log(error);
+                this.setMessage(error.toString(), this.messageType.ERROR);
+            }
+
+            ctx.redirect(ctx.request.headers.referer);
+        }
+
+    }
+
+    return ProfileController;
+};

+ 24 - 0
app/extend/helper.js

@@ -160,4 +160,28 @@ module.exports = {
         return response.data;
     },
 
+    /**
+     * 深度验证数据
+     *
+     * @param {Object} rule - 数据规则
+     * @return {void}
+     */
+    validate(rule) {
+        // 先用内置的验证器验证数据
+        this.ctx.validate(rule);
+
+        // 然后再验证是否有多余的数据
+        const postData = this.ctx.request.body;
+        delete postData._csrf;
+
+        const postDataKey = Object.keys(postData);
+        const ruleKey = Object.keys(rule);
+        for (const tmp of postDataKey) {
+            // 规则里面没有定义则抛出异常
+            if (ruleKey.indexOf(tmp) < 0) {
+                throw '参数不正确';
+            }
+        }
+    },
+
 };

+ 40 - 0
app/public/js/profile.js

@@ -0,0 +1,40 @@
+/**
+ * 账号相关js
+ *
+ * @author CaiAoLin
+ * @date 2018/1/26
+ * @version
+ */
+$(document).ready(function() {
+    try {
+        if (user !== '') {
+            $(".title-bar h2").text(user);
+        }
+
+        const options = {
+            rules: '',
+            errorPlacement: function(error, element) {
+                $(element).addClass('is-invalid');
+                $(element).after(error);
+            },
+            errorClass: "invalid-feedback",
+            errorElement: "div",
+            highlight: false,
+            success: function(element) {
+                $(element).prev('input').removeClass('is-invalid');
+                $(element).remove();
+            },
+        };
+
+        options.rules = baseRule;
+        $("#base-form").validate(options);
+
+        // 基础信息提交
+        $("#base-submit").click(function() {
+            $("#base-form").valid();
+        });
+    } catch (error) {
+        console.log(error);
+    }
+
+});

+ 4 - 0
app/router.js

@@ -33,4 +33,8 @@ module.exports = app => {
     // 台账管理相关
     app.get('/ledger', sessionAuth, 'ledgerController.index');
     app.post('/ledger/tender/add', sessionAuth, datetimeFill, 'ledgerController.addTender');
+
+    // 个人账号相关
+    app.get('/profile/info', sessionAuth, 'profileController.info');
+    app.post('/profile/save', sessionAuth, 'profileController.saveBase');
 };

+ 38 - 0
app/service/project_account.js

@@ -47,6 +47,16 @@ module.exports = app => {
                         username: { type: 'string', required: true, min: 2 },
                         password: { type: 'string', required: true, min: 4 },
                     };
+                    break;
+                case 'profileBase':
+                    rule = {
+                        name: { type: 'string', allowEmpty: true, max: 10 },
+                        company: { type: 'string', allowEmpty: true, max: 30 },
+                        role: { type: 'string', allowEmpty: true, max: 10 },
+                        mobile: { type: 'mobile', allowEmpty: true },
+                        telephone: { type: 'string', allowEmpty: true, max: 12 },
+                    };
+                    break;
                 default:
                     break;
             }
@@ -132,6 +142,7 @@ module.exports = app => {
                     // 存入session
                     this.ctx.session.sessionUser = {
                         account: accountData.account,
+                        name: accountData.name,
                         accountId: accountData.id,
                         loginTime: currentTime,
                         sessionToken,
@@ -203,6 +214,33 @@ module.exports = app => {
 
             return projectInfo;
         }
+
+        /**
+         * 修改用户数据
+         *
+         * @param {Object} data - post过来的数据
+         * @param {Number} accountId - 账号id
+         * @return {Boolean} - 返回修改结果
+         */
+        async save(data, accountId) {
+            if (data._csrf !== undefined) {
+                delete data._csrf;
+            }
+            accountId = parseInt(accountId);
+            accountId = isNaN(accountId) ? 0 : accountId;
+            let result = false;
+
+            if (accountId <= 0) {
+                return result;
+            }
+            data.id = accountId;
+
+            // 更新数据
+            const operate = await this.db.update(this.tableName, data);
+            result = operate.affectedRows > 0;
+
+            return result;
+        }
     }
 
     return ProjectAccount;

+ 1 - 2
app/view/layout/layout.ejs

@@ -82,7 +82,6 @@
 <% include ./modal.ejs %>
 <script type="text/javascript">
     let toastInfo = '<%- message %>';
-    console.log(toastInfo);
     try {
         toastInfo = toastInfo !== '' && toastInfo !== 'null' ? JSON.parse(toastInfo) : '';
     } catch (error) {
@@ -92,7 +91,7 @@
     if (toastInfo !== '') {
         toast(toastInfo.message, toastInfo.type, toastInfo.icon);
     }
-
+    let user = '<%= ctx.session.sessionUser.name %>';
 </script>
 </body>
 

+ 71 - 0
app/view/profile/info.ejs

@@ -0,0 +1,71 @@
+<% include ../layout/body_header.ejs %>
+<div class="panel-content" id="app">
+    <div class="panel-title">
+        <div class="title-main">
+            <h2>账号资料</h2>
+        </div>
+    </div>
+    <div class="content-wrap">
+        <div class="c-body">
+            <div class="row">
+                <div class="col-5">
+                    <!--账号资料-->
+                    <form action="/profile/save" method="post" id="base-form">
+                        <input-text label="账号" value="<%= accountData.account %>" readonly="readonly"></input-text>
+                        <input-text label="姓名" value="<%= accountData.name %>" placeholder="请输入姓名" name="name"></input-text>
+                        <input-text label="单位" value="<%= accountData.company %>" name="company"></input-text>
+                        <input-text label="角色/职称" value="<%= accountData.role %>" name="role"></input-text>
+                        <input-text label="手机" value="<%= accountData.mobile %>" name="mobile" maxlength="11"></input-text>
+                        <input-text label="电话" value="<%= accountData.telephone %>" name="telephone"></input-text>
+                        <input type="hidden" name="_csrf" value="<%= ctx.csrf %>">
+                        <button type="submit" class="btn btn-primary" id="base-submit">确认修改</button>
+                    </form>
+                    <!--账号安全-->
+                    <form action="/profile/password" method="post" style="margin-top: 20px;">
+                        <input-text label="旧密码" password="true" name="password"></input-text>
+                        <input-text label="新密码" password="true" name="new_password"></input-text>
+                        <input-text label="确认新密码" password="true" name="confirm_password"></input-text>
+                        <input type="hidden" name="_csrf" value="<%= ctx.csrf %>">
+                        <button type="submit" class="btn btn-primary">修改密码</button>
+                    </form>
+                    <!--绑定手机-->
+                    <div>
+                        <div class="form-group mt-5">
+                            <label>认证手机(用于 找回密码、接收通知)</label>
+                            <input class="form-control" placeholder="输入11位手机号码" value="<%= accountData.auth_mobile %>" <% if(accountData.auth_mobile !== '') { %>disabled="disabled"<% } %>/>
+                        </div>
+                        <% if (accountData.auth_mobile === '') { %>
+                        <div class="form-group">
+                            <div class="input-group mb-3">
+                                <input class="form-control" readonly>
+                                <div class="input-group-append">
+                                    <button class="btn btn-outline-secondary" type="button">获取验证码</button>
+                                </div>
+                            </div>
+                        </div>
+                        <div class="form-group">
+                            <div class="input-group mb-3">
+                                <input class="form-control" placeholder="输入短信中的5位验证码">
+                                <div class="input-group-append">
+                                    <button class="btn btn-outline-secondary disabled" type="button">重新获取 58S</button>
+                                </div>
+                            </div>
+                        </div>
+                        <button type="submit" class="btn btn-secondary disabled">确认绑定</button>
+                        <button type="submit" class="btn btn-primary">确认绑定</button>
+                        <% } %>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>
+<script type="text/javascript">
+    new Vue({
+        el: '#app',
+    });
+    let baseRule = '<%- baseRule %>'
+    baseRule = JSON.parse(baseRule);
+</script>
+<script type="text/javascript" src="/public/js/profile.js"></script>
+<script type="text/javascript" src="/public/js/validate.extend.js"></script>

+ 24 - 0
config/menu.js

@@ -56,6 +56,30 @@ const menu = {
         children: null,
         url: '/contract',
     },
+    profile: {
+        name: '账号相关',
+        icon: '',
+        display: false,
+        children: {
+            info: {
+                name: '账号资料',
+                url: '/profile/info',
+            },
+            safe: {
+                name: '账号安全',
+                url: '/profile/safe',
+            },
+            guide: {
+                name: '新手指引',
+                url: '/profile/guide',
+            },
+            help: {
+                name: '帮助中心',
+                url: '/profile/help',
+            },
+        },
+        url: '/profile',
+    },
 };
 
 module.exports = menu;