Files
CKB-mini-program/pages/channel/login.vue
2026-01-07 11:00:09 +08:00

337 lines
9.3 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="page-container">
<view class="hero">
<view class="hero-title">渠道登录</view>
<view class="hero-subtitle">登录后进入数据面板</view>
</view>
<!-- 账号密码登录H5 + 小程序通用 -->
<view class="card">
<view class="card-title">账号密码登录</view>
<uni-forms ref="h5Form" :modelValue="form">
<uni-forms-item name="phone">
<uni-easyinput
v-model="form.phone"
placeholder="请输入手机号"
type="number"
maxlength="11"
:inputBorder="false"
class="input"
/>
</uni-forms-item>
<uni-forms-item name="password">
<uni-easyinput
v-model="form.password"
placeholder="请输入密码"
:inputBorder="false"
type="password"
class="input"
/>
</uni-forms-item>
</uni-forms>
<view class="login-tip">
<text>默认初始密码为 </text>
<text class="login-tip-strong">123456</text>
<text>登录后请及时修改</text>
</view>
<button class="primary-btn" :disabled="isSubmitting" @click="handleH5Login">
<text>{{ isSubmitting ? '登录中...' : '登录' }}</text>
</button>
</view>
</view>
</template>
<script>
import config from '@/config'
export default {
data() {
return {
form: {
phone: '',
password: ''
},
isSubmitting: false,
companyId: ''
}
},
onLoad(options) {
// 获取参数
let scene = options.scene;
let companyId = options.companyId;
console.log('页面参数:', { scene, companyId });
// 小程序端解析 scene 参数
// #ifdef MP-WEIXIN
if (scene != undefined) {
// 先对 scene 进行 URL 解码(处理 %2C 等编码字符)
try {
scene = decodeURIComponent(scene);
} catch (e) {
console.warn('scene 解码失败,使用原始值:', e);
}
// scene 中可能包含 companyId或者直接就是 companyId
// 如果 scene 包含逗号,可能需要分割(根据实际业务需求调整)
if (scene.includes(',')) {
// 如果 scene 包含逗号,取第一部分作为 companyId
const parts = scene.split(',');
this.companyId = parts[0] || '';
} else {
// 如果不包含逗号scene 本身就是 companyId
this.companyId = scene;
}
} else if (companyId != undefined) {
// 兼容直接传 companyId 参数
this.companyId = companyId;
} else {
// 尝试从本地存储获取(之前可能保存过)
const storedCompanyId = uni.getStorageSync('channelCompanyId');
if (storedCompanyId) {
this.companyId = storedCompanyId;
console.log('从本地存储获取companyId:', storedCompanyId);
} else {
this.companyId = '';
}
}
// #endif
// H5 端兼容处理
// #ifdef H5
if (companyId != undefined) {
// H5 端优先使用 companyId 参数
this.companyId = companyId;
} else if (scene != undefined) {
// H5 也可能有 scene 参数(从分享链接等)
// 先对 scene 进行 URL 解码
try {
scene = decodeURIComponent(scene);
} catch (e) {
console.warn('scene 解码失败,使用原始值:', e);
}
if (scene.includes(',')) {
const parts = scene.split(',');
this.companyId = parts[0] || '';
} else {
this.companyId = scene;
}
} else {
// 尝试从本地存储获取
const storedCompanyId = uni.getStorageSync('channelCompanyId');
if (storedCompanyId) {
this.companyId = storedCompanyId;
console.log('从本地存储获取companyId:', storedCompanyId);
} else {
this.companyId = '';
}
}
// #endif
console.log('解析结果:', { companyId: this.companyId });
},
methods: {
// 账号密码登录H5 + 小程序)
handleH5Login() {
if (this.isSubmitting) return
if (!this.form.phone || !this.form.password) {
uni.showToast({ title: '请输入手机号和密码', icon: 'none', duration: 2000 })
return
}
if (!this.companyId) {
uni.showToast({ title: '缺少companyId参数', icon: 'none', duration: 2000 })
return
}
this.isSubmitting = true
// 使用和列表接口一样的请求方式和参数格式
uni.request({
method: 'POST',
url: config.apiUrl2 + '/v1/frontend/distribution/user/login',
data: {
companyId: this.companyId,
phone: this.form.phone,
password: this.form.password
},
header: {
'content-type': 'application/x-www-form-urlencoded'
},
success: (res) => {
this.isSubmitting = false
console.log('登录接口完整返回:', res)
console.log('登录接口返回数据:', res.data)
if (res.data.code === 10000 || res.data.code === 200) {
const data = res.data.data || {}
const token = data.token || ''
const channelInfo = data.channelInfo || {}
console.log('解析后的data:', data)
console.log('解析后的token:', token)
console.log('解析后的channelInfo:', channelInfo)
// 保存token
if (token) {
uni.setStorageSync('channelToken', token)
console.log('已保存token到本地存储')
} else {
console.error('token为空无法保存')
}
// 保存完整的登录数据(备用)
uni.setStorageSync('channelLoginData', JSON.stringify(data))
console.log('已保存完整登录数据到本地存储')
// 保存渠道信息 - 从channelInfo中获取
if (channelInfo.channelCode) {
uni.setStorageSync('channelCode', channelInfo.channelCode)
console.log('已保存channelCode:', channelInfo.channelCode)
} else {
console.warn('channelInfo.channelCode为空无法保存')
}
if (channelInfo.channelName) {
uni.setStorageSync('channelName', channelInfo.channelName)
console.log('已保存channelName:', channelInfo.channelName)
} else {
console.warn('channelInfo.channelName为空无法保存')
}
// 验证保存是否成功
const savedCode = uni.getStorageSync('channelCode')
const savedName = uni.getStorageSync('channelName')
const savedToken = uni.getStorageSync('channelToken')
console.log('验证保存结果:', { savedCode, savedName, savedToken })
if (!savedCode) {
console.error('警告channelCode保存失败')
uni.showToast({
title: '渠道编码保存失败,请重试',
icon: 'none',
duration: 3000
})
return
}
this.toStatistics()
} else {
const msg = res.data.message || res.data.msg || '登录失败'
console.error('登录失败:', msg)
uni.showToast({ title: msg, icon: 'none', duration: 3000 })
}
},
fail: (err) => {
console.error('登录失败', err)
this.isSubmitting = false
uni.showToast({ title: '网络错误,请重试', icon: 'none', duration: 2000 })
}
})
},
toStatistics() {
uni.redirectTo({
url: '/pages/channel/statistics'
})
}
}
}
</script>
<style lang="scss" scoped>
.page-container {
min-height: 100vh;
background: linear-gradient(180deg, #f5f7ff 0%, #f8f8f8 100%);
padding: 40rpx 30rpx 80rpx;
box-sizing: border-box;
}
.hero {
margin-bottom: 30rpx;
}
.hero-title {
font-size: 44rpx;
font-weight: 700;
color: #1f2937;
}
.hero-subtitle {
margin-top: 8rpx;
font-size: 26rpx;
color: #6b7280;
}
.card {
background: #fff;
border-radius: 16rpx;
padding: 32rpx 28rpx;
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.06);
margin-bottom: 24rpx;
}
.card-title {
font-size: 32rpx;
font-weight: 600;
color: #111827;
margin-bottom: 24rpx;
}
.input {
background: #f5f6fa;
border-radius: 12rpx;
padding: 20rpx;
}
.login-tip {
margin-top: 16rpx;
margin-bottom: 8rpx;
font-size: 24rpx;
color: #6b7280;
line-height: 1.6;
}
.login-tip-strong {
font-weight: 600;
color: #ef4444;
}
.primary-btn {
width: 100%;
height: 90rpx;
background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%);
border: none;
border-radius: 12rpx;
color: #fff;
font-size: 32rpx;
font-weight: 600;
display: flex;
align-items: center;
justify-content: center;
margin-top: 12rpx;
box-shadow: 0 8rpx 24rpx rgba(99, 102, 241, 0.25);
}
.tips {
margin-top: 16rpx;
font-size: 24rpx;
color: #6b7280;
text-align: center;
}
/* #ifdef H5 */
.primary-btn {
cursor: pointer;
transition: all 0.2s ease;
&:hover {
transform: translateY(-2rpx);
box-shadow: 0 10rpx 28rpx rgba(99, 102, 241, 0.3);
}
&:active {
transform: translateY(0);
}
}
/* #endif */
</style>