From cfe0b79fbea0fb1d7a5a796e71ada7d3b7812046 Mon Sep 17 00:00:00 2001
From: wlzboy <66905212@qq.com>
Date: 星期一, 15 十二月 2025 22:31:33 +0800
Subject: [PATCH] feat: 企业微信发送微信小程序cetd
---
app/pages/login.vue | 496 +++++++++++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 446 insertions(+), 50 deletions(-)
diff --git a/app/pages/login.vue b/app/pages/login.vue
index 7f0e8c8..e30db61 100644
--- a/app/pages/login.vue
+++ b/app/pages/login.vue
@@ -1,9 +1,9 @@
<template>
- <view class="normal-login-container">
+ <scroll-view class="normal-login-container" scroll-y="true">
<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>
+ <text class="title">姘戣埅璋冨害绯荤粺</text>
</view>
<view class="login-form-content">
<view class="input-item flex align-center">
@@ -14,32 +14,57 @@
<view class="iconfont icon-password icon"></view>
<input v-model="loginForm.password" type="password" class="input" placeholder="璇疯緭鍏ュ瘑鐮�" maxlength="20" />
</view>
- <view class="input-item flex align-center" style="width: 60%;margin: 0px;" v-if="captchaEnabled">
+ <view class="input-item flex align-center captcha-container" 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>
+ <image :src="codeUrl" @click="getCode" class="login-code-img" mode="aspectFit"></image>
</view>
</view>
+ <view class="agreement-checkbox">
+ <checkbox-group @change="onAgreementChange">
+ <label class="checkbox-label">
+ <checkbox :checked="agreedToPolicy" value="agreed" color="#007AFF" class="round-checkbox" style="margin-top: 0;" />
+ <text class="agreement-text">
+ <text class="text-grey1">鍚屾剰</text>
+ <text @click.stop="handleUserAgrement" class="text-blue agreement-link">銆婄敤鎴峰崗璁��</text>
+ <text class="text-grey1">鍜�</text>
+ <text @click.stop="handlePrivacy" class="text-blue agreement-link">銆婇殣绉佹斂绛栥��</text>
+ </text>
+ </label>
+ </checkbox-group>
+ </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>
+ <!-- 寰俊涓�閿櫥褰曟寜閽�(浠呭湪寰俊灏忕▼搴忕幆澧冩樉绀�) -->
+ <!-- #ifdef MP-WEIXIN -->
+ <button
+ v-if="isWechat && wechatOpenId"
+ @click="loginByOpenId"
+ class="wechat-login-btn cu-btn block bg-green lg round"
+ style="margin-top: 20rpx;">
+ <text class="cuIcon-wechat" style="margin-right: 10rpx;"></text>
+ 鎵嬫満鍙风爜蹇嵎鐧诲綍
+ </button>
+ <button
+ v-else-if="isWechat"
+ open-type="getPhoneNumber"
+ @getphonenumber="onGetPhoneNumber"
+ class="wechat-login-btn cu-btn block bg-green lg round"
+ style="margin-top: 20rpx;">
+ <text class="cuIcon-wechat" style="margin-right: 10rpx;"></text>
+ 鎵嬫満鍙风爜蹇嵎鐧诲綍
+ </button>
+ <!-- #endif -->
</view>
</view>
-
- </view>
+ </scroll-view>
</template>
<script>
- import { getCodeImg } from '@/api/login'
+ import { getCodeImg, loginByOpenId, loginByWechatPhone } from '@/api/login'
+ import { isWxWorkEnvironment,redirectToQyLogin } from '@/utils/wechat'
export default {
data() {
@@ -48,17 +73,38 @@
captchaEnabled: true,
// 鐢ㄦ埛娉ㄥ唽寮�鍏�
register: false,
+ // 闅愮鏀跨瓥鍚屾剰鐘舵��(榛樿鏈�変腑,闇�瑕佺敤鎴蜂富鍔ㄥ嬀閫�)
+ agreedToPolicy: false,
globalConfig: getApp().globalData.config,
loginForm: {
- username: "admin",
- password: "admin123",
+ username: "",
+ password: "",
code: "",
uuid: ''
- }
+ },
+ // 寰俊涓�閿櫥褰曠浉鍏�
+ isWechat: false, // 鏄惁涓哄井淇″皬绋嬪簭鐜
+ wechatOpenId: '', // 寰俊OpenID
+ wechatUnionId: '', // 寰俊UnionID
+ // 椤甸潰鍙傛暟
+ pageOptions: {}
}
+ },
+ onLoad(options) {
+ // 淇濆瓨椤甸潰鍙傛暟
+ this.pageOptions = options || {}
+ isWxWorkEnvironment().then(res=>{
+ if(res){
+ // console.log("浼佷笟寰俊鐜 login.vue....")
+ redirectToQyLogin(options,this.$tab);
+ }
+ });
+
},
created() {
this.getCode()
+ this.checkWechatEnv()
+ this.tryAutoLogin()
},
methods: {
// 鐢ㄦ埛娉ㄥ唽
@@ -67,13 +113,15 @@
},
// 闅愮鍗忚
handlePrivacy() {
- let site = this.globalConfig.appInfo.agreements[0]
- this.$tab.navigateTo(`/pages/common/webview/index?title=${site.title}&url=${site.url}`)
+ this.$tab.navigateTo('/pages/mine/privacy-policy/index')
},
// 鐢ㄦ埛鍗忚
handleUserAgrement() {
- let site = this.globalConfig.appInfo.agreements[1]
- this.$tab.navigateTo(`/pages/common/webview/index?title=${site.title}&url=${site.url}`)
+ this.$tab.navigateTo('/pages/mine/user-agreement/index')
+ },
+ // 鍗忚鍚屾剰鐘舵�佸彉鏇�
+ onAgreementChange(e) {
+ this.agreedToPolicy = e.detail.value.length > 0
},
// 鑾峰彇鍥惧舰楠岃瘉鐮�
getCode() {
@@ -87,6 +135,10 @@
},
// 鐧诲綍鏂规硶
async handleLogin() {
+ if (!this.agreedToPolicy) {
+ this.$modal.msgError("璇峰厛闃呰骞跺悓鎰忕敤鎴峰崗璁拰闅愮鏀跨瓥")
+ return
+ }
if (this.loginForm.username === "") {
this.$modal.msgError("璇疯緭鍏ユ偍鐨勮处鍙�")
} else if (this.loginForm.password === "") {
@@ -113,8 +165,202 @@
loginSuccess(result) {
// 璁剧疆鐢ㄦ埛淇℃伅
this.$store.dispatch('GetInfo').then(res => {
- this.$tab.reLaunch('/pages/index')
+ // 瑙﹀彂鐧诲綍鎴愬姛浜嬩欢锛屽惎鍔ㄦ秷鎭疆璇�
+ uni.$emit('user-login')
+ // 澶勭悊鑷姩璺宠浆閫昏緫
+ this.redirectAfterLogin()
})
+ },
+
+ // ==================== 寰俊涓�閿櫥褰曠浉鍏虫柟娉� ====================
+
+ // 妫�鏌ユ槸鍚﹀湪寰俊灏忕▼搴忕幆澧�
+ checkWechatEnv() {
+ // #ifdef MP-WEIXIN
+ this.isWechat = true
+ console.log('褰撳墠鐜:寰俊灏忕▼搴�')
+ // #endif
+
+ // #ifndef MP-WEIXIN
+ this.isWechat = false
+ console.log('褰撳墠鐜:闈炲井淇″皬绋嬪簭')
+ // #endif
+
+
+ },
+
+ // 灏濊瘯鑷姩鐧诲綍(妫�鏌ユ湰鍦版槸鍚︽湁淇濆瓨鐨凮penID)
+ tryAutoLogin() {
+ if (!this.isWechat) {
+ return
+ }
+
+ // 浠庢湰鍦板瓨鍌ㄤ腑鑾峰彇OpenID鍜孶nionID
+ const savedOpenId = uni.getStorageSync('wechat_openid')
+ const savedUnionId = uni.getStorageSync('wechat_unionid')
+ const autoLogin=true;
+
+ if (savedOpenId && autoLogin) {
+ console.log('妫�娴嬪埌宸蹭繚瀛樼殑OpenID锛屽皾璇曡嚜鍔ㄧ櫥褰�')
+ this.wechatOpenId = savedOpenId
+ this.wechatUnionId = savedUnionId // 鍙兘涓簄ull
+ this.loginByOpenId()
+ }
+ },
+
+ // 澶勭悊鑾峰彇鎵嬫満鍙风殑鍥炶皟
+ onGetPhoneNumber(e) {
+ console.log('鑾峰彇鎵嬫満鍙峰洖璋�:', e)
+
+ if (!this.agreedToPolicy) {
+ this.$modal.msgError("璇峰厛闃呰骞跺悓鎰忕敤鎴峰崗璁拰闅愮鏀跨瓥")
+ return
+ }
+
+ if (e.detail.errMsg === 'getPhoneNumber:ok') {
+ // 鐢ㄦ埛鍚屾剰鎺堟潈
+ const { code } = e.detail
+
+ this.$modal.loading("姝e湪鑾峰彇鎵嬫満鍙�...")
+
+ // 鍏堣幏鍙栧井淇$櫥褰昪ode
+ uni.login({
+ provider: 'weixin',
+ success: (loginRes) => {
+ console.log('寰俊鐧诲綍code:', loginRes.code)
+ console.log('鎵嬫満鍙穋ode:', code)
+
+ // 璋冪敤鍚庣鎺ュ彛,浼犲叆loginCode鍜宲honeCode
+ loginByWechatPhone(loginRes.code, code).then(response => {
+ this.$modal.closeLoading()
+
+ if (response.code === 200) {
+ // 鐧诲綍鎴愬姛,淇濆瓨OpenID鍜孶nionID
+ const openId = response.openId
+ const unionId = response.unionId
+
+ uni.setStorageSync('wechat_openid', openId)
+ this.wechatOpenId = openId
+
+ if (unionId) {
+ uni.setStorageSync('wechat_unionid', unionId)
+ this.wechatUnionId = unionId
+ }
+
+ // 淇濆瓨token鍒版湰鍦板瓨鍌ㄥ拰Vuex
+ const token = response.token
+ this.$store.commit('SET_TOKEN', token)
+ // 蹇呴』璋冪敤setToken淇濆瓨鍒版湰鍦板瓨鍌�
+ const { setToken } = require('@/utils/auth')
+ setToken(token)
+
+ // 鑾峰彇鐢ㄦ埛淇℃伅骞跺鐞嗚嚜鍔ㄨ烦杞�昏緫
+ this.$store.dispatch('GetInfo').then(() => {
+ this.redirectAfterLogin()
+ });
+ } else {
+ this.$modal.msgError(response.msg || '鐧诲綍澶辫触')
+ }
+ }).catch(error => {
+ this.$modal.closeLoading()
+ console.error('鐧诲綍澶辫触:', error)
+ this.$modal.msgError('鐧诲綍澶辫触,璇烽噸璇�')
+ })
+ },
+ fail: (err) => {
+ this.$modal.closeLoading()
+ console.error('鑾峰彇寰俊鐧诲綍code澶辫触:', err)
+ this.$modal.msgError('鑾峰彇寰俊淇℃伅澶辫触')
+ }
+ })
+ } else {
+ // 鐢ㄦ埛鎷掔粷鎺堟潈
+ this.$modal.msgError('闇�瑕佹偍鐨勬墜鏈哄彿鎵嶈兘鐧诲綍')
+ }
+ },
+
+ // 閫氳繃OpenID鍜孶nionID鐧诲綍
+ loginByOpenId() {
+ this.$modal.loading("姝e湪鐧诲綍...")
+
+ // 鍚屾椂浼犲叆openId鍜寀nionId杩涜鍙岄噸楠岃瘉
+ loginByOpenId(this.wechatOpenId, this.wechatUnionId).then(response => {
+ this.$modal.closeLoading()
+
+ if (response.code === 200) {
+ // 鐧诲綍鎴愬姛,淇濆瓨token鍒版湰鍦板瓨鍌ㄥ拰Vuex
+ const token = response.token
+ this.$store.commit('SET_TOKEN', token)
+ // 蹇呴』璋冪敤setToken淇濆瓨鍒版湰鍦板瓨鍌�
+ const { setToken } = require('@/utils/auth')
+ setToken(token)
+
+ // 鑾峰彇鐢ㄦ埛淇℃伅骞跺鐞嗚嚜鍔ㄨ烦杞�昏緫
+ this.$store.dispatch('GetInfo').then(() => {
+ this.redirectAfterLogin()
+ });
+ } else {
+ // OpenID鏈粦瀹氭垨楠岃瘉澶辫触锛岄渶瑕佽幏鍙栨墜鏈哄彿缁戝畾
+ console.log('璇penID灏氭湭缁戝畾鎴栭獙璇佸け璐ワ紝闇�瑕佽幏鍙栨墜鏈哄彿')
+ this.$modal.closeLoading()
+ this.$modal.msgError(response.msg || '璇ュ井淇¤处鍙峰皻鏈粦瀹氾紝璇风偣鍑诲井淇′竴閿櫥褰曟寜閽幏鍙栨墜鏈哄彿鎺堟潈')
+ }
+ }).catch(error => {
+ this.$modal.closeLoading()
+ console.error('鐧诲綍澶辫触:', error)
+ this.$modal.msgError('鐧诲綍澶辫触锛岃閲嶈瘯')
+ })
+ },
+
+ /**
+ * 鑾峰彇URL鍙傛暟
+ */
+ getUrlParam(name) {
+ // #ifdef H5
+ const reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
+ const r = window.location.search.substr(1).match(reg);
+ if (r != null) return decodeURIComponent(r[2]);
+ // #endif
+
+ // #ifdef MP-WEIXIN
+ // 鍦ㄥ皬绋嬪簭涓紝鍙傛暟閫氳繃onLoad鐨刼ptions浼犻��
+ if (this.pageOptions && this.pageOptions[name]) {
+ return decodeURIComponent(this.pageOptions[name]);
+ }
+ // #endif
+
+ return null;
+ },
+
+ /**
+ * 鐧诲綍鎴愬姛鍚庣殑璺宠浆澶勭悊
+ */
+ redirectAfterLogin() {
+ try {
+ // 妫�鏌ユ槸鍚︽湁redirect鍙傛暟鎸囧畾璺宠浆椤甸潰
+ let redirectUrl = this.getUrlParam("redirect");
+
+ // 濡傛灉娌℃湁redirect鍙傛暟锛屾鏌ユ槸鍚︽湁淇濆瓨鐨勭洰鏍囬〉闈�
+ if (!redirectUrl) {
+ const { getTargetUrl } = require('@/utils/auth')
+ redirectUrl = getTargetUrl()
+ }
+
+ if (redirectUrl) {
+ // 瑙g爜redirect鍙傛暟
+ redirectUrl = decodeURIComponent(redirectUrl);
+ console.log("鑷姩璺宠浆鍒版寚瀹氶〉闈�:", redirectUrl);
+ this.$tab.reLaunch(redirectUrl);
+ } else {
+ // 榛樿璺宠浆鍒伴椤�
+ console.log("璺宠浆鍒伴椤�");
+ this.$tab.reLaunch('/pages/index');
+ }
+ } catch (e) {
+ console.error("璺宠浆澶辫触锛屼娇鐢ㄩ粯璁よ烦杞�:", e);
+ // 鍑虹幇寮傚父鏃讹紝榛樿璺宠浆鍒伴椤�
+ this.$tab.reLaunch('/pages/index');
+ }
}
}
}
@@ -127,6 +373,24 @@
.normal-login-container {
width: 100%;
+ min-height: 100vh;
+ // 闅愯棌婊氬姩鏉′絾淇濇寔婊氬姩鍔熻兘
+ ::-webkit-scrollbar {
+ display: none;
+ width: 0 !important;
+ height: 0 !important;
+ background: transparent;
+ }
+
+ // Firefox婊氬姩鏉¢殣钘�
+ * {
+ scrollbar-width: none; /* Firefox */
+ }
+
+ // IE/Edge婊氬姩鏉¢殣钘�
+ * {
+ -ms-overflow-style: none; /* IE 10+ */
+ }
.logo-content {
width: 100%;
@@ -158,45 +422,177 @@
.icon {
font-size: 38rpx;
margin-left: 10px;
- color: #999;
}
.input {
+ margin-left: 20rpx;
width: 100%;
- font-size: 14px;
- line-height: 20px;
- text-align: left;
- padding-left: 15px;
+ height: 45px;
+ background: none;
+ }
+ }
+
+ .captcha-container {
+ width: 100%;
+ margin: 20px auto;
+ background-color: #f5f6f7;
+ height: 45px;
+ border-radius: 20px;
+ padding-right: 10rpx;
+ box-sizing: border-box;
+
+ .icon {
+ font-size: 38rpx;
+ margin-left: 10px;
}
+ .input {
+ margin-left: 20rpx;
+ width: 60%;
+ height: 45px;
+ background: none;
+ }
+
+ .login-code {
+ width: 30%;
+ height: 45px;
+ margin-left: 10rpx;
+ border-left: 1px solid #e0e0e0;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+
+ .login-code-img {
+ max-width: 100%;
+ max-height: 45px;
+ object-fit: contain;
+ cursor: pointer;
+ }
+ }
}
- .login-btn {
- margin-top: 40px;
- height: 45px;
+ .action-btn {
+ margin: 40rpx 0;
+
+ .login-btn {
+ height: 90rpx;
+ font-size: 32rpx;
+ }
+
+ .wechat-login-btn {
+ height: 90rpx;
+ font-size: 32rpx;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ }
}
-
+
.reg {
- margin-top: 15px;
+ margin: 20rpx 0;
+
+ .text-grey1 {
+ color: #888;
+ }
+
+ .text-blue {
+ margin: 0 10rpx;
+ color: #007AFF;
+ }
}
- .xieyi {
- color: #333;
- margin-top: 20px;
- }
-
- .login-code {
- height: 38px;
- float: right;
-
- .login-code-img {
- height: 38px;
- position: absolute;
- margin-left: 10px;
- width: 200rpx;
+ .agreement-checkbox {
+ margin: 50rpx 0 30rpx 0;
+ padding: 20rpx;
+ display: flex;
+ justify-content: flex-start;
+ align-items: left;
+
+ checkbox-group {
+ display: flex;
+ align-items: center;
+ }
+
+ .checkbox-label {
+ display: flex;
+ align-items: center;
+ justify-content: flex-start;
+
+ checkbox {
+ margin-right: 15rpx;
+ transform: scale(1.2);
+ flex-shrink: 0;
+ vertical-align: middle;
+ }
+
+ // 鍦嗗舰澶嶉�夋鏍峰紡
+ .round-checkbox {
+ border-radius: 50% !important;
+ }
+
+ // 閽堝寰俊灏忕▼搴忕殑鍦嗗舰鏍峰紡
+ ::v-deep .uni-checkbox-input,
+ ::v-deep .wx-checkbox-input {
+ border-radius: 50% !important;
+ }
+
+ // 閽堝H5鐨勫渾褰㈡牱寮�
+ ::v-deep input[type="checkbox"] {
+ border-radius: 50% !important;
+ -webkit-appearance: none;
+ appearance: none;
+ width: 36rpx;
+ height: 36rpx;
+ border: 2rpx solid #d1d1d1;
+ background-color: #fff;
+ position: relative;
+
+ &:checked {
+ background-color: #007AFF;
+ border-color: #007AFF;
+
+ &::after {
+ content: '';
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ width: 12rpx;
+ height: 12rpx;
+ background-color: #fff;
+ border-radius: 50%;
+ }
+ }
+ }
+
+ .agreement-text {
+ display: inline-flex;
+ align-items: center;
+ flex-wrap: wrap;
+ line-height: 1.5;
+ font-size: 26rpx;
+ text-align: left;
+ justify-content: flex-start;
+
+ .text-grey1 {
+ color: #666;
+ font-size: 26rpx;
+ line-height: 1.5;
+ }
+
+ .text-blue {
+ color: #007AFF;
+ font-size: 26rpx;
+ padding: 8rpx 10rpx;
+ margin: 0 5rpx;
+ display: inline-block;
+ position: relative;
+ z-index: 10;
+ line-height: 1.5;
+ }
+ }
}
}
}
}
-
-</style>
+</style>
\ No newline at end of file
--
Gitblit v1.9.1