前端页面

首先它是使用Django和Vue配合做的前后端分离的项目,我主要负责后端部分API接口,主要使用的是 rest_framework 框架实现的接口。 vue是一个构建数据驱动的 web 界面的渐进式框架。Vue.js 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。它不仅易于上手,还便于 与第三方库或既有项目整合。另一方面,当与单文件组件和 Vue 生态系统支持的库结合使用时,Vue 也完全能够为复杂的单页应用程序提供驱动。 主要功能和涉及到的知识点: 后端接口主要使用  rest_framework  框架实现,前端的页面实现的是但页面操作,使用的是 Vue 中 的路由 router 组件。 一、登录和注销(退出登录) 前端Vue,后端Django和 rest_framework 框架 1:用户输入用户名和密码。-------------------------------------------------------->v-model,双向绑定,一般用在 input 标签,格式:v-model="username";  2:点击登录触发事件------------------------------------------------------------->v-bind,绑定事件;     格式:v-bind:class="classed"        点击事件能简写成: @click="doLogin"                                                                                                                      注意: v-model其实是v-bind和v-on的语法糖 3:触发事件,执行函数,---------------------------------------------------------> methods:{dologin(){.....}}, 4:获取用户名密码等相关信息,向接口发送post请求,存在跨域,而且发送一次预检请求--->this.$axios.request(){....}  ;     注意:axios ,基于promise用于浏览器和node.js的http客户端;promise,异步执行,先统一执行AJAX逻辑,不关心如何处理结果,然后,根据结果 是成功还是失败,在将来的某个时候调用success函数或fail函数,这种对象在JavaScript中称为 promise ;node.js,是一个Javascript运行环境,Node.js 使用事件驱动, 非阻塞I/O 模型而得以轻量和高效,非常适合在分布式设备上运行数据密集型的实时应用。 由于ajax发送post请求时要发送一次预检,我们需要在我们写的中间件在settings.py中配置:      自己写的中间件:   class MiddlewareMixin(object):     def __init__(self, get_response=None):         self.get_response = get_response         super(MiddlewareMixin, self).__init__()
    def __call__(self, request):         response = None         if hasattr(self, 'process_request'):             response = self.process_request(request)         if not response:             response = self.get_response(request)         if hasattr(self, 'process_response'):             response = self.process_response(request, response)         return response
class CORSMiddleware(MiddlewareMixin):
    def process_response(self, request, response):         # 添加响应头
        # 允许你的域名来获取我的数据         response['Access-Control-Allow-Origin'] = "*"
        # 允许你携带Content-Type请求头         # response['Access-Control-Allow-Headers'] = "Content-Type"
        # 允许你发送DELETE,PUT         # response['Access-Control-Allow-Methods'] = "DELETE,PUT"
        if request.method == "OPTIONS":             response['Access-Control-Allow-Headers'] = "Content-Type"             response['Access-Control-Allow-Methods'] = "PUT,DELETE"
        return response 5:发送的数据内容和格式是: this.$axios.request({   url:'',   method:'POST',    data:{     user:this.username,                pwd:this.password,           },   headers:{     'Content-Type':'application/json',   }  }) 6:后端使用 Django 和 rest_framework 框架,在登陆视图中,视图类继承 APIView ,登陆验证时,里面写一个 post 方法,接受前端发来的数据,     user = request.data.get('user')     pwd = request.data.get('pwd')
7:然后进行数据校验,验证成功生成一个随机字符串,写入token表---------------->uid = str(uuid.uuid4())*后端*;使用 uuid 生成随机字符串 8:失败返回状态码,错误信息-----------------------------------------------------> ;在后端给前端返回数据时,使用 rest_framework 中的 Response (渲染器) 返回,数据格式是字典,可以自己定义一个response 数据类型,里面本来有一些常用的属性,比如 code,data,error 等,在定义一个方法,返回的 是一个字典,__dict__,使用@property 装饰器装饰,使用时很简单方便。 9: 成功返回token以及请求成功状态码,并将token等先关信息保存到cookie------------->import Vuex from 'vuex',全局变量,                                                                                                                                                                                                     ---->import Cookie from 'vue-cookies',cookie                                                                                                                                      ------------ > export default new Vuex.Store({  。。。  } })     定义存储 cookie 和 删除cookie的方法 10:主页面通过判断token,有token表示登录,显示用户名和注销按钮,反之显示注册和登录---><div v-if="this.$store.state.token">       还有一些其他页面也可以拿用户的token来进行判断用户是否登录来进行一些操作,比如有些页面是必须登陆成功后才能看到的,页面的有些板 块也是用户必须登陆成功后才能看到的 11:点击注销按钮,触发事件清空token等信息----------------------------------------->logout(){this.$store.commit('clearToken')},只是清空前端的 token信息,注 销后端不做处理 二、注册 和登录差不多,只是注册的时候多了一些字段,需要验证的步骤多了些,验证的逻辑有:同一账号不能重复注册,同一手机号不能重复注册,需要 提交两次密码,两次密码不一样的也不能注册成功。还有邮箱格式和手机号格式的验证(可以考虑正则),账号和密码的位数等等。 三、修改密码 1、发送邮件相关知识 import smtplib from email.mime.text import MIMEText  from email.header import Header  # SMTP是发送邮件的协议,Python内置对SMTP的支持,可以发送纯文本邮件、HTML邮件以及带附件的邮件。 # Python对SMTP支持有smtplib和email两个模块,email负责构造邮件,smtplib负责发送邮件。 定制好邮件头信息和邮件内容即可。 def mail_post():     sender = '18203692895@139.com'  # 发送者的邮箱地址     receiver = '2275715615@qq.com'  # 接受者的邮箱地址     smtpserver = 'smtp.139.com'   # 服务器地址     username = '18203692895'  # 发送者邮箱的账号     password = 'xxxx'  # 发送者邮箱的密码     subject = '密码找回验证邮箱'  # 邮件标题     msg = MIMEText('点击进入确认链接:<a href="....">。。。。</a>', 'html', 'utf-8')  # 邮件内容     msg['Subject'] = Header(subject, 'utf-8')  # 邮件信息     msg['From'] = sender     msg['To'] = receiver     smtp = smtplib.SMTP()     smtp.connect(smtpserver)   # 连接邮箱服务器     smtp.login(username, password)  # 邮箱登陆     smtp.sendmail(sender, receiver, msg.as_string())  # 邮件发送     smtp.quit()  # 服务器关闭 mail_post() 2、先填写账号和邮箱,发送邮箱确认连接,确认通过后,可以修改密码 修改密码和登录差不多,只是不同的字段而已。 四、认证 1、前端认证是使用后端发送的用户 token 进行认证的,主要使用的技术是  Vuex ,可以定义全局变量。有些页面是需要登陆成功后才能看到,就需 要在前端验证是否有用户的 token,这些页面比如:试听、购买课程视频等等。 2、后端的登录认证主要使用的是 rest_framework 中的认证组件来实现的,在那些需要登录认证的视图类中加上 认证组件的一个接口参数即可, authentication_classes = [YousiAuth, ] YousiAuth 是自己写的一个认证模块,这个是 rest_framework 中的认证组件提供的接口, from rest_framework.authentication import BaseAuthentication from rest_framework.exceptions import AuthenticationFailed from luffy_api.models import *
class LuffyAuth(BaseAuthentication):
    def authenticate(self, request):         token = request.query_params.get('token')         obj = UserToken.objects.filter(token=token).first()         if not obj:             raise AuthenticationFailed({'code': 1001, 'error': '认证失败'})         return (obj.user.user, obj) 源码流程: 先走dispatch方法 --- >   request = self.initialize_request(request, *args, **kwargs)   ---->   把接收到的原始信息进行封装, 将其放入restframework的Request 里 # 原来request对象,django.core.handlers.wsgi.WSGIRequest # 现在的request对象,rest_framework.request.Request 然后回到  dispatch 方法中 -----> 执行 self.initial(request, *args, **kwargs)  ------->           self.perform_authentication(request)             # 认证
                     self.check_permissions(request)                    # 权限  self.check_throttles(request)                         # 频率 --------->     def perform_authentication(self, request):         request.user 这里的user是Request对象里的user ------------>     def user(self):         if not hasattr(self, '_user'):             with wrap_attributeerrors():                 self._authenticate()         return self._user ----------->
   def _authenticate(self):         for authenticator in self.authenticators:             try:                 user_auth_tuple = authenticator.authenticate(self)             except exceptions.APIException:                 self._not_authenticated()                 raise             if user_auth_tuple is not None:                 self._authenticator = authenticator                 self.user, self.auth = user_auth_tuple                 return
        self._not_authenticated() 三种返回值:元组是验证通过,raise是验证失败,还有一种是None,匿名用户,没有验证 结束 权限和频率的类似 权限自定义的时候要有这个方法:has_permission 频率自定义的时候要有这个方法:allow_request 频率实现原理: 把用户名或者用户IP(ip = request.META.get('REMOTE_ADDR'))当作字典的键,用户登录时间点当作对应的值,这个值是一个列表,每次列 表新增元素时,先判断,把当前时间点和规定频率时间进行比较,再和列表中的时间进行比较,把不符合的数据删除,在计算列表的长度, 就能知道是否超频。 五、官网的  优思课程  页面:        课程分阶段,每个阶段还分不同的科目;         只有登陆的用户才能试听和购买课程;         每个课程有不同的售价,主要是为了提高学员的课程完成率,每个课程会有一个生命周期,只有在规定的生命周期内才能观看学习,过期后不能再 查看,不同生命周期的课程价格会有不同,具体看 优思 公司的人制定,购买后在发放课程视频上也有规定,规定不能一步到位,学习分阶段,会有阶段 考试,测试通过后才能进行下一阶段的学习。         奖励和惩罚机制:             对于学员来说,每次阶段测试都会有一定的奖励,只要达到一定的考试等级,就会有规定的奖励,奖励会以 虚拟币-- 金豆的形式发放,到毕业后 就能提现;学员没有惩罚扣钱操作,只会延期毕业,和请假操作,相应的课程生命周期也会随之调整;             对于导师来说,会有奖励和惩罚措施,每位导师再接到一位学员后,会有奖金提成,其中只有一小部分直接发到导师手里,大部分会以虚拟币的 形式存在导师的账号里,等到学员毕业后才能提现(具体比例优思公司的人决定),导师被投诉或者一些其他不合规措施都会有相应的扣钱措施,导师 被表扬或者学员成绩好都会再次发放奖金到其账户下。具体的一些规定是优思公司决定可以更改。 前端展示的页面是后端提供的,后端主要用到了 rest_framework 的序列化功能 serializers.ModelSerializer 可以序列化下面两种类型的数据,model 数据和 queryset 数据 queryset = Course.objects.all() ser = CourseSerializer(queryset, many=True) # queryset 数据
obj = CourseDetail.objects.filter(course_id=pk).first() ser = CourseDetailSerializer(obj, many=False) # model 数据
序列化时注意: 在取对多对和反查一对多时,要使用 提供的钩子进行方法重写
teachers = serializers.SerializerMethodField() # 钩子
def get_teachers(self, obj): # 方法重写 queryset = obj.teachers.all() return [{'id': row.id, 'name': row.name, 'title': row.title, 'role': row.get_role_display(), 'image': row.image, 'brief': row.brief} for row in queryset]
源码中 会有一个深copy ,构造成一个字典,字段名和字段对象
前端vue展示就不详细说明了
六、购物车部分 1)购物车购买数量有限制吗?    -- 有,防止有人恶意破坏,把大量商品加入购物车,不购买,占用redis的负担
2)购物车是否设置超时时间?    -- 可以设置,也可以不设置,其实只设置一下购物车购买数量即可。               (.conn.expire("shopping_car_1_1", 60*30)) 3)为什么把购物车信息放入redis? 1.购物车的操作只是个临时状态,不需要放入数据库; 2.需要频繁对购物车进行修改,放入redis的话操作速度快。 添加购物车操作:def  p ost (self, request, *args, **kwargs):
首先要先认证用户是否登录,只有登陆的用户才能把课程商品添加到购物车内; 前端只需要给后端发送年级 id 、课程 id 和价格策略的 id 即可 后端收到后需要在数据库里判断,看看数据库里是否有此年级,是否有此课程,是否有此课程的价格策略 校验通过后才能把数据取出来保存到redis中
购物车的数据存储结构: 在settings.py 中设置全局的购物车有关的redis 键 SHOPPING_CAR_KEY = "shopping_car_%s_%s_%s" # 用户id 和 年级 id 和课程 id 值是: shopping_car_dict = { 'title': course.name, 'course_img': course.course_img, 'price_policy': json.dumps(price_policy_dict), 'default_price': price_policy_id,

}

        更新购物车操作:def  patch(self, request, *args, **kwargs: 首先要先认证用户是否登录,只有登陆的用户才能把课程商品添加到购物车内; 前端只需要给后端发送年级 id 、课程 id 和价格策略的 id 即可 后端开始校验:首先校验此用户此 年级 id 、此课程 id 是否在 reids 的购物车数据中, 其次校验新的 价格策略 id 数据库里是否存在 校验通过后才能在 redis 中更新购物车信息
删除购物车信息操作:   def delete(self, request, *args, **kwargs):
首先要先认证用户是否登录,只有登陆的用户才能把课程商品添加到购物车内; 前端只需要给后端发送课程 id和年级 id  即可
后端开始校验:该年级的该课程是否在redis购物车内,校验通过后可以删除
展示购物车内容:    def get(self, request, *args, **kwargs):
注意:后端中获取当前登陆用户的信息:request.auth.user_id    在认证组件的源码里可以看到
七、结算中心 首先在settings.py中配置全局的常量: # redis中结算中心相关的和课程绑定的优惠券的key PAYMENT_KEY = "payment_%s_%s_%s"             # 用户id 和 年级 id 和课程 id
# redis中结算中心相关的通用无绑定课程优惠券的key PAYMENT_COUPON_KEY = "payment_coupon_%s"     # 用户id 

把购物车的数据添加到结算中心操作:def  post (self, request, *args, **kwargs): 首先要先认证用户是否登录,只有登陆的用户才能把课程商品添加到购物车内; 前端只需要给后端发送年级id和课程 id  即可
首先后端需要验证此年级的此课程在不在redis的购物车里,校验通过后可以取出局再次构造数据 数据结构: PAYMENT_KEY:{                     'title': self.conn.hget(course_ket, 'title').decode('utf-8'),                     'course_img': self.conn.hget(course_ket, 'course_img').decode('utf-8'),                     'valid_period_display': valid_period_display,                     'price': price,                     'price_id': default_price,                     'period': period,                     'coupon': {},           'default_coupon': 0, } PAYMENT_COUPON_KEY:{           'title': self.conn.hget(course_ket, 'title').decode('utf-8'),                     'course_img': self.conn.hget(course_ket, 'course_img').decode('utf-8'),                     'valid_period_display': valid_period_display,                     'price': price,                     'price_id': default_price,                     'period': period,                     'coupon': {},           'default_coupon': 0,

}
取出所有没有过期,符合该课程使用的优惠券,还有个人账户里的虚拟货币--金豆 优惠券分为,与课程相关的和全场通用的,分别有两种类型,满减券、打折券,优惠券  'coupon': {}根据不同的优惠券有不同的结构 结算计算时,一定先计算单个课程的,使用过优惠券相加后,再算总的,使用总的优惠券 还需要校验前端的总钱数和后端计算的是否一致 结算中心没有删除功能,查看功能就是取出数据即可,修改功能只限修改优惠券的相关信息
八、支付 使用支付宝支付 -:加密方式:rsa         -:公钥私钥:             商户私钥             支付宝公钥         - 支付成功后,断电宕机             成功:return HttpResponse('success')     1:第一步:------------------------------------------------>要注册企业账号或者个人支付宝账号,使用企业账号或者个人账号进行登录的开放平台。(正 式:营业执照)
    2:第二步:------------------------------------------------>首次进入系统界面有三个选项,用户可以根据个人自由选择第一项,第二项或者第三项的入住。
    3:第三步: ----------------------------------------------->进入沙箱环境。沙箱测试环境             商家信息:                     商家账号:refogp4784@sandbox.com                     商户:UID2088102175635525                     登录密码:111111                     账户余额:1000000.00充值                                  买家信息:                 买家账号:napkof3217@sandbox.com                 登录密码:111111                 支付密码:111111                 用户名称沙箱环境                 证件类型身份证(IDENTITY_CARD)                 证件号码:346845195607229016                 账户余额:109999.00充值                  4:第四步:------------------------------------------------>进入沙箱应用                  信息配置------------------------------------------->这里APPID和支付宝网关是自动生成的,记一下这"四个位置"一会儿在配置里面要用,                                                                 点击查看应用公钥,第一次进入是要自己填写的                 必看部分                     1:APPID:------------------------------------2016091400511568                     2:支付宝网关:-------------------------------https://openapi.alipaydev.com/gateway.do                     3:RSA2(SHA256)密钥(推荐):-------------------设置应用公钥                                      选看部分(部分接口使用,详见文档)                     应用名称沙箱测试应用                     应用图标                     4:商户:-------------------------------------UID2088102175635525                         应用网关:---------------------------------设置                         授权回调地址:-----------------------------设置                         RSA(SHA1)密钥:----------------------------设置应用公钥                         AES密钥:----------------------------------设置                                      下载钱包                     只支持安卓版-------------------------------https://sandbox.alipaydev.com/user/downloadApp.htm
                             b. 开发程序             SDK                 - 官方                 - github                     pay.py                     依赖:pip3 install pycryptodome                          公钥私钥:                 - 应用公钥                     - 支付宝公钥                 - 应用私钥             
    5:第五步:------------------------------------------------>下载RSA签名验签工具。         下载:------------------------------------------------->https://docs.open.alipay.com/291/106097
    6:第六步:------------------------------------------------>打开RSA签名验签工具.bat,根据需求生成不同的秘钥,同样给不同的配置写上编号。         (1):解压         (2):点击运行程序。         (3):选择PKCS1.(非java适用,如果是java用户选择PKCS8),2048         (4):生成秘钥             商户应用私钥:                 MIIEpQIBAAKCAQEA3xxPmZHq7m6sJp1WWMixPdeff2ktzAMBTXZ6h2XVZ953RGJJpBTo6uNbGbQAg45WczfyWEyu7rImUMgvsNdsCb6zBrL8ul                 Alsmt9YZBISm6awwl+Iez80J/RqrgfJnJ0CQgYwV6x9it72UozlUa6dJNEOvy5RFd39qsitr0Oj5xwmlchI3DvgRKMGBbIeHv7i8PA/stRodeP6GKe92hQYU                 ouxdRhfUCrOG40zOJZ1ufiMWtucAY8eXM4l5ZEmb7BJHaq1mSAGI3U75FypZzNxUDvjeRnNhORsHIRRBBgaWtPk1RkTT3zrBZkFzjB7P8rLvonyaE                 oIBAQClu9cZgf5dbdLtwFTDERowkTsHH2+Iq/bMvyUX7TqQtP4ty0Fe5LV8vrUOq9rx3sszPa0FkLkl0SqLOZnLqMq1lnZQlKcOGYDGhj+n6UB51I5b                 6bZGPUcaHoI05+hTLK/EahGiUAybJCQCA8xA2C8E9UwAbFejBtnu/hxdi7TFtD9T5lz2vbRyh+KNzXCvR9kSOBYyvyeLdhTibUq0U4ueNxAGwK9o                 ycMF+4s99PS6YVsmOxVoN7E5w717MDSmAzWWXtn7Rc3lkggL679ekVYuIytiNsjaXAtpUp6N5V4sNnhMQguShZlNE2r7reeAmWq2eGz19ZPH7hcJA                 oGBAPWhp9AVKxpkIVK1pkZVaSOdCFvPykGN7u4R2IeMkbPo4srJjpHaDb+1Wh21+r/kgT3GwgqHEZJ19dz+wJAzo4/S+Mw/QKL38UjakeadrRwO                 /Qe3e1uA3M8DBN4r1aXqFYWR5D3/XRgWgiZ2bYP1hQGzjRN7CU0a8RoNAoGBAOiHSkespyyOYxrGg9//f7x2N12rT0Swpjy9iUfTD/mAwbK4m+                 AJuqvYVmg773HBn+x0vCWdopfHGqdIVGwK0ziG3qPCcxMMmODgH2BOjBIXB5gwVDHDt1fENNsCIlp60t22yZggmozBsYXbZYL3kaG9XiPuEtCH                 t2hPBwCfZe8axRUgod07KECf7CEGH6+Iz+vaIHn3v4Tm9jrnQSCxL1OqfScTR71SRpT88bSBhguCFzcbSc3MINUOrWMQdUyATumtbpyX8/pTFQe/w                 NgyszcER6ph3RVKgB9HgJI48W0h8MtCGgZRextAoGBAIURz3d/HdiIz7xl+Ng6vl4bBQpM3DtCIJBII4UAC3dMsQzXSxk/DCUKgETX7PBDZwEXU                 vTvE5jB8tY1x7TksgrjX7l6Dw86E5qouM4tccItfjFQgN7wQRNIgGJpQb1yOqIdnnSI8E/bQ5eUmDoIRhSnzQqbDAoGAb/Rn6SxoQgBrkBebWlUZlkSP                 +93Wvo7MiOX2bBgKuZd/3MZHp3iTlwyoVkQwPQV9Wx2G8sKSJtkrYNvlCIWZCUwR5O6556IPH87u0W+vLMfCcNaYpugVXNnUqmmV0UEhxab             商户应用公钥:                 MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3xxPmZHq7m6sJp1WWMixPdeff2ktzAMBTXZ6h2XVZ953RGJJpBTo6uNbGbQAg45W                 ftR6RdvTCuGAlsmt9YZBISm6awwl+Iez80J/RqrgfJnJ0CQgYwV6x9it72UozlUa6dJNEOvy5RFd39qsitr0Oj5xwmlchI3DvgRKMGBbIeHv7i8PA/stRodeP                 fUCrOG40zOJZ1ufiMWtucAY8eXM4l5ZEmb7BJHaq1mSAGI3U75FypZzNxUDvjeRnNhORsHIRRBBgaWtPk1RkTT3zrBZkFzjB7P8rLvonyaE5wIDAQ          7:第七步:------------------------------------------------>回到支付宝沙箱配置的页面,点击查看应用公钥3,将商户应用公钥粘贴进去,会自动生成 4支 付宝公钥。          8: 第八步:------------------------------------------------>按照下面对应并下载沙箱支付宝APP测试版即可。          9:第九步:------------------------------------------------>进行相关代码开发以及商户信息配置等         开发程序                 - 官方:--------------------------------------->SDK,官方没有pythonde。                                  - github:------------------------------------->SDK,在gitup上找一个,pay.py                                  - 安装依赖:----------------------------------->pip3 install pycryptodome                                  - 请求流程:                         1:进入支付页面,获取支付金额,点击立即支付。                                                  2:获取相关信息,对购买的数据进行加密                                 appid=settings.APPID,------------------------------------APPID                                 app_notify_url=settings.NOTIFY_URL, ---------------------如果支付成功,支付宝会向这个地址发送POST请求(校验是否支付已经完 成)                                 return_url=settings.RETURN_URL, -------------------------如果支付成功,重定向回到你的网站的地址。                                 alipay_public_key_path=settings.PUB_KEY_PATH,------------支付宝公钥                                 app_private_key_path=settings.PRI_KEY_PATH,--------------应用私钥                                 debug=True, ---------------------------------------------默认False,                                                          3: 在数据库创建一条数据:状态(待支付)                                                  4:支付成功后,支付宝向该地址发送的POST请求(用于修改订单状态)                                               公钥私钥:                 - 应用公钥                     - 支付宝公钥                 - 应用私钥
    10:第十步:------------------------------------------------>根据系统提供的沙箱账号进行支付交易测试

九、微信推送消息 - 公众号 - 已认证公众号 - 服务号 - 已认证服务号 - 企业号 基于:微信认证服务号 主动推送微信消息。 前提:关注服务号
环境:沙箱环境 总结: 1. 注册账号 appID:wx89085e915d351cae appsecret:64f87abfc664f1d4f11d0ac98b24c42d 网页授权获取用户基本信息:47.98.134.86 或 域名 2. 关注公众号(已认证的服务号) 3. 生成二维码,用户扫描; 将用户信息发送给微信,微信再将数据发送给设置redirect_uri地址(md5值) 4. 回调地址:47.98.134.86/callback/ - 授权 - 用户md5 - 获取wx_id 在数据库中更新设置:wx_id 5. 发送消息(模板消息) - wx_id - access_token(2小时有效期)

posted @ 2018-08-29 10:51  aaronthon  阅读(472)  评论(0)    收藏  举报