|
# -*- coding: utf-8 -*-
from __future__ import division
import json
import shortuuid
from curtail_uuid import CurtailUUID
from django.conf import settings
from django.core.serializers.json import DjangoJSONEncoder
from logit import logit
from TimeConvert import TimeConvert as tc
from account.models import UserInfo
from group.models import GroupInfo, GroupUserInfo
from utils.error.errno_utils import GroupStatusCode, GroupUserStatusCode, TokenStatusCode, UserStatusCode
from utils.error.response_utils import response
from utils.redis.rgroup import get_group_info, get_group_users_info, set_group_info, set_group_users_info
from utils.redis.rkeys import (TOUR_GUIDE_GROUP_CUR_GATHER_INFO, TOUR_GUIDE_GROUP_CUR_SESSION,
TOUR_GUIDE_GROUP_GEO_SUBMIT_DT)
from utils.redis.rtourguide import get_tour_guide_own_group, set_tour_guide_own_group
from utils.redis.rtouruser import get_tour_user_belong_group
from utils.storage_utils import file_save
r = settings.REDIS_CACHE
@logit
def tg_group_create_api(request):
""" 旅行团创建 """
user_id = request.POST.get('user_id', '')
group_name = request.POST.get('group_name', '')
group_default_avatar = int(request.POST.get('group_default_avatar', 0))
started_at = tc.utc_string_to_utc_datetime(request.POST.get('started_at', ''), format='%Y-%m-%dT%H:%M:%SZ') # UTC, %Y-%m-%dT%H:%M:%SZ
ended_at = tc.utc_string_to_utc_datetime(request.POST.get('ended_at', ''), format='%Y-%m-%dT%H:%M:%SZ') # UTC, %Y-%m-%dT%H:%M:%SZ
total_persons = int(request.POST.get('total_persons', 1))
# 用户校验
try:
user = UserInfo.objects.get(user_id=user_id)
except UserInfo.DoesNotExist:
return response(UserStatusCode.USER_NOT_FOUND)
# 权限校验
if not user.istourguide:
return response(GroupStatusCode.NOT_GROUP_ADMIN)
# 旅行团校验
if GroupInfo.objects.filter(
admin_id=user_id,
group_closed=False,
status=True,
ended_at__gt=tc.utc_datetime(),
).exists():
return response(GroupStatusCode.COULD_HAVE_ONLY_ONE_ACTIVE_GROUP)
# 群组唯一标识
group_id = CurtailUUID.uuid(GroupInfo, 'group_id')
# 群组记录创建
group = GroupInfo.objects.create(
group_id=group_id,
admin_id=user_id,
group_name=group_name,
group_default_avatar=group_default_avatar,
group_from=GroupInfo.TOURGUIDE_GROUP,
name=user.name,
phone=user.phone,
started_at=started_at,
ended_at=ended_at,
total_persons=total_persons,
)
# Redis 群组数据缓存
group_info = set_group_info(group)
# 群组用户记录创建
GroupUserInfo.objects.create(
group_id=group_id,
user_id=user_id,
nickname=user.final_nickname,
avatar=user.avatar,
admin=True,
user_status=GroupUserInfo.PASSED,
passed_at=tc.utc_datetime(),
subadmin=True,
name=user.name,
phone=user.phone,
)
# Redis 群组用户数据缓存
group_users = set_group_users_info(group)
# Redis 设置导游拥有的旅行团
set_tour_guide_own_group(user_id, group_id)
return response(200, 'Create Tour Guide Group Success', u'旅行团创建成功', {
'group_id': group_id,
'group': group_info,
'users': group_users,
})
def set_geo_submit_flag(uinfo, geo_at, gather_at):
uinfo['geo_submited'] = False
if geo_at and gather_at:
current_dt = tc.utc_datetime()
delta_seconds = tc.total_seconds(gather_at - current_dt)
# 距离集合时间超过30分钟是5分钟,15分钟到30分钟是3分钟,15分钟以内是1分钟
for delta, gdt in [(1800, 300), (900, 180), (0, 60)]:
if delta_seconds > delta:
uinfo['geo_submited'] = tc.total_seconds(current_dt - geo_at) <= gdt
break
return uinfo
@logit
def tg_group_detail_api(request):
""" 旅行团详情 """
group_id = request.POST.get('group_id', '')
user_id = request.POST.get('user_id', '')
# GEO last submit datetimes
geo_dts = r.hgetall(TOUR_GUIDE_GROUP_GEO_SUBMIT_DT % group_id)
group_info = get_group_info(group_id)
# Gather datetime
gather_at = group_info.get('gather_at', '')
gather_at = tc.utc_string_to_utc_datetime(gather_at, format='%Y-%m-%dT%H:%M:%SZ') if isinstance(gather_at, basestring) else gather_at
if gather_at and tc.utc_datetime() > gather_at:
gather_at = ''
group_users_info = get_group_users_info(group_id, user_id)
# Remove tourguide
group_passed_users = [uinfo for uinfo in group_users_info['passed'] if not uinfo['subadmin']]
# GEO Submited Flag
group_passed_users = [set_geo_submit_flag(uinfo, tc.utc_string_to_utc_datetime(geo_dts.get(uinfo['user_id'], '')), gather_at) for uinfo in group_passed_users]
group_users_info['passed'] = group_passed_users
# Update passed count
group_users_info['passed_count'] = len(group_passed_users)
# Sum(relative_persons)
group_users_info['relative_persons'] = sum([user['relative_persons'] for user in group_passed_users])
return response(200, 'Get Tour Guide Group Detail Info Success', u'获取旅行团详情成功', {
'group_id': group_id,
'group': group_info,
'users': group_users_info,
})
@logit
def pai2_tginfo_api(request):
""" 首页旅行团信息 """
user_id = request.POST.get('user_id', '')
# 获取用户当前所处旅行团
group_id = get_tour_user_belong_group(user_id)
if not group_id:
return response(GroupUserStatusCode.USER_HAS_NOT_JOIN_GROUP)
group_info = get_group_info(group_id)
gather_at = group_info.get('gather_at', '')
if gather_at and tc.utc_datetime() > (tc.utc_string_to_utc_datetime(gather_at, format='%Y-%m-%dT%H:%M:%SZ') if isinstance(gather_at, basestring) else gather_at):
group_info['gather_at'] = ''
group_info['gather_lon'] = ''
group_info['gather_lat'] = ''
group_info['gather_location'] = ''
return response(200, 'Get Tour Guide Group Detail Info Success', u'获取旅行团详情成功', {
'group_id': group_id,
'group': group_info,
'users': get_group_users_info(group_id, user_id),
})
@logit(body=settings.LOGIT_BODY_FLAG, res=settings.LOGIT_RES_FLAG)
def tg_group_update_api(request):
""" 旅行团更新 """
group_id = request.POST.get('group_id', '')
admin_id = request.POST.get('admin_id', '') or request.POST.get('user_id', '')
group_name = request.POST.get('group_name', '')
group_desc = request.POST.get('group_desc', '')
group_avatar = request.FILES.get('group_avatar', '')
started_at = tc.utc_string_to_utc_datetime(request.POST.get('started_at', ''), format='%Y-%m-%dT%H:%M:%SZ') # UTC, %Y-%m-%dT%H:%M:%SZ
ended_at = tc.utc_string_to_utc_datetime(request.POST.get('ended_at', ''), format='%Y-%m-%dT%H:%M:%SZ') # UTC, %Y-%m-%dT%H:%M:%SZ
total_persons = int(request.POST.get('total_persons', 0))
attentions = request.FILES.get('attentions', '')
schedules = request.FILES.get('schedules', '')
# 群组校验
try:
group = GroupInfo.objects.get(group_id=group_id)
except GroupInfo.DoesNotExist:
return response(GroupStatusCode.GROUP_NOT_FOUND)
# 权限校验
if group.admin_id != admin_id:
return response(GroupStatusCode.NO_UPDATE_PERMISSION)
# 群组名称更新
if group_name:
group.group_name = group_name
# 群组描述更新
if group_desc:
group.group_desc = group_desc
# 群组头像更新
if group_avatar:
group.group_avatar = file_save(group_avatar, prefix='group', ext='jpeg')[0]
# 起止时间更新
if started_at:
group.started_at = started_at
if ended_at:
group.ended_at = ended_at
# 旅行团总人数更新
if total_persons:
group.total_persons = total_persons
# 注意事项更新
if attentions:
group.attentions_path = file_save(attentions, prefix='tour', ext='jpeg')[0]
# 行程安排更新
if schedules:
group.schedules_path = file_save(schedules, prefix='tour', ext='jpeg')[0]
group.save()
# Redis 群组数据缓存更新
group_info = set_group_info(group)
return response(200, 'Update Group Success', u'群组更新成功', {
'group_id': group_id,
'group': group_info,
'users': get_group_users_info(group_id, admin_id),
})
@logit
def tg_group_close_api(request):
""" 旅行团关闭 """
group_id = request.POST.get('group_id', '')
admin_id = request.POST.get('admin_id', '') or request.POST.get('user_id', '')
# 群组校验
try:
group = GroupInfo.objects.get(group_id=group_id)
except GroupInfo.DoesNotExist:
return response(GroupStatusCode.GROUP_NOT_FOUND)
# 权限校验
if group.admin_id != admin_id:
return response(GroupStatusCode.NO_CLOSE_PERMISSION)
# 群组解锁
group.group_closed = True
group.closed_at = tc.utc_datetime()
group.save()
# Redis 群组数据缓存更新
set_group_info(group)
return response(200, 'Close Tour Guide Group Success', u'旅行团关闭成功')
@logit
def tg_group_gather_start_api(request):
""" 旅行团设置集合时间和地点 """
group_id = request.POST.get('group_id', '')
admin_id = request.POST.get('admin_id', '') or request.POST.get('user_id', '')
gather_at = tc.utc_string_to_utc_datetime(request.POST.get('gather_at', ''), format='%Y-%m-%dT%H:%M:%SZ') # UTC, %Y-%m-%dT%H:%M:%SZ
gather_lon = request.POST.get('lon', '') # 经度
gather_lat = request.POST.get('lat', '') # 纬度
gather_location = request.POST.get('gather_location', '') # 地点
# 群组校验
try:
group = GroupInfo.objects.get(group_id=group_id)
except GroupInfo.DoesNotExist:
return response(GroupStatusCode.GROUP_NOT_FOUND)
# 权限校验
if not GroupUserInfo.objects.filter(group_id=group_id, user_id=admin_id, subadmin=True, status=True).exists():
return response(GroupStatusCode.NO_UPDATE_PERMISSION)
# 集合信息设置
group.gather_at = gather_at
group.gather_lon = gather_lon
group.gather_lat = gather_lat
group.gather_location = gather_location
group.save()
# Redis 群组数据缓存更新
set_group_info(group)
# 更新Session
r.pipeline().set(TOUR_GUIDE_GROUP_CUR_SESSION % group_id, shortuuid.uuid()).set(TOUR_GUIDE_GROUP_CUR_GATHER_INFO % group_id, json.dumps({
'gather_at': gather_at,
'gather_lon': gather_lon,
'gather_lat': gather_lat,
'gather_location': gather_location,
}, cls=DjangoJSONEncoder)).execute()
return response(200, 'Set Tour Guide Group Gather Info Success', u'设置旅行团集合信息成功')
@logit
def tg_group_token_api(request):
""" 旅行团权限管理票据 """
admin_id = request.POST.get('admin_id', '') or request.POST.get('user_id', '')
# 获取旅行团唯一标识
group_id = get_tour_guide_own_group(admin_id)
return response(200, 'Generate Token Success', u'生成票据成功', {
'token': r.token(group_id + admin_id, time=180)
})
@logit
def tg_group_transfer_api(request):
""" 旅行团权限管理转移 """
admin_id = request.POST.get('admin_id', '') # 导游唯一标识,识别二维码获取
user_id = request.POST.get('user_id', '')
token = request.POST.get('token', '')
# 获取旅行团唯一标识
group_id = get_tour_guide_own_group(admin_id)
# 票据校验
if not r.token_exists(group_id + admin_id, token):
return response(TokenStatusCode.TOKEN_NOT_FOUND)
# 用户校验
try:
user = UserInfo.objects.get(user_id=user_id)
except UserInfo.DoesNotExist:
return response(UserStatusCode.USER_NOT_FOUND)
# 群组校验
try:
group = GroupInfo.objects.get(group_id=group_id)
except GroupInfo.DoesNotExist:
return response(GroupStatusCode.GROUP_NOT_FOUND)
# 权限校验
if not GroupUserInfo.objects.filter(group_id=group_id, user_id=admin_id, admin=True, status=True).exists():
return response(GroupStatusCode.NO_TRANSFER_PERMISSION)
# 群组用户记录创建,若记录不存在,则创建,若记录已存在,则更新
group_user, created = GroupUserInfo.objects.get_or_create(
group_id=group_id,
user_id=user_id,
defaults={
'nickname': user.final_nickname,
'avatar': user.avatar,
'user_status': GroupUserInfo.PASSED,
'passed_at': tc.utc_datetime(),
'subadmin': True,
'name': user.name,
'phone': user.phone,
}
)
if not created:
group_user.current_id = -1
group_user.nickname = user.final_nickname
group_user.avatar = user.avatar
group_user.user_status = GroupUserInfo.PASSED
group_user.passed_at = tc.utc_datetime()
group_user.subadmin = True
group_user.name = user.name
group_user.phone = user.phone
group_user.save()
# Redis 群组用户数据缓存
group_users = set_group_users_info(group)
return response(200, 'Create Tour Guide Group Success', u'旅行团创建成功', {
'group_id': group_id,
'group': group.data,
'users': group_users,
})
|