'use strict'; /** * 登录页面控制器 * * @author CaiAoLin * @date 2017/11/15 * @version */ const URL = require('url'); const maintainConst = require('../const/maintain'); const OAuth = require('co-wechat-oauth'); const office = require('../const/cld_office') module.exports = app => { class LoginController extends app.BaseController { /** * 登录页面 * * @param {Object} ctx - egg全局页面 * @return {void} */ async index(ctx) { if (ctx.helper.isMobile(ctx.request.header['user-agent'])) { ctx.redirect('/wap'); return; } const errorMessage = ctx.session.loginError; // 显示完删除 ctx.session.loginError = null; // 获取系统维护信息 const maintainData = await ctx.service.maintain.getDataById(1); if (!ctx.app.config.is_debug) { await ctx.service.maintain.syncMaintainData(); } const renderData = { maintainData, maintainConst, errorMessage, hostUrl: ctx.protocol + '://' + ctx.host, appid: ctx.app.config.wxCode.appid, }; await ctx.render('login/login.ejs', renderData); } /** * 微信扫码认证并返回 * * @param {Object} ctx - egg全局页面 * @return {void} */ async wxAuth(ctx) { const code = ctx.query.code; try { const client = new OAuth(ctx.app.config.wxCode.appid, ctx.app.config.wxCode.appsecret); const token = await client.getAccessToken(code); // const user = await client.getUser(token.data.openid); // console.log(user); if (!token) { throw '微信扫码获取信息失败'; } // 判断扫码者项目是否只有一个,是则直接跳到登录页,否则显示项目选择页 const paList = await ctx.service.projectAccount.getAllDataByCondition({ where: { wx_unionid: token.data.unionid } }); if (paList && paList.length === 1) { const pro = await ctx.service.project.getDataById(paList[0].project_id); let redirect_url = ctx.protocol + '://' + ctx.host; redirect_url += ctx.query.state ? ctx.query.state : '/dashboard'; ctx.redirect('/wx/url2web?project=' + pro.code + '&url=' + redirect_url + '&unionid=' + token.data.unionid); } else { ctx.session.wechatLogin = token.data.unionid; ctx.redirect('/wxproject'); } } catch (error) { this.log(error); ctx.session.loginError = error; ctx.redirect('/login'); } } async wxProject(ctx) { try { const unionid = ctx.session.wechatLogin; if (!unionid) { throw '扫码信息已失效,请重新登录'; } ctx.session.wechatLogin = null; const paList = await ctx.service.projectAccount.getAllDataByCondition({ where: { wx_unionid: unionid } }); const pidList = ctx.app._.uniq(ctx.app._.map(paList, 'project_id')); const pList = []; const redirect_url = ctx.protocol + '://' + ctx.host + '/dashboard'; for (const p of pidList) { const pro = await ctx.service.project.getDataById(p); pro.userMsg = ctx.app._.find(paList, { project_id: p }); pList.push(pro); } // 获取系统维护信息 const maintainData = await ctx.service.maintain.getDataById(1); const renderData = { maintainData, maintainConst, unionid, pList, redirect_url, }; await ctx.render('login/wxproject.ejs', renderData); } catch (error) { this.log(error); ctx.session.loginError = error; ctx.redirect('/login'); } } // 设置用户微信登录项目,跳转到对应wap页面 async url2web(ctx) { try { if (!ctx.query.project || !ctx.query.url || !ctx.query.unionid) { throw '参数有误'; } const code = ctx.query.project; // 查找项目数据 const projectData = await ctx.service.project.getProjectByCode(code.toString().trim()); if (projectData === null) { throw '不存在项目数据'; } const pa = await ctx.service.projectAccount.getDataByCondition({ project_id: projectData.id, wx_unionid: ctx.query.unionid }); if (!pa) { throw '该微信号未绑定此项目'; } if (pa.enable !== 1) { throw '该账号已被停用,请联系销售人员'; } // 设置项目和用户session记录 const result = await ctx.service.projectAccount.accountLogin({ project: projectData, accountData: pa }, 3); if (!result) { throw '登录出错'; } ctx.redirect(ctx.query.url); } catch (error) { const renderData = { status: 1, msg: error, }; await ctx.render('wechat/tips.ejs', renderData); } } /** * 登录操作 * * @param {Object} ctx - egg全局变量 * @return {void} */ async login(ctx) { let loginType = ctx.request.body.type; try { loginType = parseInt(loginType); const result = await ctx.service.projectAccount.accountLogin(ctx.request.body, loginType); if (!result) { throw '用户名或密码错误'; } if (result === 2) { throw '该账号已被停用,请联系销售人员'; } // 调用 rotateCsrfSecret 刷新用户的 CSRF token ctx.rotateCsrfSecret(); // 判断是否已经有对应用户信息,没有则跳转初始化页面 const needBoot = await ctx.service.customer.isNeedBoot(ctx.request.body); const url = needBoot ? '/boot' : '/dashboard'; const query = URL.parse(ctx.request.header.referer, true).query; ctx.redirect(query.referer ? query.referer : url); } catch (error) { this.log(error); ctx.session.loginError = error; ctx.redirect('/login'); } } /** * 退出登录 * * @param {Object} ctx - egg全局变量 * @return {void} */ async logout(ctx) { // 删除session并跳转 ctx.session = null; ctx.redirect('/'); } /** * 获取项目名 * * @param {Object} ctx - egg全局context * @return {void} */ async projectName(ctx) { const response = { err: 0, msg: '', }; const code = ctx.query.code; try { const data = await ctx.service.project.getProjectByCode(code); if (data) { response.data = data.name; } else { throw '项目不存在'; } } catch (err) { response.err = 1; response.msg = err; } ctx.body = response; } /** * 忘记密码-重置密码 * @param ctx * @returns {Promise} */ 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; } /** * 接口登录页面 * * @param {Object} ctx - egg全局页面 * @return {void} */ async port(ctx) { // 获取系统维护信息 const maintainData = await ctx.service.maintain.getDataById(1); if (!ctx.app.config.is_debug) { await ctx.service.maintain.syncMaintainData(); } let pa; try { if (ctx.session.loginError !== null) { throw ctx.session.loginError; } if (!ctx.query.mobile) { throw '参数有误'; } pa = await ctx.service.projectAccount.getDataByCondition({ mobile: ctx.query.mobile, project_id: ctx.projectData.id }); if (!pa) { throw '您无权限登录系统。'; } if (pa.bind === 0) { // 先绑定再登录 throw ''; } else { if (pa.enable !== 1) { throw '该账号已被停用,请联系销售人员'; } const result = await ctx.service.projectAccount.accountLogin({ project: ctx.projectData, accountData: pa }, 3); if (!result) { throw '登录出错'; } ctx.redirect('/dashboard'); } } catch (error) { // this.log(error); ctx.session.loginError = error; } const errorMessage = ctx.session.loginError; // 显示完删除 ctx.session.loginError = null; const renderData = { maintainData, maintainConst, errorMessage, projectData: ctx.projectData, accountData: pa, }; await ctx.render('login/login_port.ejs', renderData); } /** * 登录操作 * * @param {Object} ctx - egg全局变量 * @return {void} */ async loginPort(ctx) { let loginType = ctx.request.body.type; try { loginType = parseInt(loginType); const data = await ctx.service.project.getProjectByCode(ctx.request.body.code.toString().trim()); if (data === null) { throw '不存在项目数据'; } if (data.custom === 0) { throw '无法通过接口登录本系统'; } if (data && data.custom === 1) { const pa = await ctx.service.projectAccount.getDataById(ctx.request.body.accountId); if (!pa) { throw '您无权限登录系统。'; } if (pa.enable !== 1) { throw '该账号已被停用,请联系销售人员'; } const updateData = { bind: 1, }; await ctx.service.projectAccount.update(updateData, { id: pa.id }); const result = await ctx.service.projectAccount.accountLogin({ project: data, accountData: pa }, loginType); if (!result) { throw '绑定登录出错,请使用账号密码登录'; } ctx.redirect('/dashboard'); } } catch (error) { this.log(error); ctx.session.loginError = error; ctx.redirect('/login'); } } /** * (项目管理)获取账号 * @param {Object} ctx - egg全局变量 */ async account(ctx) { const data = ctx.data; const response = { code: 0, data: 0, msg: '', }; try { const project = await ctx.service.project.getProjectByCode(data.code); if (!project) throw '未找到该项目'; const pa = await ctx.service.projectAccount.getAccountInfoByAccountWithPid(data.account, project.id); if (!pa ) throw '该账号不存在,请联系管理员'; const manager = await ctx.service.manager.getDataById(project.manager_id) const { is_admin: isAdmin, account_group: accountGroup, ...otherObj } = pa response.data = { account: { ...otherObj, accountGroup, isAdmin}, project: { code: project.code, name: project.name, categoryId: project.manager_office, category: office.list[project.manager_office], staff: manager.real_name } } } catch (error) { console.log(error); response.code = -1; response.msg = error.toString(); } ctx.body = response; } /** * (项目管理)获取项目 * @param {Object} ctx - egg全局变量 */ async project(ctx) { const data = ctx.data; const response = { code: 0, data: 0, msg: '', }; try { const project = await ctx.service.project.getProjectByCode(data.code); if (!project) throw '未找到该项目'; response.data = project; } catch (error) { response.code = -1; response.msg = error.toString(); } ctx.body = response; } /** * (项目管理)校验项目 * @param {Object} ctx - egg全局变量 */ async vertifyProject(ctx) { const response = { code: 0, data: 0, msg: '', }; try { const code = ctx.session.sessionProject.code const account = ctx.session.sessionUser.account if (!code || !account) { throw new Error('参数错误') } const result = await ctx.service.project.verifyManagementProject(ctx.helper.createJWT({ code })); const token = ctx.helper.createJWT({ code, account }) const redirect = `${app.config.managementPath}/auth?token=${token}` response.data = { ...result, is_admin: ctx.session.sessionUser.account === ctx.session.sessionProject.userAccount, redirect, env: app.config.env}; } catch (error) { response.code = -1; response.msg = error.toString(); } ctx.body = response; } /** * (项目管理)新增项目 * @param {Object} ctx - egg全局变量 */ async addProject(ctx) { const response = { code: 0, data: {}, msg: '', }; try { const result = await ctx.service.project.addProjectFromManagement() if (!result) { throw new Error('请求失败') } const { code = -1, data: { token = ''} = { token: ''}, msg = '请求失败' } = result if ( code === 0 && token) { response.data = { redirect: `${app.config.managementPath}/auth?token=${token}`, } } else { throw new Error(msg) } } catch (error) { response.code = -1; response.msg = error.toString(); } ctx.body = response; } } return LoginController; };