登录角色的区分和二维码跳转的修改

This commit is contained in:
Yu 2026-03-31 16:47:23 +08:00
parent 2630c7fef0
commit 431f24418a
21 changed files with 299 additions and 191 deletions

View File

@ -418,7 +418,7 @@ public class TeacherServiceImpl implements ITeacherService {
* @return 小程序页面路径 * @return 小程序页面路径
*/ */
private String buildMiniProgramPagePath() { private String buildMiniProgramPagePath() {
return "pages/pre_registration/pre_registration"; return "pages/index/index";
} }
/** /**

View File

@ -179,35 +179,44 @@ public class EnrollmentService {
* <p>- 本周招生数量 * <p>- 本周招生数量
* <p>- 本月招生数量 * <p>- 本月招生数量
* 招生数量定义student_status = 0 1 的学生数量 * 招生数量定义student_status = 0 1 的学生数量
*
* @param teacherId 招生老师 ID为空则统计所有老师
*/ */
public Map<String, Object> buildEnrollmentStats() { public Map<String, Object> buildEnrollmentStats(Integer teacherId) {
Map<String, Object> stats = new LinkedHashMap<>(); Map<String, Object> stats = new LinkedHashMap<>();
// 当前时间 // 当前时间
Date now = new Date(); Date now = new Date();
stats.put("time", new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(now)); stats.put("time", new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(now));
// 总招生数量所有时间 // 构建查询条件
long totalCount = studentInfoMapper.selectCount( com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<StudentInfo> queryWrapper =
new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<StudentInfo>() new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<StudentInfo>()
.in("student_status", 0, 1) .in("student_status", 0, 1)
.isNull("delete_time") .isNull("delete_time");
);
// 如果指定了老师 ID则只统计该老师的数据
if (teacherId != null) {
queryWrapper.eq("recruitment_teacher_id", teacherId);
}
// 总招生数量所有时间
long totalCount = studentInfoMapper.selectCount(queryWrapper);
// 今日本周本月时间范围 // 今日本周本月时间范围
LocalDate today = LocalDate.now(); LocalDate today = LocalDate.now();
Date todayStart = toDate(today.atStartOfDay()); Date todayStart = toDate(today.atStartOfDay());
Date tomorrowStart = toDate(today.plusDays(1).atStartOfDay()); Date tomorrowStart = toDate(today.plusDays(1).atStartOfDay());
LocalDate weekStartDate = today.minusDays(6); // 最近7天 LocalDate weekStartDate = today.minusDays(6); // 最近 7
Date weekStart = toDate(weekStartDate.atStartOfDay()); Date weekStart = toDate(weekStartDate.atStartOfDay());
LocalDate monthStartDate = today.minusDays(29); // 最近30天 LocalDate monthStartDate = today.minusDays(29); // 最近 30
Date monthStart = toDate(monthStartDate.atStartOfDay()); Date monthStart = toDate(monthStartDate.atStartOfDay());
long todayCount = countEnrollmentInRange(todayStart, tomorrowStart); long todayCount = countEnrollmentInRange(teacherId, todayStart, tomorrowStart);
long weekCount = countEnrollmentInRange(weekStart, tomorrowStart); long weekCount = countEnrollmentInRange(teacherId, weekStart, tomorrowStart);
long monthCount = countEnrollmentInRange(monthStart, tomorrowStart); long monthCount = countEnrollmentInRange(teacherId, monthStart, tomorrowStart);
stats.put("total_enroll_count", totalCount); stats.put("total_enroll_count", totalCount);
stats.put("today_enroll_count", todayCount); stats.put("today_enroll_count", todayCount);
@ -340,16 +349,26 @@ public class EnrollmentService {
/** /**
* 计算时间区间内的招生数量 pre_registration_time 筛选 * 计算时间区间内的招生数量 pre_registration_time 筛选
*
* @param teacherId 招生老师 ID为空则统计所有老师
* @param startTime 开始时间
* @param endTime 结束时间
*/ */
private long countEnrollmentInRange(Date startTime, Date endTime) { private long countEnrollmentInRange(Integer teacherId, Date startTime, Date endTime) {
return studentInfoMapper.selectCount( com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<StudentInfo> queryWrapper =
new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<StudentInfo>() new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<StudentInfo>()
.in("student_status", 0, 1) .in("student_status", 0, 1)
.isNull("delete_time") .isNull("delete_time")
.isNotNull("pre_registration_time") .isNotNull("pre_registration_time")
.ge("pre_registration_time", startTime) .ge("pre_registration_time", startTime)
.lt("pre_registration_time", endTime) .lt("pre_registration_time", endTime);
);
// 如果指定了老师 ID则只统计该老师的数据
if (teacherId != null) {
queryWrapper.eq("recruitment_teacher_id", teacherId);
}
return studentInfoMapper.selectCount(queryWrapper);
} }
public Map<String, Object> getAliyunUrl() { public Map<String, Object> getAliyunUrl() {

View File

@ -56,8 +56,12 @@ public class EnrollmentController {
@PostMapping("/enrollmentStatistical") @PostMapping("/enrollmentStatistical")
@ApiOperation(value = "招生统计数据") @ApiOperation(value = "招生统计数据")
public AjaxResult<Map<String, Object>> buildEnrollmentStatistical() { public AjaxResult<Map<String, Object>> buildEnrollmentStatistical(@RequestBody(required = false) Map<String, Object> params) {
return AjaxResult.success(enrollmentService.buildEnrollmentStats()); Integer teacherId = null;
if (params != null && params.get("teacherId") != null) {
teacherId = Integer.parseInt(params.get("teacherId").toString());
}
return AjaxResult.success(enrollmentService.buildEnrollmentStats(teacherId));
} }
@GetMapping("/enrollmentTrend") @GetMapping("/enrollmentTrend")

View File

@ -7,6 +7,7 @@ import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Assert; import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.mdd.common.entity.Teacher;
import com.mdd.common.entity.user.User; import com.mdd.common.entity.user.User;
import com.mdd.common.entity.user.UserAuth; import com.mdd.common.entity.user.UserAuth;
import com.mdd.common.entity.user.UserSession; import com.mdd.common.entity.user.UserSession;
@ -16,6 +17,7 @@ import com.mdd.common.exception.OperateException;
import com.mdd.common.mapper.user.UserAuthMapper; import com.mdd.common.mapper.user.UserAuthMapper;
import com.mdd.common.mapper.user.UserMapper; import com.mdd.common.mapper.user.UserMapper;
import com.mdd.common.mapper.user.UserSessionMapper; import com.mdd.common.mapper.user.UserSessionMapper;
import com.mdd.common.mapper.TeacherMapper;
import com.mdd.common.plugin.notice.NoticeCheck; import com.mdd.common.plugin.notice.NoticeCheck;
import com.mdd.common.plugin.wechat.WxMnpDriver; import com.mdd.common.plugin.wechat.WxMnpDriver;
import com.mdd.common.service.RegisterService; import com.mdd.common.service.RegisterService;
@ -56,6 +58,8 @@ public class LoginServiceImpl implements ILoginService {
UserAuthMapper userAuthMapper; UserAuthMapper userAuthMapper;
@Resource @Resource
UserSessionMapper userSessionMapper; UserSessionMapper userSessionMapper;
@Resource
TeacherMapper teacherMapper;
/** /**
* 注册账号 * 注册账号
@ -458,6 +462,25 @@ public class LoginServiceImpl implements ILoginService {
vo.setIsNew(isNew); vo.setIsNew(isNew);
vo.setMobile(mobile); vo.setMobile(mobile);
User currentUser = userMapper.selectOne(new QueryWrapper<User>()
.select("id,account")
.eq("id", userId)
.isNull("delete_time")
.last("limit 1"));
if (currentUser != null && StringUtils.isNotEmpty(currentUser.getAccount())) {
Teacher teacher = teacherMapper.selectOne(new QueryWrapper<Teacher>()
.eq("teacher_code", currentUser.getAccount())
.isNull("delete_time")
.last("limit 1"));
if (teacher != null) {
vo.setUserType(1);
} else {
vo.setUserType(0);
}
} else {
vo.setUserType(0);
}
//保存登录信息到session //保存登录信息到session
userSessionMapper.delete(new QueryWrapper<UserSession>().eq("user_id", userId).eq("terminal", terminal)); userSessionMapper.delete(new QueryWrapper<UserSession>().eq("user_id", userId).eq("terminal", terminal));

View File

@ -7,6 +7,7 @@ import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
import cn.binarywang.wx.miniapp.config.impl.WxMaDefaultConfigImpl; import cn.binarywang.wx.miniapp.config.impl.WxMaDefaultConfigImpl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.mdd.common.config.GlobalConfig; import com.mdd.common.config.GlobalConfig;
import com.mdd.common.entity.Teacher;
import com.mdd.common.entity.user.User; import com.mdd.common.entity.user.User;
import com.mdd.common.entity.user.UserAuth; import com.mdd.common.entity.user.UserAuth;
import com.mdd.common.enums.ClientEnum; import com.mdd.common.enums.ClientEnum;
@ -15,6 +16,7 @@ import com.mdd.common.enums.UserEnum;
import com.mdd.common.exception.OperateException; import com.mdd.common.exception.OperateException;
import com.mdd.common.mapper.user.UserAuthMapper; import com.mdd.common.mapper.user.UserAuthMapper;
import com.mdd.common.mapper.user.UserMapper; import com.mdd.common.mapper.user.UserMapper;
import com.mdd.common.mapper.TeacherMapper;
import com.mdd.common.plugin.notice.NoticeCheck; import com.mdd.common.plugin.notice.NoticeCheck;
import com.mdd.common.plugin.wechat.WxMnpDriver; import com.mdd.common.plugin.wechat.WxMnpDriver;
import com.mdd.common.util.*; import com.mdd.common.util.*;
@ -46,6 +48,9 @@ public class UserServiceImpl implements IUserService {
@Resource @Resource
UserAuthMapper userAuthMapper; UserAuthMapper userAuthMapper;
@Resource
TeacherMapper teacherMapper;
/** /**
* 个人中心 * 个人中心
* *
@ -83,6 +88,17 @@ public class UserServiceImpl implements IUserService {
vo.setHasPassword(StringUtils.isNotBlank(user.getPassword())); vo.setHasPassword(StringUtils.isNotBlank(user.getPassword()));
vo.setCreateTime(TimeUtils.timestampToDate(user.getCreateTime())); vo.setCreateTime(TimeUtils.timestampToDate(user.getCreateTime()));
vo.setSex(UserEnum.getSexDesc(user.getSex())); vo.setSex(UserEnum.getSexDesc(user.getSex()));
if (StringUtils.isNotEmpty(user.getAccount())) {
Teacher teacher = teacherMapper.selectOne(new QueryWrapper<Teacher>()
.eq("teacher_code", user.getAccount())
.isNull("delete_time")
.last("limit 1"));
vo.setUserType(teacher != null ? 1 : 0);
} else {
vo.setUserType(0);
}
return vo; return vo;
} }

View File

@ -27,4 +27,7 @@ public class LoginTokenVo implements Serializable {
@ApiModelProperty(value = "是否为新用户") @ApiModelProperty(value = "是否为新用户")
private Integer isNew; private Integer isNew;
@ApiModelProperty(value = "用户类型: 0=学生, 1=招生老师")
private Integer userType;
} }

View File

@ -51,5 +51,7 @@ public class UserCenterVo implements Serializable {
@ApiModelProperty("是否绑定微信") @ApiModelProperty("是否绑定微信")
private Boolean isAuth; private Boolean isAuth;
@ApiModelProperty(value = "用户类型: 0=学生, 1=招生老师")
private Integer userType;
} }

View File

@ -70,9 +70,13 @@ export function getRecruitmentList(data: any) {
} }
// 获取招生统计数据(总招生人数、本日、本周、本月) // 获取招生统计数据(总招生人数、本日、本周、本月)
export function getEnrollmentStatistical() { export function getEnrollmentStatistical(teacherId?: number) {
const data: any = {}
if (teacherId !== undefined && teacherId !== null) {
data.teacherId = teacherId
}
return request.post( return request.post(
{ url: 'frontapi/enrollment/enrollmentStatistical' }, { url: 'frontapi/enrollment/enrollmentStatistical', data },
{ urlPrefix: '' } { urlPrefix: '' }
) )
} }

View File

@ -1,6 +1,5 @@
<template> <template>
<u-tabbar <u-tabbar
v-if="showTabbar"
v-model="current" v-model="current"
v-bind="tabbarStyle" v-bind="tabbarStyle"
:list="tabbarList" :list="tabbarList"
@ -10,42 +9,44 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { useAppStore } from '@/stores/app' import { useUserStore } from '@/stores/user'
import { navigateTo } from '@/utils/util'
import { computed, ref } from 'vue' import { computed, ref } from 'vue'
const current = ref() const current = ref()
const appStore = useAppStore() const userStore = useUserStore()
const tabbarList = computed(() => {
return appStore.getTabbarConfig const allTabs = [
?.filter((item: any) => item.is_show == 1) {
.map((item: any) => { iconPath: '/static/yubaoming/home_icon.png',
return { selectedIconPath: '/static/yubaoming/home_icon_active.png',
iconPath: item.unselected, text: '首页',
selectedIconPath: item.selected, pagePath: '/pages/index/index'
text: item.name, },
link: item.link, {
pagePath: item.link.path iconPath: '/static/yubaoming/my_icon.png',
selectedIconPath: '/static/yubaoming/my_icon_active.png',
text: '我的',
pagePath: '/pages/user/user',
teacherOnly: true
} }
]
const tabbarList = computed(() => {
return allTabs.filter((item) => {
if (item.teacherOnly && !userStore.isTeacher) {
return false
}
return true
}) })
}) })
const showTabbar = computed(() => {
const currentPages = getCurrentPages()
const currentPage = currentPages[currentPages.length - 1]
const current = tabbarList.value.findIndex((item: any) => {
return item.pagePath === '/' + currentPage.route
})
return current >= 0
})
const tabbarStyle = computed(() => ({ const tabbarStyle = computed(() => ({
activeColor: appStore.getStyleConfig.selected_color, activeColor: '#2979ff',
inactiveColor: appStore.getStyleConfig.default_color inactiveColor: '#999999'
})) }))
const nativeTabbar = ['/pages/index/index', '/pages/user/user']
const handleChange = (index: number) => { const handleChange = (index: number) => {
const selectTab = tabbarList.value[index] const selectTab = tabbarList.value[index]
const navigateType = nativeTabbar.includes(selectTab.link.path) ? 'switchTab' : 'reLaunch' uni.reLaunch({ url: selectTab.pagePath })
navigateTo(selectTab.link, navigateType)
} }
</script> </script>

View File

@ -1,16 +1,16 @@
import { isDevMode } from '@/utils/env' import { isDevMode } from '@/utils/env'
// 微信小程序特殊处理:确保编译后也能正确获取 baseUrl
// 优先级:环境变量 > 默认开发地址
const envBaseUrl = import.meta.env.VITE_APP_BASE_URL || '' const envBaseUrl = import.meta.env.VITE_APP_BASE_URL || ''
let baseUrl = `${envBaseUrl}/`
/*
* `VITE_APP_BASE_URL``dev`
* 使`VITE_APP_BASE_URL`
* 使`[baseUrl]`便
*/
//#ifdef MP-WEIXIN //#ifdef MP-WEIXIN
baseUrl = isDevMode() || envBaseUrl ? baseUrl : '[baseUrl]' // 微信小程序:如果环境变量为空,使用默认开发地址
let baseUrl = envBaseUrl ? `${envBaseUrl}/` : 'http://192.168.123.123:8084/'
//#endif
//#ifndef MP-WEIXIN
let baseUrl = `${envBaseUrl}/`
//#endif //#endif
const config = { const config = {

View File

@ -87,23 +87,6 @@
"navigationStyle": "custom" "navigationStyle": "custom"
} }
}, },
"tabBar": {
"iconWidth": "20px",
"list": [
{
"iconPath": "static/images/tabbar/home.png",
"selectedIconPath": "static/yubaoming/home_icon_active.png",
"pagePath": "pages/index/index",
"text": "首页"
},
{
"iconPath": "static/images/tabbar/user.png",
"selectedIconPath": "static/yubaoming/my_icon_active.png",
"pagePath": "pages/user/user",
"text": "我的"
}
]
},
"easycom": { "easycom": {
"custom": { "custom": {
"router-navigate": "uniapp-router-next/components/router-navigate/router-navigate.vue", "router-navigate": "uniapp-router-next/components/router-navigate/router-navigate.vue",

View File

@ -13,8 +13,10 @@
class="school-logo" class="school-logo"
/> />
<view class="welcome-text"> <view class="welcome-text">
<view class="title">您好招生老师</view> <view class="title" v-if="isTeacher">您好招生老师</view>
<view class="subtitle">祝您招生顺利业绩长虹</view> <view class="title" v-else>欢迎来到预报名系统</view>
<view class="subtitle" v-if="isTeacher">祝您招生顺利业绩长虹</view>
<view class="subtitle" v-else>请选择下方功能开始操作</view>
</view> </view>
<image <image
:src="homeImageSrc" :src="homeImageSrc"
@ -23,7 +25,7 @@
/> />
<!-- 快捷操作标题 --> <!-- 快捷操作标题 -->
<view class="section-title" v-if="isLogin"> <view class="section-title" v-if="isLogin && isTeacher">
<view class="title-icon"></view> <view class="title-icon"></view>
<text>快捷操作</text> <text>快捷操作</text>
</view> </view>
@ -31,8 +33,8 @@
<!-- 主要内容区域 --> <!-- 主要内容区域 -->
<view class="main-content"> <view class="main-content">
<!-- 快捷操作入口 --> <!-- 招生老师快捷操作入口 -->
<view class="quick-actions" v-if="isLogin"> <view class="quick-actions" v-if="isLogin && isTeacher">
<view class="action-item" @click="goToPreRegistration"> <view class="action-item" @click="goToPreRegistration">
<view class="action-icon blue"> <view class="action-icon blue">
<u-icon name="edit-pen" size="40" color="#FFFFFF"></u-icon> <u-icon name="edit-pen" size="40" color="#FFFFFF"></u-icon>
@ -59,6 +61,22 @@
</view> </view>
</view> </view>
<!-- 学生功能入口 -->
<view class="quick-actions" v-if="isLogin && !isTeacher">
<view class="action-item" @click="goToPreRegistration">
<view class="action-icon blue">
<u-icon name="edit-pen" size="40" color="#FFFFFF"></u-icon>
</view>
<text class="action-text">预报名</text>
</view>
<view class="action-item" @click="goToPayment">
<view class="action-icon orange">
<u-icon name="rmb-circle" size="40" color="#FFFFFF"></u-icon>
</view>
<text class="action-text">缴费</text>
</view>
</view>
<!-- 未登录提示 --> <!-- 未登录提示 -->
<view class="login-tip" v-if="!isLogin"> <view class="login-tip" v-if="!isLogin">
<view class="tip-icon">🔒</view> <view class="tip-icon">🔒</view>
@ -101,12 +119,13 @@
<!-- 微信小程序隐私弹窗 --> <!-- 微信小程序隐私弹窗 -->
<MpPrivacyPopup></MpPrivacyPopup> <MpPrivacyPopup></MpPrivacyPopup>
<!-- #endif --> <!-- #endif -->
<tabbar />
</view> </view>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { getIndex } from '@/api/shop' import { getIndex } from '@/api/shop'
import { getEnrollmentStatistical } from '@/api/app' import { getEnrollmentStatistical, getTeacherInfo } from '@/api/app'
import { onLoad, onShow } from '@dcloudio/uni-app' import { onLoad, onShow } from '@dcloudio/uni-app'
import { computed, reactive, ref } from 'vue' import { computed, reactive, ref } from 'vue'
import { useAppStore } from '@/stores/app' import { useAppStore } from '@/stores/app'
@ -121,7 +140,7 @@ import MpPrivacyPopup from './component/mp-privacy-popup.vue'
const appStore = useAppStore() const appStore = useAppStore()
const userStore = useUserStore() const userStore = useUserStore()
const { isLogin, userInfo } = storeToRefs(userStore) const { isLogin, userInfo, isTeacher } = storeToRefs(userStore)
const state = reactive<{ const state = reactive<{
pages: any[] pages: any[]
@ -164,8 +183,31 @@ const getStats = async () => {
if (!isLogin.value) { if (!isLogin.value) {
return return
} }
try { try {
const res = await getEnrollmentStatistical() // teacherId
let teacherId: number | undefined = undefined
// userInfo
if (userInfo.value?.teacherId) {
teacherId = userInfo.value.teacherId
} else {
// userInfo getTeacherInfo
try {
const teacherRes = await getTeacherInfo({ id: userInfo.value.id })
if (teacherRes && teacherRes.code === 1 && teacherRes.data) {
teacherId = teacherRes.data.teacherId
// userInfo
userInfo.value.teacherId = teacherId
}
} catch (error) {
console.error('获取教师信息失败:', error)
}
}
if (teacherId) {
console.log('首页获取招生统计teacherId:', teacherId)
const res = await getEnrollmentStatistical(teacherId)
// code // code
if (res && res.total_enroll_count !== undefined) { if (res && res.total_enroll_count !== undefined) {
stats.value = { stats.value = {
@ -174,6 +216,9 @@ const getStats = async () => {
week: res.week_enroll_count week: res.week_enroll_count
} }
} }
} else {
console.log('未找到 teacherId跳过获取招生统计')
}
} catch (error) { } catch (error) {
console.error('获取招生统计失败:', error) console.error('获取招生统计失败:', error)
} }
@ -192,7 +237,7 @@ const goToMyRecruitment = () => {
} }
const goToUser = () => { const goToUser = () => {
uni.switchTab({ uni.reLaunch({
url: '/pages/user/user' url: '/pages/user/user'
}) })
} }
@ -220,7 +265,7 @@ const initImageSources = async () => {
} }
const shareQrcode = () => { const shareQrcode = () => {
uni.switchTab({ uni.reLaunch({
url: '/pages/user/user' url: '/pages/user/user'
}) })
setTimeout(() => { setTimeout(() => {
@ -228,14 +273,39 @@ const shareQrcode = () => {
}, 300) }, 300)
} }
onLoad(() => { onLoad((options: any) => {
initImageSources() initImageSources()
getData() getData()
if (options.scene) {
const invitationCode = decodeURIComponent(options.scene)
if (isLogin.value) {
uni.navigateTo({
url: `/pages/pre_registration/pre_registration?invitationCode=${invitationCode}`
})
} else {
uni.navigateTo({
url: `/pages/login/login?invitationCode=${invitationCode}`
})
}
}
}) })
onShow(async () => { onShow(async () => {
// //
await new Promise(resolve => setTimeout(resolve, 100)) await new Promise(resolve => setTimeout(resolve, 100))
//
if (!isLogin.value) {
return
}
// userInfo getUser
if (!userInfo.value?.id) {
await userStore.getUser()
}
// getStats teacherId
getStats() getStats()
}) })
</script> </script>

View File

@ -376,13 +376,26 @@ const loginHandle = async (data: any) => {
uni.hideLoading() uni.hideLoading()
return return
} }
userStore.login(data.token) console.log('登录返回数据:', data)
console.log('登录返回userType:', data.user_type)
userStore.login(data.token, data.user_type)
console.log('登录后token:', userStore.token) console.log('登录后token:', userStore.token)
console.log('登录后userType:', userStore.userType)
console.log('登录后isTeacher:', userStore.isTeacher)
await userStore.getUser() await userStore.getUser()
console.log('获取用户信息后userInfo:', userStore.userInfo) console.log('获取用户信息后userInfo:', userStore.userInfo)
console.log('获取用户信息后userType:', userStore.userType)
console.log('获取用户信息后isTeacher:', userStore.isTeacher)
console.log('登录状态:', userStore.isLogin) console.log('登录状态:', userStore.isLogin)
uni.$u.toast('登录成功') uni.$u.toast('登录成功')
uni.hideLoading() uni.hideLoading()
const invitationCode = cache.get('INVITATION_CODE')
if (invitationCode) {
cache.remove('INVITATION_CODE')
router.reLaunch(`/pages/pre_registration/pre_registration?invitationCode=${invitationCode}`)
cache.remove(BACK_URL)
return
}
const pages = getCurrentPages() const pages = getCurrentPages()
if (pages.length > 1) { if (pages.length > 1) {
const prevPage = pages[pages.length - 2] const prevPage = pages[pages.length - 2]
@ -393,16 +406,12 @@ const loginHandle = async (data: any) => {
onLoad && onLoad(options) onLoad && onLoad(options)
} else if (cache.get(BACK_URL)) { } else if (cache.get(BACK_URL)) {
try { try {
router.switchTab(cache.get(BACK_URL)) router.reLaunch(cache.get(BACK_URL))
} catch (error) { } catch (error) {
router.redirectTo(cache.get(BACK_URL)) router.redirectTo(cache.get(BACK_URL))
} }
} else { } else {
// try { router.reLaunch('/pages/index/index')
// router.reLaunch('/pages/index/index')
// } catch (error) {
router.switchTab('/pages/index/index')
//}
} }
cache.remove(BACK_URL) cache.remove(BACK_URL)
} }
@ -496,7 +505,10 @@ const removeWxQuery = () => {
} }
} }
onLoad(async () => { onLoad(async (pageOptions: any) => {
if (pageOptions.invitationCode) {
cache.set('INVITATION_CODE', pageOptions.invitationCode)
}
//#ifdef H5 //#ifdef H5
const options = wechatOa.getAuthData() const options = wechatOa.getAuthData()
try { try {

View File

@ -50,7 +50,7 @@
<view class="td td-name">{{ item.name }}</view> <view class="td td-name">{{ item.name }}</view>
<view class="td td-gender">{{ item.gender === 1 ? '男' : item.gender === 2 ? '女' : '-' }}</view> <view class="td td-gender">{{ item.gender === 1 ? '男' : item.gender === 2 ? '女' : '-' }}</view>
<view class="td td-score">{{ item.highSchoolScore || '-' }}</view> <view class="td td-score">{{ item.highSchoolScore || '-' }}</view>
<view class="td td-major">{{ item.majorName || '-' }}</view> <view class="td td-major">{{ item.major_name || '-' }}</view>
<view class="td td-status"> <view class="td td-status">
<text :class="item.studentStatus === 1 ? 'status-enrolled' : 'status-pre'"> <text :class="item.studentStatus === 1 ? 'status-enrolled' : 'status-pre'">
{{ item.studentStatus === 1 ? '已报名' : '预报名' }} {{ item.studentStatus === 1 ? '已报名' : '预报名' }}

View File

@ -1,13 +1,5 @@
<template> <template>
<view class="payment"> <view class="payment">
<u-navbar
title="缴费"
:border-bottom="false"
back-icon-color="#333"
title-color="#333"
:background="{ background: '#FFFFFF' }"
/>
<view class="payment-content"> <view class="payment-content">
<!-- 缴费金额输入 --> <!-- 缴费金额输入 -->
<view class="amount-section"> <view class="amount-section">

View File

@ -150,7 +150,7 @@
class="dropdown-option" class="dropdown-option"
@click="selectMajor(index)" @click="selectMajor(index)"
> >
{{ item.majorName }} {{ item.major_name }}
</view> </view>
</scroll-view> </scroll-view>
</view> </view>
@ -233,11 +233,30 @@ const submitBtnStyle = {
} }
const getTeacherData = async (teacherId: string) => { const getTeacherData = async (teacherId: string) => {
console.log('=== getTeacherData 被调用 ===')
console.log('teacherId:', teacherId)
try { try {
console.log('开始调用 getTeacherInfo...')
const res = await getTeacherInfo({ teacherId: Number(teacherId) }) const res = await getTeacherInfo({ teacherId: Number(teacherId) })
console.log('getTeacherInfo 返回:', res)
if (res.code === 1 && res.data) { if (res.code === 1 && res.data) {
formData.teacher = res.data.teacherName formData.teacher = res.data.teacher_name
formData.recruitmentTeacherId = res.data.teacherId formData.recruitmentTeacherId = res.data.teacher_id
}
} catch (error) {
console.error('获取老师信息失败:', error)
}
}
const getTeacherDataByInvitationCode = async (invitationCode: string) => {
console.log('=== getTeacherDataByInvitationCode 被调用 ===')
console.log('invitationCode:', invitationCode)
try {
const res = await getTeacherInfo({ invitationCode: invitationCode })
console.log('getTeacherInfo 返回:', res)
if (res.code === 1 && res.data) {
formData.teacher = res.data.teacher_name
formData.recruitmentTeacherId = res.data.teacher_id
} }
} catch (error) { } catch (error) {
console.error('获取老师信息失败:', error) console.error('获取老师信息失败:', error)
@ -258,7 +277,7 @@ const getMajors = async () => {
const onMajorChange = (e: any) => { const onMajorChange = (e: any) => {
console.log('选择了专业:', e) console.log('选择了专业:', e)
formData.major = majorList.value[e.detail.value].majorName formData.major = majorList.value[e.detail.value].major_name
majorIndex.value = e.detail.value majorIndex.value = e.detail.value
} }
@ -275,7 +294,7 @@ const clearMajor = () => {
const selectMajor = (index: number) => { const selectMajor = (index: number) => {
console.log('选择了专业索引:', index) console.log('选择了专业索引:', index)
formData.major = majorList.value[index].majorName formData.major = majorList.value[index].major_name
formData.majorId = majorList.value[index].id formData.majorId = majorList.value[index].id
majorIndex.value = index majorIndex.value = index
showDropdown.value = false showDropdown.value = false
@ -441,8 +460,13 @@ onMounted(() => {
}) })
onLoad((options: any) => { onLoad((options: any) => {
console.log('=== 预报名页面 onLoad ===')
console.log('options:', options)
if (options.teacherId) { if (options.teacherId) {
getTeacherData(options.teacherId) getTeacherData(options.teacherId)
} else if (options.invitationCode) {
getTeacherDataByInvitationCode(options.invitationCode)
} }
}) })
</script> </script>

View File

@ -198,6 +198,7 @@
</view> </view>
</view> </view>
</u-popup> </u-popup>
<tabbar />
</view> </view>
</template> </template>
@ -305,11 +306,12 @@ const getQrcode = async (teacherId?: number) => {
console.log('=== getQrcode 执行结束 ===') console.log('=== getQrcode 执行结束 ===')
} }
const getStats = async () => { const getStats = async (teacherId?: number) => {
console.log('=== getStats 开始执行 ===') console.log('=== getStats 开始执行 ===')
console.log('传入的 teacherId:', teacherId)
try { try {
console.log('正在调用 getEnrollmentStatistical...') console.log('正在调用 getEnrollmentStatistical, teacherId:', teacherId)
const res = await getEnrollmentStatistical() const res = await getEnrollmentStatistical(teacherId)
console.log('接口返回结果:', res) console.log('接口返回结果:', res)
// code // code
if (res && res.total_enroll_count !== undefined) { if (res && res.total_enroll_count !== undefined) {
@ -437,7 +439,7 @@ const logout = () => {
success: (res) => { success: (res) => {
if (res.confirm) { if (res.confirm) {
userStore.logout() userStore.logout()
uni.switchTab({ uni.reLaunch({
url: '/pages/index/index' url: '/pages/index/index'
}) })
uni.$u.toast('已退出登录') uni.$u.toast('已退出登录')
@ -495,9 +497,9 @@ onShow(async () => {
console.log('开始调用 getQrcode 和 getStats, teacherIdForQrcode:', teacherIdForQrcode) console.log('开始调用 getQrcode 和 getStats, teacherIdForQrcode:', teacherIdForQrcode)
console.log('userInfo 中的 teacherId:', userInfo.value?.teacherId) console.log('userInfo 中的 teacherId:', userInfo.value?.teacherId)
// 使teacherId // 使 teacherId
await getQrcode(teacherIdForQrcode) await getQrcode(teacherIdForQrcode)
await getStats() await getStats(teacherIdForQrcode)
} else { } else {
console.log('条件不满足,跳过数据获取') console.log('条件不满足,跳过数据获取')
console.log('isLogin:', isLogin.value) console.log('isLogin:', isLogin.value)

View File

@ -8,16 +8,19 @@ interface UserSate {
userInfo: Record<string, any> userInfo: Record<string, any>
token: string | null token: string | null
temToken: string | null temToken: string | null
userType: number
} }
export const useUserStore = defineStore({ export const useUserStore = defineStore({
id: 'userStore', id: 'userStore',
state: (): UserSate => ({ state: (): UserSate => ({
userInfo: {}, userInfo: {},
token: cache.get(TOKEN_KEY) || null, token: cache.get(TOKEN_KEY) || null,
temToken: null temToken: null,
userType: 0
}), }),
getters: { getters: {
isLogin: (state) => !!state.token isLogin: (state) => !!state.token,
isTeacher: (state) => state.userType === 1
}, },
actions: { actions: {
async getUser() { async getUser() {
@ -32,14 +35,20 @@ export const useUserStore = defineStore({
try { try {
const data = await getUserCenter() const data = await getUserCenter()
this.userInfo = data this.userInfo = data
if (data.user_type !== undefined && data.user_type !== null) {
this.userType = data.user_type
}
resetSession() resetSession()
} catch (error) { } catch (error) {
console.error('获取用户信息失败:', error) console.error('获取用户信息失败:', error)
} }
}, },
login(token: string) { login(token: string, userType?: number) {
console.log('保存token:', token) console.log('保存token:', token)
this.token = token this.token = token
if (userType !== undefined && userType !== null) {
this.userType = userType
}
cache.set(TOKEN_KEY, token) cache.set(TOKEN_KEY, token)
console.log('保存后从cache读取token:', cache.get(TOKEN_KEY)) console.log('保存后从cache读取token:', cache.get(TOKEN_KEY))
resetSession() resetSession()
@ -47,6 +56,7 @@ export const useUserStore = defineStore({
logout() { logout() {
this.token = '' this.token = ''
this.userInfo = {} this.userInfo = {}
this.userType = 0
cache.remove(TOKEN_KEY) cache.remove(TOKEN_KEY)
} }
} }

View File

@ -6,54 +6,5 @@
import { getTabBarIconPath } from './configUtils' import { getTabBarIconPath } from './configUtils'
import { ensureStorageConfig } from './configUtils' import { ensureStorageConfig } from './configUtils'
/**
* tabbar图标
* @param index tabbar索引
* @param iconType
* @param isActive
*/
export function setTabBarIcon(index: number, iconType: 'home' | 'user', isActive: boolean = false) {
try {
// 获取阿里云图标路径
const iconPath = getTabBarIconPath(iconType, isActive)
// 设置tabbar图标
if (isActive) {
uni.setTabBarItem({
index,
selectedIconPath: iconPath
})
} else {
uni.setTabBarItem({
index,
iconPath
})
}
} catch (error) {
console.error(`设置tabbar图标失败:`, error)
}
}
/**
* tabbar图标
*/
export function updateAllTabBarIcons() {
// 更新首页tabbar图标 (索引0)
setTabBarIcon(0, 'home', false)
setTabBarIcon(0, 'home', true)
// 更新个人中心tabbar图标 (索引1)
setTabBarIcon(1, 'user', false)
setTabBarIcon(1, 'user', true)
}
/**
* tabbar图标
*/
export function initTabBarIcons() { export function initTabBarIcons() {
// 延迟执行,确保配置已加载
setTimeout(async () => {
await ensureStorageConfig()
updateAllTabBarIcons()
}, 1000)
} }

View File

@ -66,7 +66,6 @@ export function navigateTo(
const url = link?.query ? `${link.path}?${objectToQuery(link?.query)}` : link.path const url = link?.query ? `${link.path}?${objectToQuery(link?.query)}` : link.path
;(navigateType == 'switchTab' || link.canTab) && uni.switchTab({ url })
navigateType == 'navigateTo' && uni.navigateTo({ url }) navigateType == 'navigateTo' && uni.navigateTo({ url })
navigateType == 'reLaunch' && uni.reLaunch({ url }) navigateType == 'reLaunch' && uni.reLaunch({ url })
} }

View File

@ -1,4 +1,4 @@
import { defineConfig } from 'vite' import { defineConfig, loadEnv } from 'vite'
import uni from '@dcloudio/vite-plugin-uni' import uni from '@dcloudio/vite-plugin-uni'
import tailwindcss from 'tailwindcss' import tailwindcss from 'tailwindcss'
import autoprefixer from 'autoprefixer' import autoprefixer from 'autoprefixer'
@ -24,7 +24,11 @@ if (!weappTailwindcssDisabled) {
} }
// https://vitejs.dev/config/ // https://vitejs.dev/config/
export default defineConfig({ export default defineConfig(({ mode }) => {
// 加载环境变量,支持 .env, .env.local, .env.development, .env.production
const env = loadEnv(mode, process.cwd())
return {
plugins: [uni(), uniRouter(), weappTailwindcssDisabled ? undefined : vwt()], plugins: [uni(), uniRouter(), weappTailwindcssDisabled ? undefined : vwt()],
css: { css: {
postcss: { postcss: {
@ -32,18 +36,7 @@ export default defineConfig({
} }
}, },
server: { server: {
port: 8991, port: 8991
proxy: {
'/frontapi': {
target: 'http://192.168.123.91:8084',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/frontapi/, '/frontapi')
},
'/adminapi': {
target: 'http://192.168.123.91:8084',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/adminapi/, '/adminapi')
}
} }
} }
}) })