sunlupeng 8 months ago
parent
commit
e0455841c1

+ 1 - 1
yudao-ui/yudao-ui-admin-vue2/.env.dev

@@ -14,7 +14,7 @@ VUE_CLI_BABEL_TRANSPILE_MODULES = true
 VUE_APP_TENANT_ENABLE = true
 
 # 验证码的开关
-VUE_APP_CAPTCHA_ENABLE = true
+VUE_APP_CAPTCHA_ENABLE = false
 
 # 文档的开关
 VUE_APP_DOC_ENABLE = true

+ 1 - 1
yudao-ui/yudao-ui-admin-vue2/.env.front

@@ -14,7 +14,7 @@ VUE_CLI_BABEL_TRANSPILE_MODULES = true
 VUE_APP_TENANT_ENABLE = true
 
 # 验证码的开关
-VUE_APP_CAPTCHA_ENABLE = true
+VUE_APP_CAPTCHA_ENABLE = false
 
 # 文档的开关
 VUE_APP_DOC_ENABLE = true

+ 1 - 1
yudao-ui/yudao-ui-admin-vue2/.env.prod

@@ -16,7 +16,7 @@ VUE_APP_APP_NAME ='yudao-admin'
 VUE_APP_TENANT_ENABLE = true
 
 # 验证码的开关
-VUE_APP_CAPTCHA_ENABLE = true
+VUE_APP_CAPTCHA_ENABLE = false
 
 # 文档的开关
 VUE_APP_DOC_ENABLE = false

+ 1 - 1
yudao-ui/yudao-ui-admin-vue2/.env.stage

@@ -16,7 +16,7 @@ PUBLIC_PATH = 'http://static.yudao.iocoder.cn/'
 VUE_APP_TENANT_ENABLE = true
 
 # 验证码的开关
-VUE_APP_CAPTCHA_ENABLE = true
+VUE_APP_CAPTCHA_ENABLE = false
 
 # 文档的开关
 VUE_APP_DOC_ENABLE = false

+ 18 - 1
yudao-ui/yudao-ui-admin-vue2/src/App.vue

@@ -21,8 +21,25 @@ export default {
   }
 };
 </script>
-<style scoped>
+<style>
 #app .theme-picker {
   display: none;
 }
+::-webkit-scrollbar-track {
+  background: rgba(0, 0, 0, 0.1);
+  border-radius: 0;
+}
+
+::-webkit-scrollbar {
+  -webkit-appearance: none;
+  width: 8px;
+  height: 6px;
+}
+
+::-webkit-scrollbar-thumb {
+  cursor: pointer;
+  border-radius: 5px;
+  background: rgba(0, 0, 0, 0.15);
+  transition: color 0.2s ease;
+}
 </style>

+ 1 - 1
yudao-ui/yudao-ui-admin-vue2/src/assets/styles/login.scss

@@ -128,7 +128,7 @@ $buttonHeight: $buttonH * 1px;
         }
         :deep(.el-tabs__item.is-active) {
           font-weight: bold;
-          color: #2F53EB;
+          color: #1890ff;
         }
         :deep(.el-tabs__active-bar) {
           height: 3px;

+ 1 - 1
yudao-ui/yudao-ui-admin-vue2/src/components/AppList/index.vue

@@ -4,7 +4,7 @@
       <el-card class="el-card-auto">
       <div slot="header" class="clearfix">
         <span style="font-size: 20px;">我的应用</span>
-        <el-button style="font-size: 20px;float: right; padding: 3px 0" type="text">操作按钮</el-button>
+        <el-button style="font-size: 20px;float: right; padding: 3px 0" type="text">添加应用</el-button>
       </div>
       <div class="appList">
         <div class="typeTitle">OA</div>

+ 5 - 0
yudao-ui/yudao-ui-admin-vue2/src/router/index.js

@@ -44,6 +44,11 @@ export const constantRoutes = [
     component: (resolve) => require(['@/views/login'], resolve),
     hidden: true
   },
+  {
+    path: '/register',
+    component: (resolve) => require(['@/views/register'], resolve),
+    hidden: true
+  },
   {
     path: '/sso',
     component: (resolve) => require(['@/views/sso'], resolve),

+ 1 - 1
yudao-ui/yudao-ui-admin-vue2/src/views/index.vue

@@ -150,7 +150,7 @@ export default {
   padding: 32px;
   background-color: rgb(240, 242, 245);
   position: relative;
-  height: 100vh;
+  height: 100%;
   .chart-wrapper {
     background: #fff;
     padding: 16px 16px 0;

+ 31 - 12
yudao-ui/yudao-ui-admin-vue2/src/views/login.vue

@@ -1,6 +1,6 @@
 <template xmlns="">
   <div class="container">
-    <div class="logo"></div>
+    <!-- <div class="logo"></div> -->
     <!-- 登录区域 -->
     <div class="content">
       <!-- 配图 -->
@@ -15,9 +15,9 @@
         <!-- 表单 -->
         <div class="form-cont">
           <el-tabs class="form" v-model="loginForm.loginType" style=" float:none;">
-            <el-tab-pane label="账号密码登录" name="uname">
+            <el-tab-pane label="密码登录" name="uname">
             </el-tab-pane>
-            <el-tab-pane label="短信验证码登录" name="sms">
+            <el-tab-pane label="验证码登录" name="sms">
             </el-tab-pane>
           </el-tabs>
           <div>
@@ -30,7 +30,7 @@
               <!-- 账号密码登录 -->
               <div v-if="loginForm.loginType === 'uname'">
                 <el-form-item prop="username">
-                  <el-input v-model="loginForm.username" type="text" auto-complete="off" placeholder="号">
+                  <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>
@@ -73,24 +73,28 @@
                   <span v-else>登 录 中...</span>
                 </el-button>
               </el-form-item>
-
+              <!--  注册 -->
+              <div class="register-tip">
+                没有账号?
+                <span class="register-btn" @click="doRegister()">免费注册</span>
+              </div>
               <!--  社交登录 -->
-             <el-form-item style="width:100%;">
+             <!-- <el-form-item style="width:100%;">
                   <div class="oauth-login" style="display:flex">
                     <div class="oauth-login-item" v-for="item in SysUserSocialTypeEnum" :key="item.type" @click="doSocialLogin(item)">
                       <img :src="item.img" height="25px" width="25px" alt="登录" >
                       <span>{{item.title}}</span>
                     </div>
                 </div>
-              </el-form-item>
+              </el-form-item> -->
 
               <!-- 教程说明 -->
-              <el-form-item style="width:100%; margin-top:-25px">
+              <!-- <el-form-item style="width:100%; margin-top:-25px">
                 <el-link href="https://doc.iocoder.cn/" target="_blank">📚开发指南</el-link>
                 <el-link href="https://doc.iocoder.cn/video/" target="_blank" style="padding-left: 10px">🔥视频教程</el-link>
                 <el-link href="https://www.iocoder.cn/Interview/good-collection/" target="_blank" style="padding-left: 10px">⚡面试手册</el-link>
                 <el-link href="http://static.yudao.iocoder.cn/mp/Aix9975.jpeg" target="_blank" style="padding-left: 10px">🤝外包咨询</el-link>
-              </el-form-item>
+              </el-form-item> -->
             </el-form>
           </div>
         </div>
@@ -102,9 +106,9 @@
             @success="handleLogin" />
 
     <!-- footer -->
-    <div class="footer">
+    <!-- <div class="footer">
       Copyright © 2020-2022 iocoder.cn All Rights Reserved.
-    </div>
+    </div> -->
   </div>
 </template>
 
@@ -141,6 +145,8 @@ export default {
         loginType: "uname",
         username: "admin",
         password: "admin123",
+        // username: "",
+        // password: "",
         captchaVerification: "",
         mobile: "",
         mobileCode: "",
@@ -212,6 +218,10 @@ export default {
     this.getCookie();
   },
   methods: {
+    //跳转注册
+    doRegister() {
+      this.$router.push({path: '/register'})
+    },
     getCode() {
       // 情况一,未开启:则直接登录
       if (!this.captchaEnable) {
@@ -325,7 +335,16 @@ export default {
 <style lang="scss" scoped>
 @import "~@/assets/styles/login.scss";
 
-
+.register-tip{
+  color: #141e31;
+    font-size: 14px;
+    line-height: 20px;
+    margin: 10px 0 20px;
+}
+.register-btn{
+  color:  #1890ff;
+  cursor: pointer;
+}
 .oauth-login {
   display: flex;
   align-items: center;

+ 379 - 0
yudao-ui/yudao-ui-admin-vue2/src/views/register.vue

@@ -0,0 +1,379 @@
+<template xmlns="">
+  <div class="container">
+    <!-- <div class="logo"></div> -->
+    <!-- 登录区域 -->
+    <div class="content">
+      <!-- 配图 -->
+      <div class="pic"></div>
+      <!-- 表单 -->
+      <div class="field">
+        <!-- [移动端]标题 -->
+        <h2 class="mobile-title">
+          <h3 class="title">爱思系统</h3>
+        </h2>
+
+        <!-- 表单 -->
+        <div class="form-cont">
+          <div class="form" style=" float:none;margin-bottom: 20px;">
+            <el-steps :active="loginForm.loginType" simple>
+              <el-step title="注册账号" icon="el-icon-user"></el-step>
+              <el-step title="创建团队" icon="el-icon-edit"></el-step>
+            </el-steps>
+          </div>
+          
+          <div style="width: 320px;">
+            <el-form ref="loginForm" :model="loginForm" :rules="LoginRules" class="login-form">
+             
+              <!-- 注册账号 -->
+              <div v-if="loginForm.loginType == 1">
+                <el-form-item prop="mobile">
+                  <el-input v-model="loginForm.mobile" type="text" auto-complete="off" placeholder="请输入手机号">
+                    <svg-icon slot="prefix" icon-class="phone" class="el-input__icon input-icon"/>
+                  </el-input>
+                </el-form-item>
+                <el-form-item prop="mobileCode">
+                  <el-input v-model="loginForm.mobileCode" type="text" auto-complete="off" placeholder="短信验证码"
+                            class="sms-login-mobile-code-prefix"
+                            @keyup.enter.native="handleLogin">
+                    <template>
+                      <svg-icon slot="prefix" icon-class="password" class="el-input__icon input-icon"/>
+                    </template>
+                    <template slot="append">
+                      <span v-if="mobileCodeTimer <= 0" class="getMobileCode" @click="getSmsCode" style="cursor: pointer;">获取验证码</span>
+                      <span v-if="mobileCodeTimer > 0" class="getMobileCode">{{ mobileCodeTimer }}秒后可重新获取</span>
+                    </template>
+                  </el-input>
+                </el-form-item>
+                <div class="service-laws">
+                  点击注册表明你已阅读并同意
+                  <a class="terms" href="https://www.jiandaoyun.com/index/term" target="_blank">《服务条款》</a>
+                  和
+                  <a class="terms" href="https://www.jiandaoyun.com/index/term/privacy" target="_blank">《隐私声明》</a>
+                </div>
+                <!-- 下方的下一步按钮 -->
+                <el-form-item style="width:100%;">
+                  <el-button :loading="loading" size="medium" type="primary" style="width:100%;"
+                      @click.native.prevent="getNext()">
+                    <span v-if="!loading">下 一 步</span>
+                    <span v-else>操 作 中...</span>
+                  </el-button>
+                </el-form-item>
+                 <!--  去登录 -->
+                <div class="register-tip">
+                  已有账号?
+                  <span class="register-btn" @click="doLogin()">直接登录</span>
+                </div>
+              </div>
+
+              <!-- 创建团队 -->
+              <div v-if="loginForm.loginType == 2">
+                <el-form-item prop="mobile">
+                  <el-input v-model="loginForm.mobile" type="text" auto-complete="off" placeholder="请输入企业名称">
+                  </el-input>
+                </el-form-item>
+                <el-form-item prop="mobile">
+                  <el-select v-model="loginForm.mobile" placeholder="请选择需求" style="width: 100%;">
+                    <el-option label="企业使用" value="企业使用"></el-option>
+                    <el-option label="个人使用" value="个人使用"></el-option>
+                  </el-select>
+                </el-form-item>
+                <el-form-item prop="mobile">
+                  <el-select v-model="loginForm.mobile" placeholder="请选择所属行业" style="width: 100%;">
+                    <el-option label="互联网/软件" value="互联网/软件"></el-option>
+                  </el-select>
+                </el-form-item>
+                 <!-- 下方的进入产品按钮 -->
+                <el-form-item>
+                  <el-button :loading="loading" size="medium" type="primary" style="width:100%;"
+                      @click.native.prevent="getCode">
+                    <span v-if="!loading">进 入 产 品</span>
+                    <span v-else>操 作 中...</span>
+                  </el-button>
+                </el-form-item>
+                 <!--  去登录 -->
+                 <div class="register-tip">
+                  你可以
+                  <span class="register-btn" @click="doLogin()">加入企业/团队</span>
+                </div>
+              </div>
+             
+            </el-form>
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import {sendSmsCode, socialAuthRedirect} from "@/api/login";
+import {getTenantIdByName} from "@/api/system/tenant";
+import {SystemUserSocialTypeEnum} from "@/utils/constants";
+import {getCaptchaEnable, getTenantEnable} from "@/utils/ruoyi";
+import {
+  getPassword,
+  getRememberMe, getTenantName,
+  getUsername,
+  removePassword, removeRememberMe, removeTenantName,
+  removeUsername,
+  setPassword, setRememberMe, setTenantId, setTenantName,
+  setUsername
+} from "@/utils/auth";
+
+import Verify from '@/components/Verifition/Verify';
+import {resetUserPwd} from "@/api/system/user";
+
+export default {
+  name: "Login",
+  components: {
+    Verify
+  },
+  data() {
+    return {
+      codeUrl: "",
+      captchaEnable: true,
+      tenantEnable: true,
+      mobileCodeTimer: 0,
+      loginForm: {
+        loginType: 1,
+        // username: "admin",
+        // password: "admin123",
+        username: "",
+        password: "",
+        captchaVerification: "",
+        mobile: "",
+        mobileCode: "",
+        rememberMe: false,
+        tenantName: "芋道源码",
+      },
+      scene: 21,
+
+      LoginRules: {
+        username: [
+          {required: true, trigger: "blur", message: "用户名不能为空"}
+        ],
+        password: [
+          {required: true, trigger: "blur", message: "密码不能为空"}
+        ],
+        mobile: [
+          {required: true, trigger: "blur", message: "手机号不能为空"},
+          {
+            validator: function (rule, value, callback) {
+              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) {
+                callback(new Error("手机号格式错误"));
+              } else {
+                callback();
+              }
+            }, trigger: "blur"
+          }
+        ],
+        tenantName: [
+          {required: true, trigger: "blur", message: "租户不能为空"},
+          {
+            validator: (rule, value, callback) => {
+              // debugger
+              getTenantIdByName(value).then(res => {
+                const tenantId = res.data;
+                if (tenantId && tenantId >= 0) {
+                  // 设置租户
+                  setTenantId(tenantId)
+                  callback();
+                } else {
+                  callback('租户不存在');
+                }
+              });
+            },
+            trigger: 'blur'
+          }
+        ]
+      },
+      loading: false,
+      redirect: undefined,
+      // 枚举
+      SysUserSocialTypeEnum: SystemUserSocialTypeEnum,
+    };
+  },
+  created() {
+    // 租户开关
+    this.tenantEnable = getTenantEnable();
+    if (this.tenantEnable) {
+      getTenantIdByName(this.loginForm.tenantName).then(res => { // 设置租户
+        const tenantId = res.data;
+        if (tenantId && tenantId >= 0) {
+          setTenantId(tenantId)
+        }
+      });
+    }
+    // 验证码开关
+    this.captchaEnable = getCaptchaEnable();
+    // 重定向地址
+    this.redirect = this.$route.query.redirect ? decodeURIComponent(this.$route.query.redirect) : undefined;
+    // this.getCookie();
+  },
+  methods: {
+    // 下一步
+    getNext(){
+      this.loginForm.loginType=2;
+    },
+    //跳转登录
+    doLogin() {
+      this.$router.push({path: '/login'})
+    },
+    getCode() {
+      // 情况一,未开启:则直接登录
+      if (!this.captchaEnable) {
+        this.handleLogin({})
+        return;
+      }
+
+      // 情况二,已开启:则展示验证码;只有完成验证码的情况,才进行登录
+      // 弹出验证码
+      this.$refs.verify.show()
+    },
+    getCookie() {
+      const username = getUsername();
+      const password = getPassword();
+      const rememberMe = getRememberMe();
+      const tenantName = getTenantName();
+      this.loginForm = {
+        ...this.loginForm,
+        username: username ? username : this.loginForm.username,
+        password: password ? password : this.loginForm.password,
+        rememberMe: rememberMe ? getRememberMe() : false,
+        tenantName: tenantName ? tenantName : this.loginForm.tenantName,
+      };
+    },
+    handleLogin(captchaParams) {
+      this.$refs.loginForm.validate(valid => {
+        if (valid) {
+          this.loading = true;
+          // 设置 Cookie
+          if (this.loginForm.rememberMe) {
+            setUsername(this.loginForm.username)
+            setPassword(this.loginForm.password)
+            setRememberMe(this.loginForm.rememberMe)
+            setTenantName(this.loginForm.tenantName)
+          } else {
+            removeUsername()
+            removePassword()
+            removeRememberMe()
+            removeTenantName()
+          }
+          this.loginForm.captchaVerification = captchaParams.captchaVerification
+          // 发起登陆
+          // console.log("发起登录", this.loginForm);
+          this.$store.dispatch(this.loginForm.loginType === "sms" ? "SmsLogin" : "Login", this.loginForm).then(() => {
+            this.$router.push({path: "/"}).catch(() => {
+            });
+          }).catch(() => {
+            this.loading = false;
+          });
+        }
+      });
+    },
+    async doSocialLogin(socialTypeEnum) {
+      // 设置登录中
+      this.loading = true;
+      let tenant = false;
+      if (this.tenantEnable) {
+        await this.$prompt('请输入租户名称', "提示", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消"
+        }).then(async ({value}) => {
+          await getTenantIdByName(value).then(res => {
+            const tenantId = res.data;
+            tenant = true
+            if (tenantId && tenantId >= 0) {
+              setTenantId(tenantId)
+            }
+          });
+        }).catch(() => {
+          // 取消登录按钮 loading状态
+          this.loading = false;
+
+          return false
+        });
+      } else {
+        tenant = true
+      }
+     if(tenant){
+       // 计算 redirectUri
+       const redirectUri = location.origin + '/social-login?'
+         + encodeURIComponent('type=' + socialTypeEnum.type + '&redirect=' + (this.redirect || "/")); // 重定向不能丢
+       // const redirectUri = 'http://127.0.0.1:48080/api/gitee/callback';
+       // const redirectUri = 'http://127.0.0.1:48080/api/dingtalk/callback';
+       // 进行跳转
+       socialAuthRedirect(socialTypeEnum.type, encodeURIComponent(redirectUri)).then((res) => {
+         // console.log(res.url);
+         window.location.href = res.data;
+       });
+     }
+    },
+    /** ========== 以下为升级短信登录 ========== */
+    getSmsCode() {
+      if (this.mobileCodeTimer > 0) return;
+      this.$refs.loginForm.validate(valid => {
+        if (!valid) return;
+        sendSmsCode(this.loginForm.mobile, this.scene, this.loginForm.uuid, this.loginForm.code).then(res => {
+          this.$modal.msgSuccess("获取验证码成功")
+          this.mobileCodeTimer = 60;
+          let msgTimer = setInterval(() => {
+            this.mobileCodeTimer = this.mobileCodeTimer - 1;
+            if (this.mobileCodeTimer <= 0) {
+              clearInterval(msgTimer);
+            }
+          }, 1000);
+        });
+      });
+    }
+  }
+};
+</script>
+<style lang="scss" scoped>
+@import "~@/assets/styles/login.scss";
+.service-laws {
+    color: #525967;
+    font-size: 14px;
+    margin-bottom: 10px;
+}
+.service-laws .terms {
+    color:  #1890ff;
+}
+a {
+    outline: none;
+    text-decoration: none;
+}
+.register-tip{
+  color: #141e31;
+    font-size: 14px;
+    line-height: 20px;
+    margin: 10px 0 10px;
+}
+.register-btn{
+  color:  #1890ff;
+  cursor: pointer;
+}
+.oauth-login {
+  display: flex;
+  align-items: center;
+  cursor:pointer;
+}
+.oauth-login-item {
+  display: flex;
+  align-items: center;
+  margin-right: 10px;
+}
+.oauth-login-item img {
+  height: 25px;
+  width: 25px;
+}
+.oauth-login-item span:hover {
+  text-decoration: underline red;
+  color: red;
+}
+.sms-login-mobile-code-prefix {
+  :deep(.el-input__prefix) {
+    top: 22%;
+  }
+}
+</style>