Browse Source

AI合并到云存

peng 2 years ago
parent
commit
ce82568dc8

+ 3 - 0
AdminController/DeviceManagementController.py

@@ -361,7 +361,9 @@ class DeviceManagement(View):
                 # 删除和更新设备云存相关数据
                 UID_Bucket.objects.filter(uid=uid).delete()
                 Unused_Uid_Meal.objects.filter(uid=uid).delete()
+                AiService.objects.filter(uid=uid).delete()
                 Order_Model.objects.filter(UID=uid, order_type=0).delete()
+                Order_Model.objects.filter(UID=uid, order_type=1).delete()
                 StsCrdModel.objects.filter(uid=uid).delete()
                 VodHlsModel.objects.filter(uid=uid).delete()
                 # 删除vod_hls分表数据
@@ -821,6 +823,7 @@ class DeviceManagement(View):
                 UID_Bucket.objects.filter(uid=uid).delete()
                 Unused_Uid_Meal.objects.filter(uid=uid).delete()
                 Order_Model.objects.filter(UID=uid, order_type=0).delete()
+                Order_Model.objects.filter(UID=uid, order_type=1).delete()
                 StsCrdModel.objects.filter(uid=uid).delete()
                 VodHlsModel.objects.filter(uid=uid).delete()
                 # 删除vod_hls分表数据

+ 9 - 8
AdminController/ServeManagementController.py

@@ -753,20 +753,20 @@ class serveManagement(View):
                     'payTime': order['payTime'] if order['payTime'] else 'N/A'
                 }
                 #  订单显示(或不显示)停用/退款功能
-                if order['order_type'] == 0:  # 云存
+                if order['order_type'] == 0 or order['order_type'] == 1:  # 云存
                     uid_bucket = UID_Bucket.objects.filter(uid=order['UID']).values('use_status')
                     user_status = uid_bucket[0]['use_status'] if uid_bucket.exists() else ''
                     if user_status != '':
                         data['user_status'] = user_status
                     else:
                         data['user_status'] = 2
-                elif order['order_type'] == 1:  # ai
-                    ai_service_qs = AiService.objects.filter(
-                        Q(orders_id=order['orderID']) & ~Q(use_status=2))
-                    if ai_service_qs.exists():
-                        data['user_status'] = 1
-                    else:
-                        data['user_status'] = 2
+                # elif order['order_type'] == 1:  # ai
+                #     ai_service_qs = AiService.objects.filter(
+                #         Q(orders_id=order['orderID']) & ~Q(use_status=2))
+                #     if ai_service_qs.exists():
+                #         data['user_status'] = 1
+                #     else:
+                #         data['user_status'] = 2
                 elif order['order_type'] == 2:  # 联通4G
                     unicom_combor_order_qs = UnicomComboOrderInfo.objects.filter(
                         Q(order_id=order['orderID']) & ~Q(status=2))
@@ -980,6 +980,7 @@ class serveManagement(View):
                 eq.delete()
                 Order_Model.objects.filter(uid_bucket_id=bid).delete()
                 ubq.delete()
+                AiService.objects.filter(uid=ubq[0].uid).delete()
                 return response.json(0)
             else:
                 return response.json(10007)

+ 272 - 40
Controller/CloudStorage.py

@@ -21,17 +21,19 @@ from django.http import JsonResponse, HttpResponseRedirect, HttpResponse
 from django.views.generic.base import View
 
 from Ansjer.config import SERVER_DOMAIN, PAYPAL_CRD, SERVER_DOMAIN_SSL, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, \
-    AWS_ARN, OAUTH_ACCESS_TOKEN_SECRET
+    AWS_ARN, OAUTH_ACCESS_TOKEN_SECRET, DETECT_PUSH_DOMAINS
 from Controller.CheckUserData import DataValid
 from Controller.CloudPhoto.CloudServiceController import CloudServiceController
 from Controller.PaymentCycle import Paypal
 from Model.models import Device_Info, Order_Model, Store_Meal, VodHlsModel, UID_Bucket, StsCrdModel, \
     ExperienceContextModel, Pay_Type, CDKcontextModel, Device_User, SysMsgModel, Unused_Uid_Meal, PromotionRuleModel, \
-    VideoPlaybackTimeModel, CouponModel, VodBucketModel, VodHlsSummary, VodHlsTagType
+    VideoPlaybackTimeModel, CouponModel, VodBucketModel, VodHlsSummary, AiService, UidSetModel, UidPushModel, \
+    VodHlsTagType
 from Object.AWS.AmazonS3Util import AmazonS3Util
 from Object.AWS.S3Email import S3Email
 from Object.AliPayObject import AliPayObject
 from Object.AliSmsObject import AliSmsObject
+from Object.ETkObject import ETkObject
 from Object.RedisObject import RedisObject
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
@@ -96,6 +98,8 @@ class CloudStorageView(View):
                 return self.do_create_pay_order(request_dict, user_id, ip, response)
             elif operation == 'changevodstatus':  # 修改云存状态,传送两个url,即getsignsts接口和storeplaylist接口
                 return self.do_change_vod_status(request_dict, user_id, response)
+            elif operation == 'changevodaistatus':  # 修改云存AI状态
+                return self.do_change_vod_ai_status(request_dict, user_id, response)
             elif operation == 'queryvodlist':  # 获取视频播放列表
                 return self.do_query_vod_list(request_dict, user_id, response)
             elif operation == 'commoditylist':  # 查询套餐列表
@@ -187,7 +191,10 @@ class CloudStorageView(View):
         device_info_qs = Device_Info.objects.filter(Q(UID=uid), Q(Type__lte=4) | Q(Type=10001))
         if device_info_qs.exists():
             return response.json(0)
-
+        uid_set_qs = UidSetModel.objects.filter(uid=uid).values('is_ai')
+        if not uid_set_qs.exists():
+            return response.json(173)
+        is_ai = uid_set_qs[0]['is_ai']
         store_qs = Store_Meal.objects.filter(Q(lang__lang=lang), Q(is_show=0), ~Q(pay_type='11'))  # 过滤激活码、隐藏套餐
         experience_context_qs = ExperienceContextModel.objects.filter(uid=uid, experience_type=0)
 
@@ -199,11 +206,15 @@ class CloudStorageView(View):
             store_qs = store_qs.filter(~Q(pay_type='10'))
         else:
             store_qs = store_qs.filter(pay_type='10')
+        if is_ai != 2:  # 返回支持AI的套餐
+            store_qs = store_qs.filter(is_ai=1)
+        else:  # 返回不支持AI的套餐
+            store_qs = store_qs.filter(is_ai=0)
 
         store_qs = store_qs.annotate(title=F('lang__title'), content=F('lang__content'),
                                      discount_content=F('lang__discount_content'))
         store_qs = store_qs.order_by('sort').values("id", "title", "content", "price", "day", "currency",
-                                                    "bucket__storeDay",
+                                                    "bucket__storeDay", 'is_beta', 'is_ai',
                                                     "bucket__bucket", "bucket__area", "commodity_code",
                                                     "commodity_type", "is_discounts", "virtual_price", "expire",
                                                     "discount_price", "discount_content", "symbol", "cycle_config_id")
@@ -402,7 +413,7 @@ class CloudStorageView(View):
                         "Effect": "Allow",
                         "Action": "s3:*",
                         "Resource": ["{aws_arn}:::{bucket_name}/{uid_channel}*".
-                                         format(aws_arn=aws_arn, bucket_name=bucket_name, uid_channel=storage)]
+                                     format(aws_arn=aws_arn, bucket_name=bucket_name, uid_channel=storage)]
                     }
                 ]
             }
@@ -694,6 +705,151 @@ class CloudStorageView(View):
         store_hls_url = '{}cloudstorage/storeplaylist?uidToken={}'.format(urls, uid_obj.token)
         return response.json(0, {'uidTkUrl': uid_tk_url, 'storeHlsUrl': store_hls_url})
 
+    @staticmethod
+    def do_change_vod_ai_status(request_dict, user_id, response):  # 修改云存状态
+        """
+        修改云存状态
+        @param request_dict: 请求数据
+        @param user_id: 用户id
+        @request_dict uid: uid
+        @request_dict status: 套餐状态
+        @request_dict channel: 通道
+        @param response: 响应
+        @return: response
+        """
+        uid = request_dict.get('uid', None)
+        vod_status = request_dict.get('vod_status', None)
+        channel = request_dict.get('channel', None)
+        domain_name = request_dict.get('domain_name', None)
+        token_val = request_dict.get('token_val', None)
+        appBundleId = request_dict.get('appBundleId', None)
+        app_type = request_dict.get('app_type', None)
+        push_type = request_dict.get('push_type', None)
+        ai_status = request_dict.get('ai_status', None)
+        m_code = request_dict.get('m_code', None)
+        lang = request_dict.get('lang', 'en')
+        tz = request_dict.get('tz', '0')
+        detect_group = request_dict.get('detect_group', None)
+        interval = request_dict.get('interval', None)
+        if not all([uid, vod_status, channel]):
+            return response.json(444, 'uid,vod_status,channel')
+        vod_status = int(vod_status)
+        device_info_qs = Device_Info.objects.filter(userID_id=user_id, UID=uid, isShare=False, isExist=1).values(
+            'vodPrimaryUserID', 'Type')
+        if not device_info_qs.exists() or device_info_qs[0]['vodPrimaryUserID'] != user_id:
+            return response.json(12)
+        uid_set_qs = UidSetModel.objects.filter(uid=uid)
+        if not uid_set_qs.exists():
+            return response.json(12)
+        uid_bucket_qs = UID_Bucket.objects.filter(channel=channel, uid=uid)
+        if not uid_bucket_qs.exists():
+            return response.json(10030)
+        now_time = int(time.time())
+        end_time = uid_bucket_qs[0].endTime
+        if now_time > end_time:
+            return response.json(10031)
+        try:
+            with transaction.atomic():
+                uid_bucket_qs.update(status=vod_status)
+                if vod_status == 0:
+                    ai_status = '0'
+                    if uid_set_qs[0].is_ai == 2:
+                        return response.json(0)
+                uid_obj = UidTokenObject()
+                uid_obj.generate(data={'uid': uid, 'channel': channel})
+
+                # 欧洲域名固定返回欧洲域名
+                urls = SERVER_DOMAIN_SSL
+                if domain_name in ['api.zositeche.com', 'api.loocam3.com', 'common.neutral3.com']:
+                    urls = 'https://api.zositeche.com/'
+                uid_tk_url = '{}cloudstorage/getsignsts?uidToken={}'.format(urls, uid_obj.token)
+                store_hls_url = '{}cloudstorage/storeplaylist?uidToken={}'.format(urls, uid_obj.token)
+                if uid_set_qs[0].is_ai != 2:
+                    if not all([appBundleId, app_type, token_val, uid, m_code, ai_status]):
+                        return response.json(444, 'appBundleId, app_type, token_val, uid,m_code, ai_status')
+
+                    # 如果传空上来,就默认为0
+                    tz = '0' if tz == '' else tz.replace('GMT', '')
+                    ai_status = int(ai_status)
+                    ai_service_qs = AiService.objects.filter(uid=uid, use_status=1)
+                    if not ai_service_qs.exists():
+                        return response.json(10053)
+
+                    uid_set_id = uid_set_qs[0].id
+                    interval = uid_set_qs[0].new_detect_interval if not interval else interval
+                    qs_data = {
+                        'updTime': now_time,
+                    }
+                    if interval:
+                        qs_data['detect_interval'] = int(interval)
+                        qs_data['detect_group'] = detect_group if detect_group else ''
+                    uid_set_qs.update(**qs_data)
+
+                    qs_data['detect_status'] = ai_status  # ai开关状态
+                    qs_data['endTime'] = end_time
+                    ai_service_qs.update(**qs_data)
+                    thing_name = CommonService.query_serial_with_uid(uid)  # 存在序列号则为使用序列号作为物品名
+                    topic_name = 'ansjer/generic/{}'.format(thing_name)
+
+                    if ai_status == 0:  # 关闭
+                        # mqtt通知设备关闭AI识别功能
+                        msg = {'commandType': 'AIDisable'}
+                        req_success = CommonService.req_publish_mqtt_msg(thing_name, topic_name, msg)
+                        if not req_success:
+                            return response.json(10044)
+                        if vod_status == 0:
+                            return response.json(0)
+                        return response.json(0, {'uidTkUrl': uid_tk_url, 'storeHlsUrl': store_hls_url})
+                    elif ai_status == 1:  # 开启
+                        # 更新或创建uid_push数据
+                        uid_push_qs = UidPushModel.objects.filter(userID_id=user_id, m_code=m_code, uid_set__uid=uid)
+                        uid_push_data = {
+                            'appBundleId': appBundleId,
+                            'app_type': app_type,
+                            'push_type': push_type,
+                            'token_val': token_val,
+                            'updTime': now_time,
+                            'lang': lang,
+                            'tz': tz
+                        }
+
+                        if uid_push_qs.exists():
+                            uid_push_qs.update(**uid_push_data)
+                        else:
+                            uid_push_data['uid_set_id'] = uid_set_id
+                            uid_push_data['userID_id'] = user_id
+                            uid_push_data['m_code'] = m_code
+                            uid_push_data['addTime'] = now_time
+                            UidPushModel.objects.create(**uid_push_data)
+
+                        etkObj = ETkObject(etk='')
+                        etk = etkObj.encrypt(uid)
+
+                        # mqtt通知设备开启AI识别功能
+                        push_url = DETECT_PUSH_DOMAINS
+                        # 欧洲域名固定返回欧洲域名
+                        if domain_name in ['api.zositeche.com', 'api.loocam3.com', 'common.neutral3.com']:
+                            push_url = 'https://push.zositeche.com/'
+                        aiIdentificationUrl = '{}AiService/identification'.format(push_url)
+                        msg = {
+                            'commandType': 'AIEnable',
+                            'payload': {
+                                'etk': etk,
+                                'endTime': end_time,
+                                'aiIdentificationUrl': aiIdentificationUrl,
+                            }
+                        }
+                        req_success = CommonService.req_publish_mqtt_msg(thing_name, topic_name, msg)
+                        if not req_success:
+                            return response.json(10044)
+                        return response.json(0, {'uidTkUrl': uid_tk_url, 'storeHlsUrl': store_hls_url,
+                                                 'aiIdentificationUrl': aiIdentificationUrl, 'endTime': end_time, 'etk': etk})
+
+                return response.json(0, {'uidTkUrl': uid_tk_url, 'storeHlsUrl': store_hls_url})
+        except Exception as e:
+            return response.json(500, repr(e))
+
+
     @staticmethod
     def do_pay_error():
         response = HttpResponse()
@@ -760,7 +916,8 @@ class CloudStorageView(View):
                 channel = order_list[0]['channel']
                 rank = order_list[0]['rank']
 
-                store_qs = Store_Meal.objects.filter(id=rank).values("day", "bucket_id", "bucket__storeDay", "expire")
+                store_qs = Store_Meal.objects.filter(id=rank).values("day", "bucket_id", "bucket__storeDay", "expire",
+                                                                     'is_ai')
                 bucket_id = store_qs[0]['bucket_id']
                 if not store_qs.exists():
                     return response.json(173)
@@ -819,6 +976,22 @@ class CloudStorageView(View):
                     order_qs.update(status=1, updTime=now_time, uid_bucket_id=uid_bucket_id,
                                     promotion_rule_id=promotion_rule_id)
                     date_time = time.strftime("%Y-%m-%d", time.localtime())
+                    # 开通AI服务
+                    if store_qs[0]['is_ai']:
+                        ai_service_qs = AiService.objects.filter(uid=uid, channel=channel)
+                        if ai_service_qs.exists():  # 有正在使用的套餐,套餐结束时间保存为套餐有效期
+                            ai_service_qs.update(endTime=end_time, use_status=1, updTime=now_time)
+                        else:
+                            ai_service_dict = {
+                                'uid': uid,
+                                'channel': channel,
+                                'detect_status': 1,
+                                'addTime': now_time,
+                                'updTime': now_time,
+                                'use_status': 1,
+                                'endTime': end_time
+                            }
+                            AiService.objects.create(**ai_service_dict)
                     # 如果存在序列号,消息提示用序列号
                     device_info_qs = Device_Info.objects.filter(UID=uid).values('serial_number', 'Type')
                     serial_number = device_info_qs[0]['serial_number']
@@ -914,7 +1087,8 @@ class CloudStorageView(View):
             uid = order_list[0]['UID']
             channel = order_list[0]['channel']
             rank = order_list[0]['rank']
-            store_qs = Store_Meal.objects.filter(id=rank).values("day", "bucket_id", "bucket__storeDay", "expire")
+            store_qs = Store_Meal.objects.filter(id=rank).values("day", "bucket_id", "bucket__storeDay", "expire",
+                                                                 'is_ai')
             bucket_id = store_qs[0]['bucket_id']
             if not store_qs.exists():
                 return response.json(173)
@@ -973,6 +1147,22 @@ class CloudStorageView(View):
                 order_qs.update(status=1, updTime=now_time, uid_bucket_id=uid_bucket_id,
                                 promotion_rule_id=promotion_rule_id)
                 date_time = time.strftime("%Y-%m-%d", time.localtime())
+                # 开通AI服务
+                if store_qs[0]['is_ai']:
+                    ai_service_qs = AiService.objects.filter(uid=uid, channel=channel)
+                    if ai_service_qs.exists():  # 有正在使用的套餐,套餐结束时间保存为套餐有效期
+                        ai_service_qs.update(endTime=end_time, use_status=1, updTime=now_time)
+                    else:
+                        ai_service_dict = {
+                            'uid': uid,
+                            'channel': channel,
+                            'detect_status': 1,
+                            'addTime': now_time,
+                            'updTime': now_time,
+                            'use_status': 1,
+                            'endTime': end_time
+                        }
+                        AiService.objects.create(**ai_service_dict)
                 # 如果存在序列号,消息提示用序列号
                 device_info_qs = Device_Info.objects.filter(UID=uid).values('serial_number', 'Type')
                 serial_number = device_info_qs[0]['serial_number']
@@ -1050,7 +1240,8 @@ class CloudStorageView(View):
                 uid = order_list[0]['UID']
                 channel = order_list[0]['channel']
                 rank = order_list[0]['rank']
-                store_qs = Store_Meal.objects.filter(id=rank).values("day", "bucket_id", "bucket__storeDay", "expire")
+                store_qs = Store_Meal.objects.filter(id=rank).values("day", "bucket_id", "bucket__storeDay", "expire",
+                                                                     'is_ai')
                 bucket_id = store_qs[0]['bucket_id']
                 if not store_qs.exists():
                     return HttpResponse(pay.xml_to_dict({'return_code': 'FAIL', 'return_msg': '套餐不存在'}))
@@ -1109,6 +1300,22 @@ class CloudStorageView(View):
                     order_qs.update(status=1, updTime=now_time, uid_bucket_id=uid_bucket_id,
                                     promotion_rule_id=promotion_rule_id)
                     date_time = time.strftime("%Y-%m-%d", time.localtime())
+                    # 开通AI服务
+                    if store_qs[0]['is_ai']:
+                        ai_service_qs = AiService.objects.filter(uid=uid, channel=channel)
+                        if ai_service_qs.exists():  # 有正在使用的套餐,套餐结束时间保存为套餐有效期
+                            ai_service_qs.update(endTime=end_time, use_status=1, updTime=now_time)
+                        else:
+                            ai_service_dict = {
+                                'uid': uid,
+                                'channel': channel,
+                                'detect_status': 1,
+                                'addTime': now_time,
+                                'updTime': now_time,
+                                'use_status': 1,
+                                'endTime': end_time
+                            }
+                            AiService.objects.create(**ai_service_dict)
                     # 如果存在序列号,消息提示用序列号
                     device_info_qs = Device_Info.objects.filter(UID=uid).values('serial_number', 'Type')
                     serial_number = device_info_qs[0]['serial_number']
@@ -1181,7 +1388,7 @@ class CloudStorageView(View):
         now_time = int(time.time())
         store_qs = Store_Meal.objects.filter(id=rank, pay_type=pay_type, lang__lang=lang, is_show=0). \
             values('currency', 'price', 'lang__content', 'day', 'commodity_type', 'lang__title', 'expire',
-                   'commodity_code', 'discount_price', 'bucket__mold', 'cycle_config_id')
+                   'commodity_code', 'discount_price', 'bucket__mold', 'cycle_config_id', 'is_ai')
         if not store_qs.exists():
             return response.json(173)
         store_meal_qs = Store_Meal.objects.filter(id=rank, lang__lang='cn', is_show=0).values('lang__title',
@@ -1234,14 +1441,17 @@ class CloudStorageView(View):
                 sub_info = Paypal.subscriptions(store_info=store_qs[0], lang=lang, orderID=order_id, price=price)
                 if not sub_info:
                     return response.json(10048)
-                Order_Model.objects.create(orderID=order_id, UID=uid, channel=channel, userID_id=user_id,
-                                           desc=content, payType=pay_type, payTime=now_time,
-                                           price=price, currency=currency, addTime=now_time, updTime=now_time,
-                                           pay_url=sub_info['url'], isSelectDiscounts=is_select_discount,
-                                           commodity_code=commodity_code, commodity_type=commodity_type,
-                                           rank_id=rank, plan_id=sub_info['plan_id'], coupon_id=coupon_id, ai_rank_id=1,
-                                           store_meal_name=store_meal_name)
-
+                order_qs = Order_Model.objects.create(orderID=order_id, UID=uid, channel=channel, userID_id=user_id,
+                                                      desc=content, payType=pay_type, payTime=now_time,
+                                                      price=price, currency=currency, addTime=now_time,
+                                                      updTime=now_time,
+                                                      pay_url=sub_info['url'], isSelectDiscounts=is_select_discount,
+                                                      commodity_code=commodity_code, commodity_type=commodity_type,
+                                                      rank_id=rank, plan_id=sub_info['plan_id'], coupon_id=coupon_id,
+                                                      ai_rank_id=1,
+                                                      store_meal_name=store_meal_name)
+                if store_qs[0]['is_ai'] == 1:
+                    order_qs.order_type = 1
                 return response.json(0, {"redirectUrl": sub_info['url'], "orderID": order_id})
             # 正常扣款
             call_clc_url = "{}web/paid2/fail.html".format(SERVER_DOMAIN_SSL)
@@ -1268,13 +1478,17 @@ class CloudStorageView(View):
             for link in payment.links:
                 if link.rel == "approval_url":
                     approval_url = str(link.href)
-                    Order_Model.objects.create(orderID=order_id, UID=uid, channel=channel, userID_id=user_id,
-                                               desc=content, payType=pay_type, payTime=now_time,
-                                               price=price, currency=currency, addTime=now_time, updTime=now_time,
-                                               pay_url=approval_url, isSelectDiscounts=is_select_discount,
-                                               commodity_code=commodity_code, commodity_type=commodity_type,
-                                               rank_id=rank, paymentID=payment_id, coupon_id=coupon_id, ai_rank_id=1,
-                                               store_meal_name=store_meal_name)
+                    order_qs = Order_Model.objects.create(orderID=order_id, UID=uid, channel=channel, userID_id=user_id,
+                                                          desc=content, payType=pay_type, payTime=now_time,
+                                                          price=price, currency=currency, addTime=now_time,
+                                                          updTime=now_time,
+                                                          pay_url=approval_url, isSelectDiscounts=is_select_discount,
+                                                          commodity_code=commodity_code, commodity_type=commodity_type,
+                                                          rank_id=rank, paymentID=payment_id, coupon_id=coupon_id,
+                                                          ai_rank_id=1,
+                                                          store_meal_name=store_meal_name)
+                    if store_qs[0]['is_ai'] == 1:
+                        order_qs.order_type = 1
                     return response.json(0, {"redirectUrl": approval_url, "orderID": order_id})
             return response.json(10, 'generate_order_false')
         elif pay_type == 2:
@@ -1298,14 +1512,16 @@ class CloudStorageView(View):
             else:
                 if order_string:
                     redirect_url = ali_pay_obj.alipay_prefix + order_string
-                    Order_Model.objects.create(orderID=order_id, UID=uid, channel=channel, userID_id=user_id,
-                                               desc=content, payType=pay_type, payTime=now_time,
-                                               price=price, currency=currency, addTime=now_time, updTime=now_time,
-                                               pay_url=redirect_url, isSelectDiscounts=is_select_discount,
-                                               commodity_code=commodity_code, commodity_type=commodity_type,
-                                               rank_id=rank, coupon_id=coupon_id, ai_rank_id=1,
-                                               store_meal_name=store_meal_name)
-
+                    order_qs = Order_Model.objects.create(orderID=order_id, UID=uid, channel=channel, userID_id=user_id,
+                                                          desc=content, payType=pay_type, payTime=now_time,
+                                                          price=price, currency=currency, addTime=now_time,
+                                                          updTime=now_time,
+                                                          pay_url=redirect_url, isSelectDiscounts=is_select_discount,
+                                                          commodity_code=commodity_code, commodity_type=commodity_type,
+                                                          rank_id=rank, coupon_id=coupon_id, ai_rank_id=1,
+                                                          store_meal_name=store_meal_name)
+                    if store_qs[0]['is_ai'] == 1:
+                        order_qs.order_type = 1
                     return JsonResponse(status=200, data={'result_code': 0, 'reason': 'success',
                                                           'result': {"redirectUrl": redirect_url, "orderID": order_id},
                                                           'error_code': 0})
@@ -1326,12 +1542,15 @@ class CloudStorageView(View):
             if not response:
                 return response.json(10, '生成订单错误.')
             # 回调函数
-            Order_Model.objects.create(orderID=order_id, UID=uid, channel=channel, userID_id=user_id,
-                                       desc=content, payType=pay_type, payTime=now_time,
-                                       price=price, currency=currency, addTime=now_time, updTime=now_time,
-                                       pay_url=notify_url, isSelectDiscounts=is_select_discount,
-                                       commodity_code=commodity_code, commodity_type=commodity_type, rank_id=rank,
-                                       ai_rank_id=1, store_meal_name=store_meal_name)
+            order_qs = Order_Model.objects.create(orderID=order_id, UID=uid, channel=channel, userID_id=user_id,
+                                                  desc=content, payType=pay_type, payTime=now_time,
+                                                  price=price, currency=currency, addTime=now_time, updTime=now_time,
+                                                  pay_url=notify_url, isSelectDiscounts=is_select_discount,
+                                                  commodity_code=commodity_code, commodity_type=commodity_type,
+                                                  rank_id=rank,
+                                                  ai_rank_id=1, store_meal_name=store_meal_name)
+            if store_qs[0]['is_ai'] == 1:
+                order_qs.order_type = 1
             return JsonResponse(status=200, data={'result_code': 0, 'reason': 'success',
                                                   'result': response,
                                                   'orderId': order_id,
@@ -1402,7 +1621,8 @@ class CloudStorageView(View):
 
         order_id = CommonService.createOrderID()
         now_time = int(time.time())
-        store_qs = Store_Meal.objects.filter(id=rank, lang__lang=lang, is_show=0).values("day", "bucket_id",
+        order_type = 0
+        store_qs = Store_Meal.objects.filter(id=rank, lang__lang=lang, is_show=0).values("day", "bucket_id", 'is_ai',
                                                                                          "bucket__storeDay", "expire",
                                                                                          'lang__content', 'price',
                                                                                          'currency', 'commodity_type')
@@ -1437,6 +1657,14 @@ class CloudStorageView(View):
                                                            endTime=end_time, addTime=now_time, updateTime=now_time,
                                                            use_status=1)
                     uid_bucket_id = uid_bucket.id
+                if store_qs[0]['is_ai']:
+                    order_type = 1
+                    ai_service_qs = AiService.objects.filter(uid=uid, channel=channel)
+                    if ai_service_qs.exists():
+                        ai_service_qs.update(endTime=end_time, use_status=1, updTime=now_time)
+                    else:
+                        AiService.objects.create(uid=uid, channel=channel, detect_status=1, endTime=end_time,
+                                                 addTime=now_time, updTime=now_time, use_status=1)
                 store_meal_qs = Store_Meal.objects.filter(id=rank, lang__lang='cn', is_show=0).values('lang__title',
                                                                                                       'lang__content')
                 if store_meal_qs.exists():
@@ -1446,7 +1674,7 @@ class CloudStorageView(View):
                 Order_Model.objects.create(orderID=order_id, UID=uid, channel=channel, userID_id=user_id,
                                            desc=store_qs[0]['lang__content'], payType=pay_type, payTime=now_time,
                                            price=store_qs[0]['price'], currency=store_qs[0]['currency'],
-                                           addTime=now_time,
+                                           addTime=now_time, order_type=order_type,
                                            updTime=now_time,
                                            pay_url="体验版", store_meal_name=store_meal_name,
                                            commodity_code=commodity_code, commodity_type=store_qs[0]['commodity_type'],
@@ -1529,6 +1757,7 @@ class CloudStorageView(View):
                 experience_context_qs.delete()
                 Order_Model.objects.filter(uid_bucket_id=bucket_id).delete()
                 uid_bucket_qs.delete()
+                AiService.objects.filter(uid=uid_bucket_qs[0].uid).delete()
             else:
                 return response.json(10007)
         else:
@@ -1689,6 +1918,9 @@ class CloudStorageView(View):
                 Unused_Uid_Meal.objects.filter(id=unused_id).delete()
                 StsCrdModel.objects.filter(uid=uid).delete()  # 删除sts记录
                 # VodHlsModel.objects.filter(uid=uid).delete()  # 删除播放列表,后期数据量多时应该考虑延后删除
+                AiService.objects.filter(uid=uid, channel=unused_uid_bucket['channel']).update(endTime=end_time,
+                                                                                               updTime=now_time,
+                                                                                               use_status=1)
                 return response.json(0)
         except Exception:
             return response.json(474)

+ 19 - 3
Controller/CloudVod.py

@@ -15,7 +15,7 @@ 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
 from Model.models import Device_Info, Order_Model, Store_Meal, OssCrdModel, UID_Bucket, StsCrdModel, \
-    VodBucketModel
+    VodBucketModel, UidSetModel, AiService
 from Object.AliPayObject import AliPayObject
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
@@ -82,11 +82,27 @@ class CloudVodView(View):
         dvqs = Device_Info.objects.filter(UID=uid, isShare=False)
         if not dvqs.exists():
             return response.json(12)
+        uid_set_qs = UidSetModel.objects.filter(uid=uid).values('is_ai')
+        if not uid_set_qs.exists():
+            return response.json(12)
         ubqs = UID_Bucket.objects.filter(uid=uid). \
             values('bucket__content', 'status', 'channel', 'endTime', 'uid')
         res = []
-        if ubqs.exists():
-            res = list(ubqs)
+        for item in ubqs:
+            result = {
+                'bucket__content': item['bucket__content'],
+                'status': item['status'],
+                'channel': item['channel'],
+                'endTime': item['endTime'],
+                'uid': item['uid'],
+            }
+            if uid_set_qs[0]['is_ai'] != 2:
+                ai_server_qs = AiService.objects.filter(uid=uid, use_status=1).values('detect_status', 'detect_group')
+                if not ai_server_qs.exists():
+                    return response.json(12)
+                result['detect_status'] = ai_server_qs[0]['detect_status']
+                result['detect_group'] = ai_server_qs[0]['detect_group']
+            res.append(result)
         return response.json(0, res)
 
     def do_pay_error(self):

+ 3 - 0
Controller/Cron/CronTaskController.py

@@ -259,6 +259,7 @@ class CronUpdateDataView(View):
         expired_uid_bucket = expired_uid_bucket.filter(~Q(use_status=2)).values('id')
         if expired_uid_bucket.exists():
             expired_uid_bucket.update(use_status=2)
+        AiService.objects.filter(Q(endTime__lte=now_time), ~Q(use_status=2)).update(use_status=2)
         # 监控有未使用套餐则自动生效
         expired_uid_buckets = \
             UID_Bucket.objects.filter(endTime__lte=now_time, has_unused=1).values("id", "uid")[0:1000]
@@ -293,6 +294,8 @@ class CronUpdateDataView(View):
                     Unused_Uid_Meal.objects.filter(id=unused['id']).delete()
                     StsCrdModel.objects.filter(
                         uid=expired_uid_bucket['uid']).delete()  # 删除sts记录
+                    AiService.objects.filter(uid=expired_uid_bucket['uid'], channel=unused['channel']).update(
+                        use_status=1, endTime=endTime, updTime=now_time)
             except Exception as e:
                 print(repr(e))
                 continue

+ 53 - 15
Controller/PaymentCycle.py

@@ -14,10 +14,11 @@ from Ansjer.config import PAYPAL_CRD, SERVER_DOMAIN_SSL, PAYPAL_WEB_HOOK_ID, PAY
     CONFIG_US, CONFIG_EUR
 from Controller import CloudStorage
 from Model.models import PayCycleConfigModel, Store_Meal, UID_Bucket, PromotionRuleModel, \
-    Unused_Uid_Meal, Device_Info, CouponModel, Order_Model, PaypalWebHookEvent, CountryModel
+    Unused_Uid_Meal, Device_Info, CouponModel, Order_Model, PaypalWebHookEvent, CountryModel, AiService
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
 from Service.CommonService import CommonService
+
 PAY_LOGGER = logging.getLogger('pay')
 
 
@@ -179,7 +180,7 @@ class PaypalCycleNotify(View):
         agreement_id = billing_agreement_response.id
         order_qs = Order_Model.objects.filter(orderID=orderID, status=0)
         order_list = order_qs.values("UID", "channel", "commodity_code", "rank", "isSelectDiscounts",
-                                     "userID__userID",
+                                     "userID__userID", 'rank__is_ai',
                                      "userID__username", 'coupon_id')
         if not orderID:
             logger.info('----订阅订单号失效----')
@@ -254,6 +255,22 @@ class PaypalCycleNotify(View):
                         (uid=UID, channel=channel, bucket_id=bucketId, endTime=endTime, addTime=nowTime,
                          updateTime=nowTime, use_status=1)
                     uid_bucket_id = ub_cqs.id
+                # 开通AI服务
+                if order_list[0]['rank__is_ai']:
+                    ai_service_qs = AiService.objects.filter(uid=UID, channel=channel)
+                    if ai_service_qs.exists():  # 有正在使用的套餐,套餐结束时间保存为套餐有效期
+                        ai_service_qs.update(endTime=endTime, use_status=1, updTime=nowTime)
+                    else:
+                        ai_service_dict = {
+                            'uid': UID,
+                            'channel': channel,
+                            'detect_status': 1,
+                            'addTime': nowTime,
+                            'updTime': nowTime,
+                            'use_status': 1,
+                            'endTime': endTime
+                        }
+                        AiService.objects.create(**ai_service_dict)
 
                 dvq = Device_Info.objects.filter(UID=UID, vodPrimaryUserID='', vodPrimaryMaster='')
                 if dvq.exists():
@@ -372,7 +389,7 @@ class PaypalCycleNotify(View):
                     return HttpResponse('Fail', status=500)
             else:
                 PAY_LOGGER.info('PayPal周期扣款失败,付款状态有误,resource_type:{},state:{}----'.
-                            format(resource_type, paypal_body.get('state')))
+                                format(resource_type, paypal_body.get('state')))
                 return HttpResponse('Fail', status=500)
 
             nowTime = int(time.time())
@@ -398,7 +415,7 @@ class PaypalCycleNotify(View):
                     return HttpResponse('success')
                 else:
                     PAY_LOGGER.info('PayPal周期扣款失败---paymentID:{}或paypal_transaction_id:{}为空'.
-                                format(paymentID, paypal_transaction_id))
+                                    format(paymentID, paypal_transaction_id))
                     return HttpResponse('fail', status=500)
 
             agreement_id = paypal_body.get('billing_agreement_id')
@@ -450,14 +467,15 @@ class PaypalCycleNotify(View):
             username = order_qs[0]['userID__username']
             channel = order_qs[0]['channel']
             rank = order_qs[0]['rank']
-            store_meal_qs = Store_Meal.objects.filter(id=rank).values("day", "bucket_id", "bucket__storeDay", "expire")
+            store_meal_qs = Store_Meal.objects.filter(id=rank).values("day", "bucket_id", "bucket__storeDay", "expire",
+                                                                      "is_ai")
             if not store_meal_qs.exists():
                 PAY_LOGGER.info('{} PayPal周期扣款失败---套餐数据不存在'.format(UID))
                 return HttpResponse('fail', status=500)
 
             bucketId = store_meal_qs[0]['bucket_id']
             expire = store_meal_qs[0]['expire']
-
+            is_ai = store_meal_qs[0]['is_ai']
             ubqs = UID_Bucket.objects.filter(uid=UID).values("id", "bucket_id", "bucket__storeDay", "bucket__region",
                                                              "endTime", "use_status")
 
@@ -485,7 +503,22 @@ class PaypalCycleNotify(View):
                         (uid=UID, channel=channel, bucket_id=bucketId, endTime=endTime, addTime=nowTime,
                          updateTime=nowTime, use_status=1)
                     uid_bucket_id = ub_cqs.id
-
+                # 开通AI服务
+                if is_ai:
+                    ai_service_qs = AiService.objects.filter(uid=UID, channel=channel)
+                    if ai_service_qs.exists():  # 有正在使用的套餐,套餐结束时间保存为套餐有效期
+                        ai_service_qs.update(endTime=endTime, use_status=1, updTime=nowTime)
+                    else:
+                        ai_service_dict = {
+                            'uid': UID,
+                            'channel': channel,
+                            'detect_status': 1,
+                            'addTime': nowTime,
+                            'updTime': nowTime,
+                            'use_status': 1,
+                            'endTime': endTime
+                        }
+                        AiService.objects.create(**ai_service_dict)
                 dvq = Device_Info.objects.filter(UID=UID, vodPrimaryUserID='', vodPrimaryMaster='')
                 if dvq.exists():
                     dvq_set_update_dict = {
@@ -501,14 +534,19 @@ class PaypalCycleNotify(View):
                     store_meal_name = store_meal_qs[0]['lang__title'] + '-' + store_meal_qs[0]['lang__content']
                 else:
                     store_meal_name = '未知套餐'
-                Order_Model.objects.create(orderID=orderID, UID=UID, channel=channel, userID_id=userid,
-                                           desc=desc, payType=pay_type, payTime=nowTime, price=amount.get('total'),
-                                           currency=order_qs[0]['currency'], addTime=nowTime, updTime=nowTime,
-                                           pay_url='', isSelectDiscounts=0, commodity_code=commodity_code,
-                                           commodity_type=commodity_type, rank_id=rank, paymentID='',
-                                           coupon_id='', uid_bucket_id=uid_bucket_id, status=1,
-                                           agreement_id=agreement_id, store_meal_name=store_meal_name,
-                                           plan_id=plan_id, ai_rank_id=1, trade_no=paypal_transaction_id)
+                new_order_qs = Order_Model.objects.create(orderID=orderID, UID=UID, channel=channel, userID_id=userid,
+                                                          desc=desc, payType=pay_type, payTime=nowTime,
+                                                          price=amount.get('total'),
+                                                          currency=order_qs[0]['currency'], addTime=nowTime,
+                                                          updTime=nowTime,
+                                                          pay_url='', isSelectDiscounts=0,
+                                                          commodity_code=commodity_code,
+                                                          commodity_type=commodity_type, rank_id=rank, paymentID='',
+                                                          coupon_id='', uid_bucket_id=uid_bucket_id, status=1,
+                                                          agreement_id=agreement_id, store_meal_name=store_meal_name,
+                                                          plan_id=plan_id, ai_rank_id=1, trade_no=paypal_transaction_id)
+                if is_ai:
+                    new_order_qs.order_type = 1
                 # 如果存在序列号,消息提示用序列号
                 device_name = CommonService.query_serial_with_uid(uid=UID)
                 datetime = time.strftime("%Y-%m-%d", time.localtime())

+ 5 - 6
Model/models.py

@@ -754,9 +754,8 @@ class Store_Meal(models.Model):
     lang = models.ManyToManyField(to='Lang', verbose_name='套餐语言', db_table='store_meal_lang')
     cycle_config_id = models.IntegerField(null=True, verbose_name='周期付款配置表id')
     sort = models.IntegerField(default=99, blank=True, verbose_name=u'排序,越小越靠前')  # 单位月
-    # 备用字段
-    spare_3 = models.CharField(default='', blank=True, max_length=64, db_index=True, verbose_name=u'备用字段3')
-    spare_4 = models.CharField(default='', blank=True, max_length=64, db_index=True, verbose_name=u'备用字段4')
+    is_beta = models.SmallIntegerField(default=0, verbose_name=u'是否显示beta')  # 0: 否, 1: 是
+    is_ai = models.SmallIntegerField(default=0, verbose_name=u'是否支持AI')  # 0: 否, 1: 是
 
     def __str__(self):
         return self.id
@@ -933,7 +932,7 @@ class Order_Model(models.Model):
     rank = models.ForeignKey(Store_Meal, to_field='id', default='', on_delete=models.CASCADE, verbose_name='关联云存套餐表')
     ai_rank = models.ForeignKey(AiStoreMeal, to_field='id', default='', on_delete=models.CASCADE,
                                 verbose_name='关联ai套餐表')
-    order_type = models.SmallIntegerField(default=0, verbose_name='订单类型:0:云存,1:ai,2:联通4G')
+    order_type = models.SmallIntegerField(default=0, verbose_name='订单类型:0:云存,1:云存ai,2:联通4G')
     unify_combo_id = models.CharField(blank=True, default='', max_length=32, verbose_name=u'统一套餐id')
     nickname = models.CharField(default='', max_length=64, verbose_name='设备昵称')
     uid_bucket_id = models.IntegerField(default=0, verbose_name='关联uid_bucket的字段')
@@ -2494,8 +2493,8 @@ class AiService(models.Model):
     id = models.AutoField(primary_key=True, verbose_name=u'自增标记ID')
     uid = models.CharField(max_length=20, verbose_name='设备UID', db_index=True)
     channel = models.SmallIntegerField(default=0, verbose_name='通道')
-    orders = models.ForeignKey(Order_Model, to_field='orderID', default='', on_delete=models.CASCADE,
-                               verbose_name='关联订单表')
+    #orders = models.ForeignKey(Order_Model, to_field='orderID', default='', on_delete=models.CASCADE,
+    #                           verbose_name='关联订单表')
     detect_status = models.SmallIntegerField(default=0, verbose_name='状态')  # 0:关闭, 1:开启
     endTime = models.BigIntegerField(verbose_name='套餐结束时间', db_index=True, default=0)
     addTime = models.IntegerField(verbose_name='添加时间', default=0)