sgc 1 mesiac pred
rodič
commit
046803865d
4 zmenil súbory, kde vykonal 278 pridanie a 182 odobranie
  1. 3 2
      pages.json
  2. 275 180
      pages/login.vue
  3. BIN
      static/login/login-bg.png
  4. BIN
      static/login/login-illustration.png

+ 3 - 2
pages.json

@@ -2,8 +2,9 @@
   "pages": [{
     "path": "pages/login",
     "style": {
-      "navigationBarTitleText": "登录",
-      "navigationStyle": "custom"
+      "navigationBarTitleText": "",
+      "navigationStyle": "custom",
+      "navigationBarBackgroundColor": "transparent"
     }
   }, {
     "path": "pages/register",

+ 275 - 180
pages/login.vue

@@ -1,210 +1,305 @@
 <template>
-  <view class="normal-login-container">
-    <view class="logo-content align-center justify-center flex">
-      <image style="width: 100rpx;height: 100rpx;" :src="globalConfig.appInfo.logo" mode="widthFix">
-      </image>
-      <text class="title">若依移动端登录</text>
-    </view>
-    <view class="login-form-content">
-      <view class="input-item flex align-center">
-        <view class="iconfont icon-user icon"></view>
-        <input v-model="loginForm.username" class="input" type="text" placeholder="请输入账号" maxlength="30" />
-      </view>
-      <view class="input-item flex align-center">
-        <view class="iconfont icon-password icon"></view>
-        <input v-model="loginForm.password" type="password" class="input" placeholder="请输入密码" maxlength="20" />
+  <view class="login-page">
+    <view class="login-hero"></view>
+
+    <view class="login-content">
+      <view class="status-bar"></view>
+
+      <view class="header">
+        <text class="header-title">登录律师账号</text>
+        <text class="header-subtitle">请使用手机号接收验证码进行登录</text>
       </view>
-      <view class="input-item flex align-center" style="width: 60%;margin: 0px;" v-if="captchaEnabled">
-        <view class="iconfont icon-code icon"></view>
-        <input v-model="loginForm.code" type="number" class="input" placeholder="请输入验证码" maxlength="4" />
-        <view class="login-code"> 
-          <image :src="codeUrl" @click="getCode" class="login-code-img"></image>
+
+      <view class="form-card">
+        <view class="field">
+          <text class="field-label">手机号码</text>
+          <input class="field-input" type="number" :value="phoneDisplay" placeholder="请输入手机号" maxlength="13"
+            @input="handlePhoneInput" />
+        </view>
+
+        <button @click="handleLogin" class="primary-btn">获取验证码</button>
+
+        <view class="agreement-row" @click="toggleAgreement">
+          <view :class="['agreement-checkbox', { checked: agreementChecked }]">
+            <view class="checkbox-inner"></view>
+          </view>
+          <text class="agreement-text">
+            我已阅读并同意
+            <text class="link" @click.stop="handleUserAgrement">《用户协议》</text>
+            和
+            <text class="link" @click.stop="handlePrivacy">《隐私政策》</text>
+          </text>
         </view>
-      </view>
-      <view class="action-btn">
-        <button @click="handleLogin" class="login-btn cu-btn block bg-blue lg round">登录</button>
-      </view>
-      <view class="reg text-center" v-if="register">
-        <text class="text-grey1">没有账号?</text>
-        <text @click="handleUserRegister" class="text-blue">立即注册</text>
-      </view>
-      <view class="xieyi text-center">
-        <text class="text-grey1">登录即代表同意</text>
-        <text @click="handleUserAgrement" class="text-blue">《用户协议》</text>
-        <text @click="handlePrivacy" class="text-blue">《隐私协议》</text>
       </view>
     </view>
-     
   </view>
 </template>
 
 <script>
-  import { getCodeImg } from '@/api/login'
-  import { getToken } from '@/utils/auth'
-
-  export default {
-    data() {
-      return {
-        codeUrl: "",
-        captchaEnabled: true,
-        // 用户注册开关
-        register: false,
-        globalConfig: getApp().globalData.config,
-        loginForm: {
-          username: "admin",
-          password: "admin123",
-          code: "",
-          uuid: ""
-        }
+import { getCodeImg } from '@/api/login'
+import { getToken } from '@/utils/auth'
+
+export default {
+  data() {
+    return {
+      codeUrl: "",
+      captchaEnabled: true,
+      register: false,
+      agreementChecked: true,
+      phoneDisplay: "",
+      globalConfig: getApp().globalData.config,
+      loginForm: {
+        username: "",
+        password: "admin123",
+        code: "",
+        uuid: ""
+      }
+    }
+  },
+  created() {
+    this.getCode()
+  },
+  onLoad() {
+    //#ifdef H5
+    if (getToken()) {
+      this.$tab.reLaunch('/pages/index')
+    }
+    //#endif
+  },
+  methods: {
+    handlePhoneInput(e) {
+      const raw = (e.detail.value || '').replace(/\D/g, '').slice(0, 11)
+      this.loginForm.username = raw
+      if (raw.length > 7) {
+        this.phoneDisplay = raw.replace(/(\d{3})(\d{4})(\d{0,4})/, '$1 $2 $3').trim()
+      } else if (raw.length > 3) {
+        this.phoneDisplay = raw.replace(/(\d{3})(\d{0,4})/, '$1 $2').trim()
+      } else {
+        this.phoneDisplay = raw
       }
     },
-    created() {
-      this.getCode()
+    toggleAgreement() {
+      this.agreementChecked = !this.agreementChecked
     },
-    onLoad() {
-      //#ifdef H5
-      if (getToken()) {
-        this.$tab.reLaunch('/pages/index')
-      }
-      //#endif
+    handleUserRegister() {
+      this.$tab.redirectTo(`/pages/register`)
+    },
+    handlePrivacy() {
+      let site = this.globalConfig.appInfo.agreements[0]
+      this.$tab.navigateTo(`/pages/common/webview/index?title=${site.title}&url=${site.url}`)
+    },
+    handleUserAgrement() {
+      let site = this.globalConfig.appInfo.agreements[1]
+      this.$tab.navigateTo(`/pages/common/webview/index?title=${site.title}&url=${site.url}`)
     },
-    methods: {
-      // 用户注册
-      handleUserRegister() {
-        this.$tab.redirectTo(`/pages/register`)
-      },
-      // 隐私协议
-      handlePrivacy() {
-        let site = this.globalConfig.appInfo.agreements[0]
-        this.$tab.navigateTo(`/pages/common/webview/index?title=${site.title}&url=${site.url}`)
-      },
-      // 用户协议
-      handleUserAgrement() {
-        let site = this.globalConfig.appInfo.agreements[1]
-        this.$tab.navigateTo(`/pages/common/webview/index?title=${site.title}&url=${site.url}`)
-      },
-      // 获取图形验证码
-      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
-          }
-        })
-      },
-      // 登录方法
-      async handleLogin() {
-        if (this.loginForm.username === "") {
-          this.$modal.msgError("请输入账号")
-        } else if (this.loginForm.password === "") {
-          this.$modal.msgError("请输入密码")
-        } else if (this.loginForm.code === "" && this.captchaEnabled) {
-          this.$modal.msgError("请输入验证码")
-        } else {
-          this.$modal.loading("登录中,请耐心等待...")
-          this.pwdLogin()
+    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
         }
-      },
-      // 密码登录
-      async pwdLogin() {
-        this.$store.dispatch('Login', this.loginForm).then(() => {
-          this.$modal.closeLoading()
-          this.loginSuccess()
-        }).catch(() => {
-          if (this.captchaEnabled) {
-            this.getCode()
-          }
-        })
-      },
-      // 登录成功后,处理函数
-      loginSuccess(result) {
-        // 设置用户信息
-        this.$store.dispatch('GetInfo').then(res => {
-          this.$tab.reLaunch('/pages/index')
-        })
+      })
+    },
+    async handleLogin() {
+      if (!this.agreementChecked) {
+        this.$modal.msgError('请先阅读并同意相关协议')
+        return
+      }
+      if (!/^1\d{10}$/.test(this.loginForm.username)) {
+        this.$modal.msgError('请输入正确的手机号')
+        return
       }
+      this.$modal.loading('登录中,请耐心等待...')
+      this.pwdLogin()
+    },
+    async pwdLogin() {
+      this.$store.dispatch('Login', this.loginForm).then(() => {
+        this.$modal.closeLoading()
+        this.loginSuccess()
+      }).catch(() => {
+        this.$modal.closeLoading()
+        if (this.captchaEnabled) {
+          this.getCode()
+        }
+      })
+    },
+    loginSuccess() {
+      this.$store.dispatch('GetInfo').then(() => {
+        this.$tab.reLaunch('/pages/index')
+      })
     }
   }
+}
 </script>
 
 <style lang="scss" scoped>
-  page {
-    background-color: #ffffff;
-  }
+page {
+  background-color: #eaf3ff;
+}
 
-  .normal-login-container {
-    width: 100%;
+.login-page {
+  position: relative;
+  min-height: 100vh;
+  width: 100%;
+  overflow: hidden;
+  background: url('../static/login/login-bg.png') no-repeat center center;
+}
 
-    .logo-content {
-      width: 100%;
-      font-size: 21px;
-      text-align: center;
-      padding-top: 15%;
+.login-bg {
+  position: absolute;
+  right: 0;
+  top: 0;
+  width: 100%;
+  height: 100%;
+  z-index: 0;
+}
 
-      image {
-        border-radius: 4px;
-      }
+.login-hero {
+  position: absolute;
+  width: 360px;
+  height: 580px;
+  background: url('../static/login/login-illustration.png') no-repeat;
+  background-size: 100% 100%;
+  right: 0rpx;
+  top: 40rpx;
+}
 
-      .title {
-        margin-left: 10px;
-      }
-    }
+.login-content {
+  padding: 470rpx 40rpx 0;
+  display: flex;
+  flex-direction: column;
+  box-sizing: border-box;
+}
 
-    .login-form-content {
-      text-align: center;
-      margin: 20px auto;
-      margin-top: 15%;
-      width: 80%;
-
-      .input-item {
-        margin: 20px auto;
-        background-color: #f5f6f7;
-        height: 45px;
-        border-radius: 20px;
-
-        .icon {
-          font-size: 38rpx;
-          margin-left: 10px;
-          color: #999;
-        }
+.status-bar {
+  height: var(--status-bar-height, 0px);
+}
 
-        .input {
-          width: 100%;
-          font-size: 14px;
-          line-height: 20px;
-          text-align: left;
-          padding-left: 15px;
-        }
+.header {
+  display: flex;
+  flex-direction: column;
+}
 
-      }
+.header-title {
+  font-size: 50rpx;
+  font-weight: 600;
+  color: #19274b;
+  line-height: 1.2;
+}
 
-      .login-btn {
-        margin-top: 40px;
-        height: 45px;
-      }
-      
-      .reg {
-        margin-top: 15px;
-      }
-      
-      .xieyi {
-        color: #333;
-        margin-top: 20px;
-      }
-      
-      .login-code {
-        height: 38px;
-        float: right;
-      
-        .login-code-img {
-          height: 38px;
-          position: absolute;
-          margin-left: 10px;
-          width: 200rpx;
-        }
-      }
-    }
-  }
+.header-subtitle {
+  margin-top: 24rpx;
+  font-size: 26rpx;
+  color: rgba(25, 39, 75, 0.68);
+  line-height: 1.6;
+}
+
+.form-card {
+  z-index: 9;
+  margin-top: 160rpx;
+  width: 100%;
+  box-sizing: border-box;
+}
+
+.field {
+  width: 100%;
+  display: flex;
+  flex-direction: column;
+}
+
+.field-label {
+  font-size: 26rpx;
+  color: #151515;
+  font-size: 28rpx;
+  margin-bottom: 18rpx;
+}
+
+.field-input {
+  text-align: center;
+  width: 100%;
+  height: 102rpx;
+  border-radius: 28rpx;
+  background: rgba(255, 255, 255, 0.7);
+  border: 1px solid rgba(47, 94, 187, 0.08);
+  box-shadow: inset 0 4rpx 12rpx rgba(41, 94, 187, 0.06);
+  padding: 0 36rpx;
+  box-sizing: border-box;
+  font-size: 28rpx;
+  color: #AAA;
+  letter-spacing: 6rpx;
+}
+
+.field-input::placeholder {
+  color: #AAA;
+  letter-spacing: 6rpx;
+  opacity: 0.7;
+}
+
+.primary-btn {
+  margin-top: 44rpx;
+  width: 100%;
+  height: 100rpx;
+  border-radius: 28rpx;
+  background: linear-gradient(90deg, #3677E9 0%, #2856C7 100%);
+  color: #ffffff;
+  font-size: 28rpx;
+  font-weight: 500;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  border: none;
+  box-shadow: 0 20rpx 40rpx rgba(38, 104, 255, 0.35);
+}
+
+.agreement-row {
+  position: fixed;
+  bottom: 100rpx;
+  left: 0;
+  width: 100%;
+  box-sizing: border-box;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+
+.agreement-checkbox {
+  width: 30rpx;
+  height: 30rpx;
+  margin-right: 8rpx;
+  border-radius: 50%;
+  border: 1px solid rgba(35, 96, 255, 0.5);
+  background: rgba(250, 252, 255, 0.8);
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+
+.agreement-checkbox.checked {
+  background: linear-gradient(140deg, #3c7dff 0%, #235aff 100%);
+  border: none;
+}
+
+.checkbox-inner {
+  width: 16rpx;
+  height: 16rpx;
+  border-radius: 50%;
+  background: #ffffff;
+  opacity: 0;
+}
+
+.agreement-checkbox.checked .checkbox-inner {
+  opacity: 1;
+}
+
+.agreement-text {
+  font-size: 24rpx;
+  color: rgba(34, 52, 91, 0.75);
+  line-height: 1.5;
+}
 
+.agreement-text .link {
+  color: #2360ff;
+  margin: 0 6rpx;
+}
 </style>

BIN
static/login/login-bg.png


BIN
static/login/login-illustration.png