=" item" href="/Kodo/kodo/pulls"> Pull Requests 0 Commits 906 Releases 0

No Description

models.py 21KB

    # -*- coding: utf-8 -*- from django.db import models from django.utils.translation import ugettext_lazy as _ from django_models_ext import BaseModelMixin, SexModelMixin from jsonfield import JSONField from kodo.basemodels import LensmanTypeBoolMixin from mch.models import SaleclerkInfo class LensmanInfo(BaseModelMixin, LensmanTypeBoolMixin): MALE = 1 FEMALE = 0 SEX_TYPE = ( (MALE, u'男'), (FEMALE, u'女'), ) REFUSED = -1 UNVERIFIED = 0 ACTIVATED = 1 DISABLED = 2 DELETED = 3 ASSIGN = 10 USER_STATUS = ( (REFUSED, u'已拒绝'), (UNVERIFIED, u'未验证'), (ACTIVATED, u'已激活'), (DISABLED, u'已禁用'), (DELETED, u'已删除'), (ASSIGN, u'已分配'), ) lensman_id = models.CharField(_(u'lensman_id'), max_length=32, blank=True, null=True, help_text=u'摄影师唯一标识', db_index=True, unique=True) unionid = models.CharField(_(u'unionid'), max_length=32, blank=True, null=True, help_text=u'微信 Union ID', db_index=True, unique=True) username = models.CharField(_(u'username'), max_length=255, blank=True, null=True, help_text=u'摄影师用户名', db_index=True, unique=True) password = models.CharField(_(u'password'), max_length=255, blank=True, null=True, help_text=u'摄影师密码') encryption = models.CharField(_(u'encryption'), max_length=255, blank=True, null=True, help_text=u'摄影师密码') name = models.CharField(_(u'name'), max_length=255, blank=True, null=True, help_text=u'摄影师姓名') sex = models.IntegerField(_(u'sex'), choices=SexModelMixin.SEX_TUPLE, default=SexModelMixin.UNKNOWN, help_text=u'摄影师性别') phone = models.CharField(_(u'phone'), max_length=11, blank=True, null=True, help_text=u'摄影师电话', db_index=True) location = models.CharField(_(u'location'), max_length=255, blank=True, null=True, help_text=u'摄影师地址') proportion = models.FloatField(_(u'proportion'), default=1.0, help_text=u'摄影师分成比例(0.0 ~ 1.0)') nomark = models.IntegerField(_(u'nomark'), default=299, help_text=u'摄影师无水印价格(分)') origin = models.IntegerField(_(u'origin'), default=999, help_text=u'摄影师高清图价格(分)') balance = models.IntegerField(_(u'balance'), default=0, help_text=u'摄影师余额(分)') freeze_income_balance = models.IntegerField(_(u'freeze_income_balance'), default=0, help_text=u'摄影师收入冻结余额(分)') freeze_expense_balance = models.IntegerField(_(u'freeze_expense_balance'), default=0, help_text=u'摄影师支出冻结余额(分)') user_status = models.IntegerField(_(u'user_status'), choices=USER_STATUS, default=UNVERIFIED, help_text=u'普通摄影师审核状态') outtake_status = models.IntegerField(_(u'outtake_status'), choices=USER_STATUS, default=UNVERIFIED, help_text=u'花絮摄影师审核状态') refused_reason = models.TextField(_(u'refused_reason'), blank=True, null=True, help_text=u'审核拒绝原因') signup_ip = models.CharField(_(u'signup_ip'), max_length=32, blank=True, null=True, help_text=_(u'注册IP')) login_ip = models.CharField(_(u'login_ip'), max_length=32, blank=True, null=True, help_text=_(u'登录IP')) login_at = models.DateTimeField(_(u'login_at'), blank=True, null=True, help_text=_(u'登录时间')) class Meta: verbose_name = _(u'lensmaninfo') verbose_name_plural = _(u'lensmaninfo') def __unicode__(self): return unicode(self.pk) def final_status(self, lensman_type): if lensman_type == self.COMMON: # 普通摄影师校验 return self.user_status elif lensman_type == self.OUTTAKE: # 花絮摄影师校验 return self.outtake_status return self.user_status def data(self, lensman_type): return { 'name': self.name, 'sex': self.sex, 'phone': self.phone, 'location': self.location, 'status': self.final_status(lensman_type), 'refused_reason': self.refused_reason, } def modified(self, lensman_type): if lensman_type == self.COMMON: # 普通摄影师校验 return self.user_status in [self.UNVERIFIED, self.REFUSED] elif lensman_type == self.OUTTAKE: # 花絮摄影师校验 return self.outtake_status in [self.UNVERIFIED, self.REFUSED] return False class LensmanLoginLogInfo(BaseModelMixin): SUCCESS = 0 PWD_ERROR = 1 OTHER = 2 LOGIN_RESULT = ( (SUCCESS, u'登录成功'), (PWD_ERROR, u'密码错误'), (OTHER, u'其他'), ) lensman_id = models.CharField(_(u'lensman_id'), max_length=32, blank=True, null=True, help_text=u'摄影师唯一标识', db_index=True) login_ip = models.CharField(_(u'login_ip'), max_length=32, blank=True, null=True, help_text=_(u'登录IP')) login_result = models.IntegerField(_(u'login_result'), choices=LOGIN_RESULT, default=SUCCESS) class Meta: verbose_name = _(u'lensmanloginloginfo') verbose_name_plural = _(u'lensmanloginloginfo') def __unicode__(self): return unicode(self.pk) class LensmanIncomeExpensesInfo(BaseModelMixin): INCOME = 0 EXPENSE = 1 UNFREEZE = 2 TYPE = ( (INCOME, u'收入'), (EXPENSE, u'支出'), (UNFREEZE, u'解冻'), ) lensman_id = models.CharField(_(u'lensman_id'), max_length=32, blank=True, null=True, help_text=u'摄影师唯一标识', db_index=True) photo_id = models.CharField(_(u'photo_id'), max_length=32, blank=True, null=True, help_text=u'照片唯一标识', db_index=True) type = models.IntegerField(_(u'type'), choices=TYPE, default=INCOME, help_text=u'收支类别') amount = models.IntegerField(_(u'amount'), default=0, help_text=u'余额增减数量(分)') balance = models.IntegerField(_(u'balance'), default=0, help_text=u'余额增减后数量(分)') freeze_income_amount = models.IntegerField(_(u'freeze_income_amount'), default=0, help_text=u'收入冻结余额增减数量(分)') freeze_income_balance = models.IntegerField(_(u'freeze_income_balance'), default=0, help_text=u'收入冻结余额增减后数量(分)') freeze_expense_amount = models.IntegerField(_(u'freeze_expense_amount'), default=0, help_text=u'支出冻结余额增减数量(分)') freeze_expense_balance = models.IntegerField(_(u'freeze_expense_balance'), default=0, help_text=u'支出冻结余额增减后数量(分)') remark = models.CharField(_(u'remark'), max_length=255, blank=True, null=True, help_text=u'备注') class Meta: verbose_name = _(u'lensmanincomeexpensesinfo') verbose_name_plural = _(u'lensmanincomeexpensesinfo') def __unicode__(self): return unicode(self.pk) class TourGuideInfo(BaseModelMixin): MALE = 1 FEMALE = 0 SEX_TYPE = ( (MALE, u'男'), (FEMALE, u'女'), ) REFUSED = -1 UNVERIFIED = 0 ACTIVATED = 1 DISABLED = 2 DELETED = 3 ASSIGN = 10 USER_STATUS = ( (REFUSED, u'已拒绝'), (UNVERIFIED, u'未验证'), (ACTIVATED, u'已激活'), (DISABLED, u'已禁用'), (DELETED, u'已删除'), (ASSIGN, u'已分配'), ) tourguide_id = models.CharField(_(u'tourguide_id'), max_length=32, blank=True, null=True, help_text=u'导游唯一标识', db_index=True, unique=True) unionid = models.CharField(_(u'unionid'), max_length=32, blank=True, null=True, help_text=u'微信 Union ID', db_index=True, unique=True) name = models.CharField(_(u'name'), max_length=255, blank=True, null=True, help_text=u'导游姓名') sex = models.IntegerField(_(u'sex'), choices=SexModelMixin.SEX_TUPLE, default=SexModelMixin.UNKNOWN, help_text=u'导游性别') phone = models.CharField(_(u'phone'), max_length=11, blank=True, null=True, help_text=u'导游电话', db_index=True) location = models.CharField(_(u'location'), max_length=255, blank=True, null=True, help_text=u'导游地址') no = models.CharField(_(u'no'), max_length=16, blank=True, null=True, help_text=u'导游证编号') user_status = models.IntegerField(_(u'user_status'), choices=USER_STATUS, default=UNVERIFIED) refused_reason = models.TextField(_(u'refused_reason'), blank=True, null=True, help_text=u'审核拒绝原因') class Meta: verbose_name = _(u'tourguideinfo') verbose_name_plural = _(u'tourguideinfo') def __unicode__(self): return unicode(self.pk) @property def photo_url(self): return '' @property def data(self): return { 'name': self.name, 'sex': self.sex, 'phone': self.phone, 'location': self.location, 'no': self.no, 'photo': self.photo_url, 'status': self.user_status, 'refused_reason': self.refused_reason, } @property def modified(self): return self.user_status in [self.UNVERIFIED, self.REFUSED] class WechatInfo(BaseModelMixin): MALE = 1 FEMALE = 0 SEX_TYPE = ( (MALE, u'男'), (FEMALE, u'女'), ) unionid = models.CharField(_(u'unionid'), max_length=32, blank=True, null=True, help_text=u'微信 Union ID') openids = JSONField(_(u'openids'), blank=True, null=True, help_text=u'微信 Open IDs') sex = models.IntegerField(_(u'sex'), choices=SexModelMixin.SEX_TUPLE, default=SexModelMixin.UNKNOWN, help_text=u'用户性别') nickname = models.CharField(_(u'nickname'), max_length=255, blank=True, null=True, help_text=u'用户昵称') headimgurl = models.CharField(_(u'headimgurl'), max_length=255, blank=True, null=True, help_text=u'用户头像') country = models.CharField(_(u'country'), max_length=255, blank=True, null=True, help_text=u'用户国家') province = models.CharField(_(u'province'), max_length=255, blank=True, null=True, help_text=u'用户省份') city = models.CharField(_(u'city'), max_length=255, blank=True, null=True, help_text=u'用户城市') location = models.CharField(_(u'location'), max_length=255, blank=True, null=True, help_text=u'用户地址') class Meta: verbose_name = _(u'wechatinfo') verbose_name_plural = _(u'wechatinfo') def __unicode__(self): return unicode(self.pk) class UserInfo(BaseModelMixin, LensmanTypeBoolMixin): APP_USER = 0 WX_USER = 1 USER_USER = 8 GUEST_USER = 9 LENSMAN_USER = 10 TOURGUIDE_USER = 11 MINIAPP_USER = 12 OAUTH_USER = 13 USER_FROM = ( (APP_USER, u'APP 创建用户'), (WX_USER, u'微信授权用户'), (USER_USER, u'用户端用户'), (GUEST_USER, u'游客用户'), (LENSMAN_USER, u'摄影师端用户'), (TOURGUIDE_USER, u'导游端用户'), (MINIAPP_USER, u'小程序端用户'), (OAUTH_USER, u'网页授权用户'), ) UNVERIFIED = 0 ACTIVATED = 1 DISABLED = 2 DELETED = 3 ASSIGN = 10 USER_STATUS = ( (UNVERIFIED, u'未验证'), (ACTIVATED, u'已激活'), (DISABLED, u'已禁用'), (DELETED, u'已删除'), (ASSIGN, u'已分配'), ) MALE = 1 FEMALE = 0 SEX_TYPE = ( (MALE, u'男'), (FEMALE, u'女'), ) brand_id = models.CharField(_(u'brand_id'), max_length=32, blank=True, null=True, help_text=u'品牌唯一标识', db_index=True) user_id = models.CharField(_(u'user_id'), max_length=32, blank=True, null=True, help_text=u'用户唯一标识', db_index=True, unique=True) user_from = models.IntegerField(_(u'user_from'), choices=USER_FROM, default=APP_USER, help_text=u'用户来源') uuid = models.CharField(_(u'uuid'), max_length=255, blank=True, null=True, help_text=u'通用唯一识别码 (Universally Unique Identifier)', db_index=True) # APP 创建用户 username = models.CharField(_(u'username'), max_length=255, blank=True, null=True, help_text=u'用户用户名', db_index=True) password = models.CharField(_(u'password'), max_length=255, blank=True, null=True, help_text=u'用户密码') # 微信授权用户 unionid = models.CharField(_(u'unionid'), max_length=32, blank=True, null=True, help_text=u'微信 Unionid', db_index=True) openid = models.CharField(_(u'openid'), max_length=32, blank=True, null=True, help_text=u'微信 Openid,拍爱用户端', db_index=True) openid_lensman = models.CharField(_(u'openid_lensman'), max_length=32, blank=True, null=True, help_text=u'微信 Openid,拍爱摄影师端', db_index=True) openid_tourguide = models.CharField(_(u'openid_tourguide'), max_length=32, blank=True, null=True, help_text=u'微信 Openid,拍爱导游端', db_index=True) openid_miniapp = models.CharField(_(u'openid_miniapp'), max_length=32, blank=True, null=True, help_text=u'微信 Openid,拍爱小程序', db_index=True) openid_oauth = models.CharField(_(u'openid_oauth'), max_length=32, blank=True, null=True, help_text=u'微信 Openid,拍爱用户授权', db_index=True) # 用户基本信息 name = models.CharField(_(u'name'), max_length=255, blank=True, null=True, help_text=u'用户姓名') sex = models.IntegerField(_(u'sex'), choices=SexModelMixin.SEX_TUPLE, default=SexModelMixin.UNKNOWN, help_text=u'用户性别') nickname = models.CharField(_(u'nickname'), max_length=255, blank=True, null=True, help_text=u'用户昵称') avatar = models.CharField(_(u'avatar'), max_length=255, blank=True, null=True, help_text=u'用户头像') phone = models.CharField(_(u'phone'), max_length=11, blank=True, null=True, help_text=u'用户电话', db_index=True) country = models.CharField(_(u'country'), max_length=255, blank=True, null=True, help_text=u'用户国家') province = models.CharField(_(u'province'), max_length=255, blank=True, null=True, help_text=u'用户省份') city = models.CharField(_(u'city'), max_length=255, blank=True, null=True, help_text=u'用户城市') location = models.CharField(_(u'location'), max_length=255, blank=True, null=True, help_text=u'用户地址') # 用户身份 islensman = models.BooleanField(_(u'islensman'), default=False, help_text=_(u'摄影师?'), db_index=True) istourguide = models.BooleanField(_(u'istourguide'), default=False, help_text=_(u'导游?'), db_index=True) balance = models.IntegerField(_(u'balance'), default=0, help_text=u'用户余额(分)') freeze_income_balance = models.IntegerField(_(u'freeze_income_balance'), default=0, help_text=u'用户收入冻结余额(分)') freeze_expense_balance = models.IntegerField(_(u'freeze_expense_balance'), default=0, help_text=u'用户支出冻结余额(分)') user_status = models.IntegerField(_(u'user_status'), choices=USER_STATUS, default=UNVERIFIED, help_text=u'用户状态') outtake_status = models.IntegerField(_(u'outtake_status'), choices=USER_STATUS, default=UNVERIFIED, help_text=u'花絮摄影师状态') assign_ip = models.CharField(_(u'assign_ip'), max_length=32, blank=True, null=True, help_text=_(u'分配IP')) assign_at = models.DateTimeField(_(u'assign_at'), blank=True, null=True, help_text=_(u'分配时间')) signup_ip = models.CharField(_(u'signup_ip'), max_length=32, blank=True, null=True, help_text=_(u'注册IP')) signup_at = models.DateTimeField(_(u'signup_at'), blank=True, null=True, help_text=_(u'注册时间')) login_ip = models.CharField(_(u'login_ip'), max_length=32, blank=True, null=True, help_text=_(u'登录IP')) login_at = models.DateTimeField(_(u'login_at'), blank=True, null=True, help_text=_(u'登录时间')) has_membercard = models.BooleanField(_(u'has_membercard'), default=False, help_text=_(u'是否激活会员卡'), db_index=True) membercardid = models.CharField(_(u'membercardid'), max_length=32, blank=True, null=True, help_text=_(u'会员卡编号'), db_index=True) memberusercardcode = models.CharField(_(u'memberusercardcode'), max_length=32, blank=True, null=True, help_text=_(u'用户会员卡编号'), db_index=True) clerk_id = models.CharField(_(u'clerk_id'), max_length=32, blank=True, null=True, help_text=u'店员唯一标识', db_index=True) test_user = models.BooleanField(_(u'test_user'), default=False, help_text=_(u'是否为测试用户'), db_index=True) class Meta: verbose_name = _(u'userinfo') verbose_name_plural = _(u'userinfo') unique_together = ( ('brand_id', 'unionid') ) def __unicode__(self): return unicode(self.pk) @property def final_nickname(self): if self.user_from == self.APP_USER: return self.username elif self.user_from == self.WX_USER: return self.nickname elif self.user_from == self.GUEST_USER: return self.nickname elif self.user_from == self.LENSMAN_USER: return self.name elif self.user_from == self.TOURGUIDE_USER: return self.name elif self.user_from == self.MINIAPP_USER: return self.nickname return self.nickname @property def data(self): return { 'user_id': self.user_id, 'name': self.name, 'username': self.username, 'nickname': self.nickname, 'avatar': self.avatar, 'phone': self.phone, } @property def cardList(self): return [ { 'cardId': self.membercardid, 'code': self.memberusercardcode } ] def brandata(self, brand_id=None): if self.clerk_id: try: saleclerk = SaleclerkInfo.objects.get(clerk_id=self.clerk_id, status=True) except SaleclerkInfo.DoesNotExist: saleclerk = None saleclerk_info = saleclerk.data if saleclerk and saleclerk.is_auth else {} else: saleclerk_info = {} return { 'user_id': self.user_id, 'name': self.name, 'username': self.username, 'nickname': self.nickname, 'avatar': self.avatar, 'phone': self.phone, 're_membercard': True if self.has_membercard and not self.memberusercardcode else False, 'has_membercard': self.has_membercard, 'membercardid': self.membercardid, 'memberusercardcode': self.memberusercardcode, 'cardList': self.cardList, 'saleclerk': bool(saleclerk_info), 'saleclerk_info': saleclerk_info, } class UserLoginLogInfo(BaseModelMixin): SUCCESS = 0 PWD_ERROR = 1 OTHER = 2 LOGIN_RESULT = ( (SUCCESS, u'登录成功'), (PWD_ERROR, u'密码错误'), (OTHER, u'其他'), ) user_id = models.CharField(_(u'user_id'), max_length=32, blank=True, null=True, help_text=u'用户唯一标识', db_index=True) login_ip = models.CharField(_(u'login_ip'), max_length=32, blank=True, null=True, help_text=_(u'登录IP')) login_result = models.IntegerField(_(u'login_result'), choices=LOGIN_RESULT, default=SUCCESS) class Meta: verbose_name = _(u'userloginloginfo') verbose_name_plural = _(u'userloginloginfo') def __unicode__(self): return unicode(self.pk) class UserIncomeExpensesInfo(BaseModelMixin): INCOME = 0 EXPENSE = 1 UNFREEZE = 2 TYPE = ( (INCOME, u'收入'), (EXPENSE, u'支出'), (UNFREEZE, u'解冻'), ) user_id = models.CharField(_(u'user_id'), max_length=32, blank=True, null=True, help_text=u'用户唯一标识', db_index=True) photo_id = models.CharField(_(u'photo_id'), max_length=32, blank=True, null=True, help_text=u'照片唯一标识', db_index=True) type = models.IntegerField(_(u'type'), choices=TYPE, default=INCOME, help_text=u'收支类别') amount = models.IntegerField(_(u'amount'), default=0, help_text=u'余额增减数量(分)') balance = models.IntegerField(_(u'balance'), default=0, help_text=u'余额增减后数量(分)') freeze_income_amount = models.IntegerField(_(u'freeze_income_amount'), default=0, help_text=u'收入冻结余额增减数量(分)') freeze_income_balance = models.IntegerField(_(u'freeze_income_balance'), default=0, help_text=u'收入冻结余额增减后数量(分)') freeze_expense_amount = models.IntegerField(_(u'freeze_expense_amount'), default=0, help_text=u'支出冻结余额增减数量(分)') freeze_expense_balance = models.IntegerField(_(u'freeze_expense_balance'), default=0, help_text=u'支出冻结余额增减后数量(分)') remark = models.CharField(_(u'remark'), max_length=255, blank=True, null=True, help_text=u'备注') class Meta: verbose_name = _(u'userincomeexpensesinfo') verbose_name_plural = _(u'userincomeexpensesinfo') def __unicode__(self): return unicode(self.pk)
kodo - Gogs: Go Git Service

暂无描述

tourguidegroup_views.py 13KB

    # -*- coding: utf-8 -*- from __future__ import division import json import shortuuid from django.conf import settings from django.core.serializers.json import DjangoJSONEncoder from django_curtail_uuid import CurtailUUID from django_logit import logit from django_response import response from TimeConvert import TimeConvert as tc from account.models import UserInfo from group.models import GroupInfo, GroupUserInfo from utils.admin_utils import have_active_group, is_group_admin, is_group_subadmin from utils.error.errno_utils import GroupStatusCode, GroupUserStatusCode, TokenStatusCode, UserStatusCode from utils.redis.connect import r 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 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_qiniu_utils import file_save @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 have_active_group(user_id): return response(GroupStatusCode.ONLY_ONE_ACTIVE_GROUP_ALLOWED) # 群组唯一标识 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, }) @logit def tg_group_detail_api(request): """ 旅行团详情 """ group_id = request.POST.get('group_id', '') user_id = request.POST.get('user_id', '') if not group_id: group_id = get_tour_guide_own_group(user_id) 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']] # Update 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': get_group_info(group_id), 'users': group_users_info, }) @logit def kodo_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) # Check whether ended ended_at = group_info.get('ended_at', '') if ended_at and tc.utc_datetime() > (tc.utc_string_to_utc_datetime(ended_at, format='%Y-%m-%dT%H:%M:%SZ') if isinstance(ended_at, basestring) else ended_at): return response(GroupStatusCode.GROUP_HAS_ENDED) # Check gather info 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.NOT_GROUP_ADMIN) # 群组名称更新 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').photo_path # 起止时间更新 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').photo_path # 行程安排更新 if schedules: group.schedules_path = file_save(schedules, prefix='tour', ext='.jpeg').photo_path 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.NOT_GROUP_ADMIN) # 群组解锁 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', '') # 地点 gather_screenshot = request.FILES.get('gather_screenshot', '') # 群组校验 try: group = GroupInfo.objects.get(group_id=group_id) except GroupInfo.DoesNotExist: return response(GroupStatusCode.GROUP_NOT_FOUND) # 权限校验 if not is_group_subadmin(group_id, admin_id): return response(GroupStatusCode.NOT_GROUP_SUBADMIN) # 集合信息设置 group.gather_at = gather_at group.gather_lon = gather_lon group.gather_lat = gather_lat group.gather_location = gather_location if gather_screenshot: group.gather_screenshot = file_save(gather_screenshot, prefix='tour', ext='.jpeg').photo_path 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', '') # 旅行团校验 if not have_active_group(admin_id): return response(GroupStatusCode.ACTIVE_GROUP_NOT_FOUND) # 获取旅行团唯一标识 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', '') # 旅行团校验 if have_active_group(user_id): return response(GroupStatusCode.ONLY_ONE_ACTIVE_GROUP_ALLOWED) # 获取旅行团唯一标识 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 is_group_admin(group_id, admin_id): return response(GroupStatusCode.NOT_GROUP_ADMIN) # 群组用户记录创建,若记录不存在,则创建,若记录已存在,则更新 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.status = True group_user.save() # Redis 群组用户数据缓存 group_users = set_group_users_info(group) # Redis 设置导游拥有的旅行团 set_tour_guide_own_group(user_id, group_id) return response(200, 'Transfer Tour Guide Group Success', u'转移旅行团管理权成功', { 'group_id': group_id, 'group': group.data, 'users': group_users, })