tcm-training-admin-backend/src/main/java/com/tcm/training/admin/app/home/controller/AppHomeLiveCourseController.java
@@ -5,6 +5,7 @@ import com.tcm.training.admin.common.ApiResponse; import com.tcm.training.admin.live.dto.LiveCoursePasswordVerifyRequest; import com.tcm.training.admin.live.service.LiveCourseAppService; import com.tcm.training.admin.live.service.ProjectIntroductionPasswordService; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; @@ -27,13 +28,17 @@ private final LiveCourseAppService liveCourseAppService; private final ProjectIntroductionPasswordService projectIntroductionPasswordService; /** * 注入首页养生直播服务。 */ public AppHomeLiveCourseController(AppHomeLiveCourseService appHomeLiveCourseService, LiveCourseAppService liveCourseAppService) { LiveCourseAppService liveCourseAppService, ProjectIntroductionPasswordService projectIntroductionPasswordService) { this.appHomeLiveCourseService = appHomeLiveCourseService; this.liveCourseAppService = liveCourseAppService; this.projectIntroductionPasswordService = projectIntroductionPasswordService; } /** @@ -51,4 +56,12 @@ public ApiResponse<Boolean> verifyPassword(@Valid @RequestBody LiveCoursePasswordVerifyRequest req) { return ApiResponse.ok(liveCourseAppService.verifyPassword(req)); } /** * 检查项目介绍是否启用密码访问。 */ @GetMapping("/project-introduction/password-enabled") public ApiResponse<Boolean> isProjectIntroductionPasswordEnabled() { return ApiResponse.ok(projectIntroductionPasswordService.isPasswordEnabled()); } } tcm-training-admin-backend/src/main/java/com/tcm/training/admin/live/service/ProjectIntroductionPasswordService.java
@@ -108,4 +108,17 @@ && !config.getPassword().isEmpty() && passwordEncoder.matches(inputPassword, config.getPassword()); } /** * 检查项目介绍是否启用密码访问 */ public boolean isPasswordEnabled() { ProjectIntroductionPassword config = passwordMapper.selectOne( new LambdaQueryWrapper<ProjectIntroductionPassword>() .eq(ProjectIntroductionPassword::getPasswordEnabled, 1) .orderByAsc(ProjectIntroductionPassword::getId) .last("limit 1") ); return config != null; } } traditionalApp/pages/good/good.vue
@@ -17,7 +17,9 @@ @confirm="handleConfirm" /> </view> <view class="confirm-btn" :class="{ disabled: !password }" @tap="handleConfirm">确认</view> <view class="confirm-btn" :class="{ disabled: !password || submitting }" @tap="handleConfirm"> {{ submitting ? '验证中...' : '确认' }} </view> </view> <view v-else class="entry-content"> @@ -33,40 +35,76 @@ <script setup lang="ts"> import { onMounted, ref } from 'vue' /** 项目中心访问密码,后续改为接口读取后台配置。 */ const PROJECT_CENTER_PASSWORD = '123456' import { verifyProjectIntroductionPassword, checkProjectIntroductionPasswordEnabled } from './service.js' const statusBarHeight = ref(0) const password = ref('') const autoFocus = ref(true) const unlocked = ref(false) const submitting = ref(false) const loading = ref(true) onMounted(() => { onMounted(async () => { console.log('项目中心页面加载') uni.getSystemInfo({ success: (res) => { statusBarHeight.value = res.statusBarHeight || 0 } }) // 检查是否启用密码 try { console.log('开始检查密码启用状态...') const isPasswordEnabled = await checkProjectIntroductionPasswordEnabled() console.log('密码启用状态:', isPasswordEnabled) if (!isPasswordEnabled) { // 未启用密码,直接解锁 unlocked.value = true autoFocus.value = false console.log('密码未启用,直接解锁') } else { console.log('密码已启用,显示密码输入界面') } } catch (error) { console.error('检查密码状态失败:', error) } finally { loading.value = false } }) /** * 校验项目中心密码,通过后展示三个入口。 */ function handleConfirm() { async function handleConfirm() { if (!password.value) { return } if (password.value !== PROJECT_CENTER_PASSWORD) { uni.showToast({ title: '密码错误,请重新输入', icon: 'none' }) if (submitting.value) { return } unlocked.value = true password.value = '' autoFocus.value = false submitting.value = true try { const isValid = await verifyProjectIntroductionPassword(password.value) if (isValid) { unlocked.value = true password.value = '' autoFocus.value = false } else { uni.showToast({ title: '密码错误,请重新输入', icon: 'none' }) password.value = '' } } catch (error) { uni.showToast({ title: '验证失败,请重试', icon: 'none' }) } finally { submitting.value = false } } /** traditionalApp/pages/good/service.js
New file @@ -0,0 +1,22 @@ import { publicPost, publicGet } from '@/utils/public-request.js' /** * 检查项目介绍是否启用密码访问。 */ export const checkProjectIntroductionPasswordEnabled = async () => { const res = await publicGet('/api/app/home/project-introduction/password-enabled') // 返回格式:{ code: 200, data: true/false } return res?.data === true } /** * 校验项目介绍访问密码。 */ export const verifyProjectIntroductionPassword = async (password) => { const res = await publicPost('/api/app/home/live-courses/password/verify', { type: 2, password, }) // 返回格式:{ code: 200, data: true/false } return res?.data === true }