123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595 |
- 'use strict';
- /**
- *
- *
- * @author Ellisran
- * @date 2020/7/2
- * @version
- */
- const moment = require('moment');
- // const Controller = require('egg').Controller;
- const crypto = require('crypto');
- const qywxCrypto = require('@wecom/crypto');
- const getRawBody = require('raw-body');
- const maintainConst = require('../const/maintain');
- const wxConst = require('../const/wechat_template.js');
- const smsTypeConst = require('../const/sms_type');
- const wxWork = require('../lib/wx_work');
- const { parseStringXml } = require('../lib/common');
- module.exports = app => {
- class WechatController extends app.BaseController {
- /**
- * 接入微信
- *
- * @param {Object} ctx - egg全局页面
- * @return {void}
- */
- async index(ctx) {
- try {
- const signature = ctx.query.signature;
- const timestamp = ctx.query.timestamp;
- const nonce = ctx.query.nonce;
- const echostr = ctx.query.echostr;
- const array = [ctx.app.config.wechatAll.token, timestamp, nonce];
- array.sort();
- const tempStr = array.join('');
- const hashCode = crypto.createHash('sha1');
- const resultCode = hashCode.update(tempStr, 'utf8').digest('hex');
- if (resultCode === signature) {
- ctx.body = echostr;
- // res.send(echostr);
- } else {
- throw '验证失败';
- }
- } catch (e) {
- console.log(e);
- }
- }
- /**
- * 微信自动回复
- *
- * @param {Object} ctx - egg全局页面
- * @return {void}
- */
- async replyMessage(ctx) {
- const xml = ctx.request.body;
- try {
- const {
- createTime, msgType, toUserName, toFromName, event, msgContent,
- } = await parseStringXml(xml);
- let body = '';
- if (msgType === 'text') {
- const reply_msg = '如有问题需要咨询,请电话联系0756-3850888;或添加企业QQ:800003850。';
- body = `
- <xml>
- <ToUserName><![CDATA[${toFromName}]]></ToUserName>
- <FromUserName><![CDATA[${toUserName}]]></FromUserName>
- <CreateTime>${createTime}</CreateTime>
- <MsgType><![CDATA[text]]></MsgType>
- <Content><![CDATA[${reply_msg}]]></Content>
- <MediaId><![CDATA[media_id]]></MediaId>
- </xml>
- `;
- }
- ctx.body = body;
- } catch (e) {
- console.log(e);
- }
- }
- /**
- * 微信登录验证
- *
- * @param {Object} ctx - egg全局页面
- * @return {void}
- */
- async oauth(ctx) {
- const redirect_uri = ctx.query.redirect_uri;
- const url = await app.wechat.oauth.getAuthorizeURL(redirect_uri, '', 'snsapi_userinfo');
- ctx.redirect(url);
- }
- /**
- * 绑定页面
- *
- * @param {Object} ctx - egg全局页面
- * @return {void}
- */
- async bind(ctx) {
- try {
- const user = await app.wechat.oauth.getUser(ctx.session.wechatToken.openid);
- const errorMessage = ctx.session.loginError;
- // 显示完删除
- ctx.session.loginError = null;
- // 获取系统维护信息
- const maintainData = await ctx.service.maintain.getDataById(1);
- const renderData = {
- maintainData,
- maintainConst,
- errorMessage,
- user,
- };
- await ctx.render('wechat/bind.ejs', renderData);
- } catch (e) {
- const renderData = {
- status: 1,
- msg: e,
- };
- await ctx.render('wechat/tips.ejs', renderData);
- }
- }
- async bindwx(ctx) {
- try {
- const result = await ctx.service.projectAccount.accountCheck(ctx.request.body);
- if (!result) {
- throw '用户名或密码错误';
- }
- if (result === 2) {
- // 查找项目数据
- const projectData = await this.ctx.service.project.getProjectByCode(ctx.request.body.project.toString().trim());
- // 判断是否有设置停用提示,有则展示
- const msg = await ctx.service.projectStopmsg.getMsg(projectData.id);
- throw msg;
- }
- const accountData = result;
- if (accountData.wx_openid || ctx.session.wechatToken.openid === accountData.wx_openid) {
- throw '该账号已经绑定过微信';
- }
- const wxAccountData = await ctx.service.projectAccount.getDataByCondition({ project_id: accountData.project_id, wx_openid: ctx.session.wechatToken.openid });
- if (wxAccountData) {
- throw '该微信号已绑定过本项目账号';
- }
- const user = await app.wechat.api.getUser(ctx.session.wechatToken.openid);
- if (user.subscribe === 0) {
- throw '先关注公众号才能绑定项目';
- }
- const result2 = await ctx.service.projectAccount.bindWx(accountData.id, ctx.session.wechatToken.openid, user.nickname, user.unionid);
- if (!result2) {
- throw '绑定失败';
- }
- const projectData = await ctx.service.project.getDataById(accountData.project_id);
- // 绑定成功通知
- const templateId = 'JGJeWU2FT4syWKUE5haEf3iiqaRJ1XrsxY1PKixqLpw';
- const url = '';
- const msgData = {
- first: {
- value: '您好,纵横云计量与微信绑定成功。',
- },
- keyword1: {
- value: projectData.code,
- },
- keyword2: {
- value: accountData.account,
- },
- keyword3: {
- value: moment(new Date()).format('YYYY-MM-DD'),
- },
- remark: {
- value: '感谢您的使用。',
- },
- };
- await app.wechat.api.sendTemplate(ctx.session.wechatToken.openid, templateId, url, '', msgData);
- const renderData = {
- status: 0,
- msg: '绑定成功',
- };
- await ctx.render('wechat/tips.ejs', renderData);
- } catch (error) {
- this.log(error);
- ctx.session.loginError = error;
- ctx.redirect('/wx/bind');
- }
- }
- // 设置用户微信登录项目,跳转到对应wap页面
- async url2wap(ctx) {
- try {
- if (!ctx.query.project || !ctx.query.url) {
- 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_openid: ctx.session.wechatToken.openid });
- if (!pa) {
- throw '该微信号未绑定此项目';
- }
- if (pa.enable !== 1) {
- // 判断是否有设置停用提示,有则展示
- const msg = await ctx.service.projectStopmsg.getMsg(projectData.id);
- throw msg;
- }
- // 设置项目和用户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);
- }
- }
- async project(ctx) {
- try {
- // const user = await app.wechat.oauth.getUser(ctx.session.wechatToken.openid);
- const openid = ctx.session.wechatToken.openid;
- // const openid = 'fasdfklahsdklf';
- const paList = await ctx.service.projectAccount.getAllDataByCondition({ where: { wx_openid: openid } });
- const pidList = ctx.app._.uniq(ctx.app._.map(paList, 'project_id'));
- const pList = [];
- const redirect_url = ctx.protocol + '://' + ctx.host + '/wap/dashboard';
- for (const p of pidList) {
- const pro = await ctx.service.project.getDataById(p);
- pList.push(pro);
- }
- if (pList.length === 0) {
- throw '该微信号未绑定任何项目';
- }
- // 获取系统维护信息
- const maintainData = await ctx.service.maintain.getDataById(1);
- const renderData = {
- maintainData,
- maintainConst,
- // user,
- pList,
- redirect_url,
- };
- // ctx.body = renderData;
- await ctx.render('wechat/project.ejs', renderData);
- } catch (e) {
- const renderData = {
- status: 1,
- msg: e,
- };
- await ctx.render('wechat/tips.ejs', renderData);
- }
- }
- async oauthTxt(ctx) {
- ctx.body = 't3MkWAMqplVxPjmr';
- }
- async testwx(ctx) {
- try {
- const sck = 'https://scn.ink/';
- // 微信模板通知
- const tender = {
- data: {
- name: 'XXX标段',
- },
- info: {
- deal_info: {
- buildName: 'XX项目',
- },
- },
- };
- ctx.tender = tender;
- const stageInfo = await ctx.service.stage.getDataById(1704);
- const shenpiUrl = await ctx.helper.urlToShort(ctx.protocol + '://' + ctx.host + '/wap/tender/1998/stage/' + stageInfo.order);
- const wechatData = {
- wap_url: sck + shenpiUrl,
- qi: stageInfo.order,
- status: wxConst.status.success,
- tips: wxConst.tips.success,
- code: 'P1002',
- };
- // ctx.body = { tender, wechatData };
- await ctx.helper.sendWechat(133, smsTypeConst.const.JL, smsTypeConst.judge.result.toString(), wxConst.template.stage, wechatData);
- ctx.body = 'success';
- } catch (error) {
- console.log(error);
- ctx.body = error;
- }
- }
- // 企业微信功能
- // 回调方法
- async command(ctx) {
- try {
- const msg_signature = ctx.query.msg_signature;
- const timestamp = ctx.query.timestamp;
- const nonce = ctx.query.nonce;
- const echostr = ctx.query.echostr;
- const signature = qywxCrypto.getSignature(ctx.app.config.qywx.token, timestamp, nonce, echostr);
- if (signature === msg_signature) {
- const aeskey = ctx.app.config.qywx.encodingAESKey;
- const { message } = qywxCrypto.decrypt(aeskey, echostr);
- ctx.body = message;
- // res.send(message);
- } else {
- throw '验证失败';
- }
- } catch (e) {
- console.log(e);
- }
- }
- // 获取suite_ticket方法
- async postCommand(ctx) {
- try {
- // ctx.req才能获取到rawbody
- const wholeXML = await getRawBody(ctx.req, {
- length: ctx.headers['content-length'],
- limit: '1mb',
- encoding: 'utf-8',
- });
- const formatJson = await ctx.helper.parseXML(wholeXML);
- const messageXML = qywxCrypto.decrypt(ctx.app.config.qywx.encodingAESKey, formatJson.Encrypt);
- const callbackDataBody = await ctx.helper.parseXML(messageXML.message);
- console.log('CallbackData', callbackDataBody);
- const qywx = new wxWork(ctx);
- switch (callbackDataBody.InfoType) {
- case 'suite_ticket':
- // 刷新
- console.log('SuiteTicket', callbackDataBody.SuiteTicket);
- await qywx.setSuiteTicket(callbackDataBody.SuiteTicket);
- // await app.redis.set('suite_ticket', callbackDataBody.SuiteTicket, 'EX', 1500);
- break;
- case 'reset_permanent_code':
- case 'create_auth':
- console.log('AuthCode', callbackDataBody.AuthCode);
- await qywx.savePermanentCode(callbackDataBody.AuthCode);
- qywx.setPermanentCode();// 不用马上执行,有执行就行
- break;
- case 'cancel_auth':
- // 企业管理员删除应用
- await ctx.service.wxWork.delCorp(callbackDataBody.AuthCorpId);
- break;
- default:
- break;
- }
- // 很重要,一定要返回 success 字符串
- ctx.body = 'success';
- } catch (e) {
- console.log(e);
- }
- }
- async oauthWxWorkTxt(ctx) {
- ctx.body = 'CZwGPbI7BRGOBUX1';
- }
- /**
- * 企业微信登录验证
- *
- * @param {Object} ctx - egg全局页面
- * @return {void}
- */
- async workOauth(ctx) {
- const corpid = ctx.params.corpid;
- const redirect_uri = encodeURIComponent(ctx.query.redirect_uri);
- const corpInfo = await ctx.service.wxWork.getDataByCondition({ corpid });
- const url = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${corpid}&redirect_uri=${redirect_uri}&response_type=code&scope=snsapi_privateinfo&state=STATE&agentid=${corpInfo.agentid}#wechat_redirect`;
- ctx.redirect(url);
- }
- async workBind(ctx) {
- try {
- const qywx = new wxWork(ctx);
- const token = await qywx.getCorpAccessToken(ctx.params.corpid);
- const user = await qywx.getCorpUser(token, ctx.query.code);
- if (!user) {
- throw '获取企业用户信息失败';
- }
- const errorMessage = ctx.session.loginError;
- // 显示完删除
- ctx.session.loginError = null;
- // 获取系统维护信息
- const maintainData = await ctx.service.maintain.getDataById(1);
- const renderData = {
- maintainData,
- maintainConst,
- errorMessage,
- user,
- corpid: ctx.params.corpid,
- };
- await ctx.render('wechat/work_bind.ejs', renderData);
- } catch (error) {
- console.log(error);
- const renderData = {
- status: 1,
- msg: error,
- };
- await ctx.render('wechat/tips.ejs', renderData);
- }
- }
- async workBindwx(ctx) {
- const corpid = ctx.request.body.corpid ? ctx.request.body.corpid : null;
- try {
- const result = await ctx.service.projectAccount.accountCheck(ctx.request.body);
- if (!result) {
- throw '用户名或密码错误';
- }
- if (result === 2) {
- // 查找项目数据
- const projectData = await this.ctx.service.project.getProjectByCode(ctx.request.body.project.toString().trim());
- // 判断是否有设置停用提示,有则展示
- const msg = await ctx.service.projectStopmsg.getMsg(projectData.id);
- throw msg;
- }
- const accountData = result;
- const qywx_userid = ctx.request.body.userid;
- if (!qywx_userid || !corpid) {
- throw '参数有误';
- }
- if (accountData.qywx_userid || qywx_userid === accountData.qywx_userid) {
- throw '该账号已经绑定过企业微信';
- }
- const wxAccountData = await ctx.service.projectAccount.getDataByCondition({ project_id: accountData.project_id, qywx_userid });
- if (wxAccountData) {
- throw '该企业微信号已绑定过本项目其它账号';
- }
- const qywx = new wxWork(ctx);
- const token = await qywx.getCorpAccessToken(corpid);
- const user = await qywx.getCorpUserCommonData(token, qywx_userid, corpid);
- if (!user) {
- throw '获取企业用户信息失败';
- }
- user.avatar = ctx.request.body.avatar !== undefined ? ctx.request.body.avatar : null;
- user.gender = ctx.request.body.gender !== undefined ? ctx.request.body.gender : null;
- const result2 = await ctx.service.projectAccount.bindWx4Work(accountData.id, corpid, qywx_userid, user);
- if (!result2) {
- throw '绑定失败';
- }
- const projectData = await ctx.service.project.getDataById(accountData.project_id);
- const desc = '您好,纵横云计量与企业微信绑定成功。';
- const content = [
- {
- keyname: '项目编号',
- value: projectData.code,
- },
- {
- keyname: '账号',
- value: accountData.account,
- },
- {
- keyname: '绑定时间',
- value: moment(new Date()).format('YYYY-MM-DD'),
- },
- {
- keyname: '备注',
- value: '感谢您的使用。',
- },
- ];
- const url = ctx.protocol + '://' + ctx.host + `/wx/work/${corpid}/project`;
- await qywx.sendTemplateCard([qywx_userid], corpid, '账号绑定成功通知', desc, content, url, '登录项目');
- const renderData = {
- status: 0,
- msg: '绑定成功',
- };
- await ctx.render('wechat/tips.ejs', renderData);
- } catch (error) {
- this.log(error);
- ctx.session.loginError = error;
- const returnUrl = corpid ? `/wx/work/${corpid}/bind` : '/';
- ctx.redirect(returnUrl);
- }
- }
- // 设置用户企业微信登录项目,跳转到对应wap页面
- async url2wap4work(ctx) {
- try {
- if (!ctx.query.project || !ctx.query.url) {
- throw '参数有误';
- }
- const code = ctx.query.project;
- // 查找项目数据
- const projectData = await ctx.service.project.getProjectByCode(code.toString().trim());
- if (projectData === null) {
- throw '不存在项目数据';
- }
- const qywx = new wxWork(ctx);
- const token = await qywx.getCorpAccessToken(ctx.params.corpid);
- const user = await qywx.getCorpUser(token, ctx.query.code);
- if (!user) {
- throw '获取企业用户信息失败';
- }
- const pa = await ctx.service.projectAccount.getDataByCondition({ project_id: projectData.id, qywx_userid: user.userid });
- if (!pa) {
- throw '该企业微信号未绑定此项目';
- }
- if (pa.enable !== 1) {
- // 判断是否有设置停用提示,有则展示
- const msg = await ctx.service.projectStopmsg.getMsg(projectData.id);
- throw msg;
- }
- // 设置项目和用户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);
- }
- }
- async workProject(ctx) {
- try {
- // const user = await app.wechat.oauth.getUser(ctx.session.wechatToken.openid);
- const qywx = new wxWork(ctx);
- const token = await qywx.getCorpAccessToken(ctx.params.corpid);
- const user = await qywx.getCorpUser(token, ctx.query.code);
- if (!user) {
- throw '获取企业用户信息失败';
- }
- const paList = await ctx.service.projectAccount.getAllDataByCondition({ where: { qywx_userid: user.userid } });
- const pidList = ctx.app._.uniq(ctx.app._.map(paList, 'project_id'));
- const pList = [];
- const isWap = ctx.helper.isMobile(ctx.request.header['user-agent']) ? '/wap' : '';
- const redirect_url = ctx.protocol + '://' + ctx.host + isWap + '/dashboard';
- for (const p of pidList) {
- const pro = await ctx.service.project.getDataById(p);
- pList.push(pro);
- }
- if (pList.length === 0) {
- throw '该企业微信号未绑定任何项目';
- }
- // 获取系统维护信息
- const maintainData = await ctx.service.maintain.getDataById(1);
- const renderData = {
- maintainData,
- maintainConst,
- // user,
- pList,
- redirect_url,
- corpid: ctx.params.corpid,
- };
- // ctx.body = renderData;
- await ctx.render('wechat/work_project.ejs', renderData);
- } catch (e) {
- const renderData = {
- status: 1,
- msg: e,
- };
- await ctx.render('wechat/tips.ejs', renderData);
- }
- }
- async workTest(ctx) {
- try {
- // const user = await app.wechat.oauth.getUser(ctx.session.wechatToken.openid);
- const qywx = new wxWork(ctx);
- const result = await qywx.getUserList(ctx.params.corpid);
- ctx.body = result;
- } catch (e) {
- const renderData = {
- status: 1,
- msg: e,
- };
- await ctx.render('wechat/tips.ejs', renderData);
- }
- }
- async tips(ctx) {
- const renderData = {
- status: 0,
- msg: ctx.query.msg,
- };
- await ctx.render('wechat/tips.ejs', renderData);
- }
- }
- return WechatController;
- };
|