video curcse
All checks were successful
Deploy to Server / deploy (push) Successful in 36s

This commit is contained in:
jeremygan2021
2026-02-27 14:09:11 +08:00
parent f9c104452b
commit a47be29bf1
4 changed files with 64 additions and 17 deletions

View File

@@ -106,6 +106,16 @@ const VCCourseDetail = () => {
message.success('支付成功!报名已完成。'); message.success('支付成功!报名已完成。');
setTimeout(() => { setTimeout(() => {
setIsModalOpen(false); setIsModalOpen(false);
// 刷新课程详情以获取解锁后的视频URL
const fetchDetail = async () => {
try {
const res = await getVCCourseDetail(id);
setCourse(res.data);
} catch (error) {
console.error("Failed to refresh course detail:", error);
}
};
fetchDetail();
}, 2000); // Wait 2 seconds before closing }, 2000); // Wait 2 seconds before closing
clearInterval(timer); clearInterval(timer);
} }
@@ -115,7 +125,7 @@ const VCCourseDetail = () => {
}, 3000); }, 3000);
} }
return () => clearInterval(timer); return () => clearInterval(timer);
}, [payMode, paySuccess, currentOrderId]); }, [payMode, paySuccess, currentOrderId, id]);
const handleEnroll = async (values) => { const handleEnroll = async (values) => {
setSubmitting(true); setSubmitting(true);
@@ -396,7 +406,9 @@ const VCCourseDetail = () => {
border: `1px solid rgba(0, 240, 255, 0.2)`, border: `1px solid rgba(0, 240, 255, 0.2)`,
boxShadow: `0 0 20px rgba(0, 240, 255, 0.05)` boxShadow: `0 0 20px rgba(0, 240, 255, 0.05)`
}}> }}>
<Title level={3} style={{ color: '#fff', marginTop: 0 }}>报名咨询</Title> <Title level={3} style={{ color: '#fff', marginTop: 0 }}>
{course.is_video_course ? '购买课程' : '报名咨询'}
</Title>
<div style={{ display: 'flex', alignItems: 'baseline', marginBottom: 20 }}> <div style={{ display: 'flex', alignItems: 'baseline', marginBottom: 20 }}>
{parseFloat(course.price) > 0 ? ( {parseFloat(course.price) > 0 ? (
@@ -412,7 +424,7 @@ const VCCourseDetail = () => {
type="primary" type="primary"
size="large" size="large"
block block
icon={<FormOutlined />} icon={course.is_video_course ? <PlayCircleOutlined /> : <FormOutlined />}
style={{ style={{
height: 50, height: 50,
background: '#00f0ff', background: '#00f0ff',
@@ -423,10 +435,12 @@ const VCCourseDetail = () => {
}} }}
onClick={() => setIsModalOpen(true)} onClick={() => setIsModalOpen(true)}
> >
立即报名 / 咨询 {course.is_video_course ? '购买视频课程' : '立即报名 / 咨询'}
</Button> </Button>
<p style={{ color: '#666', marginTop: 15, fontSize: 12, textAlign: 'center' }}> <p style={{ color: '#666', marginTop: 15, fontSize: 12, textAlign: 'center' }}>
* 提交后我们的顾问将尽快与您联系确认 {course.is_video_course
? '* 支付成功后自动解锁视频内容'
: '* 提交后我们的顾问将尽快与您联系确认'}
</p> </p>
</div> </div>
</div> </div>
@@ -436,7 +450,7 @@ const VCCourseDetail = () => {
{/* Enroll Modal */} {/* Enroll Modal */}
<Modal <Modal
title={payMode ? '微信扫码支付' : `报名/咨询 - ${course.title}`} title={payMode ? '微信扫码支付' : `${course.is_video_course ? '购买课程' : '报名/咨询'} - ${course.title}`}
open={isModalOpen} open={isModalOpen}
onCancel={() => setIsModalOpen(false)} onCancel={() => setIsModalOpen(false)}
footer={null} footer={null}
@@ -463,14 +477,18 @@ const VCCourseDetail = () => {
<p style={{ marginTop: 20, fontSize: 16, fontWeight: 'bold' }}>¥{course.price}</p> <p style={{ marginTop: 20, fontSize: 16, fontWeight: 'bold' }}>¥{course.price}</p>
<p style={{ color: '#666', marginTop: 10 }}>请使用微信扫一扫支付</p> <p style={{ color: '#666', marginTop: 10 }}>请使用微信扫一扫支付</p>
<div style={{ marginTop: 20, fontSize: 12, color: '#999' }}> <div style={{ marginTop: 20, fontSize: 12, color: '#999' }}>
支付完成后将自动完成报名 支付完成后将自动{course.is_video_course ? '解锁视频' : '完成报名'}
</div> </div>
</> </>
)} )}
</div> </div>
) : ( ) : (
<> <>
<p style={{ marginBottom: 20, color: '#666' }}>请填写您的联系方式我们将为您安排课程顾问</p> <p style={{ marginBottom: 20, color: '#666' }}>
{course.is_video_course
? '请确认您的联系方式,以便我们记录您的购买信息。'
: '请填写您的联系方式,我们将为您安排课程顾问。'}
</p>
<Form <Form
form={form} form={form}
layout="vertical" layout="vertical"

View File

@@ -78,15 +78,39 @@
height: 420px; height: 420px;
background-color: #111; background-color: #111;
border-radius: 16px; border-radius: 16px;
display: flex; position: relative;
flex-direction: column; overflow: hidden;
align-items: center;
justify-content: center;
border: 1px solid rgba(255, 255, 255, 0.1); border: 1px solid rgba(255, 255, 255, 0.1);
.locked-bg {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
z-index: 1;
opacity: 0.5;
filter: blur(4px);
}
.locked-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 2;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background: rgba(0, 0, 0, 0.6);
}
.lock-icon { .lock-icon {
font-size: 60px; font-size: 60px;
margin-bottom: 20px; margin-bottom: 20px;
color: #00f0ff;
} }
.lock-text { .lock-text {

View File

@@ -100,9 +100,12 @@ export default function CourseDetail() {
/> />
) : ( ) : (
<View className='video-locked' onClick={handleLaunch}> <View className='video-locked' onClick={handleLaunch}>
<View className='lock-icon'>🔒</View> <Image src={detail.cover_image_url} className='locked-bg' mode='aspectFill' />
<Text className='lock-text'></Text> <View className='locked-overlay'>
<Button className='btn-unlock'></Button> <View className='lock-icon'>🔒</View>
<Text className='lock-text'></Text>
<Button className='btn-unlock'></Button>
</View>
</View> </View>
)} )}
</View> </View>
@@ -193,7 +196,9 @@ export default function CourseDetail() {
<Text className='label'>:</Text> <Text className='label'>:</Text>
<Text className='amount'>¥{detail.price}</Text> <Text className='amount'>¥{detail.price}</Text>
</View> </View>
<Button className='btn-buy' onClick={handleLaunch}></Button> <Button className='btn-buy' onClick={handleLaunch}>
{detail.is_video_course ? '立即购买' : '立即报名'}
</Button>
</View> </View>
</View> </View>
) )

View File

@@ -342,7 +342,7 @@ export default function UserIndex() {
)} )}
<Text className='uid'>ID: {userInfo ? (userInfo.phone_number || userInfo.id || '----') : '----'}</Text> <Text className='uid'>ID: {userInfo ? (userInfo.phone_number || userInfo.id || '----') : '----'}</Text>
{!userInfo && ( {!userInfo?.phone_number && (
<View className='login-btns'> <View className='login-btns'>
<Button <Button
className='btn-login primary' className='btn-login primary'