1 /** 2 * 3 * 验证手机公用组件(非业务流程) 4 * 5 * @fileOverView 验证手机公用组件 6 * @author <a href="mailto:zhang.gd@foxmail.com">Zhang Guangda</a> 7 * @date 2012-10-25 8 */ 9 define(["core", "component/form"], function() { 10 11 var _originalMsg = "点击发送", 12 _sendingCodeMsg = "发送中...", 13 _changedMsg = "重新获取验证码", 14 _label1 = '手机号码', 15 _label1_empty = '您的手机号', 16 _label2 = '免费获取验证码', 17 _label3 = '短信验证码', 18 _defaultCooldown = 60, 19 _changedBtnClass = "we_get_code_btn_gray", 20 _cookieName = "_we_comp_vm", 21 _keyCookie = "_we_vkey", 22 _codeType = "mixed", 23 _verifyName = "phone", 24 _transName = "phone", 25 _verifyReg = function() { return '^1(3|4|5|7|8)\\d{9}$' }, 26 _getCodeUrl = $we.conf.ENV.__API + "/ajaxVcode/sendByMobile", 27 _verifyCodeUrl = $we.conf.ENV.__API + "/ajaxVcode/checkMobile", 28 _maxBindedIdPerPhone = 20, 29 _getPhoneBindedNumApi = $we.conf.ENV.__API + "/ajaxBindMobile/getSdidCountByMobile"; 30 31 var _changeBtnStyle = function(start) { 32 $(this.btnInput).val(_changedMsg + "(" + start + "秒)"); 33 $(this.btnInput).addClass(_changedBtnClass); 34 this.bCanGetCode = false; 35 }; 36 37 var _recoverBtnStyle = function() { 38 $(this.btnInput).val(_originalMsg); 39 $(this.btnInput).removeClass(_changedBtnClass); 40 this.bCanGetCode = true; 41 }; 42 43 var _countDown = function(start) { 44 start = start || this.params.cooldown + 1; 45 var btn = $(this.btnInput), 46 me = this; 47 48 _changeBtnStyle.call(this, start); 49 50 var __countDownFun = function() { 51 --start; 52 if(start < 0) { 53 _recoverBtnStyle.call(me); 54 return; 55 } 56 57 btn.val($we.string.addStrNum(btn.val(), -1)); 58 59 setTimeout(__countDownFun, 1000); 60 } 61 62 __countDownFun(); 63 64 }; 65 66 var _setCookie = function() { 67 $.cookie(this.params.cookieName, +new Date); 68 }; 69 70 var _setCodeRegExp = function(type) { 71 switch(type) { 72 case "digital": 73 return '^ *\\d{6} *$'; 74 break; 75 case "mixed": 76 return '^ *[0-9a-zA-Z]{6} *$'; 77 break; 78 case "alpha": 79 return '^ *[a-zA-Z]{6} *$'; 80 break; 81 } 82 }; 83 84 /** 85 * 绑定手机组件 86 * @lends $we.widget.comp.verify_code 87 */ 88 $we.widget.reg("comp.verify_code", { 89 /** 90 * @constructs 91 */ 92 init: function(el, params) { 93 if(typeof el == "string") this.verifyCodeRootEl = $("#" + el)[0]; 94 else this.verifyCodeRootEl = el; 95 this.params = params || {}; 96 97 // 获取code的url 98 this.params.getCodeUrl = $we.utils.setValue(this.params.getCodeUrl, _getCodeUrl); 99 // 验证code的url 100 this.params.verifyUrl = $we.utils.setValue(this.params.verifyUrl, _verifyCodeUrl); 101 // 验证码的类型,目前只有digital和alpha 102 this.params.codeType = $we.utils.setValue(this.params.codeType, _codeType); 103 // 需要验证的验证对象的名称(从process.data中可能设置该值) 104 this.params.verifyName = $we.utils.setValue(this.params.verifyName, _verifyName); 105 // 验证成功后,将该名称储存到process.data中,默认该值与verifyName相同 106 this.params.saveVerifyName = $we.utils.setValue(this.params.saveVerifyName, this.params.verifyName); 107 // 是否是jsonp请求,默认为true 108 this.params.jsonp = $we.utils.setValue(this.params.jsonp, true); 109 // 验证对象的值,deprecated 110 this.params.verifier = $we.utils.setValue(this.params.verifier, false); 111 // form表单之前的表单,array 112 this.params.formBefore = $we.utils.setValue(this.params.formBefore, false); 113 // form表单之后的表单,array 114 this.params.formAfter = $we.utils.setValue(this.params.formAfter, false); 115 // 表单中第一个label的文案,当该表单不需要输入,已经有值 116 this.params.label1 = $we.utils.setValue(this.params.label1, _label1); 117 // 表单中第一个label的文案,当该表单需要输入 118 this.params.label1_empty = $we.utils.setValue(this.params.label1_empty, _label1_empty); 119 // 表单中第二个label的文案 120 this.params.label2 = $we.utils.setValue(this.params.label2, _label2); 121 // 表单中第三个label的文案 122 this.params.label3 = $we.utils.setValue(this.params.label3, _label3); 123 // 冷却时间 124 this.params.cooldown = $we.utils.setValue(this.params.cooldown, _defaultCooldown); 125 // 冷却时间设置的cookie名称 126 this.params.cookieName = $we.utils.setValue(this.params.cookieName, _cookieName); 127 // 验证对象的正则, function或者直接注明正则名称 128 this.params.verifyReg = $we.utils.setValue(this.params.verifyReg, _verifyReg); 129 // 传递给后端接口时,验证对象的名称 130 this.params.transName = $we.utils.setValue(this.params.transName, _transName); 131 // verifyCode的时候额外的请求参数 132 this.params.extraData = $we.utils.setValue(this.params.extraData, false); 133 // 表单提交后的回调 134 this.params.formCommit = $we.utils.setValue(this.params.formCommit, $we.emptyFunction); 135 }, 136 /** 137 * interfaces 138 * @memberOf $we.widget.comp.verify_code 139 */ 140 interfaces: { 141 render: function(params) { 142 if (typeof params == "object") { 143 // 如果设置了验证对象的名称,并且没有设置储存验证对象的名称,令储存验证对象的名称等于验证对象的名称 144 if (params.verifyName && !params.saveVerifyName) 145 params.saveVerifyName = params.verifyName; 146 147 for (var i in params) { 148 this.params[i] = params[i]; 149 } 150 } 151 152 153 // 是否可以获取验证码 154 this.bCanGetCode = true; 155 // 是否需要将验证对象的名称传递给后端 156 this.bTransVerifier = false; 157 // 根据需要验证对象的名称获取验证对象的值,或者直接被赋值 158 this.verifier = $we.process.getData(this.params.verifyName) || this.params.verifier; 159 // 需要验证的对象可否被写入 160 this.bVerifierWritable = false; 161 // 如果验证对象的值存在,但是验证对象的名称与最终存储的名称不同,也就是当前验证对象的名称只是一个过渡名称 162 // 那么,我们认为这个验证对象还是需要传递给后端 163 if (this.verifier && (this.params.verifyName != this.params.saveVerifyName)) 164 this.bTransVerifier = true; 165 166 var me = this, 167 codeRegExp = _setCodeRegExp(this.params.codeType), // 验证码的正则 168 verifierItem; // 验证对象的表单item 169 170 if (this.verifier) { 171 verifierItem = { 172 label: this.params.label1, 173 name: 'verifier', 174 type: 'content', 175 value: '<span class="we_yellow">'+$we.string.maskString(this.verifier)+'</span>' 176 }; 177 } else { 178 this.bTransVerifier = true; 179 this.bVerifierWritable = true; 180 verifierItem = { 181 label: this.params.label1_empty, 182 name: 'verifier', 183 expression: me.params.verifyReg, 184 events: "blur", 185 require: "true" 186 }; 187 } 188 189 var formConfigs = [ 190 verifierItem, { 191 label: this.params.label2, 192 name: 'send_code', 193 type: 'button', 194 value: "点击发送", 195 click: function() { 196 me.sendCode(this); 197 } 198 }, { 199 label: this.params.label3, 200 name: 'code', 201 expression: function() { return codeRegExp; }, 202 events: "blur", 203 require: "true" 204 }]; 205 206 if (this.params.formBefore) { 207 if (!$.isArray(this.params.formBefore)) 208 this.params.formBefore = [this.params.formBefore]; 209 210 formConfigs = this.params.formBefore.concat(formConfigs); 211 } 212 213 if (this.params.formAfter) { 214 if (!$.isArray(this.params.formAfter)) 215 this.params.formAfter = [this.params.formAfter]; 216 217 formConfigs = formConfigs.concat(this.params.formAfter); 218 } 219 220 this.form = $we.widget.add("Form", this.verifyCodeRootEl, { 221 form_elements: formConfigs, 222 commit: this.params.formCommit 223 }); 224 225 this.btnInput = this.form.getElement("send_code"); 226 227 // 如果当前是手机的验证码,并且需要填写手机 228 if (this.bTransVerifier && this.params.verifyName == "phone" && this.form.getElement("verifier")[0] && this.form.getElement("verifier")[0].tagName.toLowerCase() == "input") { 229 this.bInterrupt = true; 230 231 $(this.btnInput).addClass(_changedBtnClass); 232 this.form.getElement("verifier").on("blur", function(e) { 233 if (!me.form.valid("verifier")) return; 234 me.form.showInfo("verifier", "验证中..."); 235 $we.utils.request(_getPhoneBindedNumApi, { 236 phone: $(this).val() 237 }, function(data) { 238 if (parseInt(data.data) < _maxBindedIdPerPhone) { 239 me.form.valid("verifier"); 240 if (me.bCanGetCode) $(me.btnInput).removeClass(_changedBtnClass); 241 me.bInterrupt = false; 242 } else { 243 me.form.showError("verifier", "该手机绑定的账号超过20个,请换一个手机"); 244 } 245 }, function(data) { 246 me.form.showError("verifier", data.msg); 247 }, "POST", me.params.jsonp); 248 }); 249 } 250 251 var restCodeTime = parseInt((+new Date - parseInt($.cookie(this.params.cookieName))) / 1000); 252 if(restCodeTime < this.params.cooldown && this.bCanGetCode) { 253 _countDown.call(this, this.params.cooldown - restCodeTime); 254 } 255 }, 256 sendCode: function() { 257 if (this.bSendingCode || !this.bCanGetCode || this.bInterrupt) return; 258 if(!this.verifier && !this.form.valid("verifier")) return; 259 260 this.bSendingCode = true; 261 262 this.form.clearTip("send_code"); 263 this.form.clearTip("code"); 264 $(this.btnInput).val(_sendingCodeMsg); 265 266 var me = this, 267 data = {}; 268 if (this.bTransVerifier) { 269 // 如果验证的号码可以被写入,重新读取它的值 270 if (this.bVerifierWritable) this.verifier = this.form.getValue("verifier"); 271 data[this.params.transName] = this.verifier; 272 } 273 274 if ($we.process.getData("auth_type")) { 275 data.auth_type = $we.process.getData("auth_type"); 276 } 277 278 $we.utils.request(this.params.getCodeUrl, data, function(data) { 279 me.vcodeKey = data.data; 280 _setCookie.call(me); 281 me.form.showSuccess("send_code", "验证码已经发送"); 282 _countDown.call(me); 283 me.bSendingCode = false; 284 }, function(data) { 285 me.form.showError("send_code", data.msg); 286 _recoverBtnStyle.call(me); 287 me.bSendingCode = false; 288 }, "GET", this.params.jsonp); 289 }, 290 getData: function() { 291 if (!this.form.valid()) return false; 292 293 return { 294 verifier: this.verifier || this.form.getValue("verifier"), 295 code: this.form.getValue("code") 296 }; 297 }, 298 verifyCode: function(cb) { 299 if (this.bVerifyingCode || this.bInterrupt || !this.form.valid()) return; 300 if (!this.vcodeKey) { 301 this.form.showError("code", "请先发送验证码再进行操作"); 302 return; 303 } 304 this.bVerifyingCode = true; 305 306 this.code = $.trim(this.form.getValue("code")); 307 308 var data = { 309 key: this.vcodeKey, 310 vcode: this.code 311 }; 312 313 if (this.bTransVerifier) { 314 // 如果验证的号码可以被写入,重新读取它的值 315 if (this.bVerifierWritable) this.verifier = this.form.getValue("verifier"); 316 data[this.params.transName] = this.verifier; 317 } 318 319 if ($we.process.getData("auth_type")) { 320 data.auth_type = $we.process.getData("auth_type"); 321 } 322 323 if (this.params.extraData && typeof this.params.extraData == "object") { 324 for (var i in this.params.extraData) { 325 data[i] = this.params.extraData[i]; 326 } 327 } 328 329 var me = this; 330 $we.utils.request(this.params.verifyUrl, data, function(data) { 331 /** 332 * 设置 verifier 333 */ 334 $we.process.setData(me.params.saveVerifyName, me.verifier); 335 // 清除cookie 336 // $.removeCookie(me.params.cookieName); 337 cb(data.data); 338 me.bVerifyingCode = false; 339 }, function(data) { 340 if (data.errno == -2011) { 341 me.form.clear("verifier"); 342 me.form.clear("code"); 343 } 344 me.form.showError("code", data.msg); 345 me.bVerifyingCode = false; 346 }, "POST", this.params.jsonp); 347 } 348 } 349 }); 350 351 return $we.widget.amd("comp.verify_code"); 352 353 });