Browse Source

增加 uniapp 云函数执行短信逻辑

XSXS 1 month ago
parent
commit
717396911d

+ 76 - 0
common/verificationCode.js

@@ -0,0 +1,76 @@
+/**
+ * 验证码工具类
+ * 用于生成和验证验证码
+ */
+
+class VerificationCode {
+  constructor() {
+    // 存储验证码的Map,key为验证码,value为过期时间戳
+    this.codeMap = new Map();
+    // 验证码有效期(毫秒),默认5分钟
+    this.expirationTime = 5 * 60 * 1000;
+  }
+
+  /**
+   * 生成6位数字验证码
+   * @returns {string} 6位数字验证码
+   */
+  generateCode() {
+    // 生成6位随机数
+    const code = Math.floor(100000 + Math.random() * 900000).toString();
+    // 设置过期时间
+    const expirationTime = Date.now() + this.expirationTime;
+    // 存储验证码和过期时间
+    this.codeMap.set(code, expirationTime);
+    return code;
+  }
+
+  /**
+   * 验证验证码是否有效
+   * @param {string} code 要验证的验证码
+   * @returns {boolean} 验证码是否有效
+   */
+  verifyCode(code) {
+    if (!code || !this.codeMap.has(code)) {
+      return false;
+    }
+
+    const expirationTime = this.codeMap.get(code);
+    const now = Date.now();
+
+    // 如果验证码已过期,从Map中删除
+    if (now > expirationTime) {
+      this.codeMap.delete(code);
+      return false;
+    }
+
+    // 验证成功后删除验证码(一次性使用)
+    this.codeMap.delete(code);
+    return true;
+  }
+
+  /**
+   * 设置验证码有效期
+   * @param {number} minutes 有效期(分钟)
+   */
+  setExpirationTime(minutes) {
+    this.expirationTime = minutes * 60 * 1000;
+  }
+
+  /**
+   * 清理过期的验证码
+   */
+  clearExpiredCodes() {
+    const now = Date.now();
+    for (const [code, expirationTime] of this.codeMap.entries()) {
+      if (now > expirationTime) {
+        this.codeMap.delete(code);
+      }
+    }
+  }
+}
+
+// 创建单例实例
+const verificationCode = new VerificationCode();
+
+export default verificationCode; 

+ 82 - 6
pages/login/login.vue

@@ -46,6 +46,8 @@
 						<view class="item">
 							<input type="text" class="input" v-model="code" placeholder="请输入验证码" maxlength="6" />
 							<view class="btn blick-btn-animation" v-if="captchaTime === 0" @click="getCode">获取验证码</view>
+							 <!-- 使用云函数发送验证码 -->
+							<!-- <view class="btn blick-btn-animation" v-if="captchaTime === 0" @click="sendSms()">获取验证码</view> -->
 							<view class="btn" v-if="captchaTime > 0">{{ captchaTime }}秒后重试</view>
 						</view>
 						<view class="other_list" v-if="false">
@@ -54,7 +56,7 @@
 						</view>
 					</block>
 					<text class="btn_submit  white" @click="toLogin">登录/注册</text>
-					<text class="btn_submit blick-btn-animation" @click="oneClickLoginFun">一键登录</text>
+					<text class="btn_submit blick-btn-animation" @click="oneClickLoginFun">一键登录</text> 
 				</template>
 				<template v-else>
 					<view
@@ -95,6 +97,7 @@
 import pubc from '@/common/public.js'
 import { mapState } from 'vuex'
 import channel from "@/common/channel.js";
+import verificationCode from '@/common/verificationCode';
 
 export default {
 	components: {},
@@ -158,7 +161,7 @@ export default {
 					"normalColor": "", // 其他登录按钮正常状态背景颜色 默认值:透明
 					"highlightColor": "", // 其他登录按钮按下状态背景颜色 默认值:透明
 					"textColor": "#656565", // 其他登录按钮文字颜色 默认值:#656565
-					"title": "其他登录方式", // 其他登录方式按钮文字 默认值:“其他登录方式”
+					"title": "其他登录方式", // 其他登录方式按钮文字 默认值:"其他登录方式"
 					"borderColor": "",  //边框颜色 默认值:透明(仅iOS支持)
 					"borderRadius": "0px" // 其他登录按钮圆角 默认值:"24px" (按钮高度的一半)
 				},
@@ -170,8 +173,8 @@ export default {
 					"checkBoxSize": 20, // 可选 条款勾选框大小
 					"textColor": "#BBBBBB", // 文字颜色 默认值:#BBBBBB
 					"termsColor": "#5496E3", //  协议文字颜色 默认值: #5496E3
-					"prefix": "我已阅读并同意", // 条款前的文案 默认值:“我已阅读并同意”
-					"suffix": "并使用本机号码登录", // 条款后的文案 默认值:“并使用本机号码登录”
+					"prefix": "我已阅读并同意", // 条款前的文案 默认值:"我已阅读并同意"
+					"suffix": "并使用本机号码登录", // 条款后的文案 默认值:"并使用本机号码登录"
 					"privacyItems": [  // 自定义协议条款,最大支持2个,需要同时设置url和title. 否则不生效
 						{
 							"url": "https://e.zhichao.art/web/yszc.php", // 点击跳转的协议详情页面
@@ -196,7 +199,10 @@ export default {
 						}
 					]
 				}
-			}
+			}, 
+			templateId :36155,//短信模板ID 
+			expMinute:'15', //短信有效时间
+			randomVerificationCode:'',
 		}
 	},
 	onLoad() {
@@ -630,7 +636,77 @@ export default {
 			}, 500)
 
 
-		}
+		},
+		// 发送短信验证码
+		sendSms() {
+			// 手机号格式验证
+			const mobileRegex = /^1[3-9]\d{9}$/;
+			if (!this.mobile) {
+				uni.showToast({
+					title: '请输入手机号',
+					icon: 'none'
+				});
+				return;
+			}
+			if (!mobileRegex.test(this.mobile)) {
+				uni.showToast({
+					title: '请输入正确的手机号',
+					icon: 'none'
+				});
+				return;
+			}
+
+			// 检查是否在倒计时中
+			if (this.captchaTime > 0) {
+				uni.showToast({
+					title: '不能重复获取',
+					icon: 'none'
+				});
+				return;
+			}
+
+			// 生成验证码
+			const code = verificationCode.generateCode();
+			console.log("生成的验证码:", code);
+			console.log({templateId: this.templateId,
+					phone: this.mobile,
+					code: code,
+					expMinute: this.expMinute});
+			// 调用云函数发送验证码
+			uniCloud.callFunction({
+				name: "smsVerification",
+				data: {
+					templateId: this.templateId + '',
+					phone: this.mobile + '',
+					code: code + '',
+					expMinute: this.expMinute + '',
+				}
+			}).then((dataRes) => {
+				console.log("云函数返回的参数", dataRes);
+				if (dataRes.result && dataRes.result.success) {
+					uni.showToast({
+						title: '验证码发送成功',
+						icon: 'none'
+					});
+					// 开始倒计时
+					this.captchaTime = 60;
+					this.getCodeTime();
+				} else {
+					uni.showToast({
+						title: dataRes.result.message || '验证码发送失败',
+						icon: 'none'
+					});
+					this.captchaTime = 0;
+				}
+			}).catch((err) => {
+				console.log("发送验证码失败:", err);
+				uni.showToast({
+					title: '验证码发送失败',
+					icon: 'none'
+				});
+				this.captchaTime = 0;
+			});
+		},
 	}
 }
 </script>

+ 29 - 0
uniCloud-aliyun/cloudfunctions/smsVerification/index.js

@@ -0,0 +1,29 @@
+// 发送单条短信示例
+'use strict';
+exports.main = async (event, context) => {
+	// event里包含着客户端提交的参数
+	console.log("event:"+event);
+  try {
+    const res = await uniCloud.sendSms({
+      appid: '__UNI__00BD11F',
+      phone: event.phone, //接收短信的手机号码 
+      templateId: event.templateId, // 请替换为自己申请的模板id
+      data: {
+        name: '萌创星球',//APP名称
+        code: event.code,//验证码
+        expMinute: event.expMinute,//有效时间
+      }
+    })
+    // 调用成功,请注意这时不代表发送成功
+    return res
+  } catch(err) {
+    // 调用失败
+    console.log(err.errCode)
+    console.log(err.errMsg)
+    return {
+      code: err.errCode,
+      msg: err.errMsg
+    }
+  }
+};
+ 

+ 7 - 0
uniCloud-aliyun/cloudfunctions/smsVerification/package.json

@@ -0,0 +1,7 @@
+{
+  "name": "smsVerification",
+  "dependencies": {},
+  "extensions": {
+    "uni-cloud-sms": {}
+  }
+}