Пример #1
0
async def change_withdraw_record(request, *args, **kwargs):
    async def withdraw_record(id):
        async with db.conn.acquire() as con:
            st = await con.prepare(
                'select id, account_id, amount from "account_withdraw" where id=$1'
            )
            data = await st.fetchrow(id)
        return data

    withdraw_infos = request.json.get('withdraw_id')
    status = request.json.get('status')
    if isinstance(withdraw_infos, list):
        for withdraw in withdraw_infos:
            wd = await withdraw_record(withdraw)
            if not wd:
                return response_json(None, code=PARAMS_ERROR_CODE)
            if status == WITHDRAW_REJECTED:
                await withdraw_rejected_account(wd['account_id'], wd['id'],
                                                wd['amount'])
            elif status == WITHDRAW_AGREE:
                await withdraw_agree_account(wd['id'])
    else:
        return response_json(None, code=PARAMS_ERROR_CODE)
    return response_json(None)
Пример #2
0
async def send_verify_code(request, user):
    user_id = user.get('user_id')
    phone = request.args.get("phone", None)
    logger.info(f'user request verify_code, user_id:{user_id}, phone:{phone}')
    if phone is not None:
        check_phone_res = await check_phone(phone)
        if check_phone_res:
            '''
            发送验证码
            1. 正则校验手机号
            1. 根据手机号,生成6位随机数字
            2. 记录手机号与其验证码缓存关系
            '''
            if await check_rate(user_id, phone):
                return response_json(None, SHORT_MSG_SEND_FREQUENTLY, 'send frequently.')  # 调用频繁
            verify_code = str(random.randint(0, 999999)).zfill(6)
            val_redis_key = SEND_MSG_VAL_REDIS_KEY.format(user_id=user_id, phone=phone)
            await redis.conn.set(val_redis_key, verify_code, ex=60 * 60 * 1)
            content = MSG_TEMPLATE.format(verify_code=verify_code)
            return await send_msg(phone, content)
        else:
            return response_json(None, PARAMS_ERROR_CODE, 'this phone may not be exists.')
    else:
        return response_json(None, PARAMS_ERROR_CODE, 'this phone may not be exists.')
Пример #3
0
async def withdraw_list_admin(request, *args, **kwargs):
    """提现列表"""
    current_page = int(request.raw_args.get('current_page', 0))
    page_size = int(request.raw_args.get('page_size', 20))
    params = request.json

    sql, sql_count = await withdraw_sql(params)
    sql = sql + ''' limit ''' + str(page_size) + ''' offset ''' + str(
        current_page * page_size)

    async with db.conn.acquire() as con:
        select_result = records_to_list(await con.fetch(sql))
        select_count = await con.fetchval(sql_count)
    page_info = get_page_info(page_size, current_page, select_count)
    return response_json(select_result, page_info=page_info)
Пример #4
0
async def send_msg(phone, content):
    timestamp = str(int(time.time()))
    user_id = 'JJ0679'
    pwd = '595489'
    m = hashlib.md5()
    pwd_str = user_id + '00000000' + pwd + timestamp
    m.update(bytes(pwd_str, encoding='utf-8'))
    pwd_md5 = m.hexdigest()
    params = {
        'userid': user_id,
        'pwd': pwd_md5,
        'mobile': phone,
        'content': quote(content.encode('gbk')),
        'timestamp': timestamp
    }
    await send_msg_montent(params)
    return response_json(None)
Пример #5
0
async def user_withdraw_view(request, user):
    '''用户提现页'''
    user_id = user.get('user_id')
    data = {}
    async with db.conn.acquire() as con:
        select_stmt = await con.prepare(
            '''select id, user_id, balance_amount, withdrawing_amount from "account" where user_id=$1'''
        )
        user_withdraw_info = dict(await select_stmt.fetchrow(user_id))
        slip_stmt = await con.prepare(
            '''select exists(select id from "account_withdraw" where account_id=$1 and status in ($2, $3) limit 1)'''
        )
        is_withdrawed = await slip_stmt.fetchval(user_withdraw_info['id'],
                                                 WITHDRAW_SUCCESSED,
                                                 WITHDRAWING)
    data.update({'is_withdrawed': is_withdrawed})
    data.update(user_withdraw_info)
    return response_json(data)
Пример #6
0
async def keyword_list(request, user):
    """查询关键字列表"""
    user_id = user.get('user_id')
    user_keywords = await find_user_key_words(user_id)
    keywords_list = []
    if user_keywords is not None:
        for key, value in user_keywords.items():
            result_dict = {
                'batch_id': key,
                'keywords': value['keywords'],
                'bind_group_counts': len(value['group_codes']),
                'reply_content': value['reply_content'],
                'trigger_times': value['trigger_times'],
                'group_codes': value['group_codes']
            }

            keywords_list.append(result_dict)

    return response_json(keywords_list)
Пример #7
0
async def launch_history(request, **kwargs):
    user_id = kwargs['user']['user_id']
    current_page = int(request.raw_args.get('current_page'))
    page_size = int(request.raw_args.get('page_size'))
    logger.debug(f'launch history req, user_id:{user_id}')
    async with db.conn.acquire() as con:
        user_task_stmt = await con.prepare(
            '''select id as task_id, to_char(send_date, 'YYYY-MM-DD HH24:MI:SS') as send_date, jsonb_array_length(group_ids)::varchar as group_count, status as send_flag from "group_task"
                where user_id = $1 and type = 2 and status =1 and create_date >= (current_date  - 2)
                order by create_date desc limit $2 offset $3''')
        user_tasks = await user_task_stmt.fetch(user_id, page_size,
                                                current_page * page_size)
        task_list = records_to_list(user_tasks)
        history_count_stmt = await con.prepare(
            '''select count(1) from "group_task" where user_id = $1 and type = 2 and status = 1 and create_date >= (current_date - 2)'''
        )
        total_records = await history_count_stmt.fetchval(user_id)
        page_info = get_page_info(page_size, current_page, total_records)
        return response_json(task_list, page_info=page_info)
Пример #8
0
async def problem_feedback(request, *args, **kwargs):
    current_page = int(request.raw_args.get('current_page', 0))
    page_size = int(request.raw_args.get('page_size', 20))
    params = request.json

    sql, sql_count = await problem_sql(params)
    sql = sql + ''' limit ''' + str(page_size) + ''' offset ''' + str(
        current_page * page_size)

    async with db.conn.acquire() as con:
        select_result = records_to_list(await con.fetch(sql))
        select_count = await con.fetchval(sql_count)

    for result in select_result:
        if result['code'] is not None:
            result['robot_info'] = result['name'] + '(' + result[
                'wechat_no'] + ')'
    page_info = get_page_info(page_size, current_page, select_count)
    return response_json(select_result, page_info=page_info)
Пример #9
0
async def exception_group_pull(request, user, group_id):
    '''异常群拉回'''
    user_id = user.get('user_id')
    async with db.conn.acquire() as con:
        get_robot_stmt = await con.prepare(
            '''select "robot".code, "robot".qr_code from "robot_group_map" 
               left join "robot" on "robot_group_map".robot_id = "robot".id where "robot_group_map".group_id = $1 and 
               "robot_group_map".status <> 3''')
        get_group_stmt = await con.prepare(
            '''select name from "group" where id = $1 limit 1''')
        get_user_stmt = await con.prepare(
            '''select code from "user" where id = $1 limit 1''')
        robot = await get_robot_stmt.fetchrow(group_id)
        robot_code = robot.get('code')
        qr_code = robot.get('qr_code')
        user_code = await get_user_stmt.fetchval(user_id)
        group_name = await get_group_stmt.fetchval(group_id)
        content = GROUP_ROBOT_CALL_BACK_WORD.format(group_name=group_name)
        await send_text_msg(robot_code, user_code, content=content)
    return response_json(qr_code)
Пример #10
0
async def get_alt_msg(request, *args, **kwargs):
    """获取@用户机器人信息"""
    user_id = kwargs['user']['user_id']
    current_page = int(request.raw_args.get('current_page', 0))
    page_size = int(request.raw_args.get('page_size', 20))
    async with db.conn.acquire() as con:
        select_altmsg = await con.prepare(
            '''select "alt_msg".msg_id as msg_id, "group".name as group_name, "alt_msg".msg_content as msg_content, 
               "group".code as group_code, "alt_msg".status as status from "alt_msg" left join "group" on 
               "group".id="alt_msg".group_id where "group".status !=3 and "alt_msg".user_id = $1 and 
               "alt_msg".create_date >=(current_date - interval '3' day) order by "alt_msg".create_date desc
                 limit $2 offset $3''')
        msg_infos = records_to_list(await select_altmsg.fetch(
            user_id, page_size, current_page * page_size))
        select_count = await con.prepare(
            '''select count(1) from "alt_msg" left join "group" on "group".id="alt_msg".group_id
               where "group".status !=3 and "alt_msg".user_id = $1 and "alt_msg".create_date >=(current_date - interval '3' day)'''
        )
        total_records = await select_count.fetchval(user_id)
        page_info = get_page_info(page_size, current_page, total_records)
        return response_json(msg_infos, page_info=page_info)
Пример #11
0
async def export_result(request, *args, **kwargs):
    params = request.json
    sql, sql_count = await withdraw_sql(params)
    async with db.conn.acquire() as con:
        select_result = records_to_list(await con.fetch(sql))
    if not select_result:
        return response_json(None)
    title = ['phone', 'amount', 'create_date', 'paid_date', 'status']

    out = io.BytesIO()
    workbook = xlsxwriter.Workbook(out)
    worksheet = workbook.add_worksheet()
    for item in title:
        worksheet.write(0, title.index(item), item)
    for item in select_result:
        worksheet.write(
            select_result.index(item) + 1, 0,
            item['phone'] if item['phone'] is not None else '')
        worksheet.write(
            select_result.index(item) + 1, 1,
            item['amount'] if item['amount'] is not None else '')
        worksheet.write(
            select_result.index(item) + 1, 2,
            item['create_date'] if item['create_date'] is not None else '')
        worksheet.write(
            select_result.index(item) + 1, 3,
            item['paid_date'] if item['paid_date'] is not None else '')
        worksheet.write(
            select_result.index(item) + 1, 4,
            item['status'] if item['status'] is not None else '')

    workbook.close()
    out.seek(0)
    filename = quote("提现列表.xlsx")
    return raw(out.getvalue(),
               headers={
                   'Content-Disposition':
                   'attachment;filename*=utf-8{0}'.format(filename)
               },
               content_type='application/vnd.ms-excel;chartset=utf-8')
Пример #12
0
async def mass_message_detail_view(request, task_id, *args, **kwargs):
    '''群发消息详情'''
    async def mass_message_detail(id):
        async with db.conn.acquire() as con:
            st = await con.prepare(
                '''select group_ids::jsonb as "groups_info", content::jsonb, to_char(send_date, 'YYYY-MM-DD HH24:MI:SS') as send_date 
                   from "group_task" where id=$1 and status<>3''')
            group_task = await st.fetchrow(id)
            if not group_task:
                return
            group_task = dict(group_task)
            gst = await con.prepare(
                'select id, name from "group" where code = any($1) and status <> 3'
            )
            group_codes = ujson.loads(group_task['groups_info'])
            groups = await gst.fetch(group_codes)
        group_task['groups_info'] = records_to_list(groups)
        group_task['content'] = ujson.loads(group_task['content'])
        return group_task

    data = await mass_message_detail(task_id)
    return response_json(data)
Пример #13
0
async def user_share_poster(request, user_id):
    """用户分享海报"""
    async def streaming_fn(response):
        await response.write(image_bytes.getvalue())

    type = request.raw_args.get('type', None)
    if type is not None:
        background_image = os.path.join(BASE_DIR, 'static/{}.png').format(type)
    else:
        background_image = os.path.join(BASE_DIR, 'static/background.png')
    user_info = await get_user_info(user_id)
    if user_info is None:
        return response_json({}, RESOURCE_NOT_FOUND_CODE, msg='用户不存在')
    head_url = user_info['head_url']
    name = user_info['nickname']
    channel = user_info.get('channel', None)
    qr_code_url = QR_CODE_URL + '?sharing_user_id=' + user_id
    if channel is not None:
        qr_code_url = qr_code_url + '&channel=' + channel
    image_bytes = await create_user_share_poster(qr_code_url, head_url, name,
                                                 background_image, type)

    return stream(streaming_fn, content_type='image/jpeg')
Пример #14
0
async def mass_message_task_view(request, user):
    '''群发消息页面'''
    async def mass_message_data(direction, current_page, page_size):
        async with db.conn.acquire() as con:
            if direction == 'up':
                st = await con.prepare(
                    '''select to_char(send_date, 'YYYY-MM-DD HH24:MI:SS') as send_date, 
                       jsonb_array_length(group_ids)::int as group_counts, status, id
                       from "group_task" where user_id=$1 and status <> $2 and type=1
                       and send_date >= timestamp 'today' and send_date <= (current_date + interval '3' day) 
                       order by send_date desc limit $3 offset $4''')
                st_count = await con.prepare(
                    '''select count(1) from "group_task" where user_id=$1 and status <> $2 and type=1
                       and send_date >= timestamp 'today' and send_date < (current_date + interval '3' day)'''
                )
            else:
                st = await con.prepare(
                    '''select to_char(send_date, 'YYYY-MM-DD HH24:MI:SS') as send_date, 
                       jsonb_array_length(group_ids)::int as group_counts, status, id
                       from "group_task" where user_id=$1 and status <> $2 and type=1
                       and send_date < timestamp 'today' and send_date >= (current_date - interval '3' day)
                       order by send_date desc limit $3 offset $4''')
                st_count = await con.prepare(
                    '''select count(1) from "group_task" where user_id=$1 and status <> $2 and type=1
                       and send_date < timestamp 'today' and send_date >= (current_date - interval '3' day)'''
                )
            count = await st_count.fetchval(user['user_id'], FAIL_DELETE)
            datas = await st.fetch(user['user_id'], FAIL_DELETE, page_size,
                                   current_page * page_size)
        return records_to_list(datas), count

    current_page = int(request.raw_args.get('current_page', 0))
    page_size = int(request.raw_args.get('page_size', 20))
    direction = request.raw_args.get('direction', 'up')
    datas, count = await mass_message_data(direction, current_page, page_size)
    page_info = get_page_info(page_size, current_page, count)
    return response_json(datas, page_info=page_info)
Пример #15
0
async def get_user_groups_disciples(request, *args, **kwargs):
    """首页获取用户群数量和徒弟徒孙数量"""
    user_id = kwargs['user']['user_id']
    async with db.conn.acquire() as con:
        select_groups = await con.prepare(
            '''select count(1) from "group" where user_id =$1 and status !=3'''
        )
        group_count = await select_groups.fetchval(user_id)
        select_apprentice = await con.prepare(
            '''select count(1) from "sharing_record" where
               sharing_user_id =$1 and status !=3''')
        apprentice_count = await select_apprentice.fetchval(user_id)
        select_disciple = await con.prepare(
            '''with t as (select user_id from sharing_record where sharing_user_id=$1) 
               select count(1) from sharing_record,t where sharing_record.sharing_user_id=t.user_id'''
        )
        disciple_count = await select_disciple.fetchval(user_id)
        result = {
            'group_count': group_count,
            'disciples': int(apprentice_count) + int(disciple_count),  # 徒弟徒孙数量
            'apprentice': int(apprentice_count),  # 徒弟数量
            'disciple': int(disciple_count)  # 徒孙数量
        }
        return response_json(data=result)
Пример #16
0
async def set_app_status(request):
    '''设置app_status'''
    data = request.json
    data_json = ujson.dumps(data)
    await redis.conn.set(APP_STATUS_REDIS_KEY, data_json)
    return response_json(data)
Пример #17
0
async def alt_switch_info(request, *args, **kwargs):
    user_id = kwargs['user']['user_id']
    user_info = await get_user_by_id(user_id)
    if user_info is not None:
        switch = user_info['alt_switch']
        return response_json(switch)
Пример #18
0
async def get_user_id(request, user):
    user_id = user.get('user_id')
    return response_json(user_id)
Пример #19
0
async def users_statistic_view(request):
    '''bi数据统计回传, 账户加钱、群同步
    {
        "settle_date": "",
        "timestamp": "",
        "sign": "",
        "data": {"code": "amount"}
    }
    '''
    async def need_settlement_groups(groups):
        groups_join = ','.join(groups.keys())
        async with db.conn.acquire() as con:
            st = await con.prepare(
                '''select "group".id as group_id, "group".code, "user".id as user_id, "user".code as user_code
                   from "group" join "user" on "group".user_id="user".id where "group".status<>3 and 
                   exists(select tmp_code from (select unnest(string_to_array($1, ',')) as tmp_code) as tmp where tmp.tmp_code="group".code) 
                   order by "user".code''')
            data = await st.fetch(groups_join)
        return records_to_list(data)

    async def coroutine_thread_run_settle(groups, settle_date):
        settle_groups = await need_settlement_groups(groups)
        logger.info(f'need settle groups: {len(settle_groups)}')
        for user_code, items in await async_groupby(settle_groups,
                                                    'user_code'):
            copy_items = list(items)
            for item in copy_items:
                item['amount'] = groups.get(item['code'], 0)
            logger.debug(f'adv settle user code: {user_code}')
            try:
                await signle_user_groups_settlement(user_code,
                                                    copy_items,
                                                    settle_date,
                                                    settle_type=TYPE.AD_CLICK)
            except Exception as e:
                logger.error(f'user [{user_code} settle occer error: [{e}]]')

    async def check_settle_day_exist(date):
        async with db.conn.acquire() as con:
            st = await con.prepare(
                'select count(*) from "account_slip" where settle_date=$1 and amount_type=$2'
            )
            count = await st.fetchval(date, TYPE.AD_CLICK)
        if count > 0:
            logger.info(f'exist settle day {date} and find count {count}')
            return True
        return False

    logger.debug(f'settlement callback data #: {request.json}')
    timestamp = request.json.get('timestamp')
    sign = request.json.get('sign')
    settlement_date = request.json.get('settle_date')
    # 数据校验
    if not all([str(timestamp), sign, settlement_date]):
        return response_json(None, code=PARAMS_ERROR_CODE)
    secret_md5 = md5()
    secret_md5.update('#'.join([timestamp, MD5_SECRET_KEY]).encode('utf-8'))
    if secret_md5.hexdigest() != sign:
        return response_json(None, code=PARAMS_ERROR_CODE)
    groups = request.json.get('data', {})
    settle_date = str_to_date(settlement_date)
    if await check_settle_day_exist(settle_date):
        logger.error(f'exist duplicate call ad click, date {settle_date}')
        return response_json(None, code=DUPLICATE_REQUEST_CODE)
    loop = asyncio.get_event_loop()
    asyncio.run_coroutine_threadsafe(
        coroutine_thread_run_settle(groups, settle_date), loop)
    return response_json(None)
Пример #20
0
async def set_marquee_info(request):
    """设置跑马灯"""
    date = request.json
    data_json = ujson.dumps(date)
    await redis.conn.set(APP_MARQUEE_REDIS_KEY, data_json)
    return response_json('SUCCESS')
Пример #21
0
async def no_click_groups(request):
    group_codes = request.json.get('group_codes')
    logger.info(f'receive BI no click groups, count:{len(group_codes)}')
    redis_key = NO_CLICK_GROUPS_REDIS_KEY.format(today=today())
    await redis.conn.set(redis_key, ujson.dumps(group_codes), ex=24 * 60 * 60)
    return response_json(None)
Пример #22
0
async def users_info(request):
    '''
    返回给BI的数据
    {
        "user_id": string,               // 用户id
        "maps": {
            "father_id": string,         // 师傅
            "grand_father_id": string    // 师爷
        },
        "groups": ["", ""]              // 群id
        }
    }
    '''
    async def get_user_relationships(user_id):
        async with db.conn.acquire() as con:
            st = await con.prepare('''with recursive parent as (
                     select user_id, sharing_user_id, 0 as depth from "sharing_record" where user_id=$1
                   union
                     select psr.user_id, psr.sharing_user_id, depth - 1
                     from "sharing_record" psr join parent p on p.sharing_user_id=psr.user_id where p.depth > -1)
                   select "user".code as code, parent.depth from parent join "user" on parent.sharing_user_id="user".id;
                ''')
            users = await st.fetch(user_id)
        results = {'grand_father_id': None}
        for user in users:
            if user['depth'] == 0:
                results.update({'father_id': user['code']})
            elif user['depth'] == -1:
                results.update({'grand_father_id': user['code']})
        if len(results) == 1 and not results.get('grand_father_id'):
            results = None
        return results

    async def get_user_ids(datetime, user_ids):
        async with db.conn.acquire() as con:
            st = await con.prepare(
                '''select "user".id as user_id, "user".code as user_code, "group".code as group_code from "user" 
                   join "group" on "user".id="group".user_id
                   where "user".status<>3 and "group".status <>3 and "user".create_date <= to_timestamp($1, 'YYYY-MM-DD HH24:MI:SS') 
                   and "group".create_date <= to_timestamp($2, 'YYYY-MM-DD HH24:MI:SS') and "user".id=any($3) order by "user".id'''
            )
            users = await st.fetch(datetime, datetime, user_ids)
        return records_to_list(users), records_to_value_list(
            users, 'user_code')

    async def get_user_counts(datetime):
        async with db.conn.acquire() as con:
            st = await con.prepare('''select "user".id from "user" 
                   join "group" on "user".id="group".user_id where "user".status<>3 
                   and "group".status <>3 and "user".create_date <= to_timestamp($1, 'YYYY-MM-DD HH24:MI:SS') 
                   and "group".create_date <= to_timestamp($2, 'YYYY-MM-DD HH24:MI:SS') group by "user".id'''
                                   )
            total_users = await st.fetch(datetime, datetime)
        return records_to_value_list(total_users, 'id'), len(total_users)

    async def async_groupby(users, sort_key):
        return groupby(users, key=itemgetter(sort_key))

    async def pre_next_page_count(current_page, page_size):
        return current_page * page_size, (current_page + 1) * page_size

    logger.debug(f'receiver bi data: {request.json}')
    datetime = request.json.get('datetime')
    current_page = int(request.raw_args.get('current_page'))
    page_size = int(request.raw_args.get('page_size'))
    timestamp = request.json.get('timestamp')
    sign = request.json.get('sign')
    # 数据校验
    if not all([timestamp, sign]):
        return response_json(None, code=PARAMS_ERROR_CODE)
    secret_md5 = md5()
    secret_md5.update('#'.join([timestamp, MD5_SECRET_KEY]).encode('utf-8'))
    if secret_md5.hexdigest() != sign:
        return response_json(None, code=PARAMS_ERROR_CODE)
    data = []
    static_users, user_counts = await get_user_counts(datetime)
    pre_count, next_count = await pre_next_page_count(current_page, page_size)
    page_user_ids = static_users[pre_count:next_count]
    users, user_codes = await get_user_ids(datetime, page_user_ids)
    cache_maps = {}
    if user_codes:
        maps = await redis.conn.hmget(COMPLETE_USER_REDIS_KEY, user_codes)
        for key, value in zip(user_codes, maps):
            cache_maps[key] = value
    for user_code, items in await async_groupby(users, 'user_code'):
        user_maps = cache_maps.get(user_code)
        copy_items = list(items)
        user_id = copy_items[0]['user_id']
        groups = []
        for item in copy_items:
            groups.append(item['group_code'])
        if not user_maps:
            user_maps = await get_user_relationships(user_id=user_id)
        data.append({
            'user_id': user_code,
            'groups': groups,
            'maps': user_maps
        })
    page_info = get_page_info(page_size, current_page, user_counts)
    return response_json(data, page_info=page_info)
Пример #23
0
async def launch_switch(request, *args, **kwargs):
    '''设置投放开关'''
    group_info = request.json
    await currency_launch_switch(group_info)
    return response_json(None, msg='设置成功')
Пример #24
0
async def completion_task_view(request, task_id, *args, **kwargs):
    '''补全群发消息'''
    async def check_can_created_today(user_id, send_date):
        async with db.conn.acquire() as con:
            st = await con.prepare(
                '''select to_char(send_date, 'YYYY-MM-DD') as day, count(1) as count from "group_task" 
                   where user_id=$1 and status<>$2 and type = 1 group by to_char(send_date, 'YYYY-MM-DD')'''
            )
            day_group_count = records_to_list(await
                                              st.fetch(user_id, FAIL_DELETE))
        date = str_to_datetime(send_date)
        if date <= datetime.now():
            return False
        str_date = date.strftime('%Y-%m-%d')
        for item in day_group_count:
            if item['day'] == str_date and item['count'] >= MAX_MASS_MSG_AMOUNT:
                logger.info(
                    f'user [{user_id}] create mass msg max day [{str_date}]')
                return False
        return True

    async def check_group_same_time_created(send_date, group_ids):
        date = str_to_datetime(send_date)
        str_date_minute = date.strftime('%Y-%m-%d %H:%M')
        async with db.conn.acquire() as con:
            st = await con.prepare('''select count(1) from "group_task" 
                   where to_char(send_date, 'YYYY-MM-DD HH24:MI') = $1 and status<>3 and type = 1 and group_ids ?| $2'''
                                   )
            count = await st.fetchval(str_date_minute, group_ids)
        if count > 0:
            return False
        return True

    async def combine_content(message):
        '''组合消息'''
        task_content = await redis.conn.get(
            MASS_MSG_TASK_CREATE_REDIS_KEY.format(task_id=task_id))
        if not task_content:
            return None
        content = ujson.loads(task_content)
        content.append(message)
        return content

    async def save_task(id, content, group_ids, user_id, send_date):
        async with db.conn.acquire() as con:
            task_stmt = await con.prepare(
                '''insert into "group_task" (id, user_id, group_ids, content, status, send_date, type)
                   values ($1, $2, $3, $4, $5, to_timestamp($6, 'YYYY-MM-DD HH24:MI:SS'), 1)'''
            )
            await task_stmt.fetchval(id, user_id, group_ids, content,
                                     NOT_SEND_MSG, send_date)
        await redis.conn.expire(
            MASS_MSG_TASK_CREATE_REDIS_KEY.format(task_id=id), 0)

    async def create_redis_task(id, send_date):
        '''创建群发缓存'''
        timestamp = int(send_date.timestamp())
        await redis.conn.zadd(TASK_MSG_MONITOR_REDIS_KEY, timestamp, id)

    user_id = kwargs['user']['user_id']
    message = request.json.get('message')
    group_ids = request.json.get('group_ids')
    send_date = request.json.get('send_date')
    if not all([message, group_ids, send_date]):
        return response_json(None, code=PARAMS_ERROR_CODE, msg='缺少必要的参数')
    if not await check_can_created_today(user_id, send_date):
        return response_json(None, code=CREATED_FAILED_CODE, msg='达到当日最大创建次数')
    if not await check_group_same_time_created(send_date, group_ids):
        return response_json(None,
                             code=EXISTS_SAME_TIME_CREATED_CODE,
                             msg='同一群存在相同的发送时间')
    if not await aly_text_check(message['content']):
        return response_json(None, code=SENSITIVE_WORD_CODE, msg='检测到敏感词汇')
    content = await combine_content(message)
    if not content:
        return response_json(None, code=RESOURCE_NOT_FOUND_CODE, msg='群发消息已过期')
    content = ujson.dumps(content)
    group_ids = ujson.dumps(group_ids)
    await save_task(task_id, content, group_ids, user_id, send_date)
    send_date = str_to_datetime(send_date)
    await create_redis_task(task_id, send_date)
    return response_json(None)
Пример #25
0
async def user_withdraw_request_view(request, user, *args, **kwargs):
    '''用户发起提现请求'''
    async def static_user_withdrow_balance_month(account_id):
        async with db.conn.acquire() as con:
            select_stmt = await con.prepare(
                '''select case when sum(amount) is not null then sum(amount) else 0 end as balance from "account_withdraw" 
                   where account_id=$1 and status=any($2) and create_date >= date_trunc('month', current_date)'''
            )
            balance = await select_stmt.fetchval(
                account_id, [WITHDRAWING, WITHDRAW_SUCCESSED])
        return balance

    async def add_user_withdraw_record(account_id, user_id, amount):
        async with db.conn.acquire() as con:
            async with con.transaction():
                insert_stmt = await con.prepare(
                    '''insert into "account_withdraw" (id, account_id, user_id, amount, review_status, status)
                       values(uuid_generate_v4(), $1, $2, $3, 0, 0)
                    ''')
                update_stmt = await con.prepare(
                    '''update "account" set balance_amount = balance_amount-$1, 
                       withdrawing_amount = withdrawing_amount+$2, update_date=now() where id=$3'''
                )
                await insert_stmt.fetch(account_id, user_id, amount)
                await update_stmt.fetch(amount, amount, account_id)

    async def is_withdraw_today(account_id):
        async with db.conn.acquire() as con:
            st = await con.prepare(
                '''select exists(select id from "account_withdraw" where account_id=$1 
                   and status=$2 and create_date >= timestamp 'today')''')
            is_withdraw = await st.fetchval(account_id, WITHDRAWING)
        return is_withdraw

    user_id = user.get('user_id')
    withdraw_balance = request.json.get('balance', None)
    balance_amounts = [1, 20, 50, 100, 200, 500]
    # 余额参数校验
    if withdraw_balance is None or withdraw_balance not in balance_amounts:
        return response_json(None, code=PARAMS_ERROR_CODE, msg='未获取到提现金额参数')
    account_info = dict(await get_account_info(user_id))
    if account_info['balance_amount'] < withdraw_balance:
        return response_json(None,
                             code=INSUFFICIENT_AMOUNT_CODE,
                             msg='提现金额超过当前余额')
    # 用户校验
    user_info = dict(await get_user_by_id(user_id))
    if not user_info.get('phone'):
        return response_json(None, code=MISS_PHONE_CODE, msg='请补全用户手机号')
    if user_info.get('status', 1) == 2:
        return response_json(None, code=WITHDRAW_FAILED_CODE, msg='用户已封号禁止提现')
    month_withdraw_balance = await static_user_withdrow_balance_month(
        account_info['id'])
    # 超800税收身份证信息补全提醒
    if month_withdraw_balance + Decimal(
            withdraw_balance) > WITHDRAW_TAX_AMOUNT:
        if not user_info.get('identity_info'):
            return response_json(None, code=MISS_IDCARD_CODE, msg='请补全用户身份证信息')
    if await is_withdraw_today(account_info['id']):
        return response_json(None, code=REVOKED_TODAY_CODE, msg='今天已提现')
    logger.info(
        f'user [{user_id} request withdraw balance [{withdraw_balance}]')
    await add_user_withdraw_record(account_info['id'], user_id,
                                   withdraw_balance)
    return response_json(None, msg='提现进入审核状态')
Пример #26
0
async def long_to_short_view(request):
    long_url = request.json.get('url')
    short_url = await long_to_short(long_url)
    return response_json(short_url)
Пример #27
0
async def robot_distribution_view(request):
    """
    - 分配机器人
    - 更新或绑定师徒关系
    - 创建机器人用户展示表
    """
    async def exists_user_access(union_id):
        async with db.conn.acquire() as con:
            select_stmt = await con.prepare(
                '''select "robot_access".id from "robot_access" join "robot" on "robot".id="robot_access".robot_id 
                   where "robot_access".union_id=$1 and "robot".status<>3 
                   order by "robot_access".create_date desc limit 1''')
            access_id = await select_stmt.fetchval(union_id)
            return access_id

    async def update_user_access(user_access_id,
                                 sharing_user_id=None,
                                 channel=None):
        if not sharing_user_id:
            is_sharing_user = False
        else:
            is_sharing_user = True
        async with db.conn.acquire() as con:
            update_stmt = await con.prepare(
                '''update "robot_access" set sharing_user_id=case when $1 then $2 else sharing_user_id end, 
                   channel=case when $3 then $4 else channel end, 
                   update_date=now() where id=$5 returning robot_id''')
            return await update_stmt.fetchval(is_sharing_user, sharing_user_id,
                                              is_sharing_user, channel,
                                              user_access_id)

    async def create_user_access(open_id,
                                 union_id,
                                 robot_id,
                                 sharing_user_id=None,
                                 channel=None):
        async with db.conn.acquire() as con:
            insert_stmt = await con.prepare('''insert into "robot_access" 
                   (id, open_id, union_id, robot_id, sharing_user_id, channel, status)
                   values (uuid_generate_v4(), $1, $2, $3, $4, $5, $6)''')
            await insert_stmt.fetch(open_id, union_id, robot_id,
                                    sharing_user_id, channel, CREATE_STATUS)

    async def robot_info(robot_id):
        '''查询机器人信息'''
        async with db.conn.acquire() as con:
            select_stmt = await con.prepare(
                'select head_url, qr_code, wechat_no, name from "robot" where id=$1'
            )
            robot = await select_stmt.fetchrow(robot_id)
        return robot

    open_id = request.json.get('open_id')
    union_id = request.json.get('union_id')
    if not open_id or not union_id:
        return response_json(None,
                             code=PARAMS_ERROR_CODE,
                             msg='缺少必要参数open_id或union_id')
    sharing_user_id = request.json.get('sharing_user_id', None)
    channel = request.json.get('channel', None)
    access_id = await exists_user_access(union_id)
    if access_id:
        if not sharing_user_id or sharing_user_id == 'null':
            sharing_user_id = None
        if not channel:
            channel = None
        robot_id = await update_user_access(access_id, sharing_user_id,
                                            channel)
    else:
        robot_id = await robot_distribution(channel=channel)
        if not robot_id:
            logger.warning(f'not match distribute robot for user [{open_id}]')
            return response_json(None,
                                 code=ROBOT_NOT_ENOUGH_CODE,
                                 msg='没有可分配的机器人')
        await create_user_access(open_id, union_id, robot_id, sharing_user_id,
                                 channel)
        await robot_today_display_record(robot_id)
    logger.info(f'distribute robot [{robot_id}] for user [{open_id}]')
    robot = await robot_info(robot_id)
    return response_json(dict(robot))