fix: 整合邮件发送代码

This commit is contained in:
gaoxiaolin.gao 2018-06-28 10:27:31 +08:00
parent 57b1be1031
commit f768900716
9 changed files with 273 additions and 101 deletions

View File

@ -1,7 +1,7 @@
# 接口设置
进入项目页可以看到项目下的所有接口需要注意的是YApi有 `接口集合``测试集合` 两个概念。
- `接口集合` 将接口进行分类,使结构结构更清晰,一个接口只能属于一个集合,且不允许与其他接口重名。
- `接口集合` 将接口进行分类,使接口结构更清晰,一个接口只能属于一个集合,且不允许与其他接口重名。
- `测试集合` 为了方便我们测试接口,`测试集合` 将若干接口组合在一起,在这里一个接口可以属于不同集合。
## 接口配置

View File

@ -125,6 +125,20 @@ hooks = {
mulit: false,
listener: null
},
/**
* 导入数据
* @param Object importDataModule
*
* @info
* 可参考 vendors/exts/yapi-plugin-import-swagger插件
* importDataModule = {};
*
*/
import_data: {
type: 'listener',
mulit: true,
listener: []
},
/**
* 导出数据
* @param Object exportDataModule
@ -142,20 +156,6 @@ hooks = {
mulit: true,
listener: []
},
/**
* 导入数据
* @param importDataModule
*
* @info
* 可参考 vendors/exts/yapi-plugin-import-swagger插件
* importDataModule = {};
*
*/
import_data: {
type: 'listener',
mulit: true,
listener: []
},
/**
* 接口页面 tab 钩子
* @param InterfaceTabs
@ -181,6 +181,104 @@ hooks = {
type: 'listener',
mulit: true,
listener: []
},
/**
* header下拉菜单 menu 钩子
* @param HeaderMenu
*
* @info
* 可参考 vendors/exts/yapi-plugin-statistics
* let HeaderMenu = {
user: {
path: '/user/profile',
name: '个人中心',
icon: 'user',
adminFlag: false
},
star: {
path: '/follow',
name: '我的关注',
icon: 'star-o',
adminFlag: false
},
solution: {
path: '/user/list',
name: '用户管理',
icon: 'solution',
adminFlag: true
},
logout: {
path: '',
name: '退出',
icon: 'logout',
adminFlag: false
}
};
*/
header_menu: {
type: 'listener',
mulit: true,
listener: []
},
/**
* Route路由列表钩子
* @param AppRoute
*
* @info
* 可参考 vendors/exts/yapi-plugin-statistics
* 添加位置在Application.js 中
* let AppRoute = {
home: {
path: '/',
component: Home
},
group: {
path: '/group',
component: Group
},
project: {
path: '/project/:id',
component: Project
},
user: {
path: '/user',
component: User
},
follow: {
path: '/follow',
component: Follows
},
addProject: {
path: '/add-project',
component: AddProject
},
login: {
path: '/login',
component: Login
}
};
};
*/
app_route: {
type: 'listener',
mulit: true,
listener: []
},
/*
* 添加 reducer
* @param Object reducerModules
*
* @info
* importDataModule = {};
*
*/
add_reducer: {
type: 'listener',
mulit: true,
listener: []
}
};
```

View File

@ -293,7 +293,7 @@ class groupController extends baseController {
let groupUserdata = await this.getUserdata(params.member_uid, params.role);
yapi.commons.saveLog({
content: `<a href="/user/profile/${this.getUid()}">${username}</a> 更改了分组成员 <a href="/user/profile/${params.member_uid}">${groupUserdata.username }</a> 的权限为 "${rolename[params.role]}"`,
content: `<a href="/user/profile/${this.getUid()}">${username}</a> 更改了分组成员 <a href="/user/profile/${params.member_uid}">${groupUserdata ? groupUserdata.username: '' }</a> 的权限为 "${rolename[params.role]}"`,
type: 'group',
uid: this.getUid(),
username: username,

View File

@ -592,7 +592,7 @@ class interfaceController extends baseController {
let project = await this.projectModel.getBaseInfo(interfaceData.project_id);
let interfaceUrl = `http://${ctx.request.host}/project/${interfaceData.project_id}/interface/api/${id}`
this.sendNotice(interfaceData.project_id, {
yapi.commons.sendNotice(interfaceData.project_id, {
title: `${username} 更新了接口`,
content: `<html>
<head>
@ -922,41 +922,6 @@ class interfaceController extends baseController {
}
async sendNotice(projectId, data) {
const list = await this.followModel.listByProjectId(projectId);
const starUsers = list.map(item => item.uid);
const projectList = await this.projectModel.get(projectId);
// const projectMembers = projectList.members.map(item => item.uid);
const projectMembers = projectList.members.filter(item => item.email_notice).map(item => item.uid);
const users = this.arrUnique(projectMembers, starUsers);
const usersInfo = await this.userModel.findByUids(users)
const emails = usersInfo.map(item => item.email).join(',');
try {
yapi.commons.sendMail({
to: emails,
contents: data.content,
subject: data.title
})
} catch (e) {
yapi.commons.log('邮件发送失败:' + e, 'error')
}
}
arrUnique(arr1, arr2) {
let arr = arr1.concat(arr2);
let res = arr.filter(function (item, index, arr) {
return arr.indexOf(item) === index;
})
return res;
}
requiredSort(params) {
return params.sort((item1, item2) => {
return item2.required - item1.required;

View File

@ -228,7 +228,7 @@ class openController extends baseController {
let autoTestUrl = `http://${
ctx.request.host
}/api/open/run_auto_test?id=${id}&token=${token}&mode=${ctx.params.mode}`;
this.sendNotice(projectId, {
yapi.commons.sendNotice(projectId, {
title: `YApi自动化测试报告`,
content: `
<html>
@ -317,36 +317,7 @@ class openController extends baseController {
return result;
}
async sendNotice(projectId, data) {
const list = await this.followModel.listByProjectId(projectId);
const starUsers = list.map(item => item.uid);
const projectList = await this.projectModel.get(projectId);
const projectMenbers = projectList.members.filter(item => item.email_notice).map(item => item.uid);
const users = this.arrUnique(projectMenbers, starUsers);
const usersInfo = await this.userModel.findByUids(users);
const emails = usersInfo.map(item => item.email).join(',');
try {
yapi.commons.sendMail({
to: emails,
contents: data.content,
subject: data.title
});
} catch (e) {
yapi.commons.log('邮件发送失败:' + e, 'error');
}
}
arrUnique(arr1, arr2) {
let arr = arr1.concat(arr2);
let res = arr.filter(function(item, index, arr) {
return arr.indexOf(item) === index;
});
return res;
}
async handleScriptTest(interfaceData, response, validRes, requestParams) {
if (interfaceData.enable_script !== true) {

View File

@ -8,6 +8,7 @@ const interfaceColModel = require('../models/interfaceCol.js');
const interfaceCaseModel = require('../models/interfaceCase.js');
const interfaceModel = require('../models/interface.js');
const userModel = require('../models/user.js');
const followModel = require('../models/follow.js')
const json5 = require('json5');
const _ = require('underscore');
const Ajv = require('ajv');
@ -546,3 +547,39 @@ exports.getUserdata = async function getUserdata(uid, role) {
};
};
exports.sendNotice = async function sendNotice(projectId, data) {
const followInst = yapi.getInst(followModel);
const userInst = yapi.getInst(userModel);
const projectInst = yapi.getInst(projectModel);
const list = await followInst.listByProjectId(projectId);
const starUsers = list.map(item => item.uid);
const projectList = await projectInst.get(projectId);
const projectMenbers = projectList.members.filter(item => item.email_notice).map(item => item.uid);
const users = arrUnique(projectMenbers, starUsers);
const usersInfo = await userInst.findByUids(users);
const emails = usersInfo.map(item => item.email).join(',');
try {
yapi.commons.sendMail({
to: emails,
contents: data.content,
subject: data.title
});
} catch (e) {
yapi.commons.log('邮件发送失败:' + e, 'error');
}
}
function arrUnique(arr1, arr2) {
let arr = arr1.concat(arr2);
let res = arr.filter(function (item, index, arr) {
return arr.indexOf(item) === index;
})
return res;
}

View File

@ -16,6 +16,9 @@
<ul>
<li>新建接口自动添加为项目成员</li>
<li>修复type为raw header type 为form 时运行body 为空问题</li>
<li>mongodb3.4-&gt; 3.6 聚合 cursor报错</li>
<li>path 路径支持 </li>
<li>json-schema 编辑器修复修改 type 导致描述信息被重置的问题</li>
</ul>
<h3 id="v1.3.17">v1.3.17</h3>
<ul>

View File

@ -128,6 +128,20 @@ hooks = {
mulit: false,
listener: null
},
/**
* &#x5BFC;&#x5165;&#x6570;&#x636E;
* @param Object importDataModule
*
* @info
* &#x53EF;&#x53C2;&#x8003; vendors/exts/yapi-plugin-import-swagger&#x63D2;&#x4EF6;
* importDataModule = {};
*
*/
import_data: {
type: &#x27;listener&#x27;,
mulit: true,
listener: []
},
/**
* &#x5BFC;&#x51FA;&#x6570;&#x636E;
* @param Object exportDataModule
@ -145,20 +159,6 @@ hooks = {
mulit: true,
listener: []
},
/**
* &#x5BFC;&#x5165;&#x6570;&#x636E;
* @param importDataModule
*
* @info
* &#x53EF;&#x53C2;&#x8003; vendors/exts/yapi-plugin-import-swagger&#x63D2;&#x4EF6;
* importDataModule = {};
*
*/
import_data: {
type: &#x27;listener&#x27;,
mulit: true,
listener: []
},
/**
* &#x63A5;&#x53E3;&#x9875;&#x9762; tab &#x94A9;&#x5B50;
* @param InterfaceTabs
@ -184,6 +184,104 @@ hooks = {
type: &#x27;listener&#x27;,
mulit: true,
listener: []
},
/**
* header&#x4E0B;&#x62C9;&#x83DC;&#x5355; menu &#x94A9;&#x5B50;
* @param HeaderMenu
*
* @info
* &#x53EF;&#x53C2;&#x8003; vendors/exts/yapi-plugin-statistics
* let HeaderMenu = {
user: {
path: &#x27;/user/profile&#x27;,
name: &#x27;&#x4E2A;&#x4EBA;&#x4E2D;&#x5FC3;&#x27;,
icon: &#x27;user&#x27;,
adminFlag: false
},
star: {
path: &#x27;/follow&#x27;,
name: &#x27;&#x6211;&#x7684;&#x5173;&#x6CE8;&#x27;,
icon: &#x27;star-o&#x27;,
adminFlag: false
},
solution: {
path: &#x27;/user/list&#x27;,
name: &#x27;&#x7528;&#x6237;&#x7BA1;&#x7406;&#x27;,
icon: &#x27;solution&#x27;,
adminFlag: true
},
logout: {
path: &#x27;&#x27;,
name: &#x27;&#x9000;&#x51FA;&#x27;,
icon: &#x27;logout&#x27;,
adminFlag: false
}
};
*/
header_menu: {
type: &#x27;listener&#x27;,
mulit: true,
listener: []
},
/**
* Route&#x8DEF;&#x7531;&#x5217;&#x8868;&#x94A9;&#x5B50;
* @param AppRoute
*
* @info
* &#x53EF;&#x53C2;&#x8003; vendors/exts/yapi-plugin-statistics
* &#x6DFB;&#x52A0;&#x4F4D;&#x7F6E;&#x5728;Application.js &#x4E2D;
* let AppRoute = {
home: {
path: &#x27;/&#x27;,
component: Home
},
group: {
path: &#x27;/group&#x27;,
component: Group
},
project: {
path: &#x27;/project/:id&#x27;,
component: Project
},
user: {
path: &#x27;/user&#x27;,
component: User
},
follow: {
path: &#x27;/follow&#x27;,
component: Follows
},
addProject: {
path: &#x27;/add-project&#x27;,
component: AddProject
},
login: {
path: &#x27;/login&#x27;,
component: Login
}
};
};
*/
app_route: {
type: &#x27;listener&#x27;,
mulit: true,
listener: []
},
/*
* &#x6DFB;&#x52A0; reducer
* @param Object reducerModules
*
* @info
* importDataModule = {};
*
*/
add_reducer: {
type: &#x27;listener&#x27;,
mulit: true,
listener: []
}
};
</code></pre>

View File

@ -995,7 +995,7 @@ window.ydoc_plugin_search_json = {
{
"title": "前端 hookList",
"url": "/documents/plugin-hooks.html#前端-hooklist",
"content": "前端 hookList/** * type component 组件\n * listener 监听函数\n * mulit 是否绑定多个监听函数\n *\n */\n\nhooks = {\n /**\n * 第三方登录 //可参考 yapi-plugin-qsso 插件\n */\n third_login: {\n type: 'component',\n mulit: false,\n listener: null\n },\n /**\n * 导出数据\n * @param Object exportDataModule\n * @param projectId\n * @info\n * exportDataModule = {};\n * exportDataModule.pdf = {\n * name: 'Pdf',\n * route: '/api/plugin/export/pdf',\n * desc: '导出项目接口文档为 pdf 文件'\n * }\n */\n export_data: {\n type: 'listener',\n mulit: true,\n listener: []\n },\n /**\n * 导入数据\n * @param importDataModule\n *\n * @info\n * 可参考 vendors/exts/yapi-plugin-import-swagger插件\n * importDataModule = {};\n *\n */\n import_data: {\n type: 'listener',\n mulit: true,\n listener: []\n },\n /**\n * 接口页面 tab 钩子\n * @param InterfaceTabs\n *\n * @info\n * 可参考 vendors/exts/yapi-plugin-advanced-mock\n * let InterfaceTabs = {\n view: {\n component: View,\n name: '预览'\n },\n edit: {\n component: Edit,\n name: '编辑'\n },\n run: {\n component: Run,\n name: '运行'\n }\n }\n */\n interface_tab: {\n type: 'listener',\n mulit: true,\n listener: []\n }\n};\n"
"content": "前端 hookList/** * type component 组件\n * listener 监听函数\n * mulit 是否绑定多个监听函数\n *\n */\n\nhooks = {\n /**\n * 第三方登录 //可参考 yapi-plugin-qsso 插件\n */\n third_login: {\n type: 'component',\n mulit: false,\n listener: null\n },\n /**\n * 导入数据\n * @param Object importDataModule\n *\n * @info\n * 可参考 vendors/exts/yapi-plugin-import-swagger插件\n * importDataModule = {};\n *\n */\n import_data: {\n type: 'listener',\n mulit: true,\n listener: []\n },\n /**\n * 导出数据\n * @param Object exportDataModule\n * @param projectId\n * @info\n * exportDataModule = {};\n * exportDataModule.pdf = {\n * name: 'Pdf',\n * route: '/api/plugin/export/pdf',\n * desc: '导出项目接口文档为 pdf 文件'\n * }\n */\n export_data: {\n type: 'listener',\n mulit: true,\n listener: []\n },\n /**\n * 接口页面 tab 钩子\n * @param InterfaceTabs\n *\n * @info\n * 可参考 vendors/exts/yapi-plugin-advanced-mock\n * let InterfaceTabs = {\n view: {\n component: View,\n name: '预览'\n },\n edit: {\n component: Edit,\n name: '编辑'\n },\n run: {\n component: Run,\n name: '运行'\n }\n }\n */\n interface_tab: {\n type: 'listener',\n mulit: true,\n listener: []\n },\n /**\n * header下拉菜单 menu 钩子\n * @param HeaderMenu\n *\n * @info\n * 可参考 vendors/exts/yapi-plugin-statistics\n * let HeaderMenu = {\n user: {\n path: '/user/profile',\n name: '个人中心',\n icon: 'user',\n adminFlag: false\n },\n star: {\n path: '/follow',\n name: '我的关注',\n icon: 'star-o',\n adminFlag: false\n },\n solution: {\n path: '/user/list',\n name: '用户管理',\n icon: 'solution',\n adminFlag: true\n\n },\n logout: {\n path: '',\n name: '退出',\n icon: 'logout',\n adminFlag: false\n\n }\n};\n */\n header_menu: {\n type: 'listener',\n mulit: true,\n listener: []\n },\n /**\n * Route路由列表钩子\n * @param AppRoute\n *\n * @info\n * 可参考 vendors/exts/yapi-plugin-statistics\n * 添加位置在Application.js 中\n * let AppRoute = {\n home: {\n path: '/',\n component: Home\n },\n group: {\n path: '/group',\n component: Group\n },\n project: {\n path: '/project/:id',\n component: Project\n },\n user: {\n path: '/user',\n component: User\n },\n follow: {\n path: '/follow',\n component: Follows\n },\n addProject: {\n path: '/add-project',\n component: AddProject\n },\n login: {\n path: '/login',\n component: Login\n }\n};\n};\n */\n app_route: {\n type: 'listener',\n mulit: true,\n listener: []\n },\n /*\n * 添加 reducer\n * @param Object reducerModules\n *\n * @info\n * importDataModule = {};\n *\n */\n\n add_reducer: {\n type: 'listener',\n mulit: true,\n listener: []\n }\n};\n"
}
]
},
@ -1012,7 +1012,7 @@ window.ydoc_plugin_search_json = {
{
"title": "前端 hookList",
"url": "/documents/plugin-hooks.html#前端-hooklist",
"content": "前端 hookList/** * type component 组件\n * listener 监听函数\n * mulit 是否绑定多个监听函数\n *\n */\n\nhooks = {\n /**\n * 第三方登录 //可参考 yapi-plugin-qsso 插件\n */\n third_login: {\n type: 'component',\n mulit: false,\n listener: null\n },\n /**\n * 导出数据\n * @param Object exportDataModule\n * @param projectId\n * @info\n * exportDataModule = {};\n * exportDataModule.pdf = {\n * name: 'Pdf',\n * route: '/api/plugin/export/pdf',\n * desc: '导出项目接口文档为 pdf 文件'\n * }\n */\n export_data: {\n type: 'listener',\n mulit: true,\n listener: []\n },\n /**\n * 导入数据\n * @param importDataModule\n *\n * @info\n * 可参考 vendors/exts/yapi-plugin-import-swagger插件\n * importDataModule = {};\n *\n */\n import_data: {\n type: 'listener',\n mulit: true,\n listener: []\n },\n /**\n * 接口页面 tab 钩子\n * @param InterfaceTabs\n *\n * @info\n * 可参考 vendors/exts/yapi-plugin-advanced-mock\n * let InterfaceTabs = {\n view: {\n component: View,\n name: '预览'\n },\n edit: {\n component: Edit,\n name: '编辑'\n },\n run: {\n component: Run,\n name: '运行'\n }\n }\n */\n interface_tab: {\n type: 'listener',\n mulit: true,\n listener: []\n }\n};\n"
"content": "前端 hookList/** * type component 组件\n * listener 监听函数\n * mulit 是否绑定多个监听函数\n *\n */\n\nhooks = {\n /**\n * 第三方登录 //可参考 yapi-plugin-qsso 插件\n */\n third_login: {\n type: 'component',\n mulit: false,\n listener: null\n },\n /**\n * 导入数据\n * @param Object importDataModule\n *\n * @info\n * 可参考 vendors/exts/yapi-plugin-import-swagger插件\n * importDataModule = {};\n *\n */\n import_data: {\n type: 'listener',\n mulit: true,\n listener: []\n },\n /**\n * 导出数据\n * @param Object exportDataModule\n * @param projectId\n * @info\n * exportDataModule = {};\n * exportDataModule.pdf = {\n * name: 'Pdf',\n * route: '/api/plugin/export/pdf',\n * desc: '导出项目接口文档为 pdf 文件'\n * }\n */\n export_data: {\n type: 'listener',\n mulit: true,\n listener: []\n },\n /**\n * 接口页面 tab 钩子\n * @param InterfaceTabs\n *\n * @info\n * 可参考 vendors/exts/yapi-plugin-advanced-mock\n * let InterfaceTabs = {\n view: {\n component: View,\n name: '预览'\n },\n edit: {\n component: Edit,\n name: '编辑'\n },\n run: {\n component: Run,\n name: '运行'\n }\n }\n */\n interface_tab: {\n type: 'listener',\n mulit: true,\n listener: []\n },\n /**\n * header下拉菜单 menu 钩子\n * @param HeaderMenu\n *\n * @info\n * 可参考 vendors/exts/yapi-plugin-statistics\n * let HeaderMenu = {\n user: {\n path: '/user/profile',\n name: '个人中心',\n icon: 'user',\n adminFlag: false\n },\n star: {\n path: '/follow',\n name: '我的关注',\n icon: 'star-o',\n adminFlag: false\n },\n solution: {\n path: '/user/list',\n name: '用户管理',\n icon: 'solution',\n adminFlag: true\n\n },\n logout: {\n path: '',\n name: '退出',\n icon: 'logout',\n adminFlag: false\n\n }\n};\n */\n header_menu: {\n type: 'listener',\n mulit: true,\n listener: []\n },\n /**\n * Route路由列表钩子\n * @param AppRoute\n *\n * @info\n * 可参考 vendors/exts/yapi-plugin-statistics\n * 添加位置在Application.js 中\n * let AppRoute = {\n home: {\n path: '/',\n component: Home\n },\n group: {\n path: '/group',\n component: Group\n },\n project: {\n path: '/project/:id',\n component: Project\n },\n user: {\n path: '/user',\n component: User\n },\n follow: {\n path: '/follow',\n component: Follows\n },\n addProject: {\n path: '/add-project',\n component: AddProject\n },\n login: {\n path: '/login',\n component: Login\n }\n};\n};\n */\n app_route: {\n type: 'listener',\n mulit: true,\n listener: []\n },\n /*\n * 添加 reducer\n * @param Object reducerModules\n *\n * @info\n * importDataModule = {};\n *\n */\n\n add_reducer: {\n type: 'listener',\n mulit: true,\n listener: []\n }\n};\n"
}
]
},
@ -1152,7 +1152,7 @@ window.ydoc_plugin_search_json = {
{
"title": "v1.3.18",
"url": "/documents/CHANGELOG.html#v1.3.18",
"content": "v1.3.18增加全局接口搜索功能\n邮件通知过滤功能\nBug Fixed新建接口自动添加为项目成员\n修复type为raw header type 为form 时运行body 为空问题\n"
"content": "v1.3.18增加全局接口搜索功能\n邮件通知过滤功能\nBug Fixed新建接口自动添加为项目成员\n修复type为raw header type 为form 时运行body 为空问题\nmongodb3.4-> 3.6 聚合 cursor报错\npath 路径支持 \njson-schema 编辑器修复修改 type 导致描述信息被重置的问题\n"
},
{
"title": "v1.3.17",
@ -1309,7 +1309,7 @@ window.ydoc_plugin_search_json = {
{
"title": "v1.3.18",
"url": "/documents/CHANGELOG.html#v1.3.18",
"content": "v1.3.18增加全局接口搜索功能\n邮件通知过滤功能\nBug Fixed新建接口自动添加为项目成员\n修复type为raw header type 为form 时运行body 为空问题\n"
"content": "v1.3.18增加全局接口搜索功能\n邮件通知过滤功能\nBug Fixed新建接口自动添加为项目成员\n修复type为raw header type 为form 时运行body 为空问题\nmongodb3.4-> 3.6 聚合 cursor报错\npath 路径支持 \njson-schema 编辑器修复修改 type 导致描述信息被重置的问题\n"
},
{
"title": "v1.3.17",