Selaa lähdekoodia

Merge remote-tracking branch 'remotes/origin/dev' into Bin_Local_User

# Conflicts:
#	Ansjer/urls.py
tanghongbin 4 vuotta sitten
vanhempi
commit
4a0eec22f1

+ 1 - 0
.gitignore

@@ -11,6 +11,7 @@
 */__pycache__
 /Ansjer/test/__pycache__
 /Ansjer/test/__init__.py
+/static/log/error.log
 /sdk_install
 /DB/mydata4vipday2.ipdb
 /venv

+ 1 - 0
Ansjer/formal_settings.py

@@ -71,6 +71,7 @@ TEMPLATES = [
 
 WSGI_APPLICATION = 'Ansjer.formal_wsgi.application'
 
+
 # 服务器类型
 DATABASE_DATA = 'Ansjer81'
 SERVER_HOST = 'database-2.clraczw4p0yj.us-west-1.rds.amazonaws.com'

+ 46 - 0
Ansjer/formal_zositech_help_weekly_task.py

@@ -0,0 +1,46 @@
+import json
+
+import requests
+import time
+
+
+# url = 'http://test.dvema.com'
+# base_url = 'http://127.0.0.1:8000/'
+base_url = 'http://dvema.com/'
+username='13800138001'
+password='ansjer.x123789'
+login_url = base_url + 'account/login'
+
+data = {
+    'userName': username,
+    'userPwd': password
+}
+res = requests.post(url=login_url, data=data)
+res = res.json()
+
+if res['result_code'] == 0:
+    isbool = True
+    while isbool:
+        try:
+            statistics_url = base_url + 'faq/synZositechHelp'
+            zhcnDatares = requests.get(
+                url='https://mobileapphelp.zendesk.com/api/v2/help_center/articles/embeddable_search.json?locale=zh-cn&section=null&origin=web_widget', timeout=1).text
+
+            enusDatares = requests.get(
+                url='https://mobileapphelp.zendesk.com/api/v2/help_center/articles/embeddable_search.json?locale=en-us&section=null&origin=web_widget', timeout=1).text
+
+            data = {
+                'token': res['result']['access_token'],
+                'zhresults': zhcnDatares,
+                'enresults': enusDatares
+            }
+            isbool = False
+            res = requests.post(url=statistics_url, data=data)
+
+        except Exception as e:
+            isbool=True
+            time.sleep(3)
+
+
+
+

+ 4 - 4
Ansjer/local_settings.py

@@ -73,10 +73,10 @@ TEMPLATES = [
 WSGI_APPLICATION = 'Ansjer.local_wsgi.application'
 
 # 服务器类型
-DATABASE_DATA = 'AnsjerLocal'
-SERVER_HOST = '192.168.136.99'
-DATABASES_USER = 'ansjer'
-DATABASES_PASS = 'ansjer.x.x'
+DATABASE_DATA = 'ansjerlocal'
+SERVER_HOST = '127.0.0.1'
+DATABASES_USER = 'root'
+DATABASES_PASS = '123456'
 
 # DATABASE_DATA2 = 'asjl'
 # SERVER_HOST2 = '127.0.0.1'

+ 2 - 1
Ansjer/test_settings.py

@@ -72,6 +72,7 @@ TEMPLATES = [
 
 WSGI_APPLICATION = 'Ansjer.test_wsgi.application'
 
+
 # 服务器类型
 DATABASE_DATA = 'AnsjerTest'
 SERVER_HOST = 'database-2.clraczw4p0yj.us-west-1.rds.amazonaws.com'
@@ -107,7 +108,7 @@ DATABASES = {
 }
 DATABASE_ROUTERS = ['Ansjer.database_router.DatabaseAppsRouter']
 DATABASE_APPS_MAPPING = {
-    'db1': 'default',
+    'Model': 'default',
     'db2': 'mysql02',
 }
 

+ 2 - 2
Ansjer/test_zositech_help_weekly_task.py

@@ -5,8 +5,8 @@ import time
 
 
 # url = 'http://test.dvema.com'
-base_url = 'http://127.0.0.1:8000/'
-#base_url = 'http://test.dvema.com/'
+# base_url = 'http://127.0.0.1:8000/'
+base_url = 'http://test.dvema.com/'
 username='13800138001'
 password='ansjer999999'
 login_url = base_url + 'account/login'

+ 5 - 1
Ansjer/urls.py

@@ -10,9 +10,10 @@ from Controller import FeedBack, EquipmentOTA, EquipmentInfo, AdminManage, AppIn
     StsOssController, UIDPreview, OssCrd, SysMsg, UidUser, EquipmentManagerV2, EquipmentManagerV3, PushDeploy, \
     AppSetController, \
     ApplicationController, UserExController, CloudStorage, TestApi, UserBrandControllerV2, \
-    StatisticsController, Alexa, FAQController, AppLogController, EquipmentVersionLimit, VoicePromptController, \
+    StatisticsController, Alexa, FAQController, AppLogController, EquipmentVersionLimit, VoicePromptController, CDKController, \
     DeviceTypeController
 
+
 urlpatterns = [
     url(r'^testApi/(?P<operation>.*)$', TestApi.testView.as_view()),
 
@@ -250,6 +251,9 @@ urlpatterns = [
     # 设备类型
     url(r'^deviceType/(?P<operation>.*)$', DeviceTypeController.DeviceTypeView.as_view()),
 
+    # cdk(激活码)
+    url(r'^cdk/(?P<operation>.*)$', CDKController.CDKView.as_view()),
+
     # app 设备消息模板
     # 路由加参数参考
     # url(r'^(?P<path>.*)/(?P<UID>.*)/lls$', Test.Test.as_view(), name=u'gg'),

+ 8 - 2
Controller/AppLogController.py

@@ -71,9 +71,14 @@ class AppLogView(View):
         if uid is None or average_delay is None or status is None or filename is None:
             return response.json(444)
         else:
+            if len(uid) < 20:
+                return response.json(444, 'uid')
+
+            # ModelService.app_log_log(userID, uid)
             now_time = int(time.time())
+            uid = uid.strip()
             data = {
-                'uid': uid,
+                'uid': uid[0:20],
                 'average_delay': average_delay,
                 'status': status,
                 'filename': filename,
@@ -105,7 +110,8 @@ class AppLogView(View):
                 if al_qs.exists():
                     count = al_qs.count()
                     start = (page - 1) * line
-                    al_qs = al_qs[start: (start + line)].values('id', 'user__username', 'user_id', 'uid', 'average_delay', 'status', 'filename', 'add_time')
+                    al_qs = al_qs[start: (start + line)].values('id', 'user__username', 'user_id', 'uid',
+                                                                'average_delay', 'status', 'filename', 'add_time')
 
                     res = []
                     auth = oss2.Auth(OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET)

+ 242 - 0
Controller/CDKController.py

@@ -0,0 +1,242 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+"""
+@Copyright (C) ansjer cop Video Technology Co.,Ltd.All rights reserved.
+@AUTHOR: ASJRD018
+@NAME: AnsjerFormal
+@software: PyCharm
+@DATE: 2018/12/5 9:30
+@Version: python3.6
+@MODIFY DECORD:ansjer dev
+@file: cloudstorage.py
+@Contact: chanjunkai@163.com
+"""
+import json
+import time
+import urllib
+import uuid
+import hashlib
+
+import boto3
+import oss2
+import paypalrestsdk
+import threading
+from aliyunsdkcore import client
+from aliyunsdksts.request.v20150401 import AssumeRoleRequest
+from boto3.session import Session
+from django.http import JsonResponse, HttpResponseRedirect, HttpResponse
+from django.views.generic.base import View
+
+from Ansjer.config import OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET, OSS_ROLE_ARN, SERVER_DOMAIN, PAYPAL_CRD, \
+    SERVER_DOMAIN_SSL
+from Model.models import Device_Info, Order_Model, Store_Meal, VodHlsModel, OssCrdModel, UID_Bucket, StsCrdModel, \
+    ExperienceContextModel, CDKcontextModel
+from Object.AliPayObject import AliPayObject
+from Object.ResponseObject import ResponseObject
+from Object.TokenObject import TokenObject
+from Object.UidTokenObject import UidTokenObject
+from Service.CommonService import CommonService
+from Object.m3u8generate import PlaylistGenerator
+from Object.WechatPayObject import WechatPayObject
+from django.db.models import Q
+from django.http import StreamingHttpResponse
+
+SERVER_DOMAIN = 'http://test.dvema.com/'
+
+
+# 设备信息添加
+class CDKView(View):
+
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        return self.validation(request.GET, request, operation)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        return self.validation(request.POST, request, operation)
+
+    def validation(self, request_dict, request, operation):
+        response = ResponseObject()
+
+        if operation is None:
+            return response.json(444, 'error path')
+        else:
+            token = request_dict.get('token', None)
+            # 设备主键uid
+            tko = TokenObject(token)
+            response.lang = tko.lang
+            if tko.code != 0:
+                return response.json(tko.code)
+            userID = tko.userID
+            if operation == 'createCDK':
+                return self.createCDK(request_dict, response)
+            elif operation == 'deleteCDK':
+                return self.deleteCDK(request_dict, response)
+            elif operation == 'queryCDK':
+                return self.queryCDK(request_dict, response)
+            elif operation == 'saveOrEditCDKform':
+                return self.saveOrEditCDKform(request_dict, response)
+            elif operation == 'saveOrEditCDK':
+                return self.saveOrEditCDK(request_dict, response)
+            elif operation == 'downloadCDK':
+                return self.downloadCDK(response)
+
+    def createCDK(self, request_dict, response):
+        cdk_num = request_dict.get("cdknum", None)
+        rank = request_dict.get('rank', None)
+        order = request_dict.get('order', None)
+        cdk_list = []
+        for i in range(int(cdk_num)):
+            nowTime = int(time.time())
+            cdk = hashlib.md5((str(uuid.uuid1()) + str(nowTime)).encode('utf-8')).hexdigest()
+            cdk_model = CDKcontextModel(
+                cdk=cdk,
+                create_time=nowTime,
+                valid_time=0,
+                is_activate=0,
+                rank_id=rank,
+                order=order,
+            )
+            cdk_list.append(cdk_model)
+        try:
+            CDKcontextModel.objects.bulk_create(cdk_list)
+        except Exception as e:
+            print(repr(e))
+            return response.json(404, repr(e))
+        else:
+            return response.json(0)
+
+    def queryCDK(self, request_dict, response):
+        page = int(request_dict.get('page', None))
+        line = int(request_dict.get('line', None))
+        # channel = request_dict.get('channel', None)
+        cdk = request_dict.get('cdk', None)
+        order = request_dict.get('order', None)
+        is_activate = request_dict.get('is_activate', None)
+
+        searchVal = ''
+        if cdk:
+            searchVal = cdk.strip()
+        elif order:
+            searchVal = order.strip()
+        elif is_activate:
+            searchVal = is_activate.strip()
+
+        if page and line:
+            cdk_qs = CDKcontextModel.objects.filter().all()  # values('cdk','create_time','valid_time','is_activate','rank__id','order__id')
+            if searchVal:
+                if cdk:
+                    cdk_qs = cdk_qs.filter(cdk__contains=searchVal)
+                elif order:
+                    cdk_qs = cdk_qs.filter(order=searchVal)
+                elif is_activate:
+                    cdk_qs = cdk_qs.filter(is_activate=searchVal)
+            cdk_qs = cdk_qs.values('id', 'cdk', 'create_time', 'valid_time', 'is_activate', 'rank__id', 'rank__title', 'order',
+                                   'create_time')
+            cdk_qs = cdk_qs.order_by('-create_time')  # 根据CDK创建时间降序排序
+            count = cdk_qs.count()
+            cdk_qs = cdk_qs[(page - 1) * line:page * line]
+
+            # cdk_dict = {}
+            # for cdk in cdk_qs:
+            #     cdk_dict[cdk['id']] = {'id': cdk['id'], 'cdk': cdk['cdk'], 'create_time': cdk['create_time'],
+            #                            'valid_time': cdk['valid_time'], 'is_activate': cdk['is_activate'],
+            #                            'rank': cdk['rank__id'], 'order': cdk['order']}
+
+            res = {
+                'datas': list(cdk_qs),
+                'count': count
+            }
+            return response.json(0, res)
+        else:
+            return response.json(444, 'page,line')
+
+    def deleteCDK(self, request_dict, response):
+        cdk_id = request_dict.get("id", None)
+        try:
+            CDKcontextModel.objects.get(cdk=cdk_id).delete()
+        except Exception as e:
+            return response.json(500, repr(e))
+        else:
+            page = int(request_dict.get('page', None))
+            line = int(request_dict.get('line', None))
+            # channel = request_dict.get('channel', None)
+            cdk = request_dict.get('cdk', None)
+            order = request_dict.get('order', None)
+            is_activate = request_dict.get('is_activate', None)
+
+            searchVal = ''
+            if cdk:
+                searchVal = cdk.strip()
+            elif order:
+                searchVal = order.strip()
+            elif is_activate:
+                searchVal = is_activate.strip()
+
+            if page and line:
+                cdk_qs = CDKcontextModel.objects.filter().all()  # values('cdk','create_time','valid_time','is_activate','rank__id','order__id')
+                if searchVal:
+                    if cdk:
+                        cdk_qs = cdk_qs.filter(cdk__contains=searchVal)
+                    elif order:
+                        cdk_qs = cdk_qs.filter(order=searchVal)
+                    elif is_activate:
+                        cdk_qs = cdk_qs.filter(is_activate=searchVal)
+                cdk_qs = cdk_qs.values('id', 'cdk', 'create_time', 'valid_time', 'is_activate', 'rank__id',
+                                       'rank__title', 'order',
+                                       'create_time')
+                cdk_qs = cdk_qs.order_by('-create_time')  # 根据CDK创建时间降序排序
+                count = cdk_qs.count()
+                cdk_qs = cdk_qs[(page - 1) * line:page * line]
+                res = {
+                    'datas': list(cdk_qs),
+                    'count': count
+                }
+                return response.json(0, res)
+
+
+
+    def saveOrEditCDK(self, request_dict, response):
+        cdk_id = request_dict.get("id", None)
+        cdk = request_dict.get('cdk', None)
+        valid_time = request_dict.get('valid_time', None)
+        is_activate = request_dict.get('is_activate', None)
+        rank = request_dict.get('rank', None)
+
+        try:
+            if cdk_id:
+                if cdk or valid_time or is_activate or rank:
+                    update_dict = {}
+                    if cdk:
+                        update_dict['cdk'] = cdk
+                    if valid_time:
+                        update_dict['valid_time'] = valid_time
+                    if is_activate:
+                        update_dict['is_activate'] = is_activate
+                    if rank:
+                        update_dict['rank'] = rank
+                    CDKcontextModel.objects.filter(id=cdk_id).update(**update_dict)
+        except Exception as e:
+            return response.json(500, repr(e))
+        else:
+            return response.json(0)
+
+    def downloadCDK(self, response):
+        content = ''
+        cdk_inactivate_qs = CDKcontextModel.objects.filter(is_activate=0).values('cdk')
+        content += '激活码\n'
+        for cdk_inactivate in cdk_inactivate_qs:
+            content += cdk_inactivate['cdk'] + '\n'
+        print(content)
+
+        response = StreamingHttpResponse(content)
+        response['Content-Type'] = 'application/octet-stream'
+        response['Content-Disposition'] = 'attachment;filename="CDK.txt"'
+        return response
+
+
+
+
+

+ 313 - 63
Controller/CloudStorage.py

@@ -18,6 +18,7 @@ import urllib
 import boto3
 import oss2
 import paypalrestsdk
+import threading
 from aliyunsdkcore import client
 from aliyunsdksts.request.v20150401 import AssumeRoleRequest
 from boto3.session import Session
@@ -26,13 +27,16 @@ from django.views.generic.base import View
 
 from Ansjer.config import OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET, OSS_ROLE_ARN, SERVER_DOMAIN, PAYPAL_CRD, \
     SERVER_DOMAIN_SSL
-from Model.models import Device_Info, Order_Model, Store_Meal, VodHlsModel, OssCrdModel, UID_Bucket, StsCrdModel
+from Model.models import Device_Info, Order_Model, Store_Meal, VodHlsModel, OssCrdModel, UID_Bucket, StsCrdModel, \
+    ExperienceContextModel, Pay_Type, CDKcontextModel
 from Object.AliPayObject import AliPayObject
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
 from Object.UidTokenObject import UidTokenObject
 from Service.CommonService import CommonService
 from Object.m3u8generate import PlaylistGenerator
+from Object.WechatPayObject import WechatPayObject
+from django.db.models import Q
 
 SERVER_DOMAIN = 'http://test.dvema.com/'
 
@@ -75,6 +79,8 @@ class CloudStorageView(View):
             return self.do_pay_by_paypal_callback(request_dict, response)
         elif operation == 'doalicallback':
             return self.do_pay_by_ali_callback(request)
+        elif operation == 'dowechatnotify':
+            return self.do_pay_by_wechat_callback(request_dict,response)
         elif operation == 'getsignsts':
             ip = CommonService.get_ip_address(request)
             return self.do_get_sign_sts(request_dict, ip, response)
@@ -103,6 +109,10 @@ class CloudStorageView(View):
                 return self.do_commodity_list(request_dict, userID, response)
             elif operation == 'queryorder':
                 return self.do_query_order(request_dict, userID, response)
+            elif operation == 'experienceorder':
+                return self.do_experience_order(request_dict, userID, response)
+            elif operation == 'experiencereset':
+                return self.do_experience_reset(request_dict, userID, response)
             else:
                 return response.json(414)
 
@@ -169,15 +179,26 @@ class CloudStorageView(View):
 
     def do_commodity_list(self, request_dict, userID, response):
         mold = request_dict.get('mold', None)
+        uid = request_dict.get('uid', None)
         qs = Store_Meal.objects
+        eq = ExperienceContextModel.objects.filter(uid=uid,experience_type=0).values('id')
+        # userqs = Device_User.objects.filter(userID=userID).values('is_experience')
+
         if mold:
             qs = qs.filter(bucket__mold=mold)
         else:
             qs = qs.all()
+
+        if eq:
+            qs=qs.filter(~Q(pay_type='10'))
+        else:
+            qs = qs.filter(pay_type='10')
+
         qs = qs.values("id", "title", "content", "price",
                        "day", "currency", "bucket__storeDay",
-                       "bucket__bucket", "bucket__area", "type",
-                       "commodity_code", "commodity_type")
+                       "bucket__bucket", "bucket__area",
+                      "commodity_code", "commodity_type")
+
         if qs.exists():
             ql = list(qs)
             from operator import itemgetter
@@ -185,7 +206,12 @@ class CloudStorageView(View):
             ql.sort(key=itemgetter('bucket__area'))
             res = []
             for area, items in groupby(ql, key=itemgetter('bucket__area')):
-                res_c = {'area': area, 'items': list(items)}
+                items_list = list(items)
+                for key, val in enumerate(items_list):
+                    pay_types = Pay_Type.objects.filter(store_meal=items_list[key]['id']).values("id","payment")
+                    items_list[key]['pay_type'] = list(pay_types)
+
+                res_c = {'area': area, 'items': items_list}
                 res.append(res_c)
             result = {
                 'meals': res,
@@ -436,6 +462,7 @@ class CloudStorageView(View):
         dv_qs = Device_Info.objects.filter(UID=uid, userID_id=userID, isShare=False)
         if not dv_qs.exists():
             return response.json(12)
+        # bv_qs = UID_Bucket.objects.filter(UID=uid,channel=channel)
         now_time = int(time.time())
         vh_qs = VodHlsModel.objects.filter \
             ( uid=uid, channel=channel, time__range=(startTime, endTime), endTime__gte=now_time). \
@@ -472,6 +499,7 @@ class CloudStorageView(View):
                 #     region_name=bucket__region
                 # )
                 # conn = session.client('s3')
+
                 # thumbspng = '{uid}/vod{channel}/{time}/Thumb.jpeg'. \
                 #     format(uid=uid, channel=channel, time=vod['time'])
                 # response_url = conn.generate_presigned_url(
@@ -483,6 +511,7 @@ class CloudStorageView(View):
                 #     ExpiresIn=3600
                 # )
                 # thumb_url = response_url
+                #     format(uid=uid, channel=channel, time=vod['time'])
 
                 vod_url = '{server_domain}/cloudstorage/signplaym3u8?' \
                           'uid={uid}&channel={channel}&time={time}&sign=tktktktk'. \
@@ -706,80 +735,82 @@ class CloudStorageView(View):
     def do_pay_ok(self):
         response = HttpResponse()
         response.content = '''
-
-<!DOCTYPE html>
 <html>
 <head>
-	<!--浏览器不缓存-->
-	<meta http-equiv="Pragma" content="no-cache">
-	<meta http-equiv="Cache-Control" content="no-cache">
-	<meta http-equiv="Expires" content="0">
-	<!--utf-8-->
+        <!--浏览器不缓存-->
+        <meta http-equiv="Pragma" content="no-cache">
+        <meta http-equiv="Cache-Control" content="no-cache">
+        <meta http-equiv="Expires" content="0">
+        <!--utf-8-->
     <meta http-equiv="content-type" content="text/html;charset=utf-8">
     <!-- viewport的<meta>标签,这个标签可以修改在大部分的移动设备上面的显示,为了确保适当的绘制和触屏缩放。-->
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
-    <link rel="shortcut icon" href="https://test.dvema.com/web/images/favicon.ico" type="image/x-icon"  charset="utf-8"/>  
+    <link rel="shortcut icon" href="https://test.dvema.com/web/images/favicon.ico" type="image/x-icon" charset="utf-8">  
     <title>Trading particulars</title>
     <style>
-    	.title_head{
-    		height: 50px;
-    		border-radius: 5px;
-    		background-color: #c3c6c7; 
-    		text-align: center;
-    		line-height: 50px;
-    	}
-    	.content{
-    		text-align: center;
-    		margin-top: 50px;
-    		font-size: 20px;
-    		color : green
-    	}
-    	.content_img{
-    		width: 60px; 
-    		height: 60px;
-    	}
-    	.bottom{
-    		 margin-bottom: 10px; 
-    		 margin-top: 250px; 
-    		 color : green
-    	}
-    	.bottom_div{
-    		border: 1px solid green; 
-    		line-height: 38px; 
-    		text-align: center; 
-    		width: 100px; 
-    		height: 38px;
-    		border-radius: 5px;
-    	}
-    	
-    	.bottom_div:hover{
-    		background-color: #dde4e2;
-    	}
+            .title_head{
+                    height: 50px;
+                    border-radius: 5px;
+                    background-color: #c3c6c7; 
+                    text-align: center;
+                    line-height: 50px;
+            }
+            .content{
+                    text-align: center;
+                    margin-top: 50px;
+                    font-size: 15px;
+                    color:#0000008A;
+					
+            }
+            .content_img{
+					margin-bottom:15px;
+                    width: 60px; 
+                    height: 60px;
+            }
+            .bottom{
+                     margin-bottom: 10px; 
+                     margin-top: 250px; 
+                     color : white;
+            }
+            .bottom_div{
+                    border: 1px solid #68c9c5; 
+                    line-height: 38px; 
+                    text-align: center; 
+                    width: 100px; 
+                    height: 38px;
+                    border-radius: 30px;
+					background-color:#68c9c5; 
+            }
+            
+            .bottom_div:hover{
+                    background-color: #dde4e2;
+            }
     </style>
 </head>
-<body>
-	<div class="title_head">Trading particulars</div>
+<body style="" rlt="1" inmaintabuse="true">
+        
     <div class="content">
-    	<p >
-    		<img src="https://test.dvema.com/web/images/timg.jpg" class="content_img">
-    		<br />
-    		Successful payment
-    	</p>
+            <p>
+					<img src="https://test.dvema.com/web/images/success.png" class="content_img">
+                    <br>
+                    支付成功
+            </p>
     </div>
     <center class="bottom">
-    	<div class="bottom_div" onclick="payOKButton()"> 
-    	 Finish
-    	</div>
+            <div class="bottom_div" onclick="payOKButton()"> 
+             完成
+            </div>
     </center>
-    <script> 	    // 点击付款成功按钮
+    <script src="//hm.baidu.com/hm.js?eaa57ca47dacb4ad4f5a257001a3457c"></script><script>             // 点击付款成功按钮
     function payOKButton() {
         // 复杂数据
         console.log('success')
         window.location.href="https://www.baidu.com?page=closePage"  
     }
-	</script>
-</body> 
-</html>
+        </script>
+ 
+
+        <div id="qds" style="display:none;"></div></body></html>
         '''
         return response
 
@@ -886,6 +917,50 @@ class CloudStorageView(View):
         red_url = "{SERVER_DOMAIN}cloudstorage/payOK".format(SERVER_DOMAIN=SERVER_DOMAIN)
         return HttpResponseRedirect(red_url)
 
+
+    def do_pay_by_wechat_callback(self, request_dict, response):
+        result_code = request_dict.get('result_code', None)
+        if result_code == 'SUCCESS':
+            response = HttpResponse()
+            check_sign = WechatPayObject.get_notifypay(request_dict)
+            if not check_sign:
+                return HttpResponse(WechatPayObject.xml_to_dict({'return_code':'FAIL', 'return_msg':'签名失败'}))
+            orderID = request_dict.get('out_trade_no',None)
+            order_qs = Order_Model.objects.filter(orderID=orderID)
+            nowTime = int(time.time())
+            order_list = order_qs.values("UID", "channel", "commodity_code")
+            UID = order_list[0]['UID']
+            channel = order_list[0]['channel']
+            commodity_code = order_list[0]['commodity_code']
+            smqs = Store_Meal.objects.filter(commodity_code=commodity_code). \
+                values("day", "bucket_id", "bucket__storeDay")
+            bucketId = smqs[0]['bucket_id']
+            if not smqs.exists():
+                return HttpResponse(WechatPayObject.xml_to_dict({'return_code':'FAIL', 'return_msg':'套餐不存在'}))
+            addTime = int(smqs[0]["day"]) * 24 * 3600
+            # ##
+            ubqs = UID_Bucket.objects.filter(uid=UID, channel=channel, endTime__gte=nowTime). \
+                values("bucket__storeDay", "bucket__region", "endTime")
+            if ubqs.exists():
+                ubqs_count = ubqs.count()
+                print(ubqs_count)
+                ubq = ubqs[ubqs_count - 1]
+                print(ubq)
+                new_starTime = ubq['endTime'] + 1
+                ub_cqs = UID_Bucket.objects.create \
+                    (uid=UID, channel=channel, bucket_id=bucketId,
+                     endTime=new_starTime + addTime)
+                uid_bucket_id = ub_cqs.id
+            else:
+                ub_cqs = UID_Bucket.objects.create \
+                    (uid=UID, channel=channel, bucket_id=bucketId, endTime=nowTime + addTime)
+                uid_bucket_id = ub_cqs.id
+            order_qs.update(status=1, updTime=nowTime, uid_bucket_id=uid_bucket_id)
+
+            return HttpResponse(WechatPayObject.xml_to_dict({'return_code':'SUCCESS', 'return_msg':'OK'}))
+
+        return HttpResponse(WechatPayObject.xml_to_dict({'return_code':'FAIL', 'return_msg':'参数格式校验错误'}))
+
     def do_create_pay_order(self, request_dict, userID, response):
         uid = request_dict.get('uid', None)
         channel = request_dict.get('channel', None)
@@ -898,7 +973,7 @@ class CloudStorageView(View):
         dv_qs = Device_Info.objects.filter(userID_id=userID, UID=uid, isShare=False, isExist=1)
         if not dv_qs.exists():
             return response.json(12)
-        smqs = Store_Meal.objects.filter(commodity_code=commodity_code, type=pay_type). \
+        smqs = Store_Meal.objects.filter(commodity_code=commodity_code, pay_type=pay_type). \
             values('currency', 'price', 'content', 'day', 'commodity_type', 'title', 'content')
         if not smqs.exists():
             return response.json(10, '套餐不存在')
@@ -915,7 +990,7 @@ class CloudStorageView(View):
         #     new_starTime = ubq['endTime'] + 1
         nowTime = int(time.time())
         orderID = CommonService.createOrderID()
-        if pay_type == 0:
+        if pay_type == 1:
             call_sub_url = "{SERVER_DOMAIN}cloudstorage/dopaypalcallback?orderID={orderID}". \
                 format(SERVER_DOMAIN=SERVER_DOMAIN, orderID=orderID)
             # call_sub_url = "http://192.168.136.40:8077/cloudstorage/payExecute?orderID={orderID}".format(
@@ -948,7 +1023,7 @@ class CloudStorageView(View):
                                                commodity_code=commodity_code, commodity_type=commodity_type,rank_id=rank)
                     return response.json(0, {"redirectUrl": approval_url, "orderID": orderID})
             return response.json(10, 'generate_order_false')
-        else:
+        elif pay_type == 2:
             try:
                 aliPayObj = AliPayObject()
                 alipay = aliPayObj.conf()
@@ -981,3 +1056,178 @@ class CloudStorageView(View):
                                                           'error_code': 0})
                 else:
                     return response.json(10, '生成订单错误.')
+
+        elif pay_type == 3:
+            # spbill_create_ip = '127.0.0.1'
+            spbill_create_ip = '120.237.157.184'
+            pay = WechatPayObject()
+            notify_url="{SERVER_DOMAIN_SSL}cloudstorage/dowechatnotify".format(
+                SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL)
+            # 获取参数
+            price = float(price)*100
+            parameter_dict = pay.get_parameter(orderID, content, price, spbill_create_ip, notify_url)
+            print('parameter_dict', parameter_dict)
+            # parameter_dict 参数中获取MWEB_URL 调转页面在路径后面添加redirect_url
+            # 统一调用接口
+            response = pay.re_finall()
+            if not response:
+                return response.json(10, '生成订单错误.')
+            # 回调函数
+            Order_Model.objects.create(orderID=orderID, UID=uid, channel=channel, userID_id=userID,
+                                       desc=content, payType=pay_type, payTime=nowTime,
+                                       price=price, currency=currency, addTime=nowTime, updTime=nowTime,
+                                       endTime=(nowTime + int(day) * 3600 * 24), pay_url=notify_url,
+                                       commodity_code=commodity_code, commodity_type=commodity_type,rank_id=rank)
+            return JsonResponse(status=200, data={'result_code': 0, 'reason': 'success',
+                                                  'result': response,
+                                                  'orderId': orderID,
+                                                  'error_code': 0})
+            # 调起支付接口
+
+    # 生成体验订单
+    def do_experience_order(self, request_dict, userID, response):
+        uid = request_dict.get('uid', None)
+        channel = request_dict.get('channel', None)
+        commodity_code = request_dict.get('commodity_code', None)
+        pay_type = int(request_dict.get('pay_type', None))
+        rank = request_dict.get('rank', None)
+        cdk = request_dict.get('cdk', None)
+
+        if cdk != None and pay_type == 11:
+            cdk_qs = CDKcontextModel.objects.filter(cdk=cdk).values('is_activate', 'rank__id', 'rank__commodity_code')
+            if not cdk_qs.exists():
+                return response.json(10, '无效激活码')
+            if cdk_qs[0]['is_activate'] == 1:
+                return response.json(10, '激活码已被使用过')
+            rank = cdk_qs[0]['rank__id']
+            commodity_code = cdk_qs[0]['rank__commodity_code']
+
+        if uid == None or channel == None or commodity_code == None or pay_type == None or rank == None:
+            return response.json(13, '参数有误.')
+        dv_qs = Device_Info.objects.filter(userID_id=userID, UID=uid, isShare=False, isExist=1)
+        if not dv_qs.exists():
+            return response.json(12)
+        smqs = Store_Meal.objects.filter(commodity_code=commodity_code, pay_type=pay_type). \
+            values('currency', 'price', 'content', 'day', 'commodity_type', 'title', 'content')
+        if not smqs.exists():
+            return response.json(10, '套餐不存在')
+        currency = smqs[0]['currency']
+        price = smqs[0]['price']
+        content = smqs[0]['content']
+        day = smqs[0]['day']
+        commodity_type = smqs[0]['commodity_type']
+        # ubqs = UID_Bucket.objects.filter(uid=uid, channel=channel, endTime__gte=nowTime). \
+        #     values("bucket__storeDay", "bucket__region", "endTime")
+        # if ubqs.exists():
+        #     ubqs_count = ubqs.count()
+        #     ubq = ubqs[ubqs_count - 1, ubqs_count]
+        #     new_starTime = ubq['endTime'] + 1
+        nowTime = int(time.time())
+        orderID = CommonService.createOrderID()
+
+        Order_Model.objects.create(orderID=orderID, UID=uid, channel=channel, userID_id=userID,
+                                   desc=content, payType=pay_type, payTime=nowTime,
+                                   price=price, currency=currency, addTime=nowTime, updTime=nowTime,
+                                   endTime=(nowTime + int(day) * 3600 * 24), pay_url="体验版",
+                                   commodity_code=commodity_code, commodity_type=commodity_type,
+                                   rank_id=rank)
+
+        order_qs = Order_Model.objects.filter(orderID=orderID)
+        nowTime = int(time.time())
+        order_list = order_qs.values("UID", "channel", "commodity_code")
+        UID = order_list[0]['UID']
+        channel = order_list[0]['channel']
+        commodity_code = order_list[0]['commodity_code']
+        smqs = Store_Meal.objects.filter(commodity_code=commodity_code). \
+            values("day", "bucket_id", "bucket__storeDay")
+        bucketId = smqs[0]['bucket_id']
+        if not smqs.exists():
+            return response.json(0, '套餐已删除')
+        addTime = int(smqs[0]["day"]) * 24 * 3600
+        # ##
+        ubqs = UID_Bucket.objects.filter(uid=UID, channel=channel, endTime__gte=nowTime). \
+            values("bucket__storeDay", "bucket__region", "endTime")
+        if ubqs.exists():
+            ubqs_count = ubqs.count()
+            print(ubqs_count)
+            ubq = ubqs[ubqs_count - 1]
+            print(ubq)
+            new_starTime = ubq['endTime'] + 1
+            ub_cqs = UID_Bucket.objects.create \
+                (uid=UID, channel=channel, bucket_id=bucketId,
+                 endTime=new_starTime + addTime)
+            uid_bucket_id = ub_cqs.id
+        else:
+            ub_cqs = UID_Bucket.objects.create \
+                (uid=UID, channel=channel, bucket_id=bucketId, endTime=nowTime + addTime)
+            uid_bucket_id = ub_cqs.id
+        order_qs.update(status=1, updTime=nowTime, uid_bucket_id=uid_bucket_id)
+
+        # return response.json(0)
+        if pay_type == 10:
+            ExperienceContextModel.objects.create(
+                experience_type=0,
+                uid=uid,
+                do_time=nowTime
+
+            )
+
+        if pay_type== 11:
+            update_dict = {}
+            update_dict['is_activate'] = 1
+            update_dict['order'] = orderID
+            CDKcontextModel.objects.filter(cdk=cdk).update(**update_dict)
+
+        result = "{SERVER_DOMAIN}cloudstorage/payOK".format(SERVER_DOMAIN=SERVER_DOMAIN)
+        return response.json(0, result)
+        # red_url =
+        # return JsonResponse(status=200, data={'red_url': red_url})
+
+        # return HttpResponseRedirect(red_url)
+
+    #重置设备云存体验
+    def do_experience_reset(self, request_dict, userID, response):
+        bid = request_dict.get("id",None)
+        ubq = UID_Bucket.objects.filter(id=bid)
+        if ubq:
+            eq =ExperienceContextModel.objects.filter(uid = ubq[0].uid)
+            if eq:
+                eq.delete()
+                Order_Model.objects.filter(uid_bucket_id = bid).delete()
+                ubq.delete()
+            else:
+                return response.json(10007)
+
+        else:
+            return response.json(0, '重置云存体验失败')
+
+        return response.json(0,'重置云存体验成功')
+
+
+def deleteVodHls(request):
+    UID = 'DSXG7481JVA2JM94111A'
+    channel = 1
+    ubqs = UID_Bucket.objects.filter(uid=UID, channel=channel). \
+        values("bucket_id", "endTime", "bucket__storeDay")
+    nowTime = int(time.time())
+    if ubqs.exists():
+        ubqs_count = ubqs.count()
+        ubq = ubqs[ubqs_count - 1, ubqs_count]
+        new_starTime = ubq['endTime'] + 1
+        print(new_starTime)
+        exit()
+
+        # ub_cqs = UID_Bucket.objects.create(uid=UID, channel=channel, bucket_id=bucketId,
+        #                                    endTime=new_starTime + addTime)
+        # uid_bucket_id = ub_cqs.id
+    exit()
+
+    response = ResponseObject()
+    i = int(request.GET.get('i', 5))
+    nowTime = int(time.time())
+    for i in range(i):
+        vh_qs = VodHlsModel.objects.filter(endTime__lte=str(nowTime))[0:10000]
+        id_list = vh_qs.values_list("id", flat=True)
+        print(id_list)
+        VodHlsModel.objects.filter(id__in=list(id_list)).delete()
+    return response.json(0)

+ 3 - 0
Controller/FAQController.py

@@ -357,6 +357,9 @@ class FAQView(View):
 
         enresults = request_dict.get('enresults', None).replace("\'", "XX??????XX")
         enresults = json.loads(enresults)
+
+        ZositechHelpModel.objects.all().delete()
+
         for data in zhresults['results']:
             labname = ""
             if data['label_names']:

+ 33 - 9
Controller/MealManage.py

@@ -18,7 +18,7 @@ from django.utils.decorators import method_decorator
 from django.views.decorators.csrf import csrf_exempt
 from django.views.generic.base import View
 
-from Model.models import Store_Meal, VodBucketModel
+from Model.models import Store_Meal, VodBucketModel, Pay_Type
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
 from Service.CommonService import CommonService
@@ -79,7 +79,8 @@ class MealManage(View):
         day = request_dict.get('day', None)
         currency = request_dict.get('currency', None)
         bucketID = request_dict.get('bucketID', None)
-        type = request_dict.get('type', None)
+        paytype = request_dict.get('paytype', None)
+        virtual_price = request_dict.get('virtual_price', None)
         if not title or not id or not price or not day or not content:
             return response.json(444, 'title,id,price,content,day,bucketID')
         own_perm = ModelService.check_perm(userID=userID, permID=40)
@@ -90,8 +91,11 @@ class MealManage(View):
             if Store_Meal.objects.filter(id=id):
                 return response.json(10, '已存在')
             store_meal = Store_Meal(id=id, title=title, price=price, content=content, day=day, bucket_id=bucketID,
-                                    currency=currency, type=type)
+                                    currency=currency, virtual_price=virtual_price)
             store_meal.save()
+            paytype = paytype.split(',')
+            if len(paytype) > 0:
+                Store_Meal.objects.get(id=id).pay_type.set(paytype)
         except Exception:
             errorInfo = traceback.format_exc()
             print(errorInfo)
@@ -116,13 +120,26 @@ class MealManage(View):
         line = int(request_dict.get('line', None))
         if page is None or line is None:
             return response.json(444)
-        qs = Store_Meal.objects.values("id", "title", "price", "content", "day", "add_time", "update_time", "currency",
-                                       "type", "bucket_id", "bucket__bucket", "commodity_type", "commodity_code",
-                                       "bucket__storeDay")
+        qs = Store_Meal.objects.values("id", "title", "price", "content", "day", "add_time", "update_time", "currency"
+                                       , "bucket_id", "bucket__bucket", "bucket__area", "commodity_type", "commodity_code",
+                                       "bucket__storeDay", "virtual_price")
         res = {}
         if qs.exists():
-            res['count'] = qs.count()
-            res['data'] = CommonService.qs_to_list(qs[(page - 1) * line:page * line])
+            ql = list(qs)
+            from operator import itemgetter
+            from itertools import groupby
+            ql.sort(key=itemgetter('bucket__area'))
+            ql=CommonService.qs_to_list(ql[(page - 1) * line:page * line])
+            for area, items in groupby(ql, key=itemgetter('bucket__area')):
+                items_list = list(items)
+                for key, val in enumerate(items_list):
+                    pay_types = Pay_Type.objects.filter(store_meal=items_list[key]['id']).values("id", "payment")
+                    items_list[key]['pay_type'] = list(pay_types)
+
+
+                res['count'] = len(ql)
+                res['data'] = items_list
+
         return response.json(0, res)
 
     def update(self, request_dict, userID, response):
@@ -135,6 +152,7 @@ class MealManage(View):
         bucketID = request_dict.get('bucketID', None)
         commodity_type = request_dict.get('commodity_type', None)
         commodity_code = request_dict.get('commodity_code', None)
+        virtual_price = request_dict.get('virtual_price', None)
         type = request_dict.get('type', None)
         if not id or not title or not price or not content or not day or not type:
             return response.json(444, 'id, title, price, content, day,type')
@@ -150,13 +168,19 @@ class MealManage(View):
             store_meal.content = content
             store_meal.commodity_type = commodity_type
             store_meal.commodity_code = commodity_code
+            store_meal.virtual_price = virtual_price
             store_meal.day = day
-            store_meal.type = type
             if bucketID:
                 store_meal.bucket_id = bucketID
             if currency:
                 store_meal.currency = currency
             store_meal.save()
+            type = type.split(',')
+            if len(type) > 0:
+                Store_Meal.objects.get(id=id).pay_type.set(type)
+            else:
+                Store_Meal.objects.get(id=id).pay_type.clear()
+
         except Exception:
             errorInfo = traceback.format_exc()
             print(errorInfo)

+ 1 - 1
Controller/TestApi.py

@@ -688,7 +688,7 @@ class testView(View):
 
         #uidToken
         # utko = UidTokenObject()
-        # res = utko.generate(data={'uid':'86YC8Z192VB1VMKU111A','channel':1})
+        # res = utko.generate(data={'uid': 'H2CMKET2LDC3ZBL4111A','channel': 1})
         return JsonResponse(status=200, data=res,safe=False)
 
     def test_upload_s3(self,request_dict):

+ 29 - 17
Controller/UserController.py

@@ -1868,6 +1868,7 @@ class InitInfoView(View):
                     update(**update_dict)
             if appBundleId:
                 user_ex_qs = UserExModel.objects.filter(userID_id=userID)
+                user_ex = None
                 if user_ex_qs.exists():
                     update_dict = {
                         'updTime': now_time,
@@ -1875,6 +1876,7 @@ class InitInfoView(View):
                         'region': lang
                     }
                     user_ex_qs.update(**update_dict)
+                    user_ex = user_ex_qs[0]
                 else:
                     create_dict = {
                         'addTime': now_time,
@@ -1883,9 +1885,9 @@ class InitInfoView(View):
                         'userID_id': userID,
                         'region': lang
                     }
-                    user_ex_qs = UserExModel.objects.create(**create_dict)
+                    user_ex = UserExModel.objects.create(**create_dict)
 
-                country_ip_qs = CountryIPModel.objects.filter(user_ex_id=user_ex_qs[0].id)
+                country_ip_qs = CountryIPModel.objects.filter(user_ex_id=user_ex.id)
                 if not country_ip_qs.exists():
                     countryIp = CountryIPModel(
                         ip=CommonService.get_ip_address(request),
@@ -1893,7 +1895,6 @@ class InitInfoView(View):
                         user_ex_id=user_ex_qs[0].id
                     )
                     countryIp.save()
-
         # 获取设备是否存在有已被删除
         res = {'usmsg': 0}  # 预留字段, 有版本app该字段去掉会报错
         return response.json(0, res)
@@ -1903,7 +1904,6 @@ class InitInfoView(View):
         appBundleId = request_dict.get('appBundleId', None)
         lang = request_dict.get('lang', '')  # 语言区域
         if username and appBundleId:
-            country = CommonService.getAddr(CommonService.get_ip_address(request))
             user_qs = Device_User.objects.filter(username=username)
             if user_qs.exists():
                 user = user_qs[0]
@@ -1913,20 +1913,27 @@ class InitInfoView(View):
                     update_dict = {
                         'updTime': now_time,
                         'appBundleId': appBundleId,
-                        'region': lang,
-                        'country': country
+                        'region': lang
                     }
                     user_ex_qs.update(**update_dict)
+                    user_ex = user_ex_qs[0]
                 else:
                     create_dict = {
                         'addTime': now_time,
                         'updTime': now_time,
                         'appBundleId': appBundleId,
                         'userID_id': user.userID,
-                        'region': lang,
-                        'country': country
+                        'region': lang
                     }
-                    UserExModel.objects.create(**create_dict)
+                    user_ex = UserExModel.objects.create(**create_dict)
+                country_ip_qs = CountryIPModel.objects.filter(user_ex_id=user_ex.id)
+                if not country_ip_qs.exists():
+                    countryIp = CountryIPModel(
+                        ip=CommonService.get_ip_address(request),
+                        add_time=now_time,
+                        user_ex_id=user_ex_qs[0].id
+                    )
+                    countryIp.save()
                 return response.json(0)
             else:
                 return response.json(104)
@@ -2176,7 +2183,8 @@ class wxPerfectView(TemplateView):
                     'com.ansjer.loocamccloud': {'appid': 'wx9f6d6ce63f85b367',
                                                 'secret': 'fe495884cd24637f1ae516c7f53d1b97', },
                     'com.ansjer.zccloud': {'appid': 'wx2a9f5ef9baf2760f', 'secret': '5d38c7079676463149ffea593c58f2ed'},
-                    'com.ansjer.customizede': {'appid':'wx2a9f5ef9baf2760f', 'secret': '5d38c7079676463149ffea593c58f2ed'},
+                    'com.ansjer.customizede': {'appid': 'wx2a9f5ef9baf2760f',
+                                               'secret': '5d38c7079676463149ffea593c58f2ed'},
                     # android
                     'com.ansjer.zccloud_ab': {'appid': 'wx2a9f5ef9baf2760f',
                                               'secret': '5d38c7079676463149ffea593c58f2ed'},
@@ -2911,7 +2919,6 @@ class Image_Code_RegisterView(TemplateView):
         unique = request_dict.get('unique', None)
         if unique:
             delete_local_account(unique)
-
         if not all([userEmail, password, lang, imageCodeId, valid_code]):
             return response.json(444)
         try:
@@ -3307,7 +3314,8 @@ class v3LoginByFingerprintView(View):
                     return response.json(104)
                 else:
                     users = user_qs.values('role__rid', 'role__roleName', 'userID', 'NickName', 'username', 'userEmail',
-                               'phone', 'password', 'userIconPath', 'fingerprint_enable', 'fingerprint_key')[0]
+                                           'phone', 'password', 'userIconPath', 'fingerprint_enable',
+                                           'fingerprint_key')[0]
                     if users['fingerprint_enable'] == 0:
                         return response.json(112)
                     else:
@@ -3335,7 +3343,8 @@ class v3LoginByFingerprintView(View):
                             res['userEmail'] = users['userEmail'] if users['userEmail'] is not None else ''
                             res['phone'] = users['phone'] if users['phone'] is not None else ''
                             res['fingerprint_enable'] = users['fingerprint_enable']
-                            res['fingerprint_key'] = CommonService.encode_data(content=users['fingerprint_key'], start=2)
+                            res['fingerprint_key'] = CommonService.encode_data(content=users['fingerprint_key'],
+                                                                               start=2)
                             return response.json(0, res)
                         else:
                             return response.json(tko.code)
@@ -3425,7 +3434,8 @@ class AppleAuthLogin(View):
 
             if key_object:
                 try:
-                    claims = jwt.decode(identity_token, key=key_object, verify=True, algorithms=[alg], audience=app_bundle_id)
+                    claims = jwt.decode(identity_token, key=key_object, verify=True, algorithms=[alg],
+                                        audience=app_bundle_id)
                     unionID = claims['sub']
                     print(claims)
                     user_extend_qs = UserOauth2Model.objects.filter(unionID=unionID, authType=2)
@@ -3533,8 +3543,8 @@ class LocalUserView(View):
         request.encoding = 'utf-8'
         request_dict = request.POST
         operation = kwargs.get('operation', None)
-        print('start_time='+ str((time.time())))
-        ip=CommonService.get_ip_address(request)
+        print('start_time=' + str((time.time())))
+        ip = CommonService.get_ip_address(request)
         print('end_time=' + str((time.time())))
         return self.validate(request_dict, operation)
 
@@ -3685,5 +3695,7 @@ def updateUserCountry(request):
 
             country_ip['country'] = country
             CountryIPModel.objects.filter(id=country_ip['id']).update(country=country, status=1)
+            # ids.append(country_ip['id'])
+        # CountryIPModel.objects.filter(id__in=tuple(ids)).update(status=1)
     response = ResponseObject()
-    return response.json(0)
+    return response.json(0)

+ 50 - 7
Model/models.py

@@ -124,7 +124,7 @@ class Device_User(AbstractBaseUser):
                               verbose_name=u'用户ID', unique=True)
     role = models.ManyToManyField(to='Role', blank=True, verbose_name=u'用户角色', db_table='user_role')
 
-    username = models.CharField(max_length=64, verbose_name=u'用户名', default='', blank=True)
+    username = models.CharField(max_length=64, db_index=True, verbose_name=u'用户名', default='', blank=True)
     password = models.CharField(max_length=128, verbose_name=u'密码')
     userEmail = models.EmailField(max_length=64, verbose_name=u'邮箱', default='', blank=True)
     # 实际的路径就是 MEDIA_ROOT/Image/filename,所以可用upload_to来指定文件存放的前缀路径
@@ -291,10 +291,10 @@ class Equipment_Info(models.Model):
     receiveTime = models.CharField(blank=True, default='', max_length=16, verbose_name=u'接收到报警时间')
     userID_id = models.CharField(default='',  db_index=True, blank=True, max_length=32, verbose_name=u'用户ID')
     is_st = models.SmallIntegerField(default=0, verbose_name='是否截图')  # 0 否,1 是图,2,视频
-    message_id = models.CharField(max_length=32, default='', verbose_name='第三方推送服务器返回的id')
-    push_type = models.SmallIntegerField(default=0, verbose_name='第三方推送服务器标志。0:APNS推送,1:谷歌推送,2:极光推送')
-    push_server_status = models.IntegerField(default=200, verbose_name='是否成功推送到第三方服务器。200:成功,other:失败')
-    push_device_status = models.SmallIntegerField(default=-1, verbose_name='是否成功推送到目标设备。0:失败,1:成功')
+    # message_id = models.CharField(blank=True, max_length=32, default='', verbose_name='第三方推送服务器返回的id')
+    # push_type = models.SmallIntegerField(blank=True, default=0, verbose_name='第三方推送服务器标志。0:APNS推送,1:谷歌推送,2:极光推送')
+    # push_server_status = models.IntegerField(blank=True, default=200, verbose_name='是否成功推送到第三方服务器。200:成功,other:失败')
+    # push_device_status = models.SmallIntegerField(blank=True, default=-1, verbose_name='是否成功推送到目标设备。0:失败,1:成功')
     addTime = models.IntegerField(verbose_name='添加时间', default=0)
 
     def __str__(self):
@@ -416,10 +416,12 @@ class Store_Meal(models.Model):
     title = models.CharField(blank=True, max_length=32, verbose_name=u'标题')
     currency = models.CharField(blank=True, default='USD', max_length=32, verbose_name=u'货币')
     price = models.CharField(blank=True, max_length=32, verbose_name=u'价格')
+    virtual_price = models.CharField(blank=True, max_length=32, verbose_name=u'虚拟价格')
     day = models.IntegerField(default=0, blank=True, verbose_name=u'套餐天数')
     content = models.TextField(blank=True, null=True, verbose_name=u'描述')
     add_time = models.DateTimeField(blank=True, null=True, verbose_name=u'加入时间', auto_now_add=True)
-    type = models.SmallIntegerField(default=0, verbose_name='付款类型')  # 0 是paypal,1为支付宝
+    # type = models.SmallIntegerField(default=0, verbose_name='付款类型')  # 0是paypal,1为支付宝
+    pay_type = models.ManyToManyField(to='pay_type', verbose_name='付款类型', db_table='store_meal_pay')
     update_time = models.DateTimeField(blank=True, verbose_name=u'更新时间', auto_now=True)
     bucket = models.ForeignKey(VodBucketModel, blank=True, to_field='id', on_delete=models.CASCADE,
                                default=1, verbose_name='存储空间')
@@ -435,6 +437,19 @@ class Store_Meal(models.Model):
         verbose_name_plural = verbose_name
         ordering = ('id',)
 
+class Pay_Type(models.Model):
+    id = models.AutoField(primary_key=True, verbose_name=u'自增ID')
+    payment = models.CharField(max_length=32, verbose_name=u'支付方式')
+
+    def __str__(self):
+        return self.id
+
+    class Meta:
+        db_table = 'pay_type'
+        verbose_name = u'付款类型'
+        verbose_name_plural = verbose_name
+        ordering = ('id',)
+
 
 class Equipment_Version(models.Model):
     eid = models.CharField(blank=True, max_length=32, primary_key=True)
@@ -640,7 +655,7 @@ class UID_Preview(models.Model):
 # 系统发送信息新到用户
 class SysMsgModel(models.Model):
     id = models.AutoField(primary_key=True, verbose_name='自增id')
-    userID_id = models.CharField(default='', db_index=True,blank=True, max_length=32, verbose_name=u'用户ID')
+    userID_id = models.CharField(default='', db_index=True, blank=True, max_length=32, verbose_name=u'用户ID')
     msg = models.TextField(blank=True, default='', verbose_name=u'发送内容')
     status = models.SmallIntegerField(verbose_name='是否已读', default=0)  # 0:否,1:是
     addTime = models.IntegerField(verbose_name='添加时间', default=0)
@@ -1081,6 +1096,34 @@ class EquipmentVersionLimitModel(models.Model):
         verbose_name_plural = verbose_name
 
 
+class ExperienceContextModel(models.Model):
+    id = models.AutoField(primary_key=True)
+    experience_type = models.SmallIntegerField(default=0,verbose_name='体验类型') # 0: 免费体验套餐, 1: 激活码
+    uid = models.CharField(max_length=20, default='', verbose_name='设备uid')
+    do_time = models.IntegerField(default=0, verbose_name='激活时间')
+    # is_experience = models.SmallIntegerField(default=0, verbose_name=u'是否云存体验用户')  # 0:不是体验用户,1:是体验用户
+
+    class Meta:
+        db_table = 'experience_context'
+        verbose_name = '设备体验表'
+        verbose_name_plural = verbose_name
+
+class CDKcontextModel(models.Model):
+    id = models.AutoField(primary_key=True)
+    cdk = models.CharField(max_length=50,unique=True,verbose_name='激活码')
+    create_time = models.IntegerField(default=0, verbose_name='创建时间')
+    valid_time = models.IntegerField(default=0, verbose_name='有效期间')  #超过有效期激活码不可在激活 ,0:永久
+    is_activate = models.SmallIntegerField(default=0, verbose_name='是否已激活') #0 未激活  1 已激活
+    rank = models.ForeignKey(Store_Meal, to_field='id', default='', on_delete=models.CASCADE, verbose_name='套餐类型')
+    # order = models.ForeignKey(Order_Model, blank=True, max_length=20, to_field='orderID', on_delete=models.CASCADE, verbose_name='订单id', unique=True)
+    order = models.CharField(max_length=20, blank=True, unique=True, verbose_name='订单id')
+
+    class Meta:
+        db_table = 'cdk_context'
+        verbose_name = '激活码表'
+        verbose_name_plural = verbose_name
+
+
 class VoicePromptModel(models.Model):
     id = models.AutoField(primary_key=True)
     title = models.CharField(max_length=128, default='', verbose_name='语音标题')

+ 1 - 0
Object/ResponseObject.py

@@ -142,6 +142,7 @@ class ResponseObject(object):
             10004: '请求方法不正确。请联系开发者',
             10005: '配置错误,客户编号这个值是错误的',
             10006: '配置错误,路径这个值是错误的',
+            10007: '此设备不是体验套餐,无法重置'
         }
         if self.lang == 'cn':
             msg = data_cn

+ 152 - 0
Object/WechatPayObject.py

@@ -0,0 +1,152 @@
+import hashlib
+import time
+from urllib.parse import quote
+
+import requests
+import xmltodict
+
+
+class WechatPayObject:
+    """配置账号信息"""
+    # 微信公众号身份的唯一标识。审核通过后,在微信发送的邮件中查看
+
+    def __init__(self):
+        # 开发者调用支付统一下单API生成预交易单
+        self.APPID = 'wx2a9f5ef9baf2760f'
+        # 商户id
+        self.MCHID = '1508209741'
+        # 异步通知url,商户根据实际开发过程设定
+        self.NOTIFY_URL = 'test'
+        self.TRADE_TYPE = 'APP'
+        self.APIKEY = 'ZHansjeransjeransjer680301000000'
+        self.url = 'https://api.mch.weixin.qq.com/pay/unifiedorder'  # 微信请求url
+        self.error = None
+        self.params = None
+
+    def get_parameter(self, order_id, body, total_fee, spbill_create_ip, notify_url):
+        self.params = {
+            'appid': self.APPID,  # appid
+            'mch_id': self.MCHID,  # 商户号
+            'nonce_str': self.getNonceStr(),
+            'body': body,  # 商品描述
+            'out_trade_no': str(order_id),  # 商户订单号
+            'total_fee': str(int(total_fee)),
+            'spbill_create_ip': spbill_create_ip,  # 127.0.0.1
+            'trade_type': self.TRADE_TYPE,  # 交易类型
+            'notify_url': notify_url,  # 微信支付结果异步通知地址
+            'receipt': 'Y'
+        }
+        return self.params
+
+    def getNonceStr(self, length=32):
+        """生成随机字符串"""
+        import random
+        chars = "abcdefghijklmnopqrstuvwxyz0123456789"
+        strs = []
+        for x in range(length):
+            strs.append(chars[random.randrange(0, len(chars))])
+        return "".join(strs)
+
+    def key_value_url(self, value, urlencode):
+        """
+        将键值对转为 key1=value1&key2=value2
+        对参数按照key=value的格式,并按照参数名ASCII字典序排序
+        """
+        slist = sorted(value)
+        buff = []
+        for k in slist:
+            v = quote(value[k]) if urlencode else value[k]
+            buff.append("{0}={1}".format(k, v))
+
+        return "&".join(buff)
+
+    def get_sign(self, params):
+        """
+        生成sign
+        拼接API密钥
+        """
+        stringA = self.key_value_url(params, False)
+        stringSignTemp = stringA + '&key=' + self.APIKEY  # APIKEY, API密钥,需要在商户后台设置
+        sign = (hashlib.md5(stringSignTemp.encode("utf-8")).hexdigest()).upper()
+        params['sign'] = sign
+        return params
+
+    def get_req_xml(self):
+        """
+        拼接XML
+        """
+        self.get_sign(self.params)
+        xml = "<xml>"
+        for k, v in self.params.items():
+            # v = v.encode('utf8')
+            # k = k.encode('utf8')
+            xml += '<' + k + '>' + v + '</' + k + '>'
+        xml += "</xml>"
+        return xml.encode("utf-8")
+
+    def get_prepay_id(self):
+        """
+        请求获取prepay_id
+        """
+        xml = self.get_req_xml()
+        respone = requests.post(self.url, xml, headers={'Content-Type': 'application/xml'})
+        msg = respone.text.encode('ISO-8859-1').decode('utf-8')
+        xmlresp = xmltodict.parse(msg)
+        if xmlresp['xml']['return_code'] == 'SUCCESS':
+            if xmlresp['xml']['result_code'] == 'SUCCESS':
+                prepay_id = xmlresp['xml']['prepay_id']
+                self.params['prepay_id'] = prepay_id
+                self.params['packageId'] = "Sign=WXPay"
+                self.params['timestamp'] = str(int(time.time()))
+                return self.params
+            else:
+                return 'failure'
+        else:
+            return 'failure'
+
+    def re_finall(self):
+        """得到prepay_id后再次签名,返回给终端参数.
+        """
+        self.get_prepay_id()
+        if self.error:
+            return False
+        sign_again_params = {
+            'appid': self.params['appid'],
+            'noncestr': self.params['nonce_str'],
+            'package': self.params['packageId'],
+            'partnerid': self.params['mch_id'],
+            'timestamp': self.params['timestamp'],
+            'prepayid': self.params['prepay_id']
+        }
+        self.get_sign(sign_again_params)
+        sign_again_params['sign'] = sign_again_params['sign']
+        sign_again_params['packageId'] = sign_again_params['package']
+        return sign_again_params  # 返回给app
+
+    def get_notifypay(self, data):
+        dictdata = dict(data)
+        _dictdata = dict(dictdata['xml'])
+        success = self.get_sign(_dictdata)
+        # print('success', success)
+        if success:
+            success.pop("sign", None)
+            success.pop("sign_type", None)
+            # return success
+            return True
+        else:
+            return False
+
+    @staticmethod
+    def xml_to_dict(params):
+        """
+        拼接XML
+        """
+        if not isinstance(params, dict):
+            return None
+        xml = "<xml>"
+        for k, v in params.items():
+            # v = v.encode('utf8')
+            # k = k.encode('utf8')
+            xml += '<' + k + '>' + v + '</' + k + '>'
+        xml += "</xml>"
+        return xml

+ 10 - 0
Service/ModelService.py

@@ -221,6 +221,16 @@ class ModelService:
         file.flush()
         file.close()
 
+    @staticmethod
+    def app_log_log(userID, UID):
+        file_path = '/'.join((BASE_DIR, 'static/app_log.log'))
+        file = open(file_path, 'a+')
+        file.write("username:" + userID + "; time:" + time.strftime(
+            "%Y-%m-%d %H:%M:%S", time.localtime()) + "; " + "; uid:" + UID)
+        file.write('\n')
+        file.flush()
+        file.close()
+
 
 def notify_alexa_delete(userID, UID):
     url = 'https://www.zositech.xyz/deviceStatus/delete'

+ 269 - 36
requirements.txt

@@ -1,36 +1,269 @@
-Django==2
-
-django-cors-headers
-django-imagekit
-django-guardian
-django-rest-framework
-simplejson
-djangorestframework-jwt
-South
-qcloudsms_py
-itsdangerous
-openpyxl
-xlrd
-mysqlclient
-boto3
-requests_aws4auth
-ffmpy
-xmltodict
-var_dump
-django-middleware-global-request
-jpush
-pyipip
-boto
-django-ratelimit
-paypalrestsdk
-pymongo
-image
-pyfcm
-pillow
-oss2
-redis
-ipip-ipdb
-alipay-sdk-python
-https://www.cnblogs.com/victorwu/p/8505336.html
-apns2
-aliyun-python-sdk-sts
+alabaster==0.7.12
+aliyun-python-sdk-core==2.13.15
+aliyun-python-sdk-core-v3==2.13.11
+aliyun-python-sdk-dysmsapi==1.0.0
+aliyun-python-sdk-kms==2.10.1
+aliyun-python-sdk-sts==3.0.1
+anaconda-client==1.7.2
+anaconda-navigator==1.9.7
+anaconda-project==0.8.3
+apns2==0.7.1
+asn1crypto==1.0.1
+astroid==2.3.1
+astropy==3.2.1
+atomicwrites==1.3.0
+attrs==19.2.0
+Babel==2.7.0
+backcall==0.1.0
+backports.functools-lru-cache==1.5
+backports.os==0.1.1
+backports.shutil-get-terminal-size==1.0.0
+backports.tempfile==1.0
+backports.weakref==1.0.post1
+beautifulsoup4==4.8.0
+bitarray==1.0.1
+bkcharts==0.2
+bleach==3.1.0
+bokeh==1.3.4
+boto==2.49.0
+boto3==1.12.13
+botocore==1.15.13
+Bottleneck==1.2.1
+certifi==2019.9.11
+cffi==1.12.3
+chardet==3.0.4
+Click==7.0
+cloudpickle==1.2.2
+clyent==1.2.2
+colorama==0.4.1
+comtypes==1.1.7
+conda==4.7.12
+conda-build==3.18.9
+conda-package-handling==1.6.0
+conda-verify==3.4.2
+contextlib2==0.6.0
+crcmod==1.7
+cryptography==2.8
+cssselect==1.1.0
+cycler==0.10.0
+Cython==0.29.13
+cytoolz==0.10.0
+dask==2.5.2
+decorator==4.4.0
+defusedxml==0.6.0
+distributed==2.5.2
+Django==2.1
+django-appconf==1.0.3
+django-cors-headers==3.2.1
+django-guardian==2.2.0
+django-imagekit==4.0.2
+django-middleware-global-request==0.1.2
+django-ratelimit==2.0.0
+django-rest-framework==0.1.0
+djangorestframework==3.11.0
+djangorestframework-jwt==1.11.0
+docutils==0.15.2
+entrypoints==0.3
+et-xmlfile==1.0.1
+fastcache==1.1.0
+ffmpy==0.2.2
+filelock==3.0.12
+Flask==1.1.1
+fsspec==0.5.2
+future==0.17.1
+gevent==1.4.0
+glob2==0.7
+greenlet==0.4.15
+gunicorn==20.0.4
+h2==2.6.2
+h5py==2.9.0
+HeapDict==1.0.1
+hpack==3.0.0
+html5lib==1.0.1
+hyper==0.7.0
+hyperframe==3.2.0
+idna==2.8
+image==1.5.28
+imageio==2.6.0
+imagesize==1.1.0
+importlib-metadata==0.23
+ipip-ipdb==1.3.2
+ipykernel==5.1.2
+ipython==7.8.0
+ipython-genutils==0.2.0
+ipywidgets==7.5.1
+isort==4.3.21
+itsdangerous==1.1.0
+jdcal==1.4.1
+jedi==0.15.1
+Jinja2==2.10.3
+jmespath==0.9.5
+joblib==0.13.2
+jpush==3.3.8
+json5==0.8.5
+jsonschema==3.0.2
+jupyter==1.0.0
+jupyter-client==5.3.3
+jupyter-console==6.0.0
+jupyter-core==4.5.0
+jupyterlab==1.1.4
+jupyterlab-server==1.0.6
+keyring==18.0.0
+kiwisolver==1.1.0
+lazy-object-proxy==1.4.2
+libarchive-c==2.8
+llvmlite==0.29.0
+locket==0.2.0
+lxml==4.4.1
+m3u8-generator==1.5
+MarkupSafe==1.1.1
+matplotlib==3.1.1
+mccabe==0.6.1
+menuinst==1.4.16
+mistune==0.8.4
+mkl-fft==1.0.14
+mkl-random==1.1.0
+mkl-service==2.3.0
+mock==3.0.5
+more-itertools==7.2.0
+mpmath==1.1.0
+msgpack==0.6.1
+multipledispatch==0.6.0
+mysqlclient==1.4.6
+navigator-updater==0.2.1
+nbconvert==5.6.0
+nbformat==4.4.0
+networkx==2.3
+nltk==3.4.5
+nose==1.3.7
+notebook==6.0.1
+numba==0.45.1
+numexpr==2.7.0
+numpy==1.16.5
+numpydoc==0.9.1
+olefile==0.46
+openpyxl==3.0.0
+oss2==2.9.1
+packaging==19.2
+pandas==0.25.1
+pandocfilters==1.4.2
+parso==0.5.1
+partd==1.0.0
+path.py==12.0.1
+pathlib2==2.3.5
+patsy==0.5.1
+paypalrestsdk==1.13.1
+pep8==1.7.1
+pickleshare==0.7.5
+pilkit==2.0
+Pillow==6.2.0
+pkginfo==1.5.0.1
+pluggy==0.13.0
+ply==3.11
+prometheus-client==0.7.1
+prompt-toolkit==2.0.10
+psutil==5.6.3
+py==1.8.0
+pyasn1==0.4.8
+pycodestyle==2.5.0
+pycosat==0.6.3
+pycparser==2.19
+pycrypto==2.6.1
+pycryptodome==3.9.7
+pycryptodomex==3.9.4
+pycurl==7.43.0.3
+pyfcm==1.4.7
+pyflakes==2.1.1
+Pygments==2.4.2
+pyipip==0.1.1
+PyJWT==1.7.1
+pylint==2.4.2
+pymongo==3.10.1
+PyMySQL==0.10.1
+pyodbc==4.0.27
+pyOpenSSL==19.1.0
+pyparsing==2.4.2
+pyquery==1.4.1
+pyreadline==2.1
+pyrsistent==0.15.4
+PySocks==1.7.1
+pytest==5.2.1
+pytest-arraydiff==0.3
+pytest-astropy==0.5.0
+pytest-doctestplus==0.4.0
+pytest-openfiles==0.4.0
+pytest-remotedata==0.3.2
+python-alipay-sdk==2.0.1
+python-dateutil==2.8.0
+pytz==2019.3
+PyWavelets==1.0.3
+pywin32==223
+pywinpty==0.5.5
+PyYAML==5.1.2
+pyzmq==18.1.0
+qcloudsms-py==0.1.4
+QtAwesome==0.6.0
+qtconsole==4.5.5
+QtPy==1.9.0
+redis==3.4.1
+requests==2.22.0
+requests-aws4auth==0.9
+rope==0.14.0
+rsa==4.0
+ruamel-yaml==0.15.46
+s3transfer==0.3.3
+scikit-image==0.15.0
+scikit-learn==0.21.3
+scipy==1.3.1
+seaborn==0.9.0
+selenium==3.141.0
+Send2Trash==1.5.0
+simplegeneric==0.8.1
+simplejson==3.17.0
+singledispatch==3.4.0.3
+six==1.12.0
+snowballstemmer==2.0.0
+sortedcollections==1.1.2
+sortedcontainers==2.1.0
+soupsieve==1.9.3
+South==1.0.2
+Sphinx==2.2.0
+sphinxcontrib-applehelp==1.0.1
+sphinxcontrib-devhelp==1.0.1
+sphinxcontrib-htmlhelp==1.0.2
+sphinxcontrib-jsmath==1.0.1
+sphinxcontrib-qthelp==1.0.2
+sphinxcontrib-serializinghtml==1.1.3
+sphinxcontrib-websupport==1.1.2
+spyder==3.3.6
+spyder-kernels==0.5.2
+SQLAlchemy==1.3.9
+statsmodels==0.10.1
+sympy==1.4
+tables==3.5.2
+tblib==1.4.0
+terminado==0.8.2
+testpath==0.4.2
+toolz==0.10.0
+tornado==6.0.3
+tqdm==4.36.1
+traitlets==4.3.3
+unicodecsv==0.14.1
+urllib3==1.24.2
+var-dump==1.2
+wcwidth==0.1.7
+webencodings==0.5.1
+Werkzeug==0.16.0
+widgetsnbextension==3.5.1
+win-inet-pton==1.1.0
+win-unicode-console==0.5
+wincertstore==0.2
+wrapt==1.11.2
+xlrd==1.2.0
+XlsxWriter==1.2.1
+xlwings==0.15.10
+xlwt==1.3.0
+xmltodict==0.12.0
+xpinyin==0.5.6
+zict==1.0.0
+zipp==0.6.0