From 45ac0f23e12ac2a45c6affe9e39d0897e4fad618 Mon Sep 17 00:00:00 2001 From: 疯狂的狮子Li <15040126243@163.com> Date: 星期四, 16 二月 2023 17:06:10 +0800 Subject: [PATCH] !286 合并 多租户功能 * add 新增 ruoyi-common-tenant 多租户模块 全框架适配多租户改动 * update 优化 隐藏页面主键 * remove 移除 缓存列表功能(多租户缓存功能繁杂多样 没有办法在页面管理) * update 重构 全局缓存KEY 与 常用缓存KEY做区分 * update 重构 OssFactory 加载方式 改为每次比对配置做实例更新 * update 优化 SaTokenDao 改为 Bean 注入 便于扩展 * update 重构 项目初始化数据改为懒加载 不提供热加载 * update 重构 验证码开关使用配置文件(经调查少有动态开启需求) * update 优化 启用 sqlserver 高版本语法 简化sql脚本语法 * update 优化 DataPermissionHelper 增加 开启/关闭 忽略数据权限功能 * update 优化 连接池增加 keepaliveTime 探活参数 * update 优化 调整连接池最长生命周期 防止出现警告 * update 优化 代码生成页面模板 校验不必要的表单数据 * add 新增 StringUtils splitTo 与 splitList 方法 优化业务代码 --- ruoyi-ui/src/views/login.vue | 465 ++++++++++++++++++++++++++++++--------------------------- 1 files changed, 246 insertions(+), 219 deletions(-) diff --git a/ruoyi-ui/src/views/login.vue b/ruoyi-ui/src/views/login.vue index 074fecd..2a47e85 100644 --- a/ruoyi-ui/src/views/login.vue +++ b/ruoyi-ui/src/views/login.vue @@ -1,219 +1,246 @@ -<template> - <div class="login"> - <el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form"> - <h3 class="title">鑻ヤ緷鍚庡彴绠$悊绯荤粺</h3> - <el-form-item prop="username"> - <el-input - v-model="loginForm.username" - type="text" - auto-complete="off" - placeholder="璐﹀彿" - > - <svg-icon slot="prefix" icon-class="user" class="el-input__icon input-icon" /> - </el-input> - </el-form-item> - <el-form-item prop="password"> - <el-input - v-model="loginForm.password" - type="password" - auto-complete="off" - placeholder="瀵嗙爜" - @keyup.enter.native="handleLogin" - > - <svg-icon slot="prefix" icon-class="password" class="el-input__icon input-icon" /> - </el-input> - </el-form-item> - <el-form-item prop="code" v-if="captchaEnabled"> - <el-input - v-model="loginForm.code" - auto-complete="off" - placeholder="楠岃瘉鐮�" - style="width: 63%" - @keyup.enter.native="handleLogin" - > - <svg-icon slot="prefix" icon-class="validCode" class="el-input__icon input-icon" /> - </el-input> - <div class="login-code"> - <img :src="codeUrl" @click="getCode" class="login-code-img"/> - </div> - </el-form-item> - <el-checkbox v-model="loginForm.rememberMe" style="margin:0px 0px 25px 0px;">璁颁綇瀵嗙爜</el-checkbox> - <el-form-item style="width:100%;"> - <el-button - :loading="loading" - size="medium" - type="primary" - style="width:100%;" - @click.native.prevent="handleLogin" - > - <span v-if="!loading">鐧� 褰�</span> - <span v-else>鐧� 褰� 涓�...</span> - </el-button> - <div style="float: right;" v-if="register"> - <router-link class="link-type" :to="'/register'">绔嬪嵆娉ㄥ唽</router-link> - </div> - </el-form-item> - </el-form> - <!-- 搴曢儴 --> - <div class="el-login-footer"> - <span>Copyright 漏 2018-2022 ruoyi.vip All Rights Reserved.</span> - </div> - </div> -</template> - -<script> -import { getCodeImg } from "@/api/login"; -import Cookies from "js-cookie"; -import { encrypt, decrypt } from '@/utils/jsencrypt' - -export default { - name: "Login", - data() { - return { - codeUrl: "", - loginForm: { - username: "admin", - password: "admin123", - rememberMe: false, - code: "", - uuid: "" - }, - loginRules: { - username: [ - { required: true, trigger: "blur", message: "璇疯緭鍏ユ偍鐨勮处鍙�" } - ], - password: [ - { required: true, trigger: "blur", message: "璇疯緭鍏ユ偍鐨勫瘑鐮�" } - ], - code: [{ required: true, trigger: "change", message: "璇疯緭鍏ラ獙璇佺爜" }] - }, - loading: false, - // 楠岃瘉鐮佸紑鍏� - captchaEnabled: true, - // 娉ㄥ唽寮�鍏� - register: false, - redirect: undefined - }; - }, - watch: { - $route: { - handler: function(route) { - this.redirect = route.query && route.query.redirect; - }, - immediate: true - } - }, - created() { - this.getCode(); - this.getCookie(); - }, - methods: { - getCode() { - getCodeImg().then(res => { - this.captchaEnabled = res.captchaEnabled === undefined ? true : res.captchaEnabled; - if (this.captchaEnabled) { - this.codeUrl = "data:image/gif;base64," + res.img; - this.loginForm.uuid = res.uuid; - } - }); - }, - getCookie() { - const username = Cookies.get("username"); - const password = Cookies.get("password"); - const rememberMe = Cookies.get('rememberMe') - this.loginForm = { - username: username === undefined ? this.loginForm.username : username, - password: password === undefined ? this.loginForm.password : decrypt(password), - rememberMe: rememberMe === undefined ? false : Boolean(rememberMe) - }; - }, - handleLogin() { - this.$refs.loginForm.validate(valid => { - if (valid) { - this.loading = true; - if (this.loginForm.rememberMe) { - Cookies.set("username", this.loginForm.username, { expires: 30 }); - Cookies.set("password", encrypt(this.loginForm.password), { expires: 30 }); - Cookies.set('rememberMe', this.loginForm.rememberMe, { expires: 30 }); - } else { - Cookies.remove("username"); - Cookies.remove("password"); - Cookies.remove('rememberMe'); - } - this.$store.dispatch("Login", this.loginForm).then(() => { - this.$router.push({ path: this.redirect || "/" }).catch(()=>{}); - }).catch(() => { - this.loading = false; - if (this.captchaEnabled) { - this.getCode(); - } - }); - } - }); - } - } -}; -</script> - -<style rel="stylesheet/scss" lang="scss"> -.login { - display: flex; - justify-content: center; - align-items: center; - height: 100%; - background-image: url("../assets/images/login-background.jpg"); - background-size: cover; -} -.title { - margin: 0px auto 30px auto; - text-align: center; - color: #707070; -} - -.login-form { - border-radius: 6px; - background: #ffffff; - width: 400px; - padding: 25px 25px 5px 25px; - .el-input { - height: 38px; - input { - height: 38px; - } - } - .input-icon { - height: 39px; - width: 14px; - margin-left: 2px; - } -} -.login-tip { - font-size: 13px; - text-align: center; - color: #bfbfbf; -} -.login-code { - width: 33%; - height: 38px; - float: right; - img { - cursor: pointer; - vertical-align: middle; - } -} -.el-login-footer { - height: 40px; - line-height: 40px; - position: fixed; - bottom: 0; - width: 100%; - text-align: center; - color: #fff; - font-family: Arial; - font-size: 12px; - letter-spacing: 1px; -} -.login-code-img { - height: 38px; -} -</style> +<template> + <div class="login"> + <el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form"> + <h3 class="title">RuoYi-Vue-Plus鍚庡彴绠$悊绯荤粺</h3> + <el-form-item prop="tenantId"> + <el-select v-model="loginForm.tenantId" filterable placeholder="璇烽�夋嫨/杈撳叆鍏徃鍚嶇О" style="width: 100%"> + <el-option + v-for="item in tenantList" + :key="item.tenantId" + :label="item.companyName" + :value="item.tenantId"> + </el-option> + <svg-icon slot="prefix" icon-class="company" class="el-input__icon input-icon" /> + </el-select> + </el-form-item> + <el-form-item prop="username"> + <el-input + v-model="loginForm.username" + type="text" + auto-complete="off" + placeholder="璐﹀彿" + > + <svg-icon slot="prefix" icon-class="user" class="el-input__icon input-icon" /> + </el-input> + </el-form-item> + <el-form-item prop="password"> + <el-input + v-model="loginForm.password" + type="password" + auto-complete="off" + placeholder="瀵嗙爜" + @keyup.enter.native="handleLogin" + > + <svg-icon slot="prefix" icon-class="password" class="el-input__icon input-icon" /> + </el-input> + </el-form-item> + <el-form-item prop="code" v-if="captchaEnabled"> + <el-input + v-model="loginForm.code" + auto-complete="off" + placeholder="楠岃瘉鐮�" + style="width: 63%" + @keyup.enter.native="handleLogin" + > + <svg-icon slot="prefix" icon-class="validCode" class="el-input__icon input-icon" /> + </el-input> + <div class="login-code"> + <img :src="codeUrl" @click="getCode" class="login-code-img"/> + </div> + </el-form-item> + <el-checkbox v-model="loginForm.rememberMe" style="margin:0px 0px 25px 0px;">璁颁綇瀵嗙爜</el-checkbox> + <el-form-item style="width:100%;"> + <el-button + :loading="loading" + size="medium" + type="primary" + style="width:100%;" + @click.native.prevent="handleLogin" + > + <span v-if="!loading">鐧� 褰�</span> + <span v-else>鐧� 褰� 涓�...</span> + </el-button> + <div style="float: right;" v-if="register"> + <router-link class="link-type" :to="'/register'">绔嬪嵆娉ㄥ唽</router-link> + </div> + </el-form-item> + </el-form> + <!-- 搴曢儴 --> + <div class="el-login-footer"> + <span>Copyright 漏 2018-2022 ruoyi.vip All Rights Reserved.</span> + </div> + </div> +</template> + +<script> +import { getCodeImg, tenantList } from "@/api/login"; +import Cookies from "js-cookie"; +import { encrypt, decrypt } from '@/utils/jsencrypt' + +export default { + name: "Login", + data() { + return { + codeUrl: "", + loginForm: { + tenantId: "000000", + username: "admin", + password: "admin123", + rememberMe: false, + code: "", + uuid: "" + }, + loginRules: { + tenantId: [ + { required: true, trigger: "blur", message: "璇疯緭鍏ユ偍鐨勭鎴风紪鍙�" } + ], + username: [ + { required: true, trigger: "blur", message: "璇疯緭鍏ユ偍鐨勮处鍙�" } + ], + password: [ + { required: true, trigger: "blur", message: "璇疯緭鍏ユ偍鐨勫瘑鐮�" } + ], + code: [{ required: true, trigger: "change", message: "璇疯緭鍏ラ獙璇佺爜" }] + }, + loading: false, + // 楠岃瘉鐮佸紑鍏� + captchaEnabled: true, + // 娉ㄥ唽寮�鍏� + register: false, + redirect: undefined, + // 绉熸埛鍒楄〃 + tenantList:[] + }; + }, + watch: { + $route: { + handler: function(route) { + this.redirect = route.query && route.query.redirect; + }, + immediate: true + } + }, + created() { + this.getCode(); + this.getTenantList(); + this.getCookie(); + }, + methods: { + getCode() { + getCodeImg().then(res => { + this.captchaEnabled = res.data.captchaEnabled === undefined ? true : res.data.captchaEnabled; + if (this.captchaEnabled) { + this.codeUrl = "data:image/gif;base64," + res.data.img; + this.loginForm.uuid = res.data.uuid; + } + }); + }, + getTenantList() { + tenantList().then(res => { + this.tenantList = res.data; + }); + }, + getCookie() { + const tenantId = Cookies.get("tenantId"); + const username = Cookies.get("username"); + const password = Cookies.get("password"); + const rememberMe = Cookies.get('rememberMe') + this.loginForm = { + tenantId: tenantId === undefined ? this.loginForm.tenantId : tenantId, + username: username === undefined ? this.loginForm.username : username, + password: password === undefined ? this.loginForm.password : decrypt(password), + rememberMe: rememberMe === undefined ? false : Boolean(rememberMe) + }; + }, + handleLogin() { + this.$refs.loginForm.validate(valid => { + if (valid) { + this.loading = true; + if (this.loginForm.rememberMe) { + Cookies.set("tenantId", this.loginForm.tenantId, { expires: 30 }); + Cookies.set("username", this.loginForm.username, { expires: 30 }); + Cookies.set("password", encrypt(this.loginForm.password), { expires: 30 }); + Cookies.set('rememberMe', this.loginForm.rememberMe, { expires: 30 }); + } else { + Cookies.remove("tenantId"); + Cookies.remove("username"); + Cookies.remove("password"); + Cookies.remove('rememberMe'); + } + this.$store.dispatch("Login", this.loginForm).then(() => { + this.$router.push({ path: this.redirect || "/" }).catch(()=>{}); + }).catch(() => { + this.loading = false; + if (this.captchaEnabled) { + this.getCode(); + } + }); + } + }); + } + } +}; +</script> + +<style rel="stylesheet/scss" lang="scss"> +.login { + display: flex; + justify-content: center; + align-items: center; + height: 100%; + background-image: url("../assets/images/login-background.jpg"); + background-size: cover; +} +.title { + margin: 0px auto 30px auto; + text-align: center; + color: #707070; +} + +.login-form { + border-radius: 6px; + background: #ffffff; + width: 400px; + padding: 25px 25px 5px 25px; + .el-input { + height: 38px; + input { + height: 38px; + } + } + .input-icon { + height: 39px; + width: 14px; + margin-left: 2px; + } +} +.login-tip { + font-size: 13px; + text-align: center; + color: #bfbfbf; +} +.login-code { + width: 33%; + height: 38px; + float: right; + img { + cursor: pointer; + vertical-align: middle; + } +} +.el-login-footer { + height: 40px; + line-height: 40px; + position: fixed; + bottom: 0; + width: 100%; + text-align: center; + color: #fff; + font-family: Arial; + font-size: 12px; + letter-spacing: 1px; +} +.login-code-img { + height: 38px; +} +</style> -- Gitblit v1.9.3