profile_controller.js 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785
  1. 'use strict';
  2. /**
  3. * 账号相关控制器
  4. *
  5. * @author CaiAoLin
  6. * @date 2018/1/26
  7. * @version
  8. */
  9. const moment = require('moment');
  10. const profileMenu = require('../../config/menu').profileMenu;
  11. const smsTypeConst = require('../const/sms_type');
  12. const qr = require('qr-image');
  13. const path = require('path');
  14. const sendToWormhole = require('stream-wormhole');
  15. const loginWay = require('../const/setting').loginWay;
  16. const wxWork = require('../lib/wx_work');
  17. const profileConst = require('../const/profile');
  18. module.exports = app => {
  19. class ProfileController extends app.BaseController {
  20. /**
  21. * 构造函数
  22. *
  23. * @param {Object} ctx - egg全局context
  24. * @return {void}
  25. */
  26. constructor(ctx) {
  27. super(ctx);
  28. ctx.subMenu = profileMenu;
  29. }
  30. /**
  31. * 账号资料页面
  32. *
  33. * @param {Object} ctx - egg全局变量
  34. * @return {void}
  35. */
  36. async info(ctx) {
  37. // 获取当前用户数据
  38. const sessionUser = ctx.session.sessionUser;
  39. // 获取账号数据
  40. const accountData = await ctx.service.projectAccount.getDataByCondition({ id: sessionUser.accountId });
  41. // 获取基础数据的字段规则
  42. const baseRule = ctx.service.projectAccount.rule('profileBase');
  43. const baseJsValidator = await this.jsValidator.convert(baseRule).setSelector('#base-form').build();
  44. const renderData = {
  45. accountData,
  46. baseJsValidator,
  47. };
  48. await this.layout('profile/info.ejs', renderData);
  49. }
  50. /**
  51. * 保存基本信息
  52. *
  53. * @param {Object} ctx - egg全局变量
  54. * @return {void}
  55. */
  56. async saveBase(ctx) {
  57. try {
  58. // 获取当前用户数据
  59. const sessionUser = ctx.session.sessionUser;
  60. // 获取基础数据的字段规则
  61. const baseRule = ctx.service.projectAccount.rule('profileBase');
  62. ctx.helper.validate(baseRule);
  63. const result = await ctx.service.projectAccount.saveInfo(ctx.request.body, sessionUser.accountId);
  64. if (!result) {
  65. throw '保存信息失败';
  66. }
  67. this.setMessage('修改成功', this.messageType.SUCCESS);
  68. } catch (error) {
  69. this.log(error);
  70. this.setMessage(error.toString(), this.messageType.ERROR);
  71. }
  72. ctx.redirect(ctx.request.header.referer);
  73. }
  74. /**
  75. * 账号资料页面
  76. *
  77. * @param {Object} ctx - egg全局变量
  78. * @return {void}
  79. */
  80. async cert(ctx) {
  81. // 获取当前用户数据
  82. const sessionUser = ctx.session.sessionUser;
  83. // 获取账号数据
  84. const accountData = await ctx.service.projectAccount.getDataByCondition({ id: sessionUser.accountId });
  85. const certList = await ctx.service.accountCert.getAllDataByCondition({ where: { uid: sessionUser.accountId }, orders: [['create_time', 'desc']] });
  86. // json转换
  87. certList.forEach(item => {
  88. item.edu_json = item.edu_json ? JSON.parse(item.edu_json) : [];
  89. });
  90. const renderData = {
  91. accountData,
  92. certList,
  93. fujianOssPath: ctx.app.config.fujianOssPath,
  94. certTypeConst: profileConst.cert.certType,
  95. certSourceConst: {
  96. cert_reg: ctx.helper._.orderBy(profileConst.cert.certReg, ['sort'], ['asc']),
  97. cert_qual: ctx.helper._.orderBy(profileConst.cert.certQual, ['sort'], ['asc']),
  98. },
  99. jsFiles: this.app.jsFiles.common.concat(this.app.jsFiles.profile.cert),
  100. };
  101. await this.layout('profile/cert.ejs', renderData, 'profile/cert_modal.ejs');
  102. }
  103. async certSave(ctx) {
  104. const response = {
  105. err: 0,
  106. msg: '',
  107. data: {},
  108. };
  109. try {
  110. const sessionUser = ctx.session.sessionUser;
  111. const data = JSON.parse(ctx.request.body.data);
  112. switch (data.type) {
  113. case 'add_cert':
  114. response.data = await ctx.service.accountCert.addCert(sessionUser.accountId);
  115. break;
  116. case 'update_cert':
  117. response.data = await ctx.service.accountCert.updateCert(data.update_data);
  118. break;
  119. case 'add_jx':
  120. response.data = await ctx.service.accountCert.addEduJson(data.id);
  121. break;
  122. case 'update_jx':
  123. response.data = await ctx.service.accountCert.updateEduJson(data.update_data);
  124. break;
  125. case 'del_cert': // 包括删除附件
  126. response.data = await ctx.service.accountCert.delCert(data.delete_data);
  127. break;
  128. default:throw '参数有误';
  129. }
  130. } catch (error) {
  131. response.err = 1;
  132. response.msg = error.toString();
  133. }
  134. ctx.body = response;
  135. }
  136. /**
  137. * 上传证书(单选)
  138. *
  139. * @param {object} ctx - egg全局变量
  140. * @return {void}
  141. */
  142. async certUpload(ctx) {
  143. const responseData = {
  144. err: 0, msg: '', data: null,
  145. };
  146. try {
  147. const stream = await ctx.getFileStream();
  148. const create_time = Date.parse(new Date()) / 1000;
  149. const fileInfo = path.parse(stream.filename);
  150. const id = stream.fields && stream.fields.id ? stream.fields.id : 0;
  151. if (!id) throw '参数有误';
  152. let jxid = '';
  153. let type = '';
  154. if (stream.fields && stream.fields.type === 'upload_jx') {
  155. jxid = stream.fields.jxid ? stream.fields.jxid : '';
  156. if (!jxid) throw '参数有误';
  157. type = 'jx';
  158. } else if (stream.fields && stream.fields.type === 'upload_cert') {
  159. type = 'cert';
  160. }
  161. if (!type) throw '参数有误';
  162. // 判断用户是否选择上传文件
  163. if (!stream.filename) {
  164. throw '请选择上传的文件!';
  165. }
  166. const filename = stream.filename;
  167. const filepath = `app/public/upload/profile/${ctx.session.sessionUser.accountId}/cert/zhengshu_${create_time + fileInfo.ext}`;
  168. // await ctx.helper.saveStreamFile(stream, path.resolve(this.app.baseDir, filepath));
  169. await ctx.app.fujianOss.put(ctx.app.config.fujianOssFolder + filepath, stream);
  170. await sendToWormhole(stream);
  171. if (type === 'jx') {
  172. const info = await ctx.service.accountCert.getDataById(id);
  173. if (!info) throw '数据有误';
  174. const edu_json = info.edu_json ? JSON.parse(info.edu_json) : [];
  175. const jxInfo = edu_json.find(item => item.id === jxid);
  176. if (!jxInfo) throw '数据有误';
  177. jxInfo.file_path = filepath;
  178. jxInfo.file_name = filename;
  179. await ctx.service.accountCert.update({ edu_json: JSON.stringify(edu_json) }, { id });
  180. } else {
  181. await ctx.service.accountCert.update({ file_path: filepath, file_name: filename }, { id });
  182. }
  183. responseData.data = { file_path: filepath, file_name: filename };
  184. } catch (err) {
  185. console.log(err);
  186. responseData.err = 1;
  187. responseData.msg = err;
  188. }
  189. ctx.body = responseData;
  190. }
  191. /**
  192. * 修改密码操作
  193. *
  194. * @param {Object} ctx - egg全局变量
  195. * @return {void}
  196. */
  197. async modifyPassword(ctx) {
  198. const password = ctx.request.body.password;
  199. const newPassword = ctx.request.body.new_password;
  200. try {
  201. const sessionUser = ctx.session.sessionUser;
  202. let accountId = sessionUser.accountId;
  203. accountId = parseInt(accountId);
  204. if (isNaN(accountId) || accountId <= 0) {
  205. throw '参数错误';
  206. }
  207. // 验证数据
  208. const passwordRule = ctx.service.projectAccount.rule('modifyPassword');
  209. ctx.helper.validate(passwordRule);
  210. // 判断新密码的强度
  211. const reg = /^(?![0-9]+$)(?![a-zA-Z]+$).{6,16}$/;
  212. if (!reg.test(newPassword)) {
  213. throw '请设置至少包含数字和字母的新密码';
  214. }
  215. const result = await ctx.service.projectAccount.modifyPassword(accountId, password, newPassword);
  216. if (!result) {
  217. throw '修改密码失败';
  218. }
  219. this.setMessage('修改密码成功', this.messageType.SUCCESS);
  220. ctx.redirect('/logout');
  221. } catch (error) {
  222. ctx.session.postError = error.toString();
  223. this.setMessage(error.toString(), this.messageType.ERROR);
  224. ctx.redirect(ctx.request.header.referer);
  225. }
  226. }
  227. /**
  228. * 设置短信验证码
  229. *
  230. * @param {object} ctx - egg全局变量
  231. * @return {void}
  232. */
  233. async getCode(ctx) {
  234. const response = {
  235. err: 0,
  236. msg: '',
  237. };
  238. try {
  239. const sessionUser = ctx.session.sessionUser;
  240. const mobile = ctx.request.body.mobile;
  241. let type = null;
  242. if (ctx.request.body.type) {
  243. type = ctx.request.body.type;
  244. delete ctx.request.body.type;
  245. }
  246. const rule = { mobile: { type: 'mobile', allowEmpty: false } };
  247. ctx.helper.validate(rule);
  248. if (type === null || type !== 'shenpi') {
  249. // 查找是否有重复的认证手机
  250. const accountData = await ctx.service.projectAccount.getDataByCondition({ project_id: ctx.session.sessionProject.id, auth_mobile: mobile });
  251. if (accountData !== null) {
  252. throw '此手机号码已被使用,请重新输入!';
  253. }
  254. }
  255. const result = await ctx.service.projectAccount.setSMSCode(sessionUser.accountId, mobile);
  256. if (!result) {
  257. throw '获取验证码失败';
  258. }
  259. } catch (error) {
  260. response.err = 1;
  261. response.msg = error.toString();
  262. }
  263. ctx.body = response;
  264. }
  265. /**
  266. * 绑定认证手机
  267. *
  268. * @param {object} ctx - egg全局变量
  269. * @return {void}
  270. */
  271. async bindMobile(ctx) {
  272. const response = {
  273. err: 0,
  274. msg: '',
  275. };
  276. try {
  277. const rule = ctx.service.projectAccount.rule('bindMobile');
  278. ctx.helper.validate(rule);
  279. const sessionUser = ctx.session.sessionUser;
  280. const result = await ctx.service.projectAccount.bindMobile(sessionUser.accountId, ctx.request.body, ctx.session.sessionProject.id);
  281. if (!result) {
  282. throw '绑定手机失败!';
  283. }
  284. // this.setMessage('绑定成功', this.messageType.SUCCESS);
  285. response.msg = '绑定成功';
  286. response.url = ctx.request.header.referer;
  287. } catch (error) {
  288. this.ctx.helper.log(error);
  289. response.err = 1;
  290. response.msg = error.toString();
  291. }
  292. ctx.body = response;
  293. }
  294. /**
  295. * 短信通知
  296. *
  297. * @param {object} ctx - egg全局变量
  298. * @return {void}
  299. */
  300. async sms(ctx) {
  301. // 获取当前用户数据
  302. const sessionUser = ctx.session.sessionUser;
  303. // 获取账号数据
  304. const accountData = await ctx.service.projectAccount.getDataByCondition({ id: sessionUser.accountId });
  305. const renderData = {
  306. accountData,
  307. smsType: smsTypeConst.type,
  308. };
  309. await this.layout('profile/sms.ejs', renderData, 'profile/modal.ejs');
  310. }
  311. /**
  312. * 短信通知类型设置
  313. *
  314. * @param {object} ctx - egg全局变量
  315. * @return {void}
  316. */
  317. async smsType(ctx) {
  318. try {
  319. const sessionUser = ctx.session.sessionUser;
  320. const result = await ctx.service.projectAccount.noticeTypeSet(sessionUser.accountId, ctx.request.body);
  321. if (!result) {
  322. throw '修改通知类型失败!';
  323. }
  324. this.setMessage('通知类型绑定成功', this.messageType.SUCCESS);
  325. } catch (error) {
  326. console.log(error);
  327. this.setMessage(error.toString(), this.messageType.ERROR);
  328. }
  329. ctx.redirect(ctx.request.header.referer);
  330. }
  331. /**
  332. * 电子签名
  333. *
  334. * @param {object} ctx - egg全局变量
  335. * @return {void}
  336. */
  337. async sign(ctx) {
  338. // 获取当前用户数据
  339. const sessionUser = ctx.session.sessionUser;
  340. // 获取账号数据
  341. const accountData = await ctx.service.projectAccount.getDataByCondition({ id: sessionUser.accountId });
  342. const renderData = {
  343. accountData,
  344. fujianOssPath: ctx.app.config.fujianOssPath,
  345. };
  346. await this.layout('profile/sign.ejs', renderData);
  347. }
  348. /**
  349. * 网证通电子签名页
  350. *
  351. * @param {object} ctx - egg全局变量
  352. * @return {void}
  353. */
  354. async netcasign(ctx) {
  355. // 获取当前用户数据
  356. const sessionUser = ctx.session.sessionUser;
  357. // 获取账号数据
  358. const accountData = await ctx.service.projectAccount.getDataByCondition({ id: sessionUser.accountId });
  359. const signData = await ctx.service.netcasign.getDataByCondition({ uid: sessionUser.accountId });
  360. const renderData = {
  361. accountData,
  362. signData,
  363. };
  364. await this.layout('profile/netcasign.ejs', renderData, 'profile/sign_modal.ejs');
  365. }
  366. /**
  367. * 网证通电子签名页面操作
  368. *
  369. * @param {object} ctx - egg全局变量
  370. * @return {void}
  371. */
  372. async signSave(ctx) {
  373. const response = {
  374. err: 0,
  375. msg: '',
  376. };
  377. try {
  378. const sessionUser = ctx.session.sessionUser;
  379. const data = JSON.parse(ctx.request.body.data);
  380. let signData;
  381. switch (data.type) {
  382. case 'bind':
  383. signData = await ctx.service.netcasign.getDataByCondition({ pid: ctx.session.sessionProject.id, keyId: data.updateData.keyId });
  384. if (signData) {
  385. const accountData = await ctx.service.projectAccount.getDataByCondition({ id: signData.uid });
  386. throw '该Ukey已绑定于 ' + accountData.name + ', 不可重复绑定';
  387. }
  388. const result = await ctx.service.netcasign.add(data.updateData, sessionUser.accountId);
  389. if (!result) {
  390. throw '绑定Ukey失败';
  391. }
  392. response.data = await ctx.service.netcasign.getDataByCondition({ uid: sessionUser.accountId });
  393. break;
  394. case 'unbind':
  395. signData = await ctx.service.netcasign.getDataByCondition({ pid: ctx.session.sessionProject.id, uid: sessionUser.accountId });
  396. if (!signData) {
  397. throw '当前用户不存在绑定证书,解除绑定失败';
  398. }
  399. await ctx.service.netcasign.del(signData.id);
  400. break;
  401. case 'savesign':
  402. signData = await ctx.service.netcasign.getDataByCondition({ pid: ctx.session.sessionProject.id, uid: sessionUser.accountId });
  403. if (!signData) {
  404. throw '当前用户不存在绑定证书';
  405. }
  406. await ctx.service.netcasign.save({ sign_base64: data.sign_base64 }, signData.id);
  407. break;
  408. case 'delsign':
  409. signData = await ctx.service.netcasign.getDataByCondition({ pid: ctx.session.sessionProject.id, uid: sessionUser.accountId });
  410. if (!signData) {
  411. throw '当前用户不存在绑定证书';
  412. }
  413. if (signData && !signData.sign_base64) {
  414. throw '当前用户不存在签名,移除签名失败';
  415. }
  416. await ctx.service.netcasign.save({ sign_base64: null }, signData.id);
  417. break;
  418. default:throw '参数有误';
  419. }
  420. } catch (error) {
  421. response.err = 1;
  422. response.msg = error.toString();
  423. }
  424. ctx.body = response;
  425. }
  426. /**
  427. * 电子签名删除
  428. *
  429. * @param {object} ctx - egg全局变量
  430. * @return {void}
  431. */
  432. async signDelete(ctx) {
  433. const response = {
  434. err: 0,
  435. msg: '',
  436. };
  437. try {
  438. const sessionUser = ctx.session.sessionUser;
  439. // 获取账号数据
  440. const accountData = await ctx.service.projectAccount.getDataByCondition({ id: sessionUser.accountId });
  441. const data = JSON.parse(ctx.request.body.data);
  442. let result = false;
  443. if (data.type && data.type === 'stamp') {
  444. if (!accountData.stamp_path) {
  445. throw '不存在签章';
  446. }
  447. const stamp_path_list = accountData.stamp_path.split('!;!');
  448. const spIndex = ctx.helper._.indexOf(stamp_path_list, data.src);
  449. if (spIndex === -1) {
  450. throw '不存在此签章';
  451. }
  452. // 不删除地址,只删除数据库数据,防止已签章的报表丢失
  453. // await ctx.app.fujianOss.delete(ctx.app.config.fujianOssFolder + stamp_path_list[spIndex]);
  454. stamp_path_list.splice(spIndex, 1);
  455. // 删除库
  456. result = await ctx.service.projectAccount.update({ stamp_path: stamp_path_list.length === 0 ? null : stamp_path_list.join('!;!') }, { id: sessionUser.accountId });
  457. } else {
  458. if (accountData.sign_path === '') {
  459. throw '不存在签名';
  460. }
  461. result = await ctx.service.projectAccount.update({ sign_path: '' }, { id: sessionUser.accountId });
  462. }
  463. if (!result) {
  464. throw '移除签名失败';
  465. }
  466. } catch (error) {
  467. response.err = 1;
  468. response.msg = error.toString();
  469. }
  470. ctx.body = response;
  471. }
  472. /**
  473. * 生成二维码
  474. *
  475. * @param {object} ctx - egg全局变量
  476. * @return {void}
  477. */
  478. async qrCode(ctx) {
  479. const size = 5;
  480. const margin = 1;
  481. try {
  482. // 获取当前用户数据
  483. const sessionUser = ctx.session.sessionUser;
  484. let text = ctx.protocol + '://' + ctx.host + '/sign?user_id=' + sessionUser.accountId + '&app_token=' + sessionUser.sessionToken;
  485. if (ctx.query.from === 'netcasign') {
  486. text += '&from=netcasign';
  487. }
  488. // 大小默认5,二维码周围间距默认1
  489. const img = qr.image(text || '', { type: 'png', size: size || 5, margin: margin || 1 });
  490. ctx.status = 200;
  491. ctx.type = 'image/png';
  492. ctx.body = img;
  493. } catch (e) {
  494. ctx.status = 414;
  495. ctx.set('Content-Type', 'text/html');
  496. ctx.body = '<h1>414 Request-URI Too Large</h1>';
  497. }
  498. }
  499. /**
  500. * 上传签名图
  501. *
  502. * @param {object} ctx - egg全局变量
  503. * @return {void}
  504. */
  505. async signUpload(ctx) {
  506. const responseData = {
  507. err: 0, msg: '', data: null,
  508. };
  509. try {
  510. const stream = await ctx.getFileStream();
  511. const create_time = Date.parse(new Date()) / 1000;
  512. const fileInfo = path.parse(stream.filename);
  513. if (stream.fields && stream.fields.type && stream.fields.type === 'stamp') {
  514. // const dirName = 'app/public/upload/sign/profile';
  515. // const fileName = moment().format('YYYYMMDD') + '_sign_' + create_time + fileInfo.ext;
  516. const filepath = `app/public/upload/sign/profile/qianzhang_${create_time + fileInfo.ext}`;
  517. await ctx.app.fujianOss.put(ctx.app.config.fujianOssFolder + filepath, stream);
  518. await sendToWormhole(stream);
  519. const result = await ctx.service.projectAccount.update({ stamp_path: filepath }, { id: ctx.session.sessionUser.accountId });
  520. if (result) {
  521. responseData.data = { stamp_path: filepath };
  522. } else {
  523. throw '添加数据库失败';
  524. }
  525. } else {
  526. const dirName = 'public/upload/sign';
  527. const fileName = moment().format('YYYYMMDD') + '_sign_' + create_time + fileInfo.ext;
  528. await ctx.helper.saveStreamFile(stream, path.join(this.app.baseDir, 'app', dirName, fileName));
  529. await sendToWormhole(stream);
  530. const result = await ctx.service.projectAccount.update({ sign_path: fileName }, { id: ctx.session.sessionUser.accountId });
  531. if (result) {
  532. responseData.data = { sign_path: fileName };
  533. } else {
  534. throw '添加数据库失败';
  535. }
  536. }
  537. } catch (err) {
  538. this.log(err);
  539. responseData.err = 1;
  540. responseData.msg = err;
  541. }
  542. ctx.body = responseData;
  543. }
  544. /**
  545. * 上传签章图(多选)
  546. *
  547. * @param {object} ctx - egg全局变量
  548. * @return {void}
  549. */
  550. async stampUpload(ctx) {
  551. const responseData = {
  552. err: 0, msg: '', data: null,
  553. };
  554. let stream;
  555. try {
  556. const parts = ctx.multipart({ autoFields: true });
  557. const paths = [];
  558. let index = 0;
  559. stream = await parts();
  560. while (stream !== undefined) {
  561. // 判断用户是否选择上传文件
  562. if (!stream.filename) {
  563. throw '请选择上传的文件!';
  564. }
  565. const fileInfo = path.parse(stream.filename);
  566. const create_time = Date.parse(new Date()) / 1000;
  567. const filepath = `app/public/upload/sign/profile/qianzhang_${create_time + index.toString() + fileInfo.ext}`;
  568. // await ctx.helper.saveStreamFile(stream, path.resolve(this.app.baseDir, filepath));
  569. await ctx.app.fujianOss.put(ctx.app.config.fujianOssFolder + filepath, stream);
  570. if (stream) {
  571. await sendToWormhole(stream);
  572. }
  573. paths.push(filepath);
  574. ++index;
  575. if (Array.isArray(parts.field.size) && index < parts.field.size.length) {
  576. stream = await parts();
  577. } else {
  578. stream = undefined;
  579. }
  580. }
  581. // 获取账号数据
  582. const accountData = await ctx.service.projectAccount.getDataByCondition({ id: ctx.session.sessionUser.accountId });
  583. const stamp_path = accountData.stamp_path ? accountData.stamp_path.split('!;!') : [];
  584. const stamp_path_list = ctx.helper._.concat(stamp_path, paths);
  585. const result = await ctx.service.projectAccount.update({ stamp_path: stamp_path_list.join('!;!') }, { id: ctx.session.sessionUser.accountId });
  586. if (result) {
  587. responseData.data = { stamp_path: stamp_path_list };
  588. } else {
  589. throw '添加数据库失败';
  590. }
  591. } catch (err) {
  592. this.log(err);
  593. // 失败需要消耗掉stream 以防卡死
  594. if (stream) {
  595. await sendToWormhole(stream);
  596. }
  597. responseData.err = 1;
  598. responseData.msg = err.toString();
  599. }
  600. ctx.body = responseData;
  601. }
  602. /**
  603. * 账号安全
  604. *
  605. * @param {object} ctx - egg全局变量
  606. * @return {void}
  607. */
  608. async safe(ctx) {
  609. // 获取当前用户数据
  610. const sessionUser = ctx.session.sessionUser;
  611. // 获取账号数据
  612. const accountData = await ctx.service.projectAccount.getDataByCondition({ id: sessionUser.accountId });
  613. // 获取修改密码的字段规则
  614. // const passwordRule = ctx.service.projectAccount.rule('modifyPassword');
  615. // const passwordJsValidator = await this.jsValidator.convert(passwordRule).setSelector('#password-form').build();
  616. // console.log(passwordJsValidator);
  617. // 获取登录日志
  618. const loginLogging = await ctx.service.loginLogging.getLoginLogs(ctx.session.sessionProject.id, ctx.session.sessionUser.accountId);
  619. const renderData = {
  620. accountData,
  621. // passwordJsValidator,
  622. loginLogging,
  623. loginWay,
  624. };
  625. await this.layout('profile/safe.ejs', renderData);
  626. }
  627. /**
  628. * 微信通知
  629. *
  630. * @param {object} ctx - egg全局变量
  631. * @return {void}
  632. */
  633. async wechat(ctx) {
  634. // 获取当前用户数据
  635. const sessionUser = ctx.session.sessionUser;
  636. // 获取账号数据
  637. const accountData = await ctx.service.projectAccount.getDataByCondition({ id: sessionUser.accountId });
  638. if (accountData.qywx_user_info !== null) {
  639. accountData.qywx_user_info = JSON.parse(accountData.qywx_user_info);
  640. }
  641. const renderData = {
  642. accountData,
  643. smsType: smsTypeConst.type,
  644. };
  645. await this.layout('profile/wechat.ejs', renderData, 'profile/wechat_modal.ejs');
  646. }
  647. /**
  648. * 微信解绑
  649. *
  650. * @param {object} ctx - egg全局变量
  651. * @return {void}
  652. */
  653. async removeWechat(ctx) {
  654. try {
  655. const sessionUser = ctx.session.sessionUser;
  656. // 获取账号数据
  657. const accountData = await ctx.service.projectAccount.getDataByCondition({ id: sessionUser.accountId });
  658. // 判断解绑类型
  659. if (ctx.request.body.data_type === 'wxWork') {
  660. const result = await ctx.service.projectAccount.bindWx4Work(sessionUser.accountId, null, null, null);
  661. if (!result) {
  662. throw '解绑企业微信失败!';
  663. }
  664. // 解绑成功通知
  665. const qywx = new wxWork(ctx);
  666. const desc = '您好,纵横云计量与企业微信解绑成功。';
  667. const content = [
  668. {
  669. keyname: '项目编号',
  670. value: ctx.session.sessionProject.code,
  671. },
  672. {
  673. keyname: '账号',
  674. value: sessionUser.account,
  675. },
  676. {
  677. keyname: '绑定时间',
  678. value: moment(new Date()).format('YYYY-MM-DD'),
  679. },
  680. {
  681. keyname: '备注',
  682. value: '感谢您的使用,要接收通知请重新绑定。',
  683. },
  684. ];
  685. const url = ctx.protocol + '://' + ctx.host + '/wx/tips?msg=解绑成功,感谢您的使用。';
  686. await qywx.sendTemplateCard([accountData.qywx_userid], accountData.qywx_corpid, '账号解绑成功通知', desc, content, url);
  687. this.setMessage('企业微信解绑成功', this.messageType.SUCCESS);
  688. } else {
  689. const result = await ctx.service.projectAccount.bindWx(sessionUser.accountId, null, null);
  690. if (!result) {
  691. throw '解绑微信失败!';
  692. }
  693. // 解绑成功通知
  694. const templateId = '0w0Yp65X4PHccTLeAyE5aQhS-blS-bylwxAPYEGy3CI';
  695. const url = '';
  696. const msgData = {
  697. first: {
  698. value: '您好,纵横云计量与微信解绑成功。',
  699. },
  700. keyword1: {
  701. value: ctx.session.sessionProject.code,
  702. },
  703. keyword2: {
  704. value: sessionUser.account,
  705. },
  706. keyword3: {
  707. value: moment(new Date()).format('YYYY-MM-DD'),
  708. },
  709. remark: {
  710. value: '感谢您的使用,要接收通知请重新绑定。',
  711. },
  712. };
  713. await app.wechat.api.sendTemplate(accountData.wx_openid, templateId, url, '', msgData);
  714. this.setMessage('微信解绑成功', this.messageType.SUCCESS);
  715. }
  716. } catch (error) {
  717. console.log(error);
  718. this.setMessage(error.toString(), this.messageType.ERROR);
  719. }
  720. ctx.redirect(ctx.request.header.referer);
  721. }
  722. }
  723. return ProfileController;
  724. };