K12(在线学习的平台)
项目:K12(在线学习的平台)
一、背景
目的是做一个在线的学习平台,提高学生的课程完成度
K12:大目标是要取代线下班
- - 录制专门的视频
- - 导师的监管:如果没有主动和那个学生聊天,就扣钱
- - 学生的激励:如果提前学完了,学习能力很强,可以免学费
二、系统架构
- - 主站
- - rest api
- - vue
- - 导师后台 (stark)
- - django
- - stark
- - 管理后台 (stark)
- - django
- - stark
三、人员和部门
- - 后端开发(5人)
- - 主站(3)
- - 导师后台(1)
- - 管理后台(1)
- - 前端开发(1)
- - UI (1)
- - 测试(1)
- - 运维(部署:上线)(1)
- - 运营(推广出去)(2)
- - 销售 (2)
- - 导师 (2)
- - 产品经理 (1)
- - 人事
- - 财务
四、需求分析
- 主站
- - 课程
- - 普通课程、学位课
- - 普通课程:比较小的课程
- - 学位课:从开始+项目+就业
- - 分配一对一的导师
- - 导师对你进行监管,督促你学习
- - 保就业
- - 如果你%50的时间学完了,退一般的学费,等。
- - 课程列表、课程详细
- - 课程周期的不同定价格
- - 个人的课程中心
- - 支付
- - 银联- 支付宝
- - 微信
- - 优惠券策略(满减(满多少减多少),立减,打折)
- - 贝里:可直接抵现金
- - 个人购物车
- - 深科技
- - 文章或者爬取的别人的文章(运营需要审核)
- 深刻有哪些功能?
- 点赞、评论、查看、收藏- - 登录 、注册
- 导师后台
- 管理后台
具体进一步谈业务需求
- a、课程:
- 业务相关:
- 1、学位课,如果你学的快;最多返指定金额的65%
- 2、作业做的好,会把额外的35%返给你
- 3、普通课程购买课程后,在我的订单中去评价
- 4、购物车的数据没有数据表。保存到redis里面去了
- 两大部分操作
- #redis操作
- 在课程详细页面,选择价格策略,点击加入购物车,吧视频和价格策略放到了redis中
- 在购物车页面,
- 可以对redis中保存的购买的视频数据和价格数据可以删除,修改,添加,查看(刷新)
- 选中,去结算中心
- #数据库操作
- #pip freeze > requirement.txt #生成文件
- #pip install -r requirement.txt #下载所有的版本
- 在结算页面:
- 优惠券
- - 选择单一的优惠券(通用、满减、折扣)
- - 课程优惠券:绑定课程的优惠券
- - 选择全站的优惠券(通用、满减、折扣)
- #单一的优惠券用完,再计算,看是否满足全站的通用卷
- - 选择贝里
- - 选择支付宝,点击立即支付
- - 在数据库中生成一个订单
- 这个订单如果用了优惠券,优惠券状态改为已使用
- 如果用了贝里,贝里的金额减少
- 如果取消订单,优惠券才不是使用状态
- 在支付页面,扫码状态为已支付
- 在我的订单中应该去数据库中读数据
- 在购物车或者结算中心的时候去redis里面读数据
- 课程列表和课程详细等等等
- 如果购买课程
- - 普通课程
- - 学位课程
- - 每个模块生成记录(人和课程模块的记录) - 买完之后自动生成
- - 开通模块(后台)
- - 导师跟进(导师)
- - 交作业(主站)
- b、深科技相关
- 来源
- 文章
- 收藏
- 通用评论表
- c、购买支付流程
- 课程id和价格策略id
- 传值的时候可以传两个值
- - 通过策略id找到买的那个课程
- - 通过课程id 获取所有的价格策略
- 处理请求
- 1、检测课程是否上线,下线
- 2、通过课程id 获取所有的价格策略,和传过来的进行对比
- 3、检测用户提交的价格策略是否在所有的价格策略中
- 4、将购物的视频添加到购物车(redis)
- - 同一个课程只能买一个,不允许一下加入两个
- 吧数据放到redis中,那么怎么存?
- 一个人就有一个购物车。可以通过用户id来存
- 所有的购物车= {
- 1:{
- 课程id1:{'prices':[],'price':9,'title':'python','img':'课程图片'},
- 课程id2:{'prices':[]}
- }
- }
- #如果看到课程已经在里面了,就不在里面添加了,这也就是用redis的原因
- class ShoppingCat(APIView):
- def post():
- #点击加入购物车保存数据到redis
- def get():
- #查看购物车列表
- def delete():
- #删除
- def patch():
- #局部更新
- pass
- 5、去结算(先简单的说一下)
- 买的所有的课程
- 课程1 价格策略
- 课程2 价格策略
- 课程3 价格策略
- 点击了去结算
- 优惠券
- 贝里
五、表结构
- 课程相关的13张表
课程大类表:e.g 前端,后端- 课程子类表:e.g python ,linux
- 普通课程表
- 学位课表
- ##学位课可以有如下好处
- 学位奖学金表
- ##当然学位课和普通课程共有的
- 价格策略表
- 优惠券表
- 课程详细表
- 课程章节表
- 课程目录表
- 课程问答表
- 课程评价(先不讨论)
课程大纲- ##
- 老师表
- contenttype
- contentType 可以一下关联两张表,django自己提供了,不用自己创建
- 深科技相关的4张表
文章来源
文章资讯
收藏(既能收藏课程,也能收藏文章,可以用contenttype)
评论(可以用contenttype的形式也可以用ForeignKey的形式)- 用户相关的两张表
用户信息表account
用户认证表userauthtoken
- 如果用户初次登录,给用户创建一个token,如果已经有token了,下次用户访问的时候直接带上token,如果没有token就说明没有登录,就没有访问其他页面的权限- 购买支付相关的7张表
已报名课程表EnrolledCourse(谁购买了那个课程)
学位课报名表
已报名的学位课程表EnrolledDegreeCourse
优惠券发放、消费记录
订单表
订单详情
贝里交易记录- 其他相关的6张表
课程评价
学位课程评价
学位课程的模块学习进度
为学生开通一个模块
学生作业记录及成绩
学员跟进记录
1、简单表结构设计分析:
需要知道的知识点:
现在学位课和普通课程都有自己的价格策略和优惠券,现在是学位课已经有了自己的价格策略,那么如果普通课程也要加价格策略,怎么弄呢?
一下有三种方法:
方法一:再单独创建一个表
方法二:不用单独创建一个表,可以多添加一个字段,其中的一个为NULL。相比方法一省了一张表
方法三:可以通过ContentType ,这个表里面存的是应用的名字以及表名。但是在我们makemigrations和migrate的时候django已经帮我们创建好了,如下图。就不用我们自己创建了
这样关联的好处:可以ForeignKey任何一张表。里面的xid是关联表的某一行数据,
这样关联以后,如果想在价格策略里面在添加一行数据,怎么添加呢?
有两种方式:
方式一:手动插入
- 自己手动查出content_type_id 和关联表里的某一行数据xid。查出来添加到价格策略表里面去
方式二:利用GenericForeignKey
- 可以通过导入 GenericForeignKey(GenericForeignKey有自动查找的功能,协助你快速做操作,没有也可以,自己手动查询)
- from django.contrib.contenttypes.fields import GenericForeignKey
使用:
- content_object = GenericForeignKey('content_type', 'object_id') #一下可以查到两个表的数据,自动插入到价格策略表里了,
优惠券表也是如此。只是为了查询方便
另外补充一个GenericRelation
- from django.contrib.contenttypes.fields import GenericRelation
GenericRelation:也是帮助做快速查询的,就像反向关联的releated_name=‘xx’。以后查找的时候通可以通过点字段名的方式去查找
- # 用于GenericForeignKey反向查询, 不会生成表字段,切勿删除
- coupon = GenericRelation("Coupon") #也是帮助做快速查询的,可以直接查出所有的学位课的价格策略等
2、具体表结构设计如下:
- 1 from django.db import models
- 2 from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation
- 3 #GenericForeignKey有自动查找的功能,协助你快速做操作,没有也可以,自己手动查询
- 4 #GenericRelation:也是帮助做快速查询的,可以直接查出所有的学位课的价格策略等
- 5
- 6 from django.contrib.contenttypes.models import ContentType
- 7 from django.db.models import Q
- 8 from django.utils.safestring import mark_safe
- 9 from django.db import models
- 10 import hashlib
- 11
- 12 class CourseCategory(models.Model):
- 13 """课程大类, e.g 前端 后端..."""
- 14 name = models.CharField(max_length=64, unique=True)
- 15
- 16 def __str__(self):
- 17 return "%s" % self.name
- 18
- 19 class Meta:
- 20 verbose_name = "课程大类" #单数
- 21 verbose_name_plural = "课程大类" #复数
- 22
- 23 class CourseSubCategory(models.Model):
- 24 """课程子类, e.g python linux """
- 25 category = models.ForeignKey("CourseCategory",verbose_name='所属类')
- 26 name = models.CharField(max_length=64, unique=True)
- 27
- 28 def __str__(self):
- 29 return "%s" % self.name
- 30
- 31 class Meta:
- 32 verbose_name = "课程子类"
- 33 verbose_name_plural = "课程子类"
- 34
- 35 class DegreeCourse(models.Model):
- 36 """学位课程"""
- 37 name = models.CharField(max_length=128, unique=True)
- 38 course_img = models.CharField(max_length=255, verbose_name="缩略图")
- 39 brief = models.TextField(verbose_name="学位课程简介", )
- 40 total_scholarship = models.PositiveIntegerField(verbose_name="总奖学金(贝里)", default=40000)
- 41 mentor_compensation_bonus = models.PositiveIntegerField(verbose_name="本课程的导师辅导费用(贝里)", default=15000)
- 42 # 用于GenericForeignKey反向查询, 不会生成表字段,切勿删除
- 43 coupon = GenericRelation("Coupon") #也是帮助做快速查询的,可以直接查出所有的学位课的价格策略等
- 44 # 为了计算学位奖学金
- 45 period = models.PositiveIntegerField(verbose_name="建议学习周期(days)", default=150)
- 46 prerequisite = models.TextField(verbose_name="课程先修要求", max_length=1024)
- 47 teachers = models.ManyToManyField("Teacher", verbose_name="课程讲师")
- 48 # 用于GenericForeignKey反向查询,不会生成表字段,切勿删除
- 49 degreecourse_price_policy = GenericRelation("PricePolicy")
- 50
- 51 def __str__(self):
- 52 return self.name
- 53
- 54 class Course(models.Model):
- 55 """课程"""
- 56 name = models.CharField(max_length=128, unique=True)
- 57 course_img = models.CharField(max_length=255)
- 58 sub_category = models.ForeignKey("CourseSubCategory")
- 59 course_type_choices = ((0, '付费'), (1, 'VIP专享'), (2, '学位课程'))
- 60 course_type = models.SmallIntegerField(choices=course_type_choices)
- 61 degree_course = models.ForeignKey("DegreeCourse", blank=True, null=True, help_text="若是学位课程,此处关联学位表")
- 62 brief = models.TextField(verbose_name="课程概述", max_length=2048)
- 63 level_choices = ((0, '初级'), (1, '中级'), (2, '高级'))
- 64 level = models.SmallIntegerField(choices=level_choices, default=1)
- 65 pub_date = models.DateField(verbose_name="发布日期", blank=True, null=True)
- 66 period = models.PositiveIntegerField(verbose_name="建议学习周期(days)", default=7)
- 67 order = models.IntegerField("课程顺序", help_text="从上一个课程数字往后排")
- 68 attachment_path = models.CharField(max_length=128, verbose_name="课件路径", blank=True, null=True)
- 69 status_choices = ((0, '上线'), (1, '下线'), (2, '预上线'))
- 70 status = models.SmallIntegerField(choices=status_choices, default=0)
- 71 template_id = models.SmallIntegerField("前端模板id", default=1)
- 72 coupon = GenericRelation("Coupon")
- 73 # 用于GenericForeignKey反向查询,不会生成表字段,切勿删除
- 74 price_policy = GenericRelation("PricePolicy")
- 75
- 76 def __str__(self):
- 77 return "%s(%s)" % (self.name, self.get_course_type_display())
- 78
- 79 def save(self, *args, **kwargs):
- 80 if self.course_type == 2:
- 81 if not self.degree_course:
- 82 raise ValueError("学位课程必须关联对应的学位表")
- 83 super(Course, self).save(*args, **kwargs)
- 84
- 85 class CourseDetail(models.Model):
- 86 """课程详情页内容"""
- 87 course = models.OneToOneField("Course")
- 88 hours = models.IntegerField("课时")
- 89 course_slogan = models.CharField(max_length=125, blank=True, null=True)
- 90 video_brief_link = models.CharField(verbose_name='课程介绍', max_length=255, blank=True, null=True)
- 91 why_study = models.TextField(verbose_name="为什么学习这门课程")
- 92 what_to_study_brief = models.TextField(verbose_name="我将学到哪些内容")
- 93 career_improvement = models.TextField(verbose_name="此项目如何有助于我的职业生涯")
- 94 prerequisite = models.TextField(verbose_name="课程先修要求", max_length=1024)
- 95 recommend_courses = models.ManyToManyField("Course", related_name="recommend_by", blank=True)
- 96 teachers = models.ManyToManyField("Teacher", verbose_name="课程讲师")
- 97
- 98 def __str__(self):
- 99 return "%s" % self.course
- 100
- 101 class OftenAskedQuestion(models.Model):
- 102 """常见问题"""
- 103 content_type = models.ForeignKey(ContentType,
- 104 limit_choices_to={'model__contains': 'course'}) # 关联course or degree_course
- 105 object_id = models.PositiveIntegerField()
- 106 content_object = GenericForeignKey('content_type', 'object_id')
- 107
- 108 question = models.CharField(max_length=255)
- 109 answer = models.TextField(max_length=1024)
- 110
- 111 def __str__(self):
- 112 return "%s-%s" % (self.content_object, self.question)
- 113
- 114 class Meta:
- 115 unique_together = ('content_type', 'object_id', 'question')
- 116
- 117 class CourseOutline(models.Model):
- 118 """课程大纲"""
- 119 course_detail = models.ForeignKey("CourseDetail")
- 120 title = models.CharField(max_length=128)
- 121 # 前端显示顺序
- 122 order = models.PositiveSmallIntegerField(default=1)
- 123
- 124 content = models.TextField("内容", max_length=2048)
- 125
- 126 def __str__(self):
- 127 return "%s" % self.title
- 128
- 129 class Meta:
- 130 unique_together = ('course_detail', 'title')
- 131
- 132 class CourseChapter(models.Model):
- 133 """课程章节"""
- 134 course = models.ForeignKey("Course", related_name='coursechapters')
- 135 chapter = models.SmallIntegerField(verbose_name="第几章", default=1)
- 136 name = models.CharField(max_length=128)
- 137 summary = models.TextField(verbose_name="章节介绍", blank=True, null=True)
- 138 pub_date = models.DateField(verbose_name="发布日期", auto_now_add=True)
- 139
- 140 class Meta:
- 141 unique_together = ("course", 'chapter')
- 142
- 143 def __str__(self):
- 144 return "%s:(第%s章)%s" % (self.course, self.chapter, self.name)
- 145
- 146 class Teacher(models.Model):
- 147 """讲师、导师表"""
- 148 name = models.CharField(max_length=32)
- 149 role_choices = ((0, '讲师'), (1, '导师'))
- 150 role = models.SmallIntegerField(choices=role_choices, default=0)
- 151 title = models.CharField(max_length=64, verbose_name="职位、职称")
- 152 signature = models.CharField(max_length=255, help_text="导师签名", blank=True, null=True)
- 153 image = models.CharField(max_length=128)
- 154 brief = models.TextField(max_length=1024)
- 155
- 156 def __str__(self):
- 157 return self.name
- 158
- 159 class PricePolicy(models.Model):
- 160 """价格与有课程效期表"""
- 161 content_type = models.ForeignKey(ContentType) # 关联course or degree_course
- 162 object_id = models.PositiveIntegerField()
- 163 content_object = GenericForeignKey('content_type', 'object_id')
- 164
- 165 # course = models.ForeignKey("Course")
- 166 valid_period_choices = ((1, '1天'), (3, '3天'),
- 167 (7, '1周'), (14, '2周'),
- 168 (30, '1个月'),
- 169 (60, '2个月'),
- 170 (90, '3个月'),
- 171 (180, '6个月'), (210, '12个月'),
- 172 (540, '18个月'), (720, '24个月'),
- 173 )
- 174 valid_period = models.SmallIntegerField(choices=valid_period_choices)
- 175 price = models.FloatField()
- 176
- 177 class Meta:
- 178 unique_together = ("content_type", 'object_id', "valid_period")
- 179
- 180 def __str__(self):
- 181 return "%s(%s)%s" % (self.content_object, self.get_valid_period_display(), self.price)
- 182
- 183 class CourseSection(models.Model):
- 184 """课时目录"""
- 185 chapter = models.ForeignKey("CourseChapter", related_name='coursesections')
- 186 name = models.CharField(max_length=128)
- 187 order = models.PositiveSmallIntegerField(verbose_name="课时排序", help_text="建议每个课时之间空1至2个值,以备后续插入课时")
- 188 section_type_choices = ((0, '文档'), (1, '练习'), (2, '视频'))
- 189 section_type = models.SmallIntegerField(default=2, choices=section_type_choices)
- 190
- 191
- 192 section_link = models.CharField(max_length=255, blank=True, null=True, help_text="若是video,填vid,若是文档,填link")
- 193 # vid:cc视频,唯一标识:sdfsgdfgdgfhgfh
- 194 video_time = models.CharField(verbose_name="视频时长", blank=True, null=True, max_length=32) # 仅在前端展示使用
- 195 pub_date = models.DateTimeField(verbose_name="发布时间", auto_now_add=True)
- 196 free_trail = models.BooleanField("是否可试看", default=False)
- 197
- 198
- 199 class Meta:
- 200 unique_together = ('chapter', 'section_link')
- 201
- 202
- 203 def __str__(self):
- 204 return "%s-%s" % (self.chapter, self.name)
- 205
- 206 class Coupon(models.Model):
- 207 """优惠券生成规则"""
- 208 name = models.CharField(max_length=64, verbose_name="活动名称")
- 209 brief = models.TextField(blank=True, null=True, verbose_name="优惠券介绍")
- 210 coupon_type_choices = ((0, '通用券'), (1, '满减券'), (2, '折扣券'))
- 211 coupon_type = models.SmallIntegerField(choices=coupon_type_choices, default=0, verbose_name="券类型")
- 212
- 213 money_equivalent_value = models.IntegerField(verbose_name="等值货币")
- 214 off_percent = models.PositiveSmallIntegerField("折扣百分比", help_text="只针对折扣券,例7.9折,写79", blank=True, null=True)
- 215 minimum_consume = models.PositiveIntegerField("最低消费", default=0, help_text="仅在满减券时填写此字段")
- 216
- 217 content_type = models.ForeignKey(ContentType, blank=True, null=True)
- 218 object_id = models.PositiveIntegerField("绑定课程", blank=True, null=True, help_text="可以把优惠券跟课程绑定")
- 219 content_object = GenericForeignKey('content_type', 'object_id')
- 220
- 221 quantity = models.PositiveIntegerField("数量(张)", default=1)
- 222 open_date = models.DateField("优惠券领取开始时间")
- 223 close_date = models.DateField("优惠券领取结束时间")
- 224 valid_begin_date = models.DateField(verbose_name="有效期开始时间", blank=True, null=True)
- 225 valid_end_date = models.DateField(verbose_name="有效结束时间", blank=True, null=True)
- 226 coupon_valid_days = models.PositiveIntegerField(verbose_name="优惠券有效期(天)", blank=True, null=True,
- 227 help_text="自券被领时开始算起")
- 228 date = models.DateTimeField(auto_now_add=True)
- 229
- 230 def __str__(self):
- 231 return "%s(%s)" % (self.get_coupon_type_display(), self.name)
- 232
- 233 def save(self, *args, **kwargs):
- 234 if not self.coupon_valid_days or (self.valid_begin_date and self.valid_end_date):
- 235 if self.valid_begin_date and self.valid_end_date:
- 236 if self.valid_end_date <= self.valid_begin_date:
- 237 raise ValueError("valid_end_date 有效期结束日期必须晚于 valid_begin_date ")
- 238 if self.coupon_valid_days == 0:
- 239 raise ValueError("coupon_valid_days 有效期不能为0")
- 240 if self.close_date < self.open_date:
- 241 raise ValueError("close_date 优惠券领取结束时间必须晚于 open_date优惠券领取开始时间 ")
- 242
- 243 super(Coupon, self).save(*args, **kwargs)
课程相关的13张表
- 1 # ######################## 深科技相关 ########################
- 2
- 3 class ArticleSource(models.Model):
- 4 """文章来源"""
- 5 name = models.CharField(max_length=64, unique=True)
- 6
- 7 def __str__(self):
- 8 return self.name
- 9
- 10
- 11 class Article(models.Model):
- 12 """文章资讯"""
- 13 title = models.CharField(max_length=255, unique=True, db_index=True, verbose_name="标题")
- 14 source = models.ForeignKey("ArticleSource", verbose_name="来源")
- 15 article_type_choices = ((0, '资讯'), (1, '视频'))
- 16 article_type = models.SmallIntegerField(choices=article_type_choices, default=0)
- 17 brief = models.TextField(max_length=512, verbose_name="摘要")
- 18 head_img = models.CharField(max_length=255)
- 19 content = models.TextField(verbose_name="文章正文")
- 20 pub_date = models.DateTimeField(verbose_name="上架日期")
- 21 offline_date = models.DateTimeField(verbose_name="下架日期")
- 22 status_choices = ((0, '在线'), (1, '下线'))
- 23 status = models.SmallIntegerField(choices=status_choices, default=0, verbose_name="状态")
- 24 order = models.SmallIntegerField(default=0, verbose_name="权重", help_text="文章想置顶,可以把数字调大,不要超过1000")
- 25 vid = models.CharField(max_length=128, verbose_name="视频VID", help_text="文章类型是视频, 则需要添加视频VID", blank=True, null=True)
- 26 comment_num = models.SmallIntegerField(default=0, verbose_name="评论数")
- 27 agree_num = models.SmallIntegerField(default=0, verbose_name="点赞数")
- 28 view_num = models.SmallIntegerField(default=0, verbose_name="观看数")
- 29 collect_num = models.SmallIntegerField(default=0, verbose_name="收藏数")
- 30
- 31 tags = models.ManyToManyField("Tags", blank=True, verbose_name="标签")
- 32 date = models.DateTimeField(auto_now_add=True, verbose_name="创建日期")
- 33
- 34 position_choices = ((0, '信息流'), (1, 'banner大图'), (2, 'banner小图'))
- 35 position = models.SmallIntegerField(choices=position_choices, default=0, verbose_name="位置")
- 36 comment = GenericRelation("Comment") # 用于GenericForeignKey反向查询, 不会生成表字段,切勿删除,如有疑问请联系老村长
- 37
- 38 def __str__(self):
- 39 return "%s-%s" % (self.source, self.title)
- 40
- 41
- 42 class Collection(models.Model):
- 43 """收藏"""
- 44 content_type = models.ForeignKey(ContentType)
- 45 object_id = models.PositiveIntegerField()
- 46 content_object = GenericForeignKey('content_type', 'object_id')
- 47
- 48 account = models.ForeignKey("Account")
- 49 date = models.DateTimeField(auto_now_add=True)
- 50
- 51 class Meta:
- 52 unique_together = ('content_type', 'object_id', 'account')
- 53
- 54
- 55 # 深科技评论和视频评论
- 56 class Comment(models.Model):
- 57 """通用的评论表: 课程评论 """
- 58 content_type = models.ForeignKey(ContentType, blank=True, null=True, verbose_name="类型")
- 59 object_id = models.PositiveIntegerField(blank=True, null=True)
- 60 content_object = GenericForeignKey('content_type', 'object_id')
- 61
- 62 p_node = models.ForeignKey("self", blank=True, null=True, verbose_name="父级评论")
- 63 content = models.TextField(max_length=1024)
- 64 account = models.ForeignKey("Account", verbose_name="会员名")
- 65 disagree_number = models.IntegerField(default=0, verbose_name="踩")
- 66 agree_number = models.IntegerField(default=0, verbose_name="赞同数")
- 67 date = models.DateTimeField(auto_now_add=True)
- 68
- 69 def __str__(self):
- 70 return self.content
深科技相关
- 1 # ######################## 购买课程相关 ########################
- 2
- 3 class EnrolledCourse(models.Model):
- 4 """已报名课程,不包括学位课程"""
- 5 account = models.ForeignKey("Account")
- 6 course = models.ForeignKey("Course", limit_choices_to=~Q(course_type=2))
- 7 enrolled_date = models.DateTimeField(auto_now_add=True)
- 8 valid_begin_date = models.DateField(verbose_name="有效期开始自")
- 9 valid_end_date = models.DateField(verbose_name="有效期结束至")
- 10 status_choices = ((0, '已开通'), (1, '已过期'))
- 11 status = models.SmallIntegerField(choices=status_choices, default=0)
- 12 order_detail = models.OneToOneField("OrderDetail") # 使订单购买后支持 课程评价
- 13
- 14 # order = models.ForeignKey("Order",blank=True,null=True)
- 15
- 16 def __str__(self):
- 17 return "%s:%s" % (self.account, self.course)
- 18
- 19
- 20 class DegreeRegistrationForm(models.Model):
- 21 """学位课程报名表"""
- 22 enrolled_degree = models.OneToOneField("EnrolledDegreeCourse")
- 23 current_company = models.CharField(max_length=64, )
- 24 current_position = models.CharField(max_length=64, )
- 25 current_salary = models.IntegerField()
- 26 work_experience_choices = (
- 27 (0, "应届生"),
- 28 (1, "1年"),
- 29 (2, "2年"),
- 30 (3, "3年"),
- 31 (4, "4年"),
- 32 (5, "5年"),
- 33 (6, "6年"),
- 34 (7, "7年"),
- 35 (8, "8年"),
- 36 (9, "9年"),
- 37 (10, "10年"),
- 38 (11, "超过10年"),
- 39 )
- 40 work_experience = models.IntegerField()
- 41 open_module = models.BooleanField("是否开通第1模块", default=True)
- 42 stu_specified_mentor = models.CharField("学员自行指定的导师名", max_length=32, blank=True, null=True)
- 43 study_plan_choices = ((0, "1-2小时/天"),
- 44 (1, "2-3小时/天"),
- 45 (2, "3-5小时/天"),
- 46 (3, "5小时+/天"),
- 47 )
- 48 study_plan = models.SmallIntegerField(choices=study_plan_choices, default=1)
- 49 why_take_this_course = models.TextField("报此课程原因", max_length=1024)
- 50 why_choose_us = models.TextField("为何选路飞", max_length=1024)
- 51 your_expectation = models.TextField("你的期待", max_length=1024)
- 52 memo = models.CharField(max_length=255, blank=True, null=True)
- 53
- 54 def __str__(self):
- 55 return "%s" % self.enrolled_degree
- 56
- 57
- 58 class EnrolledDegreeCourse(models.Model):
- 59 """已报名的学位课程"""
- 60 account = models.ForeignKey("Account")
- 61 degree_course = models.ForeignKey("DegreeCourse")
- 62 enrolled_date = models.DateTimeField(auto_now_add=True)
- 63 valid_begin_date = models.DateField(verbose_name="有效期开始自", blank=True, null=True) # 开通第一个模块时,再添加课程有效期,2年
- 64 valid_end_date = models.DateField(verbose_name="有效期结束至", blank=True, null=True)
- 65 status_choices = (
- 66 (0, '在学中'),
- 67 (1, '休学中'),
- 68 (2, '已毕业'),
- 69 (3, '超时结业'),
- 70 (4, '未开始'),
- 71 # (3, '其它'),
- 72 )
- 73 study_status = models.SmallIntegerField(choices=status_choices, default=0)
- 74 mentor = models.ForeignKey("Account", verbose_name="导师", related_name='my_students',
- 75 blank=True, null=True, limit_choices_to={'role': 1})
- 76 mentor_fee_balance = models.PositiveIntegerField("导师费用余额", help_text="这个学员的导师费用,每有惩罚,需在此字段同时扣除")
- 77 order_detail = models.OneToOneField("OrderDetail") # 使订单购买后支持填写报名表
- 78
- 79 def __str__(self):
- 80 return "%s:%s" % (self.account, self.degree_course)
- 81
- 82 class Meta:
- 83 unique_together = ('account', 'degree_course')
- 84
- 85
- 86 class Coupon(models.Model):
- 87 """优惠券生成规则"""
- 88 name = models.CharField(max_length=64, verbose_name="活动名称")
- 89 brief = models.TextField(blank=True, null=True, verbose_name="优惠券介绍")
- 90 coupon_type_choices = ((0, '通用券'), (1, '满减券'), (2, '折扣券'))
- 91 coupon_type = models.SmallIntegerField(choices=coupon_type_choices, default=0, verbose_name="券类型")
- 92
- 93 money_equivalent_value = models.IntegerField(verbose_name="等值货币")
- 94 off_percent = models.PositiveSmallIntegerField("折扣百分比", help_text="只针对折扣券,例7.9折,写79", blank=True, null=True)
- 95 minimum_consume = models.PositiveIntegerField("最低消费", default=0, help_text="仅在满减券时填写此字段")
- 96
- 97 content_type = models.ForeignKey(ContentType, blank=True, null=True)
- 98 object_id = models.PositiveIntegerField("绑定课程", blank=True, null=True, help_text="可以把优惠券跟课程绑定")
- 99 content_object = GenericForeignKey('content_type', 'object_id')
- 100
- 101 quantity = models.PositiveIntegerField("数量(张)", default=1)
- 102 open_date = models.DateField("优惠券领取开始时间")
- 103 close_date = models.DateField("优惠券领取结束时间")
- 104 valid_begin_date = models.DateField(verbose_name="有效期开始时间", blank=True, null=True)
- 105 valid_end_date = models.DateField(verbose_name="有效结束时间", blank=True, null=True)
- 106 coupon_valid_days = models.PositiveIntegerField(verbose_name="优惠券有效期(天)", blank=True, null=True,
- 107 help_text="自券被领时开始算起")
- 108 date = models.DateTimeField(auto_now_add=True)
- 109
- 110 def __str__(self):
- 111 return "%s(%s)" % (self.get_coupon_type_display(), self.name)
- 112
- 113 def save(self, *args, **kwargs):
- 114 if not self.coupon_valid_days or (self.valid_begin_date and self.valid_end_date):
- 115 if self.valid_begin_date and self.valid_end_date:
- 116 if self.valid_end_date <= self.valid_begin_date:
- 117 raise ValueError("valid_end_date 有效期结束日期必须晚于 valid_begin_date ")
- 118 if self.coupon_valid_days == 0:
- 119 raise ValueError("coupon_valid_days 有效期不能为0")
- 120 if self.close_date < self.open_date:
- 121 raise ValueError("close_date 优惠券领取结束时间必须晚于 open_date优惠券领取开始时间 ")
- 122
- 123 super(Coupon, self).save(*args, **kwargs)
- 124
- 125
- 126 class CouponRecord(models.Model):
- 127 """优惠券发放、消费纪录"""
- 128 coupon = models.ForeignKey("Coupon")
- 129 #number = models.CharField(max_length=64, unique=True)
- 130 account = models.ForeignKey("Account", verbose_name="拥有者")
- 131 status_choices = ((0, '未使用'), (1, '已使用'), (2, '已过期'),)
- 132 status = models.SmallIntegerField(choices=status_choices, default=0)
- 133 get_time = models.DateTimeField(verbose_name="领取时间", help_text="用户领取时间")
- 134 used_time = models.DateTimeField(blank=True, null=True, verbose_name="使用时间")
- 135 order = models.ForeignKey("Order", blank=True, null=True, verbose_name="关联订单") # 一个订单可以有多个优惠券
- 136
- 137
- 138 class Order(models.Model):
- 139 """订单"""
- 140 payment_type_choices = ((0, '微信'), (1, '支付宝'), (2, '优惠码'), (3, '贝里'))
- 141 payment_type = models.SmallIntegerField(choices=payment_type_choices)
- 142 payment_number = models.CharField(max_length=128, verbose_name="支付第3方订单号", null=True, blank=True)
- 143 order_number = models.CharField(max_length=128, verbose_name="订单号", unique=True) # 考虑到订单合并支付的问题
- 144 account = models.ForeignKey("Account")
- 145 actual_amount = models.FloatField(verbose_name="实付金额")
- 146
- 147 status_choices = ((0, '交易成功'), (1, '待支付'), (2, '退费申请中'), (3, '已退费'), (4, '主动取消'), (5, '超时取消'))
- 148 status = models.SmallIntegerField(choices=status_choices, verbose_name="状态")
- 149 date = models.DateTimeField(auto_now_add=True, verbose_name="订单生成时间")
- 150 pay_time = models.DateTimeField(blank=True, null=True, verbose_name="付款时间")
- 151 cancel_time = models.DateTimeField(blank=True, null=True, verbose_name="订单取消时间")
- 152
- 153 def __str__(self):
- 154 return "%s" % self.order_number
- 155
- 156
- 157 class OrderDetail(models.Model):
- 158 """订单详情"""
- 159 order = models.ForeignKey("Order")
- 160
- 161 content_type = models.ForeignKey(ContentType) # 可关联普通课程或学位
- 162 object_id = models.PositiveIntegerField()
- 163 content_object = GenericForeignKey('content_type', 'object_id')
- 164
- 165 original_price = models.FloatField("课程原价")
- 166 price = models.FloatField("折后价格")
- 167 content = models.CharField(max_length=255, blank=True, null=True) # ?
- 168 valid_period_display = models.CharField("有效期显示", max_length=32) # 在订单页显示
- 169 valid_period = models.PositiveIntegerField("有效期(days)") # 课程有效期
- 170 memo = models.CharField(max_length=255, blank=True, null=True)
- 171
- 172 # def __str__(self):
- 173 # return "%s - %s - %s" % (self.order, self.content_type, self.price)
- 174
- 175 class Meta:
- 176 # unique_together = ("order", 'course')
- 177 unique_together = ("order", 'content_type', 'object_id')
- 178
- 179
- 180 class TransactionRecord(models.Model):
- 181 """贝里交易纪录"""
- 182 account = models.ForeignKey("Account")
- 183 amount = models.IntegerField("金额")
- 184 balance = models.IntegerField("账户余额")
- 185 transaction_type_choices = ((0, '收入'), (1, '支出'), (2, '退款'), (3, "提现")) # 2 为了处理 订单过期未支付时,锁定期贝里的回退
- 186 transaction_type = models.SmallIntegerField(choices=transaction_type_choices)
- 187
- 188 content_type = models.ForeignKey(ContentType, blank=True, null=True)
- 189 object_id = models.PositiveIntegerField(blank=True, null=True, verbose_name="关联对象")
- 190 content_object = GenericForeignKey('content_type', 'object_id')
- 191
- 192 transaction_number = models.CharField(unique=True, verbose_name="流水号", max_length=128)
- 193 date = models.DateTimeField(auto_now_add=True)
- 194 memo = models.CharField(max_length=128, blank=True, null=True)
- 195
- 196 def __str__(self):
- 197 return "%s" % self.transaction_number
购买课程相关的8张表
- 1 class Homework(models.Model):
- 2 chapter = models.ForeignKey("CourseChapter")
- 3 title = models.CharField(max_length=128, verbose_name="作业题目")
- 4 order = models.PositiveSmallIntegerField("作业顺序", help_text="同一课程的每个作业之前的order值间隔1-2个数")
- 5 homework_type_choices = ((0, '作业'), (1, '模块通关考核'))
- 6 homework_type = models.SmallIntegerField(choices=homework_type_choices, default=0)
- 7 requirement = models.TextField(max_length=1024, verbose_name="作业需求")
- 8 threshold = models.TextField(max_length=1024, verbose_name="踩分点")
- 9 recommend_period = models.PositiveSmallIntegerField("推荐完成周期(天)", default=7)
- 10 scholarship_value = models.PositiveSmallIntegerField("为该作业分配的奖学金(贝里)")
- 11 note = models.TextField(blank=True, null=True)
- 12 enabled = models.BooleanField(default=True, help_text="本作业如果后期不需要了,不想让学员看到,可以设置为False")
- 13
- 14 class Meta:
- 15 unique_together = ("chapter", "title")
- 16
- 17 def __str__(self):
- 18 return "%s - %s" % (self.chapter, self.title)
- 19
- 20
- 21 class Teacher(models.Model):
- 22 """讲师、导师表"""
- 23 name = models.CharField(max_length=32)
- 24 role_choices = ((0, '讲师'), (1, '导师'))
- 25 role = models.SmallIntegerField(choices=role_choices, default=0)
- 26 title = models.CharField(max_length=64, verbose_name="职位、职称")
- 27 signature = models.CharField(max_length=255, help_text="导师签名", blank=True, null=True)
- 28 image = models.CharField(max_length=128)
- 29 brief = models.TextField(max_length=1024)
- 30
- 31 def __str__(self):
- 32 return self.name
- 33
- 34
- 35 # 普通课购买课程后,我的订单中去评价。
- 36 class CourseReview(models.Model):
- 37 """课程评价"""
- 38 enrolled_course = models.OneToOneField("EnrolledCourse")
- 39 about_teacher = models.FloatField(default=0, verbose_name="讲师讲解是否清晰")
- 40 about_video = models.FloatField(default=0, verbose_name="内容实用")
- 41 about_course = models.FloatField(default=0, verbose_name="课程内容通俗易懂")
- 42 review = models.TextField(max_length=1024, verbose_name="评价")
- 43 disagree_number = models.IntegerField(default=0, verbose_name="踩")
- 44 agree_number = models.IntegerField(default=0, verbose_name="赞同数")
- 45 tags = models.ManyToManyField("Tags", blank=True, verbose_name="标签")
- 46 date = models.DateTimeField(auto_now_add=True, verbose_name="评价日期")
- 47 is_recommend = models.BooleanField("热评推荐", default=False)
- 48 hide = models.BooleanField("不在前端页面显示此条评价", default=False)
- 49
- 50 def __str__(self):
- 51 return "%s-%s" % (self.enrolled_course.course, self.review)
- 52
- 53
- 54 # 学位课购买课程后,我的订单中去天报名表,然后就编程去学习(以后去评价)。
- 55 class DegreeCourseReview(models.Model):
- 56 """学位课程评价
- 57 为了以后可以定制单独的评价内容,所以不与普通课程的评价混在一起,单独建表
- 58 """
- 59 enrolled_course = models.ForeignKey("EnrolledDegreeCourse")
- 60 course = models.ForeignKey("Course", verbose_name="评价学位模块", blank=True, null=True,
- 61 help_text="不填写即代表评价整个学位课程", limit_choices_to={'course_type': 2})
- 62 about_teacher = models.FloatField(default=0, verbose_name="讲师讲解是否清晰")
- 63 about_video = models.FloatField(default=0, verbose_name="视频质量")
- 64 about_course = models.FloatField(default=0, verbose_name="课程")
- 65 review = models.TextField(max_length=1024, verbose_name="评价")
- 66 disagree_number = models.IntegerField(default=0, verbose_name="踩")
- 67 agree_number = models.IntegerField(default=0, verbose_name="赞同数")
- 68 tags = models.ManyToManyField("Tags", blank=True, verbose_name="标签")
- 69 date = models.DateTimeField(auto_now_add=True, verbose_name="评价日期")
- 70 is_recommend = models.BooleanField("热评推荐", default=False)
- 71 hide = models.BooleanField("不在前端页面显示此条评价", default=False)
- 72
- 73 def __str__(self):
- 74 return "%s-%s" % (self.enrolled_course, self.review)
- 75
- 76
- 77
- 78 # 购买学位课后,为每个学生每个模块会立刻生成一条学习纪录(未开通)
- 79 class StudyRecord(models.Model):
- 80 """学位课程的模块学习进度
- 81 报名学位课程后,每个模块会立刻生成一条学习纪录
- 82 """
- 83 enrolled_degree_course = models.ForeignKey("EnrolledDegreeCourse")
- 84 course_module = models.ForeignKey("Course", verbose_name="学位模块", limit_choices_to={'course_type': 2})
- 85 open_date = models.DateField(blank=True, null=True, verbose_name="开通日期")
- 86 end_date = models.DateField(blank=True, null=True, verbose_name="完成日期")
- 87 status_choices = ((2, '在学'), (1, '未开通'), (0, '已完成'))
- 88 status = models.SmallIntegerField(choices=status_choices, default=1)
- 89
- 90 class Meta:
- 91 unique_together = ('enrolled_degree_course', 'course_module')
- 92
- 93 def __str__(self):
- 94 return '%s-%s' % (self.enrolled_degree_course, self.course_module)
- 95
- 96 def save(self, *args, **kwargs):
- 97 if self.course_module.degree_course_id != self.enrolled_degree_course.degree_course_id:
- 98 raise ValueError("学员要开通的模块必须与其报名的学位课程一致!")
- 99
- 100 super(StudyRecord, self).save(*args, **kwargs)
- 101
- 102
- 103 # 为学生开通一个模块
- 104 class CourseSchedule(models.Model):
- 105 """课程进度计划表,针对学位课程,每开通一个模块,就为这个学员生成这个模块的推荐学习计划表,后面的奖惩均按此表进行"""
- 106 study_record = models.ForeignKey("StudyRecord")
- 107 homework = models.ForeignKey("Homework")
- 108 recommend_date = models.DateField("推荐交作业日期")
- 109
- 110 def __str__(self):
- 111 return "%s - %s - %s " % (self.study_record, self.homework, self.recommend_date)
- 112
- 113 class Meta:
- 114 unique_together = ('study_record', 'homework')
- 115
- 116
- 117 # 学生交作业
- 118 class HomeworkRecord(models.Model):
- 119 """学员作业记录及成绩"""
- 120 homework = models.ForeignKey("Homework")
- 121 student = models.ForeignKey("EnrolledDegreeCourse", verbose_name="学生")
- 122 score_choices = (
- 123 (100, 'A+'),
- 124 (90, 'A'),
- 125 (85, 'B+'),
- 126 (80, 'B'),
- 127 (70, 'B-'),
- 128 (60, 'C+'),
- 129 (50, 'C'),
- 130 (40, 'C-'),
- 131 (-1, 'D'),
- 132 (0, 'N/A'),
- 133 (-100, 'COPY'),
- 134 )
- 135 score = models.SmallIntegerField(verbose_name="分数", choices=score_choices, null=True, blank=True)
- 136 mentor = models.ForeignKey("Account", related_name="my_stu_homework_record", limit_choices_to={'role': 1},
- 137 verbose_name="导师")
- 138 mentor_comment = models.TextField(verbose_name="导师批注", blank=True, null=True) # 导师
- 139 status_choice = (
- 140 (0, '待批改'),
- 141 (1, '已通过'),
- 142 (2, '不合格'),
- 143 )
- 144 status = models.SmallIntegerField(verbose_name='作业状态', choices=status_choice, default=0)
- 145
- 146 submit_num = models.SmallIntegerField(verbose_name='提交次数', default=0)
- 147 correct_date = models.DateTimeField('备注日期', blank=True, null=True)
- 148 note = models.TextField(blank=True, null=True)
- 149 date = models.DateTimeField("作业提交日期", auto_now_add=True)
- 150
- 151 check_date = models.DateTimeField("批改日期", null=True, blank=True)
- 152
- 153 update_time = models.DateTimeField(auto_now=True, verbose_name="提交日期")
- 154
- 155 # homework_path = models.CharField(verbose_name='作业路径', max_length=256,blank=True,null=True) 作业路径可以动态拿到,没必要存
- 156
- 157 reward_choice = (
- 158 (0, '新提交'),
- 159 (1, '按时提交'),
- 160 (2, '未按时提交'),
- 161 (3, '成绩已奖励'),
- 162 (4, '成绩已处罚'),
- 163 (5, '未作按时检测'),
- 164 )
- 165 reward_status = models.SmallIntegerField(verbose_name='作业记录奖惩状态', default=0)
- 166
- 167 def __str__(self):
- 168 return "%s %s" % (self.homework, self.student)
- 169
- 170 class Meta:
- 171 unique_together = ("homework", "student")
- 172
- 173
- 174 # 导师跟进记录
- 175 class StuFollowUpRecord(models.Model):
- 176 """学员跟进记录"""
- 177 enrolled_degree_course = models.ForeignKey("EnrolledDegreeCourse", verbose_name="学生")
- 178 mentor = models.ForeignKey("Account", related_name='mentor', limit_choices_to={'role': 1}, verbose_name="导师")
- 179 followup_tool_choices = ((0, 'QQ'), (1, '微信'), (2, '电话'), (3, '系统通知'))
- 180 followup_tool = models.SmallIntegerField(choices=followup_tool_choices, default=1)
- 181 record = models.TextField(verbose_name="跟进记录")
- 182 attachment_path = models.CharField(max_length=128, blank=True, null=True, verbose_name="附件路径", help_text="跟进记录的截图等")
- 183 date = models.DateTimeField(auto_now_add=True)
- 184
- 185 def __str__(self):
- 186 return "%s --%s --%s" % (self.enrolled_degree_course, self.record, self.date)
学位课优惠相关的表
K12(在线学习的平台)的更多相关文章
- 一个很好的MySQL在线学习平台
一个很好的MySQL在线学习平台 https://www.techonthenet.com/sql/
- 机器人操作系统(ROS)在线实训平台学习实验指南
机器人操作系统(ROS)在线学习指南 在高校开设ROS相关课程已经积累了一年多的经验,由于自动化类专业在课程安排中不同于计算机相关专业,通常没有Linux相关的课程基础,直接上手ROS较为 ...
- 在线学习体验大PK 云智慧发布在线教育网站性能监测报告
互联网不但改变了我们的生活.娱乐和消费方式,也推动各行各业进行着快速变革,越来越多的职场人士必须通过不断的学习.充电才能跟上行业发展的步伐,获得职业的提升,而这也引发了国内教育市场的爆炸式发展.据统计 ...
- MCtalk对话学吧课堂:真正的K12在线教育才刚刚开始
课堂之外的在线教育已经被大部分家庭所熟知,既涌现出了VIPKID等行业独角兽,也有大量致力于科技改变教育的新兴机构获得了快速成长.成立于2014年的学吧课堂就是专注在K12在线教育领域的创新机构,他们 ...
- 从直播编程到直播教育:LiveEdu.tv开启多元化的在线学习直播时代
2015年9月,一个叫Livecoding.tv的网站在互联网上引起了编程界的注意.缘于Pingwest品玩的一位编辑在上网时无意中发现了这个网站,并写了一篇文章<一个比直播睡觉更奇怪的网站:直 ...
- HTML5初学者福利!11个在线学习网站推荐
HTML5初学者福利!11个在线学习网站推荐 HTML5的强大及流行趋势,让更多的人想要系统的对它进行学习.而大多数人获取HTML5知识的重要途径都是网络,不过面对五花八门的搜索结果,是不是觉得摸不着 ...
- 初学者福音——10个最佳APP开发入门在线学习网站
根据Payscale的调查显示,现在的APP开发人员的年薪达到:$66,851.这也是为什么那么多初学的开发都想跻身到APP开发这行业的主要原因之一.每当你打开App Store时候,看着琳琅满目的A ...
- 在线学习Java免费资源推荐
你想学习Java吗?来对地方了!这篇文章将会介绍很多高质量的免费资源,包括网页.论坛.电子书和速查表. Java是一种面向对象的编程语言,拥有独立.多线程.安全.动态和健壮的特点.归功于其多功能的特点 ...
- 微软大礼包 | 集合在线学习资源,助你秒变AI达人
编者按:人工智能的浪潮正如火如荼地袭来,未来人工智能将大有所为,人们的生活轨迹也正在技术不断向前推进的过程中逐渐改变.人工智能不是科研人员或开发人员的专属,微软希望能够将人工智能带给每个人,从开发者到 ...
随机推荐
- respond.js第六行 SCRIPT5: 拒绝访问。跨域问题
问题描述:respond.js第六行 SCRIPT5: 拒绝访问.昨天为学弟学妹讲bootstrap,说到对ie78的兼容问题,解决办法中有引入html5shiv.js和respond.js两个文件夹 ...
- LeetCode OJ :Remove Linked List Elements (移除链表元素)
Remove all elements from a linked list of integers that have value val. ExampleGiven: 1 --> 2 --& ...
- hp g6 2328tx 加装ssd 机械硬盘安装到光驱位置 问题小结
惠普 g6 笔记本从13年入手至今,三年有余,性能啥的开始跟不上了,所有入手了一块ssd,闪迪(sanDisk)加强版 240G的固态硬盘,准备升下级.狗东下午下单,第二天早上7点多到的,把老硬盘换下 ...
- react bootstrap-loader
1.install npm install bootstrap-loader jquery resolve-url-loader 2.webpack.config.js entry: ['bootst ...
- 2017.11.18 IAP下载(STM8,PIC,STM32)
客户要求用IAP下载,mark一下,客户还给了stm32的引导码.仅供参考. 1 PIC单片机的IAP 2 STm32 IAP https://www.cnblogs.com/WeyneChen/p ...
- DRF 权限的流程
DRF 权限的流程 django rest framework,入口是 dispatch,然后依次 --->>封装请求--->>处理版本--->>>认证--- ...
- canvas 创建渐变图形
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...
- windows获取屏幕显示比例 读取注册表法
static int GetDesktopScale() { ; HINSTANCE hUser32 = LoadLibrary(L"user32.dll"); if (hUser ...
- MpVue解析
前言 mpvue是一款使用Vue.js开发微信小程序的前端框架.使用此框架,开发者将得到完整的 Vue.js 开发体验,同时为H5和小程序提供了代码复用的能力.如果想将 H5 项目改造为小程序,或开发 ...
- nginx 转发 由于php语法错误 导致的 50x
server { listen 8008; root /root/php-test; index index.php index.html index.htm ...