login.vue 12 KB

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