Files
smt-used-car-h5/pages/login/index.vue
T
2026-03-11 11:15:33 +08:00

1083 lines
28 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view class="login-page">
<!-- 装饰背景 -->
<view class="bg-decoration">
<view class="circle circle-1"></view>
<view class="circle circle-2"></view>
<view class="circle circle-3"></view>
</view>
<!-- 主内容区 -->
<view class="login-container">
<!-- Logo 和标题 -->
<view class="header-section">
<view class="logo-wrapper">
<image class="logo" src="/static/image/car.png" mode="aspectFit"></image>
</view>
<text class="app-name">二手车采集</text>
<text class="app-desc">欢迎登录,二手车采集平台</text>
</view>
<!-- 登录卡片 -->
<view class="login-card">
<!-- 登录方式切换 -->
<view class="tab-bar">
<view
class="tab-item"
:class="{ active: loginType === 'password' }"
@tap="switchLoginType('password')"
>
<text class="tab-text">账号登录</text>
<view class="tab-line" v-if="loginType === 'password'"></view>
</view>
<view
class="tab-item"
:class="{ active: loginType === 'feishu' }"
@tap="switchLoginType('feishu')"
>
<text class="tab-text">飞书登录</text>
<view class="tab-line" v-if="loginType === 'feishu'"></view>
</view>
</view>
<!-- 账号密码登录表单 -->
<view v-if="loginType === 'password'" class="form-section">
<!-- 账号输入框 -->
<view class="input-group">
<view class="input-wrapper">
<uni-icons type="person" size="20" color="#999"></uni-icons>
<input
class="input-field"
type="text"
placeholder="请输入账号/手机号"
v-model="formData.account"
placeholder-class="input-placeholder"
/>
</view>
</view>
<!-- 密码输入框 -->
<view class="input-group">
<view class="input-wrapper">
<uni-icons type="locked" size="20" color="#999"></uni-icons>
<input
class="input-field"
:type="showPassword ? 'text' : 'password'"
placeholder="请输入密码"
v-model="formData.password"
placeholder-class="input-placeholder"
/>
<uni-icons
:type="showPassword ? 'eye' : 'eye-slash'"
size="20"
:color="showPassword ? '#2E6CF6' : '#999'"
@tap="togglePassword"
></uni-icons>
</view>
</view>
<!-- 记住密码和忘记密码 -->
<!-- <view class="form-options">
<view class="remember-me" @tap="toggleRemember">
<view class="checkbox" :class="{ checked: rememberMe }">
<uni-icons v-if="rememberMe" type="checkmarkempty" size="14" color="#fff"></uni-icons>
</view>
<text class="option-text">记住密码</text>
</view>
<text class="forget-pwd" @tap="goToForgetPwd">忘记密码?</text>
</view> -->
<!-- 登录按钮 -->
<view class="login-btn" :class="{ loading: isLoading }" @tap="handlePasswordLogin">
<text class="btn-text">{{ isLoading ? '登录中...' : '登录' }}</text>
<uni-icons v-if="isLoading" type="spinner-cycle" size="18" color="#fff"></uni-icons>
</view>
</view>
<!-- 飞书登录 -->
<view v-else class="feishu-section">
<!-- 公司选择 -->
<view class="input-group">
<view class="input-wrapper" style="display: flex;align-items: center;gap: 10px;">
<uni-icons type="home" size="20" color="#999"></uni-icons>
<picker
mode="selector"
:range="companyList"
range-key="name"
:value="selectedCompanyIndex"
@change="onCompanyChange"
>
<view class="picker-input">
<text class="picker-text" :class="{ placeholder: !selectedCompany }">
{{ selectedCompany ? selectedCompany.name : '请选择公司' }}
</text>
<uni-icons type="arrowdown" size="14" color="#999"></uni-icons>
</view>
</picker>
</view>
</view>
<!-- 飞书内环境:自动登录 -->
<view v-if="isInFeishu && selectedCompany" class="feishu-auto-login">
<view class="feishu-loading">
<uni-icons type="spinner-cycle" size="40" color="#2E6CF6"></uni-icons>
<text class="loading-text">正在跳转飞书授权...</text>
</view>
</view>
<!-- 非飞书环境:显示二维码 -->
<view v-else-if="!isInFeishu && selectedCompany" class="feishu-qrcode-section">
<view class="qrcode-container" id="feishu_qrcode_container">
<view v-if="sdkLoadFailed" class="sdk-error">
<text class="error-text">二维码加载失败</text>
<view class="retry-btn" @tap="reloadFeishuSDK">
<text>点击重试</text>
</view>
</view>
</view>
<text class="qrcode-tip">请使用飞书App扫码登录</text>
</view>
<!-- 未选择公司 -->
<view v-else class="feishu-content">
<text class="feishu-desc">请先选择公司</text>
</view>
</view>
<!-- 底部提示 -->
<!-- <view class="footer-tip">
<text class="tip-text">登录即表示同意</text>
<text class="link-text">《用户协议》</text>
<text class="tip-text">和</text>
<text class="link-text">《隐私政策》</text>
</view> -->
</view>
</view>
</view>
</template>
<script>
import { request } from '@/api/apiT.js'
import { saveRoles } from '@/common/role.js'
import { getVisibleTabBar } from '@/common/tabbar.js'
export default {
data() {
return {
loginType: 'password', // password | feishu
isLoading: false,
showPassword: false,
rememberMe: false,
fsappid: '',
// 公司相关
companyList: [],
selectedCompany: null,
selectedCompanyIndex: -1,
feishuConfig: null,
// 是否在飞书内环境
isInFeishu: false,
// SDK加载状态
sdkLoadFailed: false,
formData: {
account: '',
password: ''
}
}
},
onLoad(options) {
// 检测是否在飞书内环境
this.isInFeishu = /Lark|Feishu/i.test(navigator.userAgent || '')
// 获取飞书 appid
this.fsappid = options.appid || '';
uni.setStorageSync('fsappid', this.fsappid);
// 保存登录成功后的回跳地址
const redirect = options.redirect || options.r || ''
if (redirect) {
try {
uni.setStorageSync('post_login_redirect', decodeURIComponent(redirect))
} catch (e) {
uni.setStorageSync('post_login_redirect', redirect)
}
}
// 加载记住的密码
this.loadRememberedPassword();
// 获取公司列表
this.getCompanyList();
// 检查URL参数中的公司ID
const companyId = options.corp_id
if (companyId) {
this.selectCompanyById(Number(companyId))
}
// #ifdef H5
// 检查SDK初始状态(延迟1秒后检查)
setTimeout(() => {
console.log('[飞书登录] 页面加载后SDK状态检查:', {
typeofQRLogin: typeof window.QRLogin,
typeofQRLoginGlobal: typeof QRLogin,
hasWindow: typeof window !== 'undefined',
windowKeys: Object.keys(window).filter(k => k.includes('QR') || k.includes('Lark'))
})
// 检查脚本标签是否存在
const scripts = document.querySelectorAll('script')
const feishuScript = Array.from(scripts).find(s => s.src && s.src.includes('feishu'))
console.log('[飞书登录] 飞书SDK脚本标签:', {
found: !!feishuScript,
src: feishuScript?.src,
loaded: feishuScript?.onload ? 'has onload' : 'no onload',
error: feishuScript?.onerror ? 'has onerror' : 'no onerror',
readyState: feishuScript?.readyState
})
// 如果SDK没加载,尝试动态加载
if (typeof window.QRLogin === 'undefined') {
console.log('[飞书登录] SDK未加载,尝试动态加载...')
this.loadFeishuSDKScript()
}
}, 1000)
// #endif
},
methods: {
// 切换登录方式
switchLoginType(type) {
this.loginType = type
// 切换时清空二维码容器
// #ifdef H5
const container = document.getElementById('feishu_qrcode_container')
if (container) {
container.innerHTML = ''
}
// #endif
},
// 切换密码显示
togglePassword() {
this.showPassword = !this.showPassword
},
// 切换记住密码
toggleRemember() {
this.rememberMe = !this.rememberMe
},
// 加载记住的密码
loadRememberedPassword() {
const remembered = uni.getStorageSync('remembered_password')
if (remembered) {
this.formData.account = remembered.account || ''
this.formData.password = remembered.password || ''
this.rememberMe = true
}
},
// 保存记住的密码
saveRememberedPassword() {
if (this.rememberMe) {
uni.setStorageSync('remembered_password', {
account: this.formData.account,
password: this.formData.password
})
} else {
uni.removeStorageSync('remembered_password')
}
},
// 验证表单
validateForm() {
if (!this.formData.account) {
uni.showToast({ title: '请输入账号/手机号', icon: 'none' })
return false
}
if (!this.formData.password) {
uni.showToast({ title: '请输入密码', icon: 'none' })
return false
}
if (this.formData.password.length < 6) {
uni.showToast({ title: '密码长度不能少于6位', icon: 'none' })
return false
}
return true
},
// 账号密码登录
async handlePasswordLogin() {
if (!this.validateForm()) return
if (this.isLoading) return
this.isLoading = true
try {
const res = await request({
url: 'common/auth/login',
method: 'post',
loginType: 'upwd', // 账号密码登录
data: {
account: this.formData.account,
password: this.formData.password
}
})
if (res.data.code === 200) {
const data = res.data.data
// 保存登录类型
uni.setStorageSync('loginType', 'upwd')
// 统一使用 union_id 作为 token(与PC端保持一致)
const token = data.union_id || data.token
if (token) {
uni.setStorageSync('token', token)
}
// 处理用户信息
const userInfo = {
...data,
token: token
}
uni.setStorageSync('userInfo', userInfo)
// 处理角色信息(统一使用 role.js 工具)
saveRoles(data.role, data.role_wp)
// 保存记住的密码
this.saveRememberedPassword()
uni.showToast({ title: '登录成功', icon: 'success' })
setTimeout(() => {
this.goToRedirect()
}, 1000)
} else {
uni.showToast({ title: res.data.message || '登录失败', icon: 'none' })
}
} catch (err) {
console.error('[password login] error:', err)
uni.showToast({ title: err.message || '登录失败,请稍后重试', icon: 'none' })
} finally {
this.isLoading = false
}
},
// ========== 公司相关方法 ==========
// 获取公司列表
async getCompanyList() {
try {
const res = await request({
url: 'common/preset/corps',
method: 'get'
})
if (res.data.code === 200) {
this.companyList = res.data.data || []
}
} catch (err) {
console.error('[getCompanyList] error:', err)
}
},
// 公司选择变更
onCompanyChange(e) {
const index = e.detail.value
this.selectedCompanyIndex = index
this.selectedCompany = this.companyList[index]
if (this.selectedCompany) {
// 保存公司信息
uni.setStorageSync('companyId', this.selectedCompany.id)
uni.setStorageSync('companyAbbr', this.selectedCompany.abbr || '')
// 构建飞书配置
this.feishuConfig = {
...this.selectedCompany,
app_id: this.selectedCompany.app_id,
r_url: this.selectedCompany.m_url,
state: this.selectedCompany.state || 'xinyouhe'
}
uni.setStorageSync('fsappid', this.selectedCompany.app_id);
// 保存 app_id 供回调页面使用
if (this.feishuConfig.app_id) {
uni.setStorageSync('fsappid', this.feishuConfig.app_id)
this.fsappid = this.feishuConfig.app_id
}
// 初始化飞书登录
this.initFeishuLogin()
}
},
// 通过ID选择公司
selectCompanyById(companyId) {
const index = this.companyList.findIndex(c => c.id === companyId)
if (index !== -1) {
this.onCompanyChange({ detail: { value: index } })
}
},
// 初始化飞书登录
async initFeishuLogin() {
if (!this.selectedCompany || !this.feishuConfig) return
if (this.isInFeishu) {
// 飞书内环境,自动跳转授权
await this.handleFeishuLogin()
} else {
// 普通浏览器环境,显示二维码
await this.loadFeishuQRCode()
}
},
// 加载飞书二维码
async loadFeishuQRCode() {
// #ifdef H5
console.log('[飞书登录] 开始加载二维码')
this.sdkLoadFailed = false
try {
// 等待SDK加载完成(已在index.html中预加载)
await this.waitForFeishuSDK()
console.log('[飞书登录] SDK加载完成')
await this.$nextTick()
const container = document.getElementById('feishu_qrcode_container')
console.log('[飞书登录] 容器:', container)
if (!container) {
uni.showToast({ title: '二维码容器未找到', icon: 'none' })
return
}
container.innerHTML = ''
const { app_id, r_url, state } = this.feishuConfig
console.log('[飞书登录] 飞书配置:', { app_id, r_url, state })
if (!app_id || !r_url || !state) {
uni.showToast({ title: '飞书配置不完整', icon: 'none' })
return
}
// URL编码
const encodedRedirectUri = encodeURIComponent(r_url)
const gotoUrl = `https://passport.feishu.cn/suite/passport/oauth/authorize?client_id=${app_id}&redirect_uri=${encodedRedirectUri}&response_type=code&state=${state}`
// 检查SDK是否加载
if (typeof window.QRLogin === 'undefined') {
console.error('[飞书登录] QRLogin 未定义')
this.sdkLoadFailed = true
uni.showToast({ title: '飞书SDK未加载,请点击重试', icon: 'none' })
return
}
console.log('[飞书登录] 开始生成二维码, gotoUrl:', gotoUrl)
// 生成二维码(使用 window.QRLogin)
const QRLoginObj = window.QRLogin({
id: 'feishu_qrcode_container',
goto: gotoUrl,
width: '200',
height: '200',
style: 'width:270px;height:270px;border:none'
})
console.log('[飞书登录] 二维码生成成功:', QRLoginObj)
// 监听扫码消息
const handleMessage = (event) => {
console.log('[飞书登录] 收到消息:', event)
if (
QRLoginObj.matchOrigin &&
QRLoginObj.matchData &&
QRLoginObj.matchOrigin(event.origin) &&
QRLoginObj.matchData(event.data)
) {
const loginTmpCode = event.data.tmp_code
console.log('[飞书登录] 扫码成功,跳转授权')
window.location.href = `${gotoUrl}&tmp_code=${loginTmpCode}`
}
}
window.addEventListener('message', handleMessage, false)
} catch (error) {
console.error('[飞书登录] 加载二维码失败:', error)
this.sdkLoadFailed = true
uni.showToast({ title: error.message || '二维码加载失败,请重试', icon: 'none' })
}
// #endif
},
// 重新加载飞书SDK
reloadFeishuSDK() {
// #ifdef H5
console.log('[飞书登录] 手动重新加载SDK')
this.sdkLoadFailed = false
this.loadFeishuSDKScript()
// #endif
},
// 动态加载飞书SDK脚本
loadFeishuSDKScript() {
// #ifdef H5
// 检查是否已经加载过
if (typeof window.QRLogin === 'function') {
console.log('[飞书登录] SDK已加载,无需重复加载')
if (this.selectedCompany && !this.isInFeishu) {
this.loadFeishuQRCode()
}
return
}
// 检查是否已有正在加载的脚本
const existingScript = document.querySelector('script[data-feishu-sdk]')
if (existingScript) {
console.log('[飞书登录] SDK脚本已在加载中')
return
}
console.log('[飞书登录] 开始动态加载SDK脚本...')
const script = document.createElement('script')
script.setAttribute('data-feishu-sdk', 'true')
script.src = 'https://lf-package-cn.feishucdn.com/obj/feishu-static/lark/passport/qrcode/LarkSSOSDKWebQRCode-1.0.3.js'
script.crossOrigin = 'anonymous'
script.onload = () => {
console.log('[飞书登录] ✅ SDK脚本加载成功')
console.log('[飞书登录] QRLogin类型:', typeof window.QRLogin)
if (typeof window.QRLogin === 'function') {
console.log('[飞书登录] SDK已准备就绪')
// 如果已选择公司且在非飞书环境,加载二维码
if (this.selectedCompany && !this.isInFeishu) {
this.loadFeishuQRCode()
}
} else {
console.error('[飞书登录] ⚠️ 脚本加载成功但QRLogin未定义')
this.sdkLoadFailed = true
}
}
script.onerror = (event) => {
console.error('[飞书登录] ❌ SDK脚本加载失败:', event)
console.error('[飞书登录] 脚本URL:', script.src)
this.sdkLoadFailed = true
uni.showToast({ title: 'SDK加载失败,请检查网络', icon: 'none' })
}
script.onabort = () => {
console.error('[飞书登录] ❌ SDK脚本加载被中断')
this.sdkLoadFailed = true
}
// 添加到head而不是body
document.head.appendChild(script)
console.log('[飞书登录] SDK脚本标签已添加到head')
// #endif
},
// 等待飞书SDK加载完成(带超时)
async waitForFeishuSDK() {
// #ifdef H5
return new Promise((resolve, reject) => {
const startTime = Date.now()
const timeoutMs = 15000 // 15秒超时
const timeout = setTimeout(() => {
const elapsed = Date.now() - startTime
console.error('[飞书登录] SDK加载超时,等待时间:', elapsed, 'ms')
console.log('[飞书登录] 当前window上的属性:', Object.keys(window).filter(k => k.includes('QR') || k.includes('qr') || k.includes('Lark')))
console.log('[飞书登录] window.QRLogin类型:', typeof window.QRLogin)
console.log('[飞书登录] QRLogin类型:', typeof QRLogin)
// 检查是否有网络错误
if (typeof window.QRLogin === 'undefined') {
console.error('[飞书登录] 请检查网络连接或是否被浏览器扩展阻止')
}
this.sdkLoadFailed = true
uni.showToast({ title: '飞书SDK加载超时,请点击重试', icon: 'none' })
reject(new Error('飞书SDK加载超时,请刷新页面重试'))
}, timeoutMs)
let count = 0
const checkInterval = 200 // 每200ms检查一次
const maxCount = Math.ceil(timeoutMs / checkInterval)
const check = () => {
try {
count++
const elapsed = Date.now() - startTime
// 每1秒打印一次详细日志
if (count % 5 === 0) {
console.log(`[飞书登录] SDK检测 ${count}/${maxCount}, 已等待: ${elapsed}ms, window.QRLogin: ${typeof window.QRLogin}`)
}
// 检查全局对象 window.QRLogin
if (typeof window.QRLogin === 'function') {
clearTimeout(timeout)
console.log('[飞书登录] SDK加载成功,总耗时:', elapsed, 'ms')
resolve(true)
} else if (elapsed >= timeoutMs) {
clearTimeout(timeout)
reject(new Error('SDK加载超时'))
} else {
setTimeout(check, checkInterval)
}
} catch (err) {
console.error('[飞书登录] 检查过程出错:', err)
clearTimeout(timeout)
this.sdkLoadFailed = true
reject(err)
}
}
// 立即开始检查
check()
})
// #endif
},
// 飞书登录(飞书内环境)
async handleFeishuLogin() {
if (!this.feishuConfig) {
uni.showToast({ title: '请先选择公司', icon: 'none' })
return
}
try {
console.log('[飞书内登录] 请求参数:', {
app_id: this.feishuConfig.app_id,
config: this.feishuConfig
})
const res = await request({
url: 'common/auth/feishu/scope',
method: 'get',
loginType: 'feishu',
data: {
app_id: this.feishuConfig.app_id,
is_pc:0
}
})
console.log('[飞书内登录] 接口返回:', res)
const auth_url = res?.data?.data?.auth_url
if (!auth_url) {
console.error('[飞书内登录] 返回数据结构:', res)
throw new Error('未获取到授权地址')
}
// H5 环境跳转飞书授权
// #ifdef H5
window.location.replace(auth_url)
// #endif
} catch (err) {
console.error('[feishu login] error:', err)
uni.showToast({ title: err?.message || '跳转失败,请稍后重试', icon: 'none' })
this.isLoading = false
}
},
// 忘记密码
goToForgetPwd() {
uni.navigateTo({ url: '/pages/index/forget-password' })
},
// 跳转到目标页面(根据角色TabBar显示规则)
goToRedirect() {
// 获取用户可见的TabBar列表
const visibleTabs = getVisibleTabBar()
// 检查是否包含首页Tab
const hasIndexTab = visibleTabs.some(tab => tab.pagePath === 'pages/index/index')
// 默认跳转目标:有首页进入首页,否则进入我的页面
const defaultTarget = hasIndexTab ? '/pages/index/index' : '/pages/index/mine'
// 优先使用存储的跳转地址
const target = uni.getStorageSync('post_login_redirect') || defaultTarget
uni.removeStorageSync('post_login_redirect')
uni.reLaunch({ url: target })
}
}
}
</script>
<style scoped lang="scss">
.login-page {
min-height: 100vh;
position: relative;
overflow: hidden;
background: linear-gradient(180deg, #FF972F 0%, #FF8A2C 25%, #FFF4E8 50%, #F4F6F8 100%);
}
/* 装饰背景 */
.bg-decoration {
position: absolute;
top: 0;
left: 0;
right: 0;
height: 50vh;
overflow: hidden;
.circle {
position: absolute;
border-radius: 50%;
background: rgba(255, 255, 255, 0.15);
animation: float 6s ease-in-out infinite;
&.circle-1 {
width: 400rpx;
height: 400rpx;
top: -150rpx;
left: -100rpx;
animation-delay: 0s;
}
&.circle-2 {
width: 300rpx;
height: 300rpx;
top: -80rpx;
right: -80rpx;
animation-delay: 1s;
}
&.circle-3 {
width: 200rpx;
height: 200rpx;
top: 100rpx;
right: 100rpx;
animation-delay: 2s;
}
}
}
@keyframes float {
0%, 100% {
transform: translateY(0) scale(1);
}
50% {
transform: translateY(-20rpx) scale(1.05);
}
}
/* 主容器 */
.login-container {
position: relative;
z-index: 1;
padding: 40rpx 32rpx;
min-height: 100vh;
display: flex;
flex-direction: column;
}
/* 头部区域 */
.header-section {
padding-top: 80rpx;
padding-bottom: 40rpx;
text-align: center;
.logo-wrapper {
width: 140rpx;
height: 140rpx;
margin: 0 auto 24rpx;
// background: rgba(255, 255, 255, 0.95);
border-radius: 32rpx;
box-shadow: 0 8rpx 32rpx rgba(255, 151, 47, 0.25);
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
.logo {
width: 100rpx;
height: 100rpx;
}
}
.app-name {
display: block;
font-size: 40rpx;
font-weight: 700;
color: #1f2937;
margin-bottom: 12rpx;
}
.app-desc {
display: block;
font-size: 26rpx;
color: #6b7280;
}
}
/* 登录卡片 */
.login-card {
background: rgba(255, 255, 255, 0.95);
border-radius: 32rpx;
padding: 40rpx 32rpx;
box-shadow: 0 16rpx 48rpx rgba(255, 151, 47, 0.12);
backdrop-filter: blur(20px);
}
/* Tab 切换 */
.tab-bar {
display: flex;
margin-bottom: 40rpx;
position: relative;
&::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 1px;
// background: #e5e7eb;
}
.tab-item {
flex: 1;
text-align: center;
padding: 20rpx 0;
position: relative;
.tab-text {
font-size: 30rpx;
color: #6b7280;
transition: all 0.3s;
}
.tab-line {
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
width: 48rpx;
height: 6rpx;
background: #FF972F;
border-radius: 3rpx;
transition: all 0.3s;
}
&.active .tab-text {
color: #FF972F;
font-weight: 600;
}
}
}
/* 表单区域 */
.form-section {
.input-group {
margin-bottom: 24rpx;
.input-wrapper {
display: flex;
align-items: center;
padding: 24rpx 28rpx;
background: #F8F9FB;
border-radius: 16rpx;
border: 2rpx solid transparent;
transition: all 0.3s;
&:focus-within {
background: #fff;
border-color: #FF972F;
box-shadow: 0 0 0 6rpx rgba(255, 151, 47, 0.08);
}
.input-field {
flex: 1;
margin: 0 16rpx;
font-size: 28rpx;
color: #1f2937;
border: none;
background: none;
}
.input-placeholder {
color: #9CA3AF;
}
}
}
.form-options {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 32rpx;
.remember-me {
display: flex;
align-items: center;
.checkbox {
width: 36rpx;
height: 36rpx;
border-radius: 8rpx;
border: 2rpx solid #d1d5db;
background: #fff;
display: flex;
align-items: center;
justify-content: center;
margin-right: 12rpx;
transition: all 0.2s;
&.checked {
background: #FF972F;
border-color: #FF972F;
}
}
.option-text {
font-size: 26rpx;
color: #6b7280;
}
}
.forget-pwd {
font-size: 26rpx;
color: #FF972F;
}
}
}
/* 飞书登录区域 */
.feishu-section {
padding: 20rpx 0;
.feishu-content {
text-align: center;
padding: 40rpx 20rpx;
.feishu-icon-wrapper {
width: 120rpx;
height: 120rpx;
margin: 0 auto 24rpx;
background: linear-gradient(135deg, #FF972F 0%, #FF8A2C 100%);
border-radius: 28rpx;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 12rpx 32rpx rgba(255, 151, 47, 0.3);
.feishu-logo {
width: 80rpx;
height: 80rpx;
}
}
.feishu-title {
display: block;
font-size: 32rpx;
font-weight: 600;
color: #1f2937;
margin-bottom: 12rpx;
}
.feishu-desc {
display: block;
font-size: 26rpx;
color: #6b7280;
}
}
}
/* 登录按钮 */
.login-btn {
width: 100%;
height: 88rpx;
background: linear-gradient(135deg, #FF972F 0%, #FF8A2C 100%);
border-radius: 24rpx;
display: flex;
align-items: center;
justify-content: center;
gap: 12rpx;
box-shadow: 0 12rpx 32rpx rgba(255, 151, 47, 0.35);
transition: all 0.3s;
&:active {
transform: scale(0.98);
box-shadow: 0 8rpx 24rpx rgba(255, 151, 47, 0.25);
}
&.loading {
opacity: 0.7;
}
// &.feishu-btn {
// background: linear-gradient(135deg, #3370FF 0%, #2956CC 100%);
// box-shadow: 0 12rpx 32rpx rgba(51, 112, 255, 0.35);
// &:active {
// box-shadow: 0 8rpx 24rpx rgba(51, 112, 255, 0.25);
// }
// }
.btn-text {
font-size: 30rpx;
font-weight: 600;
color: #fff;
}
}
/* 底部提示 */
.footer-tip {
text-align: center;
padding-top: 32rpx;
font-size: 24rpx;
.tip-text {
color: #9CA3AF;
}
.link-text {
color: #FF972F;
margin: 0 4rpx;
}
}
/* 飞书登录新增样式 */
/* 公司选择下拉框 */
.picker-input {
flex: 1;
display: flex;
align-items: center;
justify-content: space-between;
font-size: 28rpx;
color: #111827;
min-height: 88rpx;
}
.picker-text {
flex: 1;
color: #111827;
&.placeholder {
color: #9CA3AF;
}
}
/* 飞书内环境自动登录 */
.feishu-auto-login {
padding: 60rpx 40rpx;
text-align: center;
.feishu-loading {
display: flex;
flex-direction: column;
align-items: center;
gap: 24rpx;
.loading-text {
font-size: 28rpx;
color: #2E6CF6;
}
}
}
/* 飞书二维码区域 */
.feishu-qrcode-section{
text-align: center;
}
</style>