课程管理

课程管理

课程管理-发布课程界面和模型完成

{% extends 'cms/base.html' %}

{% block title %}
    发布课程
{% endblock %}

{% block head %}
    <script src="{% static 'ueditor/ueditor.config.js' %}"></script>
    <script src="{% static 'ueditor/ueditor.all.min.js' %}"></script>
    <script src="{% static 'js/pub_course.min.js' %}"></script>
{% endblock %}

{% block content-header %}
<h1>发布课程</h1>
{% endblock %}

{% block content %}
<div class="row">
<div class="col-md-12">
    <div class="box">
        <div class="box-header">
            <div class="form-group">
                <label for="title-input">标题:</label>
                <input type="text" class="form-control" placeholder="课程标题" name="title" id="title-input">
            </div>
            <div class="form-group">
                <label for="category-input">分类:</label>
                <select name="category" class="form-control" id="category-input">
                    {% for category in categories %}
                        <option value="{{ category.pk }}">{{ category.name }}</option>
                    {% endfor %}
                </select>
            </div>
            <div class="form-group">
                <label for="teacher-input">讲师:</label>
                <select name="teacher" id="teacher-input" class="form-control">
                    {% for teacher in teachers %}
                        <option value="{{ teacher.pk }}">{{ teacher.username }}</option>
                    {% endfor %}
                </select>
            </div>
            <div class="form-group">
                <label for="video-input">视频地址:</label>
                <input type="text" class="form-control" name="video_url" id="video-input" placeholder="视频地址">
            </div>
            <div class="form-group">
                <label for="cover-input">封面图:</label>
                <input type="text" class="form-control" name="cover" id="cover-input" placeholder="封面图">
            </div>
            <div class="form-group">
                <label for="price-input">价格:</label>
                <input type="text" class="form-control" name="price" id="price-input" placeholder="价格">
            </div>
            <div class="form-group">
                <label for="duration-input">时长:</label>
                <input type="text" class="form-control" name="duration" id="duration-input">
            </div>
            <div class="form-group">
                <label>简介:</label>
                <script id="editor" type="text/plain"></script>
            </div>
            <div class="form-group">
                <button class="btn btn-primary pull-right" id="submit-btn">发布课程</button>
            </div>
        </div>
    </div>
</div>
</div>
{% endblock %}
# 这是课程相关的url映射
urlpatterns += [
    path('pub_course/',course_views.PubCourse.as_view(),name='pub_course')
]

function PubCourse() {

}

PubCourse.prototype.initUEditor = function () {
    window.ue = UE.getEditor("editor",{
        'serverUrl': '/ueditor/upload/'
    });
};

PubCourse.prototype.listenSubmitEvent = function () {
    var submitBtn = $("#submit-btn");
    submitBtn.click(function () {
        var title = $("#title-input").val();
        var category_id = $("#category-input").val();
        var teacher_id = $("#teacher-input").val();
        var video_url = $("#video-input").val();
        var cover_url = $("#cover-input").val();
        var price = $("#price-input").val();
        var duration = $("#duration-input").val();
        var profile = window.ue.getContent();

        xfzajax.post({
            'url': '/cms/pub_course/',
            'data': {
                'title': title,
                'video_url': video_url,
                'cover_url': cover_url,
                'price': price,
                'duration': duration,
                'profile': profile,
                'category_id': category_id,
                'teacher_id': teacher_id
            },
            'success': function (result) {
                if(result['code'] === 200){
                    window.location = window.location.href;
                }
            }
        });
    });
};

PubCourse.prototype.run = function () {
    this.initUEditor();
    this.listenSubmitEvent();
};


$(function () {
    var course = new PubCourse();
    course.run();
});
class CourseCategory(models.Model):
    name = models.CharField(max_length=100)

class Teacher(models.Model):
    username = models.CharField(max_length=100)
    avatar = models.URLField()
    jobtitle = models.CharField(max_length=100)
    profile = models.TextField()

class Course(models.Model):
    title = models.CharField(max_length=200)
    category = models.ForeignKey('CourseCategory',on_delete=models.DO_NOTHING)
    teacher = models.ForeignKey("Teacher",on_delete=models.DO_NOTHING)
    video_url = models.URLField()
    cover_url = models.URLField()
    price = models.FloatField()
    duration = models.IntegerField()
    profile = models.TextField()
    pub_time = models.DateTimeField(auto_now_add=True)

class CourseOrder(models.Model):
    uid = ShortUUIDField(primary_key=True)
    course = models.ForeignKey("Course",on_delete=models.DO_NOTHING)
    buyer = models.ForeignKey("xfzauth.User",on_delete=models.DO_NOTHING)
    amount = models.FloatField(default=0)
    pub_time = models.DateTimeField(auto_now_add=True)
    # 1:代表的是支付宝支付。2:代表的是微信支付
    istype = models.SmallIntegerField(default=0)
    # 1:代表的是未支付。2:代表的是支付成功
    status = models.SmallIntegerField(default=1)

课程管理-视频云存储讲解

https://cloud.baidu.com/

课程管理-发布课程功能完成

class PubCourseForm(forms.ModelForm,FormMixin):
    category_id = forms.IntegerField()
    teacher_id = forms.IntegerField()
    class Meta:
        model = Course
        exclude = ("category",'teacher')
@method_decorator(permission_required(perm="course.change_course",login_url='/'),name='dispatch')
class PubCourse(View):
    def get(self,request):
        context = {
            'categories': CourseCategory.objects.all(),
            'teachers': Teacher.objects.all()
        }
        return render(request,'cms/pub_course.html',context=context)

    def post(self,request):
        form = PubCourseForm(request.POST)
        if form.is_valid():
            title = form.cleaned_data.get('title')
            category_id = form.cleaned_data.get('category_id')
            video_url = form.cleaned_data.get('video_url')
            cover_url = form.cleaned_data.get("cover_url")
            price = form.cleaned_data.get('price')
            duration = form.cleaned_data.get('duration')
            profile = form.cleaned_data.get('profile')
            teacher_id = form.cleaned_data.get('teacher_id')

            category = CourseCategory.objects.get(pk=category_id)
            teacher = Teacher.objects.get(pk=teacher_id)

            Course.objects.create(title=title, video_url=video_url, cover_url=cover_url, price=price, duration=duration,
                                  profile=profile, category=category, teacher=teacher)
            return restful.ok()
        else:
            return restful.params_error(message=form.get_errors())
def course_index(request):
    context = {
        'courses': Course.objects.all()
    }
    return render(request,'course/course_index.html',context=context)


def course_detail(request,course_id):
    course = Course.objects.get(pk=course_id)
    buyed = CourseOrder.objects.filter(course=course,buyer=request.user,status=2).exists()
    context = {
        'course': course,
        'buyed': buyed
    }
    return render(request,'course/course_detail.html',context=context)

{% extends 'base/front_base.html' %}

{% block title %}
    课程列表页
{% endblock %}

{% block head %}
    <link rel="stylesheet" href="{% static 'css/course/course_index.min.css' %}">
{% endblock %}

{% block main %}
    <div class="main">
        <div class="course-nav">
            <div class="nav-container">
                <h3 class="title">在线课堂</h3>
                <ul class="nav-list">
                    <li class="active"><a href="#">最新课堂</a></li>
                    <li><a href="#">投资人说</a></li>
                    <li><a href="#">明星案例</a></li>
                    <li><a href="#">创业知识</a></li>
                </ul>
            </div>
        </div>
        <div class="wrapper">
            <ul class="course-list">
                {% for course in courses %}
                    <li>
                        <a href="{% url 'course:course_detail' course_id=course.pk %}">
                            <div class="thumbnail-group">
                                <img src="{{ course.cover_url }}" alt="" class="thumbnial">
                            </div>
                            <div class="course-info">
                                <p class="title">{{ course.title }}</p>
                                <p class="author">{{ course.teacher.username }}</p>
                                <p class="price-group">
                                    {% if course.price > 0 %}
                                        <span class="pay">{{ course.price }}</span>
                                    {% else %}
                                        <span class="free">免费</span>
                                    {% endif %}
                                </p>
                            </div>
                        </a>
                    </li>
                {% endfor %}

            </ul>
        </div>
    </div>
{% endblock %}
{% extends 'base/front_base.html' %}

{% block title %}
    课程列表页
{% endblock %}

{% block head %}
    <link rel="stylesheet" href="{% static 'css/course/course_detail.min.css' %}">
    <script src="{% static 'videojs/video.min.js' %}"></script>
<script src="{% static 'videojs/videojs-contrib-hls.min.js' %}"></script>
<script src="{% static 'videojs/videojs-contrib-quality-levels.min.js' %}"></script>
<script type="text/javascript" src="https://cdn.bdstatic.com/jwplayer/latest/cyberplayer.js"></script>
    <script src="{% static 'js/course_detail.min.js' %}"></script>
{% endblock %}

{% block main %}
    <div class="main">
        <div class="course-nav">
            <div class="nav-container">
                <h3 class="title">在线课堂</h3>
                <ul class="nav-list">
                    <li class="active"><a href="#">最新课堂</a></li>
                    <li><a href="#">投资人说</a></li>
                    <li><a href="#">明星案例</a></li>
                    <li><a href="#">创业知识</a></li>
                </ul>
            </div>
        </div>
        <div class="wrapper">
            <div class="course-wrapper">
                <div class="course-info">
                    <p class="course-title">{{ course.title }}</p>
                    <div class="price-group">
                        <div class="share-group">
                            <span class="title">分享至:</span>
                        </div>
                        <div class="buy-group">
                            <!-- <span class="price pay">¥49.0</span>
                            <a href="#" class="buy-btn">立即购买</a> -->
                            {% if course.price > 0 %}
                                {% if not buyed %}
                                    <span class="price pay">¥{{ course.price }}</span>
                                    <a href="{% url 'course:course_order' course_id=course.pk %}" class="buy-btn">立即购买</a>
                                {% endif %}
                            {% else %}
                                <span class="price free">免费</span>
                            {% endif %}
                        </div>
                    </div>
                </div>
                <div class="video-group">
                    <span id="video-info" hidden data-video-url="{{ course.video_url }}" data-cover-url="{{ course.cover_url }}" data-course-id="{{ course.pk }}"></span>
                    <div id="playercontainer"></div>
                </div>
            </div>
            <div class="bottom-wrapper">
                <div class="course-detail-wrapper">
                    <div class="item-group">
                        <p class="item-title">课程讲师</p>
                        <div class="teacher-group">
                            <div class="avatar-group">
                                <img src="{{ course.teacher.avatar }}" alt="" class="avatar">
                            </div>
                            <div class="teacher-info">
                                <p class="teacher-name">{{ course.teacher.username }}</p>
                                <p class="teacher-desc">{{ course.teacher.jobtitle }}</p>
                            </div>
                        </div>
                        <p class="item-content">{{ course.teacher.profile }}</p>
                    </div>
                    <div class="item-group">
                        <p class="item-title">课程简介</p>
                        <p class="item-content">{{ course.profile|safe }}</p>
                    </div>
                    <div class="item-group">
                        <p class="item-title">课程大纲</p>
                        <p class="item-content">小饭桌在线课堂是小饭桌旗下的线上视频课程产品,汇聚顶级创业大咖导师、行业资深专家,致力于用系统、垂直的知识体系让创业者认知升级、技能进阶。小饭桌在线课堂用知识陪伴创业者从平凡到卓越!
                        </p>
                    </div>
                    <div class="item-group">
                        <p class="item-title">适宜人群</p>
                        <p class="item-content">想学习如何做投资的!
                        </p>
                    </div>
                    <div class="item-group">
                        <p class="item-title">帮助中心</p>
                        <p class="item-content">
                             1. 购买后的课程在线可反复观看学习,视频有效期以具体课程信息为准。 <br>
                                    2. 课程暂不支持下载观看,均为在线观看视频。 <br>
                                    3. 课程一经购买,不可转让、不可退款;仅限购买账号观看。 <br>
                                    4. 如有问题请咨询客服饭桌君: 电话:18618172287   微信:fanzhuojun888 <br>
                        </p>
                    </div>
                    <div class="item-group">
                        <p class="item-title">关于小饭桌在线课堂</p>
                        <p class="item-content">
                            小饭桌在线课堂是小饭桌旗下的线上视频课程产品,汇聚顶级创业大咖导师、行业资深专家,致力于用系统、垂直的知识体系让创业者认知升级、技能进阶。小饭桌在线课堂用知识陪伴创业者从平凡到卓越!
                        </p>
                    </div>
                </div>
                <div class="recommand-wrapper">
                    <p class="recommand-title">推荐课程</p>
                    <ul class="course-list">
                        <li>
                            <a href="#">
                                <div class="course-info-group">
                                   <p class="course-title">教你制作抓住投资人眼球的商业计划书</p>
                                   <p class="teacher">知了课堂CEO</p>
                                </div>
                                <div class="thumbnail-group">
                                    <img src="https://static-image.xfz.cn/1526455098_289.png-course.list.small" alt="" class="thumbnail">
                                </div>
                            </a>
                        </li>
                        <li>
                            <a href="#">
                                <div class="course-info-group">
                                   <p class="course-title">教你制作抓住投资人眼球的商业计划书</p>
                                   <p class="teacher">知了课堂CEO</p>
                                </div>
                                <div class="thumbnail-group">
                                    <img src="https://static-image.xfz.cn/1526455098_289.png-course.list.small" alt="" class="thumbnail">
                                </div>
                            </a>
                        </li>
                    </ul>
                </div>
            </div>
        </div>
    </div>
{% endblock %}

课程管理-视频加密播放实现

def course_token(request):
    # video:是视频文件的完整链接
    file = request.GET.get('video')

    course_id = request.GET.get('course_id')
    if not CourseOrder.objects.filter(course_id=course_id,buyer=request.user,status=2).exists():
        return restful.params_error(message='请先购买课程!')

    expiration_time = int(time.time()) + 2 * 60 * 60

    USER_ID = settings.BAIDU_CLOUD_USER_ID
    USER_KEY = settings.BAIDU_CLOUD_USER_KEY

    # file=http://hemvpc6ui1kef2g0dd2.exp.bcevod.com/mda-igjsr8g7z7zqwnav/mda-igjsr8g7z7zqwnav.m3u8
    extension = os.path.splitext(file)[1]
    media_id = file.split('/')[-1].replace(extension, '')

    # unicode->bytes=unicode.encode('utf-8')bytes
    key = USER_KEY.encode('utf-8')
    message = '/{0}/{1}'.format(media_id, expiration_time).encode('utf-8')
    signature = hmac.new(key, message, digestmod=hashlib.sha256).hexdigest()
    token = '{0}_{1}_{2}'.format(signature, USER_ID, expiration_time)
    return restful.result(data={'token': token})
function CourseDetail() {
}

CourseDetail.prototype.initPlayer = function () {
    var videoInfoSpan = $("#video-info");
    var video_url = videoInfoSpan.attr("data-video-url");
    var cover_url = videoInfoSpan.attr("data-cover-url");
    var course_id = videoInfoSpan.attr('data-course-id');

    var player = cyberplayer("playercontainer").setup({
            width: '100%',
            height: '100%',
            file: video_url,
            image: cover_url,
            autostart: false,
            stretching: "uniform",
            repeat: false,
            volume: 100,
            controls: true,
            tokenEncrypt: true,
            // AccessKey
            ak: '42455a8c985649aeaa4ca86b50482d78'
        });

        player.on('beforePlay',function (e) {
            if(!/m3u8/.test(e.file)){
                return;
            }
            xfzajax.get({
                'url': '/course/course_token/',
                'data': {
                    'video': video_url,
                    'course_id': course_id
                },
                'success': function (result) {
                    if(result['code'] === 200){
                        var token = result['data']['token'];
                        player.setToken(e.file,token);
                    }else{
                        window.messageBox.showInfo(result['message']);
                        player.stop();
                    }
                },
                'fail': function (error) {
                    console.log(error);
                }
            });
        });
};

CourseDetail.prototype.run = function () {
    this.initPlayer();
};


$(function () {
    var courseDetail = new CourseDetail();
    courseDetail.run();
});

# 百度云的配置
# 控制台->用户中心->用户ID
BAIDU_CLOUD_USER_ID = '5b8849ddc6504318abcea39fe620948e'
# 点播VOD->全局设置->发布设置->安全设置->UserKey
BAIDU_CLOUD_USER_KEY = 'c228d166497b400d'

购买课程-课程订单页面完成

{% block head %}
    <link rel="stylesheet" href="{% static 'css/common/header.min.css' %}">
    <link rel="stylesheet" href="{% static 'css/common/footer.min.css' %}">
    <link rel="stylesheet" href="{% static 'css/common/body.min.css' %}">
    <style>
        .table{
            width: 100%;
            border-top: 1px solid #ccc;
            border-bottom: 1px solid #ccc;
            background: #eaeaea;
            text-align: center;
        }
        .table{
            border-spacing: 20px;
        }
        .table img{
            width: 120px;
            height: 68px;
            float: left;
        }
        .table .title{
            margin-left: 10px;
        }
        .pay-way label{
            float: right;
        }
        .pay-way span{
            border: 1px solid #ccc;
            position: relative;
            top: 20px;
        }
        .pay-way .zfb-btn{
            display: inline-block;
            width: 139px;
            height: 48px;
            cursor: pointer;
            background: url("http://study.163.com/res/images/pay/payList.png");
            background-position: -140px 0;
            background-size: 300% 200%;
            margin-right:20px;
        }
        .pay-way .wx-btn{
            display: inline-block;
            width: 139px;
            height: 48px;
            position: relative;
            cursor: pointer;
        }
        .pay-way .wx-btn img{
            top: 12px;
            left: 16px;
            position: absolute;
        }
        .submit-group{
            overflow: hidden;
            padding: 60px 0;
        }
        .submit-btn{
            display: block;
            text-align: center;
            width: 136px;
            height:49px;
            line-height: 49px;
            background: url("http://s.stu.126.net/res/images/pay/payBtns.png?c9b6b849b38cca45b160a96802575ac8") no-repeat 4449px 4449px;
            background-position: 0 -302px;
            border: none;
            cursor: pointer;
            color: #fff;
            font-size: 16px;
            float: right;
        }
        .submit-btn:hover{
            background-position: -139px -302px;
        }
    </style>
    <script>
        $(function () {
            var submitBtn = $("#submit-btn");
            submitBtn.click(function (event) {
                event.preventDefault();
                var goodsname = $("input[name='goodsname']").val();
                var istype = $("input[name='istype']:checked").val();
                var notify_url = $("input[name='notify_url']").val();
                var orderid = $("input[name='orderid']").val();
                var price = $("input[name='price']").val();
                var return_url = $("input[name='return_url']").val();
                xfzajax.post({
                    'url': '/course/course_order_key/',
                    'data': {
                        'goodsname': goodsname,
                        'istype': istype,
                        'notify_url': notify_url,
                        'orderid': orderid,
                        'price': price,
                        'return_url': return_url
                    },
                    'success': function (result) {
                        if(result['code'] === 200){
                            var key = result['data']['key'];
                            var keyInput = $("input[name='key']");
                            keyInput.val(key);
                            $("#pay-form").submit();
                        }
                    }
                });
            });
        });
    </script>
{% endblock %}

{% block main %}
    <div class="main">
        <div class="wrapper">
            <table class="table">
            <thead>
                <tr>
                    <th>商品名称</th>
                    <th>单价()</th>
                    <th>小计(元)</th>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <td align="left">
                        <a href="#">
                            <img class="thumbnail" src="{{ goods.thumbnail }}" alt="">
                            <span class="title">{{ goods.title }}</span>
                        </a>
                    </td>
                    <td>{{ goods.price }}</td>
                    <td>{{ goods.price }}</td>
                </tr>
            </tbody>
        </table>
            <form action="https://pay.bbbapi.com/" method="post" id="pay-form">
                <input type="hidden" name="uid" value="49dc532695baa99e16e01bc0">
                <input type="hidden" name="price" value="{{ goods.price }}">
                <input type="hidden" name="notify_url" value="{{ notify_url }}">
                <input type="hidden" name="return_url" value="{{ return_url }}">
                <input type="hidden" name="orderid" value="{{ order.pk }}">
                <input type="hidden" name="orderuid" value="{{ request.user.pk }}">
                <input type="hidden" name="goodsname" value="{{ goods.title }}">
                <input type="hidden" name="key" value="">
            <div class="pay-way">
                <label for="istype-wx">
                    <input id="istype-wx" type="radio" name="istype" value="2">
                    <span class="wx-btn">
                        <img src="http://nos.netease.com/test-edu-image/1BD9F69D6760CE1508D2269864AA54F8.png" alt="">
                    </span>
                </label>
                <label for="istype-zfb">
                    <input id="istype-zfb" type="radio" name="istype" value="1" checked>
                    <span class="zfb-btn"></span>
                </label>
                <div style="clear: both;"></div>
            </div>
            <div class="submit-group">
                <input type="submit" value="去支付" id="submit-btn" class="submit-btn">
            </div>
        </form>
        </div>
    </div>
{% endblock %}
@xfz_login_required
def course_order(request,course_id):
    course = Course.objects.get(pk=course_id)
    order = CourseOrder.objects.create(course=course,buyer=request.user,status=1,amount=course.price)
    context = {
        'goods': {
            'thumbnail': course.cover_url,
            'title': course.title,
            'price': course.price
        },
        'order': order,
        # /course/notify_url/
        'notify_url': request.build_absolute_uri(reverse('course:notify_view')),
        'return_url': request.build_absolute_uri(reverse('course:course_detail',kwargs={"course_id":course.pk}))
    }
    return render(request,'course/course_order.html',context=context)

购买课程-支付宝和微信支付功能准备工作

https://www.paysapi.com/
在这里插入图片描述

class CourseOrder(models.Model):
    uid = ShortUUIDField(primary_key=True)
    course = models.ForeignKey("Course",on_delete=models.DO_NOTHING)
    buyer = models.ForeignKey("xfzauth.User",on_delete=models.DO_NOTHING)
    amount = models.FloatField(default=0)
    pub_time = models.DateTimeField(auto_now_add=True)
    # 1:代表的是支付宝支付。2:代表的是微信支付
    istype = models.SmallIntegerField(default=0)
    # 1:代表的是未支付。2:代表的是支付成功
    status = models.SmallIntegerField(default=1)
@xfz_login_required
def course_order(request,course_id):
    course = Course.objects.get(pk=course_id)
    order = CourseOrder.objects.create(course=course,buyer=request.user,status=1,amount=course.price)
    context = {
        'goods': {
            'thumbnail': course.cover_url,
            'title': course.title,
            'price': course.price
        },
        'order': order,
        # /course/notify_url/
        'notify_url': request.build_absolute_uri(reverse('course:notify_view')),
        'return_url': request.build_absolute_uri(reverse('course:course_detail',kwargs={"course_id":course.pk}))
    }
    return render(request,'course/course_order.html',context=context)

购买课程-生成课程订单

购买课程-配置pycharm同步代码到服务器

购买课程-添加数据(选看)

购买课程-支付宝和微信支付功能完成

@xfz_login_required
def course_order_key(request):
    goodsname = request.POST.get("goodsname")
    istype = request.POST.get("istype")
    notify_url = request.POST.get("notify_url")
    orderid = request.POST.get("orderid")
    price = request.POST.get("price")
    return_url = request.POST.get("return_url")

    token = 'e6110f92abcb11040ba153967847b7a6'
    uid = '49dc532695baa99e16e01bc0'
    orderuid = str(request.user.pk)

    print('goodsname:',goodsname)
    print('istype:',istype)
    print('notify_url:',notify_url)
    print('orderid:',orderid)
    print('price:',price)
    print('return_url:',return_url)

    key = md5((goodsname + istype + notify_url + orderid + orderuid + price + return_url + token + uid).encode(
        "utf-8")).hexdigest()
    return restful.result(data={"key": key})


@csrf_exempt
def notify_view(request):
    orderid = request.POST.get('orderid')
    print('='*10)
    print(orderid)
    print('='*10)
    CourseOrder.objects.filter(pk=orderid).update(status=2)
    return restful.ok()
@xfz_login_required
def course_order(request,course_id):
    course = Course.objects.get(pk=course_id)
    order = CourseOrder.objects.create(course=course,buyer=request.user,status=1,amount=course.price)
    context = {
        'goods': {
            'thumbnail': course.cover_url,
            'title': course.title,
            'price': course.price
        },
        'order': order,
        # /course/notify_url/
        'notify_url': request.build_absolute_uri(reverse('course:notify_view')),
        'return_url': request.build_absolute_uri(reverse('course:course_detail',kwargs={"course_id":course.pk}))
    }
    return render(request,'course/course_order.html',context=context)
    <script>
        $(function () {
            var submitBtn = $("#submit-btn");
            submitBtn.click(function (event) {
                event.preventDefault();
                var goodsname = $("input[name='goodsname']").val();
                var istype = $("input[name='istype']:checked").val();
                var notify_url = $("input[name='notify_url']").val();
                var orderid = $("input[name='orderid']").val();
                var price = $("input[name='price']").val();
                var return_url = $("input[name='return_url']").val();
                xfzajax.post({
                    'url': '/course/course_order_key/',
                    'data': {
                        'goodsname': goodsname,
                        'istype': istype,
                        'notify_url': notify_url,
                        'orderid': orderid,
                        'price': price,
                        'return_url': return_url
                    },
                    'success': function (result) {
                        if(result['code'] === 200){
                            var key = result['data']['key'];
                            var keyInput = $("input[name='key']");
                            keyInput.val(key);
                            $("#pay-form").submit();
                        }
                    }
                });
            });
        });
    </script>
{% endblock %}

{% block main %}
    <div class="main">
        <div class="wrapper">
            <table class="table">
            <thead>
                <tr>
                    <th>商品名称</th>
                    <th>单价()</th>
                    <th>小计(元)</th>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <td align="left">
                        <a href="#">
                            <img class="thumbnail" src="{{ goods.thumbnail }}" alt="">
                            <span class="title">{{ goods.title }}</span>
                        </a>
                    </td>
                    <td>{{ goods.price }}</td>
                    <td>{{ goods.price }}</td>
                </tr>
            </tbody>
        </table>
            <form action="https://pay.bbbapi.com/" method="post" id="pay-form">
                <input type="hidden" name="uid" value="49dc532695baa99e16e01bc0">
                <input type="hidden" name="price" value="{{ goods.price }}">
                <input type="hidden" name="notify_url" value="{{ notify_url }}">
                <input type="hidden" name="return_url" value="{{ return_url }}">
                <input type="hidden" name="orderid" value="{{ order.pk }}">
                <input type="hidden" name="orderuid" value="{{ request.user.pk }}">
                <input type="hidden" name="goodsname" value="{{ goods.title }}">
                <input type="hidden" name="key" value="">
            <div class="pay-way">
                <label for="istype-wx">
                    <input id="istype-wx" type="radio" name="istype" value="2">
                    <span class="wx-btn">
                        <img src="http://nos.netease.com/test-edu-image/1BD9F69D6760CE1508D2269864AA54F8.png" alt="">
                    </span>
                </label>
                <label for="istype-zfb">
                    <input id="istype-zfb" type="radio" name="istype" value="1" checked>
                    <span class="zfb-btn"></span>
                </label>
                <div style="clear: both;"></div>
            </div>
            <div class="submit-group">
                <input type="submit" value="去支付" id="submit-btn" class="submit-btn">
            </div>
        </form>
        </div>
    </div>
{% endblock %}

购买课程-购买课程流程补充

def course_token(request):
    # video:是视频文件的完整链接
    file = request.GET.get('video')

    course_id = request.GET.get('course_id')
    if not CourseOrder.objects.filter(course_id=course_id,buyer=request.user,status=2).exists():
        return restful.params_error(message='请先购买课程!')

    expiration_time = int(time.time()) + 2 * 60 * 60

    USER_ID = settings.BAIDU_CLOUD_USER_ID
    USER_KEY = settings.BAIDU_CLOUD_USER_KEY

    # file=http://hemvpc6ui1kef2g0dd2.exp.bcevod.com/mda-igjsr8g7z7zqwnav/mda-igjsr8g7z7zqwnav.m3u8
    extension = os.path.splitext(file)[1]
    media_id = file.split('/')[-1].replace(extension, '')

    # unicode->bytes=unicode.encode('utf-8')bytes
    key = USER_KEY.encode('utf-8')
    message = '/{0}/{1}'.format(media_id, expiration_time).encode('utf-8')
    signature = hmac.new(key, message, digestmod=hashlib.sha256).hexdigest()
    token = '{0}_{1}_{2}'.format(signature, USER_ID, expiration_time)
    return restful.result(data={'token': token})
    var player = cyberplayer("playercontainer").setup({
            width: '100%',
            height: '100%',
            file: video_url,
            image: cover_url,
            autostart: false,
            stretching: "uniform",
            repeat: false,
            volume: 100,
            controls: true,
            tokenEncrypt: true,
            // AccessKey
            ak: '42455a8c985649aeaa4ca86b50482d78'
        });

        player.on('beforePlay',function (e) {
            if(!/m3u8/.test(e.file)){
                return;
            }
            xfzajax.get({
                'url': '/course/course_token/',
                'data': {
                    'video': video_url,
                    'course_id': course_id
                },
                'success': function (result) {
                    if(result['code'] === 200){
                        var token = result['data']['token'];
                        player.setToken(e.file,token);
                    }else{
                        window.messageBox.showInfo(result['message']);
                        player.stop();
                    }
                },
                'fail': function (error) {
                    console.log(error);
                }
            });
        });
};
def course_detail(request,course_id):
    course = Course.objects.get(pk=course_id)
    buyed = CourseOrder.objects.filter(course=course,buyer=request.user,status=2).exists()
    context = {
        'course': course,
        'buyed': buyed
    }
    return render(request,'course/course_detail.html',context=context)
发布了914 篇原创文章 · 获赞 17 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_41375318/article/details/104246803
今日推荐