Beispiel #1
0
class GiftAdmin(ModelView):
    form = GiftForm
    can_view_details = True
    details_modal = True
    column_details_list = ('gift_id', 'product_id', 'credit_type', 'credit_value', 'on_sale')
    column_list = ('gift_id', 'product_id', 'credit_type', 'credit_value', 'on_sale')
    column_labels = dict(gift_id=u'礼物ID', product_id=u'物品', credit_type=u'价格类型',
                         credit_value=u'价格数值', on_sale=u'是否在售')
    column_formatters = dict(
        credit_type=lambda v, c, m, n: get_choices_desc(CREDIT_TYPE, m.credit_type),
        product_id=lambda v, c, m, n: get_choices_desc(Product.all_gifts_for_admin(),
                                                       m.product_id)
    )

    def create_form(self, obj=None):
        form = super(GiftAdmin, self).create_form(obj)
        form.product_id.choices = Product.all_gifts_for_admin()
        return form

    def edit_form(self, obj=None):
        form = super(GiftAdmin, self).edit_form(obj)
        form.product_id.choices = Product.all_gifts_for_admin()
        return form

    def after_model_change(self, form, model, is_created):
        super(GiftAdmin, self).after_model_change(form, model, is_created)
        Redis.delete(ONSALE_GIFT_KEY)

    def after_model_delete(self, model):
        super(GiftAdmin, self).after_model_delete(model)
        Redis.delete(ONSALE_GIFT_KEY)
Beispiel #2
0
def user_gifts_class():
    """获取用户所有礼物分类 (GET&LOGIN)

    :uri: /gifts/user_gifts_class
    :return: {'gifts': list}
    """
    requ_type = request.values['requ_type']
    user = request.authed_user
    pdict = {}
    for p in Product.get_all_gifts():
        pdict[p.product_id] = p.format()

    uproducts = UserProduct.get_user_products(str(user._id))
    from wanx.base.log import print_log
    print_log('activity/team_vote', '[uproducts]: {0}'.format(uproducts))
    for up in uproducts:
        if up.product_id not in pdict:
            continue
        pdict[up.product_id].update(up.format())

    if requ_type == 'get_pay_gifts':
        pay_gifts = []
        for gift in pdict.values():
            if gift['product_type'] == 3 and gift.get(
                    'is_money', '') and gift.get('num', 0) != 0:
                g = Gift.get_gift_by_product_id(gift['product_id'])
                if g:
                    gift['credit_value'] = float(g.credit_value) / float(100)

                    pay_gifts.append(gift)

        cfg = GiftExchangeCfg.get_gift_config()
        is_exchange_time = GiftExchangeCfg.is_exchange_time()  # 是否在兑换时间内

        total_credit_value = UserProduct.get_current_money(pay_gifts)
        return {
            'gifts': pay_gifts,
            'total_credit_value': total_credit_value,
            'is_exchange_time': is_exchange_time,
            'gifts_config': cfg.format()
        }

    elif requ_type == 'get_gold_gifts':
        gold_gifts = []
        from wanx.base.log import print_log
        print_log('activity/team_vote', '[pdict]: {0}'.format(pdict))
        for gift in pdict.values():
            if gift['product_type'] == 3 and not gift.get(
                    'is_money', '') and gift.get('num', 0) != 0:
                g = Gift.get_gift_by_product_id(gift['product_id'])
                if g:
                    if int(g.gift_id) == 1:
                        gift['credit_value'] = 0
                    else:
                        gift['credit_value'] = g.credit_value

                    gold_gifts.append(gift)

        total_gold_value = UserProduct.get_current_gold(gold_gifts)
        return {'gifts': gold_gifts, 'total_credit_value': total_gold_value}
Beispiel #3
0
class WatchLiveTaskItemAdmin(WxModelView):
    Model = WatchLiveTaskItem
    form = WatchLiveTaskItemForm
    can_view_details = True
    details_modal = True
    column_details_list = ('wlt_id', 'product_id', 'product_num', 'title',  'identity')
    column_labels = dict(wlt_id=u'观看直播时长任务ID', product_id=u'物品', product_num=u'物品数量', title=u'商品描述',
                         identity=u'营销平台奖项ID')
    column_formatters = dict(
        wlt_id=lambda v, c, m, n: format_model(m, n, WatchLiveTask),
        product_id=lambda v, c, m, n: get_choices_desc(Product.all_products_for_admin(), m[n]),
    )

    def create_form(self, obj=None):
        form = super(WatchLiveTaskItemAdmin, self).create_form(obj)
        form.wlt_id.choices = WatchLiveTask.all_tasks_for_admin()
        form.product_id.choices = Product.all_products_for_admin()
        return form

    def edit_form(self, obj=None):
        form = super(WatchLiveTaskItemAdmin, self).edit_form(obj)
        form.wlt_id.choices = WatchLiveTask.all_tasks_for_admin()
        form.product_id.choices = Product.all_products_for_admin()
        return form

    def after_model_change(self, form, model, is_created):
        super(WatchLiveTaskItemAdmin, self).after_model_change(form, model, is_created)
        self.Model.clear_redis(form.wlt_id.data)
        self.Model.clear_redis(model['wlt_id'])

    def after_model_delete(self, model):
        super(WatchLiveTaskItemAdmin, self).after_model_delete(model)
        self.Model.clear_redis(model['wlt_id'])
Beispiel #4
0
 def create_form(self, obj=None):
     form = super(TaskAdmin, self).create_form(obj)
     form.product_id.choices = Product.all_products_for_admin()
     # aids = [('', u'不限定')]
     # aids.extend(ActivityConfig.activity())
     # form.activity_id.choices = aids
     return form
Beispiel #5
0
 def edit_form(self, obj=None):
     form = super(TaskAdmin, self).edit_form(obj)
     form.product_id.choices = Product.all_products_for_admin()
     # aids = [('', u'不限定')]
     # aids.extend(ActivityConfig.activity())
     # form.activity_id.choices = aids
     form.task_type.choices = filter(lambda x:x[0] == obj.task_type, TASK_TYPE)
     return form
Beispiel #6
0
class TaskAdmin(ModelView):
    form = TaskForm
    can_view_details = True
    details_modal = True
    column_details_list = ('title', 'description', 'image', 'task_type', 'action', 'activity_id',
                           'task_platform', 'game_id', 'num', 'product_id', 'product_num')
    column_list = ('title', 'description', 'image', 'task_type', 'action', 'task_platform', 'num',
                   'product_id', 'product_num')
    column_labels = dict(title=u'标题', description=u'描述', image=u'图片', task_type=u'任务类型',
                         action=u'任务条件', game_id=u'游戏ID', num=u'条件数值', product_id=u'奖励物品',
                         product_num=u'奖励物品数量', task_platform=u'任务平台', activity_id=u'活动ID')
    column_formatters = dict(
        image=format_image,
        task_type=lambda v, c, m, n: get_choices_desc(TASK_TYPE, m.task_type),
        action=lambda v, c, m, n: get_choices_desc(TASK_ACTION, m.action),
        game_id=format_game,
        product_id=lambda v, c, m, n: get_choices_desc(Product.all_products_for_admin(),
                                                       m.product_id),
        task_platform=lambda v, c, m, n: get_choices_desc(TASK_PLATFORMS, m.task_platform),
    )

    def create_form(self, obj=None):
        form = super(TaskAdmin, self).create_form(obj)
        form.product_id.choices = Product.all_products_for_admin()
        # aids = [('', u'不限定')]
        # aids.extend(ActivityConfig.activity())
        # form.activity_id.choices = aids
        return form

    def edit_form(self, obj=None):
        form = super(TaskAdmin, self).edit_form(obj)
        form.product_id.choices = Product.all_products_for_admin()
        # aids = [('', u'不限定')]
        # aids.extend(ActivityConfig.activity())
        # form.activity_id.choices = aids
        form.task_type.choices = filter(lambda x:x[0] == obj.task_type, TASK_TYPE)
        return form

    def after_model_change(self, form, model, is_created):
        super(TaskAdmin, self).after_model_change(form, model, is_created)
        Redis.delete(TASK_KEY)

    def after_model_delete(self, model):
        super(TaskAdmin, self).after_model_delete(model)
        UserTask.delete().where(UserTask.task_id==model.task_id).execute()
        Redis.delete(TASK_KEY)

    def create_model(self, form):
        if form.topest.data:
            Task.reset_topest_task()
        return super(TaskAdmin, self).create_model(form)

    def update_model(self, form, model):
        if form.topest.data:
            Task.reset_topest_task()
        return super(TaskAdmin, self).update_model(form, model)
Beispiel #7
0
 def format(self):
     data = model_to_dict(self)
     if self.credit_type == const.MONEY and data.get("per_piece_limit"):
         data['per_piece_id'] = {
             int(k_v.split(":")[0]): k_v.split(":")[1]
             for k_v in self.per_piece_limit.split(",") if k_v
         }
     product = Product.get_product(self.product_id)
     if product:
         data.update(product.format())
     return data
Beispiel #8
0
 def format(self):
     product = Product.get_product(self.product_id)
     data = {
         'item_id': self.item_id,
         'title': self.title,
         'credit_type': self.credit_type,
         'credit_value': self.credit_value,
         'product': product.format(),
         'product_num': self.product_num,
         'left_num': self.left_num,
         'use_num': self.use_num
     }
     return data
Beispiel #9
0
class UserOrderAdmin(ModelView):
    form = UserOrderForm
    can_create = False
    can_delete = False
    can_view_details = True
    details_modal = True
    column_details_list = ('order_id', 'user_id', 'item_id', 'store_id', 'store_type',
                           'campaign_id', 'title', 'product_id', 'product_num', 'status',
                           'result', 'recid', 'create_at')
    column_list = ('order_id', 'user_id', 'title', 'product_num', 'store_id', 'status')
    column_labels = dict(order_id=u'订单ID', user_id=u'用户', item_id=u'商品', store_id=u'商店',
                         store_type=u'商店类型', campaign_id=u'营销平台活动ID', title=u'商品描述',
                         product_id=u'物品', product_num=u'物品数量', status=u'状态',
                         result=u'抽奖结果', recid=u'营销平台兑换订单', create_at=u'创建时间')
    column_formatters = dict(
        store_id=lambda v, c, m, n: get_choices_desc(store.Store.all_stores_for_admin(),
                                                     m.store_id),
        product_id=lambda v, c, m, n: get_choices_desc(Product.all_products_for_admin(),
                                                       m.product_id),
        store_type=lambda v, c, m, n: get_choices_desc(store.STORE_TYPE, m.store_type),
        status=lambda v, c, m, n: get_choices_desc(store.STATUS, m.status),
        user_id=format_user
    )
    column_filters = (
        'user_id',
        PeeweeEqualFilter(
            column=store.UserOrder.store_id, name='商店',
            options=store.Store.all_stores_for_admin()
        ),
        PeeweeEqualFilter(
            column=store.UserOrder.status, name='订单状态',
            options=store.STATUS
        ),
        PeeweeEqualFilter(
            column=store.UserOrder.product_id, name='物品',
            options=Product.all_products_for_admin()
        ),
    )
Beispiel #10
0
 def format(self):
     product = Product.get_product(self.product_id)
     data = {
         'from_user':
         User.get_one(
             self.from_user).format(exclude_fields=['is_followed']),
         'product':
         product and product.format(),
         'num':
         self.num,
         'create_at':
         util.datetime2timestamp(self.create_at)
     }
     return data
Beispiel #11
0
 def format_log(self):
     product = Product.get_product(self.product_id)
     uid = self.user_id if 'user_id' in self.__dict__[
         '_data'] else self.from_user
     user = User.get_one(uid)
     data = {
         'user': user and user.format(exclude_fields=['is_followed']),
         'product': product and product.format(),
         'num': self.daily_sum,
         'credit_type': self.credit_type,
         'credit_value': self.credit_value,
         'send_success': self.send_success,
         'create_at': util.datetime2timestamp(self.create_at)
     }
     return data
Beispiel #12
0
    def send_default_gift(uid, task_id, user, extra, msg):
        item = WatchLiveTaskItem.get_item_by_identity(task_id, 'default')
        if not item:
            return {'ret': False, 'task': task.format(uid), 'item': None}
        # 更新库存
        item.update_left()

        # 进行物品的发放
        product = Product.get_product(item.product_id)
        status = product.add_product2user(uid, item.product_num, const.TASK,
                                          extra)
        _msg = msg % ({'name': user.nickname or user.name, 'gift': item.title})
        data = dict(message=_msg, event_id=live_id)
        Xlive.send_live_msg(data, 'activity')
        return {'ret': True, 'task': task.format(uid), 'item': item.format()}
Beispiel #13
0
def user_gifts():
    """获取用户所有礼物 (GET&LOGIN)

    :uri: /gifts/user_gifts
    :return: {'gifts': list}
    """
    user = request.authed_user
    pdict = {}
    for p in Product.get_all_gifts():
        pdict[p.product_id] = p.format()

    uproducts = UserProduct.get_user_products(str(user._id))
    for up in uproducts:
        if up.product_id not in pdict:
            continue
        pdict[up.product_id].update(up.format())

    return {'gifts': pdict.values()}
Beispiel #14
0
 def format(self):
     product = Product.get_product(self.product_id)
     result = json.loads(self.result) if self.result else None
     rid = result['id'] if result and 'id' in result else None
     code = result['giftCode'] if result and 'giftCode' in result else None
     name = result['name'] if result and 'name' in result else None
     data = {
         'order_id': self.order_id,
         'title': self.title,
         'product': product and product.format(),
         'status': self.status,
         'create_at': util.datetime2timestamp(self.create_at),
         'result': {
             'code': code,
             'name': name,
             'rid': rid
         }
     }
     return data
Beispiel #15
0
class StoreItemAdmin(ModelView):
    form = StoreItemForm
    can_view_details = True
    details_modal = True
    column_details_list = ('store_id', 'product_id', 'product_num', 'title', 'credit_type',
                           'credit_value', 'total_num', 'use_num', 'left_num', 'order', 'identity')
    column_list = ('store_id', 'product_id', 'product_num', 'credit_type', 'credit_value',
                   'left_num', 'order', 'identity')
    column_labels = dict(store_id=u'商店', product_id=u'物品', product_num=u'物品数量', title=u'商品描述',
                         credit_type=u'价格类型', credit_value=u'价格数值', total_num=u'总库存',
                         use_num=u'已用库存', left_num=u'剩余库存', order=u'显示顺序', identity=u'营销平台奖项ID')
    column_formatters = dict(
        store_id=lambda v, c, m, n: get_choices_desc(store.Store.all_stores_for_admin(),
                                                     m.store_id),
        product_id=lambda v, c, m, n: get_choices_desc(Product.all_products_for_admin(),
                                                       m.product_id),
        credit_type=lambda v, c, m, n: get_choices_desc(store.CREDIT_TYPE, m.credit_type),
    )
    column_filters = ('store_id',)

    def create_form(self, obj=None):
        form = super(StoreItemAdmin, self).create_form(obj)
        form.store_id.choices = store.Store.all_stores_for_admin()
        form.product_id.choices = Product.all_products_for_admin()
        return form

    def edit_form(self, obj=None):
        form = super(StoreItemAdmin, self).edit_form(obj)
        form.store_id.choices = filter(lambda x: x[0] == obj.store_id, store.Store.all_stores_for_admin())
        # form.store_id.choices = store.Store.all_stores_for_admin()
        form.product_id.choices = Product.all_products_for_admin()
        return form

    def after_model_change(self, form, model, is_created):
        super(StoreItemAdmin, self).after_model_change(form, model, is_created)
        key = store.STORE_ITEM_KEY % ({'store_id': model.store_id})
        Redis.delete(key)

    def after_model_delete(self, model):
        super(StoreItemAdmin, self).after_model_delete(model)
        key = store.STORE_ITEM_KEY % ({'store_id': model.store_id})
        Redis.delete(key)
Beispiel #16
0
    def receive_rewards(self):
        if not self.is_finished:
            return []

        task = Task.get(Task.task_id == self.task_id)
        key = USER_TASK_KEY % (self.user_id)
        # 如果基本任务已被删除,则删除用户任务
        if not task:
            self.delete_instance()
            Redis.delete(key)
            return []

        product = Product.get(Product.product_id == task.product_id)
        rewards = []
        with MYDB.atomic():
            self.task_status = RECEIVED
            self.save()
            if product.add_product2user(self.user_id, task.product_num,
                                        const.TASK):
                rewards.append(
                    dict(name=product.product_name, num=task.product_num))

        Redis.delete(key)
        return rewards
Beispiel #17
0
def live_task():
    """观看直播时长任务 (GET)

    :uri: /lives/task
    :param task_id: 直播任务ID
    :param os: 平台
    :param channels: 渠道(可选)
    :param version_code: 版本号
    :param live_id: 直播间ID
    :return: {'ret': bool}
    """
    user = request.authed_user
    params = request.values
    task_id = params.get('task_id', None)
    os = params.get('os', None)
    channels = params.get('channels', None)
    version_code = int(params.get('version_code', 0))
    live_id = request.values.get('live_id')

    if not os or not version_code or not task_id or not live_id:
        return error.InvalidArguments

    uid = str(user._id)
    phone = str(user.phone)
    province = None
    if user.province:
        province = user.province

    if not user.province and util.is_mobile_phone(phone):
        province = Migu.get_user_info_by_account_name(phone)
        if not isinstance(province, error.ApiError):
            user.update_model({'$set': {'province': province}})
        else:
            province = None
    # 避免出现跨天时出现没有任务的情况
    tids = WatchLiveTask.get_user_tids(uid)
    task = WatchLiveTask.get_one(task_id)
    if not task:
        return error.TaskError(u'观看直播时长任务不存在!')

    if task.os not in ['all', os]:
        return error.TaskError(u'不符合任务条件!')

    if (task.version_code_mix and task.version_code_mix > version_code) or \
            (task.version_code_max and task.version_code_max < version_code):
        return error.TaskError(u'不符合任务条件!')

    if channels and task.channels and channels not in task.channels:
        return error.TaskError(u'不符合任务条件!')

    if task.login == 'login' and (
            not uid or not task.user_in_group(str(task.group), uid)):
        return error.TaskError(u'不符合任务条件!')

    if task.province and not province:
        return error.TaskError(u'不符合任务条件!')

    if task.province and province and province not in task.province:
        return error.TaskError(u'不符合任务条件!')

    extra = dict(migu_id=user.partner_migu['id'],
                 phone=user.phone,
                 campaign_id=task.campaign_id)
    msg = u"恭喜%(name)s获得%(gift)s"

    def send_default_gift(uid, task_id, user, extra, msg):
        item = WatchLiveTaskItem.get_item_by_identity(task_id, 'default')
        if not item:
            return {'ret': False, 'task': task.format(uid), 'item': None}
        # 更新库存
        item.update_left()

        # 进行物品的发放
        product = Product.get_product(item.product_id)
        status = product.add_product2user(uid, item.product_num, const.TASK,
                                          extra)
        _msg = msg % ({'name': user.nickname or user.name, 'gift': item.title})
        data = dict(message=_msg, event_id=live_id)
        Xlive.send_live_msg(data, 'activity')
        return {'ret': True, 'task': task.format(uid), 'item': item.format()}

    lockkey = 'lock:task:%s:%s' % (uid, task_id)
    with util.Lockit(Redis, lockkey) as locked:
        if locked:
            return error.TaskError(u'请求频率过高')
        # 查看是否有抽奖机会
        stat = WatchLiveTask.update_left_chance(uid, task_id)
        if not stat:
            return error.TaskError(u'无抽奖机会!')

        # 从营销中心查询/请求抽奖机会
        left_chances = Marketing.query_lottery_chance(user.partner_migu['id'],
                                                      task.campaign_id)
        if isinstance(left_chances, error.ApiError):
            return send_default_gift(uid, task_id, user, extra, msg)
        if left_chances <= 0:
            # 进行抽奖机会的兑换
            ret = Marketing.execute_campaign(user.partner_migu['id'],
                                             user.phone, [task.campaign_id])
            if not ret or isinstance(ret, error.ApiError):
                return send_default_gift(uid, task_id, user, extra, msg)

        # 调用营销平台进行抽奖
        prize = Marketing.draw_lottery(user.partner_migu['id'],
                                       task.campaign_id)
        if isinstance(prize, error.ApiError):
            prize = None

        if not prize:
            # 如果没有抽中奖品,发放默认奖品
            return send_default_gift(uid, task_id, user, extra, msg)

        prize_name = None
        for i in prize['extensionInfo']:
            if i['key'] == 'levelName':
                prize_name = i['value']
                break
        item = WatchLiveTaskItem.get_item_by_identity(task_id, prize_name)
        # 更新库存
        item.update_left()

        # 生成兑奖订单
        order = UserLiveOrder.create(user_id=uid,
                                     item_id=str(item._id),
                                     activity_id=task_id,
                                     activity_type=0,
                                     campaign_id=task.campaign_id,
                                     title=item.title,
                                     product_id=item.product_id,
                                     product_num=item.product_num,
                                     status=const.ORDER_FINISHED,
                                     result=json.dumps(prize))
        order.save()

        # 进行物品的发放
        product = Product.get_product(item.product_id)
        status = product.add_product2user(uid, item.product_num, const.TASK,
                                          extra)

        _msg = msg % ({'name': user.nickname or user.name, 'gift': item.title})
        data = dict(message=_msg, event_id=live_id)
        Xlive.send_live_msg(data, 'activity')
    return {'ret': True, 'task': task.format(uid), 'item': item.format()}
Beispiel #18
0
def grab_redpacket():
    """直播间红包争抢(POST)

    :uri: /lives/redpacket/grab
    :param os: 平台
    :param channels: 渠道(可选)
    :param version_code: 版本号
    :param live_id: 直播间ID
    :param source_id: 红包ID
    :return: {'ret': bool}
    """
    user = request.authed_user
    params = request.values
    os = params.get('os', None)
    channels = params.get('channels', None)
    version_code = int(params.get('version_code', 0))
    live_id = params.get('live_id', None)
    source_id = params.get('source_id', None)

    if not os or not version_code or not source_id or not live_id:
        return error.InvalidArguments

    uid = None
    province = None
    if user:
        uid = str(user._id)
        phone = str(user.phone)

        if user.province:
            province = user.province

        if not user.province and util.is_mobile_phone(phone):
            province = Migu.get_user_info_by_account_name(phone)
            if not isinstance(province, error.ApiError):
                user.update_model({'$set': {'province': province}})
            else:
                province = None

    red_packet = UserRedPacket.get_one(source_id)
    if not red_packet:
        return error.RedPacketError(u'红包不存在!')

    activity = LiveRedPacket.get_one(red_packet.active_id)
    if not activity:
        return error.RedPacketError(u'直播红包活动不存在!')

    # 查看是否有抽奖机会
    if red_packet.chance <= 0:
        return error.RedPacketError(u'已达到领取红包次数上限!')

    def get_user_redpackets():
        # 先获取已存在的红包,以及已经参与的直播间抢红包
        _red_packet, _red_packet_count = None, 0
        _ids = UserRedPacket.user_red_packets(uid)
        for urp in UserRedPacket.get_list(_ids):
            if not LiveRedPacket.get_one(urp.active_id):
                continue
            if urp.source == 0:
                # 过滤掉所有直播间抽奖机会
                continue
            if urp.chance <= 0:
                continue
            if _red_packet is None or _red_packet.expire_at > urp.expire_at:
                _red_packet = urp
            _red_packet_count += 1
        # 如果是直播间红包,返回直播间红包;如果不是,返回新红包
        if red_packet.from_user == red_packet.user_id:
            _red_packet = red_packet
        # 如果没有新红包,返回当前红包,并标记剩余红包数为0
        if not _red_packet:
            _red_packet = red_packet
        return _red_packet.format(_red_packet_count)

    def send_default_gift(uid, task_id, user, extra):
        return {
            'ret': True,
            'red_packet': get_user_redpackets(True),
            'item': None,
            'current_red_packet': red_packet.format(0, True)
        }

    extra = dict(migu_id=user.partner_migu['id'],
                 phone=user.phone,
                 campaign_id=red_packet.campaign_id)
    item = None

    key = 'lock:receive_red_packet:%s' % (uid)
    with util.Lockit(Redis, key) as locked:
        if locked:
            return error.RedPacketError(u'领取红包失败,请稍后再试!')

        # 如果是直播间红包抽奖,则需要先调用抽奖接口再获取红包物品
        if not red_packet.source:
            # 从营销中心查询/请求抽奖机会
            left_chances = Marketing.query_lottery_chance(
                user.partner_migu['id'], red_packet.campaign_id)
            if isinstance(left_chances, error.ApiError):
                return send_default_gift(uid, source_id, user, extra)
            if left_chances <= 0:
                # 进行抽奖机会的兑换
                ret = Marketing.execute_campaign(user.partner_migu['id'],
                                                 user.phone,
                                                 [red_packet.campaign_id])
                if not ret or isinstance(ret, error.ApiError):
                    return send_default_gift(uid, source_id, user, extra)

            # 扣除用户抽奖次数
            red_packet.take_chance()

            # 调用营销平台进行抽奖
            prize = Marketing.draw_lottery(user.partner_migu['id'],
                                           red_packet.campaign_id)
            if isinstance(prize, error.ApiError):
                prize = None
            if not prize:
                # 如果没有抽中奖品,发放默认奖品
                return send_default_gift(uid, source_id, user, extra)

            # 先请求红包机会
            extra.update({'campaign_id': activity.redpacket_id})
            ret = Marketing.execute_campaign(user.partner_migu['id'],
                                             user.phone,
                                             [activity.redpacket_id])
            if not ret or isinstance(ret, error.ApiError):
                return send_default_gift(uid, source_id, user, extra)
            # 抢红包
            rps = Marketing.query_red_package_by_user(user.partner_migu['id'],
                                                      activity.redpacket_id)
            if isinstance(rps, error.ApiError):
                return send_default_gift(uid, source_id, user, extra)
            if not rps:
                return send_default_gift(uid, source_id, user, extra)
            # 将最新的红包放到最前面
            rps.sort(key=lambda x: x['createDate']['time'], reverse=True)

            # 将红包放入用户可分享红包
            _urp = UserRedPacket.init()
            _urp.active_id = activity._id
            _urp.campaign_id = activity.redpacket_id
            _urp.resource_id = rps[0]['id']
            _urp.chance = 1
            _urp.expire_at = activity.share_expire_at
            _urp.item_count = activity.share_count
            _urp.user_id = uid
            _urp.from_user = uid
            _urp.source = 1
            _urp.create_model()
            red_packet = _urp

        # 扣除红包领取次数
        red_packet.take_chance()

        # 从分享红包获取物品
        prize = Marketing.grab_red_package(user.partner_migu['id'],
                                           red_packet.campaign_id,
                                           red_packet.resource_id)
        if isinstance(prize, error.ApiError):
            return {
                'ret': False,
                'red_packet': get_user_redpackets(),
                'item': None,
                'current_red_packet': red_packet.format(0, True)
            }

        if not prize:
            # 如果没有抽中奖品,发放默认奖品
            return send_default_gift(uid, source_id, user, extra)

        # 发放物品
        prize_name = prize.get('name')
        item = LiveRedPacketItem.get_item_by_identity(activity._id, prize_name)
        # 更新库存
        item.update_left()

        # 生成兑奖订单
        order = UserLiveOrder.create(user_id=str(user._id),
                                     item_id=str(item._id),
                                     activity_id=str(activity._id),
                                     activity_type=1,
                                     campaign_id=red_packet.campaign_id,
                                     title=item.title,
                                     product_id=item.product_id,
                                     product_num=item.product_num,
                                     status=const.ORDER_FINISHED,
                                     result=json.dumps(prize))
        order.save()

        # 进行物品的发放
        product = Product.get_product(item.product_id)
        product.add_product2user(uid, item.product_num, const.TASK, extra)

    return {
        'ret': True,
        'red_packet': get_user_redpackets(),
        'item': item and item.format(),
        'current_red_packet': red_packet.format(0, item is None)
    }
Beispiel #19
0
 def edit_form(self, obj=None):
     form = super(WatchLiveTaskItemAdmin, self).edit_form(obj)
     form.wlt_id.choices = WatchLiveTask.all_tasks_for_admin()
     form.product_id.choices = Product.all_products_for_admin()
     return form
Beispiel #20
0
def draw_lottery():
    """抽奖接口(POST&LOGIN)

    :uri: /store/draw_lottery
    :param store_id: 抽奖活动ID
    :return: {'item': <Item>object, 'order': <Order>object}
    """
    user = request.authed_user
    store_id = request.values.get('store_id', None)
    trigger = request.values.get('trigger', None)
    user_ip = request.remote_addr
    device = request.values.get('device', None)

    if not store_id:
        return error.InvalidArguments

    store = Store.get_store(store_id)
    if not store or not store.online():
        return error.StoreError('该抽奖活动不存在或已下线')

    if store.pause():
        return error.StoreError('该抽奖活动还未开始')

    if store.yxmember:
        uservip = MiguPay.check_user_vip_level(user.phone)
        if isinstance(uservip, error.ApiError):
            return uservip
        if not (uservip['vip5']['subscribed']
                or uservip['vip10']['subscribed']):
            return error.MemberError('该抽奖需要游戏会员才能参加')

    # 进行抽奖奖项库存判断
    items = StoreItem.get_store_items(store_id)
    left_num = sum(map(lambda x: x.left_num, items))
    if left_num < 0:
        return error.StoreError('该抽奖活动奖项已被领取完')

    # 判断号码是否符合规则
    info = Marketing.query_campaign(store.campaign_id)
    if isinstance(info, error.ApiError):
        return info
    if info['mobile_phone_only'] and not util.is_mobile_phone(user.phone):
        return error.StoreError('该抽奖活动只对移动手机号开放')

    # 查看是否有抽奖机会
    left_chances = Marketing.query_lottery_chance(user.partner_migu['id'],
                                                  store.campaign_id)
    if isinstance(left_chances, error.ApiError):
        return error.StoreError('获取抽奖机会失败')

    if left_chances <= 0:
        uc = UserCredit.get_or_create_user_credit(user_id=str(user._id))
        if store.credit_type == const.SALE_GEM and uc.gem < store.credit_value:
            return error.StoreError('你的游票不足,无法参与抽奖哦!')
        elif store.credit_type == const.SALE_GOLD and uc.gold < store.credit_value:
            return error.StoreError('你的游米不足,无法参与抽奖哦!')

        key = 'lock:store:%s' % (str(user._id))
        with util.Lockit(Redis, key) as locked:
            if locked:
                return error.StoreError('抽奖太频繁')

            # 进行抽奖机会的兑换
            if not trigger:
                ret = Marketing.execute_campaign(user.partner_migu['id'],
                                                 user.phone,
                                                 [store.campaign_id])
            else:
                ret = Marketing.execute_campaign(user.partner_migu['id'],
                                                 user.phone,
                                                 [store.campaign_id],
                                                 trigger=trigger)
            if not ret or isinstance(ret, error.ApiError):
                return error.StoreError('兑换抽奖机会失败')
            else:  # 扣除货币
                if store.credit_type == const.SALE_GEM:
                    uc.reduce_gem(store.credit_value, const.LOTTERY_REWAED)
                elif store.credit_type == const.SALE_GOLD:
                    uc.reduce_gold(store.credit_value, const.LOTTERY_REWAED)

    # 调用营销平台进行抽奖
    prize = Marketing.draw_lottery(user.partner_migu['id'], store.campaign_id)
    if isinstance(prize, error.ApiError):
        return prize

    # 营销数据入库经分  抽奖活动
    data_dict = dict(cmd="lottery",
                     opt="1",
                     deviceid=request.values.get('device', ''),
                     mobile=user.phone,
                     source=request.values.get('source', 'activity'),
                     activityid=store_id,
                     activityname=store.title)
    Marketing.jf_report(data_dict)
    # 营销平台奖项有各种限制, 会导致用户抽不中任何物品的可能。
    # 比如有A/B/C三个抽奖奖项,概率分别为20%/30%/50%,如果A物品配置为一个手机号只能中一次,
    # 那当用户抽中过A之后,以后再抽奖,就会有20%(A)的几率啥也抽不中。如果B物品库存又没有了,
    # 那用户就会有20%(A)+30%(B)的几率啥也抽不中。为了处理这种情况,目前默认如果抽不中就给
    # 用户发一个抽奖活动配置的"default"奖项(运营后台: 营销平台奖项ID配置为'default')
    if not prize:
        item = StoreItem.get_item_by_identity(store.store_id, 'default')
        if not item:
            return {'item': None, 'order': None}
        else:
            # 更新库存
            item.left_num -= 1
            item.use_num += 1
            item.save()
            # 生成兑奖订单
            order = UserOrder.create(
                user_id=str(user._id),
                item_id=item.item_id,
                store_id=item.store_id,
                store_type=store.store_type,
                campaign_id=store.campaign_id,
                title=item.title,
                product_id=item.product_id,
                product_num=item.product_num,
                status=const.ORDER_NEED_DRAW,
                result='',
                user_ip=request.access_route[0],
            )
            extra = dict(migu_id=user.partner_migu['id'],
                         phone=user.phone,
                         campaign_id=store.resource_campaign_id)
            # 进行物品的发放
            product = Product.get_product(item.product_id)
            status = product.add_product2user(str(user._id), item.product_num,
                                              const.LOTTERY, extra)

            # 订单状态更新
            if status != order.status:
                order.status = status
                order.save()

            return {'item': item.format(), 'order': order.format()}

    # 由于营销平台看不到id, 暂时只能用奖项名称进行对应
    prize_name = None
    for i in prize['extensionInfo']:
        if i['key'] == 'levelName':
            prize_name = i['value']
            break

    item = StoreItem.get_item_by_identity(store.store_id, prize_name)
    # 更新库存
    item.left_num -= 1
    item.use_num += 1
    item.save()

    # 无领取规则的活动营销平台会自动领取
    status = const.ORDER_NEED_DRAW if info[
        'is_exchange_rule'] else const.ORDER_IN_HAND
    # 生成兑奖订单
    order = UserOrder.create(
        user_id=str(user._id),
        item_id=item.item_id,
        store_id=item.store_id,
        store_type=store.store_type,
        campaign_id=store.campaign_id,
        title=item.title,
        product_id=item.product_id,
        product_num=item.product_num,
        status=status,
        result=json.dumps(prize),
        user_ip=request.access_route[0],
    )

    product = Product.get_product(item.product_id)
    if product.product_type != PHYSICAL_OBJECT:  # 非实物物品直接去营销平台进行奖励兑换
        # 有领取规则的抽奖活动的非实物物品自动领取, 无领取规则的活动营销平台会自动领取
        if info['is_exchange_rule']:
            # 获取用户可兑换奖励信息
            prizes = Marketing.query_exchengable_prizes(
                user.partner_migu['id'], order.campaign_id)
            if isinstance(prizes, error.ApiError):
                return prizes

            # 进行奖励的兑换, 目前最后一条为最近获得的奖励
            for _prize in prizes[::-1]:
                exchenge_ids = map(lambda x: x['id'],
                                   _prize['exchengeResources'])
                exchengeable_id = _prize['exchengableResource']['id']
                if [prize['id']] == exchenge_ids:
                    exchenge_ids = [prize['id']]
                    ret = Marketing.draw_exchengable_prize(
                        user.partner_migu['id'], order.campaign_id,
                        exchenge_ids, exchengeable_id, prize['amount'])

                    if isinstance(ret, error.ApiError):
                        return ret

        # 由于对方没有返回订单ID, 只能通过获取用户最近一个已兑换奖励的订单ID, 实物物品需要手动领取
        ret, _ = Marketing.query_exchenged_prizes(user.partner_migu['id'],
                                                  order.campaign_id,
                                                  page=1,
                                                  pagesize=1)
        if isinstance(ret, error.ApiError):
            return ret

        # 更新订单信息
        if isinstance(ret, list) and len(ret) > 0 and 'recId' in ret[0]:
            order.recid = ret[0]['recId']

        order.status = const.ORDER_IN_HAND
        order.save()

        extra = dict(migu_id=user.partner_migu['id'],
                     phone=user.phone,
                     campaign_id=store.resource_campaign_id)
        # 进行物品的发放
        status = product.add_product2user(str(user._id), item.product_num,
                                          const.LOTTERY, extra)

        # 订单状态更新
        if status != order.status:
            order.status = status
            order.save()

    return {'item': item.format(), 'order': order.format()}
Beispiel #21
0
def receive_order():
    """领取订单奖励(POST&LOGIN)

    :uri: /store/receive_order
    :param order_id: 订单ID
    :param name: 真实名字 (实物物品)
    :param id_card: 身份证 (实物物品)
    :param address: 地址 (实物物品)
    :return: {'order': <Order>object}
    """
    user = request.authed_user
    order_id = request.values.get('order_id', None)
    name = request.values.get('name', None)
    id_card = request.values.get('id_card', None)
    address = request.values.get('address')

    if not order_id:
        return error.InvalidArguments

    order = UserOrder.get_order(order_id)
    if not order or order.user_id != str(user._id):
        return error.StoreError('用户订单不存在')

    if order.status != const.ORDER_NEED_DRAW:
        return error.StoreError('用户订单状态错误')

    store = Store.get_store(order.store_id)
    if not store or not store.online():
        return error.StoreError('该抽奖活动不存在或已下线')

    product = Product.get_product(order.product_id)
    if product.product_type == PHYSICAL_OBJECT:  # 实物物品
        if not name or not id_card or not address:
            return error.InvalidArguments

        addr = UserOrderAddress.create(order_id=order_id,
                                       user_id=str(user._id),
                                       name=name,
                                       phone=user.phone,
                                       id_card=id_card,
                                       address=address)

    prize = json.loads(order.result)

    # 获取用户可兑换奖励信息
    exchenge_prizes = Marketing.query_exchengable_prizes(
        user.partner_migu['id'], order.campaign_id)
    if isinstance(exchenge_prizes, error.ApiError):
        return exchenge_prizes

    for _prize in exchenge_prizes:
        exchenge_ids = map(lambda x: x['id'], _prize['exchengeResources'])
        exchengeable_id = _prize['exchengableResource']['id']

        if [prize['id']] == exchenge_ids:
            exchenge_ids = [prize['id']]
            if product.product_type == PHYSICAL_OBJECT:  # 实物物品
                ret = Marketing.draw_exchengable_prize(
                    user.partner_migu['id'], order.campaign_id, exchenge_ids,
                    exchengeable_id, prize['amount'], addr.name, addr.phone,
                    addr.address, addr.id_card)
            else:
                ret = Marketing.draw_exchengable_prize(user.partner_migu['id'],
                                                       order.campaign_id,
                                                       exchenge_ids,
                                                       exchengeable_id,
                                                       prize['amount'])

            if isinstance(exchenge_prizes, error.ApiError):
                return ret

    # 由于对方没有返回订单ID, 只能通过获取用户最近一个已兑换奖励的订单ID
    ret, _ = Marketing.query_exchenged_prizes(user.partner_migu['id'],
                                              order.campaign_id,
                                              page=1,
                                              pagesize=1)
    if isinstance(ret, error.ApiError):
        return ret

    # 更新订单信息
    if isinstance(ret, list) and len(ret) > 0 and 'recId' in ret[0]:
        order.recid = ret[0]['recId']

    order.status = const.ORDER_IN_HAND
    order.save()

    extra = dict(migu_id=user.partner_migu['id'],
                 phone=user.phone,
                 campaign_id=store.resource_campaign_id)
    # 进行物品的发放
    status = product.add_product2user(str(user._id), order.product_num,
                                      const.LOTTERY, extra)

    # 订单状态更新
    if status != order.status:
        order.status = status
        order.save()

    return {'order': order.format()}
Beispiel #22
0
 def edit_form(self, obj=None):
     form = super(StoreItemAdmin, self).edit_form(obj)
     form.store_id.choices = filter(lambda x: x[0] == obj.store_id, store.Store.all_stores_for_admin())
     # form.store_id.choices = store.Store.all_stores_for_admin()
     form.product_id.choices = Product.all_products_for_admin()
     return form
Beispiel #23
0
 def create_form(self, obj=None):
     form = super(StoreItemAdmin, self).create_form(obj)
     form.store_id.choices = store.Store.all_stores_for_admin()
     form.product_id.choices = Product.all_products_for_admin()
     return form
Beispiel #24
0
 def edit_form(self, obj=None):
     form = super(GiftAdmin, self).edit_form(obj)
     form.product_id.choices = Product.all_gifts_for_admin()
     return form
Beispiel #25
0
def exchange_product():
    """兑换物品接口(POST&LOGIN)

    :uri: /store/exchange_product
    :param store_id: 兑换活动ID
    :param item_id: 兑换物品ID
    :return: {'item': <Item>object, 'order': <Order>object}
    """
    user = request.authed_user
    store_id = request.values.get('store_id', None)
    item_id = request.values.get('item_id', None)

    user_ip = request.remote_addr
    device = request.values.get('device', None)

    if not store_id or not item_id:
        return error.InvalidArguments

    store = Store.get_store(store_id)
    if not store or not store.online():
        return error.StoreError('该兑换活动不存在或已下线')

    item = StoreItem.get_store_item(store_id, item_id)
    if not item:
        return error.StoreError('该兑换奖品不存在')

    # 库存判断
    if item.left_num < 1:
        return error.StoreError('该兑换奖品已卖完')

    product = Product.get_product(item.product_id)

    # 判断手机号
    if product.product_type == MOBILE_TRAFFIC and not util.is_mobile_phone(
            user.phone):
        return error.StoreError('非移动手机号不能兑换此商品')

    if product.product_type == UNICOM_TRAFFIC and not util.is_unicom_phone(
            user.phone):
        return error.StoreError('非联通手机号不能兑换此商品')

    if product.product_type == TELECOM_TRAFFIC and not util.is_telecom_phone(
            user.phone):
        return error.StoreError('非电信手机号不能兑换此商品')

    uc = UserCredit.get_or_create_user_credit(user_id=str(user._id))
    if item.credit_type == const.SALE_GEM and uc.gem < item.credit_value:
        return error.StoreError('你的游票不足,无法兑换此物品哦!')
    elif item.credit_type == const.SALE_GOLD and uc.gold < item.credit_value:
        return error.StoreError('你的游米不足,无法兑换此物品哦!')

    key = 'lock:store:%s' % (str(user._id))
    status = None
    with util.Lockit(Redis, key) as locked:
        if locked:
            return error.StoreError('兑换太频繁')

        extra = dict(migu_id=user.partner_migu['id'],
                     phone=user.phone,
                     campaign_id=store.resource_campaign_id)
        status = product.add_product2user(str(user._id), item.product_num,
                                          const.EXCHANGE, extra)
        if status == const.ORDER_FAILED:
            return error.StoreError('兑换失败')
        else:
            # 扣除货币
            if item.credit_type == const.SALE_GEM:
                uc.reduce_gem(item.credit_value, const.EXCHANGE)
            elif item.credit_type == const.SALE_GOLD:
                uc.reduce_gold(item.credit_value, const.EXCHANGE)

    # 更新库存
    item.left_num -= 1
    item.use_num += 1
    item.save()
    # 记录订单
    order = UserOrder.create(
        user_id=str(user._id),
        item_id=item.item_id,
        store_id=item.store_id,
        store_type=store.store_type,
        campaign_id=store.campaign_id,
        title=item.title,
        product_id=item.product_id,
        product_num=item.product_num,
        status=status,
        user_ip=request.access_route[0],
    )

    # 营销数据入库经分  兑换活动
    data_dict = dict(cmd="exchange",
                     opt="1",
                     deviceid=request.values.get('device', ''),
                     mobile=user.phone,
                     source=request.values.get('source', 'activity'),
                     activityid=store_id,
                     activityname=store.title)
    Marketing.jf_report(data_dict)

    return {'item': item.format(), 'order': order.format()}
Beispiel #26
0
    def send_to_user(self, from_user, to_user, num, gift_from, from_id,
                     **kwargs):
        if num < 1:
            return error.InvalidArguments

        uc = from_user_uc = UserCredit.get_or_create_user_credit(from_user)
        product = Product.get_product(self.product_id)
        if self.credit_type == const.SALE_GOLD:
            total_gold = self.credit_value * num
            if uc.gold < total_gold:
                return error.GiftError('你的游米不足,做任务可获取游米')

            with MYDB.atomic():
                uc.reduce_gold(total_gold, const.GIFT)
                product.add_product2user(to_user, num, const.GIFT)
                UserGiftLog.create(user_id=to_user,
                                   from_user=from_user,
                                   product_id=self.product_id,
                                   credit_type=self.credit_type,
                                   credit_value=self.credit_value,
                                   num=num,
                                   gold_price=self.gold_price * num,
                                   gift_from=gift_from,
                                   from_id=from_id,
                                   send_success=1)
        elif self.credit_type == const.SALE_GEM:
            total_gem = self.credit_value * num
            if uc.gem < total_gem:
                return error.GiftError('你的游票不足')

            with MYDB.atomic():
                uc.reduce_gem(total_gem, const.GIFT)
                product.add_product2user(to_user, num, const.GIFT)
                UserGiftLog.create(user_id=to_user,
                                   from_user=from_user,
                                   product_id=self.product_id,
                                   credit_type=self.credit_type,
                                   credit_value=self.credit_value,
                                   num=num,
                                   gold_price=self.gold_price * num,
                                   gift_from=gift_from,
                                   from_id=from_id,
                                   send_success=1)
        elif self.credit_type == const.DAILY_FREE:
            from_up = UserProduct.get_or_create_user_product(
                from_user, self.product_id)
            if from_up.gift_free < num:
                return error.GiftError('对不起,您今天的免费礼物已用完')

            with MYDB.atomic():
                from_up.gift_free -= num
                from_up.save()
                product.add_product2user(to_user, num, const.GIFT)
                UserGiftLog.create(user_id=to_user,
                                   from_user=from_user,
                                   product_id=self.product_id,
                                   credit_type=self.credit_type,
                                   credit_value=self.credit_value,
                                   num=num,
                                   gold_price=self.gold_price * num,
                                   gift_from=gift_from,
                                   from_id=from_id,
                                   send_success=1)
        elif self.credit_type == const.MONEY:
            # 请求支付
            with MYDB.atomic():
                # uc.reduce_gem(total_gem, const.GIFT)
                #
                send_success = kwargs.get("send_success", 0)
                if not send_success:
                    UserGiftLog.create(
                        user_id=to_user,
                        from_user=from_user,
                        product_id=self.product_id,
                        credit_type=self.credit_type,
                        credit_value=self.credit_value,
                        num=num,
                        gold_price=self.gold_price * num,
                        gift_from=gift_from,
                        from_id=from_id,
                        gift_id=self.gift_id,
                        send_success=0,
                        transaction_id=kwargs.get("transactionId"))
                else:
                    total_money = self.gold_price * num
                    from_user_uc.add_cost_money(total_money)
                    to_user_uc = UserCredit.get_or_create_user_credit(to_user)
                    to_user_uc.add_get_money(total_money)
                    # 状态为1
                    log = UserGiftLog.get_by_transaction_id(
                        kwargs.get("transactionId"))
                    if not log:
                        return error.GiftError('未发现支付记录')
                    log.send_success = 1
                    log.save()
                    # redis 更新
                    UserGiftLog.update_redis_gift(log)
                    product.add_product2user(to_user,
                                             num,
                                             const.GIFT,
                                             extra={"is_money": True})
        return True