@dypnb/dev-tools 1.0.12 → 1.0.14
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/genSwagger/index.browser.js +1 -1
- package/dist/genSwagger/index.cjs +1 -1
- package/dist/genSwagger/index.mjs +1 -1
- package/package.json +2 -3
- package/src/dome.vue +0 -25
- package/src/gen-page/config.js +0 -40
- package/src/gen-page/index.js +0 -122
- package/src/gen-page/template.js +0 -568
- package/src/gen-swagger/index.js +0 -228
- package/src/index.js +0 -12
- package/src/publish-server/index.js +0 -144
- package/src/utils/index.js +0 -82
- package/src/wx-server-notice/README.md +0 -59
- package/src/wx-server-notice/api.js +0 -45
- package/src/wx-server-notice/images/qiyewx-1.png +0 -0
- package/src/wx-server-notice/images/qiyewx-2.png +0 -0
- package/src/wx-server-notice/images/qiyewx-3-1.png +0 -0
- package/src/wx-server-notice/images/qiyewx-3-2.png +0 -0
- package/src/wx-server-notice/images/qiyewx-3.png +0 -0
- package/src/wx-server-notice/images/qiyewx-4.png +0 -0
- package/src/wx-server-notice/images/qiyewx-5-1.jpg +0 -0
- package/src/wx-server-notice/images/qiyewx-5.jpg +0 -0
- package/src/wx-server-notice/images/qiyewx-6.png +0 -0
- package/src/wx-server-notice/index.js +0 -62
package/src/gen-swagger/index.js
DELETED
@@ -1,228 +0,0 @@
|
|
1
|
-
#! /usr/bin/env node
|
2
|
-
|
3
|
-
// 将swagger 转换为 vue api代码
|
4
|
-
import path from "path";
|
5
|
-
import fs from "fs";
|
6
|
-
import http from "http";
|
7
|
-
import { getGlobalConfig, getDirname, errorLog, log, successLog, } from "../utils/index.js";
|
8
|
-
const __dirname = getDirname();
|
9
|
-
|
10
|
-
|
11
|
-
async function getSwaggerConfig() {
|
12
|
-
return await getGlobalConfig('swaggerConfig');
|
13
|
-
}
|
14
|
-
|
15
|
-
getSwaggerConfig().then(res => {
|
16
|
-
// swagger配置
|
17
|
-
const swaggerConfig = res;
|
18
|
-
if (!swaggerConfig) {
|
19
|
-
errorLog('swaggerConfig 未配置')
|
20
|
-
}
|
21
|
-
|
22
|
-
// 生成api文件地址
|
23
|
-
const srcFolder = `${process.env.PWD}${swaggerConfig.outputDir}`;
|
24
|
-
// swagger接口地址
|
25
|
-
const url = `${swaggerConfig.path}${swaggerConfig.staticPath}`;
|
26
|
-
|
27
|
-
genSwagger(srcFolder, url);
|
28
|
-
|
29
|
-
})
|
30
|
-
|
31
|
-
|
32
|
-
// 生成本地文件
|
33
|
-
function mkdirsSync(dirname) {
|
34
|
-
if (fs.existsSync(dirname)) {
|
35
|
-
return true;
|
36
|
-
} else {
|
37
|
-
if (mkdirsSync(path.dirname(dirname))) {
|
38
|
-
fs.mkdirSync(dirname);
|
39
|
-
return true;
|
40
|
-
}
|
41
|
-
}
|
42
|
-
}
|
43
|
-
|
44
|
-
function getPath(pathUrl) {
|
45
|
-
return path.resolve(__dirname, pathUrl);
|
46
|
-
}
|
47
|
-
|
48
|
-
function generateTemplate(arr) {
|
49
|
-
return `import request from '@/utils/request'\n`;
|
50
|
-
}
|
51
|
-
|
52
|
-
// 下划线转换驼峰
|
53
|
-
function toHump(name) {
|
54
|
-
return name.replace(/\/(\w)/g, function (all, letter) {
|
55
|
-
return letter.toUpperCase();
|
56
|
-
});
|
57
|
-
}
|
58
|
-
|
59
|
-
// 短横线转换驼峰
|
60
|
-
function shortToHump(name) {
|
61
|
-
return name.replace(/-(\w)/g, function (all, letter) {
|
62
|
-
return letter.toUpperCase();
|
63
|
-
});
|
64
|
-
}
|
65
|
-
|
66
|
-
// 去除花括号,获取干净的字段
|
67
|
-
function removeBrace(value) {
|
68
|
-
const regex = /\{(.+?)\}/g; // {} 花括号,大括号
|
69
|
-
const str = value.match(regex)[0] || "";
|
70
|
-
return str.replace(/\{|}/g, "");
|
71
|
-
}
|
72
|
-
|
73
|
-
/**
|
74
|
-
* 生成具体的api:
|
75
|
-
* export function postRsArticle(data) {
|
76
|
-
* return request({
|
77
|
-
* url: '/rs/article',
|
78
|
-
* method: 'post',
|
79
|
-
* data: data
|
80
|
-
* })
|
81
|
-
* }
|
82
|
-
*/
|
83
|
-
function generateFunc(url, summary, type = "post") {
|
84
|
-
// 去除 url 环境前缀: /dev-risk-api/sc/apply/{applyId} ==> /sc/apply/{applyId}
|
85
|
-
// url = url.split('/');
|
86
|
-
// url.splice(1,1)
|
87
|
-
// url = url.join('/');
|
88
|
-
|
89
|
-
const isBrace = url.indexOf("{") !== -1;
|
90
|
-
let funcName = shortToHump(toHump(type + url));
|
91
|
-
let splitUrl = "";
|
92
|
-
let braceKey = "";
|
93
|
-
if (isBrace) {
|
94
|
-
splitUrl = url.split("{")[0];
|
95
|
-
braceKey = removeBrace(url);
|
96
|
-
funcName = shortToHump(toHump(type + splitUrl + braceKey));
|
97
|
-
}
|
98
|
-
|
99
|
-
const funcArguments = `${
|
100
|
-
isBrace
|
101
|
-
? braceKey
|
102
|
-
: !isBrace && (type === "post" || type === "put")
|
103
|
-
? "data"
|
104
|
-
: "query"
|
105
|
-
}`;
|
106
|
-
const funcUrl = `${!isBrace ? `'${url}'` : `'${splitUrl}' + ${braceKey}`}`;
|
107
|
-
const funcParams = `${
|
108
|
-
isBrace
|
109
|
-
? ""
|
110
|
-
: !isBrace && (type === "post" || type === "put")
|
111
|
-
? "\n data: data"
|
112
|
-
: "\n params: query"
|
113
|
-
}`;
|
114
|
-
|
115
|
-
return `
|
116
|
-
// ${summary || ""}
|
117
|
-
export function ${funcName}(${funcArguments}) {
|
118
|
-
return request({
|
119
|
-
url: ${funcUrl},
|
120
|
-
method: '${type}', ${funcParams}
|
121
|
-
})
|
122
|
-
}\n`;
|
123
|
-
}
|
124
|
-
|
125
|
-
function httpgetJson(url) {
|
126
|
-
return new Promise((resolve, reject) => {
|
127
|
-
http
|
128
|
-
.get(url, (res) => {
|
129
|
-
const { statusCode } = res;
|
130
|
-
const contentType = res.headers["content-type"];
|
131
|
-
|
132
|
-
let error;
|
133
|
-
if (statusCode !== 200) {
|
134
|
-
error = new Error("请求失败。\n" + `状态码: ${statusCode}`);
|
135
|
-
} else if (!/^application\/json/.test(contentType)) {
|
136
|
-
error = new Error(
|
137
|
-
"无效的 content-type.\n" +
|
138
|
-
`期望 application/json 但获取的是 ${contentType}`
|
139
|
-
);
|
140
|
-
}
|
141
|
-
if (error) {
|
142
|
-
errorLog(error.message);
|
143
|
-
// 消耗响应数据以释放内存
|
144
|
-
res.resume();
|
145
|
-
return;
|
146
|
-
}
|
147
|
-
|
148
|
-
res.setEncoding("utf8");
|
149
|
-
let rawData = "";
|
150
|
-
res.on("data", (chunk) => {
|
151
|
-
rawData += chunk;
|
152
|
-
});
|
153
|
-
res.on("end", () => {
|
154
|
-
try {
|
155
|
-
const parsedData = JSON.parse(rawData);
|
156
|
-
resolve(parsedData);
|
157
|
-
} catch (e) {
|
158
|
-
reject(`错误: ${e.message}`);
|
159
|
-
}
|
160
|
-
});
|
161
|
-
})
|
162
|
-
.on("error", (e) => {
|
163
|
-
reject(`错误: ${e.message}`);
|
164
|
-
});
|
165
|
-
});
|
166
|
-
}
|
167
|
-
|
168
|
-
async function genSwagger(srcFolder, url) {
|
169
|
-
log("获取远程json文件中...");
|
170
|
-
const { paths } = await httpgetJson(url);
|
171
|
-
successLog("获取成功正在生成api文件");
|
172
|
-
const obj = {};
|
173
|
-
/**
|
174
|
-
* 将数据转换成格式
|
175
|
-
* se-ex-exam-controller: [
|
176
|
-
* {
|
177
|
-
* folder:'exam'
|
178
|
-
* name:'/ex/exam'
|
179
|
-
* summary:'修改考试考卷'
|
180
|
-
* tag:'se-ex-exam-controller'
|
181
|
-
* type:'put'
|
182
|
-
* }
|
183
|
-
* ...
|
184
|
-
* ]
|
185
|
-
*/
|
186
|
-
for (const name in paths) {
|
187
|
-
const path = paths[name] || {};
|
188
|
-
const pathKeys = Object.keys(path) || [];
|
189
|
-
for (let i = 0, len = pathKeys.length; i < len; i++) {
|
190
|
-
const apiType = pathKeys[i];
|
191
|
-
const tag = path[apiType].tags[0];
|
192
|
-
if (!tag) continue;
|
193
|
-
log(tag);
|
194
|
-
const urlArray = name.slice(1).split("/");
|
195
|
-
const folder = urlArray[1];
|
196
|
-
const item = {
|
197
|
-
summary: path[apiType].summary,
|
198
|
-
tag,
|
199
|
-
name,
|
200
|
-
type: apiType,
|
201
|
-
folder,
|
202
|
-
};
|
203
|
-
if (obj[path[apiType].tags[0]]) {
|
204
|
-
obj[path[apiType].tags[0]].push(item);
|
205
|
-
} else {
|
206
|
-
obj[path[apiType].tags[0]] = [item];
|
207
|
-
}
|
208
|
-
}
|
209
|
-
}
|
210
|
-
for (const tagName in obj) {
|
211
|
-
let jsString = "";
|
212
|
-
const requestTypes = [];
|
213
|
-
let folder = "";
|
214
|
-
for (const item of obj[tagName]) {
|
215
|
-
const requestType = requestTypes.filter((o) => o === item.type);
|
216
|
-
if (requestType.length === 0) requestTypes.push(item.type);
|
217
|
-
jsString += generateFunc(item.name, item.summary, item.type);
|
218
|
-
folder = item.folder;
|
219
|
-
}
|
220
|
-
jsString = generateTemplate(requestTypes) + jsString;
|
221
|
-
mkdirsSync(getPath(`${srcFolder}/${folder}`));
|
222
|
-
// console.log(jsString)
|
223
|
-
fs.writeFileSync(getPath(`${srcFolder}/${folder}/${tagName}.js`), jsString);
|
224
|
-
}
|
225
|
-
successLog("生成完毕");
|
226
|
-
}
|
227
|
-
|
228
|
-
|
package/src/index.js
DELETED
@@ -1,12 +0,0 @@
|
|
1
|
-
const genPage = require("./gen-page");
|
2
|
-
const genSwagger = require("./gen-swagger");
|
3
|
-
const publishServer = require("./publish-server");
|
4
|
-
const wxServerNotice = require("./wx-server-notice");
|
5
|
-
|
6
|
-
|
7
|
-
module.exports = {
|
8
|
-
genPage,
|
9
|
-
genSwagger,
|
10
|
-
publishServer,
|
11
|
-
wxServerNotice
|
12
|
-
}
|
@@ -1,144 +0,0 @@
|
|
1
|
-
#! /usr/bin/env node
|
2
|
-
|
3
|
-
// scp2 : https://www.npmjs.com/package/
|
4
|
-
// 引入scp2
|
5
|
-
import client from "scp2";
|
6
|
-
import ora from "ora";
|
7
|
-
import moment from "moment";
|
8
|
-
import { getGlobalConfig, getGitInfo, errorLog, magentaLog, log, warningLog, successLog, cyanLog } from "../utils/index.js";
|
9
|
-
import { wxNotify } from "../wx-server-notice/index.js";
|
10
|
-
import pkg from 'ssh2';
|
11
|
-
const { Client } = pkg;
|
12
|
-
|
13
|
-
moment.locale('zh-cn');
|
14
|
-
|
15
|
-
async function getUploadServeConfig() {
|
16
|
-
return await getGlobalConfig();
|
17
|
-
}
|
18
|
-
|
19
|
-
getUploadServeConfig().then(res => {
|
20
|
-
const {
|
21
|
-
projectInfo = { // 项目基本信息
|
22
|
-
name: '', // 项目名称
|
23
|
-
},
|
24
|
-
locaPath, // 本地上传地址
|
25
|
-
protocol = 'http', //协议 http、https
|
26
|
-
staticPath = {}, // 服务器静态资源地址
|
27
|
-
serverOption = {}, // 服务器配置
|
28
|
-
shell // shell 命令
|
29
|
-
} = res['uploadServeConfig'] || {};
|
30
|
-
|
31
|
-
const wxServerConfig = res['wxServerConfig'];
|
32
|
-
|
33
|
-
const isProduction = process.env.VUE_APP_PACK_ENV === "production"; // 是否是生产环境
|
34
|
-
|
35
|
-
const lineVersion = process.env.VUE_APP_LINE_VERSION; //线上环境版本(多个显示环境可使用此字段区分)
|
36
|
-
|
37
|
-
const isNewPro = isProduction && +lineVersion === 2; // 是否是新的线上版本
|
38
|
-
|
39
|
-
const curtHost = !isNewPro ? serverOption.host[0] : serverOption.host[1];
|
40
|
-
|
41
|
-
const curtStaticPath = !isProduction ? staticPath.dev : staticPath.pro;
|
42
|
-
|
43
|
-
const onlinePath = `${protocol}://${curtHost}/${curtStaticPath}`;
|
44
|
-
|
45
|
-
const server = {
|
46
|
-
port: 22, // 端口默认22
|
47
|
-
...serverOption,
|
48
|
-
host: curtHost, // 服务器 ip
|
49
|
-
locaPath: `${process.env.PWD}${locaPath}`, // 本地打包文件的位置
|
50
|
-
pathNmae: `${serverOption.pathNmae}${curtStaticPath}` // 上传到服务器的位置
|
51
|
-
};
|
52
|
-
|
53
|
-
|
54
|
-
// 服务器删除静态资源命令
|
55
|
-
const shellCommand = !shell ? `rm -rf ${server.pathNmae}/*` : shell;
|
56
|
-
|
57
|
-
const gitInfo = getGitInfo();
|
58
|
-
|
59
|
-
|
60
|
-
const packInfo = {
|
61
|
-
...(projectInfo || {}),
|
62
|
-
serverPath: server.pathNmae
|
63
|
-
}
|
64
|
-
|
65
|
-
|
66
|
-
function wxMsg(status) {
|
67
|
-
return `<div class="gray">${moment().format('lll')}</div><div class="highlight">${projectInfo.name}${isProduction ? "生产" : "开发"}环境发布${status}</div><div class="normal">commitId:${gitInfo.commitId}</div><div class="normal">commitMsg:${gitInfo.commitMsg}</div><div class="normal">访问地址:${onlinePath}</div>`
|
68
|
-
}
|
69
|
-
|
70
|
-
|
71
|
-
cyanLog("本次打包信息 =>", packInfo);
|
72
|
-
|
73
|
-
|
74
|
-
const spinner = ora(
|
75
|
-
"正在发布到" + (isProduction ? "生产" : "开发") + "服务器..."
|
76
|
-
);
|
77
|
-
|
78
|
-
// 创建shell脚本
|
79
|
-
const conn = new Client();
|
80
|
-
|
81
|
-
magentaLog("正在建立连接");
|
82
|
-
|
83
|
-
conn
|
84
|
-
.on("ready", function() {
|
85
|
-
log("已连接");
|
86
|
-
if (!server.pathNmae) {
|
87
|
-
log("连接已关闭");
|
88
|
-
conn.end();
|
89
|
-
return false;
|
90
|
-
}
|
91
|
-
// 这里我拼接了放置服务器资源目录的位置 ,首选通过rm -rf删除了这个目录下的文件
|
92
|
-
conn.exec(shellCommand, function(err, stream) {
|
93
|
-
warningLog("已删除服务端文件")
|
94
|
-
stream.on("close", function(code, signal) {
|
95
|
-
log("开始上传");
|
96
|
-
spinner.start();
|
97
|
-
client.scp(
|
98
|
-
server.locaPath,
|
99
|
-
{
|
100
|
-
host: server.host,
|
101
|
-
port: server.port,
|
102
|
-
username: server.username,
|
103
|
-
password: server.password,
|
104
|
-
path: server.pathNmae
|
105
|
-
},
|
106
|
-
err => {
|
107
|
-
spinner.stop();
|
108
|
-
if (!err) {
|
109
|
-
successLog("Success! 成功发布到" + (isProduction ? "生产" : "开发") + "服务器!", `访问地址====>${onlinePath}`)
|
110
|
-
wxNotify({
|
111
|
-
msgtype: "textcard",
|
112
|
-
textcard: {
|
113
|
-
title: "发布成功",
|
114
|
-
description: wxMsg('成功'),
|
115
|
-
url: onlinePath,
|
116
|
-
btntxt: "更多"
|
117
|
-
}
|
118
|
-
}, wxServerConfig);
|
119
|
-
} else {
|
120
|
-
errorLog("发布失败.\n", err);
|
121
|
-
wxNotify({
|
122
|
-
msgtype: "textcard",
|
123
|
-
textcard: {
|
124
|
-
title: "发布失败",
|
125
|
-
description: wxMsg('失败'),
|
126
|
-
url: onlinePath,
|
127
|
-
btntxt: "更多"
|
128
|
-
}
|
129
|
-
}, wxServerConfig);
|
130
|
-
}
|
131
|
-
conn.end(); // 结束命令
|
132
|
-
}
|
133
|
-
);
|
134
|
-
});
|
135
|
-
});
|
136
|
-
})
|
137
|
-
.connect({
|
138
|
-
host: server.host,
|
139
|
-
port: server.port,
|
140
|
-
username: server.username,
|
141
|
-
password: server.password,
|
142
|
-
privateKey: server.privateKey || undefined //使用 私钥密钥登录 目前测试服务器不需要用到
|
143
|
-
});
|
144
|
-
})
|
package/src/utils/index.js
DELETED
@@ -1,82 +0,0 @@
|
|
1
|
-
import findup from "findup-sync";
|
2
|
-
import chalk from "chalk";
|
3
|
-
import execa from "execa";
|
4
|
-
|
5
|
-
// 最新 node 核心包的导入写法
|
6
|
-
import { fileURLToPath } from "node:url";
|
7
|
-
import { dirname } from "node:path";
|
8
|
-
|
9
|
-
|
10
|
-
export async function getGlobalConfig(type) {
|
11
|
-
const name = findup("dyp.config.js", { cwd: process.env.PWD });
|
12
|
-
const dypConfig = await import(name);
|
13
|
-
if (type) {
|
14
|
-
return dypConfig["default"][type];
|
15
|
-
}
|
16
|
-
return dypConfig["default"];
|
17
|
-
}
|
18
|
-
|
19
|
-
// 首字母大写
|
20
|
-
export function strCase(str) {
|
21
|
-
return str.toLowerCase().replace(/( |^)[a-z]/g, (L) => L.toUpperCase());
|
22
|
-
}
|
23
|
-
|
24
|
-
// 获取文件名
|
25
|
-
export function getFilename() {
|
26
|
-
return fileURLToPath(import.meta.url);
|
27
|
-
}
|
28
|
-
|
29
|
-
// 获取根路径
|
30
|
-
export function getDirname() {
|
31
|
-
return dirname(fileURLToPath(import.meta.url));
|
32
|
-
}
|
33
|
-
|
34
|
-
export function log(mainMsg, laterMsg) {
|
35
|
-
return chalkLog("blue", mainMsg, laterMsg);
|
36
|
-
}
|
37
|
-
|
38
|
-
export function cyanLog(mainMsg, laterMsg = "") {
|
39
|
-
return chalkLog("cyan", mainMsg, laterMsg);
|
40
|
-
}
|
41
|
-
|
42
|
-
export function magentaLog(mainMsg, laterMsg = "") {
|
43
|
-
return chalkLog("magenta", mainMsg, laterMsg);
|
44
|
-
}
|
45
|
-
|
46
|
-
export function successLog(mainMsg, laterMsg = "") {
|
47
|
-
return chalkLog("green", mainMsg, laterMsg);
|
48
|
-
}
|
49
|
-
|
50
|
-
export function warningLog(mainMsg, laterMsg = "") {
|
51
|
-
return chalkLog("yellow", mainMsg, laterMsg);
|
52
|
-
}
|
53
|
-
|
54
|
-
export function errorLog(mainMsg, laterMsg = "") {
|
55
|
-
return chalkLog("red", mainMsg, laterMsg);
|
56
|
-
}
|
57
|
-
|
58
|
-
export function chalkLog(chalkType, mainMsg, laterMsg = "") {
|
59
|
-
if (!laterMsg) {
|
60
|
-
return console.log(chalk[chalkType](`${mainMsg}`));
|
61
|
-
}
|
62
|
-
return console.log(chalk[chalkType](`${mainMsg}`), laterMsg);
|
63
|
-
}
|
64
|
-
|
65
|
-
/**
|
66
|
-
* 获取最新 commit 提交信息
|
67
|
-
* git 获取提交信息参考:https://www.cnblogs.com/ruiy/p/15904295.html
|
68
|
-
* @returns {commitId, commitMsg}
|
69
|
-
*/
|
70
|
-
|
71
|
-
export function getGitInfo() {
|
72
|
-
const shortCommid = execa.commandSync("git rev-parse --short HEAD");
|
73
|
-
|
74
|
-
const gitComMsg = `git log --pretty=format:“%s” ${shortCommid.stdout} -1`;
|
75
|
-
|
76
|
-
const { stdout, stderr } = execa.commandSync(gitComMsg);
|
77
|
-
|
78
|
-
return {
|
79
|
-
commitId: shortCommid.stdout,
|
80
|
-
commitMsg: stdout,
|
81
|
-
};
|
82
|
-
}
|
@@ -1,59 +0,0 @@
|
|
1
|
-
### 需要的变量
|
2
|
-
|
3
|
-
```txt
|
4
|
-
WX_COMPANY_ID= 企业ID
|
5
|
-
WX_APP_ID= 应用ID
|
6
|
-
WX_APP_SECRET= 应用 Secret
|
7
|
-
|
8
|
-
TIAN_API_KEY= 天行数据 key
|
9
|
-
```
|
10
|
-
|
11
|
-
<details><summary>点击查看企业微信的注册步骤的详细示例</summary>
|
12
|
-
|
13
|
-
#### 第一步,注册企业
|
14
|
-
|
15
|
-
用电脑打开[企业微信官网](https://work.weixin.qq.com/),注册一个企业。有手机号就可以注册,不用营业执照!不用营业执照!不用营业执照!
|
16
|
-
|
17
|
-
#### 第二步,创建应用
|
18
|
-
|
19
|
-
注册成功后,点「管理企业」进入管理界面,选择「应用管理」 → 「自建」 → 「创建应用」
|
20
|
-
|
21
|
-
![创建应用-1](images/qiyewx-2.png)
|
22
|
-
|
23
|
-
应用名称随意填,可见范围选择公司名(或指定组织、个人,建议选择全部,然后在代码里指定用户)。
|
24
|
-
|
25
|
-
![创建应用-2](images/qiyewx-3.png)
|
26
|
-
|
27
|
-
指定成员或组织
|
28
|
-
|
29
|
-
![指定范围](images/qiyewx-3-2.png)
|
30
|
-
|
31
|
-
创建完成后进入应用详情页,可以得到应用 ID( agentid )①,应用 Secret( secret )②。
|
32
|
-
|
33
|
-
![创建应用-3](images/qiyewx-3-1.png)
|
34
|
-
|
35
|
-
#### 第三步,获取企业 ID
|
36
|
-
|
37
|
-
进入「[我的企业](https://work.weixin.qq.com/wework_admin/frame#profile)」页面,拉到最下边,可以得到企业 ID③。
|
38
|
-
|
39
|
-
![企业ID](images/qiyewx-6.png)
|
40
|
-
|
41
|
-
#### 第四步,推送消息到微信
|
42
|
-
|
43
|
-
进入「我的企业」 → 「[微信插件](https://work.weixin.qq.com/wework_admin/frame#profile/wxPlugin)」,拉到下边扫描二维码,关注以后即可收到推送的消息。
|
44
|
-
|
45
|
-
![第四步](images/qiyewx-4.png)
|
46
|
-
|
47
|
-
#### 无法接收到消息的异常情况处理
|
48
|
-
|
49
|
-
PS:如果出现`接口请求正常,企业微信接受消息正常,个人微信无法收到消息`的情况:
|
50
|
-
|
51
|
-
1. 进入「我的企业」 → 「微信插件」,拉到最下方,勾选 “允许成员在微信插件中接收和回复聊天消息”
|
52
|
-
|
53
|
-
![异常情况-1](images/qiyewx-5.jpg)
|
54
|
-
|
55
|
-
2. 在企业微信客户端 「我」 → 「设置」 → 「新消息通知」中关闭 “仅在企业微信中接受消息” 限制条件
|
56
|
-
|
57
|
-
![异常情况-2](images/qiyewx-5-1.jpg)
|
58
|
-
|
59
|
-
</details>
|
@@ -1,45 +0,0 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
/**
|
4
|
-
* @description 根据企业ID、应用secret 获取token
|
5
|
-
* @returns token
|
6
|
-
*/
|
7
|
-
import axios from 'axios';
|
8
|
-
const BASE_URL = 'https://qyapi.weixin.qq.com'
|
9
|
-
|
10
|
-
// 获取token
|
11
|
-
export async function getToken({ id, secret }) {
|
12
|
-
try {
|
13
|
-
const response = await axios({
|
14
|
-
url: `${BASE_URL}/cgi-bin/gettoken?corpid=${id}&corpsecret=${secret}`,
|
15
|
-
method: 'GET',
|
16
|
-
headers: {
|
17
|
-
'Content-Type': 'application/json',
|
18
|
-
},
|
19
|
-
})
|
20
|
-
return response.data.access_token
|
21
|
-
}
|
22
|
-
catch (error) {
|
23
|
-
console.log(error)
|
24
|
-
return ''
|
25
|
-
}
|
26
|
-
}
|
27
|
-
|
28
|
-
/**
|
29
|
-
* 发送消息通知到企业微信
|
30
|
-
*
|
31
|
-
* api示列: https://developer.work.weixin.qq.com/tutorial/application-message/3
|
32
|
-
* api: https://developer.work.weixin.qq.com/document/path/90372
|
33
|
-
*/
|
34
|
-
export const postMsg = async(accessToken, config) => {
|
35
|
-
const response = await axios({
|
36
|
-
url: `${BASE_URL}/cgi-bin/message/send?access_token=${accessToken}`,
|
37
|
-
method: 'POST',
|
38
|
-
data: {
|
39
|
-
touser: config.touser || '@all',
|
40
|
-
...config,
|
41
|
-
},
|
42
|
-
})
|
43
|
-
return response.data
|
44
|
-
}
|
45
|
-
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -1,62 +0,0 @@
|
|
1
|
-
/**
|
2
|
-
* @name WXbot
|
3
|
-
* @description 获取环境变量参数,执行微信消息通知函数
|
4
|
-
*/
|
5
|
-
import { getGlobalConfig, errorLog, successLog, } from "../utils/index.js";
|
6
|
-
import { getToken, postMsg } from "./api.js";
|
7
|
-
|
8
|
-
async function getWxServerConfig() {
|
9
|
-
return await getGlobalConfig('wxServerConfig');
|
10
|
-
}
|
11
|
-
|
12
|
-
// 主函数
|
13
|
-
export async function wxNotify(config, wxServerConfig) {
|
14
|
-
let configs= {};
|
15
|
-
if (wxServerConfig && Object.keys(wxServerConfig).length !== 0) {
|
16
|
-
configs = wxServerConfig;
|
17
|
-
} else {
|
18
|
-
configs = await getWxServerConfig();
|
19
|
-
}
|
20
|
-
|
21
|
-
const { WX_COMPANY_ID, WX_APP_ID, WX_APP_SECRET } = configs ;
|
22
|
-
|
23
|
-
try {
|
24
|
-
// 获取token
|
25
|
-
const accessToken = await getToken({
|
26
|
-
id: WX_COMPANY_ID,
|
27
|
-
secret: WX_APP_SECRET
|
28
|
-
});
|
29
|
-
|
30
|
-
// 发送消息
|
31
|
-
const defaultConfig = {
|
32
|
-
msgtype: "text",
|
33
|
-
agentid: WX_APP_ID,
|
34
|
-
...config
|
35
|
-
};
|
36
|
-
const option = { ...defaultConfig, ...config };
|
37
|
-
const res = await postMsg(accessToken, option);
|
38
|
-
successLog("wx:信息发送成功!", res);
|
39
|
-
return true;
|
40
|
-
} catch (error) {
|
41
|
-
errorLog("wx:信息发送失败!", error);
|
42
|
-
return false;
|
43
|
-
}
|
44
|
-
}
|
45
|
-
|
46
|
-
// wxNotify({
|
47
|
-
// msgtype: "text",
|
48
|
-
// text: {
|
49
|
-
// content: `${moment().format('lll')}`
|
50
|
-
// }
|
51
|
-
// });
|
52
|
-
|
53
|
-
// wxNotify({
|
54
|
-
// msgtype: "textcard",
|
55
|
-
// textcard: {
|
56
|
-
// title: "应用发布提醒",
|
57
|
-
// description:
|
58
|
-
// '<div class="gray">2016年9月26日</div> <div class="normal">恭喜你抽中iPhone 7一台,领奖码:xxxx</div><div class="highlight">请于2016年10月10日前联系行政同事领取</div>',
|
59
|
-
// url: "www.baidu.com",
|
60
|
-
// btntxt: "更多"
|
61
|
-
// }
|
62
|
-
// });
|