mirror of
https://github.com/cool-team-official/cool-admin-midway.git
synced 2026-02-05 01:04:14 +00:00
阿里、腾讯、云片短信
This commit is contained in:
parent
79a1fa05d3
commit
b82c32f90d
@ -4,13 +4,13 @@
|
|||||||
"description": "一个项目用COOL就够了",
|
"description": "一个项目用COOL就够了",
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@alicloud/pop-core": "^1.7.12",
|
|
||||||
"@cool-midway/cloud": "^6.0.0",
|
"@cool-midway/cloud": "^6.0.0",
|
||||||
"@cool-midway/core": "^6.0.6",
|
"@cool-midway/core": "^6.0.6",
|
||||||
"@cool-midway/file": "^6.0.1",
|
"@cool-midway/file": "^6.0.1",
|
||||||
"@cool-midway/iot": "^6.0.0",
|
"@cool-midway/iot": "^6.0.0",
|
||||||
"@cool-midway/pay": "^6.0.0",
|
"@cool-midway/pay": "^6.0.0",
|
||||||
"@cool-midway/rpc": "^6.0.1",
|
"@cool-midway/rpc": "^6.0.1",
|
||||||
|
"@cool-midway/sms": "^6.0.1",
|
||||||
"@cool-midway/task": "^6.0.0",
|
"@cool-midway/task": "^6.0.0",
|
||||||
"@midwayjs/bootstrap": "^3.11.4",
|
"@midwayjs/bootstrap": "^3.11.4",
|
||||||
"@midwayjs/cache": "^3.11.5",
|
"@midwayjs/cache": "^3.11.5",
|
||||||
@ -36,6 +36,7 @@
|
|||||||
"mysql2": "^3.2.4",
|
"mysql2": "^3.2.4",
|
||||||
"svg-captcha": "^1.4.0",
|
"svg-captcha": "^1.4.0",
|
||||||
"svg2png-wasm": "^1.3.4",
|
"svg2png-wasm": "^1.3.4",
|
||||||
|
"tencentcloud-sdk-nodejs": "^4.0.607",
|
||||||
"typeorm": "^0.3.15",
|
"typeorm": "^0.3.15",
|
||||||
"uuid": "^9.0.0"
|
"uuid": "^9.0.0"
|
||||||
},
|
},
|
||||||
|
|||||||
11
packages/sms/.editorconfig
Normal file
11
packages/sms/.editorconfig
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
# 🎨 editorconfig.org
|
||||||
|
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
charset = utf-8
|
||||||
|
end_of_line = lf
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
insert_final_newline = true
|
||||||
28
packages/sms/.eslintrc.json
Normal file
28
packages/sms/.eslintrc.json
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
{
|
||||||
|
"extends": "./node_modules/mwts/",
|
||||||
|
"ignorePatterns": [
|
||||||
|
"node_modules",
|
||||||
|
"dist",
|
||||||
|
"test",
|
||||||
|
"jest.config.js",
|
||||||
|
"typings",
|
||||||
|
"public/**/**",
|
||||||
|
"view/**/**"
|
||||||
|
],
|
||||||
|
"env": {
|
||||||
|
"jest": true
|
||||||
|
},
|
||||||
|
"rules": {
|
||||||
|
"@typescript-eslint/explicit-module-boundary-types": "off",
|
||||||
|
"@typescript-eslint/no-unused-vars": "off",
|
||||||
|
"@typescript-eslint/ban-ts-comment": "off",
|
||||||
|
"node/no-extraneous-import": "off",
|
||||||
|
"no-empty": "off",
|
||||||
|
"node/no-extraneous-require": "off",
|
||||||
|
"eqeqeq": "off",
|
||||||
|
"node/no-unsupported-features/node-builtins": "off",
|
||||||
|
"@typescript-eslint/ban-types": "off",
|
||||||
|
"no-control-regex": "off",
|
||||||
|
"prefer-const": "off"
|
||||||
|
}
|
||||||
|
}
|
||||||
15
packages/sms/.gitignore
vendored
Normal file
15
packages/sms/.gitignore
vendored
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
logs/
|
||||||
|
npm-debug.log
|
||||||
|
yarn-error.log
|
||||||
|
node_modules/
|
||||||
|
package-lock.json
|
||||||
|
yarn.lock
|
||||||
|
coverage/
|
||||||
|
dist/
|
||||||
|
.idea/
|
||||||
|
run/
|
||||||
|
.DS_Store
|
||||||
|
*.sw*
|
||||||
|
*.un~
|
||||||
|
.tsbuildinfo
|
||||||
|
.tsbuildinfo.*
|
||||||
3
packages/sms/.prettierrc.js
Normal file
3
packages/sms/.prettierrc.js
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
module.exports = {
|
||||||
|
...require('mwts/.prettierrc.json')
|
||||||
|
}
|
||||||
10
packages/sms/index.d.ts
vendored
Normal file
10
packages/sms/index.d.ts
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
export * from './dist/index';
|
||||||
|
|
||||||
|
declare module '@midwayjs/core/dist/interface' {
|
||||||
|
interface MidwayConfig {
|
||||||
|
book?: PowerPartial<{
|
||||||
|
a: number;
|
||||||
|
b: string;
|
||||||
|
}>;
|
||||||
|
}
|
||||||
|
}
|
||||||
7
packages/sms/jest.config.js
Normal file
7
packages/sms/jest.config.js
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
module.exports = {
|
||||||
|
preset: 'ts-jest',
|
||||||
|
testEnvironment: 'node',
|
||||||
|
testPathIgnorePatterns: ['<rootDir>/test/fixtures'],
|
||||||
|
coveragePathIgnorePatterns: ['<rootDir>/test/'],
|
||||||
|
setupFilesAfterEnv: ['./jest.setup.js']
|
||||||
|
};
|
||||||
1
packages/sms/jest.setup.js
Normal file
1
packages/sms/jest.setup.js
Normal file
@ -0,0 +1 @@
|
|||||||
|
jest.setTimeout(30000);
|
||||||
49
packages/sms/package.json
Normal file
49
packages/sms/package.json
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
{
|
||||||
|
"name": "@cool-midway/sms",
|
||||||
|
"version": "6.0.1",
|
||||||
|
"description": "cool-js.com 短信",
|
||||||
|
"main": "dist/index.js",
|
||||||
|
"typings": "index.d.ts",
|
||||||
|
"scripts": {
|
||||||
|
"build": "cross-env midway-bin build -c",
|
||||||
|
"test": "cross-env midway-bin test --ts",
|
||||||
|
"cov": "cross-env midway-bin cov --ts",
|
||||||
|
"lint": "mwts check",
|
||||||
|
"lint:fix": "mwts fix"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"cool",
|
||||||
|
"cool-admin",
|
||||||
|
"cooljs"
|
||||||
|
],
|
||||||
|
"author": "COOL",
|
||||||
|
"readme": "README.md",
|
||||||
|
"files": [
|
||||||
|
"dist/**/*.js",
|
||||||
|
"dist/**/*.d.ts",
|
||||||
|
"index.d.ts"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://cool-js.com"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@cool-midway/core": "^6.0.0",
|
||||||
|
"@midwayjs/cli": "^2.0.9",
|
||||||
|
"@midwayjs/core": "^3.9.0",
|
||||||
|
"@midwayjs/decorator": "^3.9.0",
|
||||||
|
"@midwayjs/mock": "^3.9.0",
|
||||||
|
"@types/jest": "^29.2.5",
|
||||||
|
"@types/node": "^18.11.18",
|
||||||
|
"cross-env": "^7.0.3",
|
||||||
|
"jest": "^29.3.1",
|
||||||
|
"mwts": "^1.3.0",
|
||||||
|
"ts-jest": "^29.0.3",
|
||||||
|
"typescript": "^4.9.4"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@alicloud/pop-core": "^1.7.13",
|
||||||
|
"tencentcloud-sdk-nodejs": "^4.0.607"
|
||||||
|
}
|
||||||
|
}
|
||||||
64
packages/sms/src/ali.ts
Normal file
64
packages/sms/src/ali.ts
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
import * as Core from '@alicloud/pop-core';
|
||||||
|
import { Config, Provide } from "@midwayjs/core";
|
||||||
|
import { CoolSmsAliConfig } from './interface';
|
||||||
|
import { CoolCommException } from '@cool-midway/core';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 阿里云短信
|
||||||
|
*/
|
||||||
|
@Provide()
|
||||||
|
export class SmsAli {
|
||||||
|
@Config('cool.sms.ali')
|
||||||
|
config: CoolSmsAliConfig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 配置
|
||||||
|
* @param config
|
||||||
|
*/
|
||||||
|
setConfig(config: CoolSmsAliConfig) {
|
||||||
|
this.config = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送短信
|
||||||
|
* @param phone 手机号
|
||||||
|
* @param params 参数
|
||||||
|
* @param config signName 签名 template 模板
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
async send(phone, params: {
|
||||||
|
[key: string]: string;
|
||||||
|
}, config?: {
|
||||||
|
signName: string;
|
||||||
|
template: string;
|
||||||
|
}) {
|
||||||
|
const { accessKeyId, accessKeySecret } = this.config;
|
||||||
|
if (!accessKeyId || !accessKeyId) {
|
||||||
|
throw new CoolCommException('请配置阿里云短信');
|
||||||
|
}
|
||||||
|
if (!config) {
|
||||||
|
config = {
|
||||||
|
signName: this.config.signName,
|
||||||
|
template: this.config.template,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
const client = new Core({
|
||||||
|
accessKeyId,
|
||||||
|
accessKeySecret,
|
||||||
|
endpoint: 'https://dysmsapi.aliyuncs.com',
|
||||||
|
// endpoint: 'https://cs.cn-hangzhou.aliyuncs.com',
|
||||||
|
apiVersion: '2017-05-25',
|
||||||
|
// apiVersion: '2018-04-18',
|
||||||
|
});
|
||||||
|
const data = {
|
||||||
|
RegionId: 'cn-shanghai',
|
||||||
|
PhoneNumbers: phone,
|
||||||
|
signName: config.signName,
|
||||||
|
templateCode: config.template,
|
||||||
|
TemplateParam: JSON.stringify(params),
|
||||||
|
};
|
||||||
|
return await client.request('SendSms', data, {
|
||||||
|
method: 'POST',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
5
packages/sms/src/config/config.default.ts
Normal file
5
packages/sms/src/config/config.default.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
export const customKey = {
|
||||||
|
a: 1,
|
||||||
|
b: 'hello',
|
||||||
|
};
|
||||||
|
|
||||||
17
packages/sms/src/configuration.ts
Normal file
17
packages/sms/src/configuration.ts
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import { Configuration } from '@midwayjs/decorator';
|
||||||
|
import * as DefaultConfig from './config/config.default';
|
||||||
|
import { IMidwayContainer } from '@midwayjs/core';
|
||||||
|
|
||||||
|
@Configuration({
|
||||||
|
namespace: 'cool:sms',
|
||||||
|
importConfigs: [
|
||||||
|
{
|
||||||
|
default: DefaultConfig,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
export class CoolPayConfiguration {
|
||||||
|
async onReady(container: IMidwayContainer) {
|
||||||
|
// TODO something
|
||||||
|
}
|
||||||
|
}
|
||||||
9
packages/sms/src/index.ts
Normal file
9
packages/sms/src/index.ts
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
export { CoolPayConfiguration as Configuration } from './configuration';
|
||||||
|
|
||||||
|
export * from './interface';
|
||||||
|
|
||||||
|
export * from './ali';
|
||||||
|
export * from './yp';
|
||||||
|
export * from './tx';
|
||||||
|
|
||||||
|
export * from './sms';
|
||||||
80
packages/sms/src/interface.ts
Normal file
80
packages/sms/src/interface.ts
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
export interface CoolSmsConfig {
|
||||||
|
/**
|
||||||
|
* 阿里云短信配置
|
||||||
|
*/
|
||||||
|
ali: CoolSmsAliConfig;
|
||||||
|
/**
|
||||||
|
* 腾讯云短信配置
|
||||||
|
*/
|
||||||
|
tx: CoolTxConfig;
|
||||||
|
/**
|
||||||
|
* 云片短信配置
|
||||||
|
*/
|
||||||
|
yp: CoolYpConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 阿里云配置
|
||||||
|
*/
|
||||||
|
export interface CoolSmsAliConfig {
|
||||||
|
/**
|
||||||
|
* 阿里云accessKeyId
|
||||||
|
*/
|
||||||
|
accessKeyId: string;
|
||||||
|
/**
|
||||||
|
* 阿里云accessKeySecret
|
||||||
|
*/
|
||||||
|
accessKeySecret: string;
|
||||||
|
/**
|
||||||
|
* 签名,非必填,调用时可以传入
|
||||||
|
*/
|
||||||
|
signName?: string;
|
||||||
|
/**
|
||||||
|
* 模板,非必填,调用时可以传入
|
||||||
|
*/
|
||||||
|
template?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 腾讯云配置
|
||||||
|
*/
|
||||||
|
export interface CoolTxConfig {
|
||||||
|
/**
|
||||||
|
* 应用ID
|
||||||
|
*/
|
||||||
|
appId: string;
|
||||||
|
/**
|
||||||
|
* 腾讯云secretId
|
||||||
|
*/
|
||||||
|
secretId: string;
|
||||||
|
/**
|
||||||
|
* 腾讯云secretKey
|
||||||
|
*/
|
||||||
|
secretKey: string;
|
||||||
|
/**
|
||||||
|
* 签名,非必填,调用时可以传入
|
||||||
|
*/
|
||||||
|
signName?: string;
|
||||||
|
/**
|
||||||
|
* 模板,非必填,调用时可以传入
|
||||||
|
*/
|
||||||
|
template?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 云片短信配置
|
||||||
|
*/
|
||||||
|
export interface CoolYpConfig {
|
||||||
|
/**
|
||||||
|
* 云片apikey
|
||||||
|
*/
|
||||||
|
apikey: string;
|
||||||
|
/**
|
||||||
|
* 签名,非必填,调用时可以传入
|
||||||
|
*/
|
||||||
|
signName?: string;
|
||||||
|
/**
|
||||||
|
* 模板,非必填,调用时可以传入
|
||||||
|
*/
|
||||||
|
template?: string;
|
||||||
|
}
|
||||||
49
packages/sms/src/package.json
Normal file
49
packages/sms/src/package.json
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
{
|
||||||
|
"name": "@cool-midway/sms",
|
||||||
|
"version": "6.0.1",
|
||||||
|
"description": "cool-js.com 短信",
|
||||||
|
"main": "index.js",
|
||||||
|
"typings": "index.d.ts",
|
||||||
|
"scripts": {
|
||||||
|
"build": "cross-env midway-bin build -c",
|
||||||
|
"test": "cross-env midway-bin test --ts",
|
||||||
|
"cov": "cross-env midway-bin cov --ts",
|
||||||
|
"lint": "mwts check",
|
||||||
|
"lint:fix": "mwts fix"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"cool",
|
||||||
|
"cool-admin",
|
||||||
|
"cooljs"
|
||||||
|
],
|
||||||
|
"author": "COOL",
|
||||||
|
"readme": "README.md",
|
||||||
|
"files": [
|
||||||
|
"**/*.js",
|
||||||
|
"**/*.d.ts",
|
||||||
|
"index.d.ts"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://cool-js.com"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@cool-midway/core": "^6.0.0",
|
||||||
|
"@midwayjs/cli": "^2.0.9",
|
||||||
|
"@midwayjs/core": "^3.9.0",
|
||||||
|
"@midwayjs/decorator": "^3.9.0",
|
||||||
|
"@midwayjs/mock": "^3.9.0",
|
||||||
|
"@types/jest": "^29.2.5",
|
||||||
|
"@types/node": "^18.11.18",
|
||||||
|
"cross-env": "^7.0.3",
|
||||||
|
"jest": "^29.3.1",
|
||||||
|
"mwts": "^1.3.0",
|
||||||
|
"ts-jest": "^29.0.3",
|
||||||
|
"typescript": "^4.9.4"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@alicloud/pop-core": "^1.7.13",
|
||||||
|
"tencentcloud-sdk-nodejs": "^4.0.607"
|
||||||
|
}
|
||||||
|
}
|
||||||
83
packages/sms/src/sms.ts
Normal file
83
packages/sms/src/sms.ts
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
import { Config, Inject, Provide } from "@midwayjs/core";
|
||||||
|
import { SmsYp } from "./yp";
|
||||||
|
import { SmsAli } from "./ali";
|
||||||
|
import { SmsTx } from "./tx";
|
||||||
|
import { CoolSmsConfig } from "./interface";
|
||||||
|
|
||||||
|
@Provide()
|
||||||
|
export class CoolSms {
|
||||||
|
@Inject()
|
||||||
|
smsYp: SmsYp
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
smsAli: SmsAli
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
smsTx: SmsTx
|
||||||
|
|
||||||
|
@Config('cool.sms')
|
||||||
|
config: CoolSmsConfig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 配置
|
||||||
|
* @param config
|
||||||
|
*/
|
||||||
|
setConfig(config: CoolSmsConfig) {
|
||||||
|
this.smsYp.setConfig(config.yp);
|
||||||
|
this.smsAli.setConfig(config.ali);
|
||||||
|
this.smsTx.setConfig(config.tx);
|
||||||
|
this.config = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送验证码 模板字段名为:code
|
||||||
|
* @param phone
|
||||||
|
* @param config
|
||||||
|
*/
|
||||||
|
async sendCode(phone, config?: {
|
||||||
|
signName: string;
|
||||||
|
template: string;
|
||||||
|
}) {
|
||||||
|
const code = this.generateNumber();
|
||||||
|
let params = {
|
||||||
|
code
|
||||||
|
}
|
||||||
|
await this.send(phone, this.config.tx ? [code] : params, config)
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送短信
|
||||||
|
* @param phone
|
||||||
|
* @param params
|
||||||
|
* @param config
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
async send(phone: string, params: any, config?: {
|
||||||
|
signName: string;
|
||||||
|
template: string;
|
||||||
|
}) {
|
||||||
|
if (this.config.ali) {
|
||||||
|
return await this.smsAli.send(phone, params, config);
|
||||||
|
}
|
||||||
|
if (this.config.tx) {
|
||||||
|
return await this.smsTx.send(phone, params, config);
|
||||||
|
}
|
||||||
|
if (this.config.yp) {
|
||||||
|
return await this.smsYp.send(phone, params, config);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成验证码
|
||||||
|
*/
|
||||||
|
generateNumber(digits = 4) {
|
||||||
|
if (digits <= 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
const min = Math.pow(10, digits - 1);
|
||||||
|
const max = Math.pow(10, digits) - 1;
|
||||||
|
return Math.floor(Math.random() * (max - min + 1)) + min;
|
||||||
|
}
|
||||||
|
}
|
||||||
70
packages/sms/src/tx.ts
Normal file
70
packages/sms/src/tx.ts
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
import { Config, Provide } from "@midwayjs/core";
|
||||||
|
import { CoolTxConfig } from './interface';
|
||||||
|
import * as tencentcloud from "tencentcloud-sdk-nodejs";
|
||||||
|
import { CoolCommException } from "@cool-midway/core";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 腾讯云短信
|
||||||
|
*/
|
||||||
|
@Provide()
|
||||||
|
export class SmsTx {
|
||||||
|
@Config('cool.sms.tx')
|
||||||
|
config: CoolTxConfig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 配置
|
||||||
|
* @param config
|
||||||
|
*/
|
||||||
|
setConfig(config: CoolTxConfig) {
|
||||||
|
this.config = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送短信
|
||||||
|
* @param phone 手机号
|
||||||
|
* @param params 参数
|
||||||
|
* @param config signName 签名 template 模板
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
async send(phone: string, params: string[], config?: {
|
||||||
|
signName: string;
|
||||||
|
template: string;
|
||||||
|
}) {
|
||||||
|
const { appId, secretId, secretKey } = this.config;
|
||||||
|
if(!config) {
|
||||||
|
config = {
|
||||||
|
signName: this.config.signName,
|
||||||
|
template: this.config.template,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if(!appId || !secretId || !secretKey) {
|
||||||
|
throw new CoolCommException('请配置腾讯云短信');
|
||||||
|
}
|
||||||
|
const smsClient = tencentcloud.sms.v20210111.Client;
|
||||||
|
|
||||||
|
const client = new smsClient({
|
||||||
|
credential: {
|
||||||
|
secretId,
|
||||||
|
secretKey,
|
||||||
|
},
|
||||||
|
region: 'ap-guangzhou',
|
||||||
|
profile: {
|
||||||
|
signMethod: 'HmacSHA256',
|
||||||
|
httpProfile: {
|
||||||
|
reqMethod: 'POST',
|
||||||
|
reqTimeout: 30,
|
||||||
|
endpoint: 'sms.tencentcloudapi.com',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const data = {
|
||||||
|
SmsSdkAppId: appId,
|
||||||
|
SignName: config.signName,
|
||||||
|
TemplateId: config.template,
|
||||||
|
TemplateParamSet: params,
|
||||||
|
PhoneNumberSet: [`+86${phone}`],
|
||||||
|
};
|
||||||
|
return client.SendSms(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
86
packages/sms/src/yp.ts
Normal file
86
packages/sms/src/yp.ts
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
import { Config, Provide } from "@midwayjs/core";
|
||||||
|
import { CoolYpConfig } from "./interface";
|
||||||
|
import { CoolCommException } from "@cool-midway/core";
|
||||||
|
import axios from 'axios';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 云片短信
|
||||||
|
*/
|
||||||
|
@Provide()
|
||||||
|
export class SmsYp {
|
||||||
|
@Config('cool.sms.yp')
|
||||||
|
config: CoolYpConfig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 配置
|
||||||
|
* @param config
|
||||||
|
*/
|
||||||
|
setConfig(config: CoolYpConfig) {
|
||||||
|
this.config = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送短信
|
||||||
|
* @param phones 手机号 数组,需要加国家码如 ["+8612345678901"]
|
||||||
|
* @param params 参数
|
||||||
|
* @param config signName 签名 template 模板
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
async send(phones: string, params: {
|
||||||
|
[key: string]: string;
|
||||||
|
}, config?: {
|
||||||
|
signName: string;
|
||||||
|
template: string;
|
||||||
|
}) {
|
||||||
|
const { apikey } = this.config;
|
||||||
|
if (!config) {
|
||||||
|
config = {
|
||||||
|
signName: this.config.signName,
|
||||||
|
template: this.config.template,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (!apikey) {
|
||||||
|
throw new CoolCommException('请配置云片短信');
|
||||||
|
}
|
||||||
|
|
||||||
|
const headers = {
|
||||||
|
Accept: 'application/json;charset=utf-8',
|
||||||
|
'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8',
|
||||||
|
};
|
||||||
|
const data = {
|
||||||
|
apikey: apikey,
|
||||||
|
mobile: phones,
|
||||||
|
tpl_id: config.template,
|
||||||
|
tpl_value: this.smsTplValue(params),
|
||||||
|
};
|
||||||
|
const result = await axios.post(
|
||||||
|
'https://sms.yunpian.com/v2/sms/tpl_single_send.json',
|
||||||
|
data,
|
||||||
|
{ headers }
|
||||||
|
);
|
||||||
|
if (result.data.code === 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得短信模板值
|
||||||
|
* @param obj
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
protected smsTplValue(obj) {
|
||||||
|
const urlParams = [];
|
||||||
|
|
||||||
|
for (let key in obj) {
|
||||||
|
// eslint-disable-next-line no-prototype-builtins
|
||||||
|
if (obj.hasOwnProperty(key)) {
|
||||||
|
const encodedKey = encodeURIComponent(`#${key}#`);
|
||||||
|
const encodedValue = encodeURIComponent(obj[key]);
|
||||||
|
urlParams.push(`${encodedKey}=${encodedValue}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return urlParams.join('&');
|
||||||
|
}
|
||||||
|
}
|
||||||
14
packages/sms/test/index.test.ts
Normal file
14
packages/sms/test/index.test.ts
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import { createLightApp } from '@midwayjs/mock';
|
||||||
|
import * as custom from '../src';
|
||||||
|
|
||||||
|
describe('/test/index.test.ts', () => {
|
||||||
|
it('test component', async () => {
|
||||||
|
const app = await createLightApp('', {
|
||||||
|
imports: [
|
||||||
|
custom
|
||||||
|
]
|
||||||
|
});
|
||||||
|
const bookService = await app.getApplicationContext().getAsync(custom.BookService);
|
||||||
|
expect(await bookService.getBookById()).toEqual('hello world');
|
||||||
|
});
|
||||||
|
});
|
||||||
24
packages/sms/tsconfig.json
Normal file
24
packages/sms/tsconfig.json
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"compileOnSave": true,
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "es2018",
|
||||||
|
"module": "commonjs",
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"experimentalDecorators": true,
|
||||||
|
"emitDecoratorMetadata": true,
|
||||||
|
"inlineSourceMap":false,
|
||||||
|
"noImplicitThis": true,
|
||||||
|
"noUnusedLocals": true,
|
||||||
|
"stripInternal": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"noImplicitReturns": false,
|
||||||
|
"pretty": true,
|
||||||
|
"declaration": true,
|
||||||
|
"outDir": "dist"
|
||||||
|
},
|
||||||
|
"exclude": [
|
||||||
|
"dist",
|
||||||
|
"node_modules",
|
||||||
|
"test"
|
||||||
|
]
|
||||||
|
}
|
||||||
@ -11,6 +11,7 @@ import * as localTask from '@midwayjs/task';
|
|||||||
import * as cool from '@cool-midway/core';
|
import * as cool from '@cool-midway/core';
|
||||||
import * as cloud from '@cool-midway/cloud';
|
import * as cloud from '@cool-midway/cloud';
|
||||||
import * as file from '@cool-midway/file';
|
import * as file from '@cool-midway/file';
|
||||||
|
// import * as sms from '@cool-midway/sms';
|
||||||
// import * as rpc from '@cool-midway/rpc';
|
// import * as rpc from '@cool-midway/rpc';
|
||||||
// import * as task from '@cool-midway/task';
|
// import * as task from '@cool-midway/task';
|
||||||
// import * as pay from '@cool-midway/pay';
|
// import * as pay from '@cool-midway/pay';
|
||||||
@ -46,6 +47,8 @@ import * as file from '@cool-midway/file';
|
|||||||
// pay,
|
// pay,
|
||||||
// 物联网开发,如MQTT支持等
|
// 物联网开发,如MQTT支持等
|
||||||
// iot,
|
// iot,
|
||||||
|
// 短信
|
||||||
|
// sms
|
||||||
{
|
{
|
||||||
component: info,
|
component: info,
|
||||||
enabledEnvironment: ['local'],
|
enabledEnvironment: ['local'],
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import { Provide, Config, Inject } from '@midwayjs/decorator';
|
import { Provide, Config, Inject } from '@midwayjs/decorator';
|
||||||
import { BaseService, CoolCommException } from '@cool-midway/core';
|
import { BaseService, CoolCommException } from '@cool-midway/core';
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
import * as Core from '@alicloud/pop-core';
|
|
||||||
import { CacheManager } from '@midwayjs/cache';
|
import { CacheManager } from '@midwayjs/cache';
|
||||||
|
import { CoolSms } from '@cool-midway/sms';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 描述
|
* 描述
|
||||||
@ -16,19 +16,17 @@ export class UserSmsService extends BaseService {
|
|||||||
@Inject()
|
@Inject()
|
||||||
cacheManager: CacheManager;
|
cacheManager: CacheManager;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
coolSms: CoolSms;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 发送验证码
|
* 发送验证码
|
||||||
* @param phone
|
* @param phone
|
||||||
*/
|
*/
|
||||||
async sendSms(phone) {
|
async sendSms(phone) {
|
||||||
try {
|
try {
|
||||||
const TemplateParam = { code: _.random(1000, 9999) };
|
const code = await this.coolSms.sendCode(phone);
|
||||||
await this.send(phone, TemplateParam);
|
this.cacheManager.set(`sms:${phone}`, code, this.config.timeout);
|
||||||
this.cacheManager.set(
|
|
||||||
`sms:${phone}`,
|
|
||||||
TemplateParam.code,
|
|
||||||
this.config.timeout
|
|
||||||
);
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new CoolCommException('发送过于频繁,请稍后再试');
|
throw new CoolCommException('发送过于频繁,请稍后再试');
|
||||||
}
|
}
|
||||||
@ -47,33 +45,4 @@ export class UserSmsService extends BaseService {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 发送短信
|
|
||||||
* @param phone
|
|
||||||
* @param templateCode
|
|
||||||
* @param template
|
|
||||||
*/
|
|
||||||
async send(phone, TemplateParam) {
|
|
||||||
const { signName, accessKeyId, accessKeySecret, templateCode } =
|
|
||||||
this.config;
|
|
||||||
const client = new Core({
|
|
||||||
accessKeyId,
|
|
||||||
accessKeySecret,
|
|
||||||
endpoint: 'https://dysmsapi.aliyuncs.com',
|
|
||||||
// endpoint: 'https://cs.cn-hangzhou.aliyuncs.com',
|
|
||||||
apiVersion: '2017-05-25',
|
|
||||||
// apiVersion: '2018-04-18',
|
|
||||||
});
|
|
||||||
const params = {
|
|
||||||
RegionId: 'cn-shanghai',
|
|
||||||
PhoneNumbers: phone,
|
|
||||||
signName,
|
|
||||||
templateCode,
|
|
||||||
TemplateParam: JSON.stringify(TemplateParam),
|
|
||||||
};
|
|
||||||
return await client.request('SendSms', params, {
|
|
||||||
method: 'POST',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user