1 <template> 2 <view class="logo-wrapper"> 3 <view class="logo-img"> 4 <image src="../../static/images/logo-login.png" mode="widthFix" /> 5 </view> 6 <view class="form-box"> 7 <view class="form-item"> 8 <view class="icon-box"> 9 <i class="iconfont icon-yonghu"></i> 10 </view> 11 <input class="ipt" v-model="username" type="text" placeholder="用户名" /> 12 </view> 13 <view class="form-item"> 14 <view class="icon-box"> 15 <i class="iconfont icon-mima"></i> 16 </view> 17 <input class="ipt" v-model="password" type="password" placeholder="密码" /> 18 </view> 19 <view class="form-item"> 20 <view class="icon-box"> 21 <i class="iconfont icon-yanzhengma"></i> 22 </view> 23 <input class="ipt short" v-model="capCode" type="text" placeholder="验证码" /> 24 <canvas class="canvas" canvas-id="yzmCanvas" id="yzmCanvas" @tap="tapCaptcha"></canvas> 25 </view> 26 <button class="btn-login" @tap="login">登录</button> 27 </view> 28 <view class="bottom-img"> 29 <image src="../../static/images/login-bottom.png" mode="widthFix" /> 30 </view> 31 </view> 32 </template> 33 34 <script> 35 export default { 36 data() { 37 return { 38 capShow: true, 39 username: '', 40 password: '', 41 capCode: '', 42 uuid: '' 43 } 44 }, 45 methods: { 46 async queryCaptcha() { 47 const { data } = await this.$http({ 48 url: '/captchaImage', 49 method: 'GET', 50 }); 51 this.uuid = data.data.uuid; 52 this.creatCanvas(data.data.image); 53 }, 54 tapCaptcha() { 55 this.capShow = false; 56 this.$nextTick(() => { 57 this.capShow = true; 58 this.queryCaptcha(); 59 }); 60 }, 61 //得到随机的颜色值 62 randomColor() { 63 var r = Math.floor(Math.random() * 256); 64 var g = Math.floor(Math.random() * 256); 65 var b = Math.floor(Math.random() * 256); 66 return 'rgb(' + r + ',' + g + ',' + b + ')'; 67 }, 68 creatCanvas(str) { 69 const ctx = uni.createCanvasContext('yzmCanvas'); 70 ctx.setFontSize(28 + Math.floor(Math.random() * 4 - 2)); 71 ctx.setFillStyle(this.randomColor()); 72 for (let i = 0; i < 4; i++) { 73 ctx.setFontSize(28 + Math.floor(Math.random() * 4 - 2)); 74 ctx.fillText(str[i], 20 * i + 10, 32); 75 ctx.setFillStyle(this.randomColor()); 76 // 旋转随机在-3到3之间 77 ctx.rotate((Math.floor(Math.random() * 6 - 3) * Math.PI) / 180); 78 } 79 // 直线 begin path 80 for (let i = 0; i < 4; i++) { 81 ctx.beginPath(); 82 ctx.setStrokeStyle(this.randomColor()); 83 // x/-10~110 y/-10~50 84 ctx.moveTo( 85 Math.floor(Math.random() * 100) + Math.floor(Math.random() * 20 - 10), 86 Math.floor(Math.random() * 40) + Math.floor(Math.random() * 20 - 10) 87 ); 88 ctx.lineTo( 89 Math.floor(Math.random() * 100) + Math.floor(Math.random() * 20 - 10), 90 Math.floor(Math.random() * 40) + Math.floor(Math.random() * 20 - 10) 91 ); 92 ctx.stroke(); 93 } 94 ctx.draw(); 95 }, 96 async login() { 97 if(this.username === '') { 98 uni.showToast({ 99 icon: 'none', 100 title: '请填写用户名' 101 }); 102 return; 103 } 104 if(this.password === '') { 105 uni.showToast({ 106 icon: 'none', 107 title: '请填写密码' 108 }); 109 return; 110 } 111 if(this.capCode === '') { 112 uni.showToast({ 113 icon: 'none', 114 title: '请填写验证码' 115 }); 116 return; 117 } 118 const { data } = await this.$http({ 119 url: '/login', 120 method: 'POST', 121 data: { 122 username: this.username, 123 password: this.password, 124 code: this.capCode, 125 uuid: this.uuid 126 } 127 }); 128 uni.setStorageSync('token', data.data.token); 129 130 const res = await this.$http({ 131 url: '/personal/userInfo', 132 method: 'GET', 133 data: { 134 token: data.data.token, 135 } 136 }); 137 let userInfo = res.data.data; 138 uni.setStorageSync('userInfo', userInfo); 139 140 uni.switchTab({ 141 url: '/pages/index/index' 142 }); 143 } 144 }, 145 onLoad() { 146 this.queryCaptcha(); 147 }, 148 } 149 </script> 150 151 <style lang="scss"> 152 .logo-wrapper { 153 display: flex; 154 flex-direction: column; 155 align-items: center; 156 justify-content: space-between; 157 } 158 .logo-img { 159 590upx; 160 height: 246upx; 161 margin-top: 60upx; 162 } 163 .form-box { 164 560upx; 165 height: 580upx; 166 margin: 30upx 0 140upx 0; 167 } 168 .form-item { 169 100%; 170 height: 82upx; 171 margin-top: 48upx; 172 border-bottom: 1px solid #c1c1c1; 173 display: flex; 174 align-items: center; 175 } 176 .icon-box { 177 50upx; 178 height: 50upx; 179 border-radius: 50%; 180 margin-right: 40upx; 181 text-align: center; 182 line-height: 42upx; 183 background-color: #f0443c; 184 color: #fff; 185 i { 186 font-size: 24upx; 187 } 188 } 189 .ipt { 190 flex: 1; 191 height: 80upx; 192 } 193 .canvas { 194 190upx; 195 height: 68upx; 196 border: 1px solid #f1f1f1; 197 background: #fdfdfd; 198 } 199 .btn-login { 200 margin-top: 84upx; 201 background-color: #f0443c; 202 color: #fff; 203 } 204 .bottom-img { 205 628upx; 206 height: 124upx; 207 // margin: 50upx auto 0; 208 } 209 </style>