Commit 0639bc24 by lixinming

Merge branch 'master' of http://123.207.147.179:8888/node_server/wenHuaBu_adminServer

# Conflicts:
#	src/config/enum.ts
#	src/data/models/model.ts
#	src/routers/public/router.ts
#	src/tools/system.ts
parents 22c214ef 38965cfe
...@@ -18,4 +18,14 @@ ...@@ -18,4 +18,14 @@
<mysqlPwd>123456</mysqlPwd> <mysqlPwd>123456</mysqlPwd>
<dataBase>xuehui</dataBase> <dataBase>xuehui</dataBase>
</mysqldb> </mysqldb>
<!-- 短信相关配置 -->
<sms>
<sdkAppId>1400799515</sdkAppId>
<appKey>a36634bd106ee72eeea4a4bb4e62a03b</appKey>
<smsSign>会员注册</smsSign>
<!-- 填报提示 -->
<pointOut>1729286</pointOut>
<!-- 单位会员注册 -->
<unitMemberRegister>1729288</unitMemberRegister>
</sms>
</config> </config>
/**
* 短信主要逻辑
*/
const tencentcloud = require("tencentcloud-sdk-nodejs");
const smsClient = tencentcloud.sms.v20210111.Client;
import { SMSTYPE } from "../config/enum";
import { ERRORENUM } from "../config/errorEnum";
import { systemConfig } from "../config/serverConfig";
import { BizError } from "../util/bizError";
var client;
export function initSMS() {
client = new smsClient({
credential: {
/* 必填:腾讯云账户密钥对secretId,secretKey。
* 这里采用的是从环境变量读取的方式,需要在环境变量中先设置这两个值。
* 你也可以直接在代码中写死密钥对,但是小心不要将代码复制、上传或者分享给他人,
* 以免泄露密钥对危及你的财产安全。
* SecretId、SecretKey 查询: https://console.cloud.tencent.com/cam/capi */
secretId: "AKIDHUYO0Xq0wc1DD2e1CJ1xpuqYIxQo0yrd",
secretKey: "zl01oOkswmXJ4apnaUJsCW5PivudLtFP",
},
/* 必填:地域信息,可以直接填写字符串ap-guangzhou,支持的地域列表参考 https://cloud.tencent.com/document/api/382/52071#.E5.9C.B0.E5.9F.9F.E5.88.97.E8.A1.A8 */
region: "ap-guangzhou",
/* 非必填:
* 客户端配置对象,可以指定超时时间等配置 */
profile: {
/* SDK默认用TC3-HMAC-SHA256进行签名,非必要请不要修改这个字段 */
signMethod: "HmacSHA256",
httpProfile: {
/* SDK默认使用POST方法。
* 如果你一定要使用GET方法,可以在这里设置。GET方法无法处理一些较大的请求 */
reqMethod: "POST",
/* SDK有默认的超时时间,非必要请不要进行调整
* 如有需要请在代码中查阅以获取最新的默认值 */
reqTimeout: 30,
/**
* 指定接入地域域名,默认就近地域接入域名为 sms.tencentcloudapi.com ,也支持指定地域域名访问,例如广州地域的域名为 sms.ap-guangzhou.tencentcloudapi.com
*/
endpoint: "sms.tencentcloudapi.com"
},
},
})
}
/**
* 给特定账号发送信息
* @param phone 需要发送的电话数组
* @param type 类别
* @param params 参数数组
*/
function sendMsmToPhoneNumber(phone, type:number, params) {
let phoneAreaList = [];
phone.forEach(info => {
phoneAreaList.push(`+86${info}`);
});
let templateId = -1;
if (type == SMSTYPE.单位会员注册) templateId = systemConfig.smsUnitMemberRegister;
const sendParam = {
/* 短信应用ID: 短信SmsSdkAppId在 [短信控制台] 添加应用后生成的实际SmsSdkAppId,示例如1400006666 */
// 应用 ID 可前往 [短信控制台](https://console.cloud.tencent.com/smsv2/app-manage) 查看
SmsSdkAppId: systemConfig.smsSDKId,
/* 短信签名内容: 使用 UTF-8 编码,必须填写已审核通过的签名 */
// 签名信息可前往 [国内短信](https://console.cloud.tencent.com/smsv2/csms-sign) 或 [国际/港澳台短信](https://console.cloud.tencent.com/smsv2/isms-sign) 的签名管理查看
SignName: systemConfig.smsSign,
/* 模板 ID: 必须填写已审核通过的模板 ID */
// 模板 ID 可前往 [国内短信](https://console.cloud.tencent.com/smsv2/csms-template) 或 [国际/港澳台短信](https://console.cloud.tencent.com/smsv2/isms-template) 的正文模板管理查看
TemplateId: templateId,
/* 模板参数: 模板参数的个数需要与 TemplateId 对应模板的变量个数保持一致,若无模板参数,则设置为空 */
TemplateParamSet: params,
/* 下发手机号码,采用 e.164 标准,+[国家或地区码][手机号]
/* 用户的 session 内容(无需要可忽略): 可以携带用户侧 ID 等上下文信息,server 会原样返回 */
SessionContext: "",
PhoneNumberSet: phoneAreaList,
/* 短信码号扩展号(无需要可忽略): 默认未开通,如需开通请联系 [腾讯云短信小助手] */
ExtendCode: "",
/* 国际/港澳台短信 senderid(无需要可忽略): 国内短信填空,默认未开通,如需开通请联系 [腾讯云短信小助手] */
SenderId: "",
}
return new Promise( (resolve, reject) => {
client.SendSms(sendParam, function (err, response) {
let isError = false;
let msg = "";
if (err) {
msg = err;
isError = true;
}
resolve({isError, msg});
});
})
}
/**
* 发送单位会员注册的短信验证码
* @param phone
* @param code
*/
export async function sendRegisterCode(phone:string, code:string, codeType) {
let sendPhoneList = [phone];
let params = [code];
let sendRes:any = await sendMsmToPhoneNumber(sendPhoneList, codeType, params);
return sendRes.isError;
}
...@@ -375,6 +375,15 @@ export enum ORDERSTATE { ...@@ -375,6 +375,15 @@ export enum ORDERSTATE {
} }
/*
* 验证码类型
*/
export enum CODETYPE {
单位会员注册 = 1,
个人会员注册,
}
/** /**
* 会费类别 * 会费类别
*/ */
...@@ -394,6 +403,28 @@ export enum INVOICESTATUS{ ...@@ -394,6 +403,28 @@ export enum INVOICESTATUS{
已开发票 已开发票
} }
/*
* 短信类型
*/
export enum SMSTYPE {
单位会员注册 = 1,
信息填报提醒,
}
/**
* 会员注册流程
*/
export enum REGISTERFLOW {
单位会员注册1 = 1,
单位会员注册2,
单位会员注册3,
个人会员注册1,
个人会员注册2
}
/** /**
* 支付方式 * 支付方式
*/ */
......
...@@ -19,7 +19,12 @@ export enum ERRORENUM { ...@@ -19,7 +19,12 @@ export enum ERRORENUM {
联系人手机号重复, 联系人手机号重复,
邮箱重复, 邮箱重复,
两次密码不一致, 两次密码不一致,
密码只能由618位字符和数字组成 密码只能由618位字符和数字组成,
发送验证码次数超限制,
发送验证码频率过快,
验证码错误,
验证码失效,
验证码过期
} }
export enum ERRORCODEENUM { export enum ERRORCODEENUM {
......
...@@ -14,5 +14,10 @@ export class ServerConfig { ...@@ -14,5 +14,10 @@ export class ServerConfig {
user:string, user:string,
pwd:string, pwd:string,
dataBase:string dataBase:string
} };
/**短信相关配置 */
smsSDKId:number;
smsAppKey:string;
smsSign:string;
smsUnitMemberRegister:number;
} }
\ No newline at end of file
...@@ -53,7 +53,7 @@ ...@@ -53,7 +53,7 @@
}, },
*/ */
import { MEMBERSTATE, USERREGISTERSTATE } from "../../config/enum"; import { MEMBERSTATE, REGISTERFLOW, USERREGISTERSTATE } from "../../config/enum";
...@@ -84,6 +84,7 @@ enum TABLEENUM { ...@@ -84,6 +84,7 @@ enum TABLEENUM {
文字资料 = 'wenZiZiLiao', 文字资料 = 'wenZiZiLiao',
订单表 = 'order', 订单表 = 'order',
单位所获得科研成果表 = "scientificResearch", 单位所获得科研成果表 = "scientificResearch",
验证码表 = "code",
} }
const ModelArray = [ const ModelArray = [
...@@ -338,8 +339,8 @@ const ModelArray = [ ...@@ -338,8 +339,8 @@ const ModelArray = [
pwd:{ type:'String'},//密码 pwd:{ type:'String'},//密码
token:{type:'String', default:''},//token token:{type:'String', default:''},//token
tokenMs:{type:'Number', default:0},//token过期时间 tokenMs:{type:'Number', default:0},//token过期时间
phone:{type:'String', index:true},//登陆手机号 phone:{type:'String', index:true},//联系电话 登陆手机号
mail:{type:'String', index:true}, mail:{type:'String', index:true},//邮箱
sex:'Number',//性别 枚举 sex:'Number',//性别 枚举
documentType:'Number',//证件类型 枚举 documentType:'Number',//证件类型 枚举
documentId:'String',//证件id 身份证 documentId:'String',//证件id 身份证
...@@ -349,11 +350,12 @@ const ModelArray = [ ...@@ -349,11 +350,12 @@ const ModelArray = [
shi:'String',//市 shi:'String',//市
qu:'String',//区 qu:'String',//区
addres:'String',//通信地址 addres:'String',//通信地址
photoUrl:'String',//证件照图片地址 photoUrl:'String',//证件照图片地址 蓝底证件照
workUnit:'String',//工作单位 workUnit:'String',//工作单位
workDuties:'String',//职务 workDuties:'String',//职务
workTitle:'String',//职称 workTitle:'String',//职称
userRegisterState:{type:'Number', default:USERREGISTERSTATE.待审核, index:true},//用户注册状态 枚举 userRegisterState:{type:'Number', default:USERREGISTERSTATE.待审核, index:true},//用户注册状态 枚举
registerFlow:'Number',//会员注册流程 枚举
auditTime:'Number',//审核时间 auditTime:'Number',//审核时间
memberState:{type:'Number', default:MEMBERSTATE.正常, index:true},//会员状态 枚举 memberState:{type:'Number', default:MEMBERSTATE.正常, index:true},//会员状态 枚举
joinTime:'Number',//入会时间 joinTime:'Number',//入会时间
...@@ -444,6 +446,18 @@ const ModelArray = [ ...@@ -444,6 +446,18 @@ const ModelArray = [
invoiceStatus:{type:'Number', index:true},//发票状态 invoiceStatus:{type:'Number', index:true},//发票状态
} }
}, },
{
tableName:TABLEENUM.验证码表,
source:TABLESOURCEENUM.mongo,
schema:{
codeId:{type:'String', index:true},
codeNum:'String',
sendMs:'Number',//下发时间 时间戳
phone:{type:'String', index:true},//用户电话
type:'Number',//验证码类型
isUse:{type:'Boolean', default:false},//是否使用 默认false
}
},
]; ];
......
...@@ -119,7 +119,13 @@ export const Config = { ...@@ -119,7 +119,13 @@ export const Config = {
subUrl:'/tongzhigonggaotype', subUrl:'/tongzhigonggaotype',
param:[], param:[],
bindBiz:setEnumInterface(enumConfig.TONGZHIGONGGAO) bindBiz:setEnumInterface(enumConfig.TONGZHIGONGGAO)
} },
{
apiName:"验证码类型",
subUrl:'/codetype',
param:[],
bindBiz:setEnumInterface(enumConfig.CODETYPE)
},
], ],
} }
......
...@@ -14,7 +14,7 @@ import * as memberRouter from "./member/router"; ...@@ -14,7 +14,7 @@ import * as memberRouter from "./member/router";
import * as officalWebsiteRouter from "./officalWebsite/router"; import * as officalWebsiteRouter from "./officalWebsite/router";
import * as asyncHandler from 'express-async-handler'; import * as asyncHandler from 'express-async-handler';
const Look = true;//true更新文档 const Look = false;//true更新文档
export async function setRouter(httpServer){ export async function setRouter(httpServer){
if (Look) { if (Look) {
......
...@@ -41,10 +41,45 @@ export function generateUserId() { ...@@ -41,10 +41,45 @@ export function generateUserId() {
return md5(`${Math.random() * 100}${new Date().valueOf()}${Math.floor(Math.random() * 10000)}`); return md5(`${Math.random() * 100}${new Date().valueOf()}${Math.floor(Math.random() * 10000)}`);
} }
/**
* 获取code的id
* @param loginId 用户Id
* @param todaySendCount 今日发送次数
* @returns ''
*/
export function getSMSCodeId(loginId:string, todaySendCount:number) {
return md5(`${loginId}${todaySendCount}${new Date().valueOf()}`);
}
/**
* 获取一个随机6位数的验证码
* @returns
*/
export function getSMSCode() {
let code = ``;
for (let i =0; i < 6; i++) {
code += Math.floor(Math.random() * 10)
}
return code;
}
/** /**
* 生成唯一订单id * 生成唯一订单id
*/ */
export function generateOrderId(userId:string) { export function generateOrderId(userId:string) {
return md5(`${userId}${Math.random() * 100}${new Date().valueOf()}${Math.floor(Math.random() * 1000)}`); return md5(`${userId}${Math.random() * 100}${new Date().valueOf()}${Math.floor(Math.random() * 1000)}`);
} }
\ No newline at end of file
/*
* 获取今天开始时刻的时间戳 0时0分
* @returns
*/
export function getTodayMs() {
let t =`${ moment().format("YYYY-MM-DD")} 00:00:00`;
return new Date(t).valueOf();
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment