예제 #1
0
async def generate_awards_by_item_settings(basic_setting, settings):
    """

    :param basic_setting:
    :param settings:
    :return:
    """
    if not (basic_setting and settings):
        raise Exception('no basic_setting or settings')

    # 删除还未发出的红包
    await RedPacketBox.delete_many({
        'rule_cid': basic_setting.rule_cid,
        'member_cid': None
    })
    box_list = await RedPacketBox.aggregate(
        [
            MatchStage({
                'rule_cid': basic_setting.rule_cid,
                'award_cid': {
                    '$ne': None
                }
            }),
            GroupStage('award_cid', sum={'$sum': 1})
        ],
        read_preference=ReadPreference.PRIMARY).to_list(None)

    # 红包的发放情况
    get_situ = {box.id: box.sum for box in box_list}

    award_list = list()
    for config in settings:
        for _ in range(config.quantity - get_situ.get(config.cid, 0)):
            box = RedPacketBox()
            box.race_cid = basic_setting.race_cid
            box.rule_cid = basic_setting.rule_cid
            box.award_cid = config.cid
            box.award_msg = config.message
            box.award_amount = config.amount
            award_list.append(box)

    has_sent_count = sum(get_situ.values())
    while len(award_list) < basic_setting.expect_num - has_sent_count:
        box = RedPacketBox()
        box.race_cid = basic_setting.race_cid
        box.rule_cid = basic_setting.rule_cid
        box.award_msg = basic_setting.fail_msg
        award_list.append(box)

    shuffle(award_list)
    if award_list:
        for award in award_list:
            await award.save()
예제 #2
0
async def generate_awards_by_config(config: RedPacketConf):
    """

    :param config:
    :return:
    """
    if not config or config.quantity == 0:
        raise Exception('parameter error')

    await RedPacketBox.delete_many({'rule_cid': config.rule_cid})
    award_list = list()

    random_list = []
    if config.category == CATEGORY_REDPACKET_RANDOM:
        random_list = generate_random_list(config.quantity,
                                           config.total_amount)

    index = 0
    while index < config.quantity:
        index += 1
        box = RedPacketBox()
        box.race_cid = config.race_cid
        box.rule_cid = config.rule_cid
        box.award_cid = config.cid
        box.award_msg = config.msg
        if config.category == CATEGORY_REDPACKET_CONST:
            box.award_amount = config.total_amount / config.quantity

        if config.category == CATEGORY_REDPACKET_RANDOM:
            current_sum_amount = sum(
                [award.award_amount for award in award_list])
            if current_sum_amount < config.total_amount:
                box.award_amount = random_list[len(award_list)]

        award_list.append(box)
        if len(award_list) > 2000:
            await RedPacketBox.insert_many(award_list)
            award_list = []

    if award_list:
        await RedPacketBox.insert_many(award_list)
예제 #3
0
def start_lottery_queuing(self, member_cid, race_cid, rule: RedPacketRule, checkpoint_cid):
    """

    :param self:
    :param member_cid:
    :param race_cid:
    :param rule:
    :param checkpoint_cid:
    :return:
    """
    logger.info('START(%s): lottery queuing, race_cid=%s, checkpoint_cid=%s, member_id=%s ' % (
        self.request.id, race_cid, checkpoint_cid, member_cid))
    try:
        if not (member_cid and race_cid and rule):
            raise Exception('There is not member_cid or race_cid or rule')

        top_limit, fail_msg = None, None
        if rule.category == CATEGORY_REDPACKET_RULE_DIRECT:
            conf = RedPacketConf.sync_find_one({'rule_cid': rule.cid})
            top_limit = conf.top_limit
            fail_msg = conf.over_msg

        if rule.category == CATEGORY_REDPACKET_RULE_LOTTERY:
            conf = RedPacketBasicSetting.sync_find_one({'rule_cid': rule.cid})
            top_limit = conf.top_limit
            fail_msg = conf.fail_msg

        has_sent_count = RedPacketBox.sync_count({'rule_cid': rule.cid, 'draw_dt': {
            '$gte': datetime.now().replace(hour=0, minute=0, second=0),
            '$lte': datetime.now().replace(hour=23, minute=59, second=59)}, 'record_flag': 1},
                                                 read_preference=ReadPreference.PRIMARY)

        msg = None
        if has_sent_count >= top_limit:
            msg = conf.over_msg
            redpkt_box = RedPacketBox()
            result = RESULT_RACE_LOTTERY_LOSE_LATE
        else:
            redpkt_box = RedPacketBox.sync_find_one({'rule_cid': rule.cid, 'draw_dt': None, 'record_flag': 1})
            if not redpkt_box:
                msg = fail_msg
                redpkt_box = RedPacketBox()
                result = RESULT_RACE_LOTTERY_LOSE
            else:
                # 拿到了红包
                if not redpkt_box.award_msg:
                    item_setting = RedPacketItemSetting.sync_find_one({'rule_cid': rule.cid})
                    msg = item_setting.message
                    logger.error('item_msg: %s' % msg)

                if not redpkt_box.award_cid:
                    result = RESULT_RACE_LOTTERY_LOSE

        redpkt_box.race_cid = race_cid
        redpkt_box.rule_cid = rule.cid
        redpkt_box.checkpoint_cid = checkpoint_cid
        redpkt_box.member_cid = member_cid
        redpkt_box.draw_dt = datetime.now()

        if msg:
            redpkt_box.award_msg = msg
        redpkt_box.sync_save()

        win = bool(redpkt_box.award_cid)
        if win:
            result = RESULT_RACE_LOTTERY_WIN
            add_notice(member_cid, race_cid, checkpoint_cid, msg_type=TYPE_MSG_DRAW, redpkt_box=redpkt_box)

        RedisCache.hset(KEY_RACE_LOTTERY_RESULT.format(checkpoint_cid), member_cid, result)
        logger.info(' END (%s): lottery end , checkpoint_cid=%s, member_id=%s, result=%s ' % (
            self.request.id, checkpoint_cid, member_cid, result))
    except Exception:
        logger.error(traceback.format_exc())
        logger.error(
            'ERROR(%s): lottery error, checkpoint_cid=%s, member_id=%s, rule_cid=%s' % (
                self.request.id, checkpoint_cid, member_cid, rule.cid))
예제 #4
0
settings = RedPacketItemSetting.sync_find({'race_cid': race.cid})
setting_map = {}
for s in settings:
    s.rule_cid = rule.cid
    setting_map[s.cid] = s
    s.sync_save()
# db.TBL_RED_PACKET_ITEM_SETTING.update({}, {$rename : {"count" : "quantity"}}, false, true)

# 奖池
for entry in RedPacketEntry.sync_find({'race_cid': race.cid}):
    item = setting_map[entry.award_cid]
    box = RedPacketBox()
    box.race_cid = race.cid
    box.rule_cid = rule.cid
    box.award_cid = entry.award_cid
    box.award_msg = item.message
    box.award_amount = item.amount

    if entry.open_id:
        member = Member.sync_find_one({'open_id': entry.open_id})
        box.member_cid = member.cid

    hist = RedPacketAwardHistory.sync_find_one({'race_cid': race.cid, 'award_cid': entry.cid, 'issue_status': {'$ne': 1}})
    if hist:
        box.draw_status = STATUS_REDPACKET_AWARDED
        box.draw_dt = hist.request_dt
        box.error_msg = hist.error_msg
        box.request_dt = hist.request_dt
        box.checkpoint_cid = last_ck.cid
    else:
        box.draw_status = STATUS_REDPACKET_AWARD_FAILED