#
zjj
2025-04-03 2a4151ddaf5cbd3834362dc077e65cc7e020fb4f
pages/login/login.vue
@@ -1,211 +1,268 @@
  <template>
   <view class="zai-box">
        <scroll-view scroll-y class="page">
            <view class="text-center" :style="[{animation: 'show ' + 0.4+ 's 1'}]">
            <image src="../../static/logo.png" mode='aspectFit' class="zai-logo "></image>
            <view class="zai-title text-shadow ">Zoneyung</view>
<template>
   <view>
      <!-- 设置 -->
      <view class="settings">
         <view class="settings-btn">
            <uni-icons type="gear" size="30" color="#707070" @click="settings"></uni-icons>
         </view>
            <view class="box padding-lr-xl login-paddingtop" :style="[{animation: 'show ' + 0.6+ 's 1'}]">
            <block v-if="loginWay==1">
               <view class="cu-form-group margin-top  shadow-warp" :class="[shape=='round'?'round':'']">
                  <view class="title"><text class="cuIcon-people margin-right-xs"></text>账号:</view>
                  <input placeholder="请输入账号" name="input" v-model="userName"></input>
               </view>
               <view class="cu-form-group margin-top shadow-warp" :class="[shape=='round'?'round':'']">
                  <view class="title"><text class="cuIcon-lock margin-right-xs"></text>密码:</view>
                  <input class="uni-input" placeholder="请输入密码" :password="!showPassword" v-model="password" />
                  <view class="action text-lg">
                      <text :class="[showPassword ? 'cuIcon-attention' : 'cuIcon-attentionforbid']" @click="changePassword"></text>
                  </view>
               </view>
               <view class="changeBox">
                  <checkbox-group class="rember">
                     <label>
                        <checkbox value="cb" :checked="rember"  @tap="rember = !rember" style="transform:scale(0.7)" /><text>记住密码</text>
                     </label>
                  </checkbox-group>
                  <text class="changeIP" @click="changeIP()">设置IP</text>
               </view>
               <view class="padding text-center margin-top">
                  <button class="cu-btn bg-blue lg margin-right shadow" :loading="loading" :class="[shape=='round'?'round':'']"
                     @tap="onLogin"><text space="emsp">{{loading ? "登录中...":" 登录 "}}</text>
                  </button>
               </view>
            </block>
            <!-- #ifdef APP-PLUS -->
            <view class="padding flex flex-direction  text-center">
               当前版本:{{version}}
            </view>
            <!-- #endif -->
            </view>
        </scroll-view>
      <!-- 登录加载弹窗 -->
      <view class="cu-load load-modal" v-if="loading">
         <!-- <view class="cuIcon-emojifill text-orange"></view> -->
         <image src="../../static/logo1.png" mode="aspectFit" class="round"></image>
         <view class="gray-text">登录中...</view>
      </view>
      <!-- logo -->
      <view class="logo">
         <view class="logo-box">
            <image src="../../static/img/zy_logo.png" mode="aspectFit"></image>
         </view>
      </view>
      <view class="content">
         <!-- 账号 -->
         <view class="box shadow-warp">
            <view class="box-icon">
               <uni-icons type="person" size="20" color="#707070"></uni-icons>
            </view>
            <view class="box-text">账号:</view>
            <view class="box-input">
               <input type="text" placeholder="请输入账号" v-model="user.userName"
               placeholder-style="font-size:14px;color:#ccc;">
            </view>
            <view class="box-show"></view>
         </view>
         <!-- 密码 -->
         <view class="box shadow-warp">
            <view class="box-icon">
               <uni-icons type="locked" size="20" color="#707070"></uni-icons>
            </view>
            <view class="box-text">密码:</view>
            <view class="box-input">
               <input :password="!showPassword" placeholder="请输入密码" v-model="user.password"
               placeholder-style="font-size:14px;color:#ccc;" >
            </view>
            <view class="box-show">
               <uni-icons type="eye-filled" size="20" color="#707070" v-if="!showPassword" @click="changePassword"></uni-icons>
               <uni-icons type="eye" size="20" color="#707070" v-if="showPassword" @click="changePassword"></uni-icons>
            </view>
         </view>
         <!-- 记住密码 -->
         <view class="check">
            <view class="check-left">
               <view>记住密码</view>
            </view>
            <view class="check-right">
               <switch :checked='remberPassword' color="#FFCC33" style="zoom:.5" @change="remberChange"/>
            </view>
         </view>
      </view>
      <!-- 登录按钮 -->
      <view class="submit">
         <view class="" style="width: 400rpx;">
            <button type="primary" @click="onLogin()" :loading="load.loading">{{load.btnText}}</button>
         </view>
      </view>
      <!-- 设置弹窗区域 -->
      <view>
         <!-- 输入框示例 -->
         <uni-popup ref="inputDialog" type="dialog">
            <uni-popup-dialog ref="inputClose" mode="input" title="请输入IP" v-model="IP"
               placeholder="请输入IP" @confirm="dialogInputConfirm">
            </uni-popup-dialog>
            <view class="popup">
               <!-- 标题 -->
               <view class="title">配置</view>
               <view class="popup-item">
                  <view class="popup-item-left">IP:</view>
                  <view class="popup-item-right"><input type="text" v-model="url.ip"></view>
               </view>
               <view class="popup-item">
                  <view class="popup-item-left">端口:</view>
                  <view class="popup-item-right"><input type="text" v-model="url.port"></view>
               </view>
               <view class="popup-item">
                  <view class="popup-item-left">项目:</view>
                  <view class="popup-item-right"><input type="text" v-model="url.project"></view>
               </view>
               <view class="btn">
                  <view class="btn-left" @click="close">取消</view>
                  <view class="btn-right" @click="settingConfirm">确认</view>
               </view>
            </view>
         </uni-popup>
      </view>
    </view>
      <view>
         <!-- 提示窗示例 -->
         <uni-popup ref="upVersion" type="dialog">
            <uni-popup-dialog :type="msgType" title="通知" :content="dialogContent" @confirm="dialogConfirm"
               @close="dialogClose"></uni-popup-dialog>
         </uni-popup>
      </view>
      <!-- 版本号 -->
      <!-- #ifdef APP-PLUS -->
      <view class="version">
         当前版本:{{version}}
      </view>
      <!-- #endif -->
   </view>
</template>
<script>
   // import { ACCESS_TOKEN,USER_NAME,USER_INFO } from "@/common/util/constants"
   import { mapActions } from "vuex"
   import md5 from '../../common/md5.js'
    // import configService from '@/common/service/config.service.js';
    export default {
        data() {
            return {
            shape:'',//round 圆形
            loading: false,
            phoneNo: '',
            smsCode: '',
            showPassword: false, //是否显示明文
            loginWay: 1, //1: 账密,2:验证码
            smsCountDown: 0,
            smsCountInterval: null,
            toggleDelay: false,
            version:'',
            //第三方登录相关信息
            thirdType:"",
            thirdLoginInfo:"",
            thirdLoginState:false,
            bindingPhoneModal:false,
            thirdUserUuid:'',
   import md5 from '../../static/js/md5.js'
   export default {
      data() {
         return {
            version: '',
            showPassword: false,
            value: '',
            remberPassword: true,
            url: {
               bindingThirdPhone: '/sys/thirdLogin/bindingThirdPhone'
               ip: '',
               port: '',
               project: ''
            },
            type:'',
            userName:'',
            password:'',
            rember:true,
            IP:'',
            };
        },
      mounted() {
         let that = this;
         //缓存的账号
         const HCuname = uni.getStorageSync('HCuname');
         //缓存的密码
         const HCpassw = uni.getStorageSync('HCpassw');
         //有缓存就赋值给文本没有就清空
         if (HCuname && HCpassw) {
             that.userName = HCuname;
             that.password = HCpassw;
         } else {
             that.userName = '';
             that.password = '';
            baseUrl: '',
            user: {
               userName: '',
               password: '',
            },
            load: {
               loading: false,
               btnText: '登录'
            },
            msgType: 'success',
            filename: '',
            dialogContent: ''
         }
         const UIP = uni.getStorageSync('UIP');
            if (UIP) {
             that.IP = UIP;
            that.baseIP = UIP;
            } else {
             that.IP = '';
            }
      },
      onLoad:function(){
         // #ifdef APP-PLUS
         var that=this
         plus.runtime.getProperty( plus.runtime.appid, function ( wgtinfo ) {
            that.version=wgtinfo.version
         });
         // #endif
      onLoad() {
         this.user = uni.getStorageSync('user')
         this.url = uni.getStorageSync('url')
         this.baseUrl = uni.getStorageSync('baseUrl')
         if (!this.user) {
            this.user = {userName: '',password: ''}
         }
         if (!this.url) {
            this.url = {ip: '',port: '',project: ''}
         }
      },
      computed: {
            isSendSMSEnable() {
              return this.smsCountDown <= 0 && this.phoneNo.length > 4;
            },
            getSendBtnText() {
              if (this.smsCountDown > 0) {
                return this.smsCountDown + '秒后发送';
              } else {
                return '发送验证码';
              }
            },
            canSMSLogin() {
              return this.userName.length > 4 && this.smsCode.length > 4;
            },
            canPwdLogin() {
              return this.userName.length > 4 && this.password.length > 4;
            },
      onShow () {
         this.getVersion()
      },
        methods: {
         changeIP(){
      methods: {
         // 显示/隐藏密码
         changePassword() {
            this.showPassword = !this.showPassword;
         },
         remberChange(e) {
            this.remberPassword = !this.remberPassword
         },
         // 设置窗口开启按钮
         settings() {
            this.$refs.inputDialog.open()
         },
         dialogInputConfirm(type){
            this.baseIP = type
            // 存入本地缓存
            uni.setStorageSync('UIP',this.baseIP)
            },
         checkboxChange: function(e) {
             if (e.detail.value.length == 1) {
                 //获取缓存的账号
                  uni.getStorageSync('HCuname',this.userName);
                  uni.getStorageSync('HCpassw',this.password);
             } else {
                   uni.removeStorageSync('HCuname');
                   uni.removeStorageSync('HCpassw');
             }
         // 设置窗口确认修改按钮
         dialogInputConfirm() {
            this.$refs.inputDialog.close()
         },
         onLogin: function (){
            if(!this.userName || this.userName.length==0){
               uni.showToast({title: '请填写账号',icon: "none"})
               return;
            }
            if(!this.password || this.password.length==0){
               uni.showToast({title: '请填写密码',icon: "none"})
               return;
            }
            uni.showLoading();
         // 设置窗口关闭按钮
         close() {
            this.$refs.inputDialog.close()
         },
         // 保存ip
         settingConfirm() {
            this.baseUrl = "http://" + this.url.ip + ':' + this.url.port + '/' + this.url.project
            uni.setStorageSync('baseUrl', this.baseUrl);
            uni.setStorageSync('url', this.url);
            this.$refs.inputDialog.close()
         },
         onLogin() {
            let that = this
            uni.request({
                url: this.baseHttp + this.baseIP + this.baseUrl + '/login.action',
                data: {
                  mobile:this.userName,
                  password:md5.hex_md5(this.password)
                },
                header: {
               url: that.baseUrl + '/login.action',
               fail(result) {
                  uni.showToast({
                     icon: 'error',
                     title: '请求失败'
                  })
               },
               data: {
                  username: that.user.userName,
                  password: md5.hex_md5(that.user.password)
               },
               header: {
                  "content-type": "application/json"
                },
                success: (result) => {
                  let res = result.data;
                  uni.hideLoading();
                  if (res.code == 200) {
               },
               success(result) {
                  if (result.statusCode === 404) {
                     uni.showToast({
                        title: '登录成功',
                        position: 'bottom',
                        duration: 1000
                     });
                     if(this.rember){
                        uni.setStorageSync('HCuname', this.userName);
                        uni.setStorageSync('HCpassw', this.password);
                     }else{
                        uni.removeStorageSync('HCuname');
                        uni.removeStorageSync('HCpassw');
                     }
                        title: '登录失败',
                        icon: "error"
                     })
                     return
                  }
                  let res = result.data
                  if (res.code === 200) {
                     that.load.loading = true;
                     that.load.btnText = '登录中';
                     uni.setStorageSync('token', res.data.token);
                     if(that.remberPassword){
                        uni.setStorageSync('user', that.user);
                     }else{
                        uni.removeStorageSync('user');
                     }
                     setTimeout(() => {
                        uni.navigateBack();      //   小程序用这个  把首页路由放第一个
                        uni.reLaunch({
                           url: '../index/index'
                        });
                     }, 1000);
                        uni.showToast({
                           title: '登录成功'
                        })
                        setTimeout(() => {
                           uni.reLaunch({
                              url: '../home/home'
                           });
                        }, 300)
                     }, 700)
                  } else {
                     uni.showToast({
                        title: res.msg
                     })
                  }
               },
            })
         },
         //检测当前平台,如果是安卓则启动安卓更新
         getVersion() {
            let that = this;
            uni.getSystemInfo({
               success: (res) => {
                  if (res.platform == "android") {
                     that.AndroidCheckUpdate();
                  }
               }
            })
         },
         // 获取当前版本号
         AndroidCheckUpdate() {
            let that = this;
            plus.runtime.getProperty(plus.runtime.appid, (wgtinfo) => {
               that.version = wgtinfo.version //客户端版本号
            })
            setTimeout(()=>{
               that.getUpdateVersion()
            },100)
         },
         // 校验版本
         getUpdateVersion() {
            let that = this
            let type = 0
            if (that.baseUrl == 'http://undefined:undefined/undefined') {
               return
            }
            let url = that.baseUrl + '/appVersion/checkUpdate/' + that.version + '/' + type
            uni.request({
               url: url,
               method: 'GET',
               success(res) {
                  console.log(res);
                  var res = res.data
                  if (res.data) {
                     that.filename = res.data.path
                     that.dialogContent = '发现新版本:' + res.data.version + ', 是否立即更新'
                     that.$refs.upVersion.open()
                  } else {
                     uni.showToast({
                        title: res.msg,
@@ -214,99 +271,205 @@
                     })
                  }
                  
                }
            });
         },
         saveClientId(){
            var info = plus.push.getClientInfo();
            var cid = info.clientid;
            this.$http.get("/sys/user/saveClientId",{params:{clientId:cid}}).then(res=>{
               this.$tip.success('登录成功!')
               this.$Router.replaceAll({name:'index'})
               }
            })
         },
         changePassword() {
            this.showPassword = !this.showPassword;
         dialogConfirm() {
            this.$refs.upVersion.close()
            this.downWgt()
         },
         loginSuccess() {
           // 登陆成功,重定向到主页
           this.$Router.replace({name:'index'})
         dialogClose() {
            this.$refs.upVersion.close()
         },
         requestFailed(err) {
           this.$message.warning("登录失败")
         downWgt() {
            let that = this;
            const downloadUrl = that.baseUrl + "/appVersion/downloadApp/" + that.filename
            uni.showLoading({
               title: '更新中……'
            })
            const downloadTask = uni.downloadFile({ //执行下载
               url: downloadUrl, //下载地址
               timeout: 1000 * 30, //30秒超时时间
               success: downloadResult => { //下载成功
                  console.log(downloadResult);
                  that.showdownLine = false
                  uni.hideLoading();
                  if (downloadResult.statusCode == 200) {
                     uni.showModal({
                        title: '',
                        content: '更新成功,确定现在重启吗?',
                        confirmText: '重启',
                        confirmColor: '#EE8F57',
                        success: function(res) {
                           if (res.confirm == true) {
                              plus.runtime.install( //安装
                                 downloadResult.tempFilePath, {
                                    force: true
                                 },
                                 function(res) {
                                    utils.showToast('更新成功,重启中');
                                    plus.runtime.restart();
                                 }
                              );
                           }
                        }
                     });
                  } else {
                     uni.hideLoading();
                     that.showdownLine = false
                     uni.showToast({
                        title:'请先上传安装包',
                        icon: 'error'
                     })
                  }
               },
               fail: err => {
                  uni.hideLoading();
                  that.showdownLine = false
                  that.$u.toast(downloadResult.errMsg)
               },
               complete: com => {
                  console.log(com)
               }
            });
            // 下载进度
            downloadTask.onProgressUpdate(res => {
               that.downloadNum = res.progress
               console.log('下载进度' + that.downloadNum);
            });
         },
        },
      beforeDestroy() {
          if (this.smsCountInterval) {
              clearInterval(this.smsCountInterval);
          }
      },
    }
      }
   }
</script>
<style>
   @import "../../colorui/main.css";
   @import "../../colorui/icon.css";
   @import "../../colorui/animation.css";
    .login-paddingtop {
        padding-top: 50upx;
    }
    .zai-box {
        padding: 0 20upx;
        padding-top: 100upx;
        position: relative;
    }
    .zai-logo {
        width: 200upx;
        height: 150px;
    }
    .zai-title {
       font-size: 58upx;
       color: #000000;
       text-align: center;
    }
    .input-placeholder, .zai-input {
        color: #94afce;
    }
    .zai-label {
        padding: 60upx 0;
        text-align: center;
        font-size: 30upx;
        color: #a7b6d0;
    }
    .zai-btn {
        background: #ff65a3;
        color: #fff;
        border: 0;
        border-radius: 100upx;
        font-size: 36upx;
    }
    .zai-btn:after {
        border: 0;
    }
    /*按钮点击效果*/
    .zai-btn.button-hover {
        transform: translate(1upx, 1upx);
    }
   .changeBox {
      margin-top: 20upx;
   @import url('../../static/css/wms.css/wms.css');
   /* 设置区域 */
   .settings {
      min-height: 100rpx;
   }
   .rember {
      display: inline-block;
   }
   .changeIP {
   .settings-btn {
      float: right;
      margin-right: 15upx;
      margin-right: 10rpx;
   }
</style>
   .logo {
      height: 25%;
      width: 100%;
      display: flex;
      justify-content: center;
   }
   .logo-box {
      margin: auto 0;
   }
   image {
      height: 300rpx;
   }
   /* 输入框区域 */
   .content {
      min-height: 250rpx;
      /* background-color: coral; */
      width: 100%;
      display: flex;
      flex-direction: column;
      align-items: center;
      color: #606266;
   }
   .box {
      width: 80%;
      height: 100rpx;
      margin-top: 30rpx;
      background-color: white;
      display: flex;
      font-size: 14px;
      align-items: center;
   }
   .box-icon {
      width: 80rpx;
      text-align: center;
   }
   .box-text {
      width: 100rpx;
      text-align: center;
   }
   .box-show {
      margin-left: auto;
      /* margin-right: 10rpx; */
      width: 60rpx;
      text-align: center;
   }
   input {
      padding-left: 10rpx;
      font-size: 14px;
      color: #303133;
   }
   .check {
      width: 78%;
      display: flex;
      font-size: 12px;
      color: #606266;
      margin-top: 10rpx;
   }
   .check-right {
      margin-left: auto;
   }
   .submit {
      display: flex;
      justify-content: center;
      position: fixed;
      width: 100%;
      bottom: 100rpx;
   }
   .version {
      position: fixed;
      width: 100%;
      bottom: 0;
      text-align: center;
      font-size: 12px;
      color: #909399;
   }
   /* ------ */
   .shadow-warp {
      position: relative;
      box-shadow: 0 0 10upx rgba(0, 0, 0, 0.1);
   }
   .shadow-warp:before,
   .shadow-warp:after {
      position: absolute;
      content: "";
      top: 20upx;
      bottom: 30upx;
      left: 20upx;
      width: 50%;
      box-shadow: 0 30upx 20upx rgba(0, 0, 0, 0.2);
      transform: rotate(-3deg);
      z-index: -1;
   }
   .shadow-warp:after {
      right: 20upx;
      left: auto;
      transform: rotate(3deg);
   }
</style>