SecurityVerify.vue 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504
  1. <template>
  2. <div>
  3. <nav-bar path="index" title="身份验证"/>
  4. <div class='card'>
  5. <h3><strong>个人资料</strong></h3>
  6. <van-cell-group :border="false">
  7. <van-field
  8. v-model="phone"
  9. required
  10. clearable
  11. label="手机号"
  12. placeholder="请输入手机号"
  13. :error="phoneError"
  14. @click="phoneError=false"
  15. />
  16. <!--<van-field-->
  17. <!--v-model="sms"-->
  18. <!--center-->
  19. <!--clearable-->
  20. <!--label="短信验证码"-->
  21. <!--placeholder="请输入短信验证码"-->
  22. <!--required-->
  23. <!--disabled-->
  24. <!--&gt;-->
  25. <!--<van-button slot="button" size="small" type="primary">发送验证码</van-button>-->
  26. <!--</van-field>-->
  27. <van-field
  28. v-model="username"
  29. required
  30. clearable
  31. label="昵称"
  32. placeholder="请输入昵称"
  33. maxlength="12"
  34. :error="usernameError"
  35. @click="usernameError=false"
  36. />
  37. <van-field
  38. v-model="wechat"
  39. required
  40. clearable
  41. label="微信号"
  42. placeholder="请输入微信号"
  43. maxlength="20"
  44. :error="wechatError"
  45. @click="wechatError=false"
  46. />
  47. </van-cell-group>
  48. <p>性别</p>
  49. <van-radio-group v-model="radio">
  50. <van-radio name="1" checked-color="#fd6740" style="float: left; margin-right: 20px">男</van-radio>
  51. <van-radio name="2" checked-color="#fd6740">女</van-radio>
  52. </van-radio-group>
  53. <p>宿舍区</p>
  54. <van-button size="large" @click="show = true">{{dormitory}}</van-button>
  55. <van-actionsheet
  56. v-model="show"
  57. :actions="actions"
  58. cancel-text="取消"
  59. @select="onSelect"
  60. />
  61. </div>
  62. <div class="card" style="margin-bottom: 10px">
  63. <p>上传校卡照片</p>
  64. <div style="margin-bottom: 10px">
  65. <add-photo @onRead="onRead"/>
  66. </div>
  67. <p>活动仅允许深大学生参与,请上传正面校卡照片审核~</p>
  68. </div>
  69. <van-button
  70. class="submit_button"
  71. type="primary"
  72. @click="next"
  73. :loading="loading"
  74. >下一步
  75. </van-button>
  76. </div>
  77. </template>
  78. <script>
  79. import {BasicFunction} from "../connector/basic-service";
  80. import NavBar from '../components/navBar';
  81. import {
  82. Uploader, Icon,
  83. CellGroup, Field,
  84. RadioGroup, Radio,
  85. Picker,
  86. Button,
  87. Actionsheet,
  88. Toast
  89. } from 'vant';
  90. import AddPhoto from "../components/addPhoto";
  91. export default {
  92. name: "SecurityVerify",
  93. components: {
  94. AddPhoto,
  95. NavBar,
  96. [Uploader.name]: Uploader, [Icon.name]: Icon,
  97. [CellGroup.name]: CellGroup, [Field.name]: Field,
  98. [RadioGroup.name]: RadioGroup, [Radio.name]: Radio,
  99. [Picker.name]: Picker,
  100. [Button.name]: Button,
  101. [Actionsheet.name]: Actionsheet
  102. },
  103. data() {
  104. return {
  105. phone: '',
  106. phoneError: false,
  107. sms: '',
  108. username: '',
  109. usernameError: false,
  110. wechat: '',
  111. wechatError: false,
  112. radio: '1',
  113. show: false,
  114. dormitory: '点击选择宿舍区',
  115. dorId: -1,
  116. actions: [
  117. {id: 0, name: '斋区'},
  118. {id: 1, name: '西南'},
  119. {id: 2, name: '南区'},
  120. {id: 3, name: '桂庙'},
  121. {id: 4, name: '西丽'},
  122. ],
  123. photo: null,
  124. loading: false,
  125. userDo : {},
  126. identityDo : {},
  127. identityUpload : false,
  128. userUpload : false
  129. };
  130. },
  131. methods: {
  132. next() {
  133. Toast.loading({
  134. mask: true,
  135. message: '此过程大约需要15s,你的校卡正在拼命上传,请耐心等待...',
  136. duration: 20000
  137. });
  138. this.loading = true;
  139. // 检查输入
  140. if (this.phone.length !== 11) {
  141. Toast.fail("请输入11位手机号");
  142. this.phoneError = true;
  143. this.loading = false;
  144. return;
  145. } else if (!isNumber(this.phone)) {
  146. Toast.fail("请输入正确格式的手机号");
  147. this.phoneError = true;
  148. this.loading = false;
  149. return;
  150. } else if (isEmojiCharacter(this.username)) {
  151. Toast.fail('不支持表情哦');
  152. this.usernameError = true;
  153. this.loading = false;
  154. return;
  155. } else if (this.username.length < 1) {
  156. Toast.fail('请输入昵称');
  157. this.usernameError = true;
  158. this.loading = false;
  159. return;
  160. } else if (isEmojiCharacter(this.wechat) || this.wechat.length < 6) {
  161. this.wechatError = true;
  162. Toast.fail('请输入正确格式的微信号');
  163. this.loading = false;
  164. return;
  165. } else if (this.dorId === -1) {
  166. Toast.fail('请选择宿舍区');
  167. this.loading = false;
  168. return;
  169. } else if (this.photo === null) {
  170. Toast.fail('请上传校卡正面照片');
  171. this.loading = false;
  172. return;
  173. }
  174. let that = this;
  175. this.compressImg();
  176. },
  177. compressImg: function () {
  178. let that = this;
  179. let fileObj = this.photo;
  180. photoCompress(fileObj, {
  181. quality: 0.2
  182. }, function (base64Codes) {
  183. let formData = new FormData();
  184. //console.log("压缩后:" + base.length / 1024 + " " + base);
  185. var bl = convertBase64UrlToBlob(base64Codes);
  186. // formData.append('file', fileObj);
  187. console.log(fileObj);
  188. formData.append("file", bl); // 文件对象
  189. console.log(bl);
  190. console.log("file_" + Date.parse(new Date()) + ".jpg");
  191. that.uploadImg(formData);
  192. });
  193. },
  194. uploadImg(formData) {
  195. let that = this;
  196. BasicFunction.get_data("fileserver/upload?sign=abcdefg", function (res) {
  197. try {
  198. if (res.ret === '10000' && res.model !== undefined && res.model.length !== 0) {
  199. let imgURL = res.model;
  200. that.updateInfo(imgURL);
  201. } else {
  202. Toast.fail('上传图片失败,请检查网络');
  203. that.loading = false;
  204. }
  205. } catch (e) {
  206. console.warn(e);
  207. Toast.fail('上传图片失败,请检查网络');
  208. that.loading = false;
  209. }
  210. }, formData);
  211. },
  212. updateInfo(image) {
  213. let userId = localStorage.getItem('frontend-userid');
  214. let that = this;
  215. let useridentity = that.identityDo;
  216. useridentity.userWxAccount = that.wechat;
  217. useridentity.dormDistrict = that.dorId;
  218. useridentity.userSex = parseInt(that.radio);
  219. if(image != null){
  220. useridentity.userSchoolCardPic = image;
  221. }
  222. let beforeImage = image;
  223. useridentity.userSchoolCardPic = image;
  224. useridentity.userReviewStatus = 100;
  225. useridentity.reviewerNote = "等待审核";
  226. useridentity.reviewerNoteToUser = "等待审核";
  227. BasicFunction.get_data("smartIdentity/updateBatch", function (response) {
  228. // console.log(useridentity);
  229. // console.log(response);
  230. if (response.ret === "10000") {
  231. // console.log('----- User Info -----');
  232. if(beforeImage != null) {
  233. that.identityUpload = true;
  234. if (that.userUpload == true) {
  235. Toast.success("注册成功");
  236. that.$router.push('presentRegister');
  237. return;
  238. }
  239. }
  240. } else {
  241. Toast.fail("注册失败,请检查网络");
  242. that.loading = false;
  243. }
  244. }, [useridentity]);
  245. let user = that.userDo;
  246. user.name = that.username;
  247. user.phone = that.phone;
  248. // console.log('----- Update User Info -----');
  249. // console.log(user);
  250. BasicFunction.get_data('smartUsers/updateBatch', function (res) {
  251. // console.log(res);
  252. if (res !== undefined && res.ret === '10000') {
  253. that.userUpload = true;
  254. if(that.identityUpload == true && beforeImage != null) {
  255. Toast.success("注册成功");
  256. that.$router.push('presentRegister');
  257. return;
  258. }
  259. } else {
  260. Toast.fail('注册失败,请稍后再试');
  261. that.loading = false;
  262. }
  263. }, [user]);
  264. },
  265. onSelect(item) {
  266. // 点击选项时默认不会关闭菜单,可以手动关闭
  267. this.show = false;
  268. this.dormitory = item.name;
  269. this.dorId = item.id;
  270. },
  271. onRead(e) {
  272. this.photo = e;
  273. }
  274. },
  275. created: function () {
  276. let userId = localStorage.getItem('frontend-userid');
  277. let that = this;
  278. if(userId == null || userId === undefined){
  279. this.$router.push('login');
  280. return;
  281. }
  282. // 获取smartUser
  283. BasicFunction.get_data('smartUsers/list?uid=' + userId, function (res) {
  284. if (res.ret === '10000') {
  285. if(res.model === undefined || res.model == null || res.model.list == undefined || res.model.list.length <= 0){
  286. localStorage.removeItem('frontend-userid');
  287. that.$router.push('login');
  288. return;
  289. }
  290. if (res.model.list[0].phone != null && res.model.list[0].phone.length !== 0) {
  291. that.$router.push('presentRegister');
  292. return;
  293. }
  294. that.userDo = res.model.list[0];
  295. }
  296. }, {});
  297. // 获取Identity
  298. BasicFunction.get_data("smartIdentity/list?userId=" + userId, function (res) {
  299. try {
  300. if (res.ret === '10000' && res.model !== undefined && res.model.list !== undefined && res.model.list.length > 0) {
  301. that.identityDo = res.model.list[0];
  302. } else {
  303. localStorage.removeItem('frontend-userid');
  304. that.loading = false;
  305. that.$router.push('login');
  306. }
  307. } catch (e) {
  308. console.warn(e);
  309. Toast.fail('获取信息缓慢,请检查网络或等一会再试吧!');
  310. localStorage.removeItem('frontend-userid');
  311. that.loading = false;
  312. that.$router.push('login');
  313. }
  314. }, {});
  315. }
  316. }
  317. // 判断是否有emoji
  318. function isEmojiCharacter(substring) {
  319. for (var i = 0; i < substring.length; i++) {
  320. var hs = substring.charCodeAt(i);
  321. if (0xd800 <= hs && hs <= 0xdbff) {
  322. if (substring.length > 1) {
  323. var ls = substring.charCodeAt(i + 1);
  324. var uc = ((hs - 0xd800) * 0x400) + (ls - 0xdc00) + 0x10000;
  325. if (0x1d000 <= uc && uc <= 0x1f77f) {
  326. return true;
  327. }
  328. }
  329. } else if (substring.length > 1) {
  330. var ls = substring.charCodeAt(i + 1);
  331. if (ls == 0x20e3) {
  332. return true;
  333. }
  334. } else {
  335. if (0x2100 <= hs && hs <= 0x27ff) {
  336. return true;
  337. } else if (0x2B05 <= hs && hs <= 0x2b07) {
  338. return true;
  339. } else if (0x2934 <= hs && hs <= 0x2935) {
  340. return true;
  341. } else if (0x3297 <= hs && hs <= 0x3299) {
  342. return true;
  343. } else if (hs == 0xa9 || hs == 0xae || hs == 0x303d || hs == 0x3030
  344. || hs == 0x2b55 || hs == 0x2b1c || hs == 0x2b1b
  345. || hs == 0x2b50) {
  346. return true;
  347. }
  348. }
  349. }
  350. }
  351. // 判断是否是数字
  352. function isNumber(str) {
  353. for (let i = 0; i < str.length; i++) {
  354. if (str[i] < '0' || str[i] > '9') return false;
  355. }
  356. return true;
  357. }
  358. /*
  359. 三个参数
  360. file:一个是文件(类型是图片格式),
  361. w:一个是文件压缩的后宽度,宽度越小,字节越小
  362. objDiv:一个是容器或者回调函数
  363. photoCompress()
  364. */
  365. function photoCompress(file, w, objDiv) {
  366. var ready = new FileReader();
  367. /*开始读取指定的Blob对象或File对象中的内容. 当读取操作完成时,readyState属性的值会成为DONE,如果设置了onloadend事件处理程序,则调用之.同时,result属性中将包含一个data: URL格式的字符串以表示所读取文件的内容.*/
  368. ready.readAsDataURL(file);
  369. ready.onload = function () {
  370. var re = this.result;
  371. canvasDataURL(re, w, objDiv)
  372. }
  373. }
  374. function canvasDataURL(path, obj, callback) {
  375. var img = new Image();
  376. img.src = path;
  377. img.onload = function () {
  378. var that = this;
  379. // 默认按比例压缩
  380. var w = that.width,
  381. h = that.height,
  382. scale = w / h;
  383. w = obj.width || w;
  384. h = obj.height || (w / scale);
  385. var quality = 0.7; // 默认图片质量为0.7
  386. //生成canvas
  387. var canvas = document.createElement('canvas');
  388. var ctx = canvas.getContext('2d');
  389. // 创建属性节点
  390. var anw = document.createAttribute("width");
  391. anw.nodeValue = w;
  392. var anh = document.createAttribute("height");
  393. anh.nodeValue = h;
  394. canvas.setAttributeNode(anw);
  395. canvas.setAttributeNode(anh);
  396. ctx.drawImage(that, 0, 0, w, h);
  397. // 图像质量
  398. if (obj.quality && obj.quality <= 1 && obj.quality > 0) {
  399. quality = obj.quality;
  400. }
  401. // quality值越小,所绘制出的图像越模糊
  402. var base64 = canvas.toDataURL('image/jpeg', quality);
  403. // 回调函数返回base64的值
  404. callback(base64);
  405. }
  406. }
  407. /**
  408. * 将以base64的图片url数据转换为Blob
  409. * @param urlData
  410. * 用url方式表示的base64图片数据
  411. */
  412. function convertBase64UrlToBlob(urlData) {
  413. var arr = urlData.split(','), mime = arr[0].match(/:(.*?);/)[1],
  414. bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
  415. while (n--) {
  416. u8arr[n] = bstr.charCodeAt(n);
  417. }
  418. return new Blob([u8arr], {type: mime});
  419. }
  420. //上传文件方法
  421. // function UpladFile() {
  422. // var fileObj = document.getElementById("file").files[0]; // js 获取文件对象
  423. // var url = "后台图片上传接口"; // 接收上传文件的后台地址
  424. //
  425. // var form = new FormData(); // FormData 对象
  426. //
  427. // if (fileObj.size / 1024 > 1025) { //大于1M,进行压缩上传
  428. // photoCompress(fileObj, {
  429. // quality: 0.2
  430. // }, function (base64Codes) {
  431. // //console.log("压缩后:" + base.length / 1024 + " " + base);
  432. // var bl = convertBase64UrlToBlob(base64Codes);
  433. // form.append("file", bl, "file_" + Date.parse(new Date()) + ".jpg"); // 文件对象
  434. // xhr = new XMLHttpRequest(); // XMLHttpRequest 对象
  435. // xhr.open("post", url, true); //post方式,url为服务器请求地址,true 该参数规定请求是否异步处理。
  436. // xhr.onload = uploadComplete; //请求完成
  437. // xhr.onerror = uploadFailed; //请求失败
  438. //
  439. // xhr.upload.onprogress = progressFunction;//【上传进度调用方法实现】
  440. // xhr.upload.onloadstart = function () {//上传开始执行方法
  441. // ot = new Date().getTime(); //设置上传开始时间
  442. // oloaded = 0;//设置上传开始时,以上传的文件大小为0
  443. // };
  444. //
  445. // xhr.send(form); //开始上传,发送form数据
  446. // });
  447. // } else { //小于等于1M 原图上传
  448. // form.append("file", fileObj); // 文件对象
  449. // xhr = new XMLHttpRequest(); // XMLHttpRequest 对象
  450. // xhr.open("post", url, true); //post方式,url为服务器请求地址,true 该参数规定请求是否异步处理。
  451. // xhr.onload = uploadComplete; //请求完成
  452. // xhr.onerror = uploadFailed; //请求失败
  453. //
  454. // xhr.upload.onprogress = progressFunction;//【上传进度调用方法实现】
  455. // xhr.upload.onloadstart = function () {//上传开始执行方法
  456. // ot = new Date().getTime(); //设置上传开始时间
  457. // oloaded = 0;//设置上传开始时,以上传的文件大小为0
  458. // };
  459. //
  460. // xhr.send(form); //开始上传,发送form数据
  461. // }
  462. // }
  463. </script>
  464. <style scoped>
  465. p, h3 {
  466. color: #fd6740;
  467. }
  468. h3 {
  469. padding: 5px;
  470. border-bottom: solid 1px #e4e4e4;
  471. }
  472. .card {
  473. background-color: white;
  474. margin: 20px 20px;
  475. border: solid 1px #e4e4e4;
  476. padding: 15px;
  477. text-align: left;
  478. }
  479. .submit_button {
  480. margin-bottom: 10px;
  481. margin-left: auto;
  482. margin-right: auto;
  483. background-color: #fd6740;
  484. border-color: #fd6740;
  485. width: 85%;
  486. }
  487. </style>