1852 lines
55 KiB
Vue
1852 lines
55 KiB
Vue
<template>
|
||
<view class="container">
|
||
<!-- 未登录状态 -->
|
||
<view v-if="!isLoggedIn" class="user-header">
|
||
<view class="user-avatar">
|
||
<text class="avatar-emoji"></text>
|
||
</view>
|
||
<view class="user-info">
|
||
<text class="user-name">你好,欢迎使用习正陪读</text>
|
||
<text class="login-tip">登录后享受更多服务</text>
|
||
</view>
|
||
<view class="login-btn" @click="goToRoleSelect">
|
||
<text>登录/注册</text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 已登录状态 -->
|
||
<view v-else class="user-header">
|
||
<view class="user-avatar">
|
||
<image
|
||
v-if="userInfo.avatar"
|
||
:src="userInfo.avatar"
|
||
class="avatar-image"
|
||
mode="aspectFill"
|
||
/>
|
||
<text v-else class="avatar-emoji">👤</text>
|
||
</view>
|
||
<view class="user-info">
|
||
<text class="user-name">{{ roleName }}</text>
|
||
<text class="user-phone" v-if="userInfo.phone">{{ userInfo.phone }}</text>
|
||
<!-- 角色标签 -->
|
||
<view class="role-tag">{{ getRoleGreeting() }}</view>
|
||
</view>
|
||
<view class="setting-btn" @click="goSetting">
|
||
<text>设置</text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 角色切换(仅登录后显示) -->
|
||
<view v-if="isLoggedIn" class="role-switch-section">
|
||
<view class="section-header" @click="toggleRoleList">
|
||
<view class="section-left">
|
||
<uni-icons class="section-icon" type="person" size="18" color="#2d9687"></uni-icons>
|
||
<text class="section-title">当前角色</text>
|
||
</view>
|
||
<view class="section-right">
|
||
<text class="current-role">{{ roleName }}</text>
|
||
<text class="arrow" :class="{ expanded: showRoleList }" decode="true">▼</text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 角色列表(折叠展开) -->
|
||
<view v-if="showRoleList && userRoles.length > 0" class="role-list-container">
|
||
<view
|
||
v-for="role in userRoles"
|
||
:key="role.roleType"
|
||
class="role-item"
|
||
:class="{ active: currentRole === getRoleValue(role.roleType), primary: role.isPrimary }"
|
||
@click="switchToRole(role.roleType)"
|
||
>
|
||
<text class="role-icon">{{ getRoleIcon(role.roleType) }}</text>
|
||
<view class="role-info">
|
||
<text class="role-name">{{ getRoleLabel(role.roleType) }}</text>
|
||
<text v-if="role.isPrimary" class="primary-badge">主身份</text>
|
||
</view>
|
||
<text v-if="currentRole === getRoleValue(role.roleType)" class="check-icon">✓</text>
|
||
</view>
|
||
|
||
<!-- 申请新身份入口 -->
|
||
<view class="apply-role-btn" @click="goToApplyRole">
|
||
<text class="plus-icon">+</text>
|
||
<text>申请其他身份</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 我的预约(仅家长,登录后显示) -->
|
||
<view class="order-section" v-if="isLoggedIn && currentRole === 'user'">
|
||
<view class="section-header" @click="goOrderList()">
|
||
<text class="section-title">我的预约</text>
|
||
<text class="section-more">全部</text>
|
||
<text decode="true">></text>
|
||
</view>
|
||
<view class="order-tabs">
|
||
<view class="order-tab" @click="goOrderList(0)">
|
||
<uni-icons class="tab-icon" type="wallet" size="20" color="#333"></uni-icons>
|
||
<text>待支付</text>
|
||
<text class="badge" v-if="orderCount.unpaid">{{ orderCount.unpaid }}</text>
|
||
</view>
|
||
<view class="order-tab" @click="goOrderList(1)">
|
||
<uni-icons class="tab-icon" type="calendar" size="20" color="#333"></uni-icons>
|
||
<text>待服务</text>
|
||
<text class="badge" v-if="orderCount.pending">{{ orderCount.pending }}</text>
|
||
</view>
|
||
<view class="order-tab" @click="goOrderList(3)">
|
||
<uni-icons class="tab-icon" type="checkbox-filled" size="20" color="#52c41a"></uni-icons>
|
||
<text>已完成</text>
|
||
</view>
|
||
<view class="order-tab" @click="goOrderList(-1)">
|
||
<uni-icons class="tab-icon" type="close" size="20" color="#ff4d4f"></uni-icons>
|
||
<text>已取消</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 功能菜单(仅家长,登录后显示) -->
|
||
<view class="menu-section" v-if="isLoggedIn && currentRole === 'user'">
|
||
<view class="menu-item" @click="goPage('/activity-package/pages/group-buy/index')">
|
||
<uni-icons class="menu-icon" type="gift" size="20" color="#2d9687"></uni-icons>
|
||
<text>我的拼团</text>
|
||
<text class="hot-badge">HOT</text>
|
||
<text class="arrow" decode="true">></text>
|
||
</view>
|
||
<view class="menu-item" @click="goPage('/user-package/pages/user/student')">
|
||
<uni-icons class="menu-icon" type="person" size="20" color="#2d9687"></uni-icons>
|
||
<text>学生管理</text>
|
||
<text class="arrow" decode="true">></text>
|
||
</view>
|
||
<view class="menu-item" @click="goPage('/user-package/pages/user/learning-record')">
|
||
<uni-icons class="menu-icon" type="compose" size="20" color="#2d9687"></uni-icons>
|
||
<text>学习记录</text>
|
||
<text class="arrow" decode="true">></text>
|
||
</view>
|
||
<view class="menu-item" @click="goPage('/user-package/pages/feedback/list')">
|
||
<uni-icons class="menu-icon" type="chat" size="20" color="#2d9687"></uni-icons>
|
||
<text>服务反馈</text>
|
||
<text class="arrow" decode="true">></text>
|
||
</view>
|
||
<view class="menu-item" @click="goPage('/user-package/pages/review/list')">
|
||
<uni-icons class="menu-icon" type="star-filled" size="20" color="#faad14"></uni-icons>
|
||
<text>我的评价</text>
|
||
<text class="arrow" decode="true">></text>
|
||
</view>
|
||
<view class="menu-item" @click="goPage('/user-package/pages/course/my-courses')">
|
||
<uni-icons class="menu-icon" type="list" size="20" color="#2d9687"></uni-icons>
|
||
<text>我的课程</text>
|
||
<text class="arrow" decode="true">></text>
|
||
</view>
|
||
<view class="menu-item" @click="goPage('/user-package/pages/user/coupon')">
|
||
<uni-icons class="menu-icon" type="gift" size="20" color="#2d9687"></uni-icons>
|
||
<text>我的优惠券</text>
|
||
<text class="badge" v-if="couponCount">{{ couponCount }}</text>
|
||
<text class="arrow" decode="true">></text>
|
||
</view>
|
||
<view class="menu-item" @click="goPage('/user-package/pages/user/timecard')">
|
||
<uni-icons class="menu-icon" type="calendar" size="20" color="#2d9687"></uni-icons>
|
||
<text>我的时卡</text>
|
||
<text class="arrow" decode="true">></text>
|
||
</view>
|
||
<view class="menu-item" @click="goPage('/user-package/pages/user/wallet')">
|
||
<uni-icons class="menu-icon" type="wallet" size="20" color="#2d9687"></uni-icons>
|
||
<text>我的钱包</text>
|
||
<text class="arrow" decode="true">></text>
|
||
</view>
|
||
<view class="menu-item" @click="goPage('/user-package/pages/user/points')">
|
||
<uni-icons class="menu-icon" type="star" size="20" color="#2d9687"></uni-icons>
|
||
<text>我的积分</text>
|
||
<text class="arrow" decode="true">></text>
|
||
</view>
|
||
<view class="menu-item" @click="goPage('/user-package/pages/user/package')">
|
||
<uni-icons class="menu-icon" type="gift" size="20" color="#2d9687"></uni-icons>
|
||
<text>我的套餐</text>
|
||
<text class="arrow" decode="true">></text>
|
||
</view>
|
||
<view class="menu-item" @click="goPage('/user-package/pages/course/course-selector')">
|
||
<uni-icons class="menu-icon" type="list" size="20" color="#2d9687"></uni-icons>
|
||
<text>课程选择</text>
|
||
<text class="arrow" decode="true">></text>
|
||
</view>
|
||
<view class="menu-item" @click="goPage('/user-package/pages/address/list')">
|
||
<uni-icons class="menu-icon" type="location" size="20" color="#2d9687"></uni-icons>
|
||
<text>地址管理</text>
|
||
<text class="arrow" decode="true">></text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 职业注册入口(仅家长,登录后显示) -->
|
||
<view class="menu-section career-section" v-if="isLoggedIn && currentRole === 'user'">
|
||
<view class="menu-item career-item" @click="goToTeacherRegister">
|
||
<view class="career-left">
|
||
<uni-icons class="menu-icon career-icon" type="person-filled" size="20" color="#1890ff"></uni-icons>
|
||
<view class="career-info">
|
||
<text class="career-name">成为陪伴员</text>
|
||
<text class="career-desc">提供专业陪伴服务,获得收益</text>
|
||
</view>
|
||
</view>
|
||
<view class="career-right">
|
||
<text class="badge recommend">热门推荐</text>
|
||
<text class="arrow" decode="true">></text>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="menu-item career-item" @click="goToDistributorRegister">
|
||
<view class="career-left">
|
||
<uni-icons class="menu-icon career-icon" type="wallet-filled" size="20" color="#52c41a"></uni-icons>
|
||
<view class="career-info">
|
||
<text class="career-name">成为分销员</text>
|
||
<text class="career-desc">推广课程获得佣金,发展事业</text>
|
||
</view>
|
||
</view>
|
||
<view class="career-right">
|
||
<text class="badge commission">高佣金</text>
|
||
<text class="arrow" decode="true">></text>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="menu-item career-item" @click="goToProviderRegister">
|
||
<view class="career-left">
|
||
<uni-icons class="menu-icon career-icon" type="home-filled" size="20" color="#fa8c16"></uni-icons>
|
||
<view class="career-info">
|
||
<text class="career-name">成为服务商</text>
|
||
<text class="career-desc">提供专业教育服务,扩大业务</text>
|
||
</view>
|
||
</view>
|
||
<view class="career-right">
|
||
<text class="badge professional">专业认证</text>
|
||
<text class="arrow" decode="true">></text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 陪伴员功能菜单(按第4版需求文档) -->
|
||
<view class="menu-section" v-if="isLoggedIn && currentRole === 'teacher'">
|
||
<view class="menu-item" @click="goPage('/teacher-package/pages/level/index')">
|
||
<uni-icons class="menu-icon" type="star" size="20" color="#2d9687"></uni-icons>
|
||
<text>我的等级</text>
|
||
<text class="level-badge" :class="'level-' + currentLevelType">{{ currentLevelName }}</text>
|
||
<text class="arrow" decode="true">></text>
|
||
</view>
|
||
<view class="menu-item" @click="goPage('/teacher-package/pages/teacher/orders')">
|
||
<uni-icons class="menu-icon" type="list" size="20" color="#2d9687"></uni-icons>
|
||
<text>我的工单</text>
|
||
<text class="arrow" decode="true">></text>
|
||
</view>
|
||
<view class="menu-item" @click="goPage('/teacher-package/pages/teacher/schedule')">
|
||
<uni-icons class="menu-icon" type="calendar" size="20" color="#2d9687"></uni-icons>
|
||
<text>时间管理</text>
|
||
<text class="arrow" decode="true">></text>
|
||
</view>
|
||
<view class="menu-item" @click="goPage('/teacher-package/pages/teacher/growth-record')">
|
||
<uni-icons class="menu-icon" type="compose" size="20" color="#2d9687"></uni-icons>
|
||
<text>成长记录</text>
|
||
<text class="arrow" decode="true">></text>
|
||
</view>
|
||
<view class="menu-item" @click="goPage('/teacher-package/pages/teacher/earnings')">
|
||
<uni-icons class="menu-icon" type="wallet" size="20" color="#2d9687"></uni-icons>
|
||
<text>收益管理</text>
|
||
<text class="arrow" decode="true">></text>
|
||
</view>
|
||
<view class="menu-item" @click="goPage('/common-package/pages/notification/list')">
|
||
<uni-icons class="menu-icon" type="chat" size="20" color="#2d9687"></uni-icons>
|
||
<text>消息通知</text>
|
||
<text class="badge" v-if="notificationCount">{{ notificationCount }}</text>
|
||
<text class="arrow" decode="true">></text>
|
||
</view>
|
||
<view class="menu-item" @click="goPage('/teacher-package/pages/teacher/settings')">
|
||
<uni-icons class="menu-icon" type="compose" size="20" color="#2d9687"></uni-icons>
|
||
<text>系统设置</text>
|
||
<text class="arrow" decode="true">></text>
|
||
</view>
|
||
<view class="menu-item" @click="contactService">
|
||
<uni-icons class="menu-icon" type="phone" size="20" color="#2d9687"></uni-icons>
|
||
<text>客服电话</text>
|
||
<text class="arrow" decode="true">></text>
|
||
</view>
|
||
|
||
<!-- #ifdef MP-WEIXIN -->
|
||
<button class="menu-item" open-type="contact">
|
||
<uni-icons class="menu-icon" type="chat" size="20" color="#2d9687"></uni-icons>
|
||
<text>在线客服</text>
|
||
<text class="arrow" decode="true">></text>
|
||
</button>
|
||
<!-- #endif -->
|
||
|
||
<!-- #ifndef MP-WEIXIN -->
|
||
<view class="menu-item" @click="contactServiceOnlineFallback">
|
||
<uni-icons class="menu-icon" type="chat" size="20" color="#2d9687"></uni-icons>
|
||
<text>在线客服</text>
|
||
<text class="arrow" decode="true">></text>
|
||
</view>
|
||
<!-- #endif -->
|
||
<view class="menu-item" @click="goPage('/common-package/pages/feedback/create')">
|
||
<uni-icons class="menu-icon" type="chat" size="20" color="#2d9687"></uni-icons>
|
||
<text>意见反馈</text>
|
||
<text class="arrow" decode="true">></text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 管理师功能菜单 -->
|
||
<view class="menu-section" v-if="isLoggedIn && currentRole === 'manager'">
|
||
<view class="menu-item" @click="goPage('/manager-package/pages/manager/work-orders')">
|
||
<uni-icons class="menu-icon" type="list" size="20" color="#2d9687"></uni-icons>
|
||
<text>工单管理</text>
|
||
<text class="arrow" decode="true">></text>
|
||
</view>
|
||
<view class="menu-item" @click="goPage('/manager-package/pages/manager/dispatch-list')">
|
||
<uni-icons class="menu-icon" type="compose" size="20" color="#2d9687"></uni-icons>
|
||
<text>派单管理</text>
|
||
<text class="arrow" decode="true">></text>
|
||
</view>
|
||
<view class="menu-item" @click="goPage('/manager-package/pages/manager/teachers')">
|
||
<uni-icons class="menu-icon" type="person" size="20" color="#2d9687"></uni-icons>
|
||
<text>陪伴员管理</text>
|
||
<text class="arrow" decode="true">></text>
|
||
</view>
|
||
<view class="menu-item" @click="goPage('/manager-package/pages/manager/parents')">
|
||
<uni-icons class="menu-icon" type="person" size="20" color="#2d9687"></uni-icons>
|
||
<text>家长管理</text>
|
||
<text class="arrow" decode="true">></text>
|
||
</view>
|
||
<view class="menu-item" @click="goPage('/manager-package/pages/manager/course-hours')">
|
||
<uni-icons class="menu-icon" type="wallet" size="20" color="#2d9687"></uni-icons>
|
||
<text>课时管理</text>
|
||
<text class="arrow" decode="true">></text>
|
||
</view>
|
||
<view class="menu-item" @click="goPage('/manager-package/pages/manager/reports')">
|
||
<uni-icons class="menu-icon" type="compose" size="20" color="#2d9687"></uni-icons>
|
||
<text>汇总报告</text>
|
||
<text class="arrow" decode="true">></text>
|
||
</view>
|
||
<view class="menu-item" @click="goPage('/manager-package/pages/manager/reminders')">
|
||
<uni-icons class="menu-icon" type="calendar" size="20" color="#2d9687"></uni-icons>
|
||
<text>提醒管理</text>
|
||
<text class="arrow" decode="true">></text>
|
||
</view>
|
||
<view class="menu-item" @click="contactService">
|
||
<uni-icons class="menu-icon" type="phone" size="20" color="#2d9687"></uni-icons>
|
||
<text>客服电话</text>
|
||
<text class="arrow" decode="true">></text>
|
||
</view>
|
||
|
||
<!-- #ifdef MP-WEIXIN -->
|
||
<button class="menu-item" open-type="contact">
|
||
<uni-icons class="menu-icon" type="chat" size="20" color="#2d9687"></uni-icons>
|
||
<text>在线客服</text>
|
||
<text class="arrow" decode="true">></text>
|
||
</button>
|
||
<!-- #endif -->
|
||
|
||
<!-- #ifndef MP-WEIXIN -->
|
||
<view class="menu-item" @click="contactServiceOnlineFallback">
|
||
<uni-icons class="menu-icon" type="chat" size="20" color="#2d9687"></uni-icons>
|
||
<text>在线客服</text>
|
||
<text class="arrow" decode="true">></text>
|
||
</view>
|
||
<!-- #endif -->
|
||
<view class="menu-item" @click="goPage('/common-package/pages/feedback/create')">
|
||
<uni-icons class="menu-icon" type="chat" size="20" color="#2d9687"></uni-icons>
|
||
<text>意见反馈</text>
|
||
<text class="arrow" decode="true">></text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 分销员功能菜单 -->
|
||
<view class="menu-section" v-if="isLoggedIn && currentRole === 'distributor'">
|
||
<view class="menu-item" @click="goPage('/distributor-package/pages/distributor/poster')">
|
||
<uni-icons class="menu-icon" type="gift" size="20" color="#2d9687"></uni-icons>
|
||
<text>推广码管理</text>
|
||
<text class="arrow" decode="true">></text>
|
||
</view>
|
||
<view class="menu-item" @click="goPage('/distributor-package/pages/distributor/course-list')">
|
||
<uni-icons class="menu-icon" type="list" size="20" color="#2d9687"></uni-icons>
|
||
<text>可分销课程</text>
|
||
<text class="arrow" decode="true">></text>
|
||
</view>
|
||
<view class="menu-item" @click="goPage('/distributor-package/pages/distributor/order-list')">
|
||
<uni-icons class="menu-icon" type="list" size="20" color="#2d9687"></uni-icons>
|
||
<text>成交记录</text>
|
||
<text class="arrow" decode="true">></text>
|
||
</view>
|
||
<view class="menu-item" @click="goPage('/distributor-package/pages/distributor/commission')">
|
||
<uni-icons class="menu-icon" type="wallet" size="20" color="#2d9687"></uni-icons>
|
||
<text>佣金管理</text>
|
||
<text class="arrow" decode="true">></text>
|
||
</view>
|
||
<view class="menu-item" @click="goPage('/distributor-package/pages/distributor/team')">
|
||
<uni-icons class="menu-icon" type="person" size="20" color="#2d9687"></uni-icons>
|
||
<text>我的团队</text>
|
||
<text class="arrow" decode="true">></text>
|
||
</view>
|
||
<view class="menu-item" @click="contactService">
|
||
<uni-icons class="menu-icon" type="phone" size="20" color="#2d9687"></uni-icons>
|
||
<text>客服电话</text>
|
||
<text class="arrow" decode="true">></text>
|
||
</view>
|
||
|
||
<!-- #ifdef MP-WEIXIN -->
|
||
<button class="menu-item" open-type="contact">
|
||
<uni-icons class="menu-icon" type="chat" size="20" color="#2d9687"></uni-icons>
|
||
<text>在线客服</text>
|
||
<text class="arrow" decode="true">></text>
|
||
</button>
|
||
<!-- #endif -->
|
||
|
||
<!-- #ifndef MP-WEIXIN -->
|
||
<view class="menu-item" @click="contactServiceOnlineFallback">
|
||
<uni-icons class="menu-icon" type="chat" size="20" color="#2d9687"></uni-icons>
|
||
<text>在线客服</text>
|
||
<text class="arrow" decode="true">></text>
|
||
</view>
|
||
<!-- #endif -->
|
||
<view class="menu-item" @click="goPage('/common-package/pages/feedback/create')">
|
||
<uni-icons class="menu-icon" type="chat" size="20" color="#2d9687"></uni-icons>
|
||
<text>意见反馈</text>
|
||
<text class="arrow" decode="true">></text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 服务商功能菜单 -->
|
||
<view class="menu-section" v-if="isLoggedIn && currentRole === 'provider'">
|
||
<view class="menu-item" @click="goPage('/provider-package/pages/provider/course-manage')">
|
||
<uni-icons class="menu-icon" type="list" size="20" color="#2d9687"></uni-icons>
|
||
<text>课程管理</text>
|
||
<text class="arrow" decode="true">></text>
|
||
</view>
|
||
<view class="menu-item" @click="goPage('/provider-package/pages/provider/student-manage')">
|
||
<uni-icons class="menu-icon" type="person" size="20" color="#2d9687"></uni-icons>
|
||
<text>学生管理</text>
|
||
<text class="arrow" decode="true">></text>
|
||
</view>
|
||
<view class="menu-item" @click="goPage('/provider-package/pages/provider/order-list')">
|
||
<uni-icons class="menu-icon" type="list" size="20" color="#2d9687"></uni-icons>
|
||
<text>订单管理</text>
|
||
<text class="arrow" decode="true">></text>
|
||
</view>
|
||
<view class="menu-item" @click="goPage('/provider-package/pages/provider/schedule')">
|
||
<uni-icons class="menu-icon" type="calendar" size="20" color="#2d9687"></uni-icons>
|
||
<text>课程安排</text>
|
||
<text class="arrow" decode="true">></text>
|
||
</view>
|
||
<view class="menu-item" @click="goPage('/provider-package/pages/provider/earnings')">
|
||
<uni-icons class="menu-icon" type="wallet" size="20" color="#2d9687"></uni-icons>
|
||
<text>收益管理</text>
|
||
<text class="arrow" decode="true">></text>
|
||
</view>
|
||
<view class="menu-item" @click="contactService">
|
||
<uni-icons class="menu-icon" type="phone" size="20" color="#2d9687"></uni-icons>
|
||
<text>客服电话</text>
|
||
<text class="arrow" decode="true">></text>
|
||
</view>
|
||
|
||
<!-- #ifdef MP-WEIXIN -->
|
||
<button class="menu-item" open-type="contact">
|
||
<uni-icons class="menu-icon" type="chat" size="20" color="#2d9687"></uni-icons>
|
||
<text>在线客服</text>
|
||
<text class="arrow" decode="true">></text>
|
||
</button>
|
||
<!-- #endif -->
|
||
|
||
<!-- #ifndef MP-WEIXIN -->
|
||
<view class="menu-item" @click="contactServiceOnlineFallback">
|
||
<uni-icons class="menu-icon" type="chat" size="20" color="#2d9687"></uni-icons>
|
||
<text>在线客服</text>
|
||
<text class="arrow" decode="true">></text>
|
||
</view>
|
||
<!-- #endif -->
|
||
<view class="menu-item" @click="goPage('/common-package/pages/feedback/create')">
|
||
<uni-icons class="menu-icon" type="chat" size="20" color="#2d9687"></uni-icons>
|
||
<text>意见反馈</text>
|
||
<text class="arrow" decode="true">></text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 通用功能菜单(仅家长角色显示) -->
|
||
<view class="menu-section" v-if="!isLoggedIn || currentRole === 'user'">
|
||
<view class="menu-item" @click="goPage('/common-package/pages/notification/list')">
|
||
<uni-icons class="menu-icon" type="chat" size="20" color="#2d9687"></uni-icons>
|
||
<text>消息通知</text>
|
||
<text class="badge" v-if="notificationCount">{{ notificationCount }}</text>
|
||
<text class="arrow" decode="true">></text>
|
||
</view>
|
||
<view class="menu-item" @click="contactService">
|
||
<uni-icons class="menu-icon" type="phone" size="20" color="#2d9687"></uni-icons>
|
||
<text>客服电话</text>
|
||
<text class="arrow" decode="true">></text>
|
||
</view>
|
||
|
||
<!-- #ifdef MP-WEIXIN -->
|
||
<button class="menu-item" open-type="contact">
|
||
<uni-icons class="menu-icon" type="chat" size="20" color="#2d9687"></uni-icons>
|
||
<text>在线客服</text>
|
||
<text class="arrow" decode="true">></text>
|
||
</button>
|
||
<!-- #endif -->
|
||
|
||
<!-- #ifndef MP-WEIXIN -->
|
||
<view class="menu-item" @click="contactServiceOnlineFallback">
|
||
<uni-icons class="menu-icon" type="chat" size="20" color="#2d9687"></uni-icons>
|
||
<text>在线客服</text>
|
||
<text class="arrow" decode="true">></text>
|
||
</view>
|
||
<!-- #endif -->
|
||
<view class="menu-item" @click="goPage('/common-package/pages/feedback/create')">
|
||
<uni-icons class="menu-icon" type="chat" size="20" color="#2d9687"></uni-icons>
|
||
<text>意见反馈</text>
|
||
<text class="arrow" decode="true">></text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 测试账号快速登录区域 -->
|
||
<view v-if="showTestEntrance" class="test-accounts-section">
|
||
<view class="test-accounts-header">
|
||
<view class="header-left">
|
||
<text class="header-icon">🔑</text>
|
||
<text class="header-title">快速测试登录</text>
|
||
</view>
|
||
<text class="header-tip">点击账号快速登录</text>
|
||
</view>
|
||
<scroll-view class="test-accounts-scroll" scroll-x>
|
||
<view class="test-accounts-list">
|
||
<view
|
||
class="test-account-card"
|
||
v-for="(account, index) in testAccounts"
|
||
:key="index"
|
||
@click="quickLoginWithTestAccount(account)"
|
||
>
|
||
<view class="card-badge">TEST</view>
|
||
<view class="card-icon-wrapper">
|
||
<text class="card-icon">{{ account.icon }}</text>
|
||
</view>
|
||
<view class="card-info">
|
||
<text class="card-role">{{ account.name }}</text>
|
||
<text class="card-phone">{{ account.phone }}</text>
|
||
</view>
|
||
<view class="card-btn">
|
||
<text>立即登录</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</scroll-view>
|
||
</view>
|
||
|
||
<!-- 退出登录按钮 -->
|
||
<view v-if="isLoggedIn" class="logout-section">
|
||
<button class="logout-btn" @click="handleLogout">退出登录</button>
|
||
</view>
|
||
|
||
<!-- 角色选择弹窗 -->
|
||
<view v-if="showRoleModal" class="modal-overlay" @click="closeRoleModal">
|
||
<view class="modal-content" @click.stop>
|
||
<view class="modal-title">选择角色</view>
|
||
<view class="role-list">
|
||
<view
|
||
v-for="role in availableRoles"
|
||
:key="role.value"
|
||
class="role-option"
|
||
:class="{ active: currentRole === role.value }"
|
||
@click="switchRole(role.value)"
|
||
>
|
||
<text class="role-icon">{{ role.icon }}</text>
|
||
<text class="role-name">{{ role.label }}</text>
|
||
<text v-if="currentRole === role.value" class="check-icon">✓</text>
|
||
</view>
|
||
</view>
|
||
<view class="modal-close" @click="closeRoleModal">取消</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
import { userApi, orderApi, notificationApi, authApi } from '@/api/index.js'
|
||
import { useUserStore } from '@/store/user'
|
||
|
||
export default {
|
||
data() {
|
||
return {
|
||
isLoggedIn: false,
|
||
currentRole: '',
|
||
userInfo: {},
|
||
showTestEntrance: false,
|
||
showRoleList: false, // 角色列表展开状态
|
||
userRoles: [], // 用户的所有角色(从数据库加载)
|
||
orderCount: {
|
||
unpaid: 0,
|
||
pending: 0,
|
||
completed: 0,
|
||
cancelled: 0
|
||
},
|
||
couponCount: 0,
|
||
notificationCount: 0,
|
||
showRoleModal: false,
|
||
currentLevelType: 'bronze', // 当前等级类型
|
||
currentLevelName: '普通陪伴员', // 当前等级名称
|
||
availableRoles: [
|
||
{ value: 'user', label: '家长', icon: '👨👩👧' },
|
||
{ value: 'teacher', label: '陪伴员', icon: '👨🏫' },
|
||
{ value: 'manager', label: '管理师', icon: '👔' },
|
||
{ value: 'distributor', label: '分销员', icon: '💼' },
|
||
{ value: 'provider', label: '服务商', icon: '🎓' }
|
||
],
|
||
// 测试账号列表
|
||
testAccounts: [
|
||
{ role: 'user', name: '家长', phone: '13800138000', password: '123456', icon: '👨👩👧' },
|
||
{ role: 'teacher', name: '陪伴师', phone: '13800138001', password: '123456', icon: '👨🏫' },
|
||
{ role: 'manager', name: '管理师', phone: '13800138002', password: '123456', icon: '👔' },
|
||
{ role: 'distributor', name: '分销员', phone: '13800138003', password: '123456', icon: '💼' },
|
||
{ role: 'provider', name: '服务商', phone: '13800138004', password: '123456', icon: '🎓' }
|
||
]
|
||
}
|
||
},
|
||
|
||
computed: {
|
||
roleName() {
|
||
const role = this.availableRoles.find(r => r.value === this.currentRole)
|
||
return role ? role.label : '用户'
|
||
}
|
||
},
|
||
|
||
onLoad() {
|
||
this.checkLoginStatus()
|
||
this.initTestEntrance()
|
||
},
|
||
|
||
onShow() {
|
||
this.checkLoginStatus()
|
||
if (this.isLoggedIn) {
|
||
this.loadUserData()
|
||
this.loadUserRoles() // 加载用户的所有角色
|
||
}
|
||
},
|
||
|
||
methods: {
|
||
initTestEntrance() {
|
||
let show = false
|
||
// #ifdef MP-WEIXIN
|
||
try {
|
||
const info = uni.getAccountInfoSync && uni.getAccountInfoSync()
|
||
const envVersion = info && info.miniProgram && info.miniProgram.envVersion
|
||
show = envVersion === 'develop' || envVersion === 'trial'
|
||
} catch (e) {
|
||
show = false
|
||
}
|
||
// #endif
|
||
|
||
// #ifndef MP-WEIXIN
|
||
show = process.env.NODE_ENV !== 'production'
|
||
// #endif
|
||
|
||
this.showTestEntrance = show
|
||
},
|
||
|
||
checkLoginStatus() {
|
||
const token = uni.getStorageSync('token')
|
||
const userStore = useUserStore()
|
||
this.isLoggedIn = !!token
|
||
this.currentRole = userStore.currentRole || 'user'
|
||
},
|
||
|
||
async loadUserData() {
|
||
try {
|
||
// 加载用户信息
|
||
const userRes = await userApi.getUserInfo()
|
||
if (userRes && userRes.success) {
|
||
this.userInfo = userRes.data || {}
|
||
console.log('个人中心加载用户信息:', this.userInfo)
|
||
console.log('头像URL:', this.userInfo.avatar)
|
||
}
|
||
} catch (error) {
|
||
console.log('加载用户信息失败:', error)
|
||
}
|
||
|
||
// 加载等级信息(仅陪伴员)
|
||
if (this.currentRole === 'teacher') {
|
||
this.loadLevelInfo()
|
||
}
|
||
|
||
try {
|
||
// 加载订单统计
|
||
if (this.currentRole === 'user') {
|
||
const orderRes = await orderApi.getOrderCount()
|
||
if (orderRes && orderRes.success && orderRes.data) {
|
||
this.orderCount = orderRes.data
|
||
}
|
||
}
|
||
} catch (error) {
|
||
console.log('加载订单统计失败:', error)
|
||
}
|
||
|
||
try {
|
||
// 加载优惠券数量
|
||
const couponRes = await userApi.getCouponCount()
|
||
if (couponRes && (couponRes.success || couponRes.code === 200)) {
|
||
const count = typeof couponRes.data === 'number' ? couponRes.data : (couponRes.data?.total || 0)
|
||
this.couponCount = count
|
||
}
|
||
} catch (error) {
|
||
console.log('加载优惠券数量失败:', error)
|
||
}
|
||
|
||
try {
|
||
// 加载未读消息数
|
||
const notifRes = await notificationApi.getUnreadCount()
|
||
if (notifRes && (notifRes.success || notifRes.code === 200)) {
|
||
const count = typeof notifRes.data === 'number'
|
||
? notifRes.data
|
||
: (notifRes.data?.total || 0)
|
||
this.notificationCount = count
|
||
}
|
||
} catch (error) {
|
||
console.log('加载消息数量失败:', error)
|
||
}
|
||
},
|
||
|
||
// 加载等级信息
|
||
async loadLevelInfo() {
|
||
try {
|
||
const userInfo = uni.getStorageSync('userInfo')
|
||
const teacherId = userInfo?.id || userInfo?.userId
|
||
|
||
if (!teacherId) {
|
||
return
|
||
}
|
||
|
||
// 使用完整的 API 地址
|
||
const baseUrl = getApp().globalData.baseUrl || 'http://localhost:8089'
|
||
|
||
uni.request({
|
||
url: `${baseUrl}/api/teacher/level/current`,
|
||
method: 'GET',
|
||
data: { teacherId },
|
||
header: {
|
||
'Authorization': uni.getStorageSync('token') || ''
|
||
},
|
||
success: (res) => {
|
||
if (res.statusCode === 200 && res.data && res.data.code === 200) {
|
||
this.currentLevelType = res.data.data.currentLevel || 'bronze'
|
||
this.currentLevelName = res.data.data.levelName || '普通陪伴员'
|
||
}
|
||
},
|
||
fail: (error) => {
|
||
console.error('加载等级信息失败:', error)
|
||
}
|
||
})
|
||
} catch (error) {
|
||
console.error('加载等级信息失败:', error)
|
||
}
|
||
},
|
||
|
||
getRoleGreeting() {
|
||
const greetings = {
|
||
user: '家长',
|
||
teacher: '陪伴员',
|
||
manager: '管理师',
|
||
distributor: '分销员',
|
||
provider: '服务商'
|
||
}
|
||
return greetings[this.currentRole] || '用户'
|
||
},
|
||
|
||
// 加载用户的所有角色(从数据库)
|
||
async loadUserRoles() {
|
||
try {
|
||
const userStore = useUserStore()
|
||
await userStore.loadAllRoles()
|
||
|
||
// 从 store 获取角色数据
|
||
this.userRoles = userStore.allRoles.map(roleType => ({
|
||
roleType: roleType,
|
||
isPrimary: roleType === userStore.primaryRole
|
||
}))
|
||
|
||
console.log('加载用户角色:', this.userRoles)
|
||
} catch (error) {
|
||
console.error('加载用户角色失败:', error)
|
||
}
|
||
},
|
||
|
||
// 切换角色列表展开/收起
|
||
toggleRoleList() {
|
||
this.showRoleList = !this.showRoleList
|
||
},
|
||
|
||
// 切换到指定角色
|
||
async switchToRole(roleType) {
|
||
const roleValue = this.getRoleValue(roleType)
|
||
|
||
if (roleValue === this.currentRole) {
|
||
this.showRoleList = false
|
||
return
|
||
}
|
||
|
||
try {
|
||
uni.showLoading({ title: '切换中...' })
|
||
|
||
const userStore = useUserStore()
|
||
const success = await userStore.switchRole(roleType)
|
||
|
||
if (success) {
|
||
this.currentRole = roleValue
|
||
this.showRoleList = false
|
||
|
||
uni.hideLoading()
|
||
uni.showToast({
|
||
title: '切换成功',
|
||
icon: 'success'
|
||
})
|
||
|
||
// 刷新页面
|
||
setTimeout(() => {
|
||
uni.reLaunch({
|
||
url: '/pages/index/index'
|
||
})
|
||
}, 500)
|
||
} else {
|
||
uni.hideLoading()
|
||
uni.showToast({
|
||
title: '切换失败',
|
||
icon: 'none'
|
||
})
|
||
}
|
||
} catch (error) {
|
||
uni.hideLoading()
|
||
uni.showToast({
|
||
title: error.message || '切换失败',
|
||
icon: 'none'
|
||
})
|
||
}
|
||
},
|
||
|
||
// 跳转到申请身份页面
|
||
goToApplyRole() {
|
||
uni.navigateTo({
|
||
url: '/src/pages/user/apply-role'
|
||
})
|
||
},
|
||
|
||
// 角色类型转换(数据库字段 -> 前端值)
|
||
getRoleValue(roleType) {
|
||
// parent -> user, 其他保持不变
|
||
return roleType === 'parent' ? 'user' : roleType
|
||
},
|
||
|
||
// 获取角色图标
|
||
getRoleIcon(roleType) {
|
||
const icons = {
|
||
parent: '👨👩👧',
|
||
user: '👨👩👧',
|
||
teacher: '👨🏫',
|
||
manager: '👔',
|
||
distributor: '💼',
|
||
provider: '🎓'
|
||
}
|
||
return icons[roleType] || '👤'
|
||
},
|
||
|
||
// 获取角色名称
|
||
getRoleLabel(roleType) {
|
||
const labels = {
|
||
parent: '家长',
|
||
user: '家长',
|
||
teacher: '陪伴员',
|
||
manager: '管理师',
|
||
distributor: '分销员',
|
||
provider: '服务商'
|
||
}
|
||
return labels[roleType] || '用户'
|
||
},
|
||
|
||
goToRoleSelect() {
|
||
uni.navigateTo({
|
||
url: '/pages/auth/role-select'
|
||
})
|
||
},
|
||
|
||
// 职业注册相关方法
|
||
goToTeacherRegister() {
|
||
uni.showModal({
|
||
title: '成为陪伴员',
|
||
content: '陪伴员为用户提供专业的陪伴和辅导服务,获得丰厚收益。我们为您提供完善的培训体系和成长路径,是否立即申请?',
|
||
confirmText: '立即申请',
|
||
cancelText: '再想想',
|
||
success: (res) => {
|
||
if (res.confirm) {
|
||
uni.navigateTo({
|
||
url: '/teacher-package/pages/auth/teacher-quick-register'
|
||
})
|
||
}
|
||
}
|
||
})
|
||
},
|
||
|
||
goToDistributorRegister() {
|
||
uni.showModal({
|
||
title: '成为分销员',
|
||
content: '分销员推广优质课程获得可观佣金收益,发展自己的教育事业。平台提供专业的营销工具和支持,是否立即申请?',
|
||
confirmText: '立即申请',
|
||
cancelText: '再想想',
|
||
success: (res) => {
|
||
if (res.confirm) {
|
||
uni.navigateTo({
|
||
url: '/distributor-package/pages/distributor/apply'
|
||
})
|
||
}
|
||
}
|
||
})
|
||
},
|
||
|
||
goToProviderRegister() {
|
||
uni.showModal({
|
||
title: '成为服务商',
|
||
content: '服务商为平台提供专业的教育培训服务,扩大业务范围和影响力。我们为您提供稳定的生源和完善的管理系统,是否立即申请?',
|
||
confirmText: '立即申请',
|
||
cancelText: '再想想',
|
||
success: (res) => {
|
||
if (res.confirm) {
|
||
uni.navigateTo({
|
||
url: '/provider-package/pages/service-provider/apply'
|
||
})
|
||
}
|
||
}
|
||
})
|
||
},
|
||
|
||
goSetting() {
|
||
uni.navigateTo({
|
||
url: '/user-package/pages/user/profile'
|
||
})
|
||
},
|
||
|
||
goOrderList(status) {
|
||
let url = '/order-package/pages/order/my-orders'
|
||
if (status !== undefined) {
|
||
url += `?status=${status}`
|
||
}
|
||
uni.navigateTo({ url })
|
||
},
|
||
|
||
goPage(url) {
|
||
uni.navigateTo({ url })
|
||
},
|
||
|
||
contactService() {
|
||
uni.makePhoneCall({
|
||
phoneNumber: '400-000-0000',
|
||
fail: () => {
|
||
uni.showToast({ title: '请拨打客服电话', icon: 'none' })
|
||
}
|
||
})
|
||
},
|
||
|
||
contactServiceOnlineFallback() {
|
||
uni.showToast({
|
||
title: '在线客服仅在微信小程序内可用',
|
||
icon: 'none'
|
||
})
|
||
},
|
||
|
||
showRoleSelector() {
|
||
this.showRoleModal = true
|
||
},
|
||
|
||
closeRoleModal() {
|
||
this.showRoleModal = false
|
||
},
|
||
|
||
switchRole(role) {
|
||
if (role === this.currentRole) {
|
||
this.closeRoleModal()
|
||
return
|
||
}
|
||
|
||
// 更新 Pinia store(这会同时更新 localStorage)
|
||
const userStore = useUserStore()
|
||
userStore.setRole(role)
|
||
|
||
this.currentRole = role
|
||
this.closeRoleModal()
|
||
|
||
// 切换到对应的首页
|
||
uni.reLaunch({
|
||
url: '/pages/index/index'
|
||
})
|
||
},
|
||
|
||
// 使用测试账号快速登录
|
||
async quickLoginWithTestAccount(account) {
|
||
try {
|
||
uni.showLoading({ title: '登录中...' })
|
||
|
||
const res = await authApi.phoneLogin({
|
||
phone: account.phone,
|
||
password: account.password || '123456'
|
||
})
|
||
|
||
if (res?.code !== 200) {
|
||
throw new Error(res?.message || '登录失败')
|
||
}
|
||
|
||
// 保存token和用户信息
|
||
const token = res?.data?.token || res?.token
|
||
const userInfo = res?.data?.userInfo || res?.userInfo || res?.data
|
||
|
||
console.log('========== 测试账号登录调试 ==========')
|
||
console.log('完整响应:', res)
|
||
console.log('token:', token)
|
||
console.log('userInfo:', userInfo)
|
||
console.log('userInfo.role:', userInfo?.role)
|
||
console.log('userInfo.userType:', userInfo?.userType)
|
||
console.log('account.role:', account.role)
|
||
console.log('=====================================')
|
||
|
||
if (!token) {
|
||
throw new Error(res?.message || '登录失败')
|
||
}
|
||
|
||
const userStore = useUserStore()
|
||
userStore.setToken(token)
|
||
if (userInfo) {
|
||
userStore.setUserInfo(userInfo)
|
||
}
|
||
// ✅ 修复:使用后端返回的角色,而不是前端定义的角色
|
||
// 后端返回的 userInfo.role 或 userInfo.userType 才是数据库中的真实角色
|
||
const backendRole = userInfo?.role || userInfo?.userType || account.role
|
||
const finalRole = backendRole === 'parent' ? 'user' : backendRole
|
||
console.log('🔥 最终设置的角色:', finalRole)
|
||
userStore.setRole(finalRole)
|
||
|
||
uni.hideLoading()
|
||
uni.showToast({
|
||
title: '登录成功',
|
||
icon: 'success',
|
||
success: () => {
|
||
setTimeout(() => {
|
||
// 🔥 强制设置角色并跳转
|
||
const userStore = useUserStore()
|
||
if (account.role === 'user') {
|
||
userStore.setRole('user')
|
||
}
|
||
uni.reLaunch({
|
||
url: '/pages/index/index'
|
||
})
|
||
}, 500)
|
||
}
|
||
})
|
||
|
||
} catch (e) {
|
||
uni.hideLoading()
|
||
uni.showToast({
|
||
title: e?.message || e?.errMsg || '登录失败',
|
||
icon: 'none'
|
||
})
|
||
}
|
||
},
|
||
|
||
handleLogout() {
|
||
uni.showModal({
|
||
title: '提示',
|
||
content: '确定要退出登录吗?',
|
||
success: (res) => {
|
||
if (res.confirm) {
|
||
// 使用 store 的 logout 方法
|
||
const userStore = useUserStore()
|
||
userStore.logout()
|
||
|
||
this.isLoggedIn = false
|
||
this.userInfo = {}
|
||
this.currentRole = 'user'
|
||
|
||
uni.showToast({
|
||
title: '已退出登录',
|
||
icon: 'success'
|
||
})
|
||
|
||
setTimeout(() => {
|
||
uni.reLaunch({
|
||
url: '/pages/index/index'
|
||
})
|
||
}, 1500)
|
||
}
|
||
}
|
||
})
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
@import '@/static/css/common.scss';
|
||
|
||
.container {
|
||
min-height: 100vh;
|
||
background: #f5f7fa;
|
||
padding-bottom: 100rpx;
|
||
}
|
||
|
||
.user-header {
|
||
background: linear-gradient(135deg, #2d9687 0%, #25806f 100%);
|
||
padding: 60rpx 30rpx 40rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 20rpx;
|
||
|
||
.user-avatar {
|
||
width: 120rpx;
|
||
height: 120rpx;
|
||
background: rgba(255, 255, 255, 0.2);
|
||
border-radius: 60rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
overflow: hidden;
|
||
flex-shrink: 0;
|
||
|
||
.avatar-image {
|
||
width: 100%;
|
||
height: 100%;
|
||
border-radius: 60rpx;
|
||
}
|
||
|
||
.avatar-emoji {
|
||
font-size: 60rpx;
|
||
}
|
||
}
|
||
|
||
.user-info {
|
||
flex: 1;
|
||
|
||
.user-name {
|
||
display: block;
|
||
font-size: 36rpx;
|
||
font-weight: bold;
|
||
color: #fff;
|
||
margin-bottom: 8rpx;
|
||
}
|
||
|
||
.user-phone,
|
||
.login-tip {
|
||
display: block;
|
||
font-size: 26rpx;
|
||
color: rgba(255, 255, 255, 0.8);
|
||
}
|
||
|
||
.role-tag {
|
||
display: inline-block;
|
||
background: rgba(255, 255, 255, 0.2);
|
||
color: #fff;
|
||
font-size: 22rpx;
|
||
padding: 4rpx 12rpx;
|
||
border-radius: 8rpx;
|
||
margin-top: 8rpx;
|
||
}
|
||
}
|
||
|
||
.login-btn,
|
||
.setting-btn {
|
||
background: rgba(255, 255, 255, 0.2);
|
||
color: #fff;
|
||
font-size: 28rpx;
|
||
padding: 12rpx 24rpx;
|
||
border-radius: 20rpx;
|
||
}
|
||
}
|
||
|
||
.role-switch-section,
|
||
.order-section,
|
||
.menu-section {
|
||
background: white;
|
||
margin-bottom: 20rpx;
|
||
border-radius: 16rpx;
|
||
overflow: hidden;
|
||
|
||
.section-header {
|
||
display: flex;
|
||
align-items: center;
|
||
padding: 30rpx;
|
||
background: #f8f9fa;
|
||
border-bottom: 1rpx solid #f0f0f0;
|
||
|
||
.section-left {
|
||
display: flex;
|
||
align-items: center;
|
||
flex: 1;
|
||
}
|
||
|
||
.section-right {
|
||
display: flex;
|
||
align-items: center;
|
||
}
|
||
|
||
.section-icon {
|
||
margin-right: 16rpx;
|
||
}
|
||
|
||
.section-title {
|
||
font-size: 32rpx;
|
||
font-weight: bold;
|
||
color: #333;
|
||
}
|
||
|
||
.section-desc {
|
||
font-size: 24rpx;
|
||
color: #999;
|
||
margin-left: 16rpx;
|
||
}
|
||
|
||
.current-role {
|
||
font-size: 28rpx;
|
||
color: #2d9687;
|
||
margin-right: 16rpx;
|
||
}
|
||
|
||
.arrow {
|
||
font-size: 20rpx;
|
||
color: #999;
|
||
transition: transform 0.3s;
|
||
|
||
&.expanded {
|
||
transform: rotate(180deg);
|
||
}
|
||
}
|
||
}
|
||
|
||
// 角色列表容器
|
||
.role-list-container {
|
||
padding: 20rpx 30rpx 30rpx;
|
||
animation: slideDown 0.3s ease-out;
|
||
|
||
.role-item {
|
||
display: flex;
|
||
align-items: center;
|
||
padding: 24rpx;
|
||
background: #f8f9fa;
|
||
border-radius: 12rpx;
|
||
margin-bottom: 16rpx;
|
||
transition: all 0.3s;
|
||
|
||
&.active {
|
||
background: #e8f5f3;
|
||
border: 2rpx solid #2d9687;
|
||
}
|
||
|
||
&.primary {
|
||
position: relative;
|
||
|
||
&::before {
|
||
content: '';
|
||
position: absolute;
|
||
left: 0;
|
||
top: 0;
|
||
bottom: 0;
|
||
width: 6rpx;
|
||
background: #2d9687;
|
||
border-radius: 12rpx 0 0 12rpx;
|
||
}
|
||
}
|
||
|
||
.role-icon {
|
||
font-size: 40rpx;
|
||
margin-right: 16rpx;
|
||
}
|
||
|
||
.role-info {
|
||
flex: 1;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 12rpx;
|
||
|
||
.role-name {
|
||
font-size: 30rpx;
|
||
color: #333;
|
||
font-weight: 500;
|
||
}
|
||
|
||
.primary-badge {
|
||
font-size: 20rpx;
|
||
padding: 4rpx 10rpx;
|
||
background: linear-gradient(135deg, #2d9687 0%, #25806f 100%);
|
||
color: #fff;
|
||
border-radius: 8rpx;
|
||
}
|
||
}
|
||
|
||
.check-icon {
|
||
font-size: 32rpx;
|
||
color: #2d9687;
|
||
font-weight: bold;
|
||
}
|
||
}
|
||
|
||
.apply-role-btn {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
gap: 12rpx;
|
||
padding: 24rpx;
|
||
background: linear-gradient(135deg, #f0f9f7 0%, #e6f7f3 100%);
|
||
border: 2rpx dashed #2d9687;
|
||
border-radius: 12rpx;
|
||
margin-top: 8rpx;
|
||
|
||
.plus-icon {
|
||
font-size: 32rpx;
|
||
color: #2d9687;
|
||
font-weight: bold;
|
||
}
|
||
|
||
text {
|
||
font-size: 28rpx;
|
||
color: #2d9687;
|
||
font-weight: 500;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
@keyframes slideDown {
|
||
from {
|
||
opacity: 0;
|
||
max-height: 0;
|
||
transform: translateY(-20rpx);
|
||
}
|
||
to {
|
||
opacity: 1;
|
||
max-height: 1000rpx;
|
||
transform: translateY(0);
|
||
}
|
||
}
|
||
|
||
.section-header {
|
||
padding: 30rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
|
||
.section-left {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 12rpx;
|
||
|
||
.section-icon {
|
||
font-size: 32rpx;
|
||
}
|
||
|
||
.section-title {
|
||
font-size: 32rpx;
|
||
font-weight: bold;
|
||
color: #333;
|
||
}
|
||
}
|
||
|
||
.section-right {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8rpx;
|
||
|
||
.current-role {
|
||
font-size: 28rpx;
|
||
color: #666;
|
||
}
|
||
|
||
.arrow {
|
||
font-size: 24rpx;
|
||
color: #999;
|
||
}
|
||
}
|
||
|
||
.section-more {
|
||
font-size: 26rpx;
|
||
color: #999;
|
||
margin-right: 8rpx;
|
||
}
|
||
}
|
||
|
||
.order-tabs {
|
||
display: flex;
|
||
padding: 0 30rpx 30rpx;
|
||
|
||
.order-tab {
|
||
flex: 1;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
gap: 12rpx;
|
||
position: relative;
|
||
|
||
.tab-icon {
|
||
font-size: 40rpx;
|
||
}
|
||
|
||
text {
|
||
font-size: 26rpx;
|
||
color: #666;
|
||
}
|
||
|
||
.badge {
|
||
position: absolute;
|
||
top: -8rpx;
|
||
right: 20rpx;
|
||
background: #ff6b6b;
|
||
color: #fff;
|
||
font-size: 20rpx;
|
||
padding: 2rpx 8rpx;
|
||
border-radius: 10rpx;
|
||
min-width: 32rpx;
|
||
text-align: center;
|
||
}
|
||
}
|
||
}
|
||
|
||
.menu-item {
|
||
padding: 30rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 16rpx;
|
||
border-bottom: 1rpx solid #f0f0f0;
|
||
background: transparent;
|
||
text-align: left;
|
||
|
||
&:last-child {
|
||
border-bottom: none;
|
||
}
|
||
|
||
.menu-icon {
|
||
font-size: 36rpx;
|
||
}
|
||
|
||
text {
|
||
font-size: 30rpx;
|
||
color: #333;
|
||
}
|
||
|
||
.hot-badge {
|
||
background: linear-gradient(135deg, #ff6b6b 0%, #ff5252 100%);
|
||
color: #fff;
|
||
font-size: 20rpx;
|
||
padding: 2rpx 8rpx;
|
||
border-radius: 8rpx;
|
||
margin-left: auto;
|
||
}
|
||
|
||
.new-badge {
|
||
background: linear-gradient(135deg, #52c41a 0%, #73d13d 100%);
|
||
color: #fff;
|
||
font-size: 20rpx;
|
||
padding: 2rpx 8rpx;
|
||
border-radius: 8rpx;
|
||
margin-left: auto;
|
||
}
|
||
|
||
.badge {
|
||
background: #ff6b6b;
|
||
color: #fff;
|
||
font-size: 20rpx;
|
||
padding: 2rpx 8rpx;
|
||
border-radius: 10rpx;
|
||
min-width: 32rpx;
|
||
text-align: center;
|
||
margin-left: auto;
|
||
}
|
||
|
||
.level-badge {
|
||
font-size: 24rpx;
|
||
padding: 4rpx 12rpx;
|
||
border-radius: 20rpx;
|
||
font-weight: bold;
|
||
margin-left: auto;
|
||
|
||
&.level-bronze {
|
||
background: #f5e6d3;
|
||
color: #cd7f32;
|
||
}
|
||
|
||
&.level-king {
|
||
background: #e8e8e8;
|
||
color: #666;
|
||
}
|
||
|
||
&.level-gold {
|
||
background: #fff7e6;
|
||
color: #ffa940;
|
||
}
|
||
}
|
||
|
||
// 职业注册徽章样式
|
||
.badge {
|
||
font-size: 20rpx;
|
||
padding: 4rpx 10rpx;
|
||
border-radius: 12rpx;
|
||
margin-right: 16rpx;
|
||
font-weight: bold;
|
||
|
||
&.recommend {
|
||
background: linear-gradient(135deg, #e6f7ff 0%, #bae7ff 100%);
|
||
color: #1890ff;
|
||
border: 1rpx solid #91d5ff;
|
||
}
|
||
|
||
&.commission {
|
||
background: linear-gradient(135deg, #f6ffed 0%, #d9f7be 100%);
|
||
color: #52c41a;
|
||
border: 1rpx solid #b7eb8f;
|
||
}
|
||
|
||
&.professional {
|
||
background: linear-gradient(135deg, #fff7e6 0%, #ffe7ba 100%);
|
||
color: #fa8c16;
|
||
border: 1rpx solid #ffd591;
|
||
}
|
||
}
|
||
|
||
.arrow {
|
||
font-size: 24rpx;
|
||
color: #999;
|
||
}
|
||
}
|
||
|
||
// 职业注册特殊样式
|
||
.career-section {
|
||
background: linear-gradient(135deg, #f0f9f7 0%, #f8fffe 100%);
|
||
border: 2rpx solid #e6f7ff;
|
||
box-shadow: 0 4rpx 16rpx rgba(45, 150, 135, 0.08);
|
||
border-radius: 16rpx;
|
||
overflow: hidden;
|
||
|
||
.career-item {
|
||
padding: 32rpx 30rpx;
|
||
border-bottom: 1rpx solid rgba(45, 150, 135, 0.08);
|
||
background: white;
|
||
transition: all 0.3s ease;
|
||
|
||
&:first-child {
|
||
border-top-left-radius: 14rpx;
|
||
border-top-right-radius: 14rpx;
|
||
}
|
||
|
||
&:last-child {
|
||
border-bottom: none;
|
||
border-bottom-left-radius: 14rpx;
|
||
border-bottom-right-radius: 14rpx;
|
||
}
|
||
|
||
&:hover {
|
||
background: #f8fffe;
|
||
}
|
||
|
||
.career-left {
|
||
display: flex;
|
||
align-items: center;
|
||
flex: 1;
|
||
gap: 20rpx;
|
||
|
||
.career-icon {
|
||
width: 48rpx;
|
||
height: 48rpx;
|
||
background: rgba(45, 150, 135, 0.08);
|
||
border-radius: 12rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
|
||
.career-info {
|
||
flex: 1;
|
||
|
||
.career-name {
|
||
display: block;
|
||
font-size: 32rpx;
|
||
font-weight: bold;
|
||
color: #333;
|
||
margin-bottom: 6rpx;
|
||
}
|
||
|
||
.career-desc {
|
||
display: block;
|
||
font-size: 24rpx;
|
||
color: #666;
|
||
line-height: 1.4;
|
||
}
|
||
}
|
||
}
|
||
|
||
.career-right {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 12rpx;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 确保button元素的menu-item样式与view元素一致
|
||
button.menu-item {
|
||
width: 100%;
|
||
border: none;
|
||
outline: none;
|
||
padding: 30rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 16rpx;
|
||
border-bottom: 1rpx solid #f0f0f0;
|
||
background: transparent;
|
||
text-align: left;
|
||
font-size: 30rpx;
|
||
color: #333;
|
||
min-height: auto;
|
||
height: auto;
|
||
line-height: normal;
|
||
box-sizing: border-box;
|
||
|
||
&:last-child {
|
||
border-bottom: none;
|
||
}
|
||
|
||
&::after {
|
||
border: none;
|
||
}
|
||
|
||
.menu-icon {
|
||
font-size: 36rpx;
|
||
}
|
||
|
||
text {
|
||
font-size: 30rpx;
|
||
color: #333;
|
||
}
|
||
|
||
.arrow {
|
||
font-size: 24rpx;
|
||
color: #999;
|
||
margin-left: auto;
|
||
}
|
||
}
|
||
|
||
// 测试账号区域样式
|
||
.test-accounts-section {
|
||
margin: 20rpx 0 40rpx;
|
||
|
||
.test-accounts-header {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
padding: 0 30rpx 20rpx;
|
||
|
||
.header-left {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 12rpx;
|
||
|
||
.header-icon {
|
||
font-size: 36rpx;
|
||
}
|
||
|
||
.header-title {
|
||
font-size: 32rpx;
|
||
font-weight: bold;
|
||
color: #333333;
|
||
}
|
||
}
|
||
|
||
.header-tip {
|
||
font-size: 24rpx;
|
||
color: #999999;
|
||
}
|
||
}
|
||
|
||
.test-accounts-scroll {
|
||
white-space: nowrap;
|
||
|
||
.test-accounts-list {
|
||
display: inline-flex;
|
||
gap: 20rpx;
|
||
padding: 0 30rpx;
|
||
|
||
.test-account-card {
|
||
display: inline-flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
width: 210rpx;
|
||
padding: 30rpx 10rpx 25rpx;
|
||
background: linear-gradient(135deg, #ffffff 0%, #fafbfc 100%);
|
||
border-radius: 24rpx;
|
||
box-shadow: 0 8rpx 24rpx rgba(45, 150, 135, 0.12);
|
||
border: 2rpx solid rgba(45, 150, 135, 0.1);
|
||
position: relative;
|
||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||
|
||
&::before {
|
||
content: '';
|
||
position: absolute;
|
||
top: 0;
|
||
left: 0;
|
||
right: 0;
|
||
height: 8rpx;
|
||
background: linear-gradient(90deg, #2d9687 0%, #52c41a 100%);
|
||
border-radius: 24rpx 24rpx 0 0;
|
||
}
|
||
|
||
&:active {
|
||
transform: translateY(-4rpx) scale(0.98);
|
||
box-shadow: 0 12rpx 32rpx rgba(45, 150, 135, 0.2);
|
||
}
|
||
|
||
.card-badge {
|
||
position: absolute;
|
||
top: 15rpx;
|
||
right: 15rpx;
|
||
background: linear-gradient(135deg, #faad14 0%, #ffc53d 100%);
|
||
color: #ffffff;
|
||
font-size: 20rpx;
|
||
font-weight: bold;
|
||
padding: 4rpx 12rpx;
|
||
border-radius: 20rpx;
|
||
box-shadow: 0 2rpx 8rpx rgba(250, 173, 20, 0.3);
|
||
}
|
||
|
||
.card-icon-wrapper {
|
||
width: 100rpx;
|
||
height: 100rpx;
|
||
background: linear-gradient(135deg, #f0f9f7 0%, #e6f7f3 100%);
|
||
border-radius: 50%;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
margin-bottom: 20rpx;
|
||
box-shadow: 0 4rpx 12rpx rgba(45, 150, 135, 0.1);
|
||
|
||
.card-icon {
|
||
font-size: 56rpx;
|
||
}
|
||
}
|
||
|
||
.card-info {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
gap: 8rpx;
|
||
margin-bottom: 20rpx;
|
||
width: 100%;
|
||
|
||
.card-role {
|
||
font-size: 28rpx;
|
||
font-weight: bold;
|
||
color: #333333;
|
||
}
|
||
|
||
.card-phone {
|
||
font-size: 22rpx;
|
||
color: #999999;
|
||
font-family: 'Courier New', monospace;
|
||
background: #f5f5f5;
|
||
padding: 4rpx 12rpx;
|
||
border-radius: 12rpx;
|
||
}
|
||
}
|
||
|
||
.card-btn {
|
||
width: 100%;
|
||
padding: 16rpx 0;
|
||
background: linear-gradient(135deg, #2d9687 0%, #25806f 100%);
|
||
border-radius: 30rpx;
|
||
text-align: center;
|
||
box-shadow: 0 4rpx 12rpx rgba(45, 150, 135, 0.3);
|
||
|
||
text {
|
||
font-size: 26rpx;
|
||
color: #ffffff;
|
||
font-weight: bold;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.logout-section {
|
||
padding: 30rpx;
|
||
|
||
.logout-btn {
|
||
width: 100%;
|
||
height: 88rpx;
|
||
background: #fff;
|
||
color: #ff6b6b;
|
||
font-size: 32rpx;
|
||
border-radius: 16rpx;
|
||
border: 2rpx solid #ff6b6b;
|
||
|
||
&::after {
|
||
border: none;
|
||
}
|
||
}
|
||
}
|
||
|
||
.modal-overlay {
|
||
position: fixed;
|
||
top: 0;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
background: rgba(0, 0, 0, 0.5);
|
||
display: flex;
|
||
align-items: flex-end;
|
||
z-index: 9999;
|
||
|
||
.modal-content {
|
||
width: 100%;
|
||
background: #fff;
|
||
border-radius: 32rpx 32rpx 0 0;
|
||
padding: 40rpx 30rpx;
|
||
|
||
.modal-title {
|
||
font-size: 36rpx;
|
||
font-weight: bold;
|
||
color: #333;
|
||
text-align: center;
|
||
margin-bottom: 30rpx;
|
||
}
|
||
|
||
.role-list {
|
||
.role-option {
|
||
padding: 30rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 20rpx;
|
||
border-radius: 16rpx;
|
||
margin-bottom: 16rpx;
|
||
background: #f5f7fa;
|
||
|
||
&.active {
|
||
background: #e8f5f3;
|
||
border: 2rpx solid #2d9687;
|
||
}
|
||
|
||
.role-icon {
|
||
font-size: 40rpx;
|
||
}
|
||
|
||
.role-name {
|
||
flex: 1;
|
||
font-size: 32rpx;
|
||
color: #333;
|
||
}
|
||
|
||
.check-icon {
|
||
font-size: 32rpx;
|
||
color: #2d9687;
|
||
}
|
||
}
|
||
}
|
||
|
||
.modal-close {
|
||
margin-top: 20rpx;
|
||
padding: 24rpx;
|
||
text-align: center;
|
||
font-size: 32rpx;
|
||
color: #666;
|
||
background: #f5f7fa;
|
||
border-radius: 16rpx;
|
||
}
|
||
}
|
||
}
|
||
</style>
|