对接uniapp端登录[C
This commit is contained in:
3
Cunkebao/.env.production
Normal file
3
Cunkebao/.env.production
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# 生产环境配置
|
||||||
|
VUE_APP_BASE_API = 'https://api.cunkebao.com'
|
||||||
|
VUE_APP_ENV = 'production'
|
||||||
3
Cunkebao/.gitignore
vendored
3
Cunkebao/.gitignore
vendored
@@ -1 +1,2 @@
|
|||||||
node_modules
|
node_modules
|
||||||
|
.env
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
# 村客宝 UniApp
|
# 存客宝 UniApp
|
||||||
|
|
||||||
基于uni-app框架开发的村客宝移动端应用,支持H5、微信小程序、App等多端部署。
|
基于uni-app框架开发的存客宝移动端应用,支持H5、微信小程序、App等多端部署。
|
||||||
|
|
||||||
## 项目结构
|
## 项目结构
|
||||||
|
|
||||||
|
|||||||
@@ -3,14 +3,14 @@ import request from '@/utils/request'
|
|||||||
/**
|
/**
|
||||||
* 用户登录
|
* 用户登录
|
||||||
* @param {Object} data 登录数据
|
* @param {Object} data 登录数据
|
||||||
* @param {string} data.username 用户名
|
* @param {string} data.account 账号(手机号)
|
||||||
* @param {string} data.password 密码
|
* @param {string} data.password 密码
|
||||||
* @param {boolean} data.is_encrypted 密码是否已加密
|
* @param {number} data.typeId 用户类型
|
||||||
* @returns {Promise} 登录结果
|
* @returns {Promise} 登录结果
|
||||||
*/
|
*/
|
||||||
export function login(data) {
|
export function login(data) {
|
||||||
return request({
|
return request({
|
||||||
url: '/api/auth/login',
|
url: '/v1/auth/login',
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
data
|
data
|
||||||
})
|
})
|
||||||
@@ -19,13 +19,14 @@ export function login(data) {
|
|||||||
/**
|
/**
|
||||||
* 手机号验证码登录
|
* 手机号验证码登录
|
||||||
* @param {Object} data 登录数据
|
* @param {Object} data 登录数据
|
||||||
* @param {string} data.mobile 手机号
|
* @param {string} data.account 手机号
|
||||||
* @param {string} data.code 验证码
|
* @param {string} data.code 验证码
|
||||||
|
* @param {number} data.typeId 用户类型
|
||||||
* @returns {Promise} 登录结果
|
* @returns {Promise} 登录结果
|
||||||
*/
|
*/
|
||||||
export function mobileLogin(data) {
|
export function mobileLogin(data) {
|
||||||
return request({
|
return request({
|
||||||
url: '/api/auth/mobile-login',
|
url: '/v1/auth/mobile-login',
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
data
|
data
|
||||||
})
|
})
|
||||||
@@ -34,13 +35,13 @@ export function mobileLogin(data) {
|
|||||||
/**
|
/**
|
||||||
* 发送验证码
|
* 发送验证码
|
||||||
* @param {Object} data 数据
|
* @param {Object} data 数据
|
||||||
* @param {string} data.mobile 手机号
|
* @param {string} data.account 手机号
|
||||||
* @param {string} data.type 验证码类型(login:登录,register:注册)
|
* @param {string} data.type 验证码类型(login:登录,register:注册)
|
||||||
* @returns {Promise} 发送结果
|
* @returns {Promise} 发送结果
|
||||||
*/
|
*/
|
||||||
export function sendCode(data) {
|
export function sendCode(data) {
|
||||||
return request({
|
return request({
|
||||||
url: '/api/auth/code',
|
url: '/v1/auth/code',
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
data
|
data
|
||||||
})
|
})
|
||||||
@@ -52,7 +53,7 @@ export function sendCode(data) {
|
|||||||
*/
|
*/
|
||||||
export function getUserInfo() {
|
export function getUserInfo() {
|
||||||
return request({
|
return request({
|
||||||
url: '/api/auth/info',
|
url: '/v1/auth/info',
|
||||||
method: 'GET'
|
method: 'GET'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -63,7 +64,7 @@ export function getUserInfo() {
|
|||||||
*/
|
*/
|
||||||
export function refreshToken() {
|
export function refreshToken() {
|
||||||
return request({
|
return request({
|
||||||
url: '/api/auth/refresh',
|
url: '/v1/auth/refresh',
|
||||||
method: 'POST'
|
method: 'POST'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -86,7 +87,7 @@ export function logout() {
|
|||||||
*/
|
*/
|
||||||
export function wechatLogin(data) {
|
export function wechatLogin(data) {
|
||||||
return request({
|
return request({
|
||||||
url: '/api/auth/wechat-login',
|
url: '/v1/auth/wechat-login',
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
data
|
data
|
||||||
})
|
})
|
||||||
@@ -100,7 +101,7 @@ export function wechatLogin(data) {
|
|||||||
*/
|
*/
|
||||||
export function appleLogin(data) {
|
export function appleLogin(data) {
|
||||||
return request({
|
return request({
|
||||||
url: '/api/auth/apple-login',
|
url: '/v1/auth/apple-login',
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
data
|
data
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name" : "村客宝",
|
"name" : "存客宝",
|
||||||
"appid" : "",
|
"appid" : "",
|
||||||
"description" : "村客宝应用",
|
"description" : "存客宝应用",
|
||||||
"versionName" : "1.0.0",
|
"versionName" : "1.0.0",
|
||||||
"versionCode" : "100",
|
"versionCode" : "100",
|
||||||
"transformPx" : false,
|
"transformPx" : false,
|
||||||
@@ -69,6 +69,6 @@
|
|||||||
"enable" : true
|
"enable" : true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"title" : "村客宝"
|
"title" : "存客宝"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "cunkebao",
|
"name": "cunkebao",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "村客宝 - 基于 uni-app 的跨平台应用",
|
"description": "存客宝 - 基于 uni-app 的跨平台应用",
|
||||||
"main": "main.js",
|
"main": "main.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "echo \"Error: no test specified\" && exit 1"
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
|||||||
@@ -108,7 +108,7 @@
|
|||||||
],
|
],
|
||||||
"globalStyle": {
|
"globalStyle": {
|
||||||
"navigationBarTextStyle": "black",
|
"navigationBarTextStyle": "black",
|
||||||
"navigationBarTitleText": "村客宝",
|
"navigationBarTitleText": "存客宝",
|
||||||
"navigationBarBackgroundColor": "#F8F8F8",
|
"navigationBarBackgroundColor": "#F8F8F8",
|
||||||
"backgroundColor": "#F8F8F8"
|
"backgroundColor": "#F8F8F8"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -6,13 +6,13 @@
|
|||||||
></u-navbar>
|
></u-navbar>
|
||||||
|
|
||||||
<view class="content">
|
<view class="content">
|
||||||
<view class="title">村客宝隐私政策</view>
|
<view class="title">存客宝隐私政策</view>
|
||||||
<view class="date">生效日期:2023年1月1日</view>
|
<view class="date">生效日期:2023年1月1日</view>
|
||||||
|
|
||||||
<view class="section">
|
<view class="section">
|
||||||
<view class="section-title">一、引言</view>
|
<view class="section-title">一、引言</view>
|
||||||
<view class="paragraph">
|
<view class="paragraph">
|
||||||
村客宝(以下简称"我们")非常重视您的隐私和个人信息保护。本隐私政策旨在向您说明我们如何收集、使用、存储、共享和保护您的个人信息,以及您享有的相关权利。
|
存客宝(以下简称"我们")非常重视您的隐私和个人信息保护。本隐私政策旨在向您说明我们如何收集、使用、存储、共享和保护您的个人信息,以及您享有的相关权利。
|
||||||
</view>
|
</view>
|
||||||
<view class="paragraph">
|
<view class="paragraph">
|
||||||
请您在使用我们的服务前,仔细阅读并了解本隐私政策的全部内容。如您对本隐私政策有任何疑问,可随时联系我们的客服。
|
请您在使用我们的服务前,仔细阅读并了解本隐私政策的全部内容。如您对本隐私政策有任何疑问,可随时联系我们的客服。
|
||||||
|
|||||||
@@ -6,26 +6,26 @@
|
|||||||
></u-navbar>
|
></u-navbar>
|
||||||
|
|
||||||
<view class="content">
|
<view class="content">
|
||||||
<view class="title">村客宝用户协议</view>
|
<view class="title">存客宝用户协议</view>
|
||||||
<view class="date">生效日期:2023年1月1日</view>
|
<view class="date">生效日期:2023年1月1日</view>
|
||||||
|
|
||||||
<view class="section">
|
<view class="section">
|
||||||
<view class="section-title">一、总则</view>
|
<view class="section-title">一、协议的接受与变更</view>
|
||||||
<view class="paragraph">
|
<view class="paragraph">
|
||||||
1.1 村客宝用户协议(以下简称"本协议")是您与村客宝平台(以下简称"我们")之间就村客宝平台服务等相关事宜所订立的契约。
|
1.1 存客宝用户协议(以下简称"本协议")是您与存客宝平台(以下简称"我们")之间就存客宝平台服务等相关事宜所订立的契约。
|
||||||
</view>
|
</view>
|
||||||
<view class="paragraph">
|
<view class="paragraph">
|
||||||
1.2 您应当在使用村客宝平台服务之前认真阅读本协议全部内容。如您对本协议有任何疑问,可随时咨询我们的客服。
|
1.2 您应当在使用存客宝平台服务之前认真阅读本协议全部内容。如您对本协议有任何疑问,可随时咨询我们的客服。
|
||||||
</view>
|
</view>
|
||||||
<view class="paragraph">
|
<view class="paragraph">
|
||||||
1.3 您点击"同意"或"下一步",或您使用村客宝平台服务,即视为您已阅读并同意签署本协议。本协议自您确认同意之时起生效。
|
1.3 您点击"同意"或"下一步",或您使用存客宝平台服务,即视为您已阅读并同意签署本协议。本协议自您确认同意之时起生效。
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="section">
|
<view class="section">
|
||||||
<view class="section-title">二、账号注册与使用</view>
|
<view class="section-title">二、账号注册与使用</view>
|
||||||
<view class="paragraph">
|
<view class="paragraph">
|
||||||
2.1 您应当保证您具有完全民事行为能力,能够独立承担民事责任,并独立承担使用村客宝平台服务的一切法律责任。
|
2.1 您应当保证您具有完全民事行为能力,能够独立承担民事责任,并独立承担使用存客宝平台服务的一切法律责任。
|
||||||
</view>
|
</view>
|
||||||
<view class="paragraph">
|
<view class="paragraph">
|
||||||
2.2 您注册成功后,我们将给予您一个用户账号及相应的密码,该用户账号和密码由您负责保管。
|
2.2 您注册成功后,我们将给予您一个用户账号及相应的密码,该用户账号和密码由您负责保管。
|
||||||
@@ -38,7 +38,7 @@
|
|||||||
<view class="section">
|
<view class="section">
|
||||||
<view class="section-title">三、服务内容</view>
|
<view class="section-title">三、服务内容</view>
|
||||||
<view class="paragraph">
|
<view class="paragraph">
|
||||||
3.1 村客宝平台服务的具体内容由我们根据实际情况提供,包括但不限于信息发布、交易撮合、数据统计等。
|
3.1 存客宝平台服务的具体内容由我们根据实际情况提供,包括但不限于信息发布、交易撮合、数据统计等。
|
||||||
</view>
|
</view>
|
||||||
<view class="paragraph">
|
<view class="paragraph">
|
||||||
3.2 我们有权不经事先通知,随时变更、中断或终止部分或全部的服务。
|
3.2 我们有权不经事先通知,随时变更、中断或终止部分或全部的服务。
|
||||||
@@ -46,19 +46,19 @@
|
|||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="section">
|
<view class="section">
|
||||||
<view class="section-title">四、用户义务</view>
|
<view class="section-title">四、用户行为规范</view>
|
||||||
<view class="paragraph">
|
<view class="paragraph">
|
||||||
4.1 您在使用村客宝平台服务时,必须遵守中华人民共和国相关法律法规。
|
4.1 您在使用存客宝平台服务时,必须遵守中华人民共和国相关法律法规。
|
||||||
</view>
|
</view>
|
||||||
<view class="paragraph">
|
<view class="paragraph">
|
||||||
4.2 您不得利用村客宝平台服务从事违法违规行为,包括但不限于发布违法信息、侵犯他人知识产权等。
|
4.2 您不得利用存客宝平台服务从事违法违规行为,包括但不限于发布违法信息、侵犯他人知识产权等。
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="section">
|
<view class="section">
|
||||||
<view class="section-title">五、知识产权</view>
|
<view class="section-title">五、知识产权</view>
|
||||||
<view class="paragraph">
|
<view class="paragraph">
|
||||||
5.1 村客宝平台所包含的全部智力成果,包括但不限于程序、源代码、图标、图饰、图像、图表、文字等,均受著作权法、商标法、专利法及其他知识产权法律法规的保护。
|
5.1 存客宝平台所包含的全部智力成果,包括但不限于程序、源代码、图标、图饰、图像、图表、文字等,均受著作权法、商标法、专利法及其他知识产权法律法规的保护。
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
@@ -78,7 +78,7 @@
|
|||||||
7.1 我们有权随时修改本协议,并在修改后的协议生效前通过适当方式通知您。
|
7.1 我们有权随时修改本协议,并在修改后的协议生效前通过适当方式通知您。
|
||||||
</view>
|
</view>
|
||||||
<view class="paragraph">
|
<view class="paragraph">
|
||||||
7.2 如您不同意修改后的协议,可以选择停止使用村客宝平台服务;如您继续使用村客宝平台服务,则视为您已同意修改后的协议。
|
7.2 如您不同意修改后的协议,可以选择停止使用存客宝平台服务;如您继续使用存客宝平台服务,则视为您已同意修改后的协议。
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
|
|||||||
@@ -100,6 +100,8 @@
|
|||||||
<script>
|
<script>
|
||||||
import LineChart from '@/components/LineChart.vue'
|
import LineChart from '@/components/LineChart.vue'
|
||||||
import CustomTabBar from '@/components/CustomTabBar.vue'
|
import CustomTabBar from '@/components/CustomTabBar.vue'
|
||||||
|
import Auth from '@/utils/auth'
|
||||||
|
import { getUserInfo, logout } from '@/api/user'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
@@ -119,14 +121,42 @@ export default {
|
|||||||
{ icon: 'coupon', color: 'yellow', count: 167, label: '海报获客' },
|
{ icon: 'coupon', color: 'yellow', count: 167, label: '海报获客' },
|
||||||
{ icon: 'play-right', color: 'black', count: 156, label: '抖音获客' },
|
{ icon: 'play-right', color: 'black', count: 156, label: '抖音获客' },
|
||||||
{ icon: 'heart', color: 'red', count: 89, label: '小红书获客' }
|
{ icon: 'heart', color: 'red', count: 89, label: '小红书获客' }
|
||||||
]
|
],
|
||||||
|
userInfo: null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onLoad() {
|
onLoad() {
|
||||||
|
// 检查登录状态
|
||||||
|
if (!Auth.isLogin()) {
|
||||||
|
uni.reLaunch({
|
||||||
|
url: '/pages/login/index'
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取用户信息
|
||||||
|
this.fetchUserInfo();
|
||||||
|
|
||||||
// 加载数据
|
// 加载数据
|
||||||
this.loadData();
|
this.loadData();
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
// 获取用户信息
|
||||||
|
fetchUserInfo() {
|
||||||
|
// 先尝试从缓存获取
|
||||||
|
this.userInfo = Auth.getUserInfo();
|
||||||
|
|
||||||
|
// 然后从服务器获取最新信息
|
||||||
|
getUserInfo().then(res => {
|
||||||
|
if (res.code === 200) {
|
||||||
|
this.userInfo = res.data;
|
||||||
|
Auth.setUserInfo(res.data);
|
||||||
|
}
|
||||||
|
}).catch(err => {
|
||||||
|
console.error('获取用户信息失败:', err);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
// 加载数据
|
// 加载数据
|
||||||
loadData() {
|
loadData() {
|
||||||
// 这里可以添加API调用获取实际数据
|
// 这里可以添加API调用获取实际数据
|
||||||
@@ -139,6 +169,34 @@ export default {
|
|||||||
uni.navigateTo({
|
uni.navigateTo({
|
||||||
url: '/pages/notification/index'
|
url: '/pages/notification/index'
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
// 退出登录
|
||||||
|
handleLogout() {
|
||||||
|
uni.showModal({
|
||||||
|
title: '提示',
|
||||||
|
content: '确认退出登录吗?',
|
||||||
|
success: (res) => {
|
||||||
|
if (res.confirm) {
|
||||||
|
// 直接清除本地保存的登录信息
|
||||||
|
Auth.removeAll();
|
||||||
|
|
||||||
|
// 显示退出成功提示
|
||||||
|
uni.showToast({
|
||||||
|
title: '退出成功',
|
||||||
|
icon: 'success',
|
||||||
|
duration: 1500
|
||||||
|
});
|
||||||
|
|
||||||
|
// 跳转到登录页面
|
||||||
|
setTimeout(() => {
|
||||||
|
uni.reLaunch({
|
||||||
|
url: '/pages/login/index'
|
||||||
|
});
|
||||||
|
}, 1500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -174,6 +232,25 @@ export default {
|
|||||||
display: flex;
|
display: flex;
|
||||||
color: black;
|
color: black;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
|
.user-info {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-right: 20rpx;
|
||||||
|
padding: 8rpx 20rpx;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
border-radius: 30rpx;
|
||||||
|
|
||||||
|
.user-name {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #333;
|
||||||
|
margin-right: 8rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-bell {
|
||||||
|
margin-left: 10rpx;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,10 +24,10 @@
|
|||||||
<!-- 手机号输入 -->
|
<!-- 手机号输入 -->
|
||||||
<view class="input-box">
|
<view class="input-box">
|
||||||
<u--input
|
<u--input
|
||||||
v-model="form.mobile"
|
v-model="form.account"
|
||||||
placeholder="+86手机号"
|
placeholder="+86手机号"
|
||||||
prefixIcon="phone"
|
prefixIcon="phone"
|
||||||
prefixIconStyle="font-size: 52rpx;color: #909399;padding-right: 16rpx;"
|
prefixIconStyle="font-size: 40rpx; color: #909399; padding-right: 16rpx;"
|
||||||
clearable
|
clearable
|
||||||
type="number"
|
type="number"
|
||||||
maxlength="11"
|
maxlength="11"
|
||||||
@@ -71,7 +71,7 @@
|
|||||||
fontSize="30rpx"
|
fontSize="30rpx"
|
||||||
suffixIcon="eye"
|
suffixIcon="eye"
|
||||||
@clickSuffixIcon="showPassword = !showPassword"
|
@clickSuffixIcon="showPassword = !showPassword"
|
||||||
suffixIconStyle="font-size: 45rpx;"
|
suffixIconStyle="font-size: 40rpx;"
|
||||||
></u--input>
|
></u--input>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
@@ -101,9 +101,10 @@
|
|||||||
<!-- 登录按钮 -->
|
<!-- 登录按钮 -->
|
||||||
<u-button
|
<u-button
|
||||||
text="登录"
|
text="登录"
|
||||||
type="primary"
|
type="info"
|
||||||
|
:disabled="!canLogin"
|
||||||
@click="handleLogin"
|
@click="handleLogin"
|
||||||
customStyle="width: 100%; margin-top: 40rpx; height: 96rpx; border-radius: 24rpx; font-size: 32rpx; font-weight: 500;"
|
customStyle="width: 100%; margin-top: 40rpx; height: 96rpx; border-radius: 24rpx; font-size: 40rpx; font-weight: bold; background-color: #2563eb; color: #fff;"
|
||||||
></u-button>
|
></u-button>
|
||||||
|
|
||||||
<!-- 分割线 -->
|
<!-- 分割线 -->
|
||||||
@@ -117,13 +118,13 @@
|
|||||||
<view class="other-login">
|
<view class="other-login">
|
||||||
<!-- 微信登录 -->
|
<!-- 微信登录 -->
|
||||||
<button class="wechat-btn" @click="handleWechatLogin">
|
<button class="wechat-btn" @click="handleWechatLogin">
|
||||||
<u-icon name="weixin-fill" size="56" color="#07c160" class="wechat-icon"></u-icon>
|
<u-icon name="weixin-fill" size="44" color="#07c160" class="wechat-icon"></u-icon>
|
||||||
<text>使用微信登录</text>
|
<text>使用微信登录</text>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<!-- Apple登录 -->
|
<!-- Apple登录 -->
|
||||||
<button class="apple-btn" @click="handleAppleLogin">
|
<button class="apple-btn" @click="handleAppleLogin">
|
||||||
<u-icon name="apple-fill" size="56" color="#333333" class="apple-icon"></u-icon>
|
<u-icon name="apple-fill" size="44" color="#333333" class="apple-icon"></u-icon>
|
||||||
<text>使用 Apple 登录</text>
|
<text>使用 Apple 登录</text>
|
||||||
</button>
|
</button>
|
||||||
</view>
|
</view>
|
||||||
@@ -135,6 +136,9 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { login, mobileLogin, sendCode } from '@/api/user'
|
||||||
|
import Auth from '@/utils/auth'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@@ -144,9 +148,10 @@ export default {
|
|||||||
],
|
],
|
||||||
current: 0,
|
current: 0,
|
||||||
form: {
|
form: {
|
||||||
mobile: '',
|
account: '',
|
||||||
code: '',
|
code: '',
|
||||||
password: ''
|
password: '',
|
||||||
|
typeId: 1 // 默认账号类型为运营后台/操盘手
|
||||||
},
|
},
|
||||||
showPassword: false,
|
showPassword: false,
|
||||||
isAgree: false,
|
isAgree: false,
|
||||||
@@ -161,7 +166,7 @@ export default {
|
|||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
isValidMobile() {
|
isValidMobile() {
|
||||||
return /^1\d{10}$/.test(this.form.mobile)
|
return /^1\d{10}$/.test(this.form.account)
|
||||||
},
|
},
|
||||||
canLogin() {
|
canLogin() {
|
||||||
if (!this.isAgree || !this.isValidMobile) return false
|
if (!this.isAgree || !this.isValidMobile) return false
|
||||||
@@ -185,18 +190,48 @@ export default {
|
|||||||
},
|
},
|
||||||
getCode() {
|
getCode() {
|
||||||
if (this.sending || !this.isValidMobile) return
|
if (this.sending || !this.isValidMobile) return
|
||||||
this.sending = true
|
|
||||||
this.codeTips = '60s'
|
// 发送验证码接口调用
|
||||||
let seconds = 60
|
sendCode({
|
||||||
const timer = setInterval(() => {
|
account: this.form.account,
|
||||||
seconds--
|
type: 'login'
|
||||||
this.codeTips = `${seconds}s`
|
}).then(res => {
|
||||||
if (seconds <= 0) {
|
if (res.code === 200) {
|
||||||
clearInterval(timer)
|
// 发送成功,开始倒计时
|
||||||
|
this.sending = true
|
||||||
|
this.codeTips = '60s'
|
||||||
|
let seconds = 60
|
||||||
|
const timer = setInterval(() => {
|
||||||
|
seconds--
|
||||||
|
this.codeTips = `${seconds}s`
|
||||||
|
if (seconds <= 0) {
|
||||||
|
clearInterval(timer)
|
||||||
|
this.sending = false
|
||||||
|
this.codeTips = '发送验证码'
|
||||||
|
}
|
||||||
|
}, 1000)
|
||||||
|
|
||||||
|
// 提示用户
|
||||||
|
uni.showToast({
|
||||||
|
title: '验证码已发送',
|
||||||
|
icon: 'success'
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// 发送失败
|
||||||
|
uni.showToast({
|
||||||
|
title: res.msg || '验证码发送失败',
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
this.sending = false
|
this.sending = false
|
||||||
this.codeTips = '发送验证码'
|
|
||||||
}
|
}
|
||||||
}, 1000)
|
}).catch(err => {
|
||||||
|
console.error('发送验证码失败:', err)
|
||||||
|
uni.showToast({
|
||||||
|
title: '验证码发送失败,请重试',
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
this.sending = false
|
||||||
|
})
|
||||||
},
|
},
|
||||||
handleLogin() {
|
handleLogin() {
|
||||||
if (!this.canLogin) {
|
if (!this.canLogin) {
|
||||||
@@ -237,42 +272,69 @@ export default {
|
|||||||
mask: true
|
mask: true
|
||||||
})
|
})
|
||||||
|
|
||||||
// 模拟登录成功
|
// 根据当前登录方式选择不同的登录API
|
||||||
setTimeout(() => {
|
const loginAction = this.current === 0 ?
|
||||||
|
mobileLogin({
|
||||||
|
account: this.form.account,
|
||||||
|
code: this.form.code,
|
||||||
|
typeId: this.form.typeId
|
||||||
|
}) :
|
||||||
|
login({
|
||||||
|
account: this.form.account,
|
||||||
|
password: this.form.password,
|
||||||
|
typeId: this.form.typeId
|
||||||
|
});
|
||||||
|
|
||||||
|
// 调用登录接口
|
||||||
|
loginAction.then(res => {
|
||||||
// 隐藏加载提示
|
// 隐藏加载提示
|
||||||
uni.hideLoading()
|
uni.hideLoading()
|
||||||
|
|
||||||
// 保存登录状态和用户信息
|
if (res.code === 200) {
|
||||||
uni.setStorageSync('token', 'mock_token_' + Date.now())
|
// 登录成功,保存token和用户信息
|
||||||
uni.setStorageSync('userInfo', {
|
Auth.setToken(res.data.token, res.data.token_expired - Math.floor(Date.now() / 1000));
|
||||||
mobile: this.form.mobile,
|
Auth.setUserInfo(res.data.member);
|
||||||
loginTime: Date.now()
|
|
||||||
})
|
// 显示登录成功提示
|
||||||
|
uni.showToast({
|
||||||
// 显示登录成功提示
|
title: '登录成功',
|
||||||
uni.showToast({
|
icon: 'success',
|
||||||
title: '登录成功',
|
duration: 1500
|
||||||
icon: 'success',
|
|
||||||
duration: 1500
|
|
||||||
})
|
|
||||||
|
|
||||||
// 延迟跳转到首页
|
|
||||||
setTimeout(() => {
|
|
||||||
uni.reLaunch({
|
|
||||||
url: '/pages/index/index',
|
|
||||||
success: () => {
|
|
||||||
console.log('跳转到首页成功')
|
|
||||||
},
|
|
||||||
fail: (err) => {
|
|
||||||
console.error('跳转失败:', err)
|
|
||||||
uni.showToast({
|
|
||||||
title: '跳转失败,请重试',
|
|
||||||
icon: 'none'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}, 1500)
|
|
||||||
}, 1000)
|
// 延迟跳转到首页
|
||||||
|
setTimeout(() => {
|
||||||
|
uni.reLaunch({
|
||||||
|
url: '/pages/index/index',
|
||||||
|
success: () => {
|
||||||
|
console.log('跳转到首页成功')
|
||||||
|
},
|
||||||
|
fail: (err) => {
|
||||||
|
console.error('跳转失败:', err)
|
||||||
|
uni.showToast({
|
||||||
|
title: '跳转失败,请重试',
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}, 1500)
|
||||||
|
} else {
|
||||||
|
// 登录失败
|
||||||
|
uni.showToast({
|
||||||
|
title: res.msg || '登录失败',
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}).catch(err => {
|
||||||
|
// 隐藏加载提示
|
||||||
|
uni.hideLoading()
|
||||||
|
|
||||||
|
console.error('登录失败:', err)
|
||||||
|
uni.showToast({
|
||||||
|
title: '登录失败,请重试',
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
})
|
||||||
},
|
},
|
||||||
handleWechatLogin() {
|
handleWechatLogin() {
|
||||||
console.log('微信登录')
|
console.log('微信登录')
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
<!-- 用户信息卡片 -->
|
<!-- 用户信息卡片 -->
|
||||||
<view class="user-card">
|
<view class="user-card">
|
||||||
<view class="avatar-wrap">
|
<view class="avatar-wrap">
|
||||||
<template v-if="userInfo.avatar">
|
<template v-if="userInfo && userInfo.avatar">
|
||||||
<image class="avatar" :src="userInfo.avatar"></image>
|
<image class="avatar" :src="userInfo.avatar"></image>
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
@@ -22,8 +22,8 @@
|
|||||||
</template>
|
</template>
|
||||||
</view>
|
</view>
|
||||||
<view class="user-info">
|
<view class="user-info">
|
||||||
<view class="username">卡若</view>
|
<view class="username">{{ userInfo && userInfo.username ? userInfo.username : '未设置昵称' }}</view>
|
||||||
<view class="account">账号: 84675209</view>
|
<view class="account">账号: {{ userInfo && userInfo.account ? userInfo.account : '未登录' }}</view>
|
||||||
<view class="edit-profile-btn" @click="editProfile">
|
<view class="edit-profile-btn" @click="editProfile">
|
||||||
编辑资料
|
编辑资料
|
||||||
</view>
|
</view>
|
||||||
@@ -74,6 +74,8 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import CustomTabBar from '@/components/CustomTabBar.vue'
|
import CustomTabBar from '@/components/CustomTabBar.vue'
|
||||||
|
import Auth from '@/utils/auth'
|
||||||
|
import { getUserInfo, logout } from '@/api/user'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
@@ -81,28 +83,48 @@ export default {
|
|||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
userInfo: {
|
userInfo: null
|
||||||
avatar: null,
|
|
||||||
username: '卡若',
|
|
||||||
account: '84675209'
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
onShow() {
|
||||||
|
// 每次显示页面时获取最新的用户信息
|
||||||
|
this.getUserInfo();
|
||||||
|
},
|
||||||
onLoad() {
|
onLoad() {
|
||||||
|
// 检查登录状态
|
||||||
|
if (!Auth.isLogin()) {
|
||||||
|
uni.reLaunch({
|
||||||
|
url: '/pages/login/index'
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// 获取用户信息
|
// 获取用户信息
|
||||||
this.getUserInfo();
|
this.getUserInfo();
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
// 获取用户信息
|
// 获取用户信息
|
||||||
getUserInfo() {
|
getUserInfo() {
|
||||||
// 这里可以添加获取用户信息的API调用
|
// 先从本地缓存获取
|
||||||
console.log('获取用户信息');
|
const cachedUserInfo = Auth.getUserInfo();
|
||||||
// 示例数据,实际应从API获取
|
if (cachedUserInfo) {
|
||||||
this.userInfo = {
|
this.userInfo = cachedUserInfo;
|
||||||
avatar: 'https://images.unsplash.com/photo-1568602471122-7832951cc4c5?w=400&h=400&auto=format&fit=crop',
|
}
|
||||||
username: '卡若',
|
|
||||||
account: '84675209'
|
// 同时从服务器获取最新信息
|
||||||
};
|
getUserInfo().then(res => {
|
||||||
|
if (res.code === 200) {
|
||||||
|
this.userInfo = res.data;
|
||||||
|
// 更新本地缓存
|
||||||
|
Auth.setUserInfo(res.data);
|
||||||
|
}
|
||||||
|
}).catch(err => {
|
||||||
|
console.error('获取用户信息失败:', err);
|
||||||
|
// 如果获取失败但有缓存,使用缓存数据
|
||||||
|
if (!this.userInfo) {
|
||||||
|
this.userInfo = Auth.getUserInfo();
|
||||||
|
}
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
// 跳转到设置页面
|
// 跳转到设置页面
|
||||||
@@ -140,14 +162,22 @@ export default {
|
|||||||
content: '确定要退出登录吗?',
|
content: '确定要退出登录吗?',
|
||||||
success: (res) => {
|
success: (res) => {
|
||||||
if (res.confirm) {
|
if (res.confirm) {
|
||||||
// 清除登录状态
|
// 直接清除本地保存的登录信息
|
||||||
// uni.removeStorageSync('token');
|
Auth.removeAll();
|
||||||
// uni.removeStorageSync('userInfo');
|
|
||||||
|
// 显示退出成功提示
|
||||||
|
uni.showToast({
|
||||||
|
title: '退出成功',
|
||||||
|
icon: 'success',
|
||||||
|
duration: 1500
|
||||||
|
});
|
||||||
|
|
||||||
// 跳转到登录页面
|
// 跳转到登录页面
|
||||||
uni.reLaunch({
|
setTimeout(() => {
|
||||||
url: '/pages/login/index'
|
uni.reLaunch({
|
||||||
});
|
url: '/pages/login/index'
|
||||||
|
});
|
||||||
|
}, 1500);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -178,7 +208,9 @@ export default {
|
|||||||
z-index: 999;
|
z-index: 999;
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
font-size: 40rpx;
|
font-size: 45rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #2664ec;
|
||||||
}
|
}
|
||||||
|
|
||||||
.header-icons {
|
.header-icons {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* 认证相关工具函数
|
* 认证相关工具函数
|
||||||
*/
|
*/
|
||||||
|
import { refreshToken } from '@/api/user';
|
||||||
|
|
||||||
const TOKEN_KEY = 'token';
|
const TOKEN_KEY = 'token';
|
||||||
const TOKEN_EXPIRES_KEY = 'token_expires';
|
const TOKEN_EXPIRES_KEY = 'token_expires';
|
||||||
@@ -67,6 +68,28 @@ function removeAll() {
|
|||||||
removeUserInfo();
|
removeUserInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 刷新Token
|
||||||
|
* @returns {Promise} 刷新结果
|
||||||
|
*/
|
||||||
|
function refreshTokenAsync() {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
refreshToken()
|
||||||
|
.then(res => {
|
||||||
|
if (res.code === 200) {
|
||||||
|
// 更新Token
|
||||||
|
setToken(res.data.token, res.data.token_expired - Math.floor(Date.now() / 1000));
|
||||||
|
resolve(res);
|
||||||
|
} else {
|
||||||
|
reject(res);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
reject(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 判断是否已登录
|
* 判断是否已登录
|
||||||
* @returns {boolean} 是否已登录
|
* @returns {boolean} 是否已登录
|
||||||
@@ -84,6 +107,24 @@ function isLogin() {
|
|||||||
return nowTime < expiresTime;
|
return nowTime < expiresTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取用户类型
|
||||||
|
* @returns {number} 用户类型ID
|
||||||
|
*/
|
||||||
|
function getUserType() {
|
||||||
|
const userInfo = getUserInfo();
|
||||||
|
return userInfo ? userInfo.typeId || 0 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否为管理员
|
||||||
|
* @returns {boolean} 是否为管理员
|
||||||
|
*/
|
||||||
|
function isAdmin() {
|
||||||
|
const userInfo = getUserInfo();
|
||||||
|
return userInfo ? !!userInfo.isAdmin : false;
|
||||||
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
setToken,
|
setToken,
|
||||||
getToken,
|
getToken,
|
||||||
@@ -92,5 +133,8 @@ export default {
|
|||||||
getUserInfo,
|
getUserInfo,
|
||||||
removeUserInfo,
|
removeUserInfo,
|
||||||
removeAll,
|
removeAll,
|
||||||
isLogin
|
isLogin,
|
||||||
|
refreshToken: refreshTokenAsync,
|
||||||
|
getUserType,
|
||||||
|
isAdmin
|
||||||
};
|
};
|
||||||
@@ -1,9 +1,7 @@
|
|||||||
import Auth from './auth';
|
import Auth from './auth';
|
||||||
|
|
||||||
// 服务器地址
|
// 服务器地址
|
||||||
const BASE_URL = process.env.NODE_ENV === 'development'
|
const BASE_URL = process.env.VUE_APP_BASE_API || 'http://yishi.com';
|
||||||
? 'http://localhost:8080'
|
|
||||||
: 'https://api.example.com';
|
|
||||||
|
|
||||||
// 请求超时时间
|
// 请求超时时间
|
||||||
const TIMEOUT = 10000;
|
const TIMEOUT = 10000;
|
||||||
@@ -17,7 +15,7 @@ function requestInterceptor(config) {
|
|||||||
// 获取 token
|
// 获取 token
|
||||||
const token = uni.getStorageSync('token');
|
const token = uni.getStorageSync('token');
|
||||||
|
|
||||||
// 如果有 token,则带上请求头
|
// 如果有 token,则带上请求头 Authorization: Bearer + token
|
||||||
if (token) {
|
if (token) {
|
||||||
config.header = {
|
config.header = {
|
||||||
...config.header,
|
...config.header,
|
||||||
@@ -39,11 +37,8 @@ function requestInterceptor(config) {
|
|||||||
function responseInterceptor(response) {
|
function responseInterceptor(response) {
|
||||||
// 未登录或token失效 - 取消登录拦截
|
// 未登录或token失效 - 取消登录拦截
|
||||||
if (response.data.code === 401) {
|
if (response.data.code === 401) {
|
||||||
// 只在控制台打印信息,不进行拦截
|
console.log('登录已过期,需要重新登录');
|
||||||
console.log('登录已过期,但不进行拦截');
|
|
||||||
|
|
||||||
/*
|
|
||||||
// 以下代码已注释,取消登录拦截
|
|
||||||
// 清除登录信息
|
// 清除登录信息
|
||||||
Auth.removeToken();
|
Auth.removeToken();
|
||||||
Auth.removeUserInfo();
|
Auth.removeUserInfo();
|
||||||
@@ -54,29 +49,43 @@ function responseInterceptor(response) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
return Promise.reject(new Error('登录已过期,请重新登录'));
|
return Promise.reject(new Error('登录已过期,请重新登录'));
|
||||||
*/
|
|
||||||
|
|
||||||
// 直接返回响应,不拦截
|
|
||||||
return response.data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// token需要刷新 - 取消登录拦截
|
// token需要刷新 - 410 状态码
|
||||||
if (response.data.code === 410) {
|
if (response.data.code === 410) {
|
||||||
// 只在控制台打印信息,不进行拦截
|
// 尝试刷新 token
|
||||||
console.log('Token需要刷新,但不进行拦截');
|
return Auth.refreshToken()
|
||||||
|
.then(res => {
|
||||||
/*
|
if (res.code === 200) {
|
||||||
// 以下代码已注释,取消登录拦截
|
// 更新本地token
|
||||||
// 处理token刷新逻辑,这里简化处理
|
Auth.setToken(res.data.token, res.data.token_expired - Math.floor(Date.now() / 1000));
|
||||||
uni.reLaunch({
|
|
||||||
url: '/pages/login/index'
|
// 使用新token重试原请求
|
||||||
});
|
const config = response.config;
|
||||||
|
config.header.Authorization = `Bearer ${res.data.token}`;
|
||||||
return Promise.reject(new Error('登录已过期,请重新登录'));
|
|
||||||
*/
|
// 重新发起请求
|
||||||
|
return request(config);
|
||||||
// 直接返回响应,不拦截
|
} else {
|
||||||
return response.data;
|
// 刷新失败,跳转到登录页
|
||||||
|
uni.reLaunch({
|
||||||
|
url: '/pages/login/index'
|
||||||
|
});
|
||||||
|
return Promise.reject(new Error('登录已过期,请重新登录'));
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.error('刷新token失败', err);
|
||||||
|
// 清除登录信息
|
||||||
|
Auth.removeToken();
|
||||||
|
Auth.removeUserInfo();
|
||||||
|
|
||||||
|
// 跳转到登录页
|
||||||
|
uni.reLaunch({
|
||||||
|
url: '/pages/login/index'
|
||||||
|
});
|
||||||
|
return Promise.reject(new Error('登录已过期,请重新登录'));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return response.data;
|
return response.data;
|
||||||
|
|||||||
@@ -110,9 +110,14 @@ class User extends Model
|
|||||||
$user->lastLoginTime = time();
|
$user->lastLoginTime = time();
|
||||||
$user->save();
|
$user->save();
|
||||||
|
|
||||||
|
// 用手机号当做默认用户名(如果没有设置用户名)
|
||||||
|
$username = $user->username ?: $user->account;
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'id' => $user->id,
|
'id' => $user->id,
|
||||||
|
'username' => $username,
|
||||||
'account' => $user->account,
|
'account' => $user->account,
|
||||||
|
'avatar' => $user->avatar,
|
||||||
'isAdmin' => $user->isAdmin,
|
'isAdmin' => $user->isAdmin,
|
||||||
'companyId' => $user->companyId,
|
'companyId' => $user->companyId,
|
||||||
'typeId' => $user->typeId,
|
'typeId' => $user->typeId,
|
||||||
@@ -137,14 +142,21 @@ class User extends Model
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 用手机号当做默认用户名(如果没有设置用户名)
|
||||||
|
$username = $user->username ?: $user->account;
|
||||||
|
// 默认头像地址
|
||||||
|
$avatar = $user->avatar ?: '';
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'id' => $user->id,
|
'id' => $user->id,
|
||||||
|
'username' => $username,
|
||||||
'account' => $user->account,
|
'account' => $user->account,
|
||||||
|
'avatar' => $avatar,
|
||||||
'isAdmin' => $user->isAdmin,
|
'isAdmin' => $user->isAdmin,
|
||||||
'companyId' => $user->companyId,
|
'companyId' => $user->companyId,
|
||||||
'typeId' => $user->typeId,
|
'typeId' => $user->typeId,
|
||||||
'role' => $user->isAdmin ? 'admin' : 'user',
|
'lastLoginIp' => $user->lastLoginIp,
|
||||||
'permissions' => $user->isAdmin ? ['*'] : ['user']
|
'lastLoginTime' => $user->lastLoginTime
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user