222
This commit is contained in:
parent
0fd7cf4c72
commit
63fb522484
|
|
@ -0,0 +1,27 @@
|
|||
# 实现邀请码升级功能
|
||||
|
||||
## 1. 修改 Waitlist.vue 组件
|
||||
- 在现有界面中添加邀请码输入框和提交按钮
|
||||
- 设计输入框样式与现有界面风格保持一致
|
||||
- 添加表单验证逻辑
|
||||
|
||||
## 2. 引入必要的模块和方法
|
||||
- 引入 user 模块的 upgrade 方法
|
||||
- 引入 auth store 的 updateUserInfo 方法
|
||||
- 引入 ElMessage 用于显示操作结果
|
||||
|
||||
## 3. 实现提交逻辑
|
||||
1. 用户输入邀请码并点击提交按钮
|
||||
2. 调用 `/views/user/index.js` 中的 `upgrade` 方法
|
||||
3. 成功后调用 `/stores/auth.js` 中的 `updateUserInfo` 方法刷新用户信息
|
||||
4. 刷新成功后返回首页
|
||||
|
||||
## 4. 添加错误处理
|
||||
- 邀请码验证失败时显示错误信息
|
||||
- 网络请求失败时显示错误提示
|
||||
- 确保用户体验流畅
|
||||
|
||||
## 5. 界面优化
|
||||
- 输入框添加合适的占位符
|
||||
- 按钮状态管理(加载中、禁用等)
|
||||
- 保持响应式设计,适配不同屏幕尺寸
|
||||
|
|
@ -4,6 +4,9 @@ import { useRouter, useRoute } from 'vue-router'
|
|||
import MainLayout from '@/components/layout/MainLayout.vue'
|
||||
import AppHeader from '@/components/layout/AppHeader.vue'
|
||||
import AppSidebar from '@/components/layout/AppSidebar.vue'
|
||||
import { useAuthStore } from '@/stores/auth';
|
||||
const authStore = useAuthStore();
|
||||
authStore.updateUserInfo()
|
||||
const route = useRoute()
|
||||
// 判断当前是否为登录页面
|
||||
const isLoginPage = computed(() => route.path === '/login')
|
||||
|
|
|
|||
|
|
@ -173,6 +173,14 @@ router.beforeEach(async (to, from, next) => {
|
|||
// window.localStorage.setItem('token','123')
|
||||
// return next()
|
||||
// }
|
||||
if(to.path=='/login'||to.path=='/login/phone'||to.path=='/register'||to.path=='/forgot-password'){
|
||||
const token = localStorage.getItem('token')
|
||||
// 如果有 token,跳转到首页
|
||||
if (token) {
|
||||
next('/czhome')
|
||||
return
|
||||
}
|
||||
}
|
||||
const newto = freeRoutes.find(route => route.path == to.path)
|
||||
if (newto?.meta?.requiresAuth) {
|
||||
const token = localStorage.getItem('token')
|
||||
|
|
@ -184,8 +192,10 @@ router.beforeEach(async (to, from, next) => {
|
|||
}
|
||||
// 检查是否需要添加动态路由
|
||||
const authStore = useAuthStore();
|
||||
const user_role = authStore.user?.user_role;
|
||||
if(user_role != '0' && router.getRoutes().length == routes.length) {
|
||||
// const info = await authStore.updateUserInfo();
|
||||
// console.log(info,'infoinfo');
|
||||
const user_role = authStore.user?.userRole;
|
||||
if((user_role == 1||user_role == 2) && router.getRoutes().length == routes.length) {
|
||||
// 添加动态路由
|
||||
addDynamicRoutes();
|
||||
if(isDynamicRoute(to.path)) {
|
||||
|
|
@ -195,7 +205,7 @@ router.beforeEach(async (to, from, next) => {
|
|||
}, 20);
|
||||
return
|
||||
}
|
||||
}else if(user_role == '0'){
|
||||
}else if(user_role == 0){
|
||||
// 恢复默认路由
|
||||
removeDynamicRoutes()
|
||||
router.addRoute(
|
||||
|
|
|
|||
|
|
@ -57,9 +57,11 @@ export const useAuthStore = defineStore('auth', () => {
|
|||
//登录成功方法
|
||||
const loginSuccess = (data,callback=null) => {
|
||||
token.value = data.accessToken
|
||||
user.value = data
|
||||
// user.value = data
|
||||
localStorage.setItem('token', token.value);
|
||||
callback&&callback(data);
|
||||
updateUserInfo().then(res => {
|
||||
callback&&callback(data);
|
||||
})
|
||||
}
|
||||
// 登出方法
|
||||
const logout = async (callback) => {
|
||||
|
|
@ -79,8 +81,28 @@ export const useAuthStore = defineStore('auth', () => {
|
|||
window?.Redirectlogin()
|
||||
}
|
||||
}
|
||||
|
||||
//更新用户信息方法
|
||||
const updateUserInfo = async (data) => {
|
||||
if(!token.value){
|
||||
return
|
||||
}
|
||||
return new Promise(async (resolve, reject) => {
|
||||
try {
|
||||
const res = await requestUtils.common(clientApi.default.USER_INFO, data)
|
||||
if(res.code === 0){
|
||||
let data = res.data;
|
||||
// 更新成功,保存用户信息
|
||||
user.value = data
|
||||
resolve(res)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('更新用户信息失败:', error)
|
||||
reject(error)
|
||||
}
|
||||
})
|
||||
}
|
||||
return {
|
||||
updateUserInfo,
|
||||
user,
|
||||
token,
|
||||
login,
|
||||
|
|
|
|||
|
|
@ -138,7 +138,6 @@ const goToRegister = () => {
|
|||
const goToPhoneLogin = () => {
|
||||
router.push('/login/phone')
|
||||
}
|
||||
|
||||
// 页面挂载时初始化认证状态
|
||||
onMounted(() => {
|
||||
})
|
||||
|
|
|
|||
|
|
@ -480,7 +480,7 @@ const handleCreatePromptCard = (index,params) => {
|
|||
status:'loading',
|
||||
imgyt:imgyt||'',
|
||||
type:'image',
|
||||
inspirationImage:cardData.inspirationImage||'',
|
||||
// inspirationImage:cardData.inspirationImage||'',
|
||||
},index);
|
||||
console.log(newCard,'newCardnewCard');
|
||||
// 添加到卡片数组
|
||||
|
|
|
|||
|
|
@ -9,6 +9,24 @@
|
|||
</div>
|
||||
<div class="waitlist-title">{{ t('waitlist.title') }}</div>
|
||||
<div class="waitlist-description">{{ t('waitlist.description') }}</div>
|
||||
|
||||
<!-- 邀请码输入区域 -->
|
||||
<div class="invite-code-section">
|
||||
<el-input
|
||||
v-model="inviteCode"
|
||||
placeholder="请输入邀请码"
|
||||
class="invite-code-input"
|
||||
clearable
|
||||
/>
|
||||
<button
|
||||
class="primary-button"
|
||||
@click="submitInviteCode"
|
||||
:loading="submitting"
|
||||
>
|
||||
提交邀请码
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="action-buttons">
|
||||
<button class="primary-button" @click="goHome">
|
||||
{{ t('waitlist.goHome') }}
|
||||
|
|
@ -26,20 +44,60 @@
|
|||
<script>
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { ref } from 'vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { UserController } from './user/index.js'
|
||||
import { useAuthStore } from '@/stores/auth.js'
|
||||
|
||||
export default {
|
||||
name: 'Waitlist',
|
||||
setup() {
|
||||
const { t } = useI18n()
|
||||
const router = useRouter()
|
||||
const authStore = useAuthStore()
|
||||
const userController = new UserController()
|
||||
|
||||
const inviteCode = ref('')
|
||||
const submitting = ref(false)
|
||||
|
||||
const goHome = () => {
|
||||
router.push('/')
|
||||
}
|
||||
|
||||
// 提交邀请码升级
|
||||
const submitInviteCode = async () => {
|
||||
if (!inviteCode.value.trim()) {
|
||||
ElMessage.warning('请输入邀请码')
|
||||
return
|
||||
}
|
||||
|
||||
submitting.value = true
|
||||
try {
|
||||
// 调用upgrade方法
|
||||
const upgradeRes = await userController.upgrade({ inviteCode: inviteCode.value })
|
||||
if (upgradeRes.code === 0) {
|
||||
// 升级成功,刷新用户信息
|
||||
await authStore.updateUserInfo()
|
||||
ElMessage.success('升级成功')
|
||||
// 返回首页
|
||||
goHome()
|
||||
} else {
|
||||
ElMessage.error(upgradeRes.message || '升级失败')
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('升级失败:', error)
|
||||
ElMessage.error(error.message || '升级失败,请稍后重试')
|
||||
} finally {
|
||||
submitting.value = false
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
t,
|
||||
goHome
|
||||
goHome,
|
||||
inviteCode,
|
||||
submitting,
|
||||
submitInviteCode
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -150,6 +208,48 @@ export default {
|
|||
left: 10%;
|
||||
}
|
||||
|
||||
/* 邀请码输入区域样式 */
|
||||
.invite-code-section {
|
||||
margin-bottom: 30px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.invite-code-input {
|
||||
width: 100%;
|
||||
max-width: 400px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.invite-code-input :deep(.el-input__wrapper) {
|
||||
border-radius: 8px;
|
||||
border: 1px solid rgba(107, 70, 193, 0.3);
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.invite-code-input :deep(.el-input__wrapper:hover) {
|
||||
border-color: rgba(107, 70, 193, 0.6);
|
||||
box-shadow: 0 0 0 2px rgba(107, 70, 193, 0.1);
|
||||
}
|
||||
|
||||
.invite-code-input :deep(.el-input__wrapper.is-focus) {
|
||||
border-color: #6B46C1;
|
||||
box-shadow: 0 0 0 2px rgba(107, 70, 193, 0.2);
|
||||
}
|
||||
|
||||
/* 按钮加载状态样式 */
|
||||
.primary-button:disabled {
|
||||
opacity: 0.7;
|
||||
cursor: not-allowed;
|
||||
transform: none !important;
|
||||
}
|
||||
|
||||
.primary-button:disabled:hover {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.waitlist-title {
|
||||
font-size: 2rem;
|
||||
|
|
@ -167,6 +267,10 @@ export default {
|
|||
.primary-button {
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
.invite-code-input {
|
||||
max-width: 300px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
|
|
@ -193,5 +297,9 @@ export default {
|
|||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
|
||||
.invite-code-input {
|
||||
max-width: 250px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -53,4 +53,41 @@ export class UserController {
|
|||
}
|
||||
*/
|
||||
}
|
||||
// 返回用户信息
|
||||
async getUserInfo() {
|
||||
return await requestUtils.common(clientApi.default.USER_INFO);
|
||||
/*
|
||||
返回示例:
|
||||
{
|
||||
"code": 0,
|
||||
"success": true,
|
||||
"data": {
|
||||
"id": 9007199254740991,
|
||||
"nickname": "string",
|
||||
"email": "string",
|
||||
"avatarUrl": "string",
|
||||
"phone": "string",
|
||||
"lastActive": "2025-12-19T09:45:20.801Z",
|
||||
"status": "string",
|
||||
"userRole": 1073741824,
|
||||
"inviteCode": "string",
|
||||
"otherInfo": {
|
||||
"additionalProp1": {},
|
||||
"additionalProp2": {},
|
||||
"additionalProp3": {}
|
||||
},
|
||||
"createdAt": "2025-12-19T09:45:20.801Z",
|
||||
"updatedAt": "2025-12-19T09:45:20.801Z"
|
||||
},
|
||||
"message": "操作成功"
|
||||
}
|
||||
*/
|
||||
}
|
||||
// 候补会员使用邀请码升级为正式会员
|
||||
async upgrade(data) {
|
||||
let parmas = {
|
||||
inviteCode:data.inviteCode,
|
||||
}
|
||||
return await requestUtils.common(clientApi.default.UPGRADE,parmas);
|
||||
}
|
||||
}
|
||||
|
|
@ -4,5 +4,7 @@ const login = {
|
|||
INVITE_CODES:{url:'/api-base/user/invite/codes',method:'GET'},// 返回当前用户的邀请码列表及使用状态
|
||||
INVITE_RECORDS:{url:'/api-base/user/invite/records',method:'GET'},// 返回邀请的用户列表,包含奖励明细
|
||||
combined:{url:'/api-base/prompt/active',method:'GET'},// 返回动态提示词
|
||||
UPGRADE:{url:'/api-base/user/upgrade',method:'POST'},// 候补会员使用邀请码升级为正式会员
|
||||
USER_INFO:{url:'/api-base/user/info',method:'GET',isLoading:true},// 返回用户信息
|
||||
}
|
||||
export default login;
|
||||
|
|
|
|||
Loading…
Reference in New Issue