管灌系统农户端微信小程序(嘉峪关应用)
pages/login/login.js
@@ -1,4 +1,8 @@
const app = getApp();
const storage = require('../../utils/storage.js');
const {
  post
} = require('../../api/request.js');
Page({
@@ -6,79 +10,239 @@
   * 页面的初始数据
   */
  data: {
    mobile: '',
    code: '',
    codeSent: false,
    countdown: 60,
    phone: '',
    verificationCode: '',
    codeText: '获取验证码',
    counting: false,
    countDown: 60,
    projectName: '嘉峪关项目', // 默认项目名称
    selectedProject: 'JYG', // 默认项目代码
    showErrorDialog: false,
    fromBack: false,  // 标记是否是从返回按钮返回的
    manualNavigate: false // 标记是否是通过编程方式导航的
  },
  bindMobileInput: function (e) {
  /**
   * 绑定手机号输入
   */
  bindPhoneInput: function (e) {
    this.setData({
      mobile: e.detail.value,
      phone: e.detail.value
    });
  },
  sendCode: function () {
    if (!this.data.mobile) {
  /**
   * 绑定验证码输入
   */
  bindCodeInput: function (e) {
    this.setData({
      verificationCode: e.detail.value
    });
  },
  /**
   * 发送验证码
   */
  sendVerificationCode: function () {
    const {
      phone,
      counting
    } = this.data;
    // 如果正在倒计时,则不允许再次发送
    if (counting) {
      return;
    }
    // 验证手机号格式
    if (!/^1\d{10}$/.test(phone)) {
      wx.showToast({
        title: '请输入手机号',
        icon: 'none',
        duration: 2000,
        title: '请输入正确的手机号',
        icon: 'none'
      });
      return;
    }
    // 在这里处理发送验证码的逻辑,可以调用后台接口实现
    // 以下是一个简单的示例,仅作参考
    wx.showToast({
      title: '验证码已发送',
      icon: 'success',
      duration: 2000,
    });
    this.setData({
      codeSent: true,
    });
    // 启动倒计时
    this.startCountdown();
    // 发送验证码请求
    this.postCode();
  },
  //倒计时
  startCountdown: function () {
    let that = this;
    let timer = setInterval(function () {
      let countdown = that.data.countdown - 1;
      that.setData({
        countdown: countdown,
      });
      if (countdown <= 0) {
  /**
   * 开始倒计时
   */
  startCountDown: function () {
    this.setData({
      counting: true,
      countDown: 60
    });
    const timer = setInterval(() => {
      if (this.data.countDown <= 1) {
        clearInterval(timer);
        that.setData({
          codeSent: false,
          countdown: 60,
        this.setData({
          counting: false,
          codeText: '获取验证码'
        });
      } else {
        this.setData({
          countDown: this.data.countDown - 1,
          codeText: `${this.data.countDown - 1}秒后重发`
        });
      }
    }, 1000);
    // 保存timer引用,以便在页面卸载时清除
    this.countDownTimer = timer;
  },
  /**
   * 停止倒计时
   */
  stopCountDown: function () {
    if (this.countDownTimer) {
      clearInterval(this.countDownTimer);
    }
    this.setData({
      counting: false,
      codeText: '获取验证码'
    });
  },
  /**
   * 登录
   */
  login: function (e) {
    console.log("login")
    let userName = "张三"
    wx.navigateTo({
      url: '/pages/wxbind/wxbind'
    })
  login: function () {
    const {
      phone,
      verificationCode
    } = this.data;
    // 验证手机号和验证码
    if (!/^1\d{10}$/.test(phone)) {
      wx.showToast({
        title: '请输入正确的手机号',
        icon: 'none'
      });
      return;
    }
    if (!/^\d{6}$/.test(verificationCode)) {
      wx.showToast({
        title: '请输入6位验证码',
        icon: 'none'
      });
      return;
    }
    // 显示加载中
    wx.showLoading({
      title: '登录中...',
      mask: true
    });
    // 标记为手动导航,确保不会触发返回逻辑
    console.log('登录按钮点击,设置manualNavigate=true');
    this.setData({
      manualNavigate: true
    });
    this.wsLogin();
  },
  /**
   * 跳转到注册页面
   */
  goToRegister: function () {
    wx.showToast({
      title: '注册功能暂未开放',
      icon: 'none',
      duration: 2000
    });
  },
  /**
   * 跳转到忘记密码页面
   */
  goToForgetPassword: function () {
    wx.showToast({
      title: '找回密码功能暂未开放',
      icon: 'none',
      duration: 2000
    });
  },
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad(options) {
  onLoad: function (options) {
    console.log('login页面加载,options:', options);
    // 设置页面数据
    this.setData({
      fromBack: false,  // 标记是否是从返回按钮返回的
      manualNavigate: false // 标记是否是通过编程方式导航的
    });
    // 获取选择的项目 - 优先使用URL参数
    if (options && options.project) {
      const project = options.project;
      const projectName = project === 'JYG' ? '嘉峪关项目' :
                         project === 'MQ' ? '民勤项目' :
                         project === 'TEST' ? '测试项目' : '未知项目';
      console.log(`从URL参数获取项目信息: ${project} (${projectName})`);
      this.setData({
        selectedProject: project,
        projectName: projectName
      });
      // 同步更新全局项目设置
      if (getApp().globalData) {
        getApp().globalData.selectedProject = project;
        // 设置对应的tag
        if (project === 'JYG') {
          getApp().globalData.tag = 'ym';
        } else if (project === 'MQ') {
          getApp().globalData.tag = 'mq';
        }
        // 更新 BASEURL
        try {
          const { PROJECT_URLS } = require('../../api/config.js');
          getApp().globalData.baseUrl = PROJECT_URLS[project];
        } catch (e) {
          console.error('设置baseUrl失败:', e);
        }
      }
      // 保存项目选择到本地存储,确保项目信息一致
      storage.setItem('selectedProject', project)
        .then(() => console.log('成功保存项目选择到存储'))
        .catch(err => console.error('保存项目选择到存储失败:', err));
    } else {
      // 从本地存储获取已选择的项目
      storage.getItemSafe('selectedProject').then(project => {
        if (project) {
          const projectName = project === 'JYG' ? '嘉峪关项目' :
                            project === 'MQ' ? '民勤项目' :
                            project === 'TEST' ? '测试项目' : '未知项目';
          console.log(`从存储获取项目信息: ${project} (${projectName})`);
          this.setData({
            selectedProject: project,
            projectName: projectName
          });
        } else {
          console.log('未找到已选择的项目,使用默认项目');
        }
      }).catch(err => {
        console.error('获取已选择项目失败:', err);
      });
    }
  },
  /**
@@ -99,14 +263,104 @@
   * 生命周期函数--监听页面隐藏
   */
  onHide() {
    // 如果不是通过编程方式导航,则可能是点击了返回按钮
    // 注意:在某些情况下,微信可能会直接调用onUnload而跳过onHide
    if (!this.data.manualNavigate) {
      console.log('页面隐藏,可能是点击了返回按钮');
      this.setData({
        fromBack: true
      });
      // 如果页面隐藏但未登录,记录一个时间戳,帮助识别是否是返回操作
      if (!getApp().globalData.isLoggedIn) {
        this.hideTimestamp = Date.now();
      }
    } else {
      console.log('页面隐藏,是通过代码导航的');
    }
  },
  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload() {
    // 清除验证码倒计时定时器
    if (this.countDownTimer) {
      clearInterval(this.countDownTimer);
      this.countDownTimer = null;
    }
    // 记录退出登录页面的情况
    console.log('登录页面卸载,fromBack:', this.data.fromBack, 'manualNavigate:', this.data.manualNavigate, '登录状态:', !!getApp().globalData.isLoggedIn);
    // 如果是登录成功,不执行返回逻辑
    if (getApp().globalData.isLoggedIn) {
      console.log('用户已登录,无需执行返回逻辑');
      return;
    }
    // 检查是否是通过编程方式明确设置了导航
    // 如果没有明确设置,就假定是返回操作
    if (!this.data.manualNavigate) {
      console.log('页面卸载时未设置manualNavigate,假定是返回按钮操作');
      // 尝试使用wx.navigateBack返回上一页(如果可行)
      const pages = getCurrentPages();
      if (pages.length > 1) {
        console.log('检测到有上一页,使用navigateBack返回');
        wx.navigateBack({
          delta: 1,
          success: () => console.log('navigateBack成功'),
          fail: (err) => {
            console.error('navigateBack失败:', err);
            // 如果navigateBack失败,尝试reLaunch
            this.backupReturnToHome();
          }
        });
      } else {
        console.log('无上一页,使用备用返回方式');
        // 没有上一页,使用备用方法
        this.backupReturnToHome();
      }
    } else {
      console.log('通过编程方式离开登录页面');
    }
  },
  // 备用的返回首页方法
  backupReturnToHome() {
    console.log('使用备用方法返回首页');
    // 尝试使用switchTab(如果首页在tabBar中)
    const useReLaunch = () => {
      console.log('使用reLaunch返回首页');
      wx.reLaunch({
        url: '/pages/home/home?fromLogin=true',
        success: () => console.log('reLaunch成功返回首页'),
        fail: (err) => {
          console.error('reLaunch返回首页失败:', err);
          // 最后的备用方案:使用redirectTo
          setTimeout(() => {
            console.log('延迟使用redirectTo尝试返回首页');
            wx.redirectTo({
              url: '/pages/home/home?fromLogin=true',
              success: () => console.log('redirectTo成功返回首页'),
              fail: (err) => console.error('所有返回方法都失败:', err)
            });
          }, 100);
        }
      });
    };
    // 先尝试使用switchTab(某些版本可能将首页设置为tabBar)
    wx.switchTab({
      url: '/pages/home/home',
      success: () => console.log('switchTab成功返回首页'),
      fail: (err) => {
        console.log('switchTab失败(可能首页不在tabBar中):', err);
        useReLaunch();
      }
    });
  },
  /**
@@ -129,7 +383,179 @@
  onShareAppMessage() {
  },
  //获取验证码
  postCode: function () {
    const params = {
      url: 'wx/client/send_sms?phoneNumber=' + this.data.phone
    };
    post(params)
      .then((data) => {
        wx.showToast({
          title: '验证码已发送',
          icon: 'success',
          duration: 2000,
        });
        this.setData({
          codeSent: true,
        });
    // 开始倒计时
    this.startCountDown();
      })
      .catch((error) => {
        wx.showToast({
          title: error.msg,
          icon: 'none'
        });
        console.error('Failed to add item:', error);
      });
  },
  wsLogin() {
    // 标记为手动导航
    console.log('wsLogin调用,设置manualNavigate=true');
    this.setData({
      manualNavigate: true
    });
    wx.login({
      success: res => {
        if (res.code) {
          console.log('微信登录成功,获取到的code:', res.code);
          // 发送 res.code 到后台服务器换取 openId, sessionKey, unionId
          this.verify(res.code)
        } else {
          console.log('微信登录失败!' + res.errMsg);
          // 登录失败时重置状态
          this.setData({
            manualNavigate: false
          });
        }
      },
      fail: err => {
        console.error('微信登录API调用失败:', err);
        // 登录失败,重置导航标记
        this.setData({
          manualNavigate: false
        });
      }
    });
  },
  //用户绑定
  verify(wxCode) {
    console.log('verify调用,确认manualNavigate=', this.data.manualNavigate);
    const params = {
      url: 'wx/client/verify',
      data: {
        phoneNumber: this.data.phone,
        securityCode: this.data.verificationCode,
        code: wxCode
      }
    };
    post(params)
      .then((data) => {
        wx.hideLoading();
        console.log('验证成功,准备保存用户数据');
        // 确保全局对象已初始化
        if (!getApp().globalData) {
          getApp().globalData = {};
        }
        // 保存会话ID和客户端ID
        getApp().globalData.sessionId = String(data.content.sessionId);
        storage.setItem("sessionId", String(data.content.sessionId));
        getApp().globalData.clientId = String(data.content.clientId);
        storage.setItem("clientId", String(data.content.clientId));
        // 设置当前项目的tag
        const tag = this.data.selectedProject === 'JYG' ? 'ym' :
                   this.data.selectedProject === 'MQ' ? 'mq' :
                   this.data.selectedProject === 'TEST' ? 'test' : 'unknown';
        getApp().globalData.tag = tag;
        // 保存用户信息
        const userInfo = {
          sessionId: String(data.content.sessionId),
          clientId: String(data.content.clientId),
          phone: this.data.phone,
          token: data.content.token || '',
          project: this.data.selectedProject,
          tag: tag
        };
        // 保存到全局变量
        getApp().globalData.userInfo = userInfo;
        getApp().globalData.isLoggedIn = true;
        // 保存到本地存储
        storage.setItem("userInfo", JSON.stringify(userInfo))
          .then(() => {
            console.log('用户信息保存成功');
            return storage.setItem("isLoggedIn", "true");
          })
          .then(() => {
            // 保存userData信息,包含sessionId和tag
            const userData = JSON.stringify({
              sessionId: String(data.content.sessionId),
              tag: tag
            });
            return storage.setItem("userData", userData);
          })
          .then(() => {
            console.log('登录状态和项目信息保存成功');
            this.bindSuccess();
          })
          .catch(err => {
            console.warn('保存用户信息过程中出错,但不影响继续操作:', err);
            this.bindSuccess();
          });
      })
      .catch((error) => {
        wx.hideLoading();
        console.error('验证请求失败:', error);
        // 验证失败,需要重置导航标记
        console.log('验证失败,重置manualNavigate=false');
        this.setData({
          manualNavigate: false
        });
        wx.showToast({
          title: error.msg || '验证失败',
          icon: 'error',
          duration: 3000,
        });
      });
  },
  bindSuccess: function () {
    // 设置标记,表示通过编程方式导航
    console.log('绑定成功,最终确认manualNavigate=true');
    this.setData({
      manualNavigate: true,
      fromBack: false // 确保不会被识别为返回操作
    });
    // 设置全局登录状态
    getApp().globalData.isLoggedIn = true;
    wx.showToast({
      title: '绑定成功',
      icon: 'success',
      duration: 1500,
      mask: true,
      success: () => {
        // 延迟跳转,确保Toast显示完成
        setTimeout(() => {
          console.log('登录成功,准备跳转到首页');
          // 跳转到首页,使用reLaunch而不是redirectTo
          wx.redirectTo({
            url: '/pages/home/home'
          });
        }, 1500);
      }
    });
  },
})