houzhongjian
2024-07-11 759b1c71011abd6b58c37d2566f3f3c208c2f1b2
提交 | 用户 | 时间
759b1c 1 <template xmlns="">
H 2   <div class="container">
3     <div class="logo"><div style="font-size: 40px; color: #1e1e1e">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;工业互联网微服务平台</div></div>
4     <!-- 登录区域 -->
5     <div class="content">
6       <!-- 配图 -->
7       <div class="pic"></div>
8       <!-- 表单 -->
9       <div class="field">
10         <!-- [移动端]标题 -->
11         <h2 class="mobile-title">
12           <h3 class="title">工业互联网微服务平台</h3>
13         </h2>
14
15         <!-- 表单 -->
16         <div class="form-cont">
17           <el-tabs class="form" v-model="loginForm.loginType" style=" float:none;">
18             <el-tab-pane label="账号密码登录" name="uname">
19             </el-tab-pane>
20             <el-tab-pane label="短信验证码登录" name="sms">
21             </el-tab-pane>
22           </el-tabs>
23           <div>
24             <el-form ref="loginForm" :model="loginForm" :rules="LoginRules" class="login-form">
25               <el-form-item prop="tenantName" v-if="tenantEnable">
26                 <el-input v-model="loginForm.tenantName" type="text" auto-complete="off" placeholder='租户'>
27                   <svg-icon slot="prefix" icon-class="tree" class="el-input__icon input-icon"/>
28                 </el-input>
29               </el-form-item>
30               <!-- 账号密码登录 -->
31               <div v-if="loginForm.loginType === 'uname'">
32                 <el-form-item prop="username">
33                   <el-input v-model="loginForm.username" type="text" auto-complete="off" placeholder="账号">
34                     <svg-icon slot="prefix" icon-class="user" class="el-input__icon input-icon"/>
35                   </el-input>
36                 </el-form-item>
37                 <el-form-item prop="password">
38                   <el-input v-model="loginForm.password" type="password" auto-complete="off" placeholder="密码"
39                             @keyup.enter.native="getCode">
40                     <svg-icon slot="prefix" icon-class="password" class="el-input__icon input-icon"/>
41                   </el-input>
42                 </el-form-item>
43                 <el-checkbox v-model="loginForm.rememberMe" style="margin:0 0 25px 0;">记住密码</el-checkbox>
44               </div>
45
46               <!-- 短信验证码登录 -->
47               <div v-if="loginForm.loginType === 'sms'">
48                 <el-form-item prop="mobile">
49                   <el-input v-model="loginForm.mobile" type="text" auto-complete="off" placeholder="请输入手机号">
50                     <svg-icon slot="prefix" icon-class="phone" class="el-input__icon input-icon"/>
51                   </el-input>
52                 </el-form-item>
53                 <el-form-item prop="mobileCode">
54                   <el-input v-model="loginForm.mobileCode" type="text" auto-complete="off" placeholder="短信验证码"
55                             class="sms-login-mobile-code-prefix"
56                             @keyup.enter.native="handleLogin">
57                     <template>
58                       <svg-icon slot="prefix" icon-class="password" class="el-input__icon input-icon"/>
59                     </template>
60                     <template slot="append">
61                       <span v-if="mobileCodeTimer <= 0" class="getMobileCode" @click="getSmsCode" style="cursor: pointer;">获取验证码</span>
62                       <span v-if="mobileCodeTimer > 0" class="getMobileCode">{{ mobileCodeTimer }}秒后可重新获取</span>
63                     </template>
64                   </el-input>
65                 </el-form-item>
66               </div>
67
68               <!-- 下方的登录按钮 -->
69               <el-form-item style="width:100%;">
70                 <el-button :loading="loading" size="medium" type="primary" style="width:100%;"
71                     @click.native.prevent="getCode">
72                   <span v-if="!loading">登 录</span>
73                   <span v-else>登 录 中...</span>
74                 </el-button>
75               </el-form-item>
76
77             </el-form>
78           </div>
79         </div>
80       </div>
81     </div>
82
83     <!-- 图形验证码 -->
84     <Verify ref="verify" :captcha-type="'blockPuzzle'" :img-size="{width:'400px',height:'200px'}"
85             @success="handleLogin" />
86
87     <!-- footer -->
88     <div class="footer">
89       Copyright © 2020-2022 iocoder.cn All Rights Reserved.
90     </div>
91   </div>
92 </template>
93
94 <script>
95 import {sendSmsCode, socialAuthRedirect} from "@/api/login";
96 import {getTenantIdByName} from "@/api/system/tenant";
97 import {SystemUserSocialTypeEnum} from "@/utils/constants";
98 import {getCaptchaEnable, getTenantEnable} from "@/utils/ruoyi";
99 import {
100   getPassword,
101   getRememberMe, getTenantName,
102   getUsername,
103   removePassword, removeRememberMe, removeTenantName,
104   removeUsername,
105   setPassword, setRememberMe, setTenantId, setTenantName,
106   setUsername
107 } from "@/utils/auth";
108
109 import Verify from '@/components/Verifition/Verify';
110 import {resetUserPwd} from "@/api/system/user";
111
112 export default {
113   name: "Login",
114   components: {
115     Verify
116   },
117   data() {
118     return {
119       codeUrl: "",
120       captchaEnable: true,
121       tenantEnable: true,
122       mobileCodeTimer: 0,
123       loginForm: {
124         loginType: "uname",
125         username: "admin",
126         password: "admin123",
127         captchaVerification: "",
128         mobile: "",
129         mobileCode: "",
130         rememberMe: false,
131         tenantName: "iailab",
132       },
133       scene: 21,
134
135       LoginRules: {
136         username: [
137           {required: true, trigger: "blur", message: "用户名不能为空"}
138         ],
139         password: [
140           {required: true, trigger: "blur", message: "密码不能为空"}
141         ],
142         mobile: [
143           {required: true, trigger: "blur", message: "手机号不能为空"},
144           {
145             validator: function (rule, value, callback) {
146               if (/^(?:(?:\+|00)86)?1(?:3[\d]|4[5-79]|5[0-35-9]|6[5-7]|7[0-8]|8[\d]|9[189])\d{8}$/.test(value) === false) {
147                 callback(new Error("手机号格式错误"));
148               } else {
149                 callback();
150               }
151             }, trigger: "blur"
152           }
153         ],
154         tenantName: [
155           {required: true, trigger: "blur", message: "租户不能为空"},
156           {
157             validator: (rule, value, callback) => {
158               // debugger
159               getTenantIdByName(value).then(res => {
160                 const tenantId = res.data;
161                 if (tenantId && tenantId >= 0) {
162                   // 设置租户
163                   setTenantId(tenantId)
164                   callback();
165                 } else {
166                   callback('租户不存在');
167                 }
168               });
169             },
170             trigger: 'blur'
171           }
172         ]
173       },
174       loading: false,
175       redirect: undefined,
176       // 枚举
177       SysUserSocialTypeEnum: SystemUserSocialTypeEnum,
178     };
179   },
180   created() {
181     // 租户开关
182     this.tenantEnable = getTenantEnable();
183     if (this.tenantEnable) {
184       getTenantIdByName(this.loginForm.tenantName).then(res => { // 设置租户
185         const tenantId = res.data;
186         if (tenantId && tenantId >= 0) {
187           setTenantId(tenantId)
188         }
189       });
190     }
191     // 验证码开关
192     this.captchaEnable = getCaptchaEnable();
193     // 重定向地址
194     this.redirect = this.$route.query.redirect ? decodeURIComponent(this.$route.query.redirect) : undefined;
195     this.getCookie();
196   },
197   methods: {
198     getCode() {
199       // 情况一,未开启:则直接登录
200       if (!this.captchaEnable) {
201         this.handleLogin({})
202         return;
203       }
204
205       // 情况二,已开启:则展示验证码;只有完成验证码的情况,才进行登录
206       // 弹出验证码
207       this.$refs.verify.show()
208     },
209     getCookie() {
210       const username = getUsername();
211       const password = getPassword();
212       const rememberMe = getRememberMe();
213       const tenantName = getTenantName();
214       this.loginForm = {
215         ...this.loginForm,
216         username: username ? username : this.loginForm.username,
217         password: password ? password : this.loginForm.password,
218         rememberMe: rememberMe ? getRememberMe() : false,
219         tenantName: tenantName ? tenantName : this.loginForm.tenantName,
220       };
221     },
222     handleLogin(captchaParams) {
223       this.$refs.loginForm.validate(valid => {
224         if (valid) {
225           this.loading = true;
226           // 设置 Cookie
227           if (this.loginForm.rememberMe) {
228             setUsername(this.loginForm.username)
229             setPassword(this.loginForm.password)
230             setRememberMe(this.loginForm.rememberMe)
231             setTenantName(this.loginForm.tenantName)
232           } else {
233             removeUsername()
234             removePassword()
235             removeRememberMe()
236             removeTenantName()
237           }
238           this.loginForm.captchaVerification = captchaParams.captchaVerification
239           // 发起登陆
240           // console.log("发起登录", this.loginForm);
241           this.$store.dispatch(this.loginForm.loginType === "sms" ? "SmsLogin" : "Login", this.loginForm).then(() => {
242             this.$router.push({path: this.redirect || "/"}).catch(() => {
243             });
244           }).catch(() => {
245             this.loading = false;
246           });
247         }
248       });
249     },
250     async doSocialLogin(socialTypeEnum) {
251       // 设置登录中
252       this.loading = true;
253       let tenant = false;
254       if (this.tenantEnable) {
255         await this.$prompt('请输入租户名称', "提示", {
256           confirmButtonText: "确定",
257           cancelButtonText: "取消"
258         }).then(async ({value}) => {
259           await getTenantIdByName(value).then(res => {
260             const tenantId = res.data;
261             tenant = true
262             if (tenantId && tenantId >= 0) {
263               setTenantId(tenantId)
264             }
265           });
266         }).catch(() => {
267           // 取消登录按钮 loading状态
268           this.loading = false;
269
270           return false
271         });
272       } else {
273         tenant = true
274       }
275      if(tenant){
276        // 计算 redirectUri
277        const redirectUri = location.origin + '/social-login?'
278          + encodeURIComponent('type=' + socialTypeEnum.type + '&redirect=' + (this.redirect || "/")); // 重定向不能丢
279        // const redirectUri = 'http://127.0.0.1:48080/api/gitee/callback';
280        // const redirectUri = 'http://127.0.0.1:48080/api/dingtalk/callback';
281        // 进行跳转
282        socialAuthRedirect(socialTypeEnum.type, encodeURIComponent(redirectUri)).then((res) => {
283          // console.log(res.url);
284          window.location.href = res.data;
285        });
286      }
287     },
288     /** ========== 以下为升级短信登录 ========== */
289     getSmsCode() {
290       if (this.mobileCodeTimer > 0) return;
291       this.$refs.loginForm.validate(valid => {
292         if (!valid) return;
293         sendSmsCode(this.loginForm.mobile, this.scene, this.loginForm.uuid, this.loginForm.code).then(res => {
294           this.$modal.msgSuccess("获取验证码成功")
295           this.mobileCodeTimer = 60;
296           let msgTimer = setInterval(() => {
297             this.mobileCodeTimer = this.mobileCodeTimer - 1;
298             if (this.mobileCodeTimer <= 0) {
299               clearInterval(msgTimer);
300             }
301           }, 1000);
302         });
303       });
304     }
305   }
306 };
307 </script>
308 <style lang="scss" scoped>
309 @import "~@/assets/styles/login.scss";
310
311
312 .oauth-login {
313   display: flex;
314   align-items: center;
315   cursor:pointer;
316 }
317 .oauth-login-item {
318   display: flex;
319   align-items: center;
320   margin-right: 10px;
321 }
322 .oauth-login-item img {
323   height: 25px;
324   width: 25px;
325 }
326 .oauth-login-item span:hover {
327   text-decoration: underline red;
328   color: red;
329 }
330 .sms-login-mobile-code-prefix {
331   :deep(.el-input__prefix) {
332     top: 22%;
333   }
334 }
335 </style>