bar"> 24   photo/migrations/0008_auto_20160901_1439.py
  • 0 23
      photo/migrations/0009_auto_20160907_1018.py
  • 0 29
      photo/migrations/0010_photouuidinfo.py
  • 0 69
      photo/migrations/0011_auto_20170119_1207.py
  • 0 60
      photo/migrations/0012_auto_20180101_2220.py
  • 0 80
      photo/migrations/0013_auto_20180103_0446.py
  • 0 28
      photo/migrations/0014_auto_20201130_0131.py
  • 0 0
      photo/migrations/__init__.py
  • 0 114
      photo/models.py
  • 0 11
      photo/serializers.py
  • 0 61
      photo/templates/photo/photo_detail.html
  • 0 63
      photo/templates/photo/session_detail.html
  • 0 4
      photo/tests.py
  • 0 0
      photo/urls.py
  • 0 276
      photo/views.py
  • 0 103
      utils/error/errno_utils.py
  • 0 22
      utils/redis/rbrief.py
  • 0 58
      utils/redis/retrieve.py
  • 0 147
      utils/redis/rgroup.py
  • 0 20
      utils/redis/rguest.py
  • 3 62
      utils/redis/rkeys.py
  • 0 32
      utils/redis/rmessage.py
  • 0 0
      utils/redis/roperation/__init__.py
  • 0 20
      utils/redis/roperation/rbox_program_version.py
  • 0 27
      utils/redis/rorder.py
  • 0 27
      utils/redis/rprice.py
  • 0 19
      utils/redis/rtourguide.py
  • 0 14
      utils/redis/rtouruser.py
  • 0 22
      utils/redis/ruuid.py
  • + 36 - 0
    account/migrations/0050_auto_20201208_1607.py

    @@ -0,0 +1,36 @@
    1
    +# -*- coding: utf-8 -*-
    2
    +# Generated by Django 1.11.26 on 2020-12-08 08:07
    3
    +from __future__ import unicode_literals
    4
    +
    5
    +from django.db import migrations
    6
    +
    7
    +
    8
    +class Migration(migrations.Migration):
    9
    +
    10
    +    dependencies = [
    11
    +        ('account', '0049_auto_20201202_1203'),
    12
    +    ]
    13
    +
    14
    +    operations = [
    15
    +        migrations.DeleteModel(
    16
    +            name='LensmanIncomeExpensesInfo',
    17
    +        ),
    18
    +        migrations.DeleteModel(
    19
    +            name='LensmanInfo',
    20
    +        ),
    21
    +        migrations.DeleteModel(
    22
    +            name='LensmanLoginLogInfo',
    23
    +        ),
    24
    +        migrations.DeleteModel(
    25
    +            name='TourGuideInfo',
    26
    +        ),
    27
    +        migrations.DeleteModel(
    28
    +            name='UserIncomeExpensesInfo',
    29
    +        ),
    30
    +        migrations.DeleteModel(
    31
    +            name='UserLoginLogInfo',
    32
    +        ),
    33
    +        migrations.DeleteModel(
    34
    +            name='WechatInfo',
    35
    +        ),
    36
    +    ]

    + 1 - 293
    account/models.py

    @@ -11,243 +11,6 @@ from mch.models import ConsumeInfoSubmitLogInfo, MaintenancemanInfo, SaleclerkIn
    11 11
     from sales.models import SalesResponsibilityInfo
    12 12
     
    13 13
     
    14
    -class LensmanInfo(BaseModelMixin, LensmanTypeBoolMixin):
    15
    -    MALE = 1
    16
    -    FEMALE = 0
    17
    -
    18
    -    SEX_TYPE = (
    19
    -        (MALE, u'男'),
    20
    -        (FEMALE, u'女'),
    21
    -    )
    22
    -
    23
    -    REFUSED = -1
    24
    -    UNVERIFIED = 0
    25
    -    ACTIVATED = 1
    26
    -    DISABLED = 2
    27
    -    DELETED = 3
    28
    -    ASSIGN = 10
    29
    -
    30
    -    USER_STATUS = (
    31
    -        (REFUSED, u'已拒绝'),
    32
    -        (UNVERIFIED, u'未验证'),
    33
    -        (ACTIVATED, u'已激活'),
    34
    -        (DISABLED, u'已禁用'),
    35
    -        (DELETED, u'已删除'),
    36
    -        (ASSIGN, u'已分配'),
    37
    -    )
    38
    -
    39
    -    lensman_id = models.CharField(_(u'lensman_id'), max_length=32, blank=True, null=True, help_text=u'摄影师唯一标识', db_index=True, unique=True)
    40
    -
    41
    -    unionid = models.CharField(_(u'unionid'), max_length=32, blank=True, null=True, help_text=u'微信 Union ID', db_index=True, unique=True)
    42
    -
    43
    -    username = models.CharField(_(u'username'), max_length=255, blank=True, null=True, help_text=u'摄影师用户名', db_index=True, unique=True)
    44
    -    password = models.CharField(_(u'password'), max_length=255, blank=True, null=True, help_text=u'摄影师密码')
    45
    -    encryption = models.CharField(_(u'encryption'), max_length=255, blank=True, null=True, help_text=u'摄影师密码')
    46
    -
    47
    -    name = models.CharField(_(u'name'), max_length=255, blank=True, null=True, help_text=u'摄影师姓名')
    48
    -    sex = models.IntegerField(_(u'sex'), choices=SexModelMixin.SEX_TUPLE, default=SexModelMixin.UNKNOWN, help_text=u'摄影师性别')
    49
    -    phone = models.CharField(_(u'phone'), max_length=11, blank=True, null=True, help_text=u'摄影师电话', db_index=True)
    50
    -    location = models.CharField(_(u'location'), max_length=255, blank=True, null=True, help_text=u'摄影师地址')
    51
    -
    52
    -    proportion = models.FloatField(_(u'proportion'), default=1.0, help_text=u'摄影师分成比例(0.0 ~ 1.0)')
    53
    -
    54
    -    nomark = models.IntegerField(_(u'nomark'), default=299, help_text=u'摄影师无水印价格(分)')
    55
    -    origin = models.IntegerField(_(u'origin'), default=999, help_text=u'摄影师高清图价格(分)')
    56
    -
    57
    -    balance = models.IntegerField(_(u'balance'), default=0, help_text=u'摄影师余额(分)')
    58
    -    freeze_income_balance = models.IntegerField(_(u'freeze_income_balance'), default=0, help_text=u'摄影师收入冻结余额(分)')
    59
    -    freeze_expense_balance = models.IntegerField(_(u'freeze_expense_balance'), default=0, help_text=u'摄影师支出冻结余额(分)')
    60
    -
    61
    -    user_status = models.IntegerField(_(u'user_status'), choices=USER_STATUS, default=UNVERIFIED, help_text=u'普通摄影师审核状态')
    62
    -    outtake_status = models.IntegerField(_(u'outtake_status'), choices=USER_STATUS, default=UNVERIFIED, help_text=u'花絮摄影师审核状态')
    63
    -    refused_reason = models.TextField(_(u'refused_reason'), blank=True, null=True, help_text=u'审核拒绝原因')
    64
    -
    65
    -    signup_ip = models.CharField(_(u'signup_ip'), max_length=32, blank=True, null=True, help_text=_(u'注册IP'))
    66
    -    login_ip = models.CharField(_(u'login_ip'), max_length=32, blank=True, null=True, help_text=_(u'登录IP'))
    67
    -    login_at = models.DateTimeField(_(u'login_at'), blank=True, null=True, help_text=_(u'登录时间'))
    68
    -
    69
    -    class Meta:
    70
    -        verbose_name = _(u'lensmaninfo')
    71
    -        verbose_name_plural = _(u'lensmaninfo')
    72
    -
    73
    -    def __unicode__(self):
    74
    -        return '%d' % self.pk
    75
    -
    76
    -    def final_status(self, lensman_type):
    77
    -        if lensman_type == self.COMMON:  # 普通摄影师校验
    78
    -            return self.user_status
    79
    -        elif lensman_type == self.OUTTAKE:  # 花絮摄影师校验
    80
    -            return self.outtake_status
    81
    -        return self.user_status
    82
    -
    83
    -    def data(self, lensman_type):
    84
    -        return {
    85
    -            'name': self.name,
    86
    -            'sex': self.sex,
    87
    -            'phone': self.phone,
    88
    -            'location': self.location,
    89
    -            'status': self.final_status(lensman_type),
    90
    -            'refused_reason': self.refused_reason,
    91
    -        }
    92
    -
    93
    -    def modified(self, lensman_type):
    94
    -        if lensman_type == self.COMMON:  # 普通摄影师校验
    95
    -            return self.user_status in [self.UNVERIFIED, self.REFUSED]
    96
    -        elif lensman_type == self.OUTTAKE:  # 花絮摄影师校验
    97
    -            return self.outtake_status in [self.UNVERIFIED, self.REFUSED]
    98
    -        return False
    99
    -
    100
    -
    101
    -class LensmanLoginLogInfo(BaseModelMixin):
    102
    -    SUCCESS = 0
    103
    -    PWD_ERROR = 1
    104
    -    OTHER = 2
    105
    -
    106
    -    LOGIN_RESULT = (
    107
    -        (SUCCESS, u'登录成功'),
    108
    -        (PWD_ERROR, u'密码错误'),
    109
    -        (OTHER, u'其他'),
    110
    -    )
    111
    -
    112
    -    lensman_id = models.CharField(_(u'lensman_id'), max_length=32, blank=True, null=True, help_text=u'摄影师唯一标识', db_index=True)
    113
    -    login_ip = models.CharField(_(u'login_ip'), max_length=32, blank=True, null=True, help_text=_(u'登录IP'))
    114
    -    login_result = models.IntegerField(_(u'login_result'), choices=LOGIN_RESULT, default=SUCCESS)
    115
    -
    116
    -    class Meta:
    117
    -        verbose_name = _(u'lensmanloginloginfo')
    118
    -        verbose_name_plural = _(u'lensmanloginloginfo')
    119
    -
    120
    -    def __unicode__(self):
    121
    -        return '%d' % self.pk
    122
    -
    123
    -
    124
    -class LensmanIncomeExpensesInfo(BaseModelMixin):
    125
    -    INCOME = 0
    126
    -    EXPENSE = 1
    127
    -    UNFREEZE = 2
    128
    -
    129
    -    TYPE = (
    130
    -        (INCOME, u'收入'),
    131
    -        (EXPENSE, u'支出'),
    132
    -        (UNFREEZE, u'解冻'),
    133
    -    )
    134
    -
    135
    -    lensman_id = models.CharField(_(u'lensman_id'), max_length=32, blank=True, null=True, help_text=u'摄影师唯一标识', db_index=True)
    136
    -    photo_id = models.CharField(_(u'photo_id'), max_length=32, blank=True, null=True, help_text=u'照片唯一标识', db_index=True)
    137
    -
    138
    -    type = models.IntegerField(_(u'type'), choices=TYPE, default=INCOME, help_text=u'收支类别')
    139
    -    amount = models.IntegerField(_(u'amount'), default=0, help_text=u'余额增减数量(分)')
    140
    -    balance = models.IntegerField(_(u'balance'), default=0, help_text=u'余额增减后数量(分)')
    141
    -    freeze_income_amount = models.IntegerField(_(u'freeze_income_amount'), default=0, help_text=u'收入冻结余额增减数量(分)')
    142
    -    freeze_income_balance = models.IntegerField(_(u'freeze_income_balance'), default=0, help_text=u'收入冻结余额增减后数量(分)')
    143
    -    freeze_expense_amount = models.IntegerField(_(u'freeze_expense_amount'), default=0, help_text=u'支出冻结余额增减数量(分)')
    144
    -    freeze_expense_balance = models.IntegerField(_(u'freeze_expense_balance'), default=0, help_text=u'支出冻结余额增减后数量(分)')
    145
    -
    146
    -    remark = models.CharField(_(u'remark'), max_length=255, blank=True, null=True, help_text=u'备注')
    147
    -
    148
    -    class Meta:
    149
    -        verbose_name = _(u'lensmanincomeexpensesinfo')
    150
    -        verbose_name_plural = _(u'lensmanincomeexpensesinfo')
    151
    -
    152
    -    def __unicode__(self):
    153
    -        return '%d' % self.pk
    154
    -
    155
    -
    156
    -class TourGuideInfo(BaseModelMixin):
    157
    -    MALE = 1
    158
    -    FEMALE = 0
    159
    -
    160
    -    SEX_TYPE = (
    161
    -        (MALE, u'男'),
    162
    -        (FEMALE, u'女'),
    163
    -    )
    164
    -
    165
    -    REFUSED = -1
    166
    -    UNVERIFIED = 0
    167
    -    ACTIVATED = 1
    168
    -    DISABLED = 2
    169
    -    DELETED = 3
    170
    -    ASSIGN = 10
    171
    -
    172
    -    USER_STATUS = (
    173
    -        (REFUSED, u'已拒绝'),
    174
    -        (UNVERIFIED, u'未验证'),
    175
    -        (ACTIVATED, u'已激活'),
    176
    -        (DISABLED, u'已禁用'),
    177
    -        (DELETED, u'已删除'),
    178
    -        (ASSIGN, u'已分配'),
    179
    -    )
    180
    -
    181
    -    tourguide_id = models.CharField(_(u'tourguide_id'), max_length=32, blank=True, null=True, help_text=u'导游唯一标识', db_index=True, unique=True)
    182
    -
    183
    -    unionid = models.CharField(_(u'unionid'), max_length=32, blank=True, null=True, help_text=u'微信 Union ID', db_index=True, unique=True)
    184
    -
    185
    -    name = models.CharField(_(u'name'), max_length=255, blank=True, null=True, help_text=u'导游姓名')
    186
    -    sex = models.IntegerField(_(u'sex'), choices=SexModelMixin.SEX_TUPLE, default=SexModelMixin.UNKNOWN, help_text=u'导游性别')
    187
    -    phone = models.CharField(_(u'phone'), max_length=11, blank=True, null=True, help_text=u'导游电话', db_index=True)
    188
    -    location = models.CharField(_(u'location'), max_length=255, blank=True, null=True, help_text=u'导游地址')
    189
    -
    190
    -    no = models.CharField(_(u'no'), max_length=16, blank=True, null=True, help_text=u'导游证编号')
    191
    -
    192
    -    user_status = models.IntegerField(_(u'user_status'), choices=USER_STATUS, default=UNVERIFIED)
    193
    -    refused_reason = models.TextField(_(u'refused_reason'), blank=True, null=True, help_text=u'审核拒绝原因')
    194
    -
    195
    -    class Meta:
    196
    -        verbose_name = _(u'tourguideinfo')
    197
    -        verbose_name_plural = _(u'tourguideinfo')
    198
    -
    199
    -    def __unicode__(self):
    200
    -        return '%d' % self.pk
    201
    -
    202
    -    @property
    203
    -    def photo_url(self):
    204
    -        return ''
    205
    -
    206
    -    @property
    207
    -    def data(self):
    208
    -        return {
    209
    -            'name': self.name,
    210
    -            'sex': self.sex,
    211
    -            'phone': self.phone,
    212
    -            'location': self.location,
    213
    -            'no': self.no,
    214
    -            'photo': self.photo_url,
    215
    -            'status': self.user_status,
    216
    -            'refused_reason': self.refused_reason,
    217
    -        }
    218
    -
    219
    -    @property
    220
    -    def modified(self):
    221
    -        return self.user_status in [self.UNVERIFIED, self.REFUSED]
    222
    -
    223
    -
    224
    -class WechatInfo(BaseModelMixin):
    225
    -    MALE = 1
    226
    -    FEMALE = 0
    227
    -
    228
    -    SEX_TYPE = (
    229
    -        (MALE, u'男'),
    230
    -        (FEMALE, u'女'),
    231
    -    )
    232
    -
    233
    -    unionid = models.CharField(_(u'unionid'), max_length=32, blank=True, null=True, help_text=u'微信 Union ID')
    234
    -    openids = JSONField(_(u'openids'), blank=True, null=True, help_text=u'微信 Open IDs')
    235
    -    sex = models.IntegerField(_(u'sex'), choices=SexModelMixin.SEX_TUPLE, default=SexModelMixin.UNKNOWN, help_text=u'用户性别')
    236
    -    nickname = models.CharField(_(u'nickname'), max_length=255, blank=True, null=True, help_text=u'用户昵称')
    237
    -    headimgurl = models.CharField(_(u'headimgurl'), max_length=255, blank=True, null=True, help_text=u'用户头像')
    238
    -    country = models.CharField(_(u'country'), max_length=255, blank=True, null=True, help_text=u'用户国家')
    239
    -    province = models.CharField(_(u'province'), max_length=255, blank=True, null=True, help_text=u'用户省份')
    240
    -    city = models.CharField(_(u'city'), max_length=255, blank=True, null=True, help_text=u'用户城市')
    241
    -    location = models.CharField(_(u'location'), max_length=255, blank=True, null=True, help_text=u'用户地址')
    242
    -
    243
    -    class Meta:
    244
    -        verbose_name = _(u'wechatinfo')
    245
    -        verbose_name_plural = _(u'wechatinfo')
    246
    -
    247
    -    def __unicode__(self):
    248
    -        return '%d' % self.pk
    249
    -
    250
    -
    251 14
     class UserInfo(BaseModelMixin, LensmanTypeBoolMixin):
    252 15
         APP_USER = 0
    253 16
         WX_USER = 1
    @@ -557,59 +320,4 @@ class UserInfo(BaseModelMixin, LensmanTypeBoolMixin):
    557 320
                 # 'brand_id': self.brand_id,
    558 321
                 'card_id': self.membercardid,
    559 322
                 'code': self.memberusercardcode,
    560
    -        }
    561
    -
    562
    -
    563
    -class UserLoginLogInfo(BaseModelMixin):
    564
    -    SUCCESS = 0
    565
    -    PWD_ERROR = 1
    566
    -    OTHER = 2
    567
    -
    568
    -    LOGIN_RESULT = (
    569
    -        (SUCCESS, u'登录成功'),
    570
    -        (PWD_ERROR, u'密码错误'),
    571
    -        (OTHER, u'其他'),
    572
    -    )
    573
    -
    574
    -    user_id = models.CharField(_(u'user_id'), max_length=32, blank=True, null=True, help_text=u'用户唯一标识', db_index=True)
    575
    -    login_ip = models.CharField(_(u'login_ip'), max_length=32, blank=True, null=True, help_text=_(u'登录IP'))
    576
    -    login_result = models.IntegerField(_(u'login_result'), choices=LOGIN_RESULT, default=SUCCESS)
    577
    -
    578
    -    class Meta:
    579
    -        verbose_name = _(u'userloginloginfo')
    580
    -        verbose_name_plural = _(u'userloginloginfo')
    581
    -
    582
    -    def __unicode__(self):
    583
    -        return '%d' % self.pk
    584
    -
    585
    -
    586
    -class UserIncomeExpensesInfo(BaseModelMixin):
    587
    -    INCOME = 0
    588
    -    EXPENSE = 1
    589
    -    UNFREEZE = 2
    590
    -
    591
    -    TYPE = (
    592
    -        (INCOME, u'收入'),
    593
    -        (EXPENSE, u'支出'),
    594
    -        (UNFREEZE, u'解冻'),
    595
    -    )
    596
    -
    597
    -    user_id = models.CharField(_(u'user_id'), max_length=32, blank=True, null=True, help_text=u'用户唯一标识', db_index=True)
    598
    -    photo_id = models.CharField(_(u'photo_id'), max_length=32, blank=True, null=True, help_text=u'照片唯一标识', db_index=True)
    599
    -
    600
    -    type = models.IntegerField(_(u'type'), choices=TYPE, default=INCOME, help_text=u'收支类别')
    601
    -    amount = models.IntegerField(_(u'amount'), default=0, help_text=u'余额增减数量(分)')
    602
    -    balance = models.IntegerField(_(u'balance'), default=0, help_text=u'余额增减后数量(分)')
    603
    -    freeze_income_amount = models.IntegerField(_(u'freeze_income_amount'), default=0, help_text=u'收入冻结余额增减数量(分)')
    604
    -    freeze_income_balance = models.IntegerField(_(u'freeze_income_balance'), default=0, help_text=u'收入冻结余额增减后数量(分)')
    605
    -    freeze_expense_amount = models.IntegerField(_(u'freeze_expense_amount'), default=0, help_text=u'支出冻结余额增减数量(分)')
    606
    -    freeze_expense_balance = models.IntegerField(_(u'freeze_expense_balance'), default=0, help_text=u'支出冻结余额增减后数量(分)')
    607
    -
    608
    -    remark = models.CharField(_(u'remark'), max_length=255, blank=True, null=True, help_text=u'备注')
    609
    -
    610
    -    class Meta:
    611
    -        verbose_name = _(u'userincomeexpensesinfo')
    612
    -        verbose_name_plural = _(u'userincomeexpensesinfo')
    613
    -
    614
    -    def __unicode__(self):
    615
    -        return '%d' % self.pk
    323
    +        }

    + 1 - 20
    account/serializers.py

    @@ -3,26 +3,7 @@
    3 3
     from django.contrib.auth.models import Group, User
    4 4
     from rest_framework import serializers
    5 5
     
    6
    -from account.models import LensmanInfo, UserInfo
    7
    -
    8
    -
    9
    -class UserSerializer(serializers.HyperlinkedModelSerializer):
    10
    -    class Meta:
    11
    -        model = User
    12
    -        fields = ('url', 'username', 'email', 'groups')
    13
    -
    14
    -
    15
    -class GroupSerializer(serializers.HyperlinkedModelSerializer):
    16
    -    class Meta:
    17
    -        model = Group
    18
    -        fields = ('url', 'name')
    19
    -
    20
    -
    21
    -class LensmanInfoSerializer(serializers.HyperlinkedModelSerializer):
    22
    -    class Meta:
    23
    -        model = LensmanInfo
    24
    -        fields = ('lensman_id', 'name', 'sex', 'phone', 'location', 'proportion', 'created_at')
    25
    -
    6
    +from account.models import UserInfo
    26 7
     
    27 8
     class UserInfoSerializer(serializers.HyperlinkedModelSerializer):
    28 9
         class Meta:

    + 0 - 84
    account/tourguide_views.py

    @@ -1,84 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -
    3
    -from __future__ import division
    4
    -
    5
    -from django.conf import settings
    6
    -from django.db import transaction
    7
    -from django_logit import logit
    8
    -from django_response import response
    9
    -
    10
    -from account.models import TourGuideInfo, UserInfo
    11
    -from utils.error.errno_utils import TourGuideStatusCode
    12
    -from utils.redis.rprofile import set_profile_info
    13
    -
    14
    -
    15
    -@logit
    16
    -def tourguide_submit_api(request):
    17
    -    """ 导游信息提交 """
    18
    -    unionid = request.POST.get('unionid', '')
    19
    -    openid = request.POST.get('openid', '')
    20
    -    phone = request.POST.get('phone', '')
    21
    -
    22
    -    serverIds = request.POST.getlist('serverIds[]', [])
    23
    -
    24
    -    # TODO: get tour guide photo from wx server
    25
    -
    26
    -    if TourGuideInfo.objects.filter(phone=phone).exclude(unionid=unionid).exists():
    27
    -        return response(TourGuideStatusCode.TOURGUIDE_PHONE_ALREADY_EXISTS)
    28
    -
    29
    -    fields = {
    30
    -        'name': request.POST.get('name', ''),
    31
    -        'sex': int(request.POST.get('sex', 1)),
    32
    -        'phone': phone,
    33
    -        'location': request.POST.get('location', ''),
    34
    -        'no': request.POST.get('no', ''),
    35
    -        'user_status': TourGuideInfo.UNVERIFIED,
    36
    -    }
    37
    -
    38
    -    tourguide, created = TourGuideInfo.objects.get_or_create(unionid=unionid, defaults=fields)
    39
    -    # 状态为 UNVERIFIED 的允许修改, 其他需要登录导游 APP 进行信息的修改
    40
    -    if tourguide.user_status not in [TourGuideInfo.UNVERIFIED, TourGuideInfo.REFUSED]:
    41
    -        return response(TourGuideStatusCode.TOURGUIDE_ALREADY_NOT_UNVERIFIED)
    42
    -    if not created:
    43
    -        for key, value in fields.iteritems():
    44
    -            setattr(tourguide, key, value)
    45
    -        tourguide.save()
    46
    -
    47
    -    return response(200, 'Submit Success', u'提交成功', {})
    48
    -
    49
    -
    50
    -@logit
    51
    -@transaction.atomic
    52
    -def tourguide_wx_authorize_api(request):
    53
    -    try:
    54
    -        user = UserInfo.objects.select_for_update().get(unionid=request.POST.get('unionid', ''), istourguide=True, status=True)
    55
    -    except UserInfo.DoesNotExist:
    56
    -        return response(TourGuideStatusCode.TOURGUIDE_NOT_FOUND)
    57
    -
    58
    -    # 用户是否激活
    59
    -    if user.user_status != UserInfo.ACTIVATED:
    60
    -        return response(TourGuideStatusCode.TOURGUIDE_NOT_ACTIVATED)
    61
    -
    62
    -    # Set User Key's Value
    63
    -    user.openid_tourguide = request.POST.get('openid', '')
    64
    -    user.sex = request.POST.get('sex', 0)
    65
    -    user.nickname = request.POST.get('nickname', '') or request.POST.get('screen_name', '')
    66
    -    user.avatar = request.POST.get('headimgurl', '') or request.POST.get('profile_image_url', '')
    67
    -    user.country = request.POST.get('country', '')
    68
    -    user.province = request.POST.get('province', '')
    69
    -    user.city = request.POST.get('city', '')
    70
    -    user.save()
    71
    -
    72
    -    set_profile_info(user)
    73
    -
    74
    -    return response(200, 'Tour Guide Login Success', u'导游登录成功', user.data)
    75
    -
    76
    -
    77
    -@logit
    78
    -def tourguide_guest_login_api(request):
    79
    -    try:
    80
    -        user = UserInfo.objects.get(unionid=settings.PAI2_TOURGUIDE_GUEST_UNIONID, istourguide=True, status=True)
    81
    -    except UserInfo.DoesNotExist:
    82
    -        return response(TourGuideStatusCode.TOURGUIDE_NOT_FOUND)
    83
    -
    84
    -    return response(200, 'Tour Guide Login Success', u'导游登录成功', user.data)

    + 1 - 120
    account/views.py

    @@ -1,120 +1 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -
    3
    -from django.contrib.auth.models import Group, User
    4
    -from django.db import transaction
    5
    -from django_curtail_uuid import CurtailUUID
    6
    -from django_logit import logit
    7
    -from django_response import response
    8
    -from ipaddr import client_ip
    9
    -from rest_framework import viewsets
    10
    -from TimeConvert import TimeConvert as tc
    11
    -
    12
    -from account.models import LensmanInfo, UserInfo
    13
    -from account.serializers import GroupSerializer, LensmanInfoSerializer, UserInfoSerializer, UserSerializer
    14
    -from operation.models import GuestEntranceControlInfo
    15
    -from utils.error.errno_utils import UserStatusCode
    16
    -from utils.redis.rguest import get_guest_entrance_control
    17
    -from utils.redis.rprofile import set_profile_info
    18
    -from utils.version_utils import is_version_match
    19
    -
    20
    -
    21
    -@logit
    22
    -@transaction.atomic
    23
    -def user_wx_authorize_api(request):
    24
    -    # Get or Create User
    25
    -    user, created = UserInfo.objects.select_for_update().get_or_create(unionid=request.POST.get('unionid', ''))
    26
    -
    27
    -    # Set User_id
    28
    -    if created:
    29
    -        user.user_id = CurtailUUID.uuid(UserInfo, 'user_id')
    30
    -
    31
    -    # Set User Key's Value
    32
    -    user.user_from = UserInfo.USER_USER
    33
    -    user.openid = request.POST.get('wx_uid', '')
    34
    -    user.sex = request.POST.get('sex', 0)
    35
    -    user.nickname = request.POST.get('nickname', '') or request.POST.get('screen_name', '')
    36
    -    user.avatar = request.POST.get('headimgurl', '') or request.POST.get('profile_image_url', '')
    37
    -    user.country = request.POST.get('country', '')
    38
    -    user.province = request.POST.get('province', '')
    39
    -    user.city = request.POST.get('city', '')
    40
    -    user.user_status = UserInfo.ACTIVATED
    41
    -    user.signup_ip = client_ip(request)
    42
    -    user.signup_at = tc.utc_datetime()
    43
    -    user.save()
    44
    -
    45
    -    set_profile_info(user)
    46
    -
    47
    -    return response(200, 'User Login Success', u'用户端登录成功', user.data)
    48
    -
    49
    -
    50
    -@logit
    51
    -@transaction.atomic
    52
    -def user_guest_login_api(request):
    53
    -    """ 游客登录 """
    54
    -    gen = get_guest_entrance_control()
    55
    -
    56
    -    # 是否配置游客入口控制信息
    57
    -    if not gen:
    58
    -        return response(UserStatusCode.GUEST_NOT_ALLOWED)
    59
    -
    60
    -    # 平台校验
    61
    -    platform = gen.get('platform', '')
    62
    -    if request.Android:
    63
    -        if platform not in [GuestEntranceControlInfo.ADR, GuestEntranceControlInfo.BOTH]:
    64
    -            return response(UserStatusCode.GUEST_NOT_ALLOWED)
    65
    -    else:
    66
    -        if platform not in [GuestEntranceControlInfo.IOS, GuestEntranceControlInfo.BOTH]:
    67
    -            return response(UserStatusCode.GUEST_NOT_ALLOWED)
    68
    -
    69
    -    # 版本校验
    70
    -    if not is_version_match(request, gen):
    71
    -        return response(UserStatusCode.GUEST_NOT_ALLOWED)
    72
    -
    73
    -    # 通用唯一识别码 (Universally Unique Identifier)
    74
    -    uuid = request.POST.get('uuid', '')
    75
    -    # 游客字段
    76
    -    fields = {
    77
    -        'user_id': CurtailUUID.uuid(UserInfo, 'user_id'),
    78
    -        'user_from': UserInfo.GUEST_USER,
    79
    -        'uuid': uuid,
    80
    -        'nickname': u'游客',
    81
    -        'user_status': UserInfo.ACTIVATED,
    82
    -    }
    83
    -    # 若 uuid 存在,则 get_or_create,否则 create
    84
    -    if uuid:
    85
    -        user, created = UserInfo.objects.select_for_update().get_or_create(user_from=UserInfo.GUEST_USER, uuid=uuid, defaults=fields)
    86
    -        if created:
    87
    -            user.nickname = u'游客{}'.format(user.pk)
    88
    -            user.save()
    89
    -    else:
    90
    -        user = UserInfo.objects.select_for_update().create(**fields)
    91
    -        user.nickname = u'游客{}'.format(user.pk)
    92
    -        user.save()
    93
    -
    94
    -    return response(200, 'Guest Login Success', u'游客登录成功', user.data)
    95
    -
    96
    -
    97
    -class UserViewSet(viewsets.ModelViewSet):
    98
    -    """
    99
    -    API endpoint that allows users to be viewed or edited.
    100
    -    """
    101
    -    queryset = User.objects.all().order_by('-pk')
    102
    -    serializer_class = UserSerializer
    103
    -
    104
    -
    105
    -class GroupViewSet(viewsets.ModelViewSet):
    106
    -    """
    107
    -    API endpoint that allows groups to be viewed or edited.
    108
    -    """
    109
    -    queryset = Group.objects.all()
    110
    -    serializer_class = GroupSerializer
    111
    -
    112
    -
    113
    -class LensmanInfoViewSet(viewsets.ModelViewSet):
    114
    -    queryset = LensmanInfo.objects.all().order_by('-pk')
    115
    -    serializer_class = LensmanInfoSerializer
    116
    -
    117
    -
    118
    -class UserInfoViewSet(viewsets.ModelViewSet):
    119
    -    queryset = UserInfo.objects.all().order_by('-pk')
    120
    -    serializer_class = UserInfoSerializer
    1
    +# -*- coding: utf-8 -*-

    + 2 - 172
    api/urls.py

    @@ -3,185 +3,19 @@
    3 3
     from django.conf.urls import url
    4 4
     from django_file_upload import views as file_views
    5 5
     
    6
    -from account import tourguide_views
    7 6
     from account import views as account_views
    8 7
     from api import (admin_views, clerk_views, distributor_views, encrypt_views, log_views, mch_views, member_views,
    9 8
                      model_views, operator_views, refresh_views, sr_views, staff_views, wx_views)
    10
    -from box import views as box_views
    11
    -from geo import views as geo_views
    12
    -from group import (groupuser_views, lensman_views, tourguidegroup_views, tourguidegroupadmin_views,
    13
    -                   tourguidegroupuser_views)
    14
    -from group import views as group_views
    15
    -from message import views as message_views
    16 9
     from miniapp import qy_views
    17 10
     from miniapp import views as mini_views
    18 11
     from operation import views as op_views
    19 12
     from page import oauth_views, sale_views, screen_views
    20
    -from pay import views as pay_views
    21
    -from photo import views as photo_views
    22 13
     from sales import views as sales_views
    23 14
     from server import server_views
    24 15
     from statistic import views as tj_views
    25 16
     
    26
    -
    27
    -# 帐户相关
    28
    -urlpatterns = [
    29
    -    url(r'^u/wx/authorize$', account_views.user_wx_authorize_api, name='user_wx_authorize_api'),  # 用户端 - 微信用户授权
    30
    -
    31
    -    url(r'^u/guest/status$', op_views.guest_api, name='user_guest_status_api'),  # 用户端 - 微游客状态(是否开启)
    32
    -    url(r'^u/guest/login$', account_views.user_guest_login_api, name='user_guest_login_api'),  # 用户端 - 微游客登录
    33
    -]
    34
    -
    35
    -# 摄影师相关
    36
    -urlpatterns += [
    37
    -    url(r'^l/submit$', lensman_views.lensman_submit_api, name='lensman_submit_api'),  # 摄影师信息提交
    38
    -
    39
    -    url(r'^l/wx/authorize$', lensman_views.lensman_wx_authorize_api, name='lensman_wx_authorize_api'),  # 摄影师端 - 微信用户授权
    40
    -
    41
    -    url(r'^l/price_fix$', lensman_views.lensman_price_fix_api, name='lensman_price_fix_api'),  # 摄影师定价
    42
    -
    43
    -    url(r'^l/upload$', lensman_views.lensman_photo_upload_api, name='lensman_photo_upload_api'),  # 摄影师照片上传
    44
    -    url(r'^l/origin_upload$', lensman_views.lensman_origin_photo_upload_api, name='lensman_origin_photo_upload_api'),  # 摄影师原图上传
    45
    -
    46
    -    url(r'^l/brief$', lensman_views.lensman_brief_api, name='lensman_brief_api'),  # 摄影师简报
    47
    -    url(r'^l/origin_wanted$', lensman_views.lensman_origin_wanted_api, name='lensman_origin_wanted_api'),  # 摄影师原图订单
    48
    -]
    49
    -
    50
    -# 导游相关
    51
    -urlpatterns += [
    52
    -    url(r'^t/submit$', tourguide_views.tourguide_submit_api, name='tourguide_submit_api'),  # 导游信息提交
    53
    -
    54
    -    url(r'^t/wx/authorize$', tourguide_views.tourguide_wx_authorize_api, name='tourguide_wx_authorize_api'),  # 导游端 - 微信用户授权
    55
    -
    56
    -    url(r'^t/guest/status$', op_views.guest_api, name='tourguide_guest_status_api'),  # 游端 - 游客状态(是否开启)
    57
    -    url(r'^t/guest/login$', tourguide_views.tourguide_guest_login_api, name='tourguide_guest_login_api'),  # 游端 - 游客登录
    58
    -]
    59
    -
    60
    -# 群组相关
    61
    -urlpatterns += [
    62
    -    url(r'^g/create$', group_views.group_create_api, name='group_create_api'),  # 群组创建
    63
    -    url(r'^g/detail$', group_views.group_detail_api, name='group_detail_api'),  # 群组详情
    64
    -    url(r'^g/update$', group_views.group_update_api, name='group_update_api'),  # 群组更新
    65
    -    url(r'^g/delete$', group_views.group_delete_api, name='group_delete_api'),  # 群组删除
    66
    -    url(r'^g/list$', group_views.group_list_api, name='group_list_api'),  # 群组列表
    67
    -    url(r'^g/lock$', group_views.group_lock_api, name='group_lock_api'),  # 群组锁定
    68
    -    url(r'^g/unlock$', group_views.group_unlock_api, name='group_unlock_api'),  # 群组解锁
    69
    -    url(r'^g/data$', group_views.group_data_api, name='group_data_api'),  # 群组数据,评论数,点赞数
    70
    -]
    71
    -
    72
    -# 群成员相关
    73
    -urlpatterns += [
    74
    -    url(r'^g/join$', groupuser_views.group_user_join_api, name='group_join_api'),  # 群成员加群
    75
    -    url(r'^g/remove$', groupuser_views.group_user_remove_api, name='group_remove_api'),  # 群成员移除,管理员主动,群成员被动
    76
    -    url(r'^g/quit$', groupuser_views.group_user_quit_api, name='group_quit_api'),  # 群成员退出,群成员主动
    77
    -]
    78
    -
    79
    -# 旅行团相关
    80
    -urlpatterns += [
    81
    -    url(r'^tg/create$', tourguidegroup_views.tg_group_create_api, name='tg_group_create_api'),  # 旅行团创建
    82
    -    url(r'^tg/detail$', tourguidegroup_views.tg_group_detail_api, name='tg_group_detail_api'),  # 旅行团详情
    83
    -    url(r'^tg/update$', tourguidegroup_views.tg_group_update_api, name='tg_group_update_api'),  # 旅行团更新
    84
    -    url(r'^tg/close$', tourguidegroup_views.tg_group_close_api, name='tg_group_close_api'),  # 旅行团关闭
    85
    -    url(r'^tg/gather/start$', tourguidegroup_views.tg_group_gather_start_api, name='tg_group_gather_start_api'),  # 旅行团设置集合时间和地点
    86
    -    # url(r'^tg/gather/end$', tourguidegroup_views.tg_group_gather_end_api, name='tg_group_gather_end_api'),  # 旅行团集合结束,清理数据
    87
    -    url(r'^tg/token$', tourguidegroup_views.tg_group_token_api, name='tg_group_token_api'),  # 旅行团权限管理票据
    88
    -    url(r'^tg/transfer$', tourguidegroup_views.tg_group_transfer_api, name='tg_group_transfer_api'),  # 旅行团权限管理转移
    89
    -
    90
    -    url(r'^tg/admin/list$', tourguidegroupadmin_views.tg_group_admin_list_api, name='tg_group_admin_list_api'),  # 旅行团管理员列表
    91
    -    url(r'^tg/admin/recovery$', tourguidegroupadmin_views.tg_group_admin_recovery_api, name='tg_group_admin_recovery_api'),  # 旅行团管理员权限回收,管理员主动,团成员被动
    92
    -    url(r'^tg/admin/waiver$', tourguidegroupadmin_views.tg_group_admin_waiver_api, name='tg_group_admin_waiver_api'),  # 旅行团管理员权限放弃
    93
    -]
    94
    -
    95
    -# 旅行团成员相关
    96
    -urlpatterns += [
    97
    -    url(r'^tgu/is_joined$', tourguidegroupuser_views.tgu_group_user_is_joined_api, name='tgu_group_user_is_joined_api'),  # 旅行团成员是否已加团
    98
    -    url(r'^tgu/join$', tourguidegroupuser_views.tgu_group_user_join_api, name='tgu_group_user_join_api'),  # 旅行团成员加团
    99
    -    url(r'^tgu/remove$', tourguidegroupuser_views.tgu_group_user_remove_api, name='tgu_group_user_remove_api'),  # 旅行团成员移除,管理员主动,团成员被动
    100
    -    url(r'^tgu/update$', tourguidegroupuser_views.tgu_group_user_update_api, name='tg_group_update_api'),  # 旅行团成员信息更新
    101
    -    url(r'^tgu/locations$', tourguidegroupuser_views.tgu_group_user_locations_api, name='tgu_group_user_locations_api'),  # 旅行团所有成员位置信息
    102
    -    url(r'^tgu/location$', tourguidegroupuser_views.tgu_group_user_location_api, name='tgu_group_user_location_api'),  # 旅行团单个成员位置信息
    103
    -]
    104
    -
    105
    -# 飞图相关
    106
    -urlpatterns += [
    107
    -    url(r'^f/upload$', group_views.flyimg_upload_api, name='flyimg_upload_api'),  # 飞图上传
    108
    -    url(r'^f/list$', group_views.flyimg_list_api, name='flyimg_list_api'),  # 飞图列表
    109
    -    url(r'^f/detail$', group_views.flyimg_detail_api, name='flyimg_detail_api'),  # 飞图详情
    110
    -    url(r'^f/comment/submit$', group_views.comment_submit_api, name='comment_submit_api'),  # 飞图评论提交
    111
    -    url(r'^f/comment/list$', group_views.comment_list_api, name='comment_list_api'),  # 飞图评论列表
    112
    -    url(r'^f/thumbup/submit$', group_views.thumbup_submit_api, name='thumbup_submit_api'),  # 飞图点赞提交
    113
    -    url(r'^f/thumbup/list$', group_views.thumbup_list_api, name='thumbup_list_api'),  # 飞图点赞列表
    114
    -    url(r'^f/thumbup/cancel$', group_views.thumbup_cancel_api, name='thumbup_cancel_api'),  # 飞图点赞取消
    115
    -    url(r'^f/price$', group_views.lensman_photo_price, name='lensman_photo_price'),  # 摄影师照片价格获取
    116
    -    url(r'^f/bought$', group_views.lensman_photo_bought, name='lensman_photo_bought'),  # 摄影师照片已购买
    117
    -]
    118
    -
    119
    -# 消息相关
    120
    -urlpatterns += [
    121
    -    url(r'^msg/list$', message_views.message_list_api, name='message_list_api'),  # 消息列表
    122
    -    url(r'^msg/(?P<msg_type>\w+)/list$', message_views.message_type_list_api, name='message_type_list_api'),  # 分类消息列表
    123
    -    url(r'^msg/(?P<msg_type>\w+)/read$', message_views.message_type_read_api, name='message_type_read_api'),  # 消息读取
    124
    -    url(r'^msg/(?P<msg_type>\w+)/delete$', message_views.message_type_delete_api, name='message_type_delete_api'),  # 消息删除
    125
    -]
    126
    -
    127
    -# 控制器相关
    128
    -urlpatterns += [
    129
    -    url(r'^uuid_init$', photo_views.uuid_init, name='uuid_init'),  # 生成唯一标识
    130
    -    url(r'^uuid$', photo_views.uuid, name='uuid'),  # 获取唯一标识
    131
    -    url(r'^photos/upload$', photo_views.upload_photo, name='upload_photo'),  # 摄影师照片上传
    132
    -    # url(r'^photos/raw/upload$', photo_views.upload_raw_photo, name='upload_raw_photo'),  # 摄影师高清照片上传
    133
    -]
    134
    -
    135
    -# 二维码相关
    136
    -urlpatterns += [
    137
    -    url(r'^s/join$', photo_views.session_join_api, name='session_join_api'),  # Session 加群
    138
    -    url(r'^p/(?P<photo>\w+)$', photo_views.photo_standard_api, name='photo_standard_api'),  # standard thumbnail, available for free
    139
    -]
    140
    -
    141
    -# 系统相关
    142
    -urlpatterns += [
    143
    -    url(r'^op/upgrade$', op_views.upgrade_api, name='upgrade_api'),  # APP 升级
    144
    -    url(r'^op/patch$', op_views.patch_api, name='patch_api'),  # APP 补丁
    145
    -    url(r'^op/online$', op_views.online_api, name='online_api'),  # 是否上线
    146
    -    url(r'^op/guest$', op_views.guest_api, name='guest_api'),  # 游客状态(是否开启)
    147
    -    url(r'^op/splash$', op_views.splash_api, name='splash_api'),  # 启动页面
    148
    -    url(r'^op/feedback$', op_views.feedback_api, name='feedback_api'),  # 用户反馈
    149
    -    url(r'^op/download$', op_views.download_api, name='download_api'),  # 下载接口
    150
    -    url(r'^op/bpversion$', op_views.box_program_version_api, name='box_program_version_api'),  # BOX 程序版本信息
    151
    -]
    152
    -
    153
    -# 地理位置相关
    154
    -urlpatterns += [
    155
    -    url(r'^geo/submit$', geo_views.geo_submit_api, name='geo_submit_api'),  # 地理位置信息提交
    156
    -]
    157
    -
    158
    -# 支付相关
    159
    -urlpatterns += [
    160
    -    url(r'^wx/order_create$', pay_views.wx_order_create_api, name='wx_order_create_api'),  # 订单创建
    161
    -    url(r'^wx/order_query$', pay_views.wx_order_query_api, name='wx_order_query_api'),  # 订单查询补单
    162
    -    url(r'^wx/order_list$', pay_views.wx_order_list_api, name='wx_order_list_api'),  # 订单列表
    163
    -    url(r'^wx/order_detail$', pay_views.wx_order_detail_api, name='wx_order_detail_api'),  # 订单详情
    164
    -    url(r'^wx/notify_url$', pay_views.wx_notify_url_api, name='wx_notify_url_api'),  # 支付异步通知回调地址
    165
    -]
    166
    -
    167
    -# 提现相关
    168
    -urlpatterns += [
    169
    -    url(r'^wx/balance_withdraw$', pay_views.wx_balance_withdraw_api, name='wx_balance_withdraw_api'),  # 余额提现: 企业付款/现金红包
    170
    -]
    171
    -
    172
    -# 首页相关
    173
    -urlpatterns += [
    174
    -    url(r'^kodo/home$', group_views.kodo_home_api, name='kodo_home_api'),  # 首页照片信息
    175
    -    url(r'^kodo/tginfo$', tourguidegroup_views.kodo_tginfo_api, name='kodo_tginfo_api'),  # 首页旅行团信息
    176
    -]
    177
    -
    178
    -# 服务器相关
    179
    -urlpatterns += [
    180
    -    url(r'^s/server_time$', server_views.get_server_time_api, name='get_server_time_api'),  # 获取服务器时间
    181
    -]
    182
    -
    183 17
     # Mini App
    184
    -urlpatterns += [
    18
    +urlpatterns = [
    185 19
         url(r'^mini/userinfo$', mini_views.get_userinfo_api, name='get_userinfo_api'),  # 获取用户信息
    186 20
         url(r'^mini/login$', mini_views.mini_login_api, name='mini_login_api'),  # 小程序登录
    187 21
         url(r'^mini/userinfo2$', mini_views.get_userinfo_api2, name='get_userinfo_api2'),  # 获取用户信息
    @@ -191,10 +25,6 @@ urlpatterns += [
    191 25
         url(r'^qy/query/userinfo$', qy_views.query_userinfo, name='query_userinfo'),  # 查询用户等级及维修劵
    192 26
     ]
    193 27
     
    194
    -urlpatterns += [
    195
    -    url(r'^box/loginqr$', box_views.login_qrcode_api, name='login_qrcode_api'),  # 二维码登录
    196
    -]
    197
    -
    198 28
     # Kodo
    199 29
     urlpatterns += [
    200 30
         url(r'^login$', mch_views.optor_login_api, name='login_api'),
    @@ -334,7 +164,7 @@ urlpatterns += [
    334 164
         url(r'^admin/member/activity/share/list$', admin_views.member_activity_share_list, name='member_activity_share_list'),
    335 165
         
    336 166
         url(r'^admin/coupon/list$', admin_views.coupon_list, name='coupon_list'),
    337
    -    url(r'^admin/coupon/details$', admin_views.coupon_details, name='coupon_details'),
    167
    +    url(r'^admin/coupon/details$', admin_views.coupon_details, name='coupon_update'),
    338 168
         url(r'^admin/coupon/create$', admin_views.coupon_create, name='coupon_create'),
    339 169
         url(r'^admin/coupon/update$', admin_views.coupon_update, name='coupon_update'),
    340 170
         url(r'^admin/coupon/delete$', admin_views.coupon_delete, name='coupon_delete'),

    + 0 - 0
    box/__init__.py


    + 0 - 4
    box/admin.py

    @@ -1,4 +0,0 @@
    1
    -from django.contrib import admin
    2
    -
    3
    -
    4
    -# Register your models here.

    + 0 - 0
    box/migrations/__init__.py


    + 0 - 4
    box/models.py

    @@ -1,4 +0,0 @@
    1
    -from django.db import models
    2
    -
    3
    -
    4
    -# Create your models here.

    + 0 - 4
    box/tests.py

    @@ -1,4 +0,0 @@
    1
    -from django.test import TestCase
    2
    -
    3
    -
    4
    -# Create your tests here.

    + 0 - 34
    box/views.py

    @@ -1,34 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -
    3
    -from django_logit import logit
    4
    -from django_response import response
    5
    -
    6
    -from account.models import UserInfo
    7
    -from utils.error.errno_utils import LensmanStatusCode, TokenStatusCode
    8
    -from utils.redis.connect import r
    9
    -
    10
    -
    11
    -@logit
    12
    -def login_qrcode_api(request):
    13
    -    lensman_type = int(request.POST.get('lensman_type', 0))
    14
    -    unionid = request.POST.get('unionid', '')
    15
    -    token = request.POST.get('token', '')
    16
    -
    17
    -    if not r.token_exists(unionid, token):
    18
    -        return response(TokenStatusCode.TOKEN_HAS_EXPIRED)
    19
    -
    20
    -    # 用户校验
    21
    -    try:
    22
    -        user = UserInfo.objects.get(unionid=unionid, islensman=True, status=True)
    23
    -    except UserInfo.DoesNotExist:
    24
    -        return response(LensmanStatusCode.LENSMAN_NOT_FOUND)
    25
    -
    26
    -    # 用户状态校验
    27
    -    if lensman_type == UserInfo.COMMON:  # 普通摄影师校验
    28
    -        if user.is_common_lensman and user.user_status != UserInfo.ACTIVATED:
    29
    -            return response(LensmanStatusCode.LENSMAN_NOT_ACTIVATED)
    30
    -    elif lensman_type == UserInfo.OUTTAKE:  # 花絮摄影师校验
    31
    -        if user.is_outtake_lensman and user.outtake_status != UserInfo.ACTIVATED:
    32
    -            return response(LensmanStatusCode.LENSMAN_NOT_ACTIVATED)
    33
    -
    34
    -    return response(200, 'Lensman Login Success', u'摄影师登录成功', user.data)

    + 0 - 0
    geo/__init__.py


    + 0 - 4
    geo/admin.py

    @@ -1,4 +0,0 @@
    1
    -from django.contrib import admin
    2
    -
    3
    -
    4
    -# Register your models here.

    + 0 - 0
    geo/migrations/__init__.py


    + 0 - 4
    geo/models.py

    @@ -1,4 +0,0 @@
    1
    -from django.db import models
    2
    -
    3
    -
    4
    -# Create your models here.

    + 0 - 4
    geo/tests.py

    @@ -1,4 +0,0 @@
    1
    -from django.test import TestCase
    2
    -
    3
    -
    4
    -# Create your tests here.

    + 0 - 43
    geo/views.py

    @@ -1,43 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -
    3
    -from __future__ import division
    4
    -
    5
    -import json
    6
    -
    7
    -from django.core.serializers.json import DjangoJSONEncoder
    8
    -from django_logit import logit
    9
    -from django_response import response
    10
    -from TimeConvert import TimeConvert as tc
    11
    -
    12
    -from utils.error.errno_utils import GroupUserStatusCode
    13
    -from utils.redis.connect import r
    14
    -from utils.redis.rkeys import (TOUR_GUIDE_GROUP_CUR_SESSION, TOUR_GUIDE_GROUP_GEO_INFO, TOUR_GUIDE_GROUP_GEO_SUBMIT_DT,
    15
    -                               TOUR_GUIDE_GROUP_USER_GEO_LIST)
    16
    -from utils.redis.rtouruser import get_tour_user_belong_group
    17
    -
    18
    -
    19
    -@logit
    20
    -def geo_submit_api(request):
    21
    -    user_id = request.POST.get('user_id', '')
    22
    -    longitude = request.POST.get('lon', '')  # 经度
    23
    -    latitude = request.POST.get('lat', '')  # 纬度
    24
    -
    25
    -    # 获取用户当前所处旅行团
    26
    -    group_id = get_tour_user_belong_group(user_id)
    27
    -    if not group_id:
    28
    -        return response(GroupUserStatusCode.USER_HAS_NOT_JOIN_GROUP)
    29
    -
    30
    -    r.pipeline().geoadd(
    31
    -        TOUR_GUIDE_GROUP_GEO_INFO % group_id, longitude, latitude, user_id
    32
    -    ).hset(
    33
    -        TOUR_GUIDE_GROUP_GEO_SUBMIT_DT % group_id, user_id, tc.utc_string(format='%Y-%m-%dT%H:%M:%SZ')
    34
    -    ).execute()
    35
    -
    36
    -    session_id = r.get(TOUR_GUIDE_GROUP_CUR_SESSION % group_id)
    37
    -    r.rpush(TOUR_GUIDE_GROUP_USER_GEO_LIST % (group_id, session_id, user_id), json.dumps({
    38
    -        'lon': longitude,
    39
    -        'lat': latitude,
    40
    -        'current_time': tc.utc_datetime(ms=False),
    41
    -    }, cls=DjangoJSONEncoder))
    42
    -
    43
    -    return response(200, 'Geo Info Submit Success', u'地理位置信息上传成功')

    + 0 - 0
    group/__init__.py


    + 0 - 4
    group/admin.py

    @@ -1,4 +0,0 @@
    1
    -from django.contrib import admin
    2
    -
    3
    -
    4
    -# Register your models here.

    + 0 - 30
    group/grouppage_views.py

    @@ -1,30 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -
    3
    -from __future__ import division
    4
    -
    5
    -from django.conf import settings
    6
    -from django.shortcuts import render
    7
    -from django_logit import logit
    8
    -
    9
    -from group.models import GroupPhotoInfo
    10
    -
    11
    -
    12
    -@logit
    13
    -def group_detail(request, group_id):
    14
    -    return render(request, 'page/kodo_user_{}_download.html'.format('ios' if request.iOS else 'adr'), {})
    15
    -
    16
    -
    17
    -@logit
    18
    -def group_photo_detail(request, photo_id):
    19
    -    photo = GroupPhotoInfo.objects.get(photo_id=photo_id)
    20
    -    return render(request, 'photo/photo_detail.html', {'photo_url': photo.photo_url, 'api_domain': settings.API_DOMAIN})
    21
    -
    22
    -
    23
    -@logit
    24
    -def tgu_group_detail(request, admin_id):
    25
    -    return render(request, 'page/kodo_tourguide_{}_download.html'.format('ios' if request.iOS else 'adr'), {})
    26
    -
    27
    -
    28
    -@logit
    29
    -def tgu_group_user_detail(request, admin_id):
    30
    -    return render(request, 'page/kodo_user_{}_download.html'.format('ios' if request.iOS else 'adr'), {})

    + 0 - 159
    group/groupuser_views.py

    @@ -1,159 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -
    3
    -from __future__ import division
    4
    -
    5
    -from django_logit import logit
    6
    -from django_response import response
    7
    -from TimeConvert import TimeConvert as tc
    8
    -
    9
    -from account.models import UserInfo
    10
    -from group.models import GroupInfo, GroupUserInfo
    11
    -from utils.error.errno_utils import GroupStatusCode, GroupUserStatusCode, UserStatusCode
    12
    -from utils.group_photo_utils import get_current_photos
    13
    -from utils.redis.connect import r
    14
    -from utils.redis.rgroup import get_group_info, get_group_users_info, set_group_users_info
    15
    -from utils.redis.rkeys import (GROUP_LAST_PHOTO_PK, GROUP_USERS_DELETED_SET, GROUP_USERS_PASSED_SET,
    16
    -                               GROUP_USERS_QUIT_SET, GROUP_USERS_REFUSED_SET)
    17
    -
    18
    -
    19
    -@logit
    20
    -def group_user_join_api(request):
    21
    -    """ 群成员加群 """
    22
    -    group_id = request.POST.get('group_id', '')
    23
    -    user_id = request.POST.get('user_id', '')
    24
    -    nickname = request.POST.get('nickname', '')
    25
    -
    26
    -    # 用户校验
    27
    -    try:
    28
    -        user = UserInfo.objects.get(user_id=user_id, status=True)
    29
    -    except UserInfo.DoesNotExist:
    30
    -        return response(UserStatusCode.USER_NOT_FOUND)
    31
    -
    32
    -    # 群组校验
    33
    -    try:
    34
    -        group = GroupInfo.objects.get(group_id=group_id, status=True)
    35
    -    except GroupInfo.DoesNotExist:
    36
    -        return response(GroupStatusCode.GROUP_NOT_FOUND)
    37
    -
    38
    -    # 群组锁定校验
    39
    -    if group.group_lock:
    40
    -        return response(GroupStatusCode.GROUP_HAS_LOCKED)
    41
    -
    42
    -    # 群组用户记录创建,若记录不存在,则创建,若记录已存在,则更新
    43
    -    group_user, created = GroupUserInfo.objects.get_or_create(
    44
    -        group_id=group_id,
    45
    -        user_id=user_id,
    46
    -    )
    47
    -    if group_user.user_status != GroupUserInfo.PASSED:
    48
    -        group_user.current_id = -1 if group.group_from == GroupInfo.SESSION_GROUP else int(r.get(GROUP_LAST_PHOTO_PK % group_id) or -1)
    49
    -        group_user.nickname = nickname or user.final_nickname
    50
    -        group_user.avatar = user.avatar
    51
    -        # group_user.admin = False  # Admin Field Default False, Should Not Assign
    52
    -        group_user.user_status = GroupUserInfo.PASSED
    53
    -        group_user.passed_at = tc.utc_datetime()
    54
    -        group_user.save()
    55
    -
    56
    -    # Redis 群组用户数据缓存
    57
    -    set_group_users_info(group)
    58
    -
    59
    -    # Redis 群组通过集合缓存
    60
    -    r.srem(GROUP_USERS_REFUSED_SET % group_id, user_id)
    61
    -    r.srem(GROUP_USERS_DELETED_SET % group_id, user_id)
    62
    -    r.srem(GROUP_USERS_QUIT_SET % group_id, user_id)
    63
    -    r.sadd(GROUP_USERS_PASSED_SET % group_id, user_id)
    64
    -
    65
    -    curinfo = get_current_photos(group_id, user_id, group_user.current_id, request=request)
    66
    -
    67
    -    return response(200, 'Group User Join Success', u'群成员加群成功', {
    68
    -        'current_id': curinfo.get('current_id', ''),
    69
    -        'photos': curinfo.get('photos', ''),
    70
    -        'group_id': group_id,
    71
    -        'group': get_group_info(group_id),
    72
    -        'user_id': user_id,
    73
    -        'users': get_group_users_info(group_id, user_id),
    74
    -    })
    75
    -
    76
    -
    77
    -@logit
    78
    -def group_user_remove_api(request):
    79
    -    """ 群成员移除,管理员主动,群成员被动 """
    80
    -    group_id = request.POST.get('group_id', '')
    81
    -    admin_id = request.POST.get('admin_id', '')
    82
    -    user_id = request.POST.get('user_id', '')
    83
    -
    84
    -    # 群组校验
    85
    -    try:
    86
    -        group = GroupInfo.objects.get(group_id=group_id, status=True)
    87
    -    except GroupInfo.DoesNotExist:
    88
    -        return response(GroupStatusCode.GROUP_NOT_FOUND)
    89
    -
    90
    -    # 权限校验
    91
    -    if group.admin_id != admin_id:
    92
    -        return response(GroupStatusCode.NOT_GROUP_ADMIN)
    93
    -
    94
    -    # 管理员也不允许将自己移除
    95
    -    if group.admin_id == user_id:
    96
    -        return response(GroupStatusCode.ADMIN_CANNOT_HANDLE_SELF)
    97
    -
    98
    -    # 群组用户校验
    99
    -    try:
    100
    -        group_user = GroupUserInfo.objects.get(group_id=group_id, user_id=user_id, status=True)
    101
    -    except GroupUserInfo.DoesNotExist:
    102
    -        return response(GroupUserStatusCode.GROUP_USER_NOT_FOUND)
    103
    -
    104
    -    # 群组用户移除
    105
    -    group_user.user_status = GroupUserInfo.DELETED
    106
    -    group_user.deleted_at = tc.utc_datetime()
    107
    -    group_user.save()
    108
    -
    109
    -    # Redis 群组数据缓存更新
    110
    -    group_users = set_group_users_info(group)
    111
    -
    112
    -    # Redis 群组删除集合缓存
    113
    -    r.srem(GROUP_USERS_PASSED_SET % group_id, user_id)
    114
    -    r.sadd(GROUP_USERS_DELETED_SET % group_id, user_id)
    115
    -
    116
    -    return response(200, 'Group User Remove Success', u'群成员移除成功', {
    117
    -        'group_id': group_id,
    118
    -        'users': group_users,
    119
    -    })
    120
    -
    121
    -
    122
    -@logit
    123
    -def group_user_quit_api(request):
    124
    -    """ 群成员退出,群成员主动 """
    125
    -    group_id = request.POST.get('group_id', '')
    126
    -    user_id = request.POST.get('user_id', '')
    127
    -
    128
    -    # 群组校验
    129
    -    try:
    130
    -        group = GroupInfo.objects.get(group_id=group_id, status=True)
    131
    -    except GroupInfo.DoesNotExist:
    132
    -        return response(GroupStatusCode.GROUP_NOT_FOUND)
    133
    -
    134
    -    # 权限校验
    135
    -    if group.admin_id == user_id:  # 管理员也不允许自己退出
    136
    -        return response(GroupStatusCode.NOT_GROUP_ADMIN)
    137
    -
    138
    -    # 群组用户校验
    139
    -    try:
    140
    -        group_user = GroupUserInfo.objects.get(group_id=group_id, user_id=user_id, status=True)
    141
    -    except GroupUserInfo.DoesNotExist:
    142
    -        return response(GroupUserStatusCode.GROUP_USER_NOT_FOUND)
    143
    -
    144
    -    # 群组用户移除
    145
    -    group_user.user_status = GroupUserInfo.QUIT
    146
    -    group_user.quit_at = tc.utc_datetime()
    147
    -    group_user.save()
    148
    -
    149
    -    # Redis 群组数据缓存更新
    150
    -    group_users = set_group_users_info(group)
    151
    -
    152
    -    # Redis 群组删除集合缓存
    153
    -    r.srem(GROUP_USERS_PASSED_SET % group_id, user_id)
    154
    -    r.sadd(GROUP_USERS_QUIT_SET % group_id, user_id)
    155
    -
    156
    -    return response(200, 'Group User Quit Success', u'群成员退出成功', {
    157
    -        'group_id': group_id,
    158
    -        'users': group_users,
    159
    -    })

    + 0 - 423
    group/lensman_views.py

    @@ -1,423 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -
    3
    -from __future__ import division
    4
    -
    5
    -from django.db import transaction
    6
    -from django_curtail_uuid import CurtailUUID
    7
    -from django_logit import logit
    8
    -from django_response import response
    9
    -from ipaddr import client_ip
    10
    -from isoweek import Week
    11
    -from paginator import pagination
    12
    -from TimeConvert import TimeConvert as tc
    13
    -
    14
    -from account.models import LensmanInfo, UserIncomeExpensesInfo, UserInfo
    15
    -from group.models import GroupInfo, GroupPhotoInfo, GroupPhotoOrderInfo
    16
    -from message.models import SystemMessageInfo
    17
    -from pay.models import OrderInfo
    18
    -from photo.models import PhotosInfo
    19
    -from utils.error.errno_utils import LensmanStatusCode, OrderStatusCode, UserStatusCode
    20
    -from utils.message_utils import system_messages
    21
    -from utils.redis.connect import r
    22
    -from utils.redis.rbrief import set_brief_info
    23
    -from utils.redis.rgroup import set_group_info, set_group_info_by_id
    24
    -from utils.redis.rkeys import GROUP_LAST_PHOTO_PK, TODAY_INCOME, TODAY_UPLOAD_PHOTO_AMOUNT, WEEK_INCOME, WEEK_SOLD
    25
    -from utils.redis.rlock import upload_lock
    26
    -from utils.redis.rorder import set_lensman_order_record
    27
    -from utils.redis.rprice import get_lensman_price_fixed, set_lensman_price_fixed
    28
    -from utils.redis.rprofile import set_profile_info
    29
    -from utils.storage_qiniu_utils import file_save
    30
    -
    31
    -
    32
    -@logit
    33
    -def lensman_submit_api(request):
    34
    -    """ 摄影师信息提交 """
    35
    -    lensman_type = int(request.POST.get('lensman_type', 0))
    36
    -    unionid = request.POST.get('unionid', '')
    37
    -    openid = request.POST.get('openid', '')
    38
    -    phone = request.POST.get('phone', '')
    39
    -
    40
    -    if LensmanInfo.objects.filter(phone=phone).exclude(unionid=unionid).exists():
    41
    -        return response(LensmanStatusCode.LENSMAN_PHONE_ALREADY_EXISTS)
    42
    -
    43
    -    fields = {
    44
    -        'name': request.POST.get('name', ''),
    45
    -        'sex': int(request.POST.get('sex', 1)),
    46
    -        'phone': phone,
    47
    -        'location': request.POST.get('location', ''),
    48
    -        'user_status': LensmanInfo.UNVERIFIED,
    49
    -    }
    50
    -
    51
    -    lensman, created = LensmanInfo.objects.get_or_create(unionid=unionid, defaults=fields)
    52
    -
    53
    -    # 状态为 UNVERIFIED 的允许修改, 其他需要登录摄影师 APP 进行信息的修改
    54
    -    # 用户状态校验
    55
    -    if lensman_type == UserInfo.COMMON:  # 普通摄影师校验
    56
    -        if lensman.is_common_lensman and lensman.user_status not in [LensmanInfo.UNVERIFIED, LensmanInfo.REFUSED]:
    57
    -            return response(LensmanStatusCode.LENSMAN_ALREADY_NOT_UNVERIFIED)
    58
    -    elif lensman_type == UserInfo.OUTTAKE:  # 花絮摄影师校验
    59
    -        if lensman.is_common_lensman and lensman.user_status not in [LensmanInfo.UNVERIFIED, LensmanInfo.REFUSED]:
    60
    -            return response(LensmanStatusCode.LENSMAN_ALREADY_NOT_UNVERIFIED)
    61
    -
    62
    -    for key, value in fields.iteritems():
    63
    -        setattr(lensman, key, value)
    64
    -
    65
    -    if lensman_type == LensmanInfo.COMMON:
    66
    -        lensman.is_common_lensman = True
    67
    -    elif lensman_type == LensmanInfo.OUTTAKE:
    68
    -        lensman.is_outtake_lensman = True
    69
    -
    70
    -    lensman.save()
    71
    -
    72
    -    return response(200, 'Submit Success', u'提交成功')
    73
    -
    74
    -
    75
    -@logit
    76
    -@transaction.atomic
    77
    -def lensman_wx_authorize_api(request):
    78
    -    lensman_type = int(request.POST.get('lensman_type', 0))
    79
    -    unionid = request.POST.get('unionid', '')
    80
    -
    81
    -    # 用户校验
    82
    -    try:
    83
    -        user = UserInfo.objects.select_for_update().get(unionid=unionid, islensman=True, status=True)
    84
    -    except UserInfo.DoesNotExist:
    85
    -        return response(LensmanStatusCode.LENSMAN_NOT_FOUND)
    86
    -
    87
    -    # 用户状态校验
    88
    -    if lensman_type == UserInfo.COMMON:  # 普通摄影师校验
    89
    -        if user.is_common_lensman and user.user_status != UserInfo.ACTIVATED:
    90
    -            return response(LensmanStatusCode.LENSMAN_NOT_ACTIVATED)
    91
    -    elif lensman_type == UserInfo.OUTTAKE:  # 花絮摄影师校验
    92
    -        if user.is_outtake_lensman and user.outtake_status != UserInfo.ACTIVATED:
    93
    -            return response(LensmanStatusCode.LENSMAN_NOT_ACTIVATED)
    94
    -
    95
    -    # Set User Key's Value
    96
    -    user.openid_lensman = request.POST.get('openid', '')
    97
    -    user.sex = request.POST.get('sex', 0)
    98
    -    user.nickname = request.POST.get('nickname', '') or request.POST.get('screen_name', '')
    99
    -    user.avatar = request.POST.get('headimgurl', '') or request.POST.get('profile_image_url', '')
    100
    -    user.country = request.POST.get('country', '')
    101
    -    user.province = request.POST.get('province', '')
    102
    -    user.city = request.POST.get('city', '')
    103
    -    user.signup_ip = client_ip(request)
    104
    -    user.signup_at = tc.utc_datetime()
    105
    -    user.save()
    106
    -
    107
    -    set_profile_info(user)
    108
    -
    109
    -    return response(200, 'Lensman Login Success', u'摄影师登录成功', user.data)
    110
    -
    111
    -
    112
    -@logit
    113
    -def lensman_price_fix_api(request):
    114
    -    lensman_id = request.POST.get('user_id', '')
    115
    -    nomark = request.POST.get('nomark', 299)
    116
    -    origin = request.POST.get('origin', 999)
    117
    -
    118
    -    # 用户校验
    119
    -    try:
    120
    -        lensman = LensmanInfo.objects.get(lensman_id=lensman_id, status=True)
    121
    -    except LensmanInfo.DoesNotExist:
    122
    -        return response(UserStatusCode.USER_NOT_FOUND)
    123
    -
    124
    -    if 'nomark' in request.POST:
    125
    -        lensman.nomark = nomark
    126
    -    if 'origin' in request.POST:
    127
    -        lensman.origin = origin
    128
    -    lensman.save()
    129
    -
    130
    -    set_lensman_price_fixed(lensman_id)
    131
    -
    132
    -    return response(200, 'Lensman Price Fix Success', u'摄影师定价修改成功')
    133
    -
    134
    -
    135
    -@logit
    136
    -def lensman_photo_upload_api(request):
    137
    -    """ 摄影师照片上传 """
    138
    -    lensman_type = int(request.POST.get('lensman_type', 0) or 0)
    139
    -    user_id = lensman_id = request.POST.get('user_id', '')
    140
    -    nickname = request.POST.get('nickname', '')
    141
    -    group_id = request.POST.get('group_id', '')
    142
    -    session_id = request.POST.get('session_id', '')
    143
    -
    144
    -    photo_id = request.POST.get('photo_id', '')
    145
    -
    146
    -    photo = request.FILES.get('photo', '')
    147
    -
    148
    -    # 用户校验
    149
    -    try:
    150
    -        user = UserInfo.objects.get(user_id=user_id, islensman=True, status=True)
    151
    -    except UserInfo.DoesNotExist:
    152
    -        return response(LensmanStatusCode.LENSMAN_NOT_FOUND)
    153
    -
    154
    -    # 用户状态校验
    155
    -    if lensman_type == UserInfo.COMMON:  # 普通摄影师校验
    156
    -        watermark = True
    157
    -        if user.is_common_lensman and user.user_status != UserInfo.ACTIVATED:
    158
    -            return response(LensmanStatusCode.LENSMAN_NOT_ACTIVATED)
    159
    -    elif lensman_type == UserInfo.OUTTAKE:  # 花絮摄影师校验
    160
    -        watermark = False
    161
    -        if user.is_outtake_lensman and user.outtake_status != UserInfo.ACTIVATED:
    162
    -            return response(LensmanStatusCode.LENSMAN_NOT_ACTIVATED)
    163
    -
    164
    -    if not group_id:
    165
    -        # 判断通过 session_id 创建的群组是否存在,如果不存在,则直接创建
    166
    -        group, group_created = GroupInfo.objects.get_or_create(session_id=session_id, group_from=GroupInfo.SESSION_GROUP, defaults={
    167
    -            'group_id': CurtailUUID.uuid(GroupInfo, 'group_id'),
    168
    -            # 'admin_id': user_id,  # 摄影师非管理员,首个扫码进群的用户为管理员
    169
    -            'group_name': user.final_nickname,
    170
    -            'group_default_avatar': 0,
    171
    -        })
    172
    -
    173
    -        # Redis 群组数据缓存
    174
    -        if group_created:
    175
    -            set_group_info(group)
    176
    -
    177
    -        group_id = group.group_id
    178
    -
    179
    -    if photo and upload_lock(group_id, user_id, photo):
    180
    -        photo_info = file_save(photo, prefix='photo', ext='.jpeg', watermark=watermark, thumbnail=True)
    181
    -
    182
    -        # 写 PhotosInfo 表
    183
    -        photo, created = PhotosInfo.objects.get_or_create(
    184
    -            lensman_id=lensman_id,
    185
    -            session_id=session_id,
    186
    -            photo_id=photo_id,
    187
    -        )
    188
    -        # 无水印
    189
    -        photo.m_photo_path = photo_info.photo_path
    190
    -        # 有水印
    191
    -        photo.p_photo_path = photo_info.photo_watermark_path
    192
    -        photo.save()
    193
    -
    194
    -        # 获取摄影师定价
    195
    -        price_info = get_lensman_price_fixed(user_id)
    196
    -
    197
    -        # 写 GroupPhotoInfo 表
    198
    -        group_photo, created = GroupPhotoInfo.objects.get_or_create(
    199
    -            group_id=group_id,
    200
    -            user_id=user_id,
    201
    -            photo_md5=photo_info.photo_md5,
    202
    -            defaults={
    203
    -                'nickname': user.final_nickname,
    204
    -                'avatar': user.avatar,
    205
    -                'photo_path': photo_info.photo_watermark_path if watermark else photo_info.photo_path,
    206
    -                'has_watermark': watermark,
    207
    -                'photo_w': photo_info.photo_w,
    208
    -                'photo_h': photo_info.photo_h,
    209
    -                'photo_thumbnail_path': photo_info.photo_thumbnail_path,
    210
    -                'photo_thumbnail_w': photo_info.photo_thumbnail_w,
    211
    -                'photo_thumbnail_h': photo_info.photo_thumbnail_h,
    212
    -                'photo_thumbnail2_path': photo_info.photo_thumbnail2_path,
    213
    -                'photo_thumbnail2_w': photo_info.photo_thumbnail2_w,
    214
    -                'photo_thumbnail2_h': photo_info.photo_thumbnail2_h,
    215
    -                'photo_from': GroupPhotoInfo.SESSION_GROUP,
    216
    -                'session_id': photo.session_id,
    217
    -                'lensman_id': photo.lensman_id,
    218
    -                'lensman_photo_id': photo.photo_id,
    219
    -                'nomark': price_info.get('nomark', 999),
    220
    -                'origin': price_info.get('origin', 999),
    221
    -                'lensman_type': lensman_type,
    222
    -            }
    223
    -        )
    224
    -
    225
    -        if created:
    226
    -            # 设置群组最后一张照片PK
    227
    -            r.set(GROUP_LAST_PHOTO_PK % group_id, group_photo.pk)
    228
    -
    229
    -            # 更新今日上传照片数量
    230
    -            r.incr(TODAY_UPLOAD_PHOTO_AMOUNT % (user_id, tc.local_string(format='%Y%m%d')))
    231
    -
    232
    -            # Redis 群组数据缓存
    233
    -            set_group_info_by_id(group_id)
    234
    -
    235
    -    return response(200, 'Lensman Upload Photo Success', u'摄影师照片上传成功', {
    236
    -        'group_id': group_id,
    237
    -    })
    238
    -
    239
    -
    240
    -@logit
    241
    -@transaction.atomic
    242
    -def lensman_origin_photo_upload_api(request):
    243
    -    order_id = request.POST.get('order_id', '')
    244
    -
    245
    -    user_id = lensman_id = request.POST.get('user_id', '')
    246
    -    session_id = request.POST.get('session_id', '')
    247
    -
    248
    -    photo_id = request.POST.get('photo_id', '')
    249
    -
    250
    -    deleted = int(request.POST.get('deleted', 0))
    251
    -
    252
    -    photo = request.FILES.get('photo', '')
    253
    -
    254
    -    try:
    255
    -        order = OrderInfo.objects.select_for_update().get(order_id=order_id, pay_status=OrderInfo.PAID)
    256
    -    except OrderInfo.DoesNotExist:
    257
    -        return response(OrderStatusCode.WX_ORDER_NOT_FOUND)
    258
    -
    259
    -    # 原图已删除, 处理退款逻辑
    260
    -    if deleted and order.photo_status == OrderInfo.WANTED:
    261
    -        # 用户余额增加
    262
    -        try:
    263
    -            from_user = UserInfo.objects.select_for_update().get(user_id=order.from_uid)
    264
    -        except UserInfo.DoesNotExist:
    265
    -            pass
    266
    -
    267
    -        if from_user:
    268
    -            # 余额增加
    269
    -            from_user.balance += order.total_fee
    270
    -            from_user.save()
    271
    -            # 余额记录
    272
    -            UserIncomeExpensesInfo.objects.create(
    273
    -                user_id=order.from_uid,
    274
    -                photo_id=order.photo_id,
    275
    -                type=UserIncomeExpensesInfo.INCOME,
    276
    -                amount=order.total_fee,
    277
    -                balance=from_user.balance,
    278
    -                freeze_income_amount=0,
    279
    -                freeze_income_balance=from_user.freeze_income_balance,
    280
    -                remark=u'高清图购买退款',
    281
    -            )
    282
    -
    283
    -        # 摄影师余额减少
    284
    -        try:
    285
    -            to_user = UserInfo.objects.select_for_update().get(user_id=order.to_uid)
    286
    -        except UserInfo.DoesNotExist:
    287
    -            pass
    288
    -
    289
    -        if to_user:
    290
    -            # 余额减少
    291
    -            to_user.freeze_income_balance -= order.total_fee
    292
    -            to_user.save()
    293
    -            # 余额记录
    294
    -            UserIncomeExpensesInfo.objects.create(
    295
    -                user_id=order.to_uid,
    296
    -                photo_id=order.photo_id,
    297
    -                type=UserIncomeExpensesInfo.EXPENSE,
    298
    -                amount=order.total_fee,
    299
    -                balance=to_user.balance,
    300
    -                freeze_income_amount=0,
    301
    -                freeze_income_balance=to_user.freeze_income_balance,
    302
    -                remark=u'高清图购买退款',
    303
    -            )
    304
    -
    305
    -        # 更新订单状态
    306
    -        order.photo_status = OrderInfo.DELETED
    307
    -        order.reback_status = True
    308
    -        order.reback_at = tc.utc_datetime()
    309
    -        order.save()
    310
    -
    311
    -    if photo and upload_lock(order_id, user_id, photo):
    312
    -        # 写 PhotosInfo 表
    313
    -        photo_info = file_save(photo, prefix='photo', ext='.jpeg')
    314
    -
    315
    -        PhotosInfo.objects.filter(
    316
    -            lensman_id=lensman_id,
    317
    -            session_id=session_id,
    318
    -            photo_id=photo_id,
    319
    -        ).update(
    320
    -            r_photo_path=photo_info.photo_path
    321
    -        )
    322
    -
    323
    -        porder, created = GroupPhotoOrderInfo.objects.select_for_update().get_or_create(
    324
    -            group_id=order.group_id,
    325
    -            session_id=session_id,
    326
    -            user_id=order.from_uid,
    327
    -            photo_id=order.photo_id,
    328
    -            lensman_photo_id=photo_id,
    329
    -        )
    330
    -        porder.r_photo_path = photo_info.photo_path
    331
    -        porder.save()
    332
    -
    333
    -        set_lensman_order_record(porder)
    334
    -
    335
    -        # 摄影师余额解冻
    336
    -        try:
    337
    -            to_user = UserInfo.objects.select_for_update().get(user_id=order.to_uid)
    338
    -        except UserInfo.DoesNotExist:
    339
    -            pass
    340
    -
    341
    -        if to_user:
    342
    -            # 余额解冻
    343
    -            to_user.balance += order.total_fee
    344
    -            to_user.freeze_income_balance -= order.total_fee
    345
    -            to_user.save()
    346
    -            # Redis 数值更新
    347
    -            set_brief_info(order.to_uid, order.photo_type, order.total_fee, dt=order.created_at)
    348
    -            # 余额记录
    349
    -            UserIncomeExpensesInfo.objects.create(
    350
    -                user_id=order.to_uid,
    351
    -                photo_id=order.photo_id,
    352
    -                type=UserIncomeExpensesInfo.UNFREEZE,
    353
    -                amount=order.total_fee,
    354
    -                balance=to_user.balance,
    355
    -                freeze_income_amount=order.total_fee,
    356
    -                freeze_income_balance=to_user.freeze_income_balance,
    357
    -                remark=u'高清图购买退款',
    358
    -            )
    359
    -
    360
    -        order.photo_status = OrderInfo.FETCHED
    361
    -        order.save()
    362
    -
    363
    -    return response(200, 'Lensman Upload Origin Photo Success', u'摄影师照片高清图上传成功')
    364
    -
    365
    -
    366
    -@logit
    367
    -def lensman_brief_api(request):
    368
    -    user_id = request.POST.get('user_id', '')
    369
    -
    370
    -    ymd = tc.local_string(format='%Y%m%d')
    371
    -    week = Week.thisweek().isoformat()
    372
    -
    373
    -    # 周收入
    374
    -    origin_week_income = int(r.get(WEEK_INCOME % (user_id, OrderInfo.ORIGIN, week)) or 0)
    375
    -    # 日收入
    376
    -    nomark_today_income = int(r.get(TODAY_INCOME % (user_id, OrderInfo.NOMARK, ymd)) or 0)
    377
    -    # 日上传
    378
    -    today_upload = int(r.get(TODAY_UPLOAD_PHOTO_AMOUNT % (user_id, ymd)) or 0)
    379
    -    # 周售出
    380
    -    week_sold = int(r.get(WEEK_SOLD % (user_id, OrderInfo.ORIGIN, ymd)) or 0)
    381
    -
    382
    -    # 摄影师端系统消息
    383
    -    systems = system_messages(user_id, SystemMessageInfo.PAIAI_LENSMAN)
    384
    -    systems, left = pagination(systems, 1, 10)
    385
    -    systems = [msg.msg_info(user_id) for msg in systems]
    386
    -
    387
    -    # 照片购买记录
    388
    -    orders = OrderInfo.objects.filter(to_uid=user_id, pay_status=OrderInfo.PAID, status=True).order_by('-pk')
    389
    -    orders, left = pagination(orders, 1, 10)
    390
    -    orders = [order.data(user_id) for order in orders]
    391
    -
    392
    -    # 获取摄影师定价
    393
    -    price_fixed = get_lensman_price_fixed(user_id)
    394
    -
    395
    -    return response(200, 'Get Lensman Brief Success', u'获取摄影师简报成功', {
    396
    -        'origin_week_income': origin_week_income,
    397
    -        'nomark_today_income': nomark_today_income,
    398
    -        'today_upload': today_upload,
    399
    -        'week_sold': week_sold,
    400
    -        'messages': {
    401
    -            'system': systems,
    402
    -            'orders': orders,
    403
    -        },
    404
    -        'price_fixed': price_fixed,
    405
    -    })
    406
    -
    407
    -
    408
    -@logit
    409
    -def lensman_origin_wanted_api(request):
    410
    -    user_id = request.POST.get('user_id', '')
    411
    -
    412
    -    orders = OrderInfo.objects.filter(
    413
    -        to_uid=user_id,
    414
    -        photo_type=OrderInfo.ORIGIN,
    415
    -        photo_status=OrderInfo.WANTED,
    416
    -        pay_status=OrderInfo.PAID,
    417
    -        status=True
    418
    -    ).order_by('pk')
    419
    -    wanted = [order.lensdata for order in orders]
    420
    -
    421
    -    return response(200, 'Get Origin Wanted Success', u'获取需要上传原图成功', {
    422
    -        'wanted': wanted
    423
    -    })

    + 0 - 69
    group/migrations/0001_initial.py

    @@ -1,69 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -from __future__ import unicode_literals
    3
    -
    4
    -from django.db import models, migrations
    5
    -
    6
    -
    7
    -class Migration(migrations.Migration):
    8
    -
    9
    -    dependencies = [
    10
    -    ]
    11
    -
    12
    -    operations = [
    13
    -        migrations.CreateModel(
    14
    -            name='GroupInfo',
    15
    -            fields=[
    16
    -                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
    17
    -                ('status', models.BooleanField(default=True, help_text='\u72b6\u6001', verbose_name='status')),
    18
    -                ('created_at', models.DateTimeField(help_text='\u521b\u5efa\u65f6\u95f4', verbose_name='created_at', auto_now_add=True)),
    19
    -                ('updated_at', models.DateTimeField(help_text='\u66f4\u65b0\u65f6\u95f4', verbose_name='updated_at', auto_now=True)),
    20
    -                ('group_id', models.CharField(null=True, max_length=255, blank=True, help_text='\u7fa4\u7ec4\u552f\u4e00\u6807\u8bc6', unique=True, verbose_name='group_id', db_index=True)),
    21
    -                ('group_name', models.CharField(help_text='\u7fa4\u7ec4\u540d\u79f0', max_length=255, null=True, verbose_name='group_name', blank=True)),
    22
    -                ('group_desc', models.TextField(help_text='\u7fa4\u7ec4\u63cf\u8ff0', null=True, verbose_name='group_desc', blank=True)),
    23
    -                ('group_from', models.IntegerField(default=0, help_text='\u7fa4\u7ec4\u6765\u6e90', verbose_name='group_from', choices=[(0, 'APP \u5efa\u7fa4'), (1, 'SESSION \u5efa\u7fa4')])),
    24
    -                ('group_lock', models.BooleanField(default=False, help_text='\u7fa4\u7ec4\u9501\u5b9a', verbose_name='group_lock')),
    25
    -            ],
    26
    -            options={
    27
    -                'verbose_name': 'groupinfo',
    28
    -                'verbose_name_plural': 'groupinfo',
    29
    -            },
    30
    -        ),
    31
    -        migrations.CreateModel(
    32
    -            name='GroupPhotoInfo',
    33
    -            fields=[
    34
    -                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
    35
    -                ('status', models.BooleanField(default=True, help_text='\u72b6\u6001', verbose_name='status')),
    36
    -                ('created_at', models.DateTimeField(help_text='\u521b\u5efa\u65f6\u95f4', verbose_name='created_at', auto_now_add=True)),
    37
    -                ('updated_at', models.DateTimeField(help_text='\u66f4\u65b0\u65f6\u95f4', verbose_name='updated_at', auto_now=True)),
    38
    -                ('group_id', models.CharField(max_length=255, blank=True, help_text='\u7fa4\u7ec4\u552f\u4e00\u6807\u8bc6', null=True, verbose_name='group_id', db_index=True)),
    39
    -                ('user_id', models.CharField(help_text='\u7528\u6237\u552f\u4e00\u6807\u8bc6', max_length=255, null=True, verbose_name='user_id', blank=True)),
    40
    -                ('nickname', models.CharField(help_text='\u7528\u6237\u7fa4\u7ec4\u6635\u79f0', max_length=255, null=True, verbose_name='nickname', blank=True)),
    41
    -                ('photo_path', models.CharField(help_text='\u7167\u7247\u5b58\u653e\u8def\u5f84', max_length=255, null=True, verbose_name='photo_path', blank=True)),
    42
    -                ('photo_thumbnail_path', models.CharField(help_text='\u7167\u7247\u7f29\u7565\u56fe\u5b58\u653e\u8def\u5f84', max_length=255, null=True, verbose_name='photo_thumbnail_path', blank=True)),
    43
    -            ],
    44
    -            options={
    45
    -                'verbose_name': 'groupuserinfo',
    46
    -                'verbose_name_plural': 'groupuserinfo',
    47
    -            },
    48
    -        ),
    49
    -        migrations.CreateModel(
    50
    -            name='GroupUserInfo',
    51
    -            fields=[
    52
    -                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
    53
    -                ('status', models.BooleanField(default=True, help_text='\u72b6\u6001', verbose_name='status')),
    54
    -                ('created_at', models.DateTimeField(help_text='\u521b\u5efa\u65f6\u95f4', verbose_name='created_at', auto_now_add=True)),
    55
    -                ('updated_at', models.DateTimeField(help_text='\u66f4\u65b0\u65f6\u95f4', verbose_name='updated_at', auto_now=True)),
    56
    -                ('group_id', models.CharField(max_length=255, blank=True, help_text='\u7fa4\u7ec4\u552f\u4e00\u6807\u8bc6', null=True, verbose_name='group_id', db_index=True)),
    57
    -                ('user_id', models.CharField(help_text='\u7528\u6237\u552f\u4e00\u6807\u8bc6', max_length=255, null=True, verbose_name='user_id', blank=True)),
    58
    -                ('nickname', models.CharField(help_text='\u7528\u6237\u7fa4\u7ec4\u6635\u79f0', max_length=255, null=True, verbose_name='nickname', blank=True)),
    59
    -                ('admin', models.BooleanField(default=False, help_text='\u7fa4\u7ec4\u7ba1\u7406\u5458', verbose_name='admin')),
    60
    -                ('user_status', models.IntegerField(default=0, verbose_name='user_status', choices=[(0, '\u7533\u8bf7\u4e2d'), (1, '\u5df2\u901a\u8fc7'), (2, '\u5df2\u62d2\u7edd')])),
    61
    -                ('passed_at', models.DateTimeField(help_text='\u901a\u8fc7\u65f6\u95f4', null=True, verbose_name='passed_at', blank=True)),
    62
    -                ('refused_at', models.DateTimeField(help_text='\u62d2\u7edd\u65f6\u95f4', null=True, verbose_name='refused_at', blank=True)),
    63
    -            ],
    64
    -            options={
    65
    -                'verbose_name': 'groupuserinfo',
    66
    -                'verbose_name_plural': 'groupuserinfo',
    67
    -            },
    68
    -        ),
    69
    -    ]

    + 0 - 19
    group/migrations/0002_groupinfo_session_id.py

    @@ -1,19 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -from __future__ import unicode_literals
    3
    -
    4
    -from django.db import models, migrations
    5
    -
    6
    -
    7
    -class Migration(migrations.Migration):
    8
    -
    9
    -    dependencies = [
    10
    -        ('group', '0001_initial'),
    11
    -    ]
    12
    -
    13
    -    operations = [
    14
    -        migrations.AddField(
    15
    -            model_name='groupinfo',
    16
    -            name='session_id',
    17
    -            field=models.CharField(max_length=255, blank=True, help_text='\u7167\u7247\u7ec4\u552f\u4e00\u6807\u8bc6', null=True, verbose_name='session_id', db_index=True),
    18
    -        ),
    19
    -    ]

    + 0 - 19
    group/migrations/0003_groupinfo_admin_id.py

    @@ -1,19 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -from __future__ import unicode_literals
    3
    -
    4
    -from django.db import models, migrations
    5
    -
    6
    -
    7
    -class Migration(migrations.Migration):
    8
    -
    9
    -    dependencies = [
    10
    -        ('group', '0002_groupinfo_session_id'),
    11
    -    ]
    12
    -
    13
    -    operations = [
    14
    -        migrations.AddField(
    15
    -            model_name='groupinfo',
    16
    -            name='admin_id',
    17
    -            field=models.CharField(help_text='\u7528\u6237\u552f\u4e00\u6807\u8bc6', max_length=255, null=True, verbose_name='admin_id', blank=True),
    18
    -        ),
    19
    -    ]

    + 0 - 23
    group/migrations/0004_auto_20151216_2337.py

    @@ -1,23 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -from __future__ import unicode_literals
    3
    -
    4
    -from django.db import models, migrations
    5
    -
    6
    -
    7
    -class Migration(migrations.Migration):
    8
    -
    9
    -    dependencies = [
    10
    -        ('group', '0003_groupinfo_admin_id'),
    11
    -    ]
    12
    -
    13
    -    operations = [
    14
    -        migrations.AlterModelOptions(
    15
    -            name='groupphotoinfo',
    16
    -            options={'verbose_name': 'groupphotoinfo', 'verbose_name_plural': 'groupphotoinfo'},
    17
    -        ),
    18
    -        migrations.AddField(
    19
    -            model_name='groupuserinfo',
    20
    -            name='deleted_at',
    21
    -            field=models.DateTimeField(help_text='\u5220\u9664\u65f6\u95f4', null=True, verbose_name='deleted_at', blank=True),
    22
    -        ),
    23
    -    ]

    + 0 - 19
    group/migrations/0005_groupuserinfo_current_id.py

    @@ -1,19 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -from __future__ import unicode_literals
    3
    -
    4
    -from django.db import models, migrations
    5
    -
    6
    -
    7
    -class Migration(migrations.Migration):
    8
    -
    9
    -    dependencies = [
    10
    -        ('group', '0004_auto_20151216_2337'),
    11
    -    ]
    12
    -
    13
    -    operations = [
    14
    -        migrations.AddField(
    15
    -            model_name='groupuserinfo',
    16
    -            name='current_id',
    17
    -            field=models.IntegerField(default=-1, help_text='\u5f53\u524d\u7fa4\u7ec4\u7167\u7247ID', verbose_name='current_id'),
    18
    -        ),
    19
    -    ]

    + 0 - 19
    group/migrations/0006_groupuserinfo_avatar.py

    @@ -1,19 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -from __future__ import unicode_literals
    3
    -
    4
    -from django.db import models, migrations
    5
    -
    6
    -
    7
    -class Migration(migrations.Migration):
    8
    -
    9
    -    dependencies = [
    10
    -        ('group', '0005_groupuserinfo_current_id'),
    11
    -    ]
    12
    -
    13
    -    operations = [
    14
    -        migrations.AddField(
    15
    -            model_name='groupuserinfo',
    16
    -            name='avatar',
    17
    -            field=models.CharField(help_text='\u7528\u6237\u5934\u50cf', max_length=255, null=True, verbose_name='avatar', blank=True),
    18
    -        ),
    19
    -    ]

    + 0 - 19
    group/migrations/0007_auto_20160112_2040.py

    @@ -1,19 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -from __future__ import unicode_literals
    3
    -
    4
    -from django.db import models, migrations
    5
    -
    6
    -
    7
    -class Migration(migrations.Migration):
    8
    -
    9
    -    dependencies = [
    10
    -        ('group', '0006_groupuserinfo_avatar'),
    11
    -    ]
    12
    -
    13
    -    operations = [
    14
    -        migrations.AlterField(
    15
    -            model_name='groupuserinfo',
    16
    -            name='user_status',
    17
    -            field=models.IntegerField(default=0, verbose_name='user_status', choices=[(0, '\u7533\u8bf7\u4e2d'), (1, '\u5df2\u901a\u8fc7'), (2, '\u5df2\u62d2\u7edd'), (3, '\u5df2\u5220\u9664')]),
    18
    -        ),
    19
    -    ]

    + 0 - 32
    group/migrations/0008_photocommentinfo.py

    @@ -1,32 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -from __future__ import unicode_literals
    3
    -
    4
    -from django.db import models, migrations
    5
    -
    6
    -
    7
    -class Migration(migrations.Migration):
    8
    -
    9
    -    dependencies = [
    10
    -        ('group', '0007_auto_20160112_2040'),
    11
    -    ]
    12
    -
    13
    -    operations = [
    14
    -        migrations.CreateModel(
    15
    -            name='PhotoCommentInfo',
    16
    -            fields=[
    17
    -                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
    18
    -                ('status', models.BooleanField(default=True, help_text='\u72b6\u6001', verbose_name='status')),
    19
    -                ('created_at', models.DateTimeField(help_text='\u521b\u5efa\u65f6\u95f4', verbose_name='created_at', auto_now_add=True)),
    20
    -                ('updated_at', models.DateTimeField(help_text='\u66f4\u65b0\u65f6\u95f4', verbose_name='updated_at', auto_now=True)),
    21
    -                ('photo_id', models.CharField(max_length=255, blank=True, help_text='\u98de\u56fe\u552f\u4e00\u6807\u8bc6', null=True, verbose_name='photo_id', db_index=True)),
    22
    -                ('user_id', models.CharField(help_text='\u7528\u6237\u552f\u4e00\u6807\u8bc6', max_length=255, null=True, verbose_name='user_id', blank=True)),
    23
    -                ('nickname', models.CharField(help_text='\u7528\u6237\u7fa4\u7ec4\u6635\u79f0', max_length=255, null=True, verbose_name='nickname', blank=True)),
    24
    -                ('avatar', models.CharField(help_text='\u7528\u6237\u5934\u50cf', max_length=255, null=True, verbose_name='avatar', blank=True)),
    25
    -                ('comment', models.TextField(help_text='\u7528\u6237\u8bc4\u8bba', null=True, verbose_name='comment', blank=True)),
    26
    -            ],
    27
    -            options={
    28
    -                'verbose_name': 'photocommentinfo',
    29
    -                'verbose_name_plural': 'photocommentinfo',
    30
    -            },
    31
    -        ),
    32
    -    ]

    + 0 - 32
    group/migrations/0009_photothumbupinfo.py

    @@ -1,32 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -from __future__ import unicode_literals
    3
    -
    4
    -from django.db import models, migrations
    5
    -
    6
    -
    7
    -class Migration(migrations.Migration):
    8
    -
    9
    -    dependencies = [
    10
    -        ('group', '0008_photocommentinfo'),
    11
    -    ]
    12
    -
    13
    -    operations = [
    14
    -        migrations.CreateModel(
    15
    -            name='PhotoThumbUpInfo',
    16
    -            fields=[
    17
    -                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
    18
    -                ('status', models.BooleanField(default=True, help_text='\u72b6\u6001', verbose_name='status')),
    19
    -                ('created_at', models.DateTimeField(help_text='\u521b\u5efa\u65f6\u95f4', verbose_name='created_at', auto_now_add=True)),
    20
    -                ('updated_at', models.DateTimeField(help_text='\u66f4\u65b0\u65f6\u95f4', verbose_name='updated_at', auto_now=True)),
    21
    -                ('photo_id', models.CharField(max_length=255, blank=True, help_text='\u98de\u56fe\u552f\u4e00\u6807\u8bc6', null=True, verbose_name='photo_id', db_index=True)),
    22
    -                ('user_id', models.CharField(help_text='\u7528\u6237\u552f\u4e00\u6807\u8bc6', max_length=255, null=True, verbose_name='user_id', blank=True)),
    23
    -                ('nickname', models.CharField(help_text='\u7528\u6237\u7fa4\u7ec4\u6635\u79f0', max_length=255, null=True, verbose_name='nickname', blank=True)),
    24
    -                ('avatar', models.CharField(help_text='\u7528\u6237\u5934\u50cf', max_length=255, null=True, verbose_name='avatar', blank=True)),
    25
    -                ('thumbup', models.BooleanField(default=True, help_text='\u7528\u6237\u70b9\u8d5e', db_index=True, verbose_name='thumbup')),
    26
    -            ],
    27
    -            options={
    28
    -                'verbose_name': 'photothumbupinfo',
    29
    -                'verbose_name_plural': 'photothumbupinfo',
    30
    -            },
    31
    -        ),
    32
    -    ]

    + 0 - 39
    group/migrations/0010_auto_20160120_1830.py

    @@ -1,39 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -from __future__ import unicode_literals
    3
    -
    4
    -from django.db import models, migrations
    5
    -
    6
    -
    7
    -class Migration(migrations.Migration):
    8
    -
    9
    -    dependencies = [
    10
    -        ('group', '0009_photothumbupinfo'),
    11
    -    ]
    12
    -
    13
    -    operations = [
    14
    -        migrations.AlterField(
    15
    -            model_name='groupinfo',
    16
    -            name='status',
    17
    -            field=models.BooleanField(default=True, help_text='\u72b6\u6001', db_index=True, verbose_name='status'),
    18
    -        ),
    19
    -        migrations.AlterField(
    20
    -            model_name='groupphotoinfo',
    21
    -            name='status',
    22
    -            field=models.BooleanField(default=True, help_text='\u72b6\u6001', db_index=True, verbose_name='status'),
    23
    -        ),
    24
    -        migrations.AlterField(
    25
    -            model_name='groupuserinfo',
    26
    -            name='status',
    27
    -            field=models.BooleanField(default=True, help_text='\u72b6\u6001', db_index=True, verbose_name='status'),
    28
    -        ),
    29
    -        migrations.AlterField(
    30
    -            model_name='photocommentinfo',
    31
    -            name='status',
    32
    -            field=models.BooleanField(default=True, help_text='\u72b6\u6001', db_index=True, verbose_name='status'),
    33
    -        ),
    34
    -        migrations.AlterField(
    35
    -            model_name='photothumbupinfo',
    36
    -            name='status',
    37
    -            field=models.BooleanField(default=True, help_text='\u72b6\u6001', db_index=True, verbose_name='status'),
    38
    -        ),
    39
    -    ]

    + 0 - 24
    group/migrations/0011_auto_20160302_2048.py

    @@ -1,24 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -from __future__ import unicode_literals
    3
    -
    4
    -from django.db import models, migrations
    5
    -
    6
    -
    7
    -class Migration(migrations.Migration):
    8
    -
    9
    -    dependencies = [
    10
    -        ('group', '0010_auto_20160120_1830'),
    11
    -    ]
    12
    -
    13
    -    operations = [
    14
    -        migrations.AddField(
    15
    -            model_name='groupphotoinfo',
    16
    -            name='comment_num',
    17
    -            field=models.IntegerField(default=0, help_text='\u7167\u7247\u8bc4\u8bba\u6570\u91cf', verbose_name='comment_num'),
    18
    -        ),
    19
    -        migrations.AddField(
    20
    -            model_name='groupphotoinfo',
    21
    -            name='thumbup_num',
    22
    -            field=models.IntegerField(default=0, help_text='\u7167\u7247\u70b9\u8d5e\u6570\u91cf', verbose_name='thumbup_num'),
    23
    -        ),
    24
    -    ]

    + 0 - 19
    group/migrations/0012_groupinfo_group_avatar.py

    @@ -1,19 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -from __future__ import unicode_literals
    3
    -
    4
    -from django.db import models, migrations
    5
    -
    6
    -
    7
    -class Migration(migrations.Migration):
    8
    -
    9
    -    dependencies = [
    10
    -        ('group', '0011_auto_20160302_2048'),
    11
    -    ]
    12
    -
    13
    -    operations = [
    14
    -        migrations.AddField(
    15
    -            model_name='groupinfo',
    16
    -            name='group_avatar',
    17
    -            field=models.CharField(help_text='\u7fa4\u7ec4\u5934\u50cf', max_length=255, null=True, verbose_name='group_avatar', blank=True),
    18
    -        ),
    19
    -    ]

    + 0 - 19
    group/migrations/0013_groupinfo_group_default_avatar.py

    @@ -1,19 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -from __future__ import unicode_literals
    3
    -
    4
    -from django.db import models, migrations
    5
    -
    6
    -
    7
    -class Migration(migrations.Migration):
    8
    -
    9
    -    dependencies = [
    10
    -        ('group', '0012_groupinfo_group_avatar'),
    11
    -    ]
    12
    -
    13
    -    operations = [
    14
    -        migrations.AddField(
    15
    -            model_name='groupinfo',
    16
    -            name='group_default_avatar',
    17
    -            field=models.IntegerField(default=0, help_text='\u7fa4\u7ec4\u9ed8\u8ba4\u5934\u50cf\uff0c0 - 255\uff0c\u6c34\u679c\u5934\u50cf', verbose_name='group_default_avatar'),
    18
    -        ),
    19
    -    ]

    + 0 - 34
    group/migrations/0014_auto_20160308_2347.py

    @@ -1,34 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -from __future__ import unicode_literals
    3
    -
    4
    -from django.db import models, migrations
    5
    -
    6
    -
    7
    -class Migration(migrations.Migration):
    8
    -
    9
    -    dependencies = [
    10
    -        ('group', '0013_groupinfo_group_default_avatar'),
    11
    -    ]
    12
    -
    13
    -    operations = [
    14
    -        migrations.AddField(
    15
    -            model_name='groupphotoinfo',
    16
    -            name='photo_h',
    17
    -            field=models.IntegerField(default=0, help_text='\u7167\u7247\u9ad8\u5ea6', verbose_name='photo_h'),
    18
    -        ),
    19
    -        migrations.AddField(
    20
    -            model_name='groupphotoinfo',
    21
    -            name='photo_thumbnail_h',
    22
    -            field=models.IntegerField(default=0, help_text='\u7167\u7247\u7f29\u7565\u56fe\u9ad8\u5ea6', verbose_name='photo_thumbnail_h'),
    23
    -        ),
    24
    -        migrations.AddField(
    25
    -            model_name='groupphotoinfo',
    26
    -            name='photo_thumbnail_w',
    27
    -            field=models.IntegerField(default=0, help_text='\u7167\u7247\u7f29\u7565\u56fe\u5bbd\u5ea6', verbose_name='photo_thumbnail_w'),
    28
    -        ),
    29
    -        migrations.AddField(
    30
    -            model_name='groupphotoinfo',
    31
    -            name='photo_w',
    32
    -            field=models.IntegerField(default=0, help_text='\u7167\u7247\u5bbd\u5ea6', verbose_name='photo_w'),
    33
    -        ),
    34
    -    ]

    + 0 - 19
    group/migrations/0015_groupphotoinfo_avatar.py

    @@ -1,19 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -from __future__ import unicode_literals
    3
    -
    4
    -from django.db import models, migrations
    5
    -
    6
    -
    7
    -class Migration(migrations.Migration):
    8
    -
    9
    -    dependencies = [
    10
    -        ('group', '0014_auto_20160308_2347'),
    11
    -    ]
    12
    -
    13
    -    operations = [
    14
    -        migrations.AddField(
    15
    -            model_name='groupphotoinfo',
    16
    -            name='avatar',
    17
    -            field=models.CharField(help_text='\u7528\u6237\u5934\u50cf', max_length=255, null=True, verbose_name='avatar', blank=True),
    18
    -        ),
    19
    -    ]

    + 0 - 24
    group/migrations/0016_auto_20160321_1535.py

    @@ -1,24 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -from __future__ import unicode_literals
    3
    -
    4
    -from django.db import models, migrations
    5
    -
    6
    -
    7
    -class Migration(migrations.Migration):
    8
    -
    9
    -    dependencies = [
    10
    -        ('group', '0015_groupphotoinfo_avatar'),
    11
    -    ]
    12
    -
    13
    -    operations = [
    14
    -        migrations.AddField(
    15
    -            model_name='groupuserinfo',
    16
    -            name='quit_at',
    17
    -            field=models.DateTimeField(help_text='\u9000\u51fa\u65f6\u95f4', null=True, verbose_name='quit_at', blank=True),
    18
    -        ),
    19
    -        migrations.AlterField(
    20
    -            model_name='groupuserinfo',
    21
    -            name='user_status',
    22
    -            field=models.IntegerField(default=0, verbose_name='user_status', choices=[(0, '\u7533\u8bf7\u4e2d'), (1, '\u5df2\u901a\u8fc7'), (2, '\u5df2\u62d2\u7edd'), (3, '\u5df2\u5220\u9664'), (4, '\u5df2\u9000\u51fa')]),
    23
    -        ),
    24
    -    ]

    + 0 - 19
    group/migrations/0017_groupphotoinfo_photo_from.py

    @@ -1,19 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -from __future__ import unicode_literals
    3
    -
    4
    -from django.db import models, migrations
    5
    -
    6
    -
    7
    -class Migration(migrations.Migration):
    8
    -
    9
    -    dependencies = [
    10
    -        ('group', '0016_auto_20160321_1535'),
    11
    -    ]
    12
    -
    13
    -    operations = [
    14
    -        migrations.AddField(
    15
    -            model_name='groupphotoinfo',
    16
    -            name='photo_from',
    17
    -            field=models.IntegerField(default=0, help_text='\u7167\u7247\u6765\u6e90', verbose_name='photo_from', choices=[(0, 'APP \u5efa\u7fa4'), (1, 'SESSION \u5efa\u7fa4')]),
    18
    -        ),
    19
    -    ]

    + 0 - 29
    group/migrations/0018_auto_20160417_2246.py

    @@ -1,29 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -from __future__ import unicode_literals
    3
    -
    4
    -from django.db import models, migrations
    5
    -
    6
    -
    7
    -class Migration(migrations.Migration):
    8
    -
    9
    -    dependencies = [
    10
    -        ('group', '0017_groupphotoinfo_photo_from'),
    11
    -    ]
    12
    -
    13
    -    operations = [
    14
    -        migrations.AddField(
    15
    -            model_name='groupphotoinfo',
    16
    -            name='photo_thumbnail2_h',
    17
    -            field=models.IntegerField(default=0, help_text='\u7167\u7247\u7f29\u7565\u56fe\u9ad8\u5ea6', verbose_name='photo_thumbnail2_h'),
    18
    -        ),
    19
    -        migrations.AddField(
    20
    -            model_name='groupphotoinfo',
    21
    -            name='photo_thumbnail2_path',
    22
    -            field=models.CharField(help_text='\u7167\u7247\u7f29\u7565\u56fe\u5b58\u653e\u8def\u5f84', max_length=255, null=True, verbose_name='photo_thumbnail2_path', blank=True),
    23
    -        ),
    24
    -        migrations.AddField(
    25
    -            model_name='groupphotoinfo',
    26
    -            name='photo_thumbnail2_w',
    27
    -            field=models.IntegerField(default=0, help_text='\u7167\u7247\u7f29\u7565\u56fe\u5bbd\u5ea6', verbose_name='photo_thumbnail2_w'),
    28
    -        ),
    29
    -    ]

    + 0 - 68
    group/migrations/0019_auto_20160422_1322.py

    @@ -1,68 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -from __future__ import unicode_literals
    3
    -
    4
    -from django.db import models, migrations
    5
    -
    6
    -
    7
    -class Migration(migrations.Migration):
    8
    -
    9
    -    dependencies = [
    10
    -        ('group', '0018_auto_20160417_2246'),
    11
    -    ]
    12
    -
    13
    -    operations = [
    14
    -        migrations.CreateModel(
    15
    -            name='GroupPhotoOrderInfo',
    16
    -            fields=[
    17
    -                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
    18
    -                ('status', models.BooleanField(default=True, help_text='\u72b6\u6001', db_index=True, verbose_name='status')),
    19
    -                ('created_at', models.DateTimeField(help_text='\u521b\u5efa\u65f6\u95f4', verbose_name='created_at', auto_now_add=True)),
    20
    -                ('updated_at', models.DateTimeField(help_text='\u66f4\u65b0\u65f6\u95f4', verbose_name='updated_at', auto_now=True)),
    21
    -                ('group_id', models.CharField(max_length=255, blank=True, help_text='\u7fa4\u7ec4\u552f\u4e00\u6807\u8bc6', null=True, verbose_name='group_id', db_index=True)),
    22
    -                ('user_id', models.CharField(max_length=255, blank=True, help_text='\u7528\u6237\u552f\u4e00\u6807\u8bc6', null=True, verbose_name='user_id', db_index=True)),
    23
    -                ('photo_id', models.CharField(max_length=255, blank=True, help_text='\u7167\u7247\u552f\u4e00\u6807\u8bc6', null=True, verbose_name='photo_id', db_index=True)),
    24
    -                ('m_photo_path', models.CharField(help_text='\u7167\u7247\u5b58\u653e\u8def\u5f84\uff0c\u63a7\u5236\u5668\u4e0a\u4f20\uff0c\u65e0\u6c34\u5370', max_length=255, null=True, verbose_name='m_photo_path', blank=True)),
    25
    -                ('l_photo_path', models.CharField(help_text='\u7167\u7247\u5b58\u653e\u8def\u5f84\uff0c\u7f8e\u5316\u5927\u56fe', max_length=255, null=True, verbose_name='l_photo_path', blank=True)),
    26
    -                ('r_photo_path', models.CharField(help_text='\u7167\u7247\u5b58\u653e\u8def\u5f84\uff0c\u9ad8\u6e05\u5927\u56fe', max_length=255, null=True, verbose_name='r_photo_path', blank=True)),
    27
    -            ],
    28
    -            options={
    29
    -                'verbose_name': 'groupphotoorderinfo',
    30
    -                'verbose_name_plural': 'groupphotoorderinfo',
    31
    -            },
    32
    -        ),
    33
    -        migrations.AddField(
    34
    -            model_name='groupphotoinfo',
    35
    -            name='lensman_id',
    36
    -            field=models.CharField(max_length=255, blank=True, help_text='\u6444\u5f71\u5e08\u552f\u4e00\u6807\u8bc6\uff0c\u540c PhotosInfo \u8868', null=True, verbose_name='lensman_id', db_index=True),
    37
    -        ),
    38
    -        migrations.AddField(
    39
    -            model_name='groupphotoinfo',
    40
    -            name='lensman_photo_id',
    41
    -            field=models.CharField(max_length=255, blank=True, help_text='\u6444\u5f71\u5e08\u7167\u7247\u552f\u4e00\u6807\u8bc6\uff0c\u540c PhotosInfo \u8868', null=True, verbose_name='lensman_photo_id', db_index=True),
    42
    -        ),
    43
    -        migrations.AlterField(
    44
    -            model_name='groupinfo',
    45
    -            name='admin_id',
    46
    -            field=models.CharField(max_length=255, blank=True, help_text='\u7528\u6237\u552f\u4e00\u6807\u8bc6', null=True, verbose_name='admin_id', db_index=True),
    47
    -        ),
    48
    -        migrations.AlterField(
    49
    -            model_name='groupphotoinfo',
    50
    -            name='user_id',
    51
    -            field=models.CharField(max_length=255, blank=True, help_text='\u7528\u6237\u552f\u4e00\u6807\u8bc6', null=True, verbose_name='user_id', db_index=True),
    52
    -        ),
    53
    -        migrations.AlterField(
    54
    -            model_name='groupuserinfo',
    55
    -            name='user_id',
    56
    -            field=models.CharField(max_length=255, blank=True, help_text='\u7528\u6237\u552f\u4e00\u6807\u8bc6', null=True, verbose_name='user_id', db_index=True),
    57
    -        ),
    58
    -        migrations.AlterField(
    59
    -            model_name='photocommentinfo',
    60
    -            name='user_id',
    61
    -            field=models.CharField(max_length=255, blank=True, help_text='\u7528\u6237\u552f\u4e00\u6807\u8bc6', null=True, verbose_name='user_id', db_index=True),
    62
    -        ),
    63
    -        migrations.AlterField(
    64
    -            model_name='photothumbupinfo',
    65
    -            name='user_id',
    66
    -            field=models.CharField(max_length=255, blank=True, help_text='\u7528\u6237\u552f\u4e00\u6807\u8bc6', null=True, verbose_name='user_id', db_index=True),
    67
    -        ),
    68
    -    ]

    + 0 - 19
    group/migrations/0020_groupphotoinfo_session_id.py

    @@ -1,19 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -from __future__ import unicode_literals
    3
    -
    4
    -from django.db import models, migrations
    5
    -
    6
    -
    7
    -class Migration(migrations.Migration):
    8
    -
    9
    -    dependencies = [
    10
    -        ('group', '0019_auto_20160422_1322'),
    11
    -    ]
    12
    -
    13
    -    operations = [
    14
    -        migrations.AddField(
    15
    -            model_name='groupphotoinfo',
    16
    -            name='session_id',
    17
    -            field=models.CharField(max_length=255, blank=True, help_text='\u7167\u7247\u7ec4\u552f\u4e00\u6807\u8bc6\uff0c\u540c PhotosInfo \u8868', null=True, verbose_name='session_id', db_index=True),
    18
    -        ),
    19
    -    ]

    + 0 - 19
    group/migrations/0021_photocommentinfo_to_uid.py

    @@ -1,19 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -from __future__ import unicode_literals
    3
    -
    4
    -from django.db import models, migrations
    5
    -
    6
    -
    7
    -class Migration(migrations.Migration):
    8
    -
    9
    -    dependencies = [
    10
    -        ('group', '0020_groupphotoinfo_session_id'),
    11
    -    ]
    12
    -
    13
    -    operations = [
    14
    -        migrations.AddField(
    15
    -            model_name='photocommentinfo',
    16
    -            name='to_uid',
    17
    -            field=models.CharField(max_length=255, blank=True, help_text='\u88ab\u8bc4\u8bba\u7528\u6237\u552f\u4e00\u6807\u8bc6', null=True, verbose_name='to_uid', db_index=True),
    18
    -        ),
    19
    -    ]

    + 0 - 29
    group/migrations/0022_auto_20160901_1439.py

    @@ -1,29 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -from __future__ import unicode_literals
    3
    -
    4
    -from django.db import models, migrations
    5
    -
    6
    -
    7
    -class Migration(migrations.Migration):
    8
    -
    9
    -    dependencies = [
    10
    -        ('group', '0021_photocommentinfo_to_uid'),
    11
    -    ]
    12
    -
    13
    -    operations = [
    14
    -        migrations.AddField(
    15
    -            model_name='groupphotoorderinfo',
    16
    -            name='lensman_photo_id',
    17
    -            field=models.CharField(max_length=255, blank=True, help_text='\u6444\u5f71\u5e08\u7167\u7247\u552f\u4e00\u6807\u8bc6\uff0c\u540c PhotosInfo \u8868', null=True, verbose_name='lensman_photo_id', db_index=True),
    18
    -        ),
    19
    -        migrations.AddField(
    20
    -            model_name='groupphotoorderinfo',
    21
    -            name='session_id',
    22
    -            field=models.CharField(max_length=255, blank=True, help_text='\u7167\u7247\u7ec4\u552f\u4e00\u6807\u8bc6\uff0c\u540c PhotosInfo \u8868', null=True, verbose_name='session_id', db_index=True),
    23
    -        ),
    24
    -        migrations.AlterField(
    25
    -            model_name='groupphotoorderinfo',
    26
    -            name='m_photo_path',
    27
    -            field=models.CharField(help_text='\u7167\u7247\u5b58\u653e\u8def\u5f84\uff0cBox\u4e0a\u4f20\uff0c\u65e0\u6c34\u5370', max_length=255, null=True, verbose_name='m_photo_path', blank=True),
    28
    -        ),
    29
    -    ]

    + 0 - 19
    group/migrations/0023_groupinfo_group_initio.py

    @@ -1,19 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -from __future__ import unicode_literals
    3
    -
    4
    -from django.db import models, migrations
    5
    -
    6
    -
    7
    -class Migration(migrations.Migration):
    8
    -
    9
    -    dependencies = [
    10
    -        ('group', '0022_auto_20160901_1439'),
    11
    -    ]
    12
    -
    13
    -    operations = [
    14
    -        migrations.AddField(
    15
    -            model_name='groupinfo',
    16
    -            name='group_initio',
    17
    -            field=models.BooleanField(default=False, help_text='\u7fa4\u7ec4\u67e5\u770b\u7167\u7247\u4ece\u5934\u5f00\u59cb', verbose_name='group_initio'),
    18
    -        ),
    19
    -    ]

    + 0 - 74
    group/migrations/0024_auto_20161214_1329.py

    @@ -1,74 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -from __future__ import unicode_literals
    3
    -
    4
    -from django.db import models, migrations
    5
    -
    6
    -
    7
    -class Migration(migrations.Migration):
    8
    -
    9
    -    dependencies = [
    10
    -        ('group', '0023_groupinfo_group_initio'),
    11
    -    ]
    12
    -
    13
    -    operations = [
    14
    -        migrations.AddField(
    15
    -            model_name='groupinfo',
    16
    -            name='ended_at',
    17
    -            field=models.DateTimeField(help_text='\u7ed3\u675f\u65f6\u95f4', null=True, verbose_name='ended_at', blank=True),
    18
    -        ),
    19
    -        migrations.AddField(
    20
    -            model_name='groupinfo',
    21
    -            name='gather_at',
    22
    -            field=models.DateTimeField(help_text='\u96c6\u5408\u65f6\u95f4', null=True, verbose_name='gather_at', blank=True),
    23
    -        ),
    24
    -        migrations.AddField(
    25
    -            model_name='groupinfo',
    26
    -            name='gather_lat',
    27
    -            field=models.FloatField(help_text='\u96c6\u5408\u7eac\u5ea6', null=True, verbose_name='gather_lat', blank=True),
    28
    -        ),
    29
    -        migrations.AddField(
    30
    -            model_name='groupinfo',
    31
    -            name='gather_lon',
    32
    -            field=models.FloatField(help_text='\u96c6\u5408\u7ecf\u5ea6', null=True, verbose_name='gather_lon', blank=True),
    33
    -        ),
    34
    -        migrations.AddField(
    35
    -            model_name='groupinfo',
    36
    -            name='group_closed',
    37
    -            field=models.BooleanField(default=False, help_text='\u7fa4\u7ec4\u5173\u95ed', verbose_name='group_closed'),
    38
    -        ),
    39
    -        migrations.AddField(
    40
    -            model_name='groupinfo',
    41
    -            name='started_at',
    42
    -            field=models.DateTimeField(help_text='\u5f00\u59cb\u65f6\u95f4', null=True, verbose_name='started_at', blank=True),
    43
    -        ),
    44
    -        migrations.AddField(
    45
    -            model_name='groupuserinfo',
    46
    -            name='name',
    47
    -            field=models.CharField(help_text='\u7528\u6237\u59d3\u540d', max_length=255, null=True, verbose_name='name', blank=True),
    48
    -        ),
    49
    -        migrations.AddField(
    50
    -            model_name='groupuserinfo',
    51
    -            name='phone',
    52
    -            field=models.CharField(help_text='\u7528\u6237\u7535\u8bdd', max_length=255, null=True, verbose_name='phone', blank=True),
    53
    -        ),
    54
    -        migrations.AddField(
    55
    -            model_name='groupuserinfo',
    56
    -            name='relative_person',
    57
    -            field=models.IntegerField(default=1, help_text='\u5173\u8054\u4eba\u6570', verbose_name='relative_person'),
    58
    -        ),
    59
    -        migrations.AddField(
    60
    -            model_name='groupuserinfo',
    61
    -            name='remark',
    62
    -            field=models.CharField(help_text='\u5907\u6ce8', max_length=255, null=True, verbose_name='remark', blank=True),
    63
    -        ),
    64
    -        migrations.AddField(
    65
    -            model_name='groupuserinfo',
    66
    -            name='subadmin',
    67
    -            field=models.BooleanField(default=False, help_text='\u526f\u7fa4\u7ec4\u7ba1\u7406\u5458', verbose_name='subadmin'),
    68
    -        ),
    69
    -        migrations.AlterField(
    70
    -            model_name='groupinfo',
    71
    -            name='group_from',
    72
    -            field=models.IntegerField(default=0, help_text='\u7fa4\u7ec4\u6765\u6e90', verbose_name='group_from', choices=[(0, 'APP \u5efa\u7fa4'), (1, 'SESSION \u5efa\u7fa4'), (10, '\u5bfc\u6e38\u5efa\u7fa4')]),
    73
    -        ),
    74
    -    ]

    + 0 - 54
    group/migrations/0025_auto_20161214_1659.py

    @@ -1,54 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -from __future__ import unicode_literals
    3
    -
    4
    -from django.db import models, migrations
    5
    -
    6
    -
    7
    -class Migration(migrations.Migration):
    8
    -
    9
    -    dependencies = [
    10
    -        ('group', '0024_auto_20161214_1329'),
    11
    -    ]
    12
    -
    13
    -    operations = [
    14
    -        migrations.AddField(
    15
    -            model_name='groupinfo',
    16
    -            name='name',
    17
    -            field=models.CharField(help_text='\u5bfc\u6e38\u59d3\u540d', max_length=255, null=True, verbose_name='name', blank=True),
    18
    -        ),
    19
    -        migrations.AddField(
    20
    -            model_name='groupinfo',
    21
    -            name='phone',
    22
    -            field=models.CharField(help_text='\u5bfc\u6e38\u7535\u8bdd', max_length=255, null=True, verbose_name='phone', blank=True),
    23
    -        ),
    24
    -        migrations.AlterField(
    25
    -            model_name='groupinfo',
    26
    -            name='ended_at',
    27
    -            field=models.DateTimeField(help_text='\u65c5\u6e38\u56e2\u7ed3\u675f\u65f6\u95f4', null=True, verbose_name='ended_at', blank=True),
    28
    -        ),
    29
    -        migrations.AlterField(
    30
    -            model_name='groupinfo',
    31
    -            name='gather_at',
    32
    -            field=models.DateTimeField(help_text='\u65c5\u6e38\u56e2\u96c6\u5408\u65f6\u95f4', null=True, verbose_name='gather_at', blank=True),
    33
    -        ),
    34
    -        migrations.AlterField(
    35
    -            model_name='groupinfo',
    36
    -            name='gather_lat',
    37
    -            field=models.FloatField(help_text='\u65c5\u6e38\u56e2\u96c6\u5408\u7eac\u5ea6', null=True, verbose_name='gather_lat', blank=True),
    38
    -        ),
    39
    -        migrations.AlterField(
    40
    -            model_name='groupinfo',
    41
    -            name='gather_lon',
    42
    -            field=models.FloatField(help_text='\u65c5\u6e38\u56e2\u96c6\u5408\u7ecf\u5ea6', null=True, verbose_name='gather_lon', blank=True),
    43
    -        ),
    44
    -        migrations.AlterField(
    45
    -            model_name='groupinfo',
    46
    -            name='group_closed',
    47
    -            field=models.BooleanField(default=False, help_text='\u65c5\u6e38\u56e2\u5173\u95ed', verbose_name='group_closed'),
    48
    -        ),
    49
    -        migrations.AlterField(
    50
    -            model_name='groupinfo',
    51
    -            name='started_at',
    52
    -            field=models.DateTimeField(help_text='\u65c5\u6e38\u56e2\u5f00\u59cb\u65f6\u95f4', null=True, verbose_name='started_at', blank=True),
    53
    -        ),
    54
    -    ]

    + 0 - 28
    group/migrations/0026_auto_20161216_1301.py

    @@ -1,28 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -from __future__ import unicode_literals
    3
    -
    4
    -from django.db import models, migrations
    5
    -
    6
    -
    7
    -class Migration(migrations.Migration):
    8
    -
    9
    -    dependencies = [
    10
    -        ('group', '0025_auto_20161214_1659'),
    11
    -    ]
    12
    -
    13
    -    operations = [
    14
    -        migrations.RemoveField(
    15
    -            model_name='groupuserinfo',
    16
    -            name='relative_person',
    17
    -        ),
    18
    -        migrations.AddField(
    19
    -            model_name='groupinfo',
    20
    -            name='total_persons',
    21
    -            field=models.IntegerField(default=1, help_text='\u65c5\u6e38\u56e2\u603b\u4eba\u6570', verbose_name='total_persons'),
    22
    -        ),
    23
    -        migrations.AddField(
    24
    -            model_name='groupuserinfo',
    25
    -            name='relative_persons',
    26
    -            field=models.IntegerField(default=1, help_text='\u5173\u8054\u4eba\u6570', verbose_name='relative_persons'),
    27
    -        ),
    28
    -    ]

    + 0 - 19
    group/migrations/0027_groupuserinfo_authority.py

    @@ -1,19 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -from __future__ import unicode_literals
    3
    -
    4
    -from django.db import models, migrations
    5
    -
    6
    -
    7
    -class Migration(migrations.Migration):
    8
    -
    9
    -    dependencies = [
    10
    -        ('group', '0026_auto_20161216_1301'),
    11
    -    ]
    12
    -
    13
    -    operations = [
    14
    -        migrations.AddField(
    15
    -            model_name='groupuserinfo',
    16
    -            name='authority',
    17
    -            field=models.BooleanField(default=True, help_text='\u662f\u5426\u6709\u5b9a\u4f4d\u6743\u9650', verbose_name='authority'),
    18
    -        ),
    19
    -    ]

    + 0 - 24
    group/migrations/0028_auto_20161220_1815.py

    @@ -1,24 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -from __future__ import unicode_literals
    3
    -
    4
    -from django.db import models, migrations
    5
    -
    6
    -
    7
    -class Migration(migrations.Migration):
    8
    -
    9
    -    dependencies = [
    10
    -        ('group', '0027_groupuserinfo_authority'),
    11
    -    ]
    12
    -
    13
    -    operations = [
    14
    -        migrations.AddField(
    15
    -            model_name='groupinfo',
    16
    -            name='attentions_path',
    17
    -            field=models.CharField(help_text='\u6ce8\u610f\u4e8b\u9879\u7167\u7247\u5b58\u653e\u8def\u5f84', max_length=255, null=True, verbose_name='attentions_path', blank=True),
    18
    -        ),
    19
    -        migrations.AddField(
    20
    -            model_name='groupinfo',
    21
    -            name='schedules_path',
    22
    -            field=models.CharField(help_text='\u884c\u7a0b\u5b89\u6392\u7167\u7247\u5b58\u653e\u8def\u5f84', max_length=255, null=True, verbose_name='schedules_path', blank=True),
    23
    -        ),
    24
    -    ]

    + 0 - 18
    group/migrations/0029_auto_20161224_1616.py

    @@ -1,18 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -from __future__ import unicode_literals
    3
    -
    4
    -from django.db import models, migrations
    5
    -
    6
    -
    7
    -class Migration(migrations.Migration):
    8
    -
    9
    -    dependencies = [
    10
    -        ('group', '0028_auto_20161220_1815'),
    11
    -    ]
    12
    -
    13
    -    operations = [
    14
    -        migrations.AlterUniqueTogether(
    15
    -            name='groupuserinfo',
    16
    -            unique_together=set([('group_id', 'user_id')]),
    17
    -        ),
    18
    -    ]

    + 0 - 19
    group/migrations/0030_groupinfo_gather_location.py

    @@ -1,19 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -from __future__ import unicode_literals
    3
    -
    4
    -from django.db import models, migrations
    5
    -
    6
    -
    7
    -class Migration(migrations.Migration):
    8
    -
    9
    -    dependencies = [
    10
    -        ('group', '0029_auto_20161224_1616'),
    11
    -    ]
    12
    -
    13
    -    operations = [
    14
    -        migrations.AddField(
    15
    -            model_name='groupinfo',
    16
    -            name='gather_location',
    17
    -            field=models.CharField(help_text='\u65c5\u6e38\u56e2\u96c6\u5408\u5730\u70b9', max_length=255, null=True, verbose_name='gather_location', blank=True),
    18
    -        ),
    19
    -    ]

    + 0 - 19
    group/migrations/0031_groupphotoinfo_photo_md5.py

    @@ -1,19 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -from __future__ import unicode_literals
    3
    -
    4
    -from django.db import models, migrations
    5
    -
    6
    -
    7
    -class Migration(migrations.Migration):
    8
    -
    9
    -    dependencies = [
    10
    -        ('group', '0030_groupinfo_gather_location'),
    11
    -    ]
    12
    -
    13
    -    operations = [
    14
    -        migrations.AddField(
    15
    -            model_name='groupphotoinfo',
    16
    -            name='photo_md5',
    17
    -            field=models.CharField(max_length=255, blank=True, help_text='\u7167\u7247 MD5', null=True, verbose_name='photo_md5', db_index=True),
    18
    -        ),
    19
    -    ]

    + 0 - 19
    group/migrations/0032_groupinfo_gather_screenshot.py

    @@ -1,19 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -from __future__ import unicode_literals
    3
    -
    4
    -from django.db import models, migrations
    5
    -
    6
    -
    7
    -class Migration(migrations.Migration):
    8
    -
    9
    -    dependencies = [
    10
    -        ('group', '0031_groupphotoinfo_photo_md5'),
    11
    -    ]
    12
    -
    13
    -    operations = [
    14
    -        migrations.AddField(
    15
    -            model_name='groupinfo',
    16
    -            name='gather_screenshot',
    17
    -            field=models.CharField(help_text='\u65c5\u6e38\u56e2\u96c6\u5408\u5730\u70b9\u622a\u56fe', max_length=255, null=True, verbose_name='gather_screenshot', blank=True),
    18
    -        ),
    19
    -    ]

    + 0 - 20
    group/migrations/0033_groupphotoinfo_photo_id.py

    @@ -1,20 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -from __future__ import unicode_literals
    3
    -
    4
    -from django.db import models, migrations
    5
    -import shortuuidfield.fields
    6
    -
    7
    -
    8
    -class Migration(migrations.Migration):
    9
    -
    10
    -    dependencies = [
    11
    -        ('group', '0032_groupinfo_gather_screenshot'),
    12
    -    ]
    13
    -
    14
    -    operations = [
    15
    -        migrations.AddField(
    16
    -            model_name='groupphotoinfo',
    17
    -            name='photo_id',
    18
    -            field=shortuuidfield.fields.ShortUUIDField(help_text='\u7167\u7247\u552f\u4e00\u6807\u8bc6', max_length=22, editable=False, db_index=True, blank=True),
    19
    -        ),
    20
    -    ]

    + 0 - 24
    group/migrations/0034_auto_20170411_1156.py

    @@ -1,24 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -from __future__ import unicode_literals
    3
    -
    4
    -from django.db import models, migrations
    5
    -
    6
    -
    7
    -class Migration(migrations.Migration):
    8
    -
    9
    -    dependencies = [
    10
    -        ('group', '0033_groupphotoinfo_photo_id'),
    11
    -    ]
    12
    -
    13
    -    operations = [
    14
    -        migrations.AddField(
    15
    -            model_name='groupphotoinfo',
    16
    -            name='nomark',
    17
    -            field=models.IntegerField(default=299, help_text='\u6444\u5f71\u5e08\u7167\u7247\u65e0\u6c34\u5370\u4ef7\u683c(\u5206)', verbose_name='nomark'),
    18
    -        ),
    19
    -        migrations.AddField(
    20
    -            model_name='groupphotoinfo',
    21
    -            name='origin',
    22
    -            field=models.IntegerField(default=999, help_text='\u6444\u5f71\u5e08\u7167\u7247\u9ad8\u6e05\u56fe\u4ef7\u683c(\u5206)', verbose_name='origin'),
    23
    -        ),
    24
    -    ]

    + 0 - 19
    group/migrations/0035_groupuserinfo_admin_status.py

    @@ -1,19 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -from __future__ import unicode_literals
    3
    -
    4
    -from django.db import models, migrations
    5
    -
    6
    -
    7
    -class Migration(migrations.Migration):
    8
    -
    9
    -    dependencies = [
    10
    -        ('group', '0034_auto_20170411_1156'),
    11
    -    ]
    12
    -
    13
    -    operations = [
    14
    -        migrations.AddField(
    15
    -            model_name='groupuserinfo',
    16
    -            name='admin_status',
    17
    -            field=models.BooleanField(default=True, help_text='\u7fa4\u7ec4\u7ba1\u7406\u5458\u72b6\u6001', verbose_name='admin_status'),
    18
    -        ),
    19
    -    ]

    + 0 - 20
    group/migrations/0036_groupphotoinfo_has_watermark.py

    @@ -1,20 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -# Generated by Django 1.11.3 on 2017-08-21 03:13
    3
    -from __future__ import unicode_literals
    4
    -
    5
    -from django.db import migrations, models
    6
    -
    7
    -
    8
    -class Migration(migrations.Migration):
    9
    -
    10
    -    dependencies = [
    11
    -        ('group', '0035_groupuserinfo_admin_status'),
    12
    -    ]
    13
    -
    14
    -    operations = [
    15
    -        migrations.AddField(
    16
    -            model_name='groupphotoinfo',
    17
    -            name='has_watermark',
    18
    -            field=models.BooleanField(db_index=True, default=False, help_text='\u662f\u5426\u6709\u6c34\u5370', verbose_name='has_watermark'),
    19
    -        ),
    20
    -    ]

    + 0 - 19
    group/migrations/0037_auto_20170821_1600.py

    @@ -1,19 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -# Generated by Django 1.11.3 on 2017-08-21 08:00
    3
    -from __future__ import unicode_literals
    4
    -
    5
    -from django.db import migrations
    6
    -
    7
    -
    8
    -class Migration(migrations.Migration):
    9
    -
    10
    -    dependencies = [
    11
    -        ('group', '0036_groupphotoinfo_has_watermark'),
    12
    -    ]
    13
    -
    14
    -    operations = [
    15
    -        migrations.AlterUniqueTogether(
    16
    -            name='groupinfo',
    17
    -            unique_together=set([('session_id', 'group_from')]),
    18
    -        ),
    19
    -    ]

    + 0 - 19
    group/migrations/0038_auto_20170821_1608.py

    @@ -1,19 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -# Generated by Django 1.11.3 on 2017-08-21 08:08
    3
    -from __future__ import unicode_literals
    4
    -
    5
    -from django.db import migrations
    6
    -
    7
    -
    8
    -class Migration(migrations.Migration):
    9
    -
    10
    -    dependencies = [
    11
    -        ('group', '0037_auto_20170821_1600'),
    12
    -    ]
    13
    -
    14
    -    operations = [
    15
    -        migrations.AlterUniqueTogether(
    16
    -            name='groupphotoinfo',
    17
    -            unique_together=set([('group_id', 'user_id', 'photo_md5')]),
    18
    -        ),
    19
    -    ]

    + 0 - 19
    group/migrations/0039_auto_20170821_1613.py

    @@ -1,19 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -# Generated by Django 1.11.3 on 2017-08-21 08:13
    3
    -from __future__ import unicode_literals
    4
    -
    5
    -from django.db import migrations
    6
    -
    7
    -
    8
    -class Migration(migrations.Migration):
    9
    -
    10
    -    dependencies = [
    11
    -        ('group', '0038_auto_20170821_1608'),
    12
    -    ]
    13
    -
    14
    -    operations = [
    15
    -        migrations.AlterUniqueTogether(
    16
    -            name='photothumbupinfo',
    17
    -            unique_together=set([('photo_id', 'user_id')]),
    18
    -        ),
    19
    -    ]

    + 0 - 40
    group/migrations/0040_auto_20170825_1342.py

    @@ -1,40 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -# Generated by Django 1.11.3 on 2017-08-25 05:42
    3
    -from __future__ import unicode_literals
    4
    -
    5
    -from django.db import migrations, models
    6
    -
    7
    -
    8
    -class Migration(migrations.Migration):
    9
    -
    10
    -    dependencies = [
    11
    -        ('group', '0039_auto_20170821_1613'),
    12
    -    ]
    13
    -
    14
    -    operations = [
    15
    -        migrations.AlterField(
    16
    -            model_name='groupphotoorderinfo',
    17
    -            name='group_id',
    18
    -            field=models.CharField(blank=True, db_index=True, help_text='\u7fa4\u7ec4\u552f\u4e00\u6807\u8bc6', max_length=32, null=True, verbose_name='group_id'),
    19
    -        ),
    20
    -        migrations.AlterField(
    21
    -            model_name='groupphotoorderinfo',
    22
    -            name='lensman_photo_id',
    23
    -            field=models.CharField(blank=True, db_index=True, help_text='\u6444\u5f71\u5e08\u7167\u7247\u552f\u4e00\u6807\u8bc6\uff0c\u540c PhotosInfo \u8868', max_length=127, null=True, verbose_name='lensman_photo_id'),
    24
    -        ),
    25
    -        migrations.AlterField(
    26
    -            model_name='groupphotoorderinfo',
    27
    -            name='photo_id',
    28
    -            field=models.CharField(blank=True, db_index=True, help_text='\u7167\u7247\u552f\u4e00\u6807\u8bc6', max_length=32, null=True, verbose_name='photo_id'),
    29
    -        ),
    30
    -        migrations.AlterField(
    31
    -            model_name='groupphotoorderinfo',
    32
    -            name='session_id',
    33
    -            field=models.CharField(blank=True, db_index=True, help_text='\u7167\u7247\u7ec4\u552f\u4e00\u6807\u8bc6\uff0c\u540c PhotosInfo \u8868', max_length=32, null=True, verbose_name='session_id'),
    34
    -        ),
    35
    -        migrations.AlterField(
    36
    -            model_name='groupphotoorderinfo',
    37
    -            name='user_id',
    38
    -            field=models.CharField(blank=True, db_index=True, help_text='\u7528\u6237\u552f\u4e00\u6807\u8bc6', max_length=32, null=True, verbose_name='user_id'),
    39
    -        ),
    40
    -    ]

    + 0 - 19
    group/migrations/0041_auto_20170825_1342.py

    @@ -1,19 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -# Generated by Django 1.11.3 on 2017-08-25 05:42
    3
    -from __future__ import unicode_literals
    4
    -
    5
    -from django.db import migrations
    6
    -
    7
    -
    8
    -class Migration(migrations.Migration):
    9
    -
    10
    -    dependencies = [
    11
    -        ('group', '0040_auto_20170825_1342'),
    12
    -    ]
    13
    -
    14
    -    operations = [
    15
    -        migrations.AlterUniqueTogether(
    16
    -            name='groupphotoorderinfo',
    17
    -            unique_together=set([('group_id', 'session_id', 'user_id', 'photo_id', 'lensman_photo_id')]),
    18
    -        ),
    19
    -    ]

    + 0 - 20
    group/migrations/0042_groupphotoinfo_lensman_type.py

    @@ -1,20 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -# Generated by Django 1.11.3 on 2017-09-17 10:06
    3
    -from __future__ import unicode_literals
    4
    -
    5
    -from django.db import migrations, models
    6
    -
    7
    -
    8
    -class Migration(migrations.Migration):
    9
    -
    10
    -    dependencies = [
    11
    -        ('group', '0041_auto_20170825_1342'),
    12
    -    ]
    13
    -
    14
    -    operations = [
    15
    -        migrations.AddField(
    16
    -            model_name='groupphotoinfo',
    17
    -            name='lensman_type',
    18
    -            field=models.IntegerField(choices=[(0, '\u666e\u901a\u6444\u5f71\u5e08'), (10, '\u82b1\u7d6e\u6444\u5f71\u5e08')], db_index=True, default=-1, help_text='\u6444\u5f71\u5e08\u7c7b\u522b', verbose_name='lensman_type'),
    19
    -        ),
    20
    -    ]

    + 0 - 105
    group/migrations/0043_auto_20180101_2220.py

    @@ -1,105 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -# Generated by Django 1.11.3 on 2018-01-01 14:20
    3
    -from __future__ import unicode_literals
    4
    -
    5
    -from django.db import migrations, models
    6
    -
    7
    -
    8
    -class Migration(migrations.Migration):
    9
    -
    10
    -    dependencies = [
    11
    -        ('group', '0042_groupphotoinfo_lensman_type'),
    12
    -    ]
    13
    -
    14
    -    operations = [
    15
    -        migrations.AlterField(
    16
    -            model_name='groupinfo',
    17
    -            name='created_at',
    18
    -            field=models.DateTimeField(auto_now_add=True, help_text='Create Time', verbose_name='created_at'),
    19
    -        ),
    20
    -        migrations.AlterField(
    21
    -            model_name='groupinfo',
    22
    -            name='status',
    23
    -            field=models.BooleanField(db_index=True, default=True, help_text='Status', verbose_name='status'),
    24
    -        ),
    25
    -        migrations.AlterField(
    26
    -            model_name='groupinfo',
    27
    -            name='updated_at',
    28
    -            field=models.DateTimeField(auto_now=True, help_text='Update Time', verbose_name='updated_at'),
    29
    -        ),
    30
    -        migrations.AlterField(
    31
    -            model_name='groupphotoinfo',
    32
    -            name='created_at',
    33
    -            field=models.DateTimeField(auto_now_add=True, help_text='Create Time', verbose_name='created_at'),
    34
    -        ),
    35
    -        migrations.AlterField(
    36
    -            model_name='groupphotoinfo',
    37
    -            name='status',
    38
    -            field=models.BooleanField(db_index=True, default=True, help_text='Status', verbose_name='status'),
    39
    -        ),
    40
    -        migrations.AlterField(
    41
    -            model_name='groupphotoinfo',
    42
    -            name='updated_at',
    43
    -            field=models.DateTimeField(auto_now=True, help_text='Update Time', verbose_name='updated_at'),
    44
    -        ),
    45
    -        migrations.AlterField(
    46
    -            model_name='groupphotoorderinfo',
    47
    -            name='created_at',
    48
    -            field=models.DateTimeField(auto_now_add=True, help_text='Create Time', verbose_name='created_at'),
    49
    -        ),
    50
    -        migrations.AlterField(
    51
    -            model_name='groupphotoorderinfo',
    52
    -            name='status',
    53
    -            field=models.BooleanField(db_index=True, default=True, help_text='Status', verbose_name='status'),
    54
    -        ),
    55
    -        migrations.AlterField(
    56
    -            model_name='groupphotoorderinfo',
    57
    -            name='updated_at',
    58
    -            field=models.DateTimeField(auto_now=True, help_text='Update Time', verbose_name='updated_at'),
    59
    -        ),
    60
    -        migrations.AlterField(
    61
    -            model_name='groupuserinfo',
    62
    -            name='created_at',
    63
    -            field=models.DateTimeField(auto_now_add=True, help_text='Create Time', verbose_name='created_at'),
    64
    -        ),
    65
    -        migrations.AlterField(
    66
    -            model_name='groupuserinfo',
    67
    -            name='status',
    68
    -            field=models.BooleanField(db_index=True, default=True, help_text='Status', verbose_name='status'),
    69
    -        ),
    70
    -        migrations.AlterField(
    71
    -            model_name='groupuserinfo',
    72
    -            name='updated_at',
    73
    -            field=models.DateTimeField(auto_now=True, help_text='Update Time', verbose_name='updated_at'),
    74
    -        ),
    75
    -        migrations.AlterField(
    76
    -            model_name='photocommentinfo',
    77
    -            name='created_at',
    78
    -            field=models.DateTimeField(auto_now_add=True, help_text='Create Time', verbose_name='created_at'),
    79
    -        ),
    80
    -        migrations.AlterField(
    81
    -            model_name='photocommentinfo',
    82
    -            name='status',
    83
    -            field=models.BooleanField(db_index=True, default=True, help_text='Status', verbose_name='status'),
    84
    -        ),
    85
    -        migrations.AlterField(
    86
    -            model_name='photocommentinfo',
    87
    -            name='updated_at',
    88
    -            field=models.DateTimeField(auto_now=True, help_text='Update Time', verbose_name='updated_at'),
    89
    -        ),
    90
    -        migrations.AlterField(
    91
    -            model_name='photothumbupinfo',
    92
    -            name='created_at',
    93
    -            field=models.DateTimeField(auto_now_add=True, help_text='Create Time', verbose_name='created_at'),
    94
    -        ),
    95
    -        migrations.AlterField(
    96
    -            model_name='photothumbupinfo',
    97
    -            name='status',
    98
    -            field=models.BooleanField(db_index=True, default=True, help_text='Status', verbose_name='status'),
    99
    -        ),
    100
    -        migrations.AlterField(
    101
    -            model_name='photothumbupinfo',
    102
    -            name='updated_at',
    103
    -            field=models.DateTimeField(auto_now=True, help_text='Update Time', verbose_name='updated_at'),
    104
    -        ),
    105
    -    ]

    + 0 - 155
    group/migrations/0044_auto_20180103_0446.py

    @@ -1,155 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -# Generated by Django 1.11.3 on 2018-01-02 20:46
    3
    -from __future__ import unicode_literals
    4
    -
    5
    -from django.db import migrations, models
    6
    -
    7
    -
    8
    -class Migration(migrations.Migration):
    9
    -
    10
    -    dependencies = [
    11
    -        ('group', '0043_auto_20180101_2220'),
    12
    -    ]
    13
    -
    14
    -    operations = [
    15
    -        migrations.AlterField(
    16
    -            model_name='groupinfo',
    17
    -            name='admin_id',
    18
    -            field=models.CharField(blank=True, db_index=True, help_text='\u7528\u6237\u552f\u4e00\u6807\u8bc6', max_length=32, null=True, verbose_name='admin_id'),
    19
    -        ),
    20
    -        migrations.AlterField(
    21
    -            model_name='groupinfo',
    22
    -            name='attentions_path',
    23
    -            field=models.CharField(blank=True, help_text='\u6ce8\u610f\u4e8b\u9879\u7167\u7247\u5b58\u653e\u8def\u5f84', max_length=32, null=True, verbose_name='attentions_path'),
    24
    -        ),
    25
    -        migrations.AlterField(
    26
    -            model_name='groupinfo',
    27
    -            name='gather_screenshot',
    28
    -            field=models.CharField(blank=True, help_text='\u65c5\u6e38\u56e2\u96c6\u5408\u5730\u70b9\u622a\u56fe', max_length=32, null=True, verbose_name='gather_screenshot'),
    29
    -        ),
    30
    -        migrations.AlterField(
    31
    -            model_name='groupinfo',
    32
    -            name='group_id',
    33
    -            field=models.CharField(blank=True, db_index=True, help_text='\u7fa4\u7ec4\u552f\u4e00\u6807\u8bc6', max_length=32, null=True, unique=True, verbose_name='group_id'),
    34
    -        ),
    35
    -        migrations.AlterField(
    36
    -            model_name='groupinfo',
    37
    -            name='phone',
    38
    -            field=models.CharField(blank=True, help_text='\u5bfc\u6e38\u7535\u8bdd', max_length=16, null=True, verbose_name='phone'),
    39
    -        ),
    40
    -        migrations.AlterField(
    41
    -            model_name='groupinfo',
    42
    -            name='schedules_path',
    43
    -            field=models.CharField(blank=True, help_text='\u884c\u7a0b\u5b89\u6392\u7167\u7247\u5b58\u653e\u8def\u5f84', max_length=32, null=True, verbose_name='schedules_path'),
    44
    -        ),
    45
    -        migrations.AlterField(
    46
    -            model_name='groupinfo',
    47
    -            name='session_id',
    48
    -            field=models.CharField(blank=True, db_index=True, help_text='\u7167\u7247\u7ec4\u552f\u4e00\u6807\u8bc6', max_length=32, null=True, verbose_name='session_id'),
    49
    -        ),
    50
    -        migrations.AlterField(
    51
    -            model_name='groupphotoinfo',
    52
    -            name='group_id',
    53
    -            field=models.CharField(blank=True, db_index=True, help_text='\u7fa4\u7ec4\u552f\u4e00\u6807\u8bc6', max_length=32, null=True, verbose_name='group_id'),
    54
    -        ),
    55
    -        migrations.AlterField(
    56
    -            model_name='groupphotoinfo',
    57
    -            name='lensman_id',
    58
    -            field=models.CharField(blank=True, db_index=True, help_text='\u6444\u5f71\u5e08\u552f\u4e00\u6807\u8bc6\uff0c\u540c PhotosInfo \u8868', max_length=32, null=True, verbose_name='lensman_id'),
    59
    -        ),
    60
    -        migrations.AlterField(
    61
    -            model_name='groupphotoinfo',
    62
    -            name='lensman_photo_id',
    63
    -            field=models.CharField(blank=True, db_index=True, help_text='\u6444\u5f71\u5e08\u7167\u7247\u552f\u4e00\u6807\u8bc6\uff0c\u540c PhotosInfo \u8868', max_length=32, null=True, verbose_name='lensman_photo_id'),
    64
    -        ),
    65
    -        migrations.AlterField(
    66
    -            model_name='groupphotoinfo',
    67
    -            name='photo_md5',
    68
    -            field=models.CharField(blank=True, db_index=True, help_text='\u7167\u7247 MD5', max_length=32, null=True, verbose_name='photo_md5'),
    69
    -        ),
    70
    -        migrations.AlterField(
    71
    -            model_name='groupphotoinfo',
    72
    -            name='photo_path',
    73
    -            field=models.CharField(blank=True, help_text='\u7167\u7247\u5b58\u653e\u8def\u5f84', max_length=32, null=True, verbose_name='photo_path'),
    74
    -        ),
    75
    -        migrations.AlterField(
    76
    -            model_name='groupphotoinfo',
    77
    -            name='photo_thumbnail2_path',
    78
    -            field=models.CharField(blank=True, help_text='\u7167\u7247\u7f29\u7565\u56fe\u5b58\u653e\u8def\u5f84', max_length=32, null=True, verbose_name='photo_thumbnail2_path'),
    79
    -        ),
    80
    -        migrations.AlterField(
    81
    -            model_name='groupphotoinfo',
    82
    -            name='photo_thumbnail_path',
    83
    -            field=models.CharField(blank=True, help_text='\u7167\u7247\u7f29\u7565\u56fe\u5b58\u653e\u8def\u5f84', max_length=32, null=True, verbose_name='photo_thumbnail_path'),
    84
    -        ),
    85
    -        migrations.AlterField(
    86
    -            model_name='groupphotoinfo',
    87
    -            name='session_id',
    88
    -            field=models.CharField(blank=True, db_index=True, help_text='\u7167\u7247\u7ec4\u552f\u4e00\u6807\u8bc6\uff0c\u540c PhotosInfo \u8868', max_length=32, null=True, verbose_name='session_id'),
    89
    -        ),
    90
    -        migrations.AlterField(
    91
    -            model_name='groupphotoinfo',
    92
    -            name='user_id',
    93
    -            field=models.CharField(blank=True, db_index=True, help_text='\u7528\u6237\u552f\u4e00\u6807\u8bc6', max_length=32, null=True, verbose_name='user_id'),
    94
    -        ),
    95
    -        migrations.AlterField(
    96
    -            model_name='groupphotoorderinfo',
    97
    -            name='l_photo_path',
    98
    -            field=models.CharField(blank=True, help_text='\u7167\u7247\u5b58\u653e\u8def\u5f84\uff0c\u7f8e\u5316\u5927\u56fe', max_length=32, null=True, verbose_name='l_photo_path'),
    99
    -        ),
    100
    -        migrations.AlterField(
    101
    -            model_name='groupphotoorderinfo',
    102
    -            name='lensman_photo_id',
    103
    -            field=models.CharField(blank=True, db_index=True, help_text='\u6444\u5f71\u5e08\u7167\u7247\u552f\u4e00\u6807\u8bc6\uff0c\u540c PhotosInfo \u8868', max_length=32, null=True, verbose_name='lensman_photo_id'),
    104
    -        ),
    105
    -        migrations.AlterField(
    106
    -            model_name='groupphotoorderinfo',
    107
    -            name='m_photo_path',
    108
    -            field=models.CharField(blank=True, help_text='\u7167\u7247\u5b58\u653e\u8def\u5f84\uff0cBox\u4e0a\u4f20\uff0c\u65e0\u6c34\u5370', max_length=32, null=True, verbose_name='m_photo_path'),
    109
    -        ),
    110
    -        migrations.AlterField(
    111
    -            model_name='groupphotoorderinfo',
    112
    -            name='r_photo_path',
    113
    -            field=models.CharField(blank=True, help_text='\u7167\u7247\u5b58\u653e\u8def\u5f84\uff0c\u9ad8\u6e05\u5927\u56fe', max_length=32, null=True, verbose_name='r_photo_path'),
    114
    -        ),
    115
    -        migrations.AlterField(
    116
    -            model_name='groupuserinfo',
    117
    -            name='group_id',
    118
    -            field=models.CharField(blank=True, db_index=True, help_text='\u7fa4\u7ec4\u552f\u4e00\u6807\u8bc6', max_length=32, null=True, verbose_name='group_id'),
    119
    -        ),
    120
    -        migrations.AlterField(
    121
    -            model_name='groupuserinfo',
    122
    -            name='phone',
    123
    -            field=models.CharField(blank=True, help_text='\u7528\u6237\u7535\u8bdd', max_length=16, null=True, verbose_name='phone'),
    124
    -        ),
    125
    -        migrations.AlterField(
    126
    -            model_name='groupuserinfo',
    127
    -            name='user_id',
    128
    -            field=models.CharField(blank=True, db_index=True, help_text='\u7528\u6237\u552f\u4e00\u6807\u8bc6', max_length=32, null=True, verbose_name='user_id'),
    129
    -        ),
    130
    -        migrations.AlterField(
    131
    -            model_name='photocommentinfo',
    132
    -            name='photo_id',
    133
    -            field=models.CharField(blank=True, db_index=True, help_text='\u98de\u56fe\u552f\u4e00\u6807\u8bc6', max_length=32, null=True, verbose_name='photo_id'),
    134
    -        ),
    135
    -        migrations.AlterField(
    136
    -            model_name='photocommentinfo',
    137
    -            name='to_uid',
    138
    -            field=models.CharField(blank=True, db_index=True, help_text='\u88ab\u8bc4\u8bba\u7528\u6237\u552f\u4e00\u6807\u8bc6', max_length=32, null=True, verbose_name='to_uid'),
    139
    -        ),
    140
    -        migrations.AlterField(
    141
    -            model_name='photocommentinfo',
    142
    -            name='user_id',
    143
    -            field=models.CharField(blank=True, db_index=True, help_text='\u7528\u6237\u552f\u4e00\u6807\u8bc6', max_length=32, null=True, verbose_name='user_id'),
    144
    -        ),
    145
    -        migrations.AlterField(
    146
    -            model_name='photothumbupinfo',
    147
    -            name='photo_id',
    148
    -            field=models.CharField(blank=True, db_index=True, help_text='\u98de\u56fe\u552f\u4e00\u6807\u8bc6', max_length=32, null=True, verbose_name='photo_id'),
    149
    -        ),
    150
    -        migrations.AlterField(
    151
    -            model_name='photothumbupinfo',
    152
    -            name='user_id',
    153
    -            field=models.CharField(blank=True, db_index=True, help_text='\u7528\u6237\u552f\u4e00\u6807\u8bc6', max_length=32, null=True, verbose_name='user_id'),
    154
    -        ),
    155
    -    ]

    + 0 - 25
    group/migrations/0045_auto_20180930_1159.py

    @@ -1,25 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -# Generated by Django 1.11.15 on 2018-09-30 03:59
    3
    -from __future__ import unicode_literals
    4
    -
    5
    -from django.db import migrations, models
    6
    -
    7
    -
    8
    -class Migration(migrations.Migration):
    9
    -
    10
    -    dependencies = [
    11
    -        ('group', '0044_auto_20180103_0446'),
    12
    -    ]
    13
    -
    14
    -    operations = [
    15
    -        migrations.AlterField(
    16
    -            model_name='groupinfo',
    17
    -            name='phone',
    18
    -            field=models.CharField(blank=True, help_text='\u5bfc\u6e38\u7535\u8bdd', max_length=11, null=True, verbose_name='phone'),
    19
    -        ),
    20
    -        migrations.AlterField(
    21
    -            model_name='groupuserinfo',
    22
    -            name='phone',
    23
    -            field=models.CharField(blank=True, help_text='\u7528\u6237\u7535\u8bdd', max_length=11, null=True, verbose_name='phone'),
    24
    -        ),
    25
    -    ]

    + 0 - 43
    group/migrations/0046_auto_20201130_0131.py

    @@ -1,43 +0,0 @@
    1
    -# Generated by Django 2.2.15 on 2020-11-29 17:31
    2
    -
    3
    -from django.db import migrations, models
    4
    -
    5
    -
    6
    -class Migration(migrations.Migration):
    7
    -
    8
    -    dependencies = [
    9
    -        ('group', '0045_auto_20180930_1159'),
    10
    -    ]
    11
    -
    12
    -    operations = [
    13
    -        migrations.AlterField(
    14
    -            model_name='groupinfo',
    15
    -            name='status',
    16
    -            field=models.BooleanField(default=True, help_text='Status', verbose_name='status'),
    17
    -        ),
    18
    -        migrations.AlterField(
    19
    -            model_name='groupphotoinfo',
    20
    -            name='status',
    21
    -            field=models.BooleanField(default=True, help_text='Status', verbose_name='status'),
    22
    -        ),
    23
    -        migrations.AlterField(
    24
    -            model_name='groupphotoorderinfo',
    25
    -            name='status',
    26
    -            field=models.BooleanField(default=True, help_text='Status', verbose_name='status'),
    27
    -        ),
    28
    -        migrations.AlterField(
    29
    -            model_name='groupuserinfo',
    30
    -            name='status',
    31
    -            field=models.BooleanField(default=True, help_text='Status', verbose_name='status'),
    32
    -        ),
    33
    -        migrations.AlterField(
    34
    -            model_name='photocommentinfo',
    35
    -            name='status',
    36
    -            field=models.BooleanField(default=True, help_text='Status', verbose_name='status'),
    37
    -        ),
    38
    -        migrations.AlterField(
    39
    -            model_name='photothumbupinfo',
    40
    -            name='status',
    41
    -            field=models.BooleanField(default=True, help_text='Status', verbose_name='status'),
    42
    -        ),
    43
    -    ]

    + 0 - 25
    group/migrations/0047_auto_20201202_1203.py

    @@ -1,25 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -# Generated by Django 1.11.29 on 2020-12-02 04:03
    3
    -from __future__ import unicode_literals
    4
    -
    5
    -from django.db import migrations, models
    6
    -
    7
    -
    8
    -class Migration(migrations.Migration):
    9
    -
    10
    -    dependencies = [
    11
    -        ('group', '0046_auto_20201130_0131'),
    12
    -    ]
    13
    -
    14
    -    operations = [
    15
    -        migrations.AlterField(
    16
    -            model_name='groupphotoinfo',
    17
    -            name='has_watermark',
    18
    -            field=models.BooleanField(default=False, help_text='\u662f\u5426\u6709\u6c34\u5370', verbose_name='has_watermark'),
    19
    -        ),
    20
    -        migrations.AlterField(
    21
    -            model_name='photothumbupinfo',
    22
    -            name='thumbup',
    23
    -            field=models.BooleanField(default=True, help_text='\u7528\u6237\u70b9\u8d5e', verbose_name='thumbup'),
    24
    -        ),
    25
    -    ]

    + 0 - 0
    group/migrations/__init__.py


    + 0 - 433
    group/models.py

    @@ -1,433 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -
    3
    -from django.db import models
    4
    -from django.utils.translation import ugettext_lazy as _
    5
    -from django_models_ext import BaseModelMixin
    6
    -from shortuuidfield import ShortUUIDField
    7
    -from TimeConvert import TimeConvert as tc
    8
    -
    9
    -from kodo.basemodels import LensmanTypeMixin
    10
    -from utils.qiniucdn import qiniu_file_url
    11
    -from utils.redis.rgroup import get_group_photo_thumbup_flag
    12
    -from utils.redis.rorder import get_lensman_order_record
    13
    -from utils.time_utils import origin_expired_stamps
    14
    -from utils.url_utils import share_url
    15
    -
    16
    -
    17
    -class GroupInfo(BaseModelMixin):
    18
    -    APP_GROUP = 0
    19
    -    SESSION_GROUP = 1
    20
    -    TOURGUIDE_GROUP = 10
    21
    -
    22
    -    GROUP_FROM = (
    23
    -        (APP_GROUP, u'APP 建群'),
    24
    -        (SESSION_GROUP, u'SESSION 建群'),
    25
    -        (TOURGUIDE_GROUP, u'导游建群'),
    26
    -    )
    27
    -
    28
    -    group_id = models.CharField(_(u'group_id'), max_length=32, blank=True, null=True, help_text=u'群组唯一标识', db_index=True, unique=True)
    29
    -    admin_id = models.CharField(_(u'admin_id'), max_length=32, blank=True, null=True, help_text=u'用户唯一标识', db_index=True)
    30
    -    group_name = models.CharField(_(u'group_name'), max_length=255, blank=True, null=True, help_text=u'群组名称')
    31
    -    group_default_avatar = models.IntegerField(_(u'group_default_avatar'), default=0, help_text=u'群组默认头像,0 - 255,水果头像')
    32
    -    group_avatar = models.CharField(_(u'group_avatar'), max_length=255, blank=True, null=True, help_text=u'群组头像')
    33
    -    group_desc = models.TextField(_(u'group_desc'), blank=True, null=True, help_text=u'群组描述')
    34
    -    group_from = models.IntegerField(_(u'group_from'), choices=GROUP_FROM, default=APP_GROUP, help_text=u'群组来源')
    35
    -    session_id = models.CharField(_(u'session_id'), max_length=32, blank=True, null=True, help_text=u'照片组唯一标识', db_index=True)
    36
    -    group_lock = models.BooleanField(_(u'group_lock'), default=False, help_text=u'群组锁定')
    37
    -    group_initio = models.BooleanField(_(u'group_initio'), default=False, help_text=u'群组查看照片从头开始')
    38
    -    # 旅行团
    39
    -    name = models.CharField(_(u'name'), max_length=255, blank=True, null=True, help_text=u'导游姓名')
    40
    -    phone = models.CharField(_(u'phone'), max_length=11, blank=True, null=True, help_text=u'导游电话')
    41
    -    started_at = models.DateTimeField(_(u'started_at'), blank=True, null=True, help_text=_(u'旅游团开始时间'))
    42
    -    ended_at = models.DateTimeField(_(u'ended_at'), blank=True, null=True, help_text=_(u'旅游团结束时间'))
    43
    -    total_persons = models.IntegerField(_(u'total_persons'), default=1, help_text=u'旅游团总人数')
    44
    -    group_closed = models.BooleanField(_(u'group_closed'), default=False, help_text=u'旅游团关闭')
    45
    -    gather_at = models.DateTimeField(_(u'gather_at'), blank=True, null=True, help_text=_(u'旅游团集合时间'))
    46
    -    gather_lon = models.FloatField(_(u'gather_lon'), blank=True, null=True, help_text=_(u'旅游团集合经度'))
    47
    -    gather_lat = models.FloatField(_(u'gather_lat'), blank=True, null=True, help_text=_(u'旅游团集合纬度'))
    48
    -    gather_location = models.CharField(_(u'gather_location'), max_length=255, blank=True, null=True, help_text=u'旅游团集合地点')
    49
    -    gather_screenshot = models.CharField(_(u'gather_screenshot'), max_length=32, blank=True, null=True, help_text=u'旅游团集合地点截图')
    50
    -
    51
    -    attentions_path = models.CharField(_(u'attentions_path'), max_length=32, blank=True, null=True, help_text=u'注意事项照片存放路径')
    52
    -    schedules_path = models.CharField(_(u'schedules_path'), max_length=32, blank=True, null=True, help_text=u'行程安排照片存放路径')
    53
    -
    54
    -    class Meta:
    55
    -        verbose_name = _(u'groupinfo')
    56
    -        verbose_name_plural = _(u'groupinfo')
    57
    -
    58
    -        unique_together = (
    59
    -            ('session_id', 'group_from'),
    60
    -        )
    61
    -
    62
    -    def __unicode__(self):
    63
    -        return self.group_id
    64
    -
    65
    -    @property
    66
    -    def group_avatar_url(self):
    67
    -        return qiniu_file_url(self.group_avatar, bucket='photo')
    68
    -
    69
    -    @property
    70
    -    def group_attentions_url(self):
    71
    -        return qiniu_file_url(self.attentions_path, bucket='photo')
    72
    -
    73
    -    @property
    74
    -    def group_schedules_url(self):
    75
    -        return qiniu_file_url(self.schedules_path, bucket='photo')
    76
    -
    77
    -    @property
    78
    -    def gather_screenshot_url(self):
    79
    -        return qiniu_file_url(self.gather_screenshot, bucket='photo')
    80
    -
    81
    -    @property
    82
    -    def group_photo_num(self):
    83
    -        return GroupPhotoInfo.objects.filter(group_id=self.group_id, status=True).count()
    84
    -
    85
    -    @property
    86
    -    def data(self):
    87
    -        return {
    88
    -            'group_id': self.group_id,
    89
    -            'admin_id': self.admin_id,
    90
    -            'group_name': self.group_name,
    91
    -            'group_default_avatar': self.group_default_avatar,
    92
    -            'group_avatar': self.group_avatar_url,
    93
    -            'group_desc': self.group_desc,
    94
    -            'group_from': self.group_from,
    95
    -            'group_lock': self.group_lock,
    96
    -            'group_initio': self.group_initio,
    97
    -            'group_photo_num': self.group_photo_num,
    98
    -            'name': self.name,
    99
    -            'phone': self.phone,
    100
    -            'started_at': tc.remove_microsecond(self.started_at),
    101
    -            'ended_at': tc.remove_microsecond(self.ended_at),
    102
    -            'total_persons': self.total_persons,
    103
    -            'gather_at': tc.remove_microsecond(self.gather_at),
    104
    -            'gather_lon': self.gather_lon,
    105
    -            'gather_lat': self.gather_lat,
    106
    -            'gather_location': self.gather_location,
    107
    -            'gather_screenshot': self.gather_screenshot_url,
    108
    -            'created_at': tc.remove_microsecond(self.created_at),
    109
    -            'banners': {
    110
    -                'attentions': self.group_attentions_url,
    111
    -                'schedules': self.group_schedules_url,
    112
    -            },
    113
    -        }
    114
    -
    115
    -    def users(self, admin=True, user_id=None):
    116
    -        all_users = GroupUserInfo.objects.filter(group_id=self.group_id, user_status__in=[GroupUserInfo.APPLYING, GroupUserInfo.PASSED], status=True)
    117
    -
    118
    -        passed_users = all_users.filter(user_status=GroupUserInfo.PASSED)
    119
    -        passed_count = passed_users.count()
    120
    -        passed = [passed.user_info for passed in passed_users]
    121
    -
    122
    -        if admin and self.admin_id != user_id:
    123
    -            return {
    124
    -                'passed_count': passed_count,
    125
    -                'passed': passed,
    126
    -            }
    127
    -
    128
    -        applying_users = all_users.filter(user_status=GroupUserInfo.APPLYING)
    129
    -        applying_count = applying_users.count()
    130
    -        applying = [applying.user_info for applying in applying_users]
    131
    -
    132
    -        return {
    133
    -            'applying_count': applying_count,
    134
    -            'passed_count': passed_count,
    135
    -            'applying': applying,
    136
    -            'passed': passed,
    137
    -        }
    138
    -
    139
    -
    140
    -class GroupUserInfo(BaseModelMixin):
    141
    -    APPLYING = 0
    142
    -    PASSED = 1
    143
    -    REFUSED = 2
    144
    -    DELETED = 3
    145
    -    QUIT = 4
    146
    -
    147
    -    USER_STATUS = (
    148
    -        (APPLYING, u'申请中'),
    149
    -        (PASSED, u'已通过'),
    150
    -        (REFUSED, u'已拒绝'),
    151
    -        (DELETED, u'已删除'),
    152
    -        (QUIT, u'已退出'),
    153
    -    )
    154
    -
    155
    -    group_id = models.CharField(_(u'group_id'), max_length=32, blank=True, null=True, help_text=u'群组唯一标识', db_index=True)
    156
    -    user_id = models.CharField(_(u'user_id'), max_length=32, blank=True, null=True, help_text=u'用户唯一标识', db_index=True)
    157
    -    current_id = models.IntegerField(_(u'current_id'), default=-1, help_text=u'当前群组照片ID')
    158
    -    nickname = models.CharField(_(u'nickname'), max_length=255, blank=True, null=True, help_text=u'用户群组昵称')
    159
    -    avatar = models.CharField(_(u'avatar'), max_length=255, blank=True, null=True, help_text=u'用户头像')
    160
    -    admin = models.BooleanField(_(u'admin'), default=False, help_text=u'群组管理员')
    161
    -    user_status = models.IntegerField(_(u'user_status'), choices=USER_STATUS, default=APPLYING)
    162
    -    passed_at = models.DateTimeField(_(u'passed_at'), blank=True, null=True, help_text=_(u'通过时间'))
    163
    -    refused_at = models.DateTimeField(_(u'refused_at'), blank=True, null=True, help_text=_(u'拒绝时间'))
    164
    -    deleted_at = models.DateTimeField(_(u'deleted_at'), blank=True, null=True, help_text=_(u'删除时间'))
    165
    -    quit_at = models.DateTimeField(_(u'quit_at'), blank=True, null=True, help_text=_(u'退出时间'))
    166
    -    # 旅行团相关
    167
    -    subadmin = models.BooleanField(_(u'subadmin'), default=False, help_text=u'副群组管理员')
    168
    -    name = models.CharField(_(u'name'), max_length=255, blank=True, null=True, help_text=u'用户姓名')
    169
    -    phone = models.CharField(_(u'phone'), max_length=11, blank=True, null=True, help_text=u'用户电话')
    170
    -    relative_persons = models.IntegerField(_(u'relative_persons'), default=1, help_text=u'关联人数')
    171
    -    authority = models.BooleanField(_(u'authority'), default=True, help_text=u'是否有定位权限')
    172
    -    remark = models.CharField(_(u'remark'), max_length=255, blank=True, null=True, help_text=u'备注')
    173
    -    admin_status = models.BooleanField(_(u'admin_status'), default=True, help_text=_(u'群组管理员状态'))
    174
    -
    175
    -    class Meta:
    176
    -        verbose_name = _(u'groupuserinfo')
    177
    -        verbose_name_plural = _(u'groupuserinfo')
    178
    -
    179
    -        unique_together = (
    180
    -            ('group_id', 'user_id'),
    181
    -        )
    182
    -
    183
    -    def __unicode__(self):
    184
    -        return '%d' % self.pk
    185
    -
    186
    -    @property
    187
    -    def user_info(self):
    188
    -        return {
    189
    -            'user_id': self.user_id,
    190
    -            'nickname': self.nickname,
    191
    -            'avatar': self.avatar,
    192
    -            'admin': self.admin,
    193
    -            'subadmin': self.subadmin,
    194
    -            'name': self.name,
    195
    -            'phone': self.phone,
    196
    -            'relative_persons': self.relative_persons,
    197
    -            'authority': self.authority,
    198
    -            'remark': self.remark,
    199
    -        }
    200
    -
    201
    -    @property
    202
    -    def admin_info(self):
    203
    -        return {
    204
    -            'user_id': self.user_id,
    205
    -            'nickname': self.nickname,
    206
    -            'avatar': self.avatar,
    207
    -            'admin': self.admin,
    208
    -            'subadmin': self.subadmin,
    209
    -            'name': self.name,
    210
    -            'phone': self.phone,
    211
    -            'relative_persons': self.relative_persons,
    212
    -            'authority': self.authority,
    213
    -            'remark': self.remark,
    214
    -            'status': self.admin_status,
    215
    -        }
    216
    -
    217
    -
    218
    -class GroupPhotoInfo(BaseModelMixin, LensmanTypeMixin):
    219
    -    APP_GROUP = 0
    220
    -    SESSION_GROUP = 1
    221
    -
    222
    -    PHOTO_FROM = (
    223
    -        (APP_GROUP, u'APP 建群'),
    224
    -        (SESSION_GROUP, u'SESSION 建群'),
    225
    -    )
    226
    -
    227
    -    photo_id = ShortUUIDField(_(u'photo_id'), max_length=32, help_text=u'照片唯一标识', db_index=True)
    228
    -
    229
    -    group_id = models.CharField(_(u'group_id'), max_length=32, blank=True, null=True, help_text=u'群组唯一标识', db_index=True)
    230
    -    user_id = models.CharField(_(u'user_id'), max_length=32, blank=True, null=True, help_text=u'用户唯一标识', db_index=True)
    231
    -    nickname = models.CharField(_(u'nickname'), max_length=255, blank=True, null=True, help_text=u'用户群组昵称')
    232
    -    avatar = models.CharField(_(u'avatar'), max_length=255, blank=True, null=True, help_text=u'用户头像')
    233
    -
    234
    -    photo_md5 = models.CharField(_(u'photo_md5'), max_length=32, blank=True, null=True, help_text=u'照片 MD5', db_index=True)
    235
    -
    236
    -    photo_path = models.CharField(_(u'photo_path'), max_length=32, blank=True, null=True, help_text=u'照片存放路径')
    237
    -    has_watermark = models.BooleanField(_(u'has_watermark'), default=False, help_text=_(u'是否有水印'))
    238
    -    photo_w = models.IntegerField(_(u'photo_w'), default=0, help_text=u'照片宽度')
    239
    -    photo_h = models.IntegerField(_(u'photo_h'), default=0, help_text=u'照片高度')
    240
    -
    241
    -    # 双列: 540, 40-50K
    242
    -    photo_thumbnail_path = models.CharField(_(u'photo_thumbnail_path'), max_length=32, blank=True, null=True, help_text=u'照片缩略图存放路径')
    243
    -    photo_thumbnail_w = models.IntegerField(_(u'photo_thumbnail_w'), default=0, help_text=u'照片缩略图宽度')
    244
    -    photo_thumbnail_h = models.IntegerField(_(u'photo_thumbnail_h'), default=0, help_text=u'照片缩略图高度')
    245
    -
    246
    -    # 单列: 1080, xx-100K
    247
    -    photo_thumbnail2_path = models.CharField(_(u'photo_thumbnail2_path'), max_length=32, blank=True, null=True, help_text=u'照片缩略图存放路径')
    248
    -    photo_thumbnail2_w = models.IntegerField(_(u'photo_thumbnail2_w'), default=0, help_text=u'照片缩略图宽度')
    249
    -    photo_thumbnail2_h = models.IntegerField(_(u'photo_thumbnail2_h'), default=0, help_text=u'照片缩略图高度')
    250
    -
    251
    -    comment_num = models.IntegerField(_(u'comment_num'), default=0, help_text=u'照片评论数量')
    252
    -    thumbup_num = models.IntegerField(_(u'thumbup_num'), default=0, help_text=u'照片点赞数量')
    253
    -
    254
    -    photo_from = models.IntegerField(_(u'photo_from'), choices=PHOTO_FROM, default=APP_GROUP, help_text=u'照片来源')
    255
    -
    256
    -    session_id = models.CharField(_(u'session_id'), max_length=32, blank=True, null=True, help_text=u'照片组唯一标识,同 PhotosInfo 表', db_index=True)
    257
    -    lensman_id = models.CharField(_(u'lensman_id'), max_length=32, blank=True, null=True, help_text=u'摄影师唯一标识,同 PhotosInfo 表', db_index=True)
    258
    -    lensman_photo_id = models.CharField(_(u'lensman_photo_id'), max_length=32, blank=True, null=True, help_text=u'摄影师照片唯一标识,同 PhotosInfo 表', db_index=True)
    259
    -
    260
    -    nomark = models.IntegerField(_(u'nomark'), default=299, help_text=u'摄影师照片无水印价格(分)')
    261
    -    origin = models.IntegerField(_(u'origin'), default=999, help_text=u'摄影师照片高清图价格(分)')
    262
    -
    263
    -    class Meta:
    264
    -        verbose_name = _(u'groupphotoinfo')
    265
    -        verbose_name_plural = _(u'groupphotoinfo')
    266
    -
    267
    -        unique_together = (
    268
    -            ('group_id', 'user_id', 'photo_md5'),
    269
    -        )
    270
    -
    271
    -    def __unicode__(self):
    272
    -        return '%d' % self.pk
    273
    -
    274
    -    @property
    275
    -    def photo_url(self):
    276
    -        return qiniu_file_url(self.photo_path, bucket='watermark' if self.has_watermark else 'photo')
    277
    -
    278
    -    @property
    279
    -    def photo_thumbnail_url(self):
    280
    -        return qiniu_file_url(self.photo_thumbnail_path, bucket='thumbnail')
    281
    -
    282
    -    @property
    283
    -    def photo_thumbnail2_url(self):
    284
    -        return qiniu_file_url(self.photo_thumbnail2_path, bucket='thumbnail2')
    285
    -
    286
    -    @property
    287
    -    def photo_share_url(self):
    288
    -        return share_url(self.photo_id)
    289
    -
    290
    -    @property
    291
    -    def photo_data(self):
    292
    -        return {
    293
    -            'photo_id': self.photo_id,
    294
    -            'comment_num': self.comment_num,
    295
    -            'thumbup_num': self.thumbup_num,
    296
    -        }
    297
    -
    298
    -    def photo_info(self, user_id):
    299
    -        try:
    300
    -            group = GroupInfo.objects.get(group_id=self.group_id)
    301
    -        except GroupInfo.DoesNotExist:
    302
    -            group = None
    303
    -        porder = get_lensman_order_record(self.photo_id, user_id) if self.photo_from == GroupPhotoInfo.SESSION_GROUP else {}
    304
    -        created_at = self.created_at.replace(microsecond=0)
    305
    -        return {
    306
    -            'group_id': group and group.group_id,
    307
    -            'group_name': group and group.group_name,
    308
    -            'group_default_avatar': group and group.group_default_avatar,
    309
    -            'group_avatar': group and group.group_avatar_url,
    310
    -            'group_from': group and group.group_from,
    311
    -            'photo_id': self.photo_id,
    312
    -            'photo_url': self.photo_url,
    313
    -            'photo_w': self.photo_w,
    314
    -            'photo_h': self.photo_h,
    315
    -            'photo_thumbnail_url': self.photo_thumbnail_url,
    316
    -            'photo_thumbnail_w': self.photo_thumbnail_w,
    317
    -            'photo_thumbnail_h': self.photo_thumbnail_h,
    318
    -            'photo_thumbnail2_url': self.photo_thumbnail2_url,
    319
    -            'photo_thumbnail2_w': self.photo_thumbnail2_w,
    320
    -            'photo_thumbnail2_h': self.photo_thumbnail2_h,
    321
    -            'photo_share_url': self.photo_share_url,
    322
    -            'user_id': self.user_id,
    323
    -            'nickname': self.nickname,
    324
    -            'avatar': self.avatar,
    325
    -            'comment_num': self.comment_num,
    326
    -            'thumbup': get_group_photo_thumbup_flag(self.pk, user_id),
    327
    -            'thumbup_num': self.thumbup_num,
    328
    -            'photo_from': self.photo_from,
    329
    -            'session_id': self.session_id,
    330
    -            'nomark': self.nomark,
    331
    -            'origin': self.origin,
    332
    -            'porder': porder,
    333
    -            'created_at': created_at,
    334
    -            'origin_expired_stamps': origin_expired_stamps(created_at, self.user_id),
    335
    -            'display_payment_btn': self.photo_from == self.SESSION_GROUP and self.lensman_type not in [self.OUTTAKE],
    336
    -        }
    337
    -
    338
    -
    339
    -class GroupPhotoOrderInfo(BaseModelMixin):
    340
    -    group_id = models.CharField(_(u'group_id'), max_length=32, blank=True, null=True, help_text=u'群组唯一标识', db_index=True)
    341
    -    session_id = models.CharField(_(u'session_id'), max_length=32, blank=True, null=True, help_text=u'照片组唯一标识,同 PhotosInfo 表', db_index=True)
    342
    -    user_id = models.CharField(_(u'user_id'), max_length=32, blank=True, null=True, help_text=u'用户唯一标识', db_index=True)
    343
    -    photo_id = models.CharField(_(u'photo_id'), max_length=32, blank=True, null=True, help_text=u'照片唯一标识', db_index=True)
    344
    -    lensman_photo_id = models.CharField(_(u'lensman_photo_id'), max_length=32, blank=True, null=True, help_text=u'摄影师照片唯一标识,同 PhotosInfo 表', db_index=True)
    345
    -
    346
    -    m_photo_path = models.CharField(_(u'm_photo_path'), max_length=32, blank=True, null=True, help_text=u'照片存放路径,Box上传,无水印')
    347
    -    l_photo_path = models.CharField(_(u'l_photo_path'), max_length=32, blank=True, null=True, help_text=u'照片存放路径,美化大图')
    348
    -    r_photo_path = models.CharField(_(u'r_photo_path'), max_length=32, blank=True, null=True, help_text=u'照片存放路径,高清大图')
    349
    -
    350
    -    class Meta:
    351
    -        verbose_name = _(u'groupphotoorderinfo')
    352
    -        verbose_name_plural = _(u'groupphotoorderinfo')
    353
    -
    354
    -        unique_together = (
    355
    -            ('group_id', 'session_id', 'user_id', 'photo_id', 'lensman_photo_id'),
    356
    -        )
    357
    -
    358
    -    def __unicode__(self):
    359
    -        return '%d' % self.pk
    360
    -
    361
    -    @property
    362
    -    def m_photo_url(self):
    363
    -        return qiniu_file_url(self.m_photo_path, bucket='photo')
    364
    -
    365
    -    @property
    366
    -    def l_photo_url(self):
    367
    -        return qiniu_file_url(self.l_photo_path, bucket='prettify')
    368
    -
    369
    -    @property
    370
    -    def r_photo_url(self):
    371
    -        return qiniu_file_url(self.r_photo_path, bucket='original')
    372
    -
    373
    -    @property
    374
    -    def porder_info(self):
    375
    -        return {
    376
    -            'm_photo_url': self.m_photo_url,
    377
    -            'l_photo_url': self.l_photo_url,
    378
    -            'r_photo_url': self.r_photo_url,
    379
    -        }
    380
    -
    381
    -
    382
    -class PhotoCommentInfo(BaseModelMixin):
    383
    -    photo_id = models.CharField(_(u'photo_id'), max_length=32, blank=True, null=True, help_text=u'飞图唯一标识', db_index=True)
    384
    -    user_id = models.CharField(_(u'user_id'), max_length=32, blank=True, null=True, help_text=u'用户唯一标识', db_index=True)
    385
    -    nickname = models.CharField(_(u'nickname'), max_length=255, blank=True, null=True, help_text=u'用户群组昵称')
    386
    -    avatar = models.CharField(_(u'avatar'), max_length=255, blank=True, null=True, help_text=u'用户头像')
    387
    -    to_uid = models.CharField(_(u'to_uid'), max_length=32, blank=True, null=True, help_text=u'被评论用户唯一标识', db_index=True)
    388
    -    comment = models.TextField(_(u'comment'), blank=True, null=True, help_text=u'用户评论')
    389
    -
    390
    -    class Meta:
    391
    -        verbose_name = _(u'photocommentinfo')
    392
    -        verbose_name_plural = _(u'photocommentinfo')
    393
    -
    394
    -    def __unicode__(self):
    395
    -        return '%d' % self.pk
    396
    -
    397
    -    @property
    398
    -    def comment_info(self):
    399
    -        return {
    400
    -            'user_id': self.user_id,
    401
    -            'nickname': self.nickname,
    402
    -            'avatar': self.avatar,
    403
    -            'to_uid': self.to_uid,
    404
    -            'comment': self.comment,
    405
    -            'created_at': tc.remove_microsecond(self.created_at),
    406
    -        }
    407
    -
    408
    -
    409
    -class PhotoThumbUpInfo(BaseModelMixin):
    410
    -    photo_id = models.CharField(_(u'photo_id'), max_length=32, blank=True, null=True, help_text=u'飞图唯一标识', db_index=True)
    411
    -    user_id = models.CharField(_(u'user_id'), max_length=32, blank=True, null=True, help_text=u'用户唯一标识', db_index=True)
    412
    -    nickname = models.CharField(_(u'nickname'), max_length=255, blank=True, null=True, help_text=u'用户群组昵称')
    413
    -    avatar = models.CharField(_(u'avatar'), max_length=255, blank=True, null=True, help_text=u'用户头像')
    414
    -    thumbup = models.BooleanField(_(u'thumbup'), default=True, help_text=u'用户点赞')
    415
    -
    416
    -    class Meta:
    417
    -        verbose_name = _(u'photothumbupinfo')
    418
    -        verbose_name_plural = _(u'photothumbupinfo')
    419
    -
    420
    -        unique_together = (
    421
    -            ('photo_id', 'user_id'),
    422
    -        )
    423
    -
    424
    -    def __unicode__(self):
    425
    -        return '%d' % self.pk
    426
    -
    427
    -    @property
    428
    -    def thumbup_info(self):
    429
    -        return {
    430
    -            'user_id': self.user_id,
    431
    -            'nickname': self.nickname,
    432
    -            'avatar': self.avatar,
    433
    -        }

    + 0 - 23
    group/serializers.py

    @@ -1,23 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -
    3
    -from rest_framework import serializers
    4
    -
    5
    -from group.models import GroupInfo, GroupPhotoInfo, GroupUserInfo
    6
    -
    7
    -
    8
    -class GroupInfoSerializer(serializers.HyperlinkedModelSerializer):
    9
    -    class Meta:
    10
    -        model = GroupInfo
    11
    -        fields = ('group_id', 'admin_id', 'group_name', 'group_desc', 'group_from', 'group_lock', 'status', 'created_at', 'updated_at')
    12
    -
    13
    -
    14
    -class GroupUserInfoSerializer(serializers.HyperlinkedModelSerializer):
    15
    -    class Meta:
    16
    -        model = GroupUserInfo
    17
    -        fields = ('group_id', 'user_id', 'current_id', 'nickname', 'admin', 'user_status', 'passed_at', 'refused_at', 'status', 'created_at', 'updated_at')
    18
    -
    19
    -
    20
    -class GroupPhotoInfoSerializer(serializers.HyperlinkedModelSerializer):
    21
    -    class Meta:
    22
    -        model = GroupPhotoInfo
    23
    -        fields = ('group_id', 'user_id', 'nickname', 'photo_path', 'photo_thumbnail_path', 'status', 'created_at', 'updated_at')

    + 0 - 4
    group/tests.py

    @@ -1,4 +0,0 @@
    1
    -from django.test import TestCase
    2
    -
    3
    -
    4
    -# Create your tests here.

    + 0 - 381
    group/tourguidegroup_views.py

    @@ -1,381 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -
    3
    -from __future__ import division
    4
    -
    5
    -import json
    6
    -
    7
    -import shortuuid
    8
    -from django.conf import settings
    9
    -from django.core.serializers.json import DjangoJSONEncoder
    10
    -from django_curtail_uuid import CurtailUUID
    11
    -from django_logit import logit
    12
    -from django_response import response
    13
    -from TimeConvert import TimeConvert as tc
    14
    -
    15
    -from account.models import UserInfo
    16
    -from group.models import GroupInfo, GroupUserInfo
    17
    -from utils.admin_utils import have_active_group, is_group_admin, is_group_subadmin
    18
    -from utils.error.errno_utils import GroupStatusCode, GroupUserStatusCode, TokenStatusCode, UserStatusCode
    19
    -from utils.redis.connect import r
    20
    -from utils.redis.rgroup import get_group_info, get_group_users_info, set_group_info, set_group_users_info
    21
    -from utils.redis.rkeys import TOUR_GUIDE_GROUP_CUR_GATHER_INFO, TOUR_GUIDE_GROUP_CUR_SESSION
    22
    -from utils.redis.rtourguide import get_tour_guide_own_group, set_tour_guide_own_group
    23
    -from utils.redis.rtouruser import get_tour_user_belong_group
    24
    -from utils.storage_qiniu_utils import file_save
    25
    -
    26
    -
    27
    -@logit
    28
    -def tg_group_create_api(request):
    29
    -    """ 旅行团创建 """
    30
    -    user_id = request.POST.get('user_id', '')
    31
    -    group_name = request.POST.get('group_name', '')
    32
    -    group_default_avatar = int(request.POST.get('group_default_avatar', 0))
    33
    -    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
    34
    -    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
    35
    -    total_persons = int(request.POST.get('total_persons', 1))
    36
    -
    37
    -    # 用户校验
    38
    -    try:
    39
    -        user = UserInfo.objects.get(user_id=user_id)
    40
    -    except UserInfo.DoesNotExist:
    41
    -        return response(UserStatusCode.USER_NOT_FOUND)
    42
    -
    43
    -    # 权限校验
    44
    -    if not user.istourguide:
    45
    -        return response(GroupStatusCode.NOT_GROUP_ADMIN)
    46
    -
    47
    -    # 旅行团校验
    48
    -    if have_active_group(user_id):
    49
    -        return response(GroupStatusCode.ONLY_ONE_ACTIVE_GROUP_ALLOWED)
    50
    -
    51
    -    # 群组唯一标识
    52
    -    group_id = CurtailUUID.uuid(GroupInfo, 'group_id')
    53
    -
    54
    -    # 群组记录创建
    55
    -    group = GroupInfo.objects.create(
    56
    -        group_id=group_id,
    57
    -        admin_id=user_id,
    58
    -        group_name=group_name,
    59
    -        group_default_avatar=group_default_avatar,
    60
    -        group_from=GroupInfo.TOURGUIDE_GROUP,
    61
    -        name=user.name,
    62
    -        phone=user.phone,
    63
    -        started_at=started_at,
    64
    -        ended_at=ended_at,
    65
    -        total_persons=total_persons,
    66
    -    )
    67
    -
    68
    -    # Redis 群组数据缓存
    69
    -    group_info = set_group_info(group)
    70
    -
    71
    -    # 群组用户记录创建
    72
    -    GroupUserInfo.objects.create(
    73
    -        group_id=group_id,
    74
    -        user_id=user_id,
    75
    -        nickname=user.final_nickname,
    76
    -        avatar=user.avatar,
    77
    -        admin=True,
    78
    -        user_status=GroupUserInfo.PASSED,
    79
    -        passed_at=tc.utc_datetime(),
    80
    -        subadmin=True,
    81
    -        name=user.name,
    82
    -        phone=user.phone,
    83
    -    )
    84
    -
    85
    -    # Redis 群组用户数据缓存
    86
    -    group_users = set_group_users_info(group)
    87
    -
    88
    -    # Redis 设置导游拥有的旅行团
    89
    -    set_tour_guide_own_group(user_id, group_id)
    90
    -
    91
    -    return response(200, 'Create Tour Guide Group Success', u'旅行团创建成功', {
    92
    -        'group_id': group_id,
    93
    -        'group': group_info,
    94
    -        'users': group_users,
    95
    -    })
    96
    -
    97
    -
    98
    -@logit
    99
    -def tg_group_detail_api(request):
    100
    -    """ 旅行团详情 """
    101
    -    group_id = request.POST.get('group_id', '')
    102
    -    user_id = request.POST.get('user_id', '')
    103
    -
    104
    -    if not group_id:
    105
    -        group_id = get_tour_guide_own_group(user_id)
    106
    -
    107
    -    group_users_info = get_group_users_info(group_id, user_id)
    108
    -    # Remove tourguide
    109
    -    group_passed_users = [uinfo for uinfo in group_users_info['passed'] if not uinfo['subadmin']]
    110
    -    # Update passed users
    111
    -    group_users_info['passed'] = group_passed_users
    112
    -    # Update passed count
    113
    -    group_users_info['passed_count'] = len(group_passed_users)
    114
    -    # Sum(relative_persons)
    115
    -    group_users_info['relative_persons'] = sum([user['relative_persons'] for user in group_passed_users])
    116
    -
    117
    -    return response(200, 'Get Tour Guide Group Detail Info Success', u'获取旅行团详情成功', {
    118
    -        'group_id': group_id,
    119
    -        'group': get_group_info(group_id),
    120
    -        'users': group_users_info,
    121
    -    })
    122
    -
    123
    -
    124
    -@logit
    125
    -def kodo_tginfo_api(request):
    126
    -    """ 首页旅行团信息 """
    127
    -    user_id = request.POST.get('user_id', '')
    128
    -
    129
    -    # 获取用户当前所处旅行团
    130
    -    group_id = get_tour_user_belong_group(user_id)
    131
    -    if not group_id:
    132
    -        return response(GroupUserStatusCode.USER_HAS_NOT_JOIN_GROUP)
    133
    -
    134
    -    group_info = get_group_info(group_id)
    135
    -
    136
    -    # Check whether ended
    137
    -    ended_at = group_info.get('ended_at', '')
    138
    -    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):
    139
    -        return response(GroupStatusCode.GROUP_HAS_ENDED)
    140
    -
    141
    -    # Check gather info
    142
    -    gather_at = group_info.get('gather_at', '')
    143
    -    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):
    144
    -        group_info['gather_at'] = ''
    145
    -        group_info['gather_lon'] = ''
    146
    -        group_info['gather_lat'] = ''
    147
    -        group_info['gather_location'] = ''
    148
    -
    149
    -    return response(200, 'Get Tour Guide Group Detail Info Success', u'获取旅行团详情成功', {
    150
    -        'group_id': group_id,
    151
    -        'group': group_info,
    152
    -        'users': get_group_users_info(group_id, user_id),
    153
    -    })
    154
    -
    155
    -
    156
    -@logit(body=settings.LOGIT_BODY_FLAG, res=settings.LOGIT_RES_FLAG)
    157
    -def tg_group_update_api(request):
    158
    -    """ 旅行团更新 """
    159
    -    group_id = request.POST.get('group_id', '')
    160
    -    admin_id = request.POST.get('admin_id', '') or request.POST.get('user_id', '')
    161
    -    group_name = request.POST.get('group_name', '')
    162
    -    group_desc = request.POST.get('group_desc', '')
    163
    -
    164
    -    group_avatar = request.FILES.get('group_avatar', '')
    165
    -
    166
    -    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
    167
    -    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
    168
    -    total_persons = int(request.POST.get('total_persons', 0))
    169
    -
    170
    -    attentions = request.FILES.get('attentions', '')
    171
    -    schedules = request.FILES.get('schedules', '')
    172
    -
    173
    -    # 群组校验
    174
    -    try:
    175
    -        group = GroupInfo.objects.get(group_id=group_id)
    176
    -    except GroupInfo.DoesNotExist:
    177
    -        return response(GroupStatusCode.GROUP_NOT_FOUND)
    178
    -
    179
    -    # 权限校验
    180
    -    if group.admin_id != admin_id:
    181
    -        return response(GroupStatusCode.NOT_GROUP_ADMIN)
    182
    -
    183
    -    # 群组名称更新
    184
    -    if group_name:
    185
    -        group.group_name = group_name
    186
    -    # 群组描述更新
    187
    -    if group_desc:
    188
    -        group.group_desc = group_desc
    189
    -    # 群组头像更新
    190
    -    if group_avatar:
    191
    -        group.group_avatar = file_save(group_avatar, prefix='group', ext='.jpeg').photo_path
    192
    -    # 起止时间更新
    193
    -    if started_at:
    194
    -        group.started_at = started_at
    195
    -    if ended_at:
    196
    -        group.ended_at = ended_at
    197
    -    # 旅行团总人数更新
    198
    -    if total_persons:
    199
    -        group.total_persons = total_persons
    200
    -    # 注意事项更新
    201
    -    if attentions:
    202
    -        group.attentions_path = file_save(attentions, prefix='tour', ext='.jpeg').photo_path
    203
    -    # 行程安排更新
    204
    -    if schedules:
    205
    -        group.schedules_path = file_save(schedules, prefix='tour', ext='.jpeg').photo_path
    206
    -    group.save()
    207
    -
    208
    -    # Redis 群组数据缓存更新
    209
    -    group_info = set_group_info(group)
    210
    -
    211
    -    return response(200, 'Update Group Success', u'群组更新成功', {
    212
    -        'group_id': group_id,
    213
    -        'group': group_info,
    214
    -        'users': get_group_users_info(group_id, admin_id),
    215
    -    })
    216
    -
    217
    -
    218
    -@logit
    219
    -def tg_group_close_api(request):
    220
    -    """ 旅行团关闭 """
    221
    -    group_id = request.POST.get('group_id', '')
    222
    -    admin_id = request.POST.get('admin_id', '') or request.POST.get('user_id', '')
    223
    -
    224
    -    # 群组校验
    225
    -    try:
    226
    -        group = GroupInfo.objects.get(group_id=group_id)
    227
    -    except GroupInfo.DoesNotExist:
    228
    -        return response(GroupStatusCode.GROUP_NOT_FOUND)
    229
    -
    230
    -    # 权限校验
    231
    -    if group.admin_id != admin_id:
    232
    -        return response(GroupStatusCode.NOT_GROUP_ADMIN)
    233
    -
    234
    -    # 群组解锁
    235
    -    group.group_closed = True
    236
    -    group.closed_at = tc.utc_datetime()
    237
    -    group.save()
    238
    -
    239
    -    # Redis 群组数据缓存更新
    240
    -    set_group_info(group)
    241
    -
    242
    -    return response(200, 'Close Tour Guide Group Success', u'旅行团关闭成功')
    243
    -
    244
    -
    245
    -@logit
    246
    -def tg_group_gather_start_api(request):
    247
    -    """ 旅行团设置集合时间和地点 """
    248
    -    group_id = request.POST.get('group_id', '')
    249
    -    admin_id = request.POST.get('admin_id', '') or request.POST.get('user_id', '')
    250
    -    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
    251
    -    gather_lon = request.POST.get('lon', '')  # 经度
    252
    -    gather_lat = request.POST.get('lat', '')  # 纬度
    253
    -    gather_location = request.POST.get('gather_location', '')  # 地点
    254
    -    gather_screenshot = request.FILES.get('gather_screenshot', '')
    255
    -
    256
    -    # 群组校验
    257
    -    try:
    258
    -        group = GroupInfo.objects.get(group_id=group_id)
    259
    -    except GroupInfo.DoesNotExist:
    260
    -        return response(GroupStatusCode.GROUP_NOT_FOUND)
    261
    -
    262
    -    # 权限校验
    263
    -    if not is_group_subadmin(group_id, admin_id):
    264
    -        return response(GroupStatusCode.NOT_GROUP_SUBADMIN)
    265
    -
    266
    -    # 集合信息设置
    267
    -    group.gather_at = gather_at
    268
    -    group.gather_lon = gather_lon
    269
    -    group.gather_lat = gather_lat
    270
    -    group.gather_location = gather_location
    271
    -    if gather_screenshot:
    272
    -        group.gather_screenshot = file_save(gather_screenshot, prefix='tour', ext='.jpeg').photo_path
    273
    -    group.save()
    274
    -
    275
    -    # Redis 群组数据缓存更新
    276
    -    set_group_info(group)
    277
    -
    278
    -    # 更新Session
    279
    -    r.pipeline().set(
    280
    -        TOUR_GUIDE_GROUP_CUR_SESSION % group_id, shortuuid.uuid()
    281
    -    ).set(
    282
    -        TOUR_GUIDE_GROUP_CUR_GATHER_INFO % group_id, json.dumps({
    283
    -            'gather_at': gather_at,
    284
    -            'gather_lon': gather_lon,
    285
    -            'gather_lat': gather_lat,
    286
    -            'gather_location': gather_location,
    287
    -        }, cls=DjangoJSONEncoder)
    288
    -    ).execute()
    289
    -
    290
    -    return response(200, 'Set Tour Guide Group Gather Info Success', u'设置旅行团集合信息成功')
    291
    -
    292
    -
    293
    -@logit
    294
    -def tg_group_token_api(request):
    295
    -    """ 旅行团权限管理票据 """
    296
    -    admin_id = request.POST.get('admin_id', '') or request.POST.get('user_id', '')
    297
    -
    298
    -    # 旅行团校验
    299
    -    if not have_active_group(admin_id):
    300
    -        return response(GroupStatusCode.ACTIVE_GROUP_NOT_FOUND)
    301
    -
    302
    -    # 获取旅行团唯一标识
    303
    -    group_id = get_tour_guide_own_group(admin_id)
    304
    -
    305
    -    return response(200, 'Generate Token Success', u'生成票据成功', {
    306
    -        'token': r.token(group_id + admin_id, time=180)
    307
    -    })
    308
    -
    309
    -
    310
    -@logit
    311
    -def tg_group_transfer_api(request):
    312
    -    """ 旅行团权限管理转移 """
    313
    -    admin_id = request.POST.get('admin_id', '')  # 导游唯一标识,识别二维码获取
    314
    -    user_id = request.POST.get('user_id', '')
    315
    -    token = request.POST.get('token', '')
    316
    -
    317
    -    # 旅行团校验
    318
    -    if have_active_group(user_id):
    319
    -        return response(GroupStatusCode.ONLY_ONE_ACTIVE_GROUP_ALLOWED)
    320
    -
    321
    -    # 获取旅行团唯一标识
    322
    -    group_id = get_tour_guide_own_group(admin_id)
    323
    -
    324
    -    # 票据校验
    325
    -    if not r.token_exists(group_id + admin_id, token):
    326
    -        return response(TokenStatusCode.TOKEN_NOT_FOUND)
    327
    -
    328
    -    # 用户校验
    329
    -    try:
    330
    -        user = UserInfo.objects.get(user_id=user_id)
    331
    -    except UserInfo.DoesNotExist:
    332
    -        return response(UserStatusCode.USER_NOT_FOUND)
    333
    -
    334
    -    # 群组校验
    335
    -    try:
    336
    -        group = GroupInfo.objects.get(group_id=group_id)
    337
    -    except GroupInfo.DoesNotExist:
    338
    -        return response(GroupStatusCode.GROUP_NOT_FOUND)
    339
    -
    340
    -    # 权限校验
    341
    -    if not is_group_admin(group_id, admin_id):
    342
    -        return response(GroupStatusCode.NOT_GROUP_ADMIN)
    343
    -
    344
    -    # 群组用户记录创建,若记录不存在,则创建,若记录已存在,则更新
    345
    -    group_user, created = GroupUserInfo.objects.get_or_create(
    346
    -        group_id=group_id,
    347
    -        user_id=user_id,
    348
    -        defaults={
    349
    -            'nickname': user.final_nickname,
    350
    -            'avatar': user.avatar,
    351
    -            'user_status': GroupUserInfo.PASSED,
    352
    -            'passed_at': tc.utc_datetime(),
    353
    -            'subadmin': True,
    354
    -            'name': user.name,
    355
    -            'phone': user.phone,
    356
    -        }
    357
    -    )
    358
    -
    359
    -    if not created:
    360
    -        group_user.current_id = -1
    361
    -        group_user.nickname = user.final_nickname
    362
    -        group_user.avatar = user.avatar
    363
    -        group_user.user_status = GroupUserInfo.PASSED
    364
    -        group_user.passed_at = tc.utc_datetime()
    365
    -        group_user.subadmin = True
    366
    -        group_user.name = user.name
    367
    -        group_user.phone = user.phone
    368
    -        group_user.status = True
    369
    -        group_user.save()
    370
    -
    371
    -    # Redis 群组用户数据缓存
    372
    -    group_users = set_group_users_info(group)
    373
    -
    374
    -    # Redis 设置导游拥有的旅行团
    375
    -    set_tour_guide_own_group(user_id, group_id)
    376
    -
    377
    -    return response(200, 'Transfer Tour Guide Group Success', u'转移旅行团管理权成功', {
    378
    -        'group_id': group_id,
    379
    -        'group': group.data,
    380
    -        'users': group_users,
    381
    -    })

    + 0 - 74
    group/tourguidegroupadmin_views.py

    @@ -1,74 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -
    3
    -from __future__ import division
    4
    -
    5
    -from django_logit import logit
    6
    -from django_response import response
    7
    -
    8
    -from group.models import GroupUserInfo
    9
    -from utils.admin_utils import is_group_admin
    10
    -from utils.error.errno_utils import GroupStatusCode
    11
    -
    12
    -
    13
    -@logit
    14
    -def tg_group_admin_list_api(request):
    15
    -    """ 旅行团管理员列表 """
    16
    -    group_id = request.POST.get('group_id', '')
    17
    -    admin_id = request.POST.get('admin_id', '')  # 导游唯一标识
    18
    -
    19
    -    # 权限校验
    20
    -    if not is_group_admin(group_id, admin_id):
    21
    -        return response(GroupStatusCode.NOT_GROUP_ADMIN)
    22
    -
    23
    -    admins = GroupUserInfo.objects.filter(group_id=group_id, subadmin=True, status=True)
    24
    -    admins = [admin.admin_info for admin in admins]
    25
    -
    26
    -    return response(200, 'Get Tour Guide Group Admin List Success', u'获取旅行团管理员列表成功', {
    27
    -        'group_id': group_id,
    28
    -        'admins': admins,
    29
    -    })
    30
    -
    31
    -
    32
    -@logit
    33
    -def tg_group_admin_recovery_api(request):
    34
    -    """ 旅行团管理员权限回收,管理员主动,团成员被动 """
    35
    -    group_id = request.POST.get('group_id', '')
    36
    -    admin_id = request.POST.get('admin_id', '')  # 导游唯一标识
    37
    -    user_id = request.POST.get('user_id', '')
    38
    -
    39
    -    # 权限校验
    40
    -    if not is_group_admin(group_id, admin_id):
    41
    -        return response(GroupStatusCode.NOT_GROUP_ADMIN)
    42
    -
    43
    -    # 管理员也不允许将自己移除
    44
    -    if admin_id == user_id:
    45
    -        return response(GroupStatusCode.ADMIN_CANNOT_HANDLE_SELF)
    46
    -
    47
    -    try:
    48
    -        subadmin = GroupUserInfo.objects.get(group_id=group_id, user_id=user_id, subadmin=True, admin_status=True, status=True)
    49
    -    except GroupUserInfo.DoesNotExist:
    50
    -        return response(GroupStatusCode.NOT_GROUP_SUBADMIN)
    51
    -
    52
    -    # 权限回收
    53
    -    subadmin.admin_status = False
    54
    -    subadmin.save()
    55
    -
    56
    -    return response(200, 'Tour Guide Group Admin Right Recovery Success', u'旅行团管理员权限回收成功')
    57
    -
    58
    -
    59
    -@logit
    60
    -def tg_group_admin_waiver_api(request):
    61
    -    """ 旅行团管理员权限放弃 """
    62
    -    group_id = request.POST.get('group_id', '')
    63
    -    user_id = request.POST.get('user_id', '')
    64
    -
    65
    -    try:
    66
    -        subadmin = GroupUserInfo.objects.get(group_id=group_id, user_id=user_id, subadmin=True, admin_status=True, status=True)
    67
    -    except GroupUserInfo.DoesNotExist:
    68
    -        return response(GroupStatusCode.NOT_GROUP_SUBADMIN)
    69
    -
    70
    -    # 权限回收
    71
    -    subadmin.admin_status = False
    72
    -    subadmin.save()
    73
    -
    74
    -    return response(200, 'Tour Guide Group Admin Right Waiver Success', u'旅行团管理员权限放弃成功')

    + 0 - 334
    group/tourguidegroupuser_views.py

    @@ -1,334 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -
    3
    -from __future__ import division
    4
    -
    5
    -import json
    6
    -
    7
    -from django.conf import settings
    8
    -from django.db import transaction
    9
    -from django_logit import logit
    10
    -from django_response import response
    11
    -from TimeConvert import TimeConvert as tc
    12
    -
    13
    -from account.models import UserInfo
    14
    -from group.models import GroupInfo, GroupUserInfo
    15
    -from utils.admin_utils import is_group_subadmin
    16
    -from utils.error.errno_utils import GroupStatusCode, GroupUserStatusCode, UserStatusCode
    17
    -from utils.group_photo_utils import get_current_photos
    18
    -from utils.redis.connect import r
    19
    -from utils.redis.rgroup import get_group_info, get_group_users_info, get_group_users_kv_info, set_group_users_info
    20
    -from utils.redis.rkeys import (GROUP_LAST_PHOTO_PK, GROUP_USERS_DELETED_SET, GROUP_USERS_PASSED_SET,
    21
    -                               GROUP_USERS_QUIT_SET, GROUP_USERS_REFUSED_SET, TOUR_GUIDE_GROUP_CUR_GATHER_INFO,
    22
    -                               TOUR_GUIDE_GROUP_CUR_SESSION, TOUR_GUIDE_GROUP_GEO_INFO, TOUR_GUIDE_GROUP_GEO_SUBMIT_DT,
    23
    -                               TOUR_GUIDE_GROUP_USER_GEO_LIST)
    24
    -from utils.redis.rtourguide import get_tour_guide_own_group
    25
    -from utils.redis.rtouruser import set_tour_user_belong_group
    26
    -
    27
    -
    28
    -@logit
    29
    -def tgu_group_user_is_joined_api(request):
    30
    -    """ 旅行团成员是否已加团 """
    31
    -    admin_id = request.POST.get('admin_id', '')  # 导游唯一标识,识别二维码获取
    32
    -    user_id = request.POST.get('user_id', '')
    33
    -
    34
    -    # 获取旅行团唯一标识
    35
    -    group_id = get_tour_guide_own_group(admin_id)
    36
    -
    37
    -    # 用户校验
    38
    -    try:
    39
    -        user = UserInfo.objects.get(user_id=user_id)
    40
    -    except UserInfo.DoesNotExist:
    41
    -        return response(UserStatusCode.USER_NOT_FOUND)
    42
    -
    43
    -    # 群组校验
    44
    -    try:
    45
    -        group = GroupInfo.objects.get(group_id=group_id)
    46
    -    except GroupInfo.DoesNotExist:
    47
    -        return response(GroupStatusCode.GROUP_NOT_FOUND)
    48
    -
    49
    -    # 群组锁定校验
    50
    -    if group.group_lock:
    51
    -        return response(GroupStatusCode.GROUP_HAS_LOCKED)
    52
    -
    53
    -    # Check whether ended
    54
    -    ended_at = group.ended_at
    55
    -    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):
    56
    -        return response(GroupStatusCode.GROUP_HAS_ENDED)
    57
    -
    58
    -    # 群组用户是否存在
    59
    -    joined = GroupUserInfo.objects.filter(group_id=group_id, user_id=user_id).exists()
    60
    -
    61
    -    return response(200, 'Tour Guide User Has Joined', u'旅行团成员已加团', {
    62
    -        'joined': joined,
    63
    -        'group': get_group_info(group_id),
    64
    -    })
    65
    -
    66
    -
    67
    -@logit(res=settings.LOGIT_RES_FLAG)
    68
    -def tgu_group_user_join_api(request):
    69
    -    """ 旅行团成员加团 """
    70
    -    admin_id = request.POST.get('admin_id', '')  # 导游唯一标识,识别二维码获取
    71
    -    user_id = request.POST.get('user_id', '')
    72
    -    nickname = request.POST.get('nickname', '')
    73
    -
    74
    -    name = request.POST.get('name', '')
    75
    -    phone = request.POST.get('phone', '')
    76
    -    relative_persons = int(request.POST.get('relative_persons', 1))
    77
    -    authority = bool(int(request.POST.get('authority', 1)))
    78
    -    remark = request.POST.get('remark', '')
    79
    -
    80
    -    # 获取旅行团唯一标识
    81
    -    group_id = get_tour_guide_own_group(admin_id)
    82
    -
    83
    -    # 用户校验
    84
    -    try:
    85
    -        user = UserInfo.objects.get(user_id=user_id)
    86
    -    except UserInfo.DoesNotExist:
    87
    -        return response(UserStatusCode.USER_NOT_FOUND)
    88
    -
    89
    -    # 群组校验
    90
    -    try:
    91
    -        group = GroupInfo.objects.get(group_id=group_id)
    92
    -    except GroupInfo.DoesNotExist:
    93
    -        return response(GroupStatusCode.GROUP_NOT_FOUND)
    94
    -
    95
    -    # 群组锁定校验
    96
    -    if group.group_lock:
    97
    -        return response(GroupStatusCode.GROUP_HAS_LOCKED)
    98
    -
    99
    -    # Check whether ended
    100
    -    ended_at = group.ended_at
    101
    -    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):
    102
    -        return response(GroupStatusCode.GROUP_HAS_ENDED)
    103
    -
    104
    -    # 群组用户记录创建,若记录不存在,则创建,若记录已存在,则更新
    105
    -    group_user, created = GroupUserInfo.objects.get_or_create(
    106
    -        group_id=group_id,
    107
    -        user_id=user_id,
    108
    -        defaults={
    109
    -            'name': name,
    110
    -            'phone': phone,
    111
    -            'relative_persons': relative_persons,
    112
    -            'authority': authority,
    113
    -            'remark': remark,
    114
    -        }
    115
    -    )
    116
    -
    117
    -    if not created:
    118
    -        group_user.name = name
    119
    -        group_user.phone = phone
    120
    -        group_user.relative_persons = relative_persons
    121
    -        group_user.authority = authority
    122
    -        group_user.remark = remark
    123
    -        group_user.save()
    124
    -
    125
    -    if group_user.user_status != GroupUserInfo.PASSED:
    126
    -        group_user.current_id = int(r.get(GROUP_LAST_PHOTO_PK % group_id) or -1)
    127
    -        group_user.nickname = nickname or user.final_nickname
    128
    -        group_user.avatar = user.avatar
    129
    -        # group_user.admin = False  # Admin Field Default False, Should Not Assign
    130
    -        group_user.user_status = GroupUserInfo.PASSED
    131
    -        group_user.passed_at = tc.utc_datetime()
    132
    -        group_user.save()
    133
    -
    134
    -    # Redis 群组用户数据缓存
    135
    -    set_group_users_info(group)
    136
    -
    137
    -    # Redis 群组通过集合缓存
    138
    -    r.srem(GROUP_USERS_REFUSED_SET % group_id, user_id)
    139
    -    r.srem(GROUP_USERS_DELETED_SET % group_id, user_id)
    140
    -    r.srem(GROUP_USERS_QUIT_SET % group_id, user_id)
    141
    -    r.sadd(GROUP_USERS_PASSED_SET % group_id, user_id)
    142
    -
    143
    -    curinfo = get_current_photos(group_id, user_id, group_user.current_id, request=request)
    144
    -
    145
    -    # 添加默认地理位置信息
    146
    -    r.geoadd(TOUR_GUIDE_GROUP_GEO_INFO % group_id, 0, 0, user_id)
    147
    -
    148
    -    # 设置旅行团成员所属的旅行团
    149
    -    set_tour_user_belong_group(user_id, group_id)
    150
    -
    151
    -    return response(200, 'Tour Guide User Join Success', u'旅行团成员加团成功', {
    152
    -        'current_id': curinfo.get('current_id', ''),
    153
    -        'photos': curinfo.get('photos', ''),
    154
    -        'group_id': group_id,
    155
    -        'group': get_group_info(group_id),
    156
    -        'user_id': user_id,
    157
    -        'users': get_group_users_info(group_id, user_id),
    158
    -    })
    159
    -
    160
    -
    161
    -@logit
    162
    -def tgu_group_user_remove_api(request):
    163
    -    """ 旅行团成员移除,管理员主动,团成员被动 """
    164
    -    group_id = request.POST.get('group_id', '')
    165
    -    admin_id = request.POST.get('admin_id', '')  # 导游唯一标识
    166
    -    user_id = request.POST.get('user_id', '')
    167
    -
    168
    -    # 群组校验
    169
    -    try:
    170
    -        group = GroupInfo.objects.get(group_id=group_id)
    171
    -    except GroupInfo.DoesNotExist:
    172
    -        return response(GroupStatusCode.GROUP_NOT_FOUND)
    173
    -
    174
    -    # 权限校验
    175
    -    if not is_group_subadmin(group_id, admin_id):
    176
    -        return response(GroupStatusCode.NOT_GROUP_SUBADMIN)
    177
    -
    178
    -    # 管理员也不允许将自己移除
    179
    -    if admin_id == user_id:
    180
    -        return response(GroupStatusCode.ADMIN_CANNOT_HANDLE_SELF)
    181
    -
    182
    -    # 群组用户校验
    183
    -    try:
    184
    -        group_user = GroupUserInfo.objects.get(group_id=group_id, user_id=user_id, status=True)
    185
    -    except GroupUserInfo.DoesNotExist:
    186
    -        return response(GroupUserStatusCode.GROUP_USER_NOT_FOUND)
    187
    -
    188
    -    # 群组用户移除
    189
    -    group_user.user_status = GroupUserInfo.DELETED
    190
    -    group_user.deleted_at = tc.utc_datetime()
    191
    -    group_user.save()
    192
    -
    193
    -    # Redis 群组数据缓存更新
    194
    -    group_users = set_group_users_info(group)
    195
    -
    196
    -    # Redis 群组删除集合缓存
    197
    -    r.srem(GROUP_USERS_PASSED_SET % group_id, user_id)
    198
    -    r.sadd(GROUP_USERS_DELETED_SET % group_id, user_id)
    199
    -
    200
    -    # 移除地理位置信息
    201
    -    r.georem(TOUR_GUIDE_GROUP_GEO_INFO % group_id, user_id)
    202
    -
    203
    -    return response(200, 'Tour Guide User Remove Success', u'旅行团成员移除成功', {
    204
    -        'group_id': group_id,
    205
    -        'users': group_users,
    206
    -    })
    207
    -
    208
    -
    209
    -@logit
    210
    -@transaction.atomic
    211
    -def tgu_group_user_update_api(request):
    212
    -    """ 旅行团成员信息更新 """
    213
    -    group_id = request.POST.get('group_id', '')
    214
    -    admin_id = request.POST.get('admin_id', '')  # 导游唯一标识
    215
    -    user_id = request.POST.get('user_id', '')
    216
    -
    217
    -    name = request.POST.get('name', '')
    218
    -    phone = request.POST.get('phone', '')
    219
    -    relative_persons = int(request.POST.get('relative_persons', 0))
    220
    -    authority = bool(int(request.POST.get('authority', 0)))
    221
    -    remark = request.POST.get('remark', '')
    222
    -
    223
    -    # 群组校验
    224
    -    try:
    225
    -        group = GroupInfo.objects.get(group_id=group_id)
    226
    -    except GroupInfo.DoesNotExist:
    227
    -        return response(GroupStatusCode.GROUP_NOT_FOUND)
    228
    -
    229
    -    # 权限校验
    230
    -    if admin_id:
    231
    -        if not is_group_subadmin(group_id, admin_id):
    232
    -            return response(GroupStatusCode.NOT_GROUP_SUBADMIN)
    233
    -    else:
    234
    -        if not GroupUserInfo.objects.filter(group_id=group_id, user_id=user_id, status=True).exists():
    235
    -            return response(GroupStatusCode.NOT_GROUP_ADMIN)
    236
    -
    237
    -    # 权限
    238
    -    try:
    239
    -        group_user = GroupUserInfo.objects.select_for_update().get(group_id=group_id, user_id=user_id, status=True)
    240
    -    except GroupUserInfo.DoesNotExist:
    241
    -        return response(GroupUserStatusCode.GROUP_USER_NOT_FOUND)
    242
    -
    243
    -    # 用户信息更新
    244
    -    # TODO: Whether sync name and phone to UserInfo or not?
    245
    -    if name:
    246
    -        group_user.name = name
    247
    -    if phone:
    248
    -        group_user.phone = phone
    249
    -    if relative_persons:
    250
    -        # TODO & UNDO: Should check not gt GroupInfo.total_persons & App remind
    251
    -        group_user.relative_persons = relative_persons
    252
    -    if authority:
    253
    -        group_user.authority = authority
    254
    -    if remark:
    255
    -        group_user.remark = remark
    256
    -    group_user.save()
    257
    -
    258
    -    # Redis 群组用户数据缓存
    259
    -    group_users = set_group_users_info(group)
    260
    -
    261
    -    return response(200, 'Tour Guide User Update Success', u'旅行团成员信息更新成功', {
    262
    -        'group_id': group_id,
    263
    -        'group': group.data,
    264
    -        'users': group_users,
    265
    -    })
    266
    -
    267
    -
    268
    -def get_geo_submit_flag(geo_at, gather_at):
    269
    -    """ 是否上传过位置字段(即是否失联) """
    270
    -    if geo_at and gather_at:
    271
    -        geo_at = tc.utc_string_to_utc_datetime(geo_at, format='%Y-%m-%dT%H:%M:%SZ')
    272
    -        gather_at = tc.utc_string_to_utc_datetime(gather_at, format='%Y-%m-%dT%H:%M:%SZ')
    273
    -        current_dt = tc.utc_datetime()
    274
    -        delta_seconds = tc.total_seconds(gather_at - current_dt)
    275
    -        # 距离集合时间超过30分钟是5分钟,15分钟到30分钟是3分钟,15分钟以内是1分钟
    276
    -        for delta, gdt in [(1800, 300), (900, 180), (0, 60)]:
    277
    -            if delta_seconds > delta:
    278
    -                return tc.total_seconds(current_dt - geo_at) <= gdt
    279
    -    return False
    280
    -
    281
    -
    282
    -@logit
    283
    -def tgu_group_user_locations_api(request):
    284
    -    """ 旅行团所有成员位置信息 """
    285
    -    group_id = request.POST.get('group_id', '')
    286
    -    admin_id = request.POST.get('admin_id', '')  # 导游唯一标识
    287
    -
    288
    -    # 权限校验
    289
    -    if not is_group_subadmin(group_id, admin_id):
    290
    -        return response(GroupStatusCode.NOT_GROUP_SUBADMIN)
    291
    -
    292
    -    # 获取集合经纬度
    293
    -    gather_info = json.loads(r.get(TOUR_GUIDE_GROUP_CUR_GATHER_INFO % group_id) or '{}')
    294
    -
    295
    -    # GEO submit dts
    296
    -    geo_dts = r.hgetall(TOUR_GUIDE_GROUP_GEO_SUBMIT_DT % group_id)
    297
    -
    298
    -    # [['x', 0.33, (2.68220901489e-06, 1.26736058093e-06)], []]
    299
    -    locations = r.georadius(TOUR_GUIDE_GROUP_GEO_INFO % group_id, gather_info.get('gather_lon', 0), gather_info.get('gather_lat', 0), '+inf', unit='m', withdist=True, withcoord=True, sort='ASC')
    300
    -    # [{'lon': 2.68220901489e-06, 'lat': 26736058093e-06, 'dist': 0.33, etc...}, {}]
    301
    -    # 获取旅行团用户 KV 信息
    302
    -    group_users_kv_info = get_group_users_kv_info(group_id)
    303
    -    locations = [dict(group_users_kv_info[loc[0]], **{
    304
    -        'lon': loc[2][0],
    305
    -        'lat': loc[2][1],
    306
    -        'dist': loc[1],
    307
    -        'geo_submited': get_geo_submit_flag(geo_dts.get(loc[0], ''), gather_info.get('gather_at', '')),
    308
    -    }) for loc in locations]
    309
    -
    310
    -    return response(200, 'Get Tour Guide Group All User Location Success', u'获取旅行团成员地理位置信息成功', {
    311
    -        'group_id': group_id,
    312
    -        'locations': locations,
    313
    -    })
    314
    -
    315
    -
    316
    -@logit
    317
    -def tgu_group_user_location_api(request):
    318
    -    """ 旅行团单个成员位置信息 """
    319
    -    group_id = request.POST.get('group_id', '')
    320
    -    admin_id = request.POST.get('admin_id', '')  # 导游唯一标识
    321
    -    user_id = request.POST.get('user_id', '')
    322
    -
    323
    -    # 权限校验
    324
    -    if not is_group_subadmin(group_id, admin_id):
    325
    -        return response(GroupStatusCode.NOT_GROUP_SUBADMIN)
    326
    -
    327
    -    session_id = r.get(TOUR_GUIDE_GROUP_CUR_SESSION % group_id)
    328
    -    locations = r.lrange(TOUR_GUIDE_GROUP_USER_GEO_LIST % (group_id, session_id, user_id), 0, -1)
    329
    -
    330
    -    return response(200, 'Get Tour Guide Group User Location Success', u'获取旅行团成员地理位置信息成功', {
    331
    -        'group_id': group_id,
    332
    -        'user_id': user_id,
    333
    -        'locations': [json.loads(loc) for loc in locations]
    334
    -    })

    + 0 - 710
    group/views.py

    @@ -1,710 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -
    3
    -from __future__ import division
    4
    -
    5
    -from django.conf import settings
    6
    -from django.db import connection, transaction
    7
    -from django_curtail_uuid import CurtailUUID
    8
    -from django_logit import logit
    9
    -from django_response import response
    10
    -from paginator import pagination
    11
    -from rest_framework import viewsets
    12
    -from TimeConvert import TimeConvert as tc
    13
    -
    14
    -from account.models import UserInfo
    15
    -from group.models import GroupInfo, GroupPhotoInfo, GroupUserInfo, PhotoCommentInfo, PhotoThumbUpInfo
    16
    -from group.serializers import GroupInfoSerializer, GroupPhotoInfoSerializer, GroupUserInfoSerializer
    17
    -from message.models import UserMessageInfo
    18
    -from utils.error.errno_utils import GroupPhotoStatusCode, GroupStatusCode, GroupUserStatusCode, UserStatusCode
    19
    -from utils.group_photo_utils import get_current_photos
    20
    -from utils.price_utils import get_group_photo_price
    21
    -from utils.qiniucdn import qiniu_file_url
    22
    -from utils.redis.connect import r
    23
    -from utils.redis.rgroup import (del_group_photo_thumbup_flag, get_group_info, get_group_photo_comment_list,
    24
    -                                get_group_photo_data, get_group_photo_thumbup_flag, get_group_photo_thumbup_list,
    25
    -                                get_group_photo_watchers, get_group_users_info, set_group_info, set_group_info_by_id,
    26
    -                                set_group_photo_comment_list, set_group_photo_data, set_group_photo_thumbup_flag,
    27
    -                                set_group_photo_thumbup_list, set_group_users_info)
    28
    -from utils.redis.rkeys import GROUP_LAST_PHOTO_PK, GROUP_PHOTO_WATCHER_SET, GROUP_USERS_PASSED_SET
    29
    -from utils.redis.rlock import upload_lock
    30
    -from utils.redis.rorder import get_lensman_order_record
    31
    -from utils.sql.raw import PAI2_HOME_API, PAI2_HOME_WX_API
    32
    -from utils.storage_qiniu_utils import file_save
    33
    -from utils.time_utils import origin_expired_stamps
    34
    -from utils.url_utils import share_url
    35
    -
    36
    -
    37
    -@logit
    38
    -@transaction.atomic
    39
    -def group_create_api(request):
    40
    -    """ 群组创建 """
    41
    -    user_id = request.POST.get('user_id', '')
    42
    -    group_name = request.POST.get('group_name', '')
    43
    -    group_default_avatar = int(request.POST.get('group_default_avatar', 0))
    44
    -
    45
    -    # 用户校验
    46
    -    try:
    47
    -        user = UserInfo.objects.get(user_id=user_id)
    48
    -    except UserInfo.DoesNotExist:
    49
    -        return response(UserStatusCode.USER_NOT_FOUND)
    50
    -
    51
    -    # 群组唯一标识
    52
    -    group_id = CurtailUUID.uuid(GroupInfo, 'group_id')
    53
    -
    54
    -    # 群组记录创建
    55
    -    group = GroupInfo.objects.create(
    56
    -        group_id=group_id,
    57
    -        admin_id=user_id,
    58
    -        group_name=group_name,
    59
    -        group_default_avatar=group_default_avatar,
    60
    -        group_from=GroupInfo.APP_GROUP,
    61
    -    )
    62
    -
    63
    -    # Redis 群组数据缓存
    64
    -    group_info = set_group_info(group)
    65
    -
    66
    -    # 群组用户记录创建
    67
    -    GroupUserInfo.objects.create(
    68
    -        group_id=group_id,
    69
    -        user_id=user_id,
    70
    -        nickname=user.final_nickname,
    71
    -        avatar=user.avatar,
    72
    -        admin=True,
    73
    -        user_status=GroupUserInfo.PASSED,
    74
    -        passed_at=tc.utc_datetime(),
    75
    -    )
    76
    -
    77
    -    # Redis 群组用户数据缓存
    78
    -    group_users = set_group_users_info(group)
    79
    -
    80
    -    # Redis 群组通过集合缓存
    81
    -    r.sadd(GROUP_USERS_PASSED_SET % group_id, user_id)
    82
    -
    83
    -    return response(200, 'Create Group Success', u'群组创建成功', {
    84
    -        'group_id': group_id,
    85
    -        'group': group_info,
    86
    -        'users': group_users,
    87
    -    })
    88
    -
    89
    -
    90
    -@logit
    91
    -def group_detail_api(request):
    92
    -    """ 群组详情 """
    93
    -    group_id = request.POST.get('group_id', '')
    94
    -    user_id = request.POST.get('user_id', '')
    95
    -
    96
    -    return response(200, 'Get Group Detail Info Success', u'获取群组详情成功', {
    97
    -        'group_id': group_id,
    98
    -        'group': get_group_info(group_id),
    99
    -        'users': get_group_users_info(group_id, user_id),
    100
    -    })
    101
    -
    102
    -
    103
    -@logit
    104
    -def group_update_api(request):
    105
    -    """ 群组更新 """
    106
    -    group_id = request.POST.get('group_id', '')
    107
    -    admin_id = request.POST.get('admin_id', '') or request.POST.get('user_id', '')
    108
    -    group_name = request.POST.get('group_name', '')
    109
    -    group_desc = request.POST.get('group_desc', '')
    110
    -
    111
    -    group_avatar = request.FILES.get('group_avatar', '')
    112
    -
    113
    -    # 群组校验
    114
    -    try:
    115
    -        group = GroupInfo.objects.get(group_id=group_id)
    116
    -    except GroupInfo.DoesNotExist:
    117
    -        return response(GroupStatusCode.GROUP_NOT_FOUND)
    118
    -
    119
    -    # 权限校验
    120
    -    if group.admin_id != admin_id:
    121
    -        return response(GroupStatusCode.NOT_GROUP_ADMIN)
    122
    -
    123
    -    # 群组名称更新
    124
    -    if group_name:
    125
    -        group.group_name = group_name
    126
    -    # 群组描述更新
    127
    -    if group_desc:
    128
    -        group.group_desc = group_desc
    129
    -    # 群组头像更新
    130
    -    if group_avatar:
    131
    -        group.group_avatar = file_save(group_avatar, prefix='group', ext='.jpeg').photo_path
    132
    -    group.save()
    133
    -
    134
    -    # Redis 群组数据缓存更新
    135
    -    group_info = set_group_info(group)
    136
    -
    137
    -    return response(200, 'Update Group Success', u'群组更新成功', {
    138
    -        'group_id': group_id,
    139
    -        'group': group_info,
    140
    -        'users': get_group_users_info(group_id, admin_id),
    141
    -    })
    142
    -
    143
    -
    144
    -@logit
    145
    -def group_delete_api(request):
    146
    -    """ 群组删除 """
    147
    -    group_id = request.POST.get('group_id', '')
    148
    -    admin_id = request.POST.get('admin_id', '') or request.POST.get('user_id', '')
    149
    -
    150
    -    # 群组校验
    151
    -    try:
    152
    -        group = GroupInfo.objects.get(group_id=group_id)
    153
    -    except GroupInfo.DoesNotExist:
    154
    -        return response(GroupStatusCode.GROUP_NOT_FOUND)
    155
    -
    156
    -    # 权限校验
    157
    -    if group.admin_id != admin_id:
    158
    -        return response(GroupStatusCode.NOT_GROUP_ADMIN)
    159
    -
    160
    -    # 照片数量校验
    161
    -    if GroupPhotoInfo.objects.filter(group_id=group_id, status=True).count():
    162
    -        return response(GroupStatusCode.GROUP_PHOTO_NOT_EMPTY)
    163
    -
    164
    -    # 删除群组
    165
    -    group.status = False
    166
    -    group.save()
    167
    -
    168
    -    # 删除群组用户
    169
    -    GroupUserInfo.objects.filter(group_id=group_id).update(status=False)
    170
    -
    171
    -    return response(200, 'Delete Group Success', u'群组删除成功')
    172
    -
    173
    -
    174
    -@logit
    175
    -def group_list_api(request):
    176
    -    """ 群组列表 """
    177
    -    user_id = request.POST.get('user_id', '')
    178
    -    page = int(request.POST.get('page', 1))
    179
    -    num = int(request.POST.get('num', settings.GROUP_NUM_PER_PAGE))
    180
    -
    181
    -    group_users = GroupUserInfo.objects.filter(user_id=user_id, user_status=GroupUserInfo.PASSED, status=True).order_by('-pk')
    182
    -    group_users, left = pagination(group_users, page, num)
    183
    -
    184
    -    groups = []
    185
    -    for group_user in group_users:
    186
    -        group_info = get_group_info(group_user.group_id)
    187
    -        groups.append(group_info) if group_info else None
    188
    -
    189
    -    return response(200, 'Get Group List Success', u'获取群组列表成功', {
    190
    -        'groups': groups,
    191
    -        'left': left,
    192
    -    })
    193
    -
    194
    -
    195
    -@logit
    196
    -def group_lock_api(request):
    197
    -    """ 群组锁定 """
    198
    -    group_id = request.POST.get('group_id', '')
    199
    -    admin_id = request.POST.get('admin_id', '') or request.POST.get('user_id', '')
    200
    -
    201
    -    # 群组校验
    202
    -    try:
    203
    -        group = GroupInfo.objects.get(group_id=group_id)
    204
    -    except GroupInfo.DoesNotExist:
    205
    -        return response(GroupStatusCode.GROUP_NOT_FOUND)
    206
    -
    207
    -    # 权限校验
    208
    -    if group.admin_id != admin_id:
    209
    -        return response(GroupStatusCode.NOT_GROUP_ADMIN)
    210
    -
    211
    -    # 群组锁定
    212
    -    group.group_lock = True
    213
    -    group.save()
    214
    -
    215
    -    # Redis 群组数据缓存更新
    216
    -    set_group_info(group)
    217
    -
    218
    -    return response(200, 'Lock Success', u'锁定成功')
    219
    -
    220
    -
    221
    -@logit
    222
    -def group_unlock_api(request):
    223
    -    """ 群组解锁 """
    224
    -    group_id = request.POST.get('group_id', '')
    225
    -    admin_id = request.POST.get('admin_id', '') or request.POST.get('user_id', '')
    226
    -
    227
    -    # 群组校验
    228
    -    try:
    229
    -        group = GroupInfo.objects.get(group_id=group_id)
    230
    -    except GroupInfo.DoesNotExist:
    231
    -        return response(GroupStatusCode.GROUP_NOT_FOUND)
    232
    -
    233
    -    # 权限校验
    234
    -    if group.admin_id != admin_id:
    235
    -        return response(GroupStatusCode.NOT_GROUP_ADMIN)
    236
    -
    237
    -    # 群组解锁
    238
    -    group.group_lock = False
    239
    -    group.save()
    240
    -
    241
    -    # Redis 群组数据缓存更新
    242
    -    set_group_info(group)
    243
    -
    244
    -    return response(200, 'Unlock Success', u'解锁成功')
    245
    -
    246
    -
    247
    -@logit
    248
    -def group_data_api(request):
    249
    -    """ 群组数据,评论数,点赞数 """
    250
    -    group_id = request.POST.get('group_id', '')
    251
    -
    252
    -    return response(200, 'Get Group Data Success', u'获取群组数据成功', {
    253
    -        'photo_datas': get_group_photo_data(group_id),
    254
    -    })
    255
    -
    256
    -
    257
    -@logit(body=settings.LOGIT_BODY_FLAG, res=settings.LOGIT_RES_FLAG)
    258
    -def flyimg_upload_api(request):
    259
    -    """ 飞图上传 """
    260
    -    group_id = request.POST.get('group_id', '')
    261
    -    user_id = request.POST.get('user_id', '')
    262
    -    nickname = request.POST.get('nickname', '')
    263
    -
    264
    -    photo = request.FILES.get('photo', '')
    265
    -
    266
    -    current_id = int(request.POST.get('current_id', -1))
    267
    -
    268
    -    # 用户校验
    269
    -    try:
    270
    -        user = UserInfo.objects.get(user_id=user_id)
    271
    -    except UserInfo.DoesNotExist:
    272
    -        return response(UserStatusCode.USER_NOT_FOUND)
    273
    -
    274
    -    # 群组用户校验
    275
    -    try:
    276
    -        group_user = GroupUserInfo.objects.get(group_id=group_id, user_id=user_id, user_status=GroupUserInfo.PASSED)
    277
    -    except GroupUserInfo.DoesNotExist:
    278
    -        return response(GroupUserStatusCode.GROUP_USER_NOT_FOUND)
    279
    -
    280
    -    if photo and upload_lock(group_id, user_id, photo):
    281
    -        photo_info = file_save(photo, prefix='fly', ext='.jpeg', thumbnail=True)
    282
    -
    283
    -        # 群组照片记录创建
    284
    -        group_photo, created = GroupPhotoInfo.objects.get_or_create(
    285
    -            group_id=group_id,
    286
    -            user_id=user_id,
    287
    -            photo_md5=photo_info.photo_md5,
    288
    -            defaults={
    289
    -                'nickname': nickname or user.final_nickname,
    290
    -                'avatar': user.avatar,
    291
    -                'photo_path': photo_info.photo_path,
    292
    -                'has_watermark': False,
    293
    -                'photo_w': photo_info.photo_w,
    294
    -                'photo_h': photo_info.photo_h,
    295
    -                'photo_thumbnail_path': photo_info.photo_thumbnail_path,
    296
    -                'photo_thumbnail_w': photo_info.photo_thumbnail_w,
    297
    -                'photo_thumbnail_h': photo_info.photo_thumbnail_h,
    298
    -                'photo_thumbnail2_path': photo_info.photo_thumbnail2_path,
    299
    -                'photo_thumbnail2_w': photo_info.photo_thumbnail2_w,
    300
    -                'photo_thumbnail2_h': photo_info.photo_thumbnail2_h,
    301
    -            }
    302
    -        )
    303
    -
    304
    -        if created:
    305
    -            # 设置群组最后一张照片PK
    306
    -            r.set(GROUP_LAST_PHOTO_PK % group_id, group_photo.pk)
    307
    -
    308
    -            # Redis 群组数据缓存
    309
    -            set_group_info_by_id(group_id)
    310
    -
    311
    -    curinfo = get_current_photos(group_id, user_id, max(current_id, group_user.current_id), request=request)
    312
    -
    313
    -    return response(200, 'Flyimg Upload Success', u'飞图上传成功', curinfo)
    314
    -
    315
    -
    316
    -@logit
    317
    -def flyimg_list_api(request):
    318
    -    """ 飞图列表 """
    319
    -    group_id = request.POST.get('group_id', '')
    320
    -    user_id = request.POST.get('user_id', '')
    321
    -    current_id = int(request.POST.get('current_id', -1))
    322
    -
    323
    -    # 群组用户校验
    324
    -    try:
    325
    -        group_user = GroupUserInfo.objects.get(group_id=group_id, user_id=user_id, user_status=GroupUserInfo.PASSED)
    326
    -    except GroupUserInfo.DoesNotExist:
    327
    -        return response(GroupUserStatusCode.GROUP_USER_NOT_FOUND)
    328
    -
    329
    -    curinfo = get_current_photos(group_id, user_id, max(current_id, group_user.current_id), request=request)
    330
    -
    331
    -    return response(200, 'Get Flyimg List Success', u'获取飞图上传成功', curinfo)
    332
    -
    333
    -
    334
    -@logit
    335
    -def flyimg_detail_api(request):
    336
    -    user_id = request.POST.get('user_id', '')
    337
    -    photo_id = request.POST.get('photo_id', '')
    338
    -
    339
    -    # 群组照片校验
    340
    -    try:
    341
    -        group_photo = GroupPhotoInfo.objects.get(photo_id=photo_id)
    342
    -    except GroupPhotoInfo.DoesNotExist:
    343
    -        return response(GroupPhotoStatusCode.GROUP_PHOTO_NOT_FOUND)
    344
    -
    345
    -    return response(200, 'Get Flyimg Detail Success', u'获取飞图详情成功', {
    346
    -        'photo_info': group_photo.photo_info(user_id),
    347
    -        'comments': get_group_photo_comment_list(photo_id),
    348
    -        'thumbup': get_group_photo_thumbup_flag(photo_id, user_id),  # user_id 是否点赞 photo_id
    349
    -        'thumbups': get_group_photo_thumbup_list(photo_id),  # 群组照片点赞列表
    350
    -    })
    351
    -
    352
    -
    353
    -@logit
    354
    -def comment_submit_api(request):
    355
    -    """ 飞图评论提交 """
    356
    -    group_id = request.POST.get('group_id', '')
    357
    -    user_id = request.POST.get('user_id', '')
    358
    -    to_uid = request.POST.get('to_uid', '')
    359
    -    photo_id = request.POST.get('photo_id', '')
    360
    -    comment = request.POST.get('comment', '')
    361
    -
    362
    -    # 群组用户校验
    363
    -    try:
    364
    -        group_user = GroupUserInfo.objects.get(group_id=group_id, user_id=user_id, user_status=GroupUserInfo.PASSED)
    365
    -    except GroupUserInfo.DoesNotExist:
    366
    -        return response(GroupUserStatusCode.GROUP_USER_NOT_FOUND)
    367
    -
    368
    -    # 群组照片校验
    369
    -    try:
    370
    -        group_photo = GroupPhotoInfo.objects.get(photo_id=photo_id)
    371
    -    except GroupPhotoInfo.DoesNotExist:
    372
    -        return response(GroupPhotoStatusCode.GROUP_PHOTO_NOT_FOUND)
    373
    -
    374
    -    # 评论内容校验
    375
    -    if not comment:
    376
    -        return response(GroupPhotoStatusCode.COMMENT_CONTENT_EMPTY)
    377
    -
    378
    -    # 群组照片评论记录创建
    379
    -    PhotoCommentInfo.objects.create(
    380
    -        photo_id=photo_id,
    381
    -        user_id=user_id,
    382
    -        nickname=group_user.nickname,
    383
    -        avatar=group_user.avatar,
    384
    -        to_uid=to_uid,
    385
    -        comment=comment,
    386
    -    )
    387
    -
    388
    -    # 群组照片评论数更新
    389
    -    group_photo.comment_num += 1
    390
    -    group_photo.save()
    391
    -
    392
    -    # Redis 群组照片数据缓存
    393
    -    set_group_photo_data(group_id)
    394
    -
    395
    -    # Redis 群组照片评论列表缓存刷新
    396
    -    set_group_photo_comment_list(photo_id)
    397
    -
    398
    -    r.sadd(GROUP_PHOTO_WATCHER_SET % photo_id, user_id)
    399
    -
    400
    -    # 判断群组照片发布者是否已经被管理员移除/主动退出,如若移除/退出,则不给发布者提醒
    401
    -    if r.sismember(GROUP_USERS_PASSED_SET % group_photo.group_id, group_photo.user_id):
    402
    -        UserMessageInfo.objects.create(
    403
    -            from_uid=user_id,
    404
    -            from_nickname=group_user.nickname,
    405
    -            from_avatar=group_user.avatar,
    406
    -            to_uid=group_photo.user_id,
    407
    -            group_id=group_photo.group_id,
    408
    -            photo_id=group_photo.photo_id,
    409
    -            msg_type=UserMessageInfo.COMMENT,
    410
    -            msg_title=u'评论',
    411
    -            msg_content=comment,
    412
    -        )
    413
    -
    414
    -    # 给所有关注者(评论/点赞)发送提醒,移除(评论/点赞)者和照片所有者
    415
    -    watchers = get_group_photo_watchers(photo_id, [user_id, group_photo.user_id])
    416
    -    for watcher in watchers:
    417
    -        UserMessageInfo.objects.create(
    418
    -            from_uid=user_id,
    419
    -            from_nickname=group_user.nickname,
    420
    -            from_avatar=group_user.avatar,
    421
    -            to_uid=watcher,
    422
    -            group_id=group_photo.group_id,
    423
    -            photo_id=group_photo.photo_id,
    424
    -            msg_type=UserMessageInfo.COMMENT,
    425
    -            msg_title=u'评论',
    426
    -            msg_content=comment,
    427
    -        )
    428
    -
    429
    -    return response(200, 'Comment Success', u'评论成功', {
    430
    -        'comments': get_group_photo_comment_list(photo_id),
    431
    -    })
    432
    -
    433
    -
    434
    -@logit
    435
    -def comment_list_api(request):
    436
    -    """ 飞图评论列表 """
    437
    -    photo_id = request.POST.get('photo_id', '')
    438
    -
    439
    -    # 群组照片校验
    440
    -    if not GroupPhotoInfo.objects.filter(photo_id=photo_id).exists():
    441
    -        return response(GroupPhotoStatusCode.GROUP_PHOTO_NOT_FOUND)
    442
    -
    443
    -    return response(200, 'Get Comment List Success', u'获取评论列表成功', {
    444
    -        'comments': get_group_photo_comment_list(photo_id),
    445
    -    })
    446
    -
    447
    -
    448
    -@logit
    449
    -def thumbup_submit_api(request):
    450
    -    """ 飞图点赞提交 """
    451
    -    group_id = request.POST.get('group_id', '')
    452
    -    user_id = request.POST.get('user_id', '')
    453
    -    photo_id = request.POST.get('photo_id', '')
    454
    -
    455
    -    # 群组用户校验
    456
    -    try:
    457
    -        group_user = GroupUserInfo.objects.get(group_id=group_id, user_id=user_id, user_status=GroupUserInfo.PASSED)
    458
    -    except GroupUserInfo.DoesNotExist:
    459
    -        return response(GroupUserStatusCode.GROUP_USER_NOT_FOUND)
    460
    -
    461
    -    # 群组照片校验
    462
    -    try:
    463
    -        group_photo = GroupPhotoInfo.objects.get(photo_id=photo_id)
    464
    -    except GroupPhotoInfo.DoesNotExist:
    465
    -        return response(GroupPhotoStatusCode.GROUP_PHOTO_NOT_FOUND)
    466
    -
    467
    -    # user_id 是否点赞 photo_id
    468
    -    if get_group_photo_thumbup_flag(photo_id, user_id):
    469
    -        return response(GroupPhotoStatusCode.DUPLICATE_THUMB_UP)
    470
    -
    471
    -    # 群组照片点赞记录创建/更新
    472
    -    photo_thumbup, created = PhotoThumbUpInfo.objects.get_or_create(
    473
    -        photo_id=photo_id,
    474
    -        user_id=user_id,
    475
    -    )
    476
    -    photo_thumbup.nickname = group_user.nickname
    477
    -    photo_thumbup.avatar = group_user.avatar
    478
    -    photo_thumbup.thumbup = True
    479
    -    photo_thumbup.save()
    480
    -
    481
    -    # Redis 群组照片点赞数据缓存
    482
    -    set_group_photo_thumbup_flag(photo_id, user_id)
    483
    -
    484
    -    # 群组照片点赞数更新
    485
    -    group_photo.thumbup_num += 1
    486
    -    group_photo.save()
    487
    -
    488
    -    # Redis 群组照片数据缓存
    489
    -    set_group_photo_data(group_id)
    490
    -
    491
    -    # Redis 群组照片点赞列表缓存刷新
    492
    -    set_group_photo_thumbup_list(photo_id)
    493
    -
    494
    -    r.sadd(GROUP_PHOTO_WATCHER_SET % photo_id, user_id)
    495
    -
    496
    -    # 判断群组照片发布者是否已经被管理员移除/主动退出,如若移除/退出,则不给发布者提醒
    497
    -    if r.sismember(GROUP_USERS_PASSED_SET % group_photo.group_id, group_photo.user_id):
    498
    -        UserMessageInfo.objects.create(
    499
    -            from_uid=user_id,
    500
    -            from_nickname=group_user.nickname,
    501
    -            from_avatar=group_user.avatar,
    502
    -            to_uid=group_photo.user_id,
    503
    -            group_id=group_photo.group_id,
    504
    -            photo_id=group_photo.photo_id,
    505
    -            msg_type=UserMessageInfo.THUMBUP,
    506
    -            msg_title=u'点赞',
    507
    -            msg_content=u'点赞',
    508
    -        )
    509
    -
    510
    -    # 给所有关注者(评论/点赞)发送提醒,移除(评论/点赞)者和照片所有者
    511
    -    watchers = get_group_photo_watchers(photo_id, [user_id, group_photo.user_id])
    512
    -    for watcher in watchers:
    513
    -        UserMessageInfo.objects.create(
    514
    -            from_uid=user_id,
    515
    -            from_nickname=group_user.nickname,
    516
    -            from_avatar=group_user.avatar,
    517
    -            to_uid=watcher,
    518
    -            group_id=group_photo.group_id,
    519
    -            photo_id=group_photo.photo_id,
    520
    -            msg_type=UserMessageInfo.THUMBUP,
    521
    -            msg_title=u'点赞',
    522
    -            msg_content=u'点赞',
    523
    -        )
    524
    -
    525
    -    return response(200, 'Thumbup Success', u'点赞提交成功', {
    526
    -        'thumbup': True,
    527
    -        'thumbups': get_group_photo_thumbup_list(photo_id),
    528
    -    })
    529
    -
    530
    -
    531
    -@logit
    532
    -def thumbup_list_api(request):
    533
    -    """ 飞图点赞列表 """
    534
    -    user_id = request.POST.get('user_id', '')
    535
    -    photo_id = request.POST.get('photo_id', '')
    536
    -
    537
    -    return response(200, 'Get Thumbup List Success', u'获取点赞列表成功', {
    538
    -        'thumbup': get_group_photo_thumbup_flag(photo_id, user_id),  # user_id 是否点赞 photo_id
    539
    -        'thumbups': get_group_photo_thumbup_list(photo_id),  # 群组照片点赞列表
    540
    -    })
    541
    -
    542
    -
    543
    -@logit
    544
    -def thumbup_cancel_api(request):
    545
    -    """ 飞图点赞取消 """
    546
    -    group_id = request.POST.get('group_id', '')
    547
    -    user_id = request.POST.get('user_id', '')
    548
    -    photo_id = request.POST.get('photo_id', '')
    549
    -
    550
    -    # 群组用户校验
    551
    -    try:
    552
    -        group_user = GroupUserInfo.objects.get(group_id=group_id, user_id=user_id, user_status=GroupUserInfo.PASSED)
    553
    -    except GroupUserInfo.DoesNotExist:
    554
    -        return response(GroupUserStatusCode.GROUP_USER_NOT_FOUND)
    555
    -
    556
    -    # 群组照片校验
    557
    -    try:
    558
    -        group_photo = GroupPhotoInfo.objects.get(photo_id=photo_id)
    559
    -    except GroupPhotoInfo.DoesNotExist:
    560
    -        return response(GroupPhotoStatusCode.GROUP_PHOTO_NOT_FOUND)
    561
    -
    562
    -    # user_id 是否点赞 photo_id
    563
    -    if not get_group_photo_thumbup_flag(photo_id, user_id):
    564
    -        return response(GroupPhotoStatusCode.THUMB_UP_NOT_FOUND)
    565
    -
    566
    -    # 群组照片点赞取消
    567
    -    photo_thumbup, created = PhotoThumbUpInfo.objects.get_or_create(
    568
    -        photo_id=photo_id,
    569
    -        user_id=user_id,
    570
    -    )
    571
    -    photo_thumbup.thumbup = False
    572
    -    photo_thumbup.save()
    573
    -
    574
    -    # Redis 群组照片点赞数据移除
    575
    -    del_group_photo_thumbup_flag(photo_id, user_id)
    576
    -
    577
    -    # 群组照片点赞数更新
    578
    -    group_photo.thumbup_num -= 1
    579
    -    group_photo.save()
    580
    -
    581
    -    # Redis 群组照片数据缓存
    582
    -    set_group_photo_data(group_id)
    583
    -
    584
    -    # Redis 群组照片点赞列表缓存刷新
    585
    -    set_group_photo_thumbup_list(photo_id)
    586
    -
    587
    -    # 判断群组照片发布者是否已经被管理员移除/主动退出,如若移除/退出,则不给发布者提醒
    588
    -    if r.sismember(GROUP_USERS_PASSED_SET % group_photo.group_id, group_photo.user_id):
    589
    -        UserMessageInfo.objects.create(
    590
    -            from_uid=user_id,
    591
    -            from_nickname=group_user.nickname,
    592
    -            from_avatar=group_user.avatar,
    593
    -            to_uid=group_photo.user_id,
    594
    -            group_id=group_photo.group_id,
    595
    -            photo_id=group_photo.photo_id,
    596
    -            msg_type=UserMessageInfo.THUMBUP,
    597
    -            msg_title=u'取消点赞',
    598
    -            msg_content=u'取消点赞',
    599
    -        )
    600
    -
    601
    -    # 群组照片点赞列表
    602
    -    photo_thumbups = PhotoThumbUpInfo.objects.filter(photo_id=photo_id, thumbup=True, status=True)
    603
    -
    604
    -    return response(200, 'Thumbup Cancel Success', u'点赞取消成功', {
    605
    -        'thumbup': False,
    606
    -        'thumbups': [thumbup.thumbup_info for thumbup in photo_thumbups],
    607
    -    })
    608
    -
    609
    -
    610
    -@logit
    611
    -def kodo_home_api(request):
    612
    -    """ 首页照片信息 """
    613
    -    user_id = request.POST.get('user_id', '')
    614
    -    page = int(request.POST.get('page', 1))
    615
    -    num = int(request.POST.get('num', settings.PAI2_HOME_PER_PAGE))
    616
    -
    617
    -    # 执行原生 SQL 语句,获取首页照片列表
    618
    -    cursor = connection.cursor()
    619
    -    cursor.execute((PAI2_HOME_WX_API if request.weixin else PAI2_HOME_API).format(
    620
    -        user_id=user_id,
    621
    -        offset=0,
    622
    -        rows=settings.PAI2_HOME_MAX_ROWS,
    623
    -    ))
    624
    -    rows = cursor.fetchall()
    625
    -
    626
    -    # 首页照片分页
    627
    -    rows, left = pagination(rows, page, num)
    628
    -
    629
    -    # 首页照片信息
    630
    -    rows = [{
    631
    -        'group_id': row[0],
    632
    -        'group_name': row[1],
    633
    -        'group_default_avatar': row[2],
    634
    -        'group_avatar': row[3],
    635
    -        'group_from': row[4],
    636
    -        'photo_id': row[5],
    637
    -        'photo_url': qiniu_file_url(row[6], bucket='watermark' if row[7] else 'photo'),
    638
    -        'photo_w': row[8],
    639
    -        'photo_h': row[9],
    640
    -        'photo_thumbnail_url': qiniu_file_url(row[10], bucket='thumbnail'),
    641
    -        'photo_thumbnail_w': row[11],
    642
    -        'photo_thumbnail_h': row[12],
    643
    -        'photo_thumbnail2_url': qiniu_file_url(row[13], bucket='thumbnail2'),
    644
    -        'photo_thumbnail2_w': row[14],
    645
    -        'photo_thumbnail2_h': row[15],
    646
    -        'photo_share_url': share_url(row[5]),  # Warning: Index of This Line is 5
    647
    -        'user_id': row[16],
    648
    -        'nickname': row[17],
    649
    -        'avatar': row[18],
    650
    -        'comment_num': row[19],
    651
    -        'thumbup_num': row[20],
    652
    -        'photo_from': row[21],
    653
    -        'session_id': row[22],
    654
    -        'nomark': row[23],
    655
    -        'origin': row[24],
    656
    -        'created_at': row[25],
    657
    -        'origin_expired_stamps': origin_expired_stamps(row[25], row[16]),
    658
    -        'thumbup': get_group_photo_thumbup_flag(row[5], user_id),
    659
    -        'porder': get_lensman_order_record(row[5], user_id) if row[21] == GroupPhotoInfo.SESSION_GROUP else {},
    660
    -        'display_payment_btn': row[21] == GroupPhotoInfo.SESSION_GROUP and row[26] not in [GroupPhotoInfo.OUTTAKE],
    661
    -    } for row in rows]
    662
    -
    663
    -    return response(200, 'Get Home Data Success', u'获取首页数据成功', {
    664
    -        'photos': rows,
    665
    -        'left': left,
    666
    -    })
    667
    -
    668
    -
    669
    -@logit
    670
    -def lensman_photo_price(request):
    671
    -    """ 摄影师照片价格获取 """
    672
    -    user_id = request.POST.get('user_id', '')
    673
    -    photo_id = request.POST.get('photo_id', '')
    674
    -    photo_type = request.POST.get('photo_type', 'nomark')  # nomark for 去除水印, origin for 获取高清图
    675
    -
    676
    -    # 群组照片校验
    677
    -    try:
    678
    -        group_photo = GroupPhotoInfo.objects.get(photo_id=photo_id)
    679
    -    except GroupPhotoInfo.DoesNotExist:
    680
    -        return response(GroupPhotoStatusCode.GROUP_PHOTO_NOT_FOUND)
    681
    -
    682
    -    return response(200, 'Get Price Success', u'获取价格成功', {
    683
    -        'price': get_group_photo_price(group_photo, photo_type)
    684
    -    })
    685
    -
    686
    -
    687
    -@logit
    688
    -def lensman_photo_bought(request):
    689
    -    """ 摄影师照片已购买 """
    690
    -    user_id = request.POST.get('user_id', '')
    691
    -    photo_id = request.POST.get('photo_id', '')
    692
    -
    693
    -    return response(200, 'Get Bought Data Success', u'获取购买数据成功', {
    694
    -        'porder': get_lensman_order_record(photo_id, user_id)
    695
    -    })
    696
    -
    697
    -
    698
    -class GroupInfoViewSet(viewsets.ModelViewSet):
    699
    -    queryset = GroupInfo.objects.all().order_by('-pk')
    700
    -    serializer_class = GroupInfoSerializer
    701
    -
    702
    -
    703
    -class GroupUserInfoViewSet(viewsets.ModelViewSet):
    704
    -    queryset = GroupUserInfo.objects.all().order_by('-pk')
    705
    -    serializer_class = GroupUserInfoSerializer
    706
    -
    707
    -
    708
    -class GroupPhotoInfoViewSet(viewsets.ModelViewSet):
    709
    -    queryset = GroupPhotoInfo.objects.all().order_by('-pk')
    710
    -    serializer_class = GroupPhotoInfoSerializer

    + 0 - 5
    kodo/settings.py

    @@ -53,22 +53,17 @@ INSTALLED_APPS = (
    53 53
         'simditor',
    54 54
         'api',
    55 55
         'account',
    56
    -    'box',
    57 56
         'commands',
    58 57
         'coupon',
    59
    -    'group',
    60 58
         'guideline',
    61 59
         'integral',
    62 60
         'logs',
    63 61
         'marketcode',
    64 62
         'mch',
    65 63
         'member',
    66
    -    'message',
    67 64
         'miniapp',
    68 65
         'operation',
    69 66
         'page',
    70
    -    'pay',
    71
    -    'photo',
    72 67
         'pre',
    73 68
         'sales',
    74 69
         'server',

    + 0 - 46
    kodo/urls.py

    @@ -22,59 +22,13 @@ from django.contrib import admin
    22 22
     from rest_framework import routers
    23 23
     
    24 24
     from account import views as account_views
    25
    -from group import grouppage_views
    26
    -from group import views as group_views
    27 25
     from miniapp import views as mini_views
    28
    -from photo import views as photo_views
    29 26
     from website import views as website_views
    30 27
     
    31
    -
    32
    -# router = routers.DefaultRouter()
    33
    -# # router.register(r'users', account_views.UserViewSet)
    34
    -# # router.register(r'groups', account_views.GroupViewSet)
    35
    -#
    36
    -# router.register(r'lensmans', account_views.LensmanInfoViewSet)
    37
    -# router.register(r'users', account_views.UserInfoViewSet)
    38
    -#
    39
    -# router.register(r'groups', group_views.GroupInfoViewSet)
    40
    -# router.register(r'group_users', group_views.GroupUserInfoViewSet)
    41
    -# router.register(r'group_photos', group_views.GroupPhotoInfoViewSet)
    42
    -#
    43
    -# router.register(r'photos', photo_views.PhotoInfoViewSet)
    44
    -
    45 28
     urlpatterns = [
    46 29
         url(r'^kodoadmin/', admin.site.urls),
    47 30
     ]
    48 31
     
    49
    -# urlpatterns += [
    50
    -#     # url(r'^api/', include('api.urls', namespace='api')),
    51
    -#     url(r'^s/(?P<session_id>\w+)$', photo_views.session_detail, name='session_detail'),  # Session 详情
    52
    -#     url(r'^p/(?P<photo_id>\w+)$', photo_views.photo_standard, name='photo_standard'),  # standard thumbnail, available for free
    53
    -#     url(r'^m/(?P<photo_id>\w+)$', photo_views.photo_medium, name='photo_medium'),  # medium/mobile version, without watermark, login or paid by others
    54
    -#     url(r'^l/(?P<photo_id>\w+)$', photo_views.photo_large, name='photo_large'),  # large, might support server side panning later, login required
    55
    -#     url(r'^r/(?P<photo_id>\w+)$', photo_views.photo_raw, name='photo_raw'),  # raw image, only for finishers
    56
    -# ]
    57
    -#
    58
    -# urlpatterns += [
    59
    -#     url(r'^g/(?P<group_id>\w+)$', grouppage_views.group_detail, name='group_detail'),  # 群组详情(拍爱用户端下载页)
    60
    -# ]
    61
    -#
    62
    -# urlpatterns += [
    63
    -#     url(r'^gp/(?P<photo_id>\w+)$', grouppage_views.group_photo_detail, name='group_photo_detail'),  # 群组照片详情
    64
    -# ]
    65
    -#
    66
    -# urlpatterns += [
    67
    -#     url(r'^tg/(?P<admin_id>\w+)$', grouppage_views.tgu_group_detail, name='tgu_group_detail'),  # 旅行团详情(拍爱导游端下载页)
    68
    -# ]
    69
    -#
    70
    -# urlpatterns += [
    71
    -#     url(r'^tgu/(?P<admin_id>\w+)$', grouppage_views.tgu_group_user_detail, name='tgu_group_user_detail'),  # 旅行团成员详情(拍爱用户端下载页)
    72
    -# ]
    73
    -#
    74
    -# urlpatterns += [
    75
    -#     url(r'^$', website_views.kodo_home, name='kodo_home'),  # 官网首页
    76
    -# ]
    77
    -
    78 32
     # Mini App
    79 33
     urlpatterns += [
    80 34
         url(r'^mini/userinfo$', mini_views.get_userinfo_api, name='get_userinfo_api2'),  # 获取用户信息

    + 0 - 0
    message/__init__.py


    + 0 - 4
    message/admin.py

    @@ -1,4 +0,0 @@
    1
    -from django.contrib import admin
    2
    -
    3
    -
    4
    -# Register your models here.

    + 0 - 36
    message/migrations/0001_initial.py

    @@ -1,36 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -from __future__ import unicode_literals
    3
    -
    4
    -from django.db import models, migrations
    5
    -
    6
    -
    7
    -class Migration(migrations.Migration):
    8
    -
    9
    -    dependencies = [
    10
    -    ]
    11
    -
    12
    -    operations = [
    13
    -        migrations.CreateModel(
    14
    -            name='UserMessageInfo',
    15
    -            fields=[
    16
    -                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
    17
    -                ('status', models.BooleanField(default=True, help_text='\u72b6\u6001', verbose_name='status')),
    18
    -                ('created_at', models.DateTimeField(help_text='\u521b\u5efa\u65f6\u95f4', verbose_name='created_at', auto_now_add=True)),
    19
    -                ('updated_at', models.DateTimeField(help_text='\u66f4\u65b0\u65f6\u95f4', verbose_name='updated_at', auto_now=True)),
    20
    -                ('from_uid', models.CharField(max_length=255, blank=True, help_text='\u53d1\u9001\u6d88\u606f\u7528\u6237\u552f\u4e00\u6807\u8bc6', null=True, verbose_name='from_uid', db_index=True)),
    21
    -                ('from_nickname', models.CharField(help_text='\u53d1\u9001\u6d88\u606f\u7528\u6237\u6635\u79f0', max_length=255, null=True, verbose_name='from_nickname', blank=True)),
    22
    -                ('from_avatar', models.CharField(help_text='\u53d1\u9001\u6d88\u606f\u7528\u6237\u5934\u50cf', max_length=255, null=True, verbose_name='from_avatar', blank=True)),
    23
    -                ('to_uid', models.CharField(max_length=255, blank=True, help_text='\u63a5\u6536\u6d88\u606f\u7528\u6237\u552f\u4e00\u6807\u8bc6', null=True, verbose_name='to_uid', db_index=True)),
    24
    -                ('group_id', models.CharField(help_text='\u7fa4\u7ec4\u552f\u4e00\u6807\u8bc6', max_length=255, null=True, verbose_name='group_id', blank=True)),
    25
    -                ('photo_id', models.CharField(help_text='\u98de\u56fe\u552f\u4e00\u6807\u8bc6', max_length=255, null=True, verbose_name='photo_id', blank=True)),
    26
    -                ('msg_type', models.CharField(default=b'system', help_text='\u6d88\u606f\u7c7b\u578b', max_length=255, verbose_name='msg_type', db_index=True)),
    27
    -                ('msg_title', models.CharField(help_text='\u6d88\u606f\u6807\u9898', max_length=255, null=True, verbose_name='msg_title', blank=True)),
    28
    -                ('msg_content', models.TextField(help_text='\u6d88\u606f\u5185\u5bb9', null=True, verbose_name='msg_content', blank=True)),
    29
    -                ('read', models.BooleanField(default=False, help_text='\u6d88\u606f\u662f\u5426\u5df2\u8bfb', verbose_name='read')),
    30
    -            ],
    31
    -            options={
    32
    -                'verbose_name': 'usermessageinfo',
    33
    -                'verbose_name_plural': 'usermessageinfo',
    34
    -            },
    35
    -        ),
    36
    -    ]

    + 0 - 19
    message/migrations/0002_auto_20160120_1830.py

    @@ -1,19 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -from __future__ import unicode_literals
    3
    -
    4
    -from django.db import models, migrations
    5
    -
    6
    -
    7
    -class Migration(migrations.Migration):
    8
    -
    9
    -    dependencies = [
    10
    -        ('message', '0001_initial'),
    11
    -    ]
    12
    -
    13
    -    operations = [
    14
    -        migrations.AlterField(
    15
    -            model_name='usermessageinfo',
    16
    -            name='status',
    17
    -            field=models.BooleanField(default=True, help_text='\u72b6\u6001', db_index=True, verbose_name='status'),
    18
    -        ),
    19
    -    ]

    + 0 - 45
    message/migrations/0003_systemmessageinfo_systemmessagereadinfo.py

    @@ -1,45 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -from __future__ import unicode_literals
    3
    -
    4
    -from django.db import models, migrations
    5
    -
    6
    -
    7
    -class Migration(migrations.Migration):
    8
    -
    9
    -    dependencies = [
    10
    -        ('message', '0002_auto_20160120_1830'),
    11
    -    ]
    12
    -
    13
    -    operations = [
    14
    -        migrations.CreateModel(
    15
    -            name='SystemMessageInfo',
    16
    -            fields=[
    17
    -                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
    18
    -                ('status', models.BooleanField(default=True, help_text='\u72b6\u6001', db_index=True, verbose_name='status')),
    19
    -                ('created_at', models.DateTimeField(help_text='\u521b\u5efa\u65f6\u95f4', verbose_name='created_at', auto_now_add=True)),
    20
    -                ('updated_at', models.DateTimeField(help_text='\u66f4\u65b0\u65f6\u95f4', verbose_name='updated_at', auto_now=True)),
    21
    -                ('title', models.CharField(help_text='\u7cfb\u7edf\u6d88\u606f\u6807\u9898', max_length=255, verbose_name='title')),
    22
    -                ('content', models.TextField(help_text='\u7cfb\u7edf\u6d88\u606f\u5185\u5bb9', null=True, verbose_name='content', blank=True)),
    23
    -                ('url', models.CharField(help_text='\u7cfb\u7edf\u6d88\u606f\u94fe\u63a5', max_length=255, null=True, verbose_name='url', blank=True)),
    24
    -            ],
    25
    -            options={
    26
    -                'verbose_name': 'systemmessageinfo',
    27
    -                'verbose_name_plural': 'systemmessageinfo',
    28
    -            },
    29
    -        ),
    30
    -        migrations.CreateModel(
    31
    -            name='SystemMessageReadInfo',
    32
    -            fields=[
    33
    -                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
    34
    -                ('status', models.BooleanField(default=True, help_text='\u72b6\u6001', db_index=True, verbose_name='status')),
    35
    -                ('created_at', models.DateTimeField(help_text='\u521b\u5efa\u65f6\u95f4', verbose_name='created_at', auto_now_add=True)),
    36
    -                ('updated_at', models.DateTimeField(help_text='\u66f4\u65b0\u65f6\u95f4', verbose_name='updated_at', auto_now=True)),
    37
    -                ('user_id', models.CharField(max_length=255, blank=True, help_text='\u7528\u6237\u552f\u4e00\u6807\u8bc6', null=True, verbose_name='user_id', db_index=True)),
    38
    -                ('msg_id', models.CharField(max_length=255, blank=True, help_text='\u7cfb\u7edf\u6d88\u606f\u552f\u4e00\u6807\u8bc6', null=True, verbose_name='msg_id', db_index=True)),
    39
    -            ],
    40
    -            options={
    41
    -                'verbose_name': 'systemmessagereadinfo',
    42
    -                'verbose_name_plural': 'systemmessagereadinfo',
    43
    -            },
    44
    -        ),
    45
    -    ]

    + 0 - 29
    message/migrations/0004_systemmessagedeleteinfo.py

    @@ -1,29 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -from __future__ import unicode_literals
    3
    -
    4
    -from django.db import models, migrations
    5
    -
    6
    -
    7
    -class Migration(migrations.Migration):
    8
    -
    9
    -    dependencies = [
    10
    -        ('message', '0003_systemmessageinfo_systemmessagereadinfo'),
    11
    -    ]
    12
    -
    13
    -    operations = [
    14
    -        migrations.CreateModel(
    15
    -            name='SystemMessageDeleteInfo',
    16
    -            fields=[
    17
    -                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
    18
    -                ('status', models.BooleanField(default=True, help_text='\u72b6\u6001', db_index=True, verbose_name='status')),
    19
    -                ('created_at', models.DateTimeField(help_text='\u521b\u5efa\u65f6\u95f4', verbose_name='created_at', auto_now_add=True)),
    20
    -                ('updated_at', models.DateTimeField(help_text='\u66f4\u65b0\u65f6\u95f4', verbose_name='updated_at', auto_now=True)),
    21
    -                ('user_id', models.CharField(max_length=255, blank=True, help_text='\u7528\u6237\u552f\u4e00\u6807\u8bc6', null=True, verbose_name='user_id', db_index=True)),
    22
    -                ('msg_id', models.CharField(max_length=255, blank=True, help_text='\u7cfb\u7edf\u6d88\u606f\u552f\u4e00\u6807\u8bc6', null=True, verbose_name='msg_id', db_index=True)),
    23
    -            ],
    24
    -            options={
    25
    -                'verbose_name': 'systemmessagedeleteinfo',
    26
    -                'verbose_name_plural': 'systemmessagedeleteinfo',
    27
    -            },
    28
    -        ),
    29
    -    ]

    + 0 - 24
    message/migrations/0005_auto_20160422_1322.py

    @@ -1,24 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -from __future__ import unicode_literals
    3
    -
    4
    -from django.db import models, migrations
    5
    -
    6
    -
    7
    -class Migration(migrations.Migration):
    8
    -
    9
    -    dependencies = [
    10
    -        ('message', '0004_systemmessagedeleteinfo'),
    11
    -    ]
    12
    -
    13
    -    operations = [
    14
    -        migrations.AlterField(
    15
    -            model_name='usermessageinfo',
    16
    -            name='group_id',
    17
    -            field=models.CharField(max_length=255, blank=True, help_text='\u7fa4\u7ec4\u552f\u4e00\u6807\u8bc6', null=True, verbose_name='group_id', db_index=True),
    18
    -        ),
    19
    -        migrations.AlterField(
    20
    -            model_name='usermessageinfo',
    21
    -            name='photo_id',
    22
    -            field=models.CharField(max_length=255, blank=True, help_text='\u98de\u56fe\u552f\u4e00\u6807\u8bc6', null=True, verbose_name='photo_id', db_index=True),
    23
    -        ),
    24
    -    ]

    + 0 - 19
    message/migrations/0006_systemmessageinfo_src.py

    @@ -1,19 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -from __future__ import unicode_literals
    3
    -
    4
    -from django.db import models, migrations
    5
    -
    6
    -
    7
    -class Migration(migrations.Migration):
    8
    -
    9
    -    dependencies = [
    10
    -        ('message', '0005_auto_20160422_1322'),
    11
    -    ]
    12
    -
    13
    -    operations = [
    14
    -        migrations.AddField(
    15
    -            model_name='systemmessageinfo',
    16
    -            name='src',
    17
    -            field=models.IntegerField(default=0, help_text='\u7cfb\u7edf\u6d88\u606f\u7c7b\u522b', verbose_name='src', choices=[(0, '\u62cd\u7231\u7528\u6237\u7aef'), (1, '\u62cd\u7231\u6444\u5f71\u5e08\u7aef')]),
    18
    -        ),
    19
    -    ]

    + 0 - 19
    message/migrations/0007_auto_20160907_1740.py

    @@ -1,19 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -from __future__ import unicode_literals
    3
    -
    4
    -from django.db import models, migrations
    5
    -
    6
    -
    7
    -class Migration(migrations.Migration):
    8
    -
    9
    -    dependencies = [
    10
    -        ('message', '0006_systemmessageinfo_src'),
    11
    -    ]
    12
    -
    13
    -    operations = [
    14
    -        migrations.AlterField(
    15
    -            model_name='systemmessageinfo',
    16
    -            name='src',
    17
    -            field=models.IntegerField(default=0, help_text='\u7cfb\u7edf\u6d88\u606f\u7c7b\u522b', db_index=True, verbose_name='src', choices=[(0, '\u62cd\u7231\u7528\u6237\u7aef'), (1, '\u62cd\u7231\u6444\u5f71\u5e08\u7aef')]),
    18
    -        ),
    19
    -    ]

    + 0 - 19
    message/migrations/0008_auto_20170315_2243.py

    @@ -1,19 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -from __future__ import unicode_literals
    3
    -
    4
    -from django.db import models, migrations
    5
    -
    6
    -
    7
    -class Migration(migrations.Migration):
    8
    -
    9
    -    dependencies = [
    10
    -        ('message', '0007_auto_20160907_1740'),
    11
    -    ]
    12
    -
    13
    -    operations = [
    14
    -        migrations.AlterField(
    15
    -            model_name='systemmessageinfo',
    16
    -            name='src',
    17
    -            field=models.IntegerField(default=0, help_text='\u6765\u6e90', db_index=True, verbose_name='src', choices=[(0, '\u62cd\u7231\u7528\u6237\u7aef'), (1, '\u62cd\u7231\u6444\u5f71\u5e08\u7aef'), (2, '\u62cd\u7231\u5bfc\u6e38\u7aef')]),
    18
    -        ),
    19
    -    ]

    + 0 - 20
    message/migrations/0009_auto_20170814_2001.py

    @@ -1,20 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -# Generated by Django 1.11.3 on 2017-08-14 12:01
    3
    -from __future__ import unicode_literals
    4
    -
    5
    -from django.db import migrations, models
    6
    -
    7
    -
    8
    -class Migration(migrations.Migration):
    9
    -
    10
    -    dependencies = [
    11
    -        ('message', '0008_auto_20170315_2243'),
    12
    -    ]
    13
    -
    14
    -    operations = [
    15
    -        migrations.AlterField(
    16
    -            model_name='systemmessageinfo',
    17
    -            name='src',
    18
    -            field=models.IntegerField(choices=[(0, '\u62cd\u7231\u7528\u6237\u7aef'), (1, '\u62cd\u7231\u6444\u5f71\u5e08\u7aef'), (1, '\u62cd\u7231\u6444\u5f71\u5e08\u7aef2'), (2, '\u62cd\u7231\u5bfc\u6e38\u7aef')], db_index=True, default=0, help_text='\u6765\u6e90', verbose_name='src'),
    19
    -        ),
    20
    -    ]

    + 0 - 20
    message/migrations/0010_auto_20170814_2004.py

    @@ -1,20 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -# Generated by Django 1.11.3 on 2017-08-14 12:04
    3
    -from __future__ import unicode_literals
    4
    -
    5
    -from django.db import migrations, models
    6
    -
    7
    -
    8
    -class Migration(migrations.Migration):
    9
    -
    10
    -    dependencies = [
    11
    -        ('message', '0009_auto_20170814_2001'),
    12
    -    ]
    13
    -
    14
    -    operations = [
    15
    -        migrations.AlterField(
    16
    -            model_name='systemmessageinfo',
    17
    -            name='src',
    18
    -            field=models.IntegerField(choices=[(0, '\u62cd\u7231\u7528\u6237\u7aef'), (1, '\u62cd\u7231\u6444\u5f71\u5e08\u7aef'), (10, '\u62cd\u7231\u6444\u5f71\u5e08\u7aef2'), (2, '\u62cd\u7231\u5bfc\u6e38\u7aef')], db_index=True, default=0, help_text='\u6765\u6e90', verbose_name='src'),
    19
    -        ),
    20
    -    ]

    + 0 - 23
    message/migrations/0011_auto_20170821_1615.py

    @@ -1,23 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -# Generated by Django 1.11.3 on 2017-08-21 08:15
    3
    -from __future__ import unicode_literals
    4
    -
    5
    -from django.db import migrations
    6
    -
    7
    -
    8
    -class Migration(migrations.Migration):
    9
    -
    10
    -    dependencies = [
    11
    -        ('message', '0010_auto_20170814_2004'),
    12
    -    ]
    13
    -
    14
    -    operations = [
    15
    -        migrations.AlterUniqueTogether(
    16
    -            name='systemmessagedeleteinfo',
    17
    -            unique_together=set([('user_id', 'msg_id')]),
    18
    -        ),
    19
    -        migrations.AlterUniqueTogether(
    20
    -            name='systemmessagereadinfo',
    21
    -            unique_together=set([('user_id', 'msg_id')]),
    22
    -        ),
    23
    -    ]

    + 0 - 75
    message/migrations/0012_auto_20180101_2220.py

    @@ -1,75 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -# Generated by Django 1.11.3 on 2018-01-01 14:20
    3
    -from __future__ import unicode_literals
    4
    -
    5
    -from django.db import migrations, models
    6
    -
    7
    -
    8
    -class Migration(migrations.Migration):
    9
    -
    10
    -    dependencies = [
    11
    -        ('message', '0011_auto_20170821_1615'),
    12
    -    ]
    13
    -
    14
    -    operations = [
    15
    -        migrations.AlterField(
    16
    -            model_name='systemmessagedeleteinfo',
    17
    -            name='created_at',
    18
    -            field=models.DateTimeField(auto_now_add=True, help_text='Create Time', verbose_name='created_at'),
    19
    -        ),
    20
    -        migrations.AlterField(
    21
    -            model_name='systemmessagedeleteinfo',
    22
    -            name='status',
    23
    -            field=models.BooleanField(db_index=True, default=True, help_text='Status', verbose_name='status'),
    24
    -        ),
    25
    -        migrations.AlterField(
    26
    -            model_name='systemmessagedeleteinfo',
    27
    -            name='updated_at',
    28
    -            field=models.DateTimeField(auto_now=True, help_text='Update Time', verbose_name='updated_at'),
    29
    -        ),
    30
    -        migrations.AlterField(
    31
    -            model_name='systemmessageinfo',
    32
    -            name='created_at',
    33
    -            field=models.DateTimeField(auto_now_add=True, help_text='Create Time', verbose_name='created_at'),
    34
    -        ),
    35
    -        migrations.AlterField(
    36
    -            model_name='systemmessageinfo',
    37
    -            name='status',
    38
    -            field=models.BooleanField(db_index=True, default=True, help_text='Status', verbose_name='status'),
    39
    -        ),
    40
    -        migrations.AlterField(
    41
    -            model_name='systemmessageinfo',
    42
    -            name='updated_at',
    43
    -            field=models.DateTimeField(auto_now=True, help_text='Update Time', verbose_name='updated_at'),
    44
    -        ),
    45
    -        migrations.AlterField(
    46
    -            model_name='systemmessagereadinfo',
    47
    -            name='created_at',
    48
    -            field=models.DateTimeField(auto_now_add=True, help_text='Create Time', verbose_name='created_at'),
    49
    -        ),
    50
    -        migrations.AlterField(
    51
    -            model_name='systemmessagereadinfo',
    52
    -            name='status',
    53
    -            field=models.BooleanField(db_index=True, default=True, help_text='Status', verbose_name='status'),
    54
    -        ),
    55
    -        migrations.AlterField(
    56
    -            model_name='systemmessagereadinfo',
    57
    -            name='updated_at',
    58
    -            field=models.DateTimeField(auto_now=True, help_text='Update Time', verbose_name='updated_at'),
    59
    -        ),
    60
    -        migrations.AlterField(
    61
    -            model_name='usermessageinfo',
    62
    -            name='created_at',
    63
    -            field=models.DateTimeField(auto_now_add=True, help_text='Create Time', verbose_name='created_at'),
    64
    -        ),
    65
    -        migrations.AlterField(
    66
    -            model_name='usermessageinfo',
    67
    -            name='status',
    68
    -            field=models.BooleanField(db_index=True, default=True, help_text='Status', verbose_name='status'),
    69
    -        ),
    70
    -        migrations.AlterField(
    71
    -            model_name='usermessageinfo',
    72
    -            name='updated_at',
    73
    -            field=models.DateTimeField(auto_now=True, help_text='Update Time', verbose_name='updated_at'),
    74
    -        ),
    75
    -    ]

    + 0 - 60
    message/migrations/0013_auto_20180103_0446.py

    @@ -1,60 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -# Generated by Django 1.11.3 on 2018-01-02 20:46
    3
    -from __future__ import unicode_literals
    4
    -
    5
    -from django.db import migrations, models
    6
    -
    7
    -
    8
    -class Migration(migrations.Migration):
    9
    -
    10
    -    dependencies = [
    11
    -        ('message', '0012_auto_20180101_2220'),
    12
    -    ]
    13
    -
    14
    -    operations = [
    15
    -        migrations.AlterField(
    16
    -            model_name='systemmessagedeleteinfo',
    17
    -            name='msg_id',
    18
    -            field=models.CharField(blank=True, db_index=True, help_text='\u7cfb\u7edf\u6d88\u606f\u552f\u4e00\u6807\u8bc6', max_length=32, null=True, verbose_name='msg_id'),
    19
    -        ),
    20
    -        migrations.AlterField(
    21
    -            model_name='systemmessagedeleteinfo',
    22
    -            name='user_id',
    23
    -            field=models.CharField(blank=True, db_index=True, help_text='\u7528\u6237\u552f\u4e00\u6807\u8bc6', max_length=32, null=True, verbose_name='user_id'),
    24
    -        ),
    25
    -        migrations.AlterField(
    26
    -            model_name='systemmessagereadinfo',
    27
    -            name='msg_id',
    28
    -            field=models.CharField(blank=True, db_index=True, help_text='\u7cfb\u7edf\u6d88\u606f\u552f\u4e00\u6807\u8bc6', max_length=32, null=True, verbose_name='msg_id'),
    29
    -        ),
    30
    -        migrations.AlterField(
    31
    -            model_name='systemmessagereadinfo',
    32
    -            name='user_id',
    33
    -            field=models.CharField(blank=True, db_index=True, help_text='\u7528\u6237\u552f\u4e00\u6807\u8bc6', max_length=32, null=True, verbose_name='user_id'),
    34
    -        ),
    35
    -        migrations.AlterField(
    36
    -            model_name='usermessageinfo',
    37
    -            name='from_uid',
    38
    -            field=models.CharField(blank=True, db_index=True, help_text='\u53d1\u9001\u6d88\u606f\u7528\u6237\u552f\u4e00\u6807\u8bc6', max_length=32, null=True, verbose_name='from_uid'),
    39
    -        ),
    40
    -        migrations.AlterField(
    41
    -            model_name='usermessageinfo',
    42
    -            name='group_id',
    43
    -            field=models.CharField(blank=True, db_index=True, help_text='\u7fa4\u7ec4\u552f\u4e00\u6807\u8bc6', max_length=32, null=True, verbose_name='group_id'),
    44
    -        ),
    45
    -        migrations.AlterField(
    46
    -            model_name='usermessageinfo',
    47
    -            name='msg_type',
    48
    -            field=models.CharField(db_index=True, default=b'system', help_text='\u6d88\u606f\u7c7b\u578b', max_length=8, verbose_name='msg_type'),
    49
    -        ),
    50
    -        migrations.AlterField(
    51
    -            model_name='usermessageinfo',
    52
    -            name='photo_id',
    53
    -            field=models.CharField(blank=True, db_index=True, help_text='\u98de\u56fe\u552f\u4e00\u6807\u8bc6', max_length=32, null=True, verbose_name='photo_id'),
    54
    -        ),
    55
    -        migrations.AlterField(
    56
    -            model_name='usermessageinfo',
    57
    -            name='to_uid',
    58
    -            field=models.CharField(blank=True, db_index=True, help_text='\u63a5\u6536\u6d88\u606f\u7528\u6237\u552f\u4e00\u6807\u8bc6', max_length=32, null=True, verbose_name='to_uid'),
    59
    -        ),
    60
    -    ]

    + 0 - 35
    message/migrations/0014_auto_20201202_1203.py

    @@ -1,35 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -# Generated by Django 1.11.29 on 2020-12-02 04:03
    3
    -from __future__ import unicode_literals
    4
    -
    5
    -from django.db import migrations, models
    6
    -
    7
    -
    8
    -class Migration(migrations.Migration):
    9
    -
    10
    -    dependencies = [
    11
    -        ('message', '0013_auto_20180103_0446'),
    12
    -    ]
    13
    -
    14
    -    operations = [
    15
    -        migrations.AlterField(
    16
    -            model_name='systemmessagedeleteinfo',
    17
    -            name='status',
    18
    -            field=models.BooleanField(default=True, help_text='Status', verbose_name='status'),
    19
    -        ),
    20
    -        migrations.AlterField(
    21
    -            model_name='systemmessageinfo',
    22
    -            name='status',
    23
    -            field=models.BooleanField(default=True, help_text='Status', verbose_name='status'),
    24
    -        ),
    25
    -        migrations.AlterField(
    26
    -            model_name='systemmessagereadinfo',
    27
    -            name='status',
    28
    -            field=models.BooleanField(default=True, help_text='Status', verbose_name='status'),
    29
    -        ),
    30
    -        migrations.AlterField(
    31
    -            model_name='usermessageinfo',
    32
    -            name='status',
    33
    -            field=models.BooleanField(default=True, help_text='Status', verbose_name='status'),
    34
    -        ),
    35
    -    ]

    + 0 - 0
    message/migrations/__init__.py


    + 0 - 133
    message/models.py

    @@ -1,133 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -
    3
    -from django.conf import settings
    4
    -from django.db import models
    5
    -from django.utils.translation import ugettext_lazy as _
    6
    -from django_models_ext import BaseModelMixin
    7
    -from TimeConvert import TimeConvert as tc
    8
    -
    9
    -from group.models import GroupPhotoInfo
    10
    -from kodo.basemodels import PaiaiSrcMixin
    11
    -
    12
    -
    13
    -class UserMessageInfo(BaseModelMixin):
    14
    -    SYSTEM = 'system'
    15
    -    COMMENT = 'comment'
    16
    -    THUMBUP = 'thumbup'
    17
    -
    18
    -    MESSAGE_TYPE = (
    19
    -        (SYSTEM, u'系统'),
    20
    -        (COMMENT, u'评论'),
    21
    -        (THUMBUP, u'点赞'),
    22
    -    )
    23
    -
    24
    -    MESSAGE_TYPE_INFO = [
    25
    -        {
    26
    -            'msg_type': SYSTEM,
    27
    -            'msg_type_desc': u'系统',
    28
    -            'msg_avatar': settings.SYSTEM_MESSAGE_AVATAR
    29
    -        }, {
    30
    -            'msg_type': COMMENT,
    31
    -            'msg_type_desc': u'评论',
    32
    -            'msg_avatar': settings.COMMENT_MESSAGE_AVATAR
    33
    -        }, {
    34
    -            'msg_type': THUMBUP,
    35
    -            'msg_type_desc': u'点赞',
    36
    -            'msg_avatar': settings.THUMBUP_MESSAGE_AVATAR
    37
    -        }
    38
    -    ]
    39
    -
    40
    -    from_uid = models.CharField(_(u'from_uid'), max_length=32, blank=True, null=True, help_text=u'发送消息用户唯一标识', db_index=True)
    41
    -    from_nickname = models.CharField(_(u'from_nickname'), max_length=255, blank=True, null=True, help_text=u'发送消息用户昵称')
    42
    -    from_avatar = models.CharField(_(u'from_avatar'), max_length=255, blank=True, null=True, help_text=u'发送消息用户头像')
    43
    -
    44
    -    to_uid = models.CharField(_(u'to_uid'), max_length=32, blank=True, null=True, help_text=u'接收消息用户唯一标识', db_index=True)
    45
    -
    46
    -    group_id = models.CharField(_(u'group_id'), max_length=32, blank=True, null=True, help_text=u'群组唯一标识', db_index=True)
    47
    -    photo_id = models.CharField(_(u'photo_id'), max_length=32, blank=True, null=True, help_text=u'飞图唯一标识', db_index=True)
    48
    -
    49
    -    # TODO: IntegerField?
    50
    -    msg_type = models.CharField(_(u'msg_type'), max_length=8, default='system', help_text=u'消息类型', db_index=True)
    51
    -    msg_title = models.CharField(_(u'msg_title'), max_length=255, blank=True, null=True, help_text=u'消息标题')
    52
    -    msg_content = models.TextField(_(u'msg_content'), blank=True, null=True, help_text=u'消息内容')
    53
    -    read = models.BooleanField(_(u'read'), default=False, help_text=u'消息是否已读')
    54
    -
    55
    -    class Meta:
    56
    -        verbose_name = _('usermessageinfo')
    57
    -        verbose_name_plural = _('usermessageinfo')
    58
    -
    59
    -    def __unicode__(self):
    60
    -        return '%d' % self.pk
    61
    -
    62
    -    def msg_info(self, user_id=None):
    63
    -        try:
    64
    -            group_photo = GroupPhotoInfo.objects.get(photo_id=self.photo_id)
    65
    -        except GroupPhotoInfo.DoesNotExist:
    66
    -            group_photo = {}
    67
    -        return {
    68
    -            'pk': self.pk,
    69
    -            'from_uid': self.from_uid,
    70
    -            'from_nickname': self.from_nickname,
    71
    -            'from_avatar': self.from_avatar,
    72
    -            'group_id': self.group_id,
    73
    -            'photo_id': self.photo_id,
    74
    -            'group_photo_info': group_photo and group_photo.photo_info(user_id),
    75
    -            'msg_title': self.msg_title,
    76
    -            'msg_content': self.msg_content,
    77
    -            'read': self.read,
    78
    -            'created_at': tc.remove_microsecond(self.created_at),
    79
    -        }
    80
    -
    81
    -
    82
    -class SystemMessageInfo(BaseModelMixin, PaiaiSrcMixin):
    83
    -    title = models.CharField(_(u'title'), max_length=255, help_text=u'系统消息标题')
    84
    -    content = models.TextField(_(u'content'), blank=True, null=True, help_text=u'系统消息内容')
    85
    -    url = models.CharField(_(u'url'), max_length=255, blank=True, null=True, help_text=u'系统消息链接')
    86
    -
    87
    -    class Meta:
    88
    -        verbose_name = _('systemmessageinfo')
    89
    -        verbose_name_plural = _('systemmessageinfo')
    90
    -
    91
    -    def __unicode__(self):
    92
    -        return '%d' % self.pk
    93
    -
    94
    -    def msg_info(self, user_id=None):
    95
    -        return {
    96
    -            'pk': self.pk,
    97
    -            'title': self.title,
    98
    -            'content': self.content,
    99
    -            'url': self.url,
    100
    -            'read': SystemMessageReadInfo.objects.filter(user_id=user_id, msg_id=self.pk, status=True).exists(),
    101
    -        }
    102
    -
    103
    -
    104
    -class SystemMessageReadInfo(BaseModelMixin):
    105
    -    user_id = models.CharField(_(u'user_id'), max_length=32, blank=True, null=True, help_text=u'用户唯一标识', db_index=True)
    106
    -    msg_id = models.CharField(_(u'msg_id'), max_length=32, blank=True, null=True, help_text=u'系统消息唯一标识', db_index=True)
    107
    -
    108
    -    class Meta:
    109
    -        verbose_name = _('systemmessagereadinfo')
    110
    -        verbose_name_plural = _('systemmessagereadinfo')
    111
    -
    112
    -        unique_together = (
    113
    -            ('user_id', 'msg_id'),
    114
    -        )
    115
    -
    116
    -    def __unicode__(self):
    117
    -        return '%d' % self.pk
    118
    -
    119
    -
    120
    -class SystemMessageDeleteInfo(BaseModelMixin):
    121
    -    user_id = models.CharField(_(u'user_id'), max_length=32, blank=True, null=True, help_text=u'用户唯一标识', db_index=True)
    122
    -    msg_id = models.CharField(_(u'msg_id'), max_length=32, blank=True, null=True, help_text=u'系统消息唯一标识', db_index=True)
    123
    -
    124
    -    class Meta:
    125
    -        verbose_name = _('systemmessagedeleteinfo')
    126
    -        verbose_name_plural = _('systemmessagedeleteinfo')
    127
    -
    128
    -        unique_together = (
    129
    -            ('user_id', 'msg_id'),
    130
    -        )
    131
    -
    132
    -    def __unicode__(self):
    133
    -        return '%d' % self.pk

    + 0 - 4
    message/tests.py

    @@ -1,4 +0,0 @@
    1
    -from django.test import TestCase
    2
    -
    3
    -
    4
    -# Create your tests here.

    + 0 - 130
    message/views.py

    @@ -1,130 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -
    3
    -from django.conf import settings
    4
    -from django_logit import logit
    5
    -from django_response import response
    6
    -from paginator import pagination
    7
    -
    8
    -from account.models import UserInfo
    9
    -from message.models import SystemMessageDeleteInfo, SystemMessageInfo, SystemMessageReadInfo, UserMessageInfo
    10
    -from utils.error.errno_utils import MessageStatusCode, UserStatusCode
    11
    -from utils.message_utils import system_messages, system_unread_messages
    12
    -from utils.redis.rmessage import set_system_message_delete_info, set_system_message_read_info
    13
    -
    14
    -
    15
    -@logit
    16
    -def message_list_api(request):
    17
    -    """ 消息列表 """
    18
    -    user_id = request.POST.get('user_id', '') or request.GET.get('user_id', '')
    19
    -
    20
    -    messages = UserMessageInfo.MESSAGE_TYPE_INFO
    21
    -
    22
    -    final_messages = []
    23
    -    for message in messages:
    24
    -        msg_type = message['msg_type']
    25
    -        if msg_type == UserMessageInfo.SYSTEM:
    26
    -            type_unread_messages = system_unread_messages(user_id, SystemMessageInfo.PAIAI_USER)
    27
    -        else:
    28
    -            type_unread_messages = UserMessageInfo.objects.filter(
    29
    -                to_uid=user_id,
    30
    -                msg_type=msg_type,
    31
    -                read=False,
    32
    -                status=True,
    33
    -            )
    34
    -        message['msg_unread_num'] = type_unread_messages.count()
    35
    -        final_messages.append(message)
    36
    -
    37
    -    return response(200, 'Get Message List Success', u'获取消息列表成功', {
    38
    -        'messages': final_messages,
    39
    -    })
    40
    -
    41
    -
    42
    -@logit
    43
    -def message_type_list_api(request, msg_type):
    44
    -    """ 分类消息列表 """
    45
    -    user_id = request.POST.get('user_id', '') or request.GET.get('user_id', '')
    46
    -    page = int(request.POST.get('page') or request.GET.get('page') or 1)
    47
    -    num = int(request.POST.get('num') or request.GET.get('num') or settings.MESSAGE_NUM_PER_PAGE)
    48
    -
    49
    -    if msg_type == UserMessageInfo.SYSTEM:
    50
    -        type_messages = system_messages(user_id, SystemMessageInfo.PAIAI_USER)
    51
    -    else:
    52
    -        type_messages = UserMessageInfo.objects.filter(
    53
    -            to_uid=user_id,
    54
    -            msg_type=msg_type,
    55
    -            status=True,
    56
    -        )
    57
    -    type_messages = type_messages.order_by(
    58
    -        '-pk'
    59
    -    )
    60
    -    type_messages, left = pagination(type_messages, page, num)
    61
    -    type_messages = [msg.msg_info(user_id) for msg in type_messages]
    62
    -
    63
    -    return response(200, 'Get Message List Success', u'获取消息列表成功', {
    64
    -        'messages': type_messages,
    65
    -        'left': left,
    66
    -    })
    67
    -
    68
    -
    69
    -@logit
    70
    -def message_type_read_api(request, msg_type=None):
    71
    -    """ 消息读取 """
    72
    -    user_id = request.POST.get('user_id', '') or request.GET.get('user_id', '')
    73
    -    pk = int(request.POST.get('pk', 0) or request.GET.get('pk', 0) or -1)
    74
    -    _all = (request.POST.get('all', '') or request.GET.get('all', '')).lower()
    75
    -
    76
    -    # 用户校验
    77
    -    try:
    78
    -        user = UserInfo.objects.get(user_id=user_id, status=True)
    79
    -    except UserInfo.DoesNotExist:
    80
    -        return response(UserStatusCode.USER_NOT_FOUND)
    81
    -
    82
    -    # 消息读取
    83
    -    if msg_type == UserMessageInfo.SYSTEM:
    84
    -        if pk > 0:  # 系统消息单个读取
    85
    -            if not SystemMessageInfo.objects.filter(pk=pk, status=True).exists():
    86
    -                return response(MessageStatusCode.MESSAGE_NOT_FOUND)
    87
    -            SystemMessageReadInfo.objects.get_or_create(user_id=user_id, msg_id=pk)
    88
    -        if _all == 'true':  # 系统消息全部读取
    89
    -            for msg in SystemMessageInfo.objects.filter(src=SystemMessageInfo.PAIAI_USER, status=True):
    90
    -                SystemMessageReadInfo.objects.get_or_create(user_id=user_id, msg_id=msg.pk)
    91
    -        set_system_message_read_info(user_id)
    92
    -    else:
    93
    -        if pk > 0:  # 用户(点赞/评论)消息单个读取
    94
    -            UserMessageInfo.objects.filter(pk=pk, to_uid=user_id, status=True).update(read=True)
    95
    -        if _all == 'true':  # 用户消息(点赞/评论)全部读取
    96
    -            UserMessageInfo.objects.filter(to_uid=user_id, msg_type=msg_type, status=True).update(read=True)
    97
    -
    98
    -    return response(200, 'Read Message Success', u'已读消息成功')
    99
    -
    100
    -
    101
    -@logit
    102
    -def message_type_delete_api(request, msg_type=None):
    103
    -    """ 消息删除 """
    104
    -    user_id = request.POST.get('user_id', '') or request.GET.get('user_id', '')
    105
    -    pk = int(request.POST.get('pk', 0) or request.GET.get('pk', 0) or -1)
    106
    -    _all = (request.POST.get('all', '') or request.GET.get('all', '')).lower()
    107
    -
    108
    -    # 用户校验
    109
    -    try:
    110
    -        user = UserInfo.objects.get(user_id=user_id, status=True)
    111
    -    except UserInfo.DoesNotExist:
    112
    -        return response(UserStatusCode.USER_NOT_FOUND)
    113
    -
    114
    -    # 消息删除
    115
    -    if msg_type == UserMessageInfo.SYSTEM:
    116
    -        if pk > 0:  # 系统消息单个删除
    117
    -            if not SystemMessageInfo.objects.filter(pk=pk, status=True).exists():
    118
    -                return response(MessageStatusCode.MESSAGE_NOT_FOUND)
    119
    -            SystemMessageDeleteInfo.objects.get_or_create(user_id=user_id, msg_id=pk)
    120
    -        if _all == 'true':  # 系统消息全部删除
    121
    -            for msg in SystemMessageInfo.objects.filter(src=SystemMessageInfo.PAIAI_USER, status=True):
    122
    -                SystemMessageDeleteInfo.objects.get_or_create(user_id=user_id, msg_id=msg.pk)
    123
    -        set_system_message_delete_info(user_id)
    124
    -    else:
    125
    -        if pk > 0:  # 用户(点赞/评论)消息单个删除
    126
    -            UserMessageInfo.objects.filter(pk=pk, to_uid=user_id, status=True).update(status=False)
    127
    -        if _all == 'true':  # 用户消息(点赞/评论)全部删除
    128
    -            UserMessageInfo.objects.filter(to_uid=user_id, msg_type=msg_type, status=True).update(status=False)
    129
    -
    130
    -    return response(200, 'Delete Message Success', u'消息删除成功')

    + 0 - 44
    operation/views.py

    @@ -11,8 +11,6 @@ from account.models import UserInfo
    11 11
     from operation.models import FeedbackInfo, GuestEntranceControlInfo, LatestAppInfo, SplashInfo
    12 12
     from utils.error.errno_utils import UserStatusCode
    13 13
     from utils.redis.rapp import get_latest_app
    14
    -from utils.redis.rguest import get_guest_entrance_control
    15
    -from utils.redis.roperation.rbox_program_version import get_box_program_version
    16 14
     from utils.redis.rpatch import get_app_patch_info
    17 15
     from utils.redis.rsettings import get_app_settings_info
    18 16
     from utils.version_utils import is_version_match
    @@ -70,34 +68,6 @@ def online_api(request):
    70 68
             'online': app_settings.get('online', True),
    71 69
         })
    72 70
     
    73
    -
    74
    -@logit
    75
    -def guest_api(request):
    76
    -    """ 游客状态 """
    77
    -    src = int(request.POST.get('src', 0))
    78
    -
    79
    -    gen = get_guest_entrance_control(src)
    80
    -
    81
    -    # 是否配置游客入口控制信息
    82
    -    if not gen:
    83
    -        return response(UserStatusCode.GUEST_NOT_ALLOWED)
    84
    -
    85
    -    # 平台校验
    86
    -    platform = gen.get('platform', '')
    87
    -    if request.Android:
    88
    -        if platform not in [GuestEntranceControlInfo.ADR, GuestEntranceControlInfo.BOTH]:
    89
    -            return response(UserStatusCode.GUEST_NOT_ALLOWED)
    90
    -    else:
    91
    -        if platform not in [GuestEntranceControlInfo.IOS, GuestEntranceControlInfo.BOTH]:
    92
    -            return response(UserStatusCode.GUEST_NOT_ALLOWED)
    93
    -
    94
    -    # 版本校验
    95
    -    if not is_version_match(request, gen):
    96
    -        return response(UserStatusCode.GUEST_NOT_ALLOWED)
    97
    -
    98
    -    return response(200, 'Guest Login Allowed', u'游客登录开启')
    99
    -
    100
    -
    101 71
     @logit
    102 72
     def splash_api(request):
    103 73
         """ 启动页面 """
    @@ -158,17 +128,3 @@ def download_api(request):
    158 128
     def kvformat(bpversion, k):
    159 129
         v = bpversion.get(k, '')
    160 130
         return '"{}":{}'.format(k, v) if isinstance(v, int) else '"{}":"{}"'.format(k, v)
    161
    -
    162
    -
    163
    -def box_program_version_api(request):
    164
    -    """ BOX 程序版本信息 """
    165
    -    bpversion = get_box_program_version()
    166
    -
    167
    -    keys = ['srv_version_code', 'srv_version_name', 'srv_sha1', 'proc_version_code', 'proc_version_name', 'proc_sha1']
    168
    -    kvs = [kvformat(bpversion, k) for k in keys]
    169
    -    bpversion_str = os.linesep.join(kvs)
    170
    -
    171
    -    return response(200, 'Get Box Program Version Success', u'获取盒子程序版本成功', {
    172
    -        'bpversion': bpversion,
    173
    -        'bpversion_str': bpversion_str,
    174
    -    })

    + 0 - 32
    page/oauth_views.py

    @@ -7,42 +7,10 @@ from django_logit import logit
    7 7
     from django_response import response
    8 8
     from json_render import json_render
    9 9
     
    10
    -from account.models import LensmanInfo, TourGuideInfo
    11 10
     from mch.models import BrandInfo, DistributorInfo, SaleclerkInfo
    12 11
     from utils.error.errno_utils import ProductBrandStatusCode, ProductDistributorStatusCode, SaleclerkStatusCode
    13 12
     from utils.redis.connect import r
    14 13
     
    15
    -
    16
    -def lensman_oauth(request):
    17
    -    lensman_type = int(request.GET.get('lt') or 0)
    18
    -    unionid = request.GET.get('unionid', '')
    19
    -
    20
    -    try:
    21
    -        lensman = LensmanInfo.objects.get(unionid=unionid)
    22
    -    except LensmanInfo.DoesNotExist:
    23
    -        lensman = None
    24
    -
    25
    -    return render(request, 'page/lensman_oauth.html', {
    26
    -        'lensman_type': lensman_type,
    27
    -        'lensman_info': lensman and lensman.data(lensman_type),
    28
    -        'modified': bool((not lensman) or (lensman and lensman.modified(lensman_type))),  # 是否可以更改信息
    29
    -    })
    30
    -
    31
    -
    32
    -def tourguide_oauth(request):
    33
    -    unionid = request.GET.get('unionid', '')
    34
    -
    35
    -    try:
    36
    -        tourguide = TourGuideInfo.objects.get(unionid=unionid)
    37
    -    except TourGuideInfo.DoesNotExist:
    38
    -        tourguide = None
    39
    -
    40
    -    return render(request, 'page/tourguide_oauth.html', {
    41
    -        'tourguide_info': tourguide and tourguide.data,
    42
    -        'modified': bool((not tourguide) or (tourguide and tourguide.modified)),  # 是否可以更改信息
    43
    -    })
    44
    -
    45
    -
    46 14
     def login_qrcode(request):
    47 15
         lensman_type = int(request.GET.get('lt') or 0)
    48 16
         unionid = request.GET.get('unionid', '')

    + 0 - 15
    page/page_views.py

    @@ -1,15 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -
    3
    -from django.shortcuts import render
    4
    -
    5
    -
    6
    -def user_agreement(request):
    7
    -    return render(request, 'page/user_agreement.html', {})
    8
    -
    9
    -
    10
    -def contact_us(request):
    11
    -    return render(request, 'page/contact_us.html', {})
    12
    -
    13
    -
    14
    -def lensman_price(request):
    15
    -    return render(request, 'page/lensman_price.html', {})

    + 1 - 26
    page/urls.py

    @@ -2,32 +2,7 @@
    2 2
     
    3 3
     from django.conf.urls import url
    4 4
     
    5
    -from account import tourguide_views
    6
    -from group import lensman_views
    7
    -from page import info_views, oauth_views, page_views, preauth_views, sale_views, screen_views, supersr_views
    8
    -
    9
    -
    10
    -urlpatterns = [
    11
    -    url(r'^user_agreement$', page_views.user_agreement, name='user_agreement'),  # 用户协议页面
    12
    -    url(r'^contact_us$', page_views.contact_us, name='contact_us'),  # 联系我们页面
    13
    -    url(r'^price$', page_views.lensman_price, name='lensman_price'),  # 摄影师照片价格和分成规则
    14
    -]
    15
    -
    16
    -urlpatterns += [
    17
    -    url(r'^lensman$', oauth_views.lensman_oauth, name='lensman_oauth'),  # 摄影师授权页面
    18
    -    url(r'^tourguide$', oauth_views.tourguide_oauth, name='tourguide_oauth'),  # 导游授权页面
    19
    -    url(r'^loginqr$', oauth_views.login_qrcode, name='login_qrcode'),  # 登录二维码页面
    20
    -]
    21
    -
    22
    -# 摄影师相关
    23
    -urlpatterns += [
    24
    -    url(r'^l/submit$', lensman_views.lensman_submit_api, name='lensman_submit_api'),  # 摄影师信息提交
    25
    -]
    26
    -
    27
    -# 导游相关
    28
    -urlpatterns += [
    29
    -    url(r'^t/submit$', tourguide_views.tourguide_submit_api, name='tourguide_submit_api'),  # 导游信息提交
    30
    -]
    5
    +from page import info_views, oauth_views, preauth_views, sale_views, screen_views, supersr_views
    31 6
     
    32 7
     urlpatterns = [
    33 8
         url(r'^clerk$', oauth_views.clerk_oauth, name='clerk_oauth'),  # 店员授权页面

    + 0 - 0
    pay/__init__.py


    + 0 - 4
    pay/admin.py

    @@ -1,4 +0,0 @@
    1
    -from django.contrib import admin
    2
    -
    3
    -
    4
    -# Register your models here.

    + 0 - 35
    pay/migrations/0001_initial.py

    @@ -1,35 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -from __future__ import unicode_literals
    3
    -
    4
    -from django.db import models, migrations
    5
    -import shortuuidfield.fields
    6
    -
    7
    -
    8
    -class Migration(migrations.Migration):
    9
    -
    10
    -    dependencies = [
    11
    -    ]
    12
    -
    13
    -    operations = [
    14
    -        migrations.CreateModel(
    15
    -            name='OrderInfo',
    16
    -            fields=[
    17
    -                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
    18
    -                ('status', models.BooleanField(default=True, help_text='\u72b6\u6001', db_index=True, verbose_name='status')),
    19
    -                ('created_at', models.DateTimeField(help_text='\u521b\u5efa\u65f6\u95f4', verbose_name='created_at', auto_now_add=True)),
    20
    -                ('updated_at', models.DateTimeField(help_text='\u66f4\u65b0\u65f6\u95f4', verbose_name='updated_at', auto_now=True)),
    21
    -                ('order_id', shortuuidfield.fields.ShortUUIDField(help_text='\u8ba2\u5355\u552f\u4e00\u6807\u8bc6', max_length=22, editable=False, db_index=True, blank=True)),
    22
    -                ('from_uid', models.CharField(help_text='\u4ed8\u6b3e\u7528\u6237\u552f\u4e00\u6807\u8bc6', max_length=255, verbose_name='from_uid', db_index=True)),
    23
    -                ('to_lid', models.CharField(max_length=255, blank=True, help_text='\u6536\u6b3e\u6444\u5f71\u5e08\u552f\u4e00\u6807\u8bc6', null=True, verbose_name='to_lid', db_index=True)),
    24
    -                ('to_uid', models.CharField(max_length=255, blank=True, help_text='\u6536\u6b3e\u7528\u6237\u552f\u4e00\u6807\u8bc6', null=True, verbose_name='to_uid', db_index=True)),
    25
    -                ('body', models.CharField(help_text='\u5546\u54c1\u63cf\u8ff0', max_length=255, null=True, verbose_name='body', blank=True)),
    26
    -                ('total_fee', models.IntegerField(default=0, help_text='\u603b\u91d1\u989d', verbose_name='total_fee')),
    27
    -                ('pay_status', models.IntegerField(default=0, help_text='\u652f\u4ed8\u72b6\u6001', db_index=True, verbose_name='pay_status', choices=[(0, '\u5f85\u652f\u4ed8'), (1, '\u5df2\u652f\u4ed8')])),
    28
    -                ('paid_at', models.DateTimeField(help_text='\u652f\u4ed8\u65f6\u95f4', null=True, verbose_name='paid_at', blank=True)),
    29
    -            ],
    30
    -            options={
    31
    -                'verbose_name': 'orderinfo',
    32
    -                'verbose_name_plural': 'orderinfo',
    33
    -            },
    34
    -        ),
    35
    -    ]

    + 0 - 19
    pay/migrations/0002_orderinfo_trade_type.py

    @@ -1,19 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -from __future__ import unicode_literals
    3
    -
    4
    -from django.db import models, migrations
    5
    -
    6
    -
    7
    -class Migration(migrations.Migration):
    8
    -
    9
    -    dependencies = [
    10
    -        ('pay', '0001_initial'),
    11
    -    ]
    12
    -
    13
    -    operations = [
    14
    -        migrations.AddField(
    15
    -            model_name='orderinfo',
    16
    -            name='trade_type',
    17
    -            field=models.CharField(help_text='\u652f\u4ed8\u65b9\u5f0f', max_length=255, null=True, verbose_name='trade_type', blank=True),
    18
    -        ),
    19
    -    ]

    + 0 - 19
    pay/migrations/0003_auto_20160417_1544.py

    @@ -1,19 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -from __future__ import unicode_literals
    3
    -
    4
    -from django.db import models, migrations
    5
    -
    6
    -
    7
    -class Migration(migrations.Migration):
    8
    -
    9
    -    dependencies = [
    10
    -        ('pay', '0002_orderinfo_trade_type'),
    11
    -    ]
    12
    -
    13
    -    operations = [
    14
    -        migrations.AlterField(
    15
    -            model_name='orderinfo',
    16
    -            name='pay_status',
    17
    -            field=models.IntegerField(default=0, help_text='\u652f\u4ed8\u72b6\u6001', db_index=True, verbose_name='pay_status', choices=[(0, '\u5f85\u652f\u4ed8'), (1, '\u5df2\u652f\u4ed8'), (2, '\u5df2\u5931\u8d25')]),
    18
    -        ),
    19
    -    ]

    + 0 - 34
    pay/migrations/0004_auto_20160422_1322.py

    @@ -1,34 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -from __future__ import unicode_literals
    3
    -
    4
    -from django.db import models, migrations
    5
    -
    6
    -
    7
    -class Migration(migrations.Migration):
    8
    -
    9
    -    dependencies = [
    10
    -        ('pay', '0003_auto_20160417_1544'),
    11
    -    ]
    12
    -
    13
    -    operations = [
    14
    -        migrations.AddField(
    15
    -            model_name='orderinfo',
    16
    -            name='group_id',
    17
    -            field=models.CharField(max_length=255, blank=True, help_text='\u7fa4\u7ec4\u552f\u4e00\u6807\u8bc6', null=True, verbose_name='group_id', db_index=True),
    18
    -        ),
    19
    -        migrations.AddField(
    20
    -            model_name='orderinfo',
    21
    -            name='lensman_photo_id',
    22
    -            field=models.CharField(max_length=255, blank=True, help_text='\u6444\u5f71\u5e08\u7167\u7247\u552f\u4e00\u6807\u8bc6\uff0c\u540c PhotosInfo \u8868', null=True, verbose_name='lensman_photo_id', db_index=True),
    23
    -        ),
    24
    -        migrations.AddField(
    25
    -            model_name='orderinfo',
    26
    -            name='photo_id',
    27
    -            field=models.CharField(max_length=255, blank=True, help_text='\u98de\u56fe\u552f\u4e00\u6807\u8bc6', null=True, verbose_name='photo_id', db_index=True),
    28
    -        ),
    29
    -        migrations.AddField(
    30
    -            model_name='orderinfo',
    31
    -            name='photo_type',
    32
    -            field=models.IntegerField(default=0, help_text='\u8d2d\u4e70\u7167\u7247\u7c7b\u578b', verbose_name='photo_type', choices=[(0, '\u53bb\u9664\u6c34\u5370'), (1, '\u83b7\u53d6\u9ad8\u6e05\u56fe')]),
    33
    -        ),
    34
    -    ]

    + 0 - 18
    pay/migrations/0005_remove_orderinfo_to_lid.py

    @@ -1,18 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -from __future__ import unicode_literals
    3
    -
    4
    -from django.db import models, migrations
    5
    -
    6
    -
    7
    -class Migration(migrations.Migration):
    8
    -
    9
    -    dependencies = [
    10
    -        ('pay', '0004_auto_20160422_1322'),
    11
    -    ]
    12
    -
    13
    -    operations = [
    14
    -        migrations.RemoveField(
    15
    -            model_name='orderinfo',
    16
    -            name='to_lid',
    17
    -        ),
    18
    -    ]

    + 0 - 39
    pay/migrations/0006_auto_20160901_1439.py

    @@ -1,39 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -from __future__ import unicode_literals
    3
    -
    4
    -from django.db import models, migrations
    5
    -
    6
    -
    7
    -class Migration(migrations.Migration):
    8
    -
    9
    -    dependencies = [
    10
    -        ('pay', '0005_remove_orderinfo_to_lid'),
    11
    -    ]
    12
    -
    13
    -    operations = [
    14
    -        migrations.AddField(
    15
    -            model_name='orderinfo',
    16
    -            name='photo_status',
    17
    -            field=models.IntegerField(default=0, help_text='\u8d2d\u4e70\u7167\u7247\u72b6\u6001, \u6807\u8bc6\u7528\u6237\u662f\u5426\u5df2\u7ecf\u83b7\u5f97\u7167\u7247', db_index=True, verbose_name='photo_status', choices=[(0, '\u5f85\u4e0a\u4f20'), (1, '\u5df2\u4e0a\u4f20'), (2, '\u5df2\u5220\u9664')]),
    18
    -        ),
    19
    -        migrations.AddField(
    20
    -            model_name='orderinfo',
    21
    -            name='reback_at',
    22
    -            field=models.DateTimeField(help_text='\u9000\u6b3e\u65f6\u95f4', null=True, verbose_name='reback_at', blank=True),
    23
    -        ),
    24
    -        migrations.AddField(
    25
    -            model_name='orderinfo',
    26
    -            name='reback_status',
    27
    -            field=models.BooleanField(default=False, help_text='\u9000\u6b3e\u72b6\u6001', db_index=True, verbose_name='reback_status'),
    28
    -        ),
    29
    -        migrations.AddField(
    30
    -            model_name='orderinfo',
    31
    -            name='session_id',
    32
    -            field=models.CharField(max_length=255, blank=True, help_text='\u7167\u7247\u7ec4\u552f\u4e00\u6807\u8bc6\uff0c\u540c PhotosInfo \u8868', null=True, verbose_name='session_id', db_index=True),
    33
    -        ),
    34
    -        migrations.AlterField(
    35
    -            model_name='orderinfo',
    36
    -            name='photo_type',
    37
    -            field=models.IntegerField(default=0, help_text='\u8d2d\u4e70\u7167\u7247\u7c7b\u578b', db_index=True, verbose_name='photo_type', choices=[(0, '\u53bb\u9664\u6c34\u5370'), (1, '\u83b7\u53d6\u9ad8\u6e05\u56fe')]),
    38
    -        ),
    39
    -    ]

    + 0 - 19
    pay/migrations/0007_orderinfo_unifiedorder_result.py

    @@ -1,19 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -from __future__ import unicode_literals
    3
    -
    4
    -from django.db import models, migrations
    5
    -
    6
    -
    7
    -class Migration(migrations.Migration):
    8
    -
    9
    -    dependencies = [
    10
    -        ('pay', '0006_auto_20160901_1439'),
    11
    -    ]
    12
    -
    13
    -    operations = [
    14
    -        migrations.AddField(
    15
    -            model_name='orderinfo',
    16
    -            name='unifiedorder_result',
    17
    -            field=models.TextField(help_text='\u7edf\u4e00\u4e0b\u5355\u7ed3\u679c', null=True, verbose_name='unifiedorder_result', blank=True),
    18
    -        ),
    19
    -    ]

    + 0 - 30
    pay/migrations/0008_auto_20170714_0759.py

    @@ -1,30 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -# Generated by Django 1.11.3 on 2017-07-13 23:59
    3
    -from __future__ import unicode_literals
    4
    -
    5
    -from django.db import migrations, models
    6
    -
    7
    -
    8
    -class Migration(migrations.Migration):
    9
    -
    10
    -    dependencies = [
    11
    -        ('pay', '0007_orderinfo_unifiedorder_result'),
    12
    -    ]
    13
    -
    14
    -    operations = [
    15
    -        migrations.AddField(
    16
    -            model_name='orderinfo',
    17
    -            name='notify_msg',
    18
    -            field=models.TextField(blank=True, help_text='\u56de\u8c03\u4fe1\u606f', null=True, verbose_name='notify_msg'),
    19
    -        ),
    20
    -        migrations.AddField(
    21
    -            model_name='orderinfo',
    22
    -            name='prepay_id',
    23
    -            field=models.CharField(blank=True, help_text='\u9884\u652f\u4ed8\u4ea4\u6613\u4f1a\u8bdd\u6807\u8bc6', max_length=255, null=True, verbose_name='prepay_id'),
    24
    -        ),
    25
    -        migrations.AddField(
    26
    -            model_name='orderinfo',
    27
    -            name='transaction_id',
    28
    -            field=models.CharField(blank=True, help_text='\u5fae\u4fe1\u8ba2\u5355\u53f7', max_length=255, null=True, verbose_name='transaction_id'),
    29
    -        ),
    30
    -    ]

    + 0 - 20
    pay/migrations/0009_auto_20170715_2314.py

    @@ -1,20 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -# Generated by Django 1.11.3 on 2017-07-15 15:14
    3
    -from __future__ import unicode_literals
    4
    -
    5
    -from django.db import migrations, models
    6
    -
    7
    -
    8
    -class Migration(migrations.Migration):
    9
    -
    10
    -    dependencies = [
    11
    -        ('pay', '0008_auto_20170714_0759'),
    12
    -    ]
    13
    -
    14
    -    operations = [
    15
    -        migrations.AlterField(
    16
    -            model_name='orderinfo',
    17
    -            name='transaction_id',
    18
    -            field=models.CharField(blank=True, help_text='\u4ea4\u6613\u5355\u53f7', max_length=255, null=True, verbose_name='transaction_id'),
    19
    -        ),
    20
    -    ]

    + 0 - 30
    pay/migrations/0010_auto_20180101_2220.py

    @@ -1,30 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -# Generated by Django 1.11.3 on 2018-01-01 14:20
    3
    -from __future__ import unicode_literals
    4
    -
    5
    -from django.db import migrations, models
    6
    -
    7
    -
    8
    -class Migration(migrations.Migration):
    9
    -
    10
    -    dependencies = [
    11
    -        ('pay', '0009_auto_20170715_2314'),
    12
    -    ]
    13
    -
    14
    -    operations = [
    15
    -        migrations.AlterField(
    16
    -            model_name='orderinfo',
    17
    -            name='created_at',
    18
    -            field=models.DateTimeField(auto_now_add=True, help_text='Create Time', verbose_name='created_at'),
    19
    -        ),
    20
    -        migrations.AlterField(
    21
    -            model_name='orderinfo',
    22
    -            name='status',
    23
    -            field=models.BooleanField(db_index=True, default=True, help_text='Status', verbose_name='status'),
    24
    -        ),
    25
    -        migrations.AlterField(
    26
    -            model_name='orderinfo',
    27
    -            name='updated_at',
    28
    -            field=models.DateTimeField(auto_now=True, help_text='Update Time', verbose_name='updated_at'),
    29
    -        ),
    30
    -    ]

    + 0 - 55
    pay/migrations/0011_auto_20180103_0446.py

    @@ -1,55 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -# Generated by Django 1.11.3 on 2018-01-02 20:46
    3
    -from __future__ import unicode_literals
    4
    -
    5
    -from django.db import migrations, models
    6
    -
    7
    -
    8
    -class Migration(migrations.Migration):
    9
    -
    10
    -    dependencies = [
    11
    -        ('pay', '0010_auto_20180101_2220'),
    12
    -    ]
    13
    -
    14
    -    operations = [
    15
    -        migrations.AlterField(
    16
    -            model_name='orderinfo',
    17
    -            name='from_uid',
    18
    -            field=models.CharField(db_index=True, help_text='\u4ed8\u6b3e\u7528\u6237\u552f\u4e00\u6807\u8bc6', max_length=32, verbose_name='from_uid'),
    19
    -        ),
    20
    -        migrations.AlterField(
    21
    -            model_name='orderinfo',
    22
    -            name='group_id',
    23
    -            field=models.CharField(blank=True, db_index=True, help_text='\u7fa4\u7ec4\u552f\u4e00\u6807\u8bc6', max_length=32, null=True, verbose_name='group_id'),
    24
    -        ),
    25
    -        migrations.AlterField(
    26
    -            model_name='orderinfo',
    27
    -            name='lensman_photo_id',
    28
    -            field=models.CharField(blank=True, db_index=True, help_text='\u6444\u5f71\u5e08\u7167\u7247\u552f\u4e00\u6807\u8bc6\uff0c\u540c PhotosInfo \u8868', max_length=32, null=True, verbose_name='lensman_photo_id'),
    29
    -        ),
    30
    -        migrations.AlterField(
    31
    -            model_name='orderinfo',
    32
    -            name='photo_id',
    33
    -            field=models.CharField(blank=True, db_index=True, help_text='\u98de\u56fe\u552f\u4e00\u6807\u8bc6', max_length=32, null=True, verbose_name='photo_id'),
    34
    -        ),
    35
    -        migrations.AlterField(
    36
    -            model_name='orderinfo',
    37
    -            name='prepay_id',
    38
    -            field=models.CharField(blank=True, help_text='\u9884\u652f\u4ed8\u4ea4\u6613\u4f1a\u8bdd\u6807\u8bc6', max_length=64, null=True, verbose_name='prepay_id'),
    39
    -        ),
    40
    -        migrations.AlterField(
    41
    -            model_name='orderinfo',
    42
    -            name='session_id',
    43
    -            field=models.CharField(blank=True, db_index=True, help_text='\u7167\u7247\u7ec4\u552f\u4e00\u6807\u8bc6\uff0c\u540c PhotosInfo \u8868', max_length=32, null=True, verbose_name='session_id'),
    44
    -        ),
    45
    -        migrations.AlterField(
    46
    -            model_name='orderinfo',
    47
    -            name='to_uid',
    48
    -            field=models.CharField(blank=True, db_index=True, help_text='\u6536\u6b3e\u7528\u6237\u552f\u4e00\u6807\u8bc6', max_length=32, null=True, verbose_name='to_uid'),
    49
    -        ),
    50
    -        migrations.AlterField(
    51
    -            model_name='orderinfo',
    52
    -            name='transaction_id',
    53
    -            field=models.CharField(blank=True, help_text='\u4ea4\u6613\u5355\u53f7', max_length=32, null=True, verbose_name='transaction_id'),
    54
    -        ),
    55
    -    ]

    + 0 - 18
    pay/migrations/0012_auto_20201130_0131.py

    @@ -1,18 +0,0 @@
    1
    -# Generated by Django 2.2.15 on 2020-11-29 17:31
    2
    -
    3
    -from django.db import migrations, models
    4
    -
    5
    -
    6
    -class Migration(migrations.Migration):
    7
    -
    8
    -    dependencies = [
    9
    -        ('pay', '0011_auto_20180103_0446'),
    10
    -    ]
    11
    -
    12
    -    operations = [
    13
    -        migrations.AlterField(
    14
    -            model_name='orderinfo',
    15
    -            name='status',
    16
    -            field=models.BooleanField(default=True, help_text='Status', verbose_name='status'),
    17
    -        ),
    18
    -    ]

    + 0 - 20
    pay/migrations/0013_auto_20201202_1203.py

    @@ -1,20 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -# Generated by Django 1.11.29 on 2020-12-02 04:03
    3
    -from __future__ import unicode_literals
    4
    -
    5
    -from django.db import migrations, models
    6
    -
    7
    -
    8
    -class Migration(migrations.Migration):
    9
    -
    10
    -    dependencies = [
    11
    -        ('pay', '0012_auto_20201130_0131'),
    12
    -    ]
    13
    -
    14
    -    operations = [
    15
    -        migrations.AlterField(
    16
    -            model_name='orderinfo',
    17
    -            name='reback_status',
    18
    -            field=models.BooleanField(default=False, help_text='\u9000\u6b3e\u72b6\u6001', verbose_name='reback_status'),
    19
    -        ),
    20
    -    ]

    + 0 - 0
    pay/migrations/__init__.py


    + 0 - 123
    pay/models.py

    @@ -1,123 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -
    3
    -from django.db import models
    4
    -from django.utils.translation import ugettext_lazy as _
    5
    -from django_models_ext import BaseModelMixin
    6
    -from shortuuidfield import ShortUUIDField
    7
    -from TimeConvert import TimeConvert as tc
    8
    -
    9
    -from group.models import GroupPhotoInfo
    10
    -
    11
    -
    12
    -class OrderInfo(BaseModelMixin):
    13
    -    NOMARK = 0
    14
    -    ORIGIN = 1
    15
    -
    16
    -    PHOTO_TYPE = (
    17
    -        (NOMARK, u'去除水印'),
    18
    -        (ORIGIN, u'获取高清图'),
    19
    -    )
    20
    -
    21
    -    WANTED = 0
    22
    -    FETCHED = 1
    23
    -    DELETED = 2
    24
    -
    25
    -    PHOTO_STATUS = (
    26
    -        (WANTED, u'待上传'),
    27
    -        (FETCHED, u'已上传'),
    28
    -        (DELETED, u'已删除'),
    29
    -    )
    30
    -
    31
    -    """
    32
    -    # Trade State of Wechat Query
    33
    -    SUCCESS ——— 支付成功
    34
    -    REFUND ——— 转入退款
    35
    -    NOTPAY ——— 未支付
    36
    -    CLOSED ——— 已关闭
    37
    -    REVOKED ——— 已撤销(刷卡支付)
    38
    -    USERPAYING ——— 用户支付中
    39
    -    PAYERROR ——— 支付失败(其他原因,如银行返回失败)
    40
    -    """
    41
    -
    42
    -    WAITING_PAY = 0
    43
    -    PAID = 1
    44
    -    FAIL = 2
    45
    -    # DELETED = 9
    46
    -
    47
    -    PAY_STATUS = (
    48
    -        (WAITING_PAY, u'待支付'),
    49
    -        (PAID, u'已支付'),
    50
    -        (FAIL, u'已失败'),
    51
    -        # (DELETED, u'已删除'),
    52
    -    )
    53
    -
    54
    -    order_id = ShortUUIDField(_(u'order_id'), max_length=32, help_text=u'订单唯一标识', db_index=True)
    55
    -
    56
    -    prepay_id = models.CharField(_(u'prepay_id'), max_length=64, blank=True, null=True, help_text=u'预支付交易会话标识')
    57
    -    transaction_id = models.CharField(_(u'transaction_id'), max_length=32, blank=True, null=True, help_text=u'交易单号')
    58
    -
    59
    -    group_id = models.CharField(_(u'group_id'), max_length=32, blank=True, null=True, help_text=u'群组唯一标识', db_index=True)
    60
    -    session_id = models.CharField(_(u'session_id'), max_length=32, blank=True, null=True, help_text=u'照片组唯一标识,同 PhotosInfo 表', db_index=True)
    61
    -    photo_id = models.CharField(_(u'photo_id'), max_length=32, blank=True, null=True, help_text=u'飞图唯一标识', db_index=True)
    62
    -    lensman_photo_id = models.CharField(_(u'lensman_photo_id'), max_length=32, blank=True, null=True, help_text=u'摄影师照片唯一标识,同 PhotosInfo 表', db_index=True)
    63
    -
    64
    -    photo_type = models.IntegerField(_(u'photo_type'), choices=PHOTO_TYPE, default=NOMARK, help_text=u'购买照片类型', db_index=True)
    65
    -    photo_status = models.IntegerField(_(u'photo_status'), choices=PHOTO_STATUS, default=WANTED, help_text=_(u'购买照片状态, 标识用户是否已经获得照片'), db_index=True)
    66
    -
    67
    -    from_uid = models.CharField(_(u'from_uid'), max_length=32, help_text=u'付款用户唯一标识', db_index=True)
    68
    -    to_uid = models.CharField(_(u'to_uid'), max_length=32, blank=True, null=True, help_text=u'收款用户唯一标识', db_index=True)
    69
    -
    70
    -    body = models.CharField(_(u'body'), max_length=255, blank=True, null=True, help_text=u'商品描述')
    71
    -    total_fee = models.IntegerField(_(u'total_fee'), default=0, help_text=u'总金额')
    72
    -
    73
    -    trade_type = models.CharField(_(u'trade_type'), max_length=255, blank=True, null=True, help_text=u'支付方式')
    74
    -
    75
    -    pay_status = models.IntegerField(_(u'pay_status'), choices=PAY_STATUS, default=WAITING_PAY, help_text=u'支付状态', db_index=True)
    76
    -    paid_at = models.DateTimeField(_(u'paid_at'), blank=True, null=True, help_text=_(u'支付时间'))
    77
    -
    78
    -    reback_status = models.BooleanField(_(u'reback_status'), default=False, help_text=u'退款状态')
    79
    -    reback_at = models.DateTimeField(_(u'reback_at'), blank=True, null=True, help_text=_(u'退款时间'))
    80
    -
    81
    -    # 微信统一下单
    82
    -    unifiedorder_result = models.TextField(_(u'unifiedorder_result'), blank=True, null=True, help_text=_(u'统一下单结果'))
    83
    -    # 微信支付回调
    84
    -    notify_msg = models.TextField(_(u'notify_msg'), blank=True, null=True, help_text=u'回调信息')
    85
    -
    86
    -    class Meta:
    87
    -        verbose_name = _(u'orderinfo')
    88
    -        verbose_name_plural = _(u'orderinfo')
    89
    -
    90
    -    def __unicode__(self):
    91
    -        return u'{0.pk}'.format(self)
    92
    -
    93
    -    def data(self, user_id=None):
    94
    -        try:
    95
    -            group_photo = GroupPhotoInfo.objects.get(photo_id=self.photo_id)
    96
    -        except GroupPhotoInfo.DoesNotExist:
    97
    -            group_photo = None
    98
    -        return {
    99
    -            'order_id': self.order_id,
    100
    -            'from_uid': self.from_uid,
    101
    -            'group_id': self.group_id,
    102
    -            'photo_id': self.photo_id,
    103
    -            'group_photo_info': group_photo and group_photo.photo_info(user_id),
    104
    -            'to_uid': self.to_uid,
    105
    -            'body': self.body,
    106
    -            'total_fee': self.total_fee,
    107
    -            'pay_status': self.pay_status,
    108
    -            'paid_at': tc.remove_microsecond(self.paid_at),
    109
    -            'created_at': tc.remove_microsecond(self.created_at),
    110
    -        }
    111
    -
    112
    -    @property
    113
    -    def lensdata(self, user_id=None):
    114
    -        try:
    115
    -            group_photo = GroupPhotoInfo.objects.get(photo_id=self.photo_id)
    116
    -        except GroupPhotoInfo.DoesNotExist:
    117
    -            group_photo = None
    118
    -        return {
    119
    -            'order_id': self.order_id,
    120
    -            'session_id': self.session_id,
    121
    -            'photo_id': self.lensman_photo_id,
    122
    -            'group_photo_info': group_photo and group_photo.photo_info(user_id),
    123
    -        }

    + 0 - 4
    pay/tests.py

    @@ -1,4 +0,0 @@
    1
    -from django.test import TestCase
    2
    -
    3
    -
    4
    -# Create your tests here.

    + 0 - 344
    pay/views.py

    @@ -1,344 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -
    3
    -from django.conf import settings
    4
    -from django.db import transaction
    5
    -from django.shortcuts import HttpResponse
    6
    -from django_logit import logit
    7
    -from django_response import response
    8
    -from paginator import pagination
    9
    -from pywe_exception import WeChatPayException
    10
    -from pywe_pay import WeChatPay
    11
    -from pywe_pay_notify import check_pay_notify
    12
    -from pywe_response import WXPAY_NOTIFY_FAIL, WXPAY_NOTIFY_SUCCESS
    13
    -from pywe_sign import check_signature
    14
    -from TimeConvert import TimeConvert as tc
    15
    -
    16
    -from account.models import UserIncomeExpensesInfo, UserInfo
    17
    -from group.models import GroupPhotoInfo, GroupPhotoOrderInfo
    18
    -from pay.models import OrderInfo
    19
    -from photo.models import PhotosInfo
    20
    -from utils.error.errno_utils import (GroupPhotoStatusCode, OrderStatusCode, UserStatusCode, WechatStatusCode,
    21
    -                                     WithdrawStatusCode)
    22
    -from utils.price_utils import get_group_photo_price
    23
    -from utils.redis.rbrief import set_brief_info
    24
    -from utils.redis.rorder import set_lensman_order_record
    25
    -from utils.wx_utils import get_trade_type, get_user_openid
    26
    -
    27
    -
    28
    -WECHAT = settings.WECHAT
    29
    -
    30
    -
    31
    -@logit
    32
    -@transaction.atomic
    33
    -def wx_order_create_api(request):
    34
    -    """ 订单创建 """
    35
    -    group_id = request.POST.get('group_id', '')
    36
    -    user_id = request.POST.get('user_id', '')
    37
    -    photo_id = request.POST.get('photo_id', '')
    38
    -    photo_type = request.POST.get('photo_type', 'nomark')  # nomark for 去除水印, origin for 获取高清图
    39
    -
    40
    -    photo_type_int = OrderInfo.ORIGIN if photo_type == 'origin' else OrderInfo.NOMARK
    41
    -
    42
    -    # 用户校验
    43
    -    try:
    44
    -        user = UserInfo.objects.get(user_id=user_id)
    45
    -    except UserInfo.DoesNotExist:
    46
    -        return response(UserStatusCode.USER_NOT_FOUND)
    47
    -
    48
    -    # 群组照片校验
    49
    -    try:
    50
    -        group_photo = GroupPhotoInfo.objects.get(photo_id=photo_id, status=True)
    51
    -    except GroupPhotoInfo.DoesNotExist:
    52
    -        return response(GroupPhotoStatusCode.GROUP_PHOTO_NOT_FOUND)
    53
    -
    54
    -    # 判断是否重复购买
    55
    -    if OrderInfo.objects.filter(photo_id=photo_id, photo_type=photo_type_int, from_uid=user_id, pay_status=OrderInfo.PAID, status=True).exists():
    56
    -        return response(OrderStatusCode.WX_ORDER_PAID_ALREADY_EXISTS)
    57
    -
    58
    -    body = request.POST.get('body', '')  # 商品描述
    59
    -    total_fee = int(request.POST.get('total_fee', 0))  # 总金额,单位分
    60
    -
    61
    -    # 金额校验
    62
    -    if get_group_photo_price(group_photo, photo_type) != total_fee:
    63
    -        return response(OrderStatusCode.FEE_CHECK_FAIL)
    64
    -
    65
    -    # 获取 from_uid, to_uid
    66
    -    from_uid = user_id
    67
    -    to_uid = group_photo.lensman_id or group_photo.user_id
    68
    -
    69
    -    # JSAPI--公众号支付、NATIVE--原生扫码支付、APP--app支付,统一下单接口trade_type的传参可参考这里
    70
    -    trade_type = request.POST.get('trade_type', '')
    71
    -
    72
    -    # 根据 trade_type 获取 wechat 配置
    73
    -    wxcfg = WECHAT.get(trade_type, {})
    74
    -    # WeChatPay 初始化
    75
    -    wxpay = WeChatPay(wxcfg.get('appID'), wxcfg.get('apiKey'), wxcfg.get('mchID'))
    76
    -
    77
    -    # 生成订单
    78
    -    order = OrderInfo.objects.create(
    79
    -        group_id=group_id,
    80
    -        photo_id=photo_id,
    81
    -        lensman_photo_id=group_photo.lensman_photo_id,
    82
    -        photo_type=photo_type_int,
    83
    -        from_uid=from_uid,
    84
    -        to_uid=to_uid,
    85
    -        session_id=group_photo.session_id,
    86
    -        total_fee=total_fee,
    87
    -        trade_type=trade_type,
    88
    -    )
    89
    -
    90
    -    try:
    91
    -        prepay_data = wxpay.order.create(
    92
    -            body=body,
    93
    -            notify_url=settings.API_DOMAIN + '/wx/notify_url',
    94
    -            out_trade_no=order.order_id,
    95
    -            total_fee=total_fee,
    96
    -            trade_type=get_trade_type(trade_type),
    97
    -            openid=get_user_openid(user, trade_type),  # 可选,用户在商户appid下的唯一标识。trade_type=JSAPI,此参数必传
    98
    -        )
    99
    -    except WeChatPayException as e:
    100
    -        order.unifiedorder_result = e.message
    101
    -        order.save()
    102
    -        return response(OrderStatusCode.WX_UNIFIED_ORDER_FAIL)
    103
    -
    104
    -    prepay_id = prepay_data.get('prepay_id', '')
    105
    -    order.prepay_id = prepay_id
    106
    -    order.save()
    107
    -
    108
    -    if trade_type == 'JSAPI' or trade_type == 'MINIAPP':
    109
    -        wxpay_params = wxpay.jsapi.get_jsapi_params(prepay_id)
    110
    -    elif trade_type == 'APP':
    111
    -        wxpay_params = wxpay.order.get_appapi_params(prepay_id)
    112
    -
    113
    -    return response(200, 'Order Create Success', u'订单创建成功', {
    114
    -        'order_id': order.order_id,
    115
    -        'prepay_id': prepay_id,
    116
    -        'wxpay_params': wxpay_params,
    117
    -    })
    118
    -
    119
    -
    120
    -def order_paid_success(order):
    121
    -    if order.pay_status == OrderInfo.PAID:
    122
    -        return
    123
    -
    124
    -    if order.photo_type == OrderInfo.NOMARK:
    125
    -        order.photo_status = OrderInfo.FETCHED
    126
    -    order.pay_status = OrderInfo.PAID
    127
    -    order.paid_at = tc.utc_datetime()
    128
    -    order.save()
    129
    -
    130
    -    porder, created = GroupPhotoOrderInfo.objects.select_for_update().get_or_create(
    131
    -        group_id=order.group_id,
    132
    -        session_id=order.session_id,
    133
    -        user_id=order.from_uid,
    134
    -        photo_id=order.photo_id,
    135
    -        lensman_photo_id=order.lensman_photo_id,
    136
    -    )
    137
    -    photo = PhotosInfo.objects.get(
    138
    -        lensman_id=order.to_uid,
    139
    -        session_id=order.session_id,
    140
    -        photo_id=order.lensman_photo_id,
    141
    -    )
    142
    -    if order.photo_type == OrderInfo.NOMARK:
    143
    -        porder.m_photo_path = photo.m_photo_path
    144
    -    elif order.photo_type == OrderInfo.ORIGIN:
    145
    -        porder.r_photo_path = photo.r_photo_path
    146
    -    porder.save()
    147
    -
    148
    -    set_lensman_order_record(porder)
    149
    -
    150
    -    to_uid = order.to_uid
    151
    -    total_fee = order.total_fee
    152
    -
    153
    -    try:
    154
    -        user = UserInfo.objects.select_for_update().get(user_id=to_uid)
    155
    -    except UserInfo.DoesNotExist:
    156
    -        return
    157
    -
    158
    -    if order.photo_type == OrderInfo.NOMARK:
    159
    -        # 余额增加
    160
    -        amount, freeze_income_amount = total_fee, 0
    161
    -        user.balance += amount
    162
    -        # Redis 数值更新
    163
    -        set_brief_info(to_uid, order.photo_type, total_fee)
    164
    -        # 余额记录
    165
    -        UserIncomeExpensesInfo.objects.create(
    166
    -            user_id=to_uid,
    167
    -            photo_id=order.photo_id,
    168
    -            type=UserIncomeExpensesInfo.INCOME,
    169
    -            amount=amount,
    170
    -            balance=user.balance,
    171
    -            freeze_income_amount=freeze_income_amount,
    172
    -            freeze_income_balance=user.freeze_income_balance,
    173
    -            remark=u'图片购买',
    174
    -        )
    175
    -    elif order.photo_type == OrderInfo.ORIGIN:
    176
    -        amount, freeze_income_amount = 0, total_fee
    177
    -        user.freeze_income_balance += freeze_income_amount
    178
    -    user.save()
    179
    -
    180
    -
    181
    -def order_paid_fail(order):
    182
    -    if order.pay_status == OrderInfo.FAIL:
    183
    -        return
    184
    -
    185
    -    order.pay_status = OrderInfo.FAIL
    186
    -    order.save()
    187
    -
    188
    -
    189
    -@logit
    190
    -@transaction.atomic
    191
    -def wx_order_query_api(request):
    192
    -    """ 订单查询 """
    193
    -    order_id = request.POST.get('order_id', '')
    194
    -    transaction_id = request.POST.get('transaction_id', '')
    195
    -
    196
    -    try:
    197
    -        order = OrderInfo.objects.select_for_update().get(order_id=order_id, status=True)
    198
    -    except OrderInfo.DoesNotExist:
    199
    -        return response(OrderStatusCode.WX_ORDER_NOT_FOUND)
    200
    -
    201
    -    if order.pay_status == OrderInfo.PAID:
    202
    -        return response(200, 'Order Pay Success', u'订单支付成功')
    203
    -    elif order.pay_status == OrderInfo.FAIL:
    204
    -        return response(OrderStatusCode.WX_ORDER_PAY_FAIL)
    205
    -
    206
    -    # 根据 trade_type 获取 wechat 配置
    207
    -    wxcfg = WECHAT.get(order.trade_type, {})
    208
    -    # WeChatPay 初始化
    209
    -    wxpay = WeChatPay(wxcfg.get('appID'), wxcfg.get('apiKey'), wxcfg.get('mchID'))
    210
    -
    211
    -    # 订单查询
    212
    -    query_data = wxpay.order.query(transaction_id, order_id)
    213
    -    # 签名校验
    214
    -    if not check_signature(query_data, wxcfg.get('apiKey')):
    215
    -        return response(OrderStatusCode.SIGN_CHECK_FAIL)
    216
    -
    217
    -    order.notify_msg = query_data
    218
    -    order.transaction_id = query_data.get('transaction_id', '')
    219
    -    order.save()
    220
    -
    221
    -    # 交易状态
    222
    -    trade_state = query_data.get('trade_state')
    223
    -    # 订单状态判断更新
    224
    -    if trade_state == 'SUCCESS':  # 订单支付成功
    225
    -        order_paid_success(order)
    226
    -        return response(200, 'Order Pay Success', u'订单支付成功')
    227
    -    elif trade_state == 'NOTPAY':  # 订单未支付
    228
    -        return response(OrderStatusCode.WX_ORDER_NOT_PAY)
    229
    -    elif trade_state == 'USERPAYING':  # 订单支付中
    230
    -        return response(OrderStatusCode.WX_ORDER_PAYING)
    231
    -    else:  # 订单支付失败
    232
    -        order_paid_fail(order)
    233
    -        return response(OrderStatusCode.WX_ORDER_PAY_FAIL)
    234
    -
    235
    -
    236
    -@logit
    237
    -@transaction.atomic
    238
    -def wx_order_list_api(request):
    239
    -    """ 订单列表 """
    240
    -    user_id = request.POST.get('user_id', '')
    241
    -    page = int(request.POST.get('page', 1))
    242
    -    num = int(request.POST.get('num', settings.ORDER_NUM_PER_PAGE))
    243
    -
    244
    -    orders = OrderInfo.objects.filter(from_uid=user_id, pay_status=OrderInfo.PAID, status=True).order_by('-pk')
    245
    -    orders, left = pagination(orders, page, num)
    246
    -    orders = [order.data(user_id) for order in orders]
    247
    -
    248
    -    return response(200, 'Get Order List Success', u'获取订单列表成功', {
    249
    -        'orders': orders,
    250
    -        'left': left,
    251
    -    })
    252
    -
    253
    -
    254
    -@logit
    255
    -@transaction.atomic
    256
    -def wx_order_detail_api(request):
    257
    -    """ 订单详情 """
    258
    -    user_id = request.POST.get('user_id', '')
    259
    -    order_id = request.POST.get('order_id', '')
    260
    -
    261
    -    try:
    262
    -        order = OrderInfo.objects.get(order_id=order_id, status=True)
    263
    -    except OrderInfo.DoesNotExist:
    264
    -        return response(OrderStatusCode.WX_ORDER_NOT_FOUND)
    265
    -
    266
    -    if user_id not in [order.from_uid, order.to_uid]:
    267
    -        return response(OrderStatusCode.NO_DETAIL_PERMISSION)
    268
    -
    269
    -    return response(200, 'Get Order Detail Success', u'获取订单详情成功', order.data(user_id))
    270
    -
    271
    -
    272
    -@logit
    273
    -@transaction.atomic
    274
    -def wx_notify_url_api(request):
    275
    -    """ 支付异步通知回调地址 """
    276
    -    notify_data, success = check_pay_notify(request.body, wx_configs=settings.WECHAT)
    277
    -    if not success:
    278
    -        return HttpResponse(WXPAY_NOTIFY_FAIL)
    279
    -
    280
    -    try:
    281
    -        order = OrderInfo.objects.select_for_update().get(order_id=notify_data.get('out_trade_no', ''), status=True)
    282
    -    except OrderInfo.DoesNotExist:
    283
    -        return HttpResponse(WXPAY_NOTIFY_FAIL)
    284
    -
    285
    -    order.notify_msg = request.body
    286
    -    order.transaction_id = notify_data.get('transaction_id', '')
    287
    -    order.save()
    288
    -
    289
    -    result_code = notify_data.get('result_code', '')
    290
    -    if result_code == 'SUCCESS':
    291
    -        order_paid_success(order)
    292
    -    else:
    293
    -        order_paid_fail(order)
    294
    -
    295
    -    return HttpResponse(WXPAY_NOTIFY_SUCCESS)
    296
    -
    297
    -
    298
    -@logit
    299
    -@transaction.atomic
    300
    -def wx_balance_withdraw_api(request):
    301
    -    user_id = request.POST.get('user_id', '')
    302
    -
    303
    -    # 用户校验
    304
    -    try:
    305
    -        user = UserInfo.objects.select_for_update().get(user_id=user_id)
    306
    -    except UserInfo.DoesNotExist:
    307
    -        return response(UserStatusCode.USER_NOT_FOUND)
    308
    -
    309
    -    # JSAPI--公众号支付、NATIVE--原生扫码支付、APP--app支付,统一下单接口trade_type的传参可参考这里
    310
    -    trade_type = request.POST.get('trade_type', '')
    311
    -    # TRANSFER--企业付款、PACKET--现金红包, 余额提现接口withdraw_type的传参可参考这里
    312
    -    withdraw_type = request.POST.get('withdraw_type', 'TRANSFER')
    313
    -    amount = int(request.POST.get('amount', 0))
    314
    -
    315
    -    if not user.openid:
    316
    -        return response(WechatStatusCode.OPENID_NOT_FOUND)
    317
    -
    318
    -    if user.balance < amount:
    319
    -        return response(WithdrawStatusCode.BALANCE_NOT_ENOUGH)
    320
    -
    321
    -    # 根据 trade_type 获取 wechat 配置
    322
    -    wxcfg = WECHAT.get(trade_type, {})
    323
    -    # WeChatPay 初始化
    324
    -    wxpay = WeChatPay(wxcfg.get('appID'), wxcfg.get('apiKey'), wxcfg.get('mchID'), mch_cert=wxcfg.get('mch_cert'), mch_key=wxcfg.get('mch_key'))
    325
    -
    326
    -    if withdraw_type == 'TRANSFER':
    327
    -        ret_data = wxpay.transfer.transfer(user.openid, amount, u'摄影师余额提现,企业付款', check_name='NO_CHECK')
    328
    -    elif withdraw_type == 'PACKET':
    329
    -        wxrpk = wxcfg.get('redpack', {})
    330
    -        ret_data = wxpay.redpack.send(
    331
    -            user.openid,
    332
    -            amount,
    333
    -            send_name=wxrpk.get('SEND_NAME'),
    334
    -            nick_name=wxrpk.get('NICK_NAME'),
    335
    -            act_name=wxrpk.get('ACT_NAME'),
    336
    -            wishing=wxrpk.get('WISHING'),
    337
    -            remark=wxrpk.get('REMARK'),
    338
    -        )
    339
    -
    340
    -    # 根据 ret_data 判断是否提现成功, 成功则减余额, 失败则提示
    341
    -    user.balance -= amount
    342
    -    user.save()
    343
    -
    344
    -    return response(200, 'Withdraw Success', u'提现成功', {})

    + 0 - 0
    photo/__init__.py


    + 0 - 25
    photo/admin.py

    @@ -1,25 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -
    3
    -from django.contrib import admin
    4
    -
    5
    -from photo.models import PhotosInfo, PhotoUUIDInfo, UUIDInfo
    6
    -
    7
    -
    8
    -class UUIDInfoAdmin(admin.ModelAdmin):
    9
    -    list_display = ('uuid', 'lensman_id', 'status', 'created_at', 'updated_at')
    10
    -    list_filter = ('lensman_id', 'status')
    11
    -
    12
    -
    13
    -class PhotoUUIDInfoAdmin(admin.ModelAdmin):
    14
    -    list_display = ('photo_md5', 'photo_path', 'photo_watermark_path', 'photo_thumbnail_path', 'photo_thumbnail2_path', 'status', 'created_at', 'updated_at')
    15
    -    list_filter = ('status', )
    16
    -
    17
    -
    18
    -class PhotosInfoAdmin(admin.ModelAdmin):
    19
    -    list_display = ('lensman_id', 'session_id', 'photo_id', 'p_photo_path', 'm_photo_path', 'l_photo_path', 'r_photo_path', 'status', 'created_at', 'updated_at')
    20
    -    list_filter = ('lensman_id', 'status')
    21
    -
    22
    -
    23
    -# admin.site.register(UUIDInfo, UUIDInfoAdmin)
    24
    -# admin.site.register(PhotosInfo, PhotosInfoAdmin)
    25
    -# admin.site.register(PhotoUUIDInfo, PhotoUUIDInfoAdmin)

    + 0 - 34
    photo/migrations/0001_initial.py

    @@ -1,34 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -from __future__ import unicode_literals
    3
    -
    4
    -from django.db import models, migrations
    5
    -
    6
    -
    7
    -class Migration(migrations.Migration):
    8
    -
    9
    -    dependencies = [
    10
    -    ]
    11
    -
    12
    -    operations = [
    13
    -        migrations.CreateModel(
    14
    -            name='PhotosInfo',
    15
    -            fields=[
    16
    -                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
    17
    -                ('status', models.BooleanField(default=True, help_text='\u72b6\u6001', verbose_name='status')),
    18
    -                ('created_at', models.DateTimeField(help_text='\u521b\u5efa\u65f6\u95f4', verbose_name='created_at', auto_now_add=True)),
    19
    -                ('updated_at', models.DateTimeField(help_text='\u66f4\u65b0\u65f6\u95f4', verbose_name='updated_at', auto_now=True)),
    20
    -                ('lesman_id', models.CharField(max_length=255, blank=True, help_text='\u6444\u5f71\u5e08\u552f\u4e00\u6807\u8bc6', null=True, verbose_name='lesman_id', db_index=True)),
    21
    -                ('session_id', models.CharField(max_length=255, blank=True, help_text='\u7167\u7247\u7ec4\u552f\u4e00\u6807\u8bc6', null=True, verbose_name='session_id', db_index=True)),
    22
    -                ('photo_id', models.CharField(null=True, max_length=255, blank=True, help_text='\u7167\u7247\u552f\u4e00\u6807\u8bc6', unique=True, verbose_name='photo_id', db_index=True)),
    23
    -                ('photo_path', models.CharField(help_text='\u7167\u7247\u5b58\u653e\u8def\u5f84', max_length=255, null=True, verbose_name='photo_path', blank=True)),
    24
    -            ],
    25
    -            options={
    26
    -                'verbose_name': 'photosinfo',
    27
    -                'verbose_name_plural': 'photosinfo',
    28
    -            },
    29
    -        ),
    30
    -        migrations.AlterIndexTogether(
    31
    -            name='photosinfo',
    32
    -            index_together=set([('lesman_id', 'session_id')]),
    33
    -        ),
    34
    -    ]

    + 0 - 27
    photo/migrations/0002_auto_20151113_1419.py

    @@ -1,27 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -from __future__ import unicode_literals
    3
    -
    4
    -from django.db import models, migrations
    5
    -
    6
    -
    7
    -class Migration(migrations.Migration):
    8
    -
    9
    -    dependencies = [
    10
    -        ('photo', '0001_initial'),
    11
    -    ]
    12
    -
    13
    -    operations = [
    14
    -        migrations.AddField(
    15
    -            model_name='photosinfo',
    16
    -            name='lensman_id',
    17
    -            field=models.CharField(max_length=255, blank=True, help_text='\u6444\u5f71\u5e08\u552f\u4e00\u6807\u8bc6', null=True, verbose_name='lensman_id', db_index=True),
    18
    -        ),
    19
    -        migrations.AlterIndexTogether(
    20
    -            name='photosinfo',
    21
    -            index_together=set([('lensman_id', 'session_id')]),
    22
    -        ),
    23
    -        migrations.RemoveField(
    24
    -            model_name='photosinfo',
    25
    -            name='lesman_id',
    26
    -        ),
    27
    -    ]

    + 0 - 29
    photo/migrations/0003_uuidinfo.py

    @@ -1,29 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -from __future__ import unicode_literals
    3
    -
    4
    -from django.db import models, migrations
    5
    -
    6
    -
    7
    -class Migration(migrations.Migration):
    8
    -
    9
    -    dependencies = [
    10
    -        ('photo', '0002_auto_20151113_1419'),
    11
    -    ]
    12
    -
    13
    -    operations = [
    14
    -        migrations.CreateModel(
    15
    -            name='UUIDInfo',
    16
    -            fields=[
    17
    -                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
    18
    -                ('status', models.BooleanField(default=True, help_text='\u72b6\u6001', verbose_name='status')),
    19
    -                ('created_at', models.DateTimeField(help_text='\u521b\u5efa\u65f6\u95f4', verbose_name='created_at', auto_now_add=True)),
    20
    -                ('updated_at', models.DateTimeField(help_text='\u66f4\u65b0\u65f6\u95f4', verbose_name='updated_at', auto_now=True)),
    21
    -                ('uuid', models.CharField(null=True, max_length=22, blank=True, help_text='\u552f\u4e00\u6807\u8bc6', unique=True, verbose_name='uuid', db_index=True)),
    22
    -                ('lensman_id', models.CharField(max_length=255, blank=True, help_text='\u6444\u5f71\u5e08\u552f\u4e00\u6807\u8bc6', null=True, verbose_name='lensman_id', db_index=True)),
    23
    -            ],
    24
    -            options={
    25
    -                'verbose_name': 'uuidinfo',
    26
    -                'verbose_name_plural': 'uuidinfo',
    27
    -            },
    28
    -        ),
    29
    -    ]

    + 0 - 19
    photo/migrations/0004_photosinfo_photo_name.py

    @@ -1,19 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -from __future__ import unicode_literals
    3
    -
    4
    -from django.db import models, migrations
    5
    -
    6
    -
    7
    -class Migration(migrations.Migration):
    8
    -
    9
    -    dependencies = [
    10
    -        ('photo', '0003_uuidinfo'),
    11
    -    ]
    12
    -
    13
    -    operations = [
    14
    -        migrations.AddField(
    15
    -            model_name='photosinfo',
    16
    -            name='photo_name',
    17
    -            field=models.CharField(help_text='\u7167\u7247\u5b58\u653e\u540d\u79f0', max_length=255, null=True, verbose_name='photo_name', blank=True),
    18
    -        ),
    19
    -    ]

    + 0 - 42
    photo/migrations/0005_auto_20151207_1811.py

    @@ -1,42 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -from __future__ import unicode_literals
    3
    -
    4
    -from django.db import models, migrations
    5
    -
    6
    -
    7
    -class Migration(migrations.Migration):
    8
    -
    9
    -    dependencies = [
    10
    -        ('photo', '0004_photosinfo_photo_name'),
    11
    -    ]
    12
    -
    13
    -    operations = [
    14
    -        migrations.RemoveField(
    15
    -            model_name='photosinfo',
    16
    -            name='photo_name',
    17
    -        ),
    18
    -        migrations.RemoveField(
    19
    -            model_name='photosinfo',
    20
    -            name='photo_path',
    21
    -        ),
    22
    -        migrations.AddField(
    23
    -            model_name='photosinfo',
    24
    -            name='l_photo_path',
    25
    -            field=models.CharField(help_text='\u7167\u7247\u5b58\u653e\u8def\u5f84', max_length=255, null=True, verbose_name='l_photo_path', blank=True),
    26
    -        ),
    27
    -        migrations.AddField(
    28
    -            model_name='photosinfo',
    29
    -            name='m_photo_path',
    30
    -            field=models.CharField(help_text='\u7167\u7247\u5b58\u653e\u8def\u5f84', max_length=255, null=True, verbose_name='m_photo_path', blank=True),
    31
    -        ),
    32
    -        migrations.AddField(
    33
    -            model_name='photosinfo',
    34
    -            name='p_photo_path',
    35
    -            field=models.CharField(help_text='\u7167\u7247\u5b58\u653e\u8def\u5f84', max_length=255, null=True, verbose_name='p_photo_path', blank=True),
    36
    -        ),
    37
    -        migrations.AddField(
    38
    -            model_name='photosinfo',
    39
    -            name='r_photo_path',
    40
    -            field=models.CharField(help_text='\u7167\u7247\u5b58\u653e\u8def\u5f84', max_length=255, null=True, verbose_name='r_photo_path', blank=True),
    41
    -        ),
    42
    -    ]

    + 0 - 24
    photo/migrations/0006_auto_20160120_1830.py

    @@ -1,24 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -from __future__ import unicode_literals
    3
    -
    4
    -from django.db import models, migrations
    5
    -
    6
    -
    7
    -class Migration(migrations.Migration):
    8
    -
    9
    -    dependencies = [
    10
    -        ('photo', '0005_auto_20151207_1811'),
    11
    -    ]
    12
    -
    13
    -    operations = [
    14
    -        migrations.AlterField(
    15
    -            model_name='photosinfo',
    16
    -            name='status',
    17
    -            field=models.BooleanField(default=True, help_text='\u72b6\u6001', db_index=True, verbose_name='status'),
    18
    -        ),
    19
    -        migrations.AlterField(
    20
    -            model_name='uuidinfo',
    21
    -            name='status',
    22
    -            field=models.BooleanField(default=True, help_text='\u72b6\u6001', db_index=True, verbose_name='status'),
    23
    -        ),
    24
    -    ]

    + 0 - 34
    photo/migrations/0007_auto_20160422_1322.py

    @@ -1,34 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -from __future__ import unicode_literals
    3
    -
    4
    -from django.db import models, migrations
    5
    -
    6
    -
    7
    -class Migration(migrations.Migration):
    8
    -
    9
    -    dependencies = [
    10
    -        ('photo', '0006_auto_20160120_1830'),
    11
    -    ]
    12
    -
    13
    -    operations = [
    14
    -        migrations.AlterField(
    15
    -            model_name='photosinfo',
    16
    -            name='l_photo_path',
    17
    -            field=models.CharField(help_text='\u7167\u7247\u5b58\u653e\u8def\u5f84\uff0c\u7f8e\u5316\u5927\u56fe', max_length=255, null=True, verbose_name='l_photo_path', blank=True),
    18
    -        ),
    19
    -        migrations.AlterField(
    20
    -            model_name='photosinfo',
    21
    -            name='m_photo_path',
    22
    -            field=models.CharField(help_text='\u7167\u7247\u5b58\u653e\u8def\u5f84\uff0c\u63a7\u5236\u5668\u4e0a\u4f20\uff0c\u65e0\u6c34\u5370', max_length=255, null=True, verbose_name='m_photo_path', blank=True),
    23
    -        ),
    24
    -        migrations.AlterField(
    25
    -            model_name='photosinfo',
    26
    -            name='p_photo_path',
    27
    -            field=models.CharField(help_text='\u7167\u7247\u5b58\u653e\u8def\u5f84\uff0c\u63a7\u5236\u5668\u4e0a\u4f20\uff0c\u6709\u6c34\u5370\uff0c\u670d\u52a1\u5668\u6dfb\u52a0', max_length=255, null=True, verbose_name='p_photo_path', blank=True),
    28
    -        ),
    29
    -        migrations.AlterField(
    30
    -            model_name='photosinfo',
    31
    -            name='r_photo_path',
    32
    -            field=models.CharField(help_text='\u7167\u7247\u5b58\u653e\u8def\u5f84\uff0c\u9ad8\u6e05\u5927\u56fe', max_length=255, null=True, verbose_name='r_photo_path', blank=True),
    33
    -        ),
    34
    -    ]

    + 0 - 24
    photo/migrations/0008_auto_20160901_1439.py

    @@ -1,24 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -from __future__ import unicode_literals
    3
    -
    4
    -from django.db import models, migrations
    5
    -
    6
    -
    7
    -class Migration(migrations.Migration):
    8
    -
    9
    -    dependencies = [
    10
    -        ('photo', '0007_auto_20160422_1322'),
    11
    -    ]
    12
    -
    13
    -    operations = [
    14
    -        migrations.AlterField(
    15
    -            model_name='photosinfo',
    16
    -            name='m_photo_path',
    17
    -            field=models.CharField(help_text='\u7167\u7247\u5b58\u653e\u8def\u5f84\uff0cBox\u4e0a\u4f20\uff0c\u65e0\u6c34\u5370', max_length=255, null=True, verbose_name='m_photo_path', blank=True),
    18
    -        ),
    19
    -        migrations.AlterField(
    20
    -            model_name='photosinfo',
    21
    -            name='p_photo_path',
    22
    -            field=models.CharField(help_text='\u7167\u7247\u5b58\u653e\u8def\u5f84\uff0cBox\u4e0a\u4f20\uff0c\u6709\u6c34\u5370\uff0c\u670d\u52a1\u5668\u6dfb\u52a0', max_length=255, null=True, verbose_name='p_photo_path', blank=True),
    23
    -        ),
    24
    -    ]

    + 0 - 23
    photo/migrations/0009_auto_20160907_1018.py

    @@ -1,23 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -from __future__ import unicode_literals
    3
    -
    4
    -from django.db import models, migrations
    5
    -
    6
    -
    7
    -class Migration(migrations.Migration):
    8
    -
    9
    -    dependencies = [
    10
    -        ('photo', '0008_auto_20160901_1439'),
    11
    -    ]
    12
    -
    13
    -    operations = [
    14
    -        migrations.AlterField(
    15
    -            model_name='photosinfo',
    16
    -            name='photo_id',
    17
    -            field=models.CharField(max_length=255, blank=True, help_text='\u7167\u7247\u552f\u4e00\u6807\u8bc6', null=True, verbose_name='photo_id', db_index=True),
    18
    -        ),
    19
    -        migrations.AlterUniqueTogether(
    20
    -            name='photosinfo',
    21
    -            unique_together=set([('lensman_id', 'session_id', 'photo_id')]),
    22
    -        ),
    23
    -    ]

    + 0 - 29
    photo/migrations/0010_photouuidinfo.py

    @@ -1,29 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -from __future__ import unicode_literals
    3
    -
    4
    -from django.db import models, migrations
    5
    -
    6
    -
    7
    -class Migration(migrations.Migration):
    8
    -
    9
    -    dependencies = [
    10
    -        ('photo', '0009_auto_20160907_1018'),
    11
    -    ]
    12
    -
    13
    -    operations = [
    14
    -        migrations.CreateModel(
    15
    -            name='PhotoUUIDInfo',
    16
    -            fields=[
    17
    -                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
    18
    -                ('status', models.BooleanField(default=True, help_text='\u72b6\u6001', db_index=True, verbose_name='status')),
    19
    -                ('created_at', models.DateTimeField(help_text='\u521b\u5efa\u65f6\u95f4', verbose_name='created_at', auto_now_add=True)),
    20
    -                ('updated_at', models.DateTimeField(help_text='\u66f4\u65b0\u65f6\u95f4', verbose_name='updated_at', auto_now=True)),
    21
    -                ('photo_md5', models.CharField(null=True, max_length=255, blank=True, help_text='\u7167\u7247\u552f\u4e00\u6807\u8bc6', unique=True, verbose_name='photo_md5', db_index=True)),
    22
    -                ('photo_path', models.CharField(help_text='\u7167\u7247\u8def\u5f84', max_length=255, null=True, verbose_name='photo_path', blank=True)),
    23
    -            ],
    24
    -            options={
    25
    -                'verbose_name': 'photouuidinfo',
    26
    -                'verbose_name_plural': 'photouuidinfo',
    27
    -            },
    28
    -        ),
    29
    -    ]

    + 0 - 69
    photo/migrations/0011_auto_20170119_1207.py

    @@ -1,69 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -from __future__ import unicode_literals
    3
    -
    4
    -from django.db import models, migrations
    5
    -
    6
    -
    7
    -class Migration(migrations.Migration):
    8
    -
    9
    -    dependencies = [
    10
    -        ('photo', '0010_photouuidinfo'),
    11
    -    ]
    12
    -
    13
    -    operations = [
    14
    -        migrations.AddField(
    15
    -            model_name='photouuidinfo',
    16
    -            name='photo_h',
    17
    -            field=models.IntegerField(default=0, help_text='\u7167\u7247\u9ad8\u5ea6', verbose_name='photo_h'),
    18
    -        ),
    19
    -        migrations.AddField(
    20
    -            model_name='photouuidinfo',
    21
    -            name='photo_thumbnail2_h',
    22
    -            field=models.IntegerField(default=0, help_text='\u7167\u7247\u7f29\u7565\u56fe\u9ad8\u5ea6', verbose_name='photo_thumbnail2_h'),
    23
    -        ),
    24
    -        migrations.AddField(
    25
    -            model_name='photouuidinfo',
    26
    -            name='photo_thumbnail2_path',
    27
    -            field=models.CharField(help_text='\u7167\u7247\u7f29\u7565\u56fe\u5b58\u653e\u8def\u5f84', max_length=255, null=True, verbose_name='photo_thumbnail2_path', blank=True),
    28
    -        ),
    29
    -        migrations.AddField(
    30
    -            model_name='photouuidinfo',
    31
    -            name='photo_thumbnail2_w',
    32
    -            field=models.IntegerField(default=0, help_text='\u7167\u7247\u7f29\u7565\u56fe\u5bbd\u5ea6', verbose_name='photo_thumbnail2_w'),
    33
    -        ),
    34
    -        migrations.AddField(
    35
    -            model_name='photouuidinfo',
    36
    -            name='photo_thumbnail_h',
    37
    -            field=models.IntegerField(default=0, help_text='\u7167\u7247\u7f29\u7565\u56fe\u9ad8\u5ea6', verbose_name='photo_thumbnail_h'),
    38
    -        ),
    39
    -        migrations.AddField(
    40
    -            model_name='photouuidinfo',
    41
    -            name='photo_thumbnail_path',
    42
    -            field=models.CharField(help_text='\u7167\u7247\u7f29\u7565\u56fe\u5b58\u653e\u8def\u5f84', max_length=255, null=True, verbose_name='photo_thumbnail_path', blank=True),
    43
    -        ),
    44
    -        migrations.AddField(
    45
    -            model_name='photouuidinfo',
    46
    -            name='photo_thumbnail_w',
    47
    -            field=models.IntegerField(default=0, help_text='\u7167\u7247\u7f29\u7565\u56fe\u5bbd\u5ea6', verbose_name='photo_thumbnail_w'),
    48
    -        ),
    49
    -        migrations.AddField(
    50
    -            model_name='photouuidinfo',
    51
    -            name='photo_w',
    52
    -            field=models.IntegerField(default=0, help_text='\u7167\u7247\u5bbd\u5ea6', verbose_name='photo_w'),
    53
    -        ),
    54
    -        migrations.AddField(
    55
    -            model_name='photouuidinfo',
    56
    -            name='photo_watermark_h',
    57
    -            field=models.IntegerField(default=0, help_text='\u7167\u7247\u6c34\u5370\u56fe\u9ad8\u5ea6', verbose_name='photo_watermark_h'),
    58
    -        ),
    59
    -        migrations.AddField(
    60
    -            model_name='photouuidinfo',
    61
    -            name='photo_watermark_path',
    62
    -            field=models.CharField(help_text='\u7167\u7247\u5b58\u653e\u8def\u5f84\uff0cBox\u4e0a\u4f20\uff0c\u6709\u6c34\u5370\uff0c\u670d\u52a1\u5668\u6dfb\u52a0', max_length=255, null=True, verbose_name='photo_watermark_path', blank=True),
    63
    -        ),
    64
    -        migrations.AddField(
    65
    -            model_name='photouuidinfo',
    66
    -            name='photo_watermark_w',
    67
    -            field=models.IntegerField(default=0, help_text='\u7167\u7247\u6c34\u5370\u56fe\u5bbd\u5ea6', verbose_name='photo_watermark_w'),
    68
    -        ),
    69
    -    ]

    + 0 - 60
    photo/migrations/0012_auto_20180101_2220.py

    @@ -1,60 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -# Generated by Django 1.11.3 on 2018-01-01 14:20
    3
    -from __future__ import unicode_literals
    4
    -
    5
    -from django.db import migrations, models
    6
    -
    7
    -
    8
    -class Migration(migrations.Migration):
    9
    -
    10
    -    dependencies = [
    11
    -        ('photo', '0011_auto_20170119_1207'),
    12
    -    ]
    13
    -
    14
    -    operations = [
    15
    -        migrations.AlterField(
    16
    -            model_name='photosinfo',
    17
    -            name='created_at',
    18
    -            field=models.DateTimeField(auto_now_add=True, help_text='Create Time', verbose_name='created_at'),
    19
    -        ),
    20
    -        migrations.AlterField(
    21
    -            model_name='photosinfo',
    22
    -            name='status',
    23
    -            field=models.BooleanField(db_index=True, default=True, help_text='Status', verbose_name='status'),
    24
    -        ),
    25
    -        migrations.AlterField(
    26
    -            model_name='photosinfo',
    27
    -            name='updated_at',
    28
    -            field=models.DateTimeField(auto_now=True, help_text='Update Time', verbose_name='updated_at'),
    29
    -        ),
    30
    -        migrations.AlterField(
    31
    -            model_name='photouuidinfo',
    32
    -            name='created_at',
    33
    -            field=models.DateTimeField(auto_now_add=True, help_text='Create Time', verbose_name='created_at'),
    34
    -        ),
    35
    -        migrations.AlterField(
    36
    -            model_name='photouuidinfo',
    37
    -            name='status',
    38
    -            field=models.BooleanField(db_index=True, default=True, help_text='Status', verbose_name='status'),
    39
    -        ),
    40
    -        migrations.AlterField(
    41
    -            model_name='photouuidinfo',
    42
    -            name='updated_at',
    43
    -            field=models.DateTimeField(auto_now=True, help_text='Update Time', verbose_name='updated_at'),
    44
    -        ),
    45
    -        migrations.AlterField(
    46
    -            model_name='uuidinfo',
    47
    -            name='created_at',
    48
    -            field=models.DateTimeField(auto_now_add=True, help_text='Create Time', verbose_name='created_at'),
    49
    -        ),
    50
    -        migrations.AlterField(
    51
    -            model_name='uuidinfo',
    52
    -            name='status',
    53
    -            field=models.BooleanField(db_index=True, default=True, help_text='Status', verbose_name='status'),
    54
    -        ),
    55
    -        migrations.AlterField(
    56
    -            model_name='uuidinfo',
    57
    -            name='updated_at',
    58
    -            field=models.DateTimeField(auto_now=True, help_text='Update Time', verbose_name='updated_at'),
    59
    -        ),
    60
    -    ]

    + 0 - 80
    photo/migrations/0013_auto_20180103_0446.py

    @@ -1,80 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -# Generated by Django 1.11.3 on 2018-01-02 20:46
    3
    -from __future__ import unicode_literals
    4
    -
    5
    -from django.db import migrations, models
    6
    -
    7
    -
    8
    -class Migration(migrations.Migration):
    9
    -
    10
    -    dependencies = [
    11
    -        ('photo', '0012_auto_20180101_2220'),
    12
    -    ]
    13
    -
    14
    -    operations = [
    15
    -        migrations.AlterField(
    16
    -            model_name='photosinfo',
    17
    -            name='l_photo_path',
    18
    -            field=models.CharField(blank=True, help_text='\u7167\u7247\u5b58\u653e\u8def\u5f84\uff0c\u7f8e\u5316\u5927\u56fe', max_length=32, null=True, verbose_name='l_photo_path'),
    19
    -        ),
    20
    -        migrations.AlterField(
    21
    -            model_name='photosinfo',
    22
    -            name='lensman_id',
    23
    -            field=models.CharField(blank=True, db_index=True, help_text='\u6444\u5f71\u5e08\u552f\u4e00\u6807\u8bc6', max_length=32, null=True, verbose_name='lensman_id'),
    24
    -        ),
    25
    -        migrations.AlterField(
    26
    -            model_name='photosinfo',
    27
    -            name='m_photo_path',
    28
    -            field=models.CharField(blank=True, help_text='\u7167\u7247\u5b58\u653e\u8def\u5f84\uff0cBox\u4e0a\u4f20\uff0c\u65e0\u6c34\u5370', max_length=32, null=True, verbose_name='m_photo_path'),
    29
    -        ),
    30
    -        migrations.AlterField(
    31
    -            model_name='photosinfo',
    32
    -            name='p_photo_path',
    33
    -            field=models.CharField(blank=True, help_text='\u7167\u7247\u5b58\u653e\u8def\u5f84\uff0cBox\u4e0a\u4f20\uff0c\u6709\u6c34\u5370\uff0c\u670d\u52a1\u5668\u6dfb\u52a0', max_length=32, null=True, verbose_name='p_photo_path'),
    34
    -        ),
    35
    -        migrations.AlterField(
    36
    -            model_name='photosinfo',
    37
    -            name='photo_id',
    38
    -            field=models.CharField(blank=True, db_index=True, help_text='\u7167\u7247\u552f\u4e00\u6807\u8bc6', max_length=32, null=True, verbose_name='photo_id'),
    39
    -        ),
    40
    -        migrations.AlterField(
    41
    -            model_name='photosinfo',
    42
    -            name='r_photo_path',
    43
    -            field=models.CharField(blank=True, help_text='\u7167\u7247\u5b58\u653e\u8def\u5f84\uff0c\u9ad8\u6e05\u5927\u56fe', max_length=32, null=True, verbose_name='r_photo_path'),
    44
    -        ),
    45
    -        migrations.AlterField(
    46
    -            model_name='photosinfo',
    47
    -            name='session_id',
    48
    -            field=models.CharField(blank=True, db_index=True, help_text='\u7167\u7247\u7ec4\u552f\u4e00\u6807\u8bc6', max_length=32, null=True, verbose_name='session_id'),
    49
    -        ),
    50
    -        migrations.AlterField(
    51
    -            model_name='photouuidinfo',
    52
    -            name='photo_md5',
    53
    -            field=models.CharField(blank=True, db_index=True, help_text='\u7167\u7247\u552f\u4e00\u6807\u8bc6', max_length=32, null=True, unique=True, verbose_name='photo_md5'),
    54
    -        ),
    55
    -        migrations.AlterField(
    56
    -            model_name='photouuidinfo',
    57
    -            name='photo_path',
    58
    -            field=models.CharField(blank=True, help_text='\u7167\u7247\u8def\u5f84', max_length=32, null=True, verbose_name='photo_path'),
    59
    -        ),
    60
    -        migrations.AlterField(
    61
    -            model_name='photouuidinfo',
    62
    -            name='photo_thumbnail2_path',
    63
    -            field=models.CharField(blank=True, help_text='\u7167\u7247\u7f29\u7565\u56fe\u5b58\u653e\u8def\u5f84', max_length=32, null=True, verbose_name='photo_thumbnail2_path'),
    64
    -        ),
    65
    -        migrations.AlterField(
    66
    -            model_name='photouuidinfo',
    67
    -            name='photo_thumbnail_path',
    68
    -            field=models.CharField(blank=True, help_text='\u7167\u7247\u7f29\u7565\u56fe\u5b58\u653e\u8def\u5f84', max_length=32, null=True, verbose_name='photo_thumbnail_path'),
    69
    -        ),
    70
    -        migrations.AlterField(
    71
    -            model_name='photouuidinfo',
    72
    -            name='photo_watermark_path',
    73
    -            field=models.CharField(blank=True, help_text='\u7167\u7247\u5b58\u653e\u8def\u5f84\uff0cBox\u4e0a\u4f20\uff0c\u6709\u6c34\u5370\uff0c\u670d\u52a1\u5668\u6dfb\u52a0', max_length=32, null=True, verbose_name='photo_watermark_path'),
    74
    -        ),
    75
    -        migrations.AlterField(
    76
    -            model_name='uuidinfo',
    77
    -            name='lensman_id',
    78
    -            field=models.CharField(blank=True, db_index=True, help_text='\u6444\u5f71\u5e08\u552f\u4e00\u6807\u8bc6', max_length=32, null=True, verbose_name='lensman_id'),
    79
    -        ),
    80
    -    ]

    + 0 - 28
    photo/migrations/0014_auto_20201130_0131.py

    @@ -1,28 +0,0 @@
    1
    -# Generated by Django 2.2.15 on 2020-11-29 17:31
    2
    -
    3
    -from django.db import migrations, models
    4
    -
    5
    -
    6
    -class Migration(migrations.Migration):
    7
    -
    8
    -    dependencies = [
    9
    -        ('photo', '0013_auto_20180103_0446'),
    10
    -    ]
    11
    -
    12
    -    operations = [
    13
    -        migrations.AlterField(
    14
    -            model_name='photosinfo',
    15
    -            name='status',
    16
    -            field=models.BooleanField(default=True, help_text='Status', verbose_name='status'),
    17
    -        ),
    18
    -        migrations.AlterField(
    19
    -            model_name='photouuidinfo',
    20
    -            name='status',
    21
    -            field=models.BooleanField(default=True, help_text='Status', verbose_name='status'),
    22
    -        ),
    23
    -        migrations.AlterField(
    24
    -            model_name='uuidinfo',
    25
    -            name='status',
    26
    -            field=models.BooleanField(default=True, help_text='Status', verbose_name='status'),
    27
    -        ),
    28
    -    ]

    + 0 - 0
    photo/migrations/__init__.py


    + 0 - 114
    photo/models.py

    @@ -1,114 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -
    3
    -from django.db import models
    4
    -from django.utils.translation import ugettext_lazy as _
    5
    -from django_models_ext import BaseModelMixin
    6
    -
    7
    -from utils.qiniucdn import qiniu_file_url
    8
    -
    9
    -
    10
    -class UUIDInfo(BaseModelMixin):
    11
    -    uuid = models.CharField(_(u'uuid'), max_length=22, blank=True, null=True, help_text=u'唯一标识', db_index=True, unique=True)
    12
    -    lensman_id = models.CharField(_(u'lensman_id'), max_length=32, blank=True, null=True, help_text=u'摄影师唯一标识', db_index=True)
    13
    -
    14
    -    class Meta:
    15
    -        verbose_name = _('uuidinfo')
    16
    -        verbose_name_plural = _('uuidinfo')
    17
    -
    18
    -    def __unicode__(self):
    19
    -        return u'{0.pk}'.format(self)
    20
    -
    21
    -    @property
    22
    -    def data(self):
    23
    -        return {
    24
    -            'pk': self.pk,
    25
    -            'uuid': self.uuid,
    26
    -            'lensman_id': self.lensman_id,
    27
    -        }
    28
    -
    29
    -
    30
    -class PhotoUUIDInfo(BaseModelMixin):
    31
    -    photo_md5 = models.CharField(_(u'photo_md5'), max_length=32, blank=True, null=True, help_text=u'照片唯一标识', db_index=True, unique=True)
    32
    -
    33
    -    photo_path = models.CharField(_(u'photo_path'), max_length=32, blank=True, null=True, help_text=u'照片路径')
    34
    -    photo_w = models.IntegerField(_(u'photo_w'), default=0, help_text=u'照片宽度')
    35
    -    photo_h = models.IntegerField(_(u'photo_h'), default=0, help_text=u'照片高度')
    36
    -
    37
    -    photo_watermark_path = models.CharField(_(u'photo_watermark_path'), max_length=32, blank=True, null=True, help_text=u'照片存放路径,Box上传,有水印,服务器添加')
    38
    -    photo_watermark_w = models.IntegerField(_(u'photo_watermark_w'), default=0, help_text=u'照片水印图宽度')
    39
    -    photo_watermark_h = models.IntegerField(_(u'photo_watermark_h'), default=0, help_text=u'照片水印图高度')
    40
    -
    41
    -    photo_thumbnail_path = models.CharField(_(u'photo_thumbnail_path'), max_length=32, blank=True, null=True, help_text=u'照片缩略图存放路径')
    42
    -    photo_thumbnail_w = models.IntegerField(_(u'photo_thumbnail_w'), default=0, help_text=u'照片缩略图宽度')
    43
    -    photo_thumbnail_h = models.IntegerField(_(u'photo_thumbnail_h'), default=0, help_text=u'照片缩略图高度')
    44
    -
    45
    -    photo_thumbnail2_path = models.CharField(_(u'photo_thumbnail2_path'), max_length=32, blank=True, null=True, help_text=u'照片缩略图存放路径')
    46
    -    photo_thumbnail2_w = models.IntegerField(_(u'photo_thumbnail2_w'), default=0, help_text=u'照片缩略图宽度')
    47
    -    photo_thumbnail2_h = models.IntegerField(_(u'photo_thumbnail2_h'), default=0, help_text=u'照片缩略图高度')
    48
    -
    49
    -    class Meta:
    50
    -        verbose_name = _('photouuidinfo')
    51
    -        verbose_name_plural = _('photouuidinfo')
    52
    -
    53
    -    def __unicode__(self):
    54
    -        return u'{0.pk}'.format(self)
    55
    -
    56
    -
    57
    -class PhotosInfo(BaseModelMixin):
    58
    -    lensman_id = models.CharField(_(u'lensman_id'), max_length=32, blank=True, null=True, help_text=u'摄影师唯一标识', db_index=True)
    59
    -    session_id = models.CharField(_(u'session_id'), max_length=32, blank=True, null=True, help_text=u'照片组唯一标识', db_index=True)
    60
    -    photo_id = models.CharField(_(u'photo_id'), max_length=32, blank=True, null=True, help_text=u'照片唯一标识', db_index=True)
    61
    -    p_photo_path = models.CharField(_(u'p_photo_path'), max_length=32, blank=True, null=True, help_text=u'照片存放路径,Box上传,有水印,服务器添加')
    62
    -    m_photo_path = models.CharField(_(u'm_photo_path'), max_length=32, blank=True, null=True, help_text=u'照片存放路径,Box上传,无水印')
    63
    -    l_photo_path = models.CharField(_(u'l_photo_path'), max_length=32, blank=True, null=True, help_text=u'照片存放路径,美化大图')
    64
    -    r_photo_path = models.CharField(_(u'r_photo_path'), max_length=32, blank=True, null=True, help_text=u'照片存放路径,高清大图')
    65
    -
    66
    -    class Meta:
    67
    -        verbose_name = _('photosinfo')
    68
    -        verbose_name_plural = _('photosinfo')
    69
    -
    70
    -        index_together = [
    71
    -            ['lensman_id', 'session_id'],
    72
    -        ]
    73
    -
    74
    -        unique_together = (
    75
    -            ('lensman_id', 'session_id', 'photo_id'),
    76
    -        )
    77
    -
    78
    -    def __unicode__(self):
    79
    -        return u'{0.pk}'.format(self)
    80
    -
    81
    -    @property
    82
    -    def p_photo_url(self):
    83
    -        return qiniu_file_url(self.p_photo_path, bucket='watermark')
    84
    -
    85
    -    @property
    86
    -    def m_photo_url(self):
    87
    -        return qiniu_file_url(self.m_photo_path, bucket='photo')
    88
    -
    89
    -    @property
    90
    -    def l_photo_url(self):
    91
    -        return qiniu_file_url(self.l_photo_path, bucket='prettify')
    92
    -
    93
    -    @property
    94
    -    def r_photo_url(self):
    95
    -        return qiniu_file_url(self.r_photo_path, bucket='original')
    96
    -
    97
    -    @property
    98
    -    def data(self):
    99
    -        return {
    100
    -            'pk': self.pk,
    101
    -            'user_id': self.lensman_id,
    102
    -            'session_id': self.session_id,
    103
    -            'photo_id': self.photo_id,
    104
    -        }
    105
    -
    106
    -    @property
    107
    -    def detail(self):
    108
    -        return {
    109
    -            'pk': self.pk,
    110
    -            'user_id': self.lensman_id,
    111
    -            'session_id': self.session_id,
    112
    -            'photo_id': self.photo_id,
    113
    -            'photo_url': self.p_photo_url,
    114
    -        }

    + 0 - 11
    photo/serializers.py

    @@ -1,11 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -
    3
    -from rest_framework import serializers
    4
    -
    5
    -from photo.models import PhotosInfo
    6
    -
    7
    -
    8
    -class PhotosInfoSerializer(serializers.HyperlinkedModelSerializer):
    9
    -    class Meta:
    10
    -        model = PhotosInfo
    11
    -        fields = ('lensman_id', 'session_id', 'photo_id', 'p_photo_path', 'm_photo_path', 'l_photo_path', 'r_photo_path', 'created_at')

    + 0 - 61
    photo/templates/photo/photo_detail.html

    @@ -1,61 +0,0 @@
    1
    -{% load staticfiles %}
    2
    -
    3
    -<!DOCTYPE html>
    4
    -<html lang="zh-CN">
    5
    -    <head>
    6
    -        <meta charset="utf-8">
    7
    -        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    8
    -        <meta name="format-detection" content="telephone=no,email=no,address=no">
    9
    -        <meta name="viewport" content="width=device-width,initial-scale=1.0,user-scalable=no">
    10
    -        <title>照片详情</title>
    11
    -        <style>
    12
    -            body {position:absolute;top:0;right:0;bottom:0;left:0;margin:0;font-family:"Microsoft YaHei","sans-serif","Microsoft Sans Serif","Microsoft JhengHei UI";background:#fff6e6;color:gray}
    13
    -            img {width:100%}
    14
    -
    15
    -            /* For Download Section */
    16
    -            .download_section {position:fixed;right:0;bottom:0;left:0;height:55px;padding:5px;background:#f0f0f0;box-sizing:border-box}
    17
    -            .kodo_icon {width:45px;height:45px;float:left}
    18
    -            .kodo_icon>img {width:100%;height:100%}
    19
    -            .kodo_desc {height:45px;padding:5px 0 0 5px;float:left}
    20
    -            .kodo_name {padding-top:2px;font-size:14px;text-align:left}
    21
    -            .kodo_des {padding-top:2px;font-size:12px;line-height:23px;color:#8f8f8f;text-align:left}
    22
    -            .kodo_download {position:relative;top:5px;width:100px;height:35px;line-height:35px;text-align:center;background:#d13621;color:#fff;border-radius:5px;float:right;text-decoration:none}
    23
    -            /* For PC */
    24
    -            body, .download_section {
    25
    -                max-width: 414px !important;
    26
    -                margin: 0 auto !important;
    27
    -            }
    28
    -        </style>
    29
    -    </head>
    30
    -    <body>
    31
    -        <div class="container">
    32
    -            <article class="text-center">
    33
    -                <img src="{{ photo_url }}">
    34
    -            </article>
    35
    -        </div>
    36
    -
    37
    -        <div id="download_section" class="download_section">
    38
    -            <div class="kodo_icon">
    39
    -                <img src="{% static 'kodo/img/paiai_96_96.png' %}">
    40
    -            </div>
    41
    -            <div class="kodo_desc">
    42
    -                <div class="kodo_name">拍爱</div>
    43
    -                <div class="kodo_des">即拍即分享</div>
    44
    -            </div>
    45
    -            <a href="https://api.pai.ai/op/download" target="_blank" id="kodo_download" class="kodo_download">立即下载</a>
    46
    -        </div>
    47
    -
    48
    -        <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/zepto/1.1.6/zepto.min.js"></script>
    49
    -        <script type="text/javascript" src="//res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
    50
    -        <script type="text/javascript" src="{% static 'kodo/js/jswe-0.0.4.js' %}"></script>
    51
    -        <script>
    52
    -            V.initWxData({
    53
    -                imgUrl: "http://pai.ai/static/kodo/img/paiai_96_96.png",
    54
    -                link: window.location.href,
    55
    -                desc: "我使用拍爱分享了一张美图,你也快来试试吧",
    56
    -                title: "拍爱",
    57
    -                timeLine: ""
    58
    -            }, true);
    59
    -        </script>
    60
    -    </body>
    61
    -</html>

    + 0 - 63
    photo/templates/photo/session_detail.html

    @@ -1,63 +0,0 @@
    1
    -{% load staticfiles %}
    2
    -
    3
    -<!DOCTYPE html>
    4
    -<html lang="zh-CN">
    5
    -    <head>
    6
    -        <meta charset="utf-8">
    7
    -        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    8
    -        <meta name="format-detection" content="telephone=no,email=no,address=no">
    9
    -        <meta name="viewport" content="width=device-width,initial-scale=1.0,user-scalable=no">
    10
    -        <title>照片列表</title>
    11
    -        <style>
    12
    -            body {position:absolute;top:0;right:0;bottom:0;left:0;margin:0;font-family:"Microsoft YaHei","sans-serif","Microsoft Sans Serif","Microsoft JhengHei UI";background:#fff6e6;color:gray}
    13
    -            img {width:100%}
    14
    -
    15
    -            /* For Download Section */
    16
    -            .download_section {position:fixed;right:0;bottom:0;left:0;height:55px;padding:5px;background:#f0f0f0;box-sizing:border-box}
    17
    -            .kodo_icon {width:45px;height:45px;float:left}
    18
    -            .kodo_icon>img {width:100%;height:100%}
    19
    -            .kodo_desc {height:45px;padding:5px 0 0 5px;float:left}
    20
    -            .kodo_name {padding-top:2px;font-size:14px;text-align:left}
    21
    -            .kodo_des {padding-top:2px;font-size:12px;line-height:23px;color:#8f8f8f;text-align:left}
    22
    -            .kodo_download {position:relative;top:5px;width:100px;height:35px;line-height:35px;text-align:center;background:#d13621;color:#fff;border-radius:5px;float:right;text-decoration:none}
    23
    -            /* For PC */
    24
    -            body, .download_section {
    25
    -                max-width: 414px !important;
    26
    -                margin: 0 auto !important;
    27
    -            }
    28
    -        </style>
    29
    -    </head>
    30
    -    <body>
    31
    -        <div class="container">
    32
    -            <article class="text-center">
    33
    -                {% for photo in photos %}
    34
    -                <div><img src="{{ photo.p_photo_url }}"></div>
    35
    -                {% endfor %}
    36
    -            </article>
    37
    -        </div>
    38
    -
    39
    -        <div id="download_section" class="download_section">
    40
    -            <div class="kodo_icon">
    41
    -                <img src="{% static 'kodo/img/paiai_96_96.png' %}">
    42
    -            </div>
    43
    -            <div class="kodo_desc">
    44
    -                <div class="kodo_name">拍爱</div>
    45
    -                <div class="kodo_des">即拍即分享</div>
    46
    -            </div>
    47
    -            <a href="https://api.pai.ai/op/download" target="_blank" id="kodo_download" class="kodo_download">立即下载</a>
    48
    -        </div>
    49
    -
    50
    -        <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/zepto/1.1.6/zepto.min.js"></script>
    51
    -        <script type="text/javascript" src="//res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
    52
    -        <script type="text/javascript" src="{% static 'kodo/js/jswe-0.0.4.js' %}"></script>
    53
    -        <script>
    54
    -            V.initWxData({
    55
    -                imgUrl: "http://pai.ai/static/kodo/img/paiai_96_96.png",
    56
    -                link: window.location.href,
    57
    -                desc: "我使用拍爱分享了一张美图,你也快来试试吧",
    58
    -                title: "拍爱",
    59
    -                timeLine: ""
    60
    -            }, true);
    61
    -        </script>
    62
    -    </body>
    63
    -</html>

    + 0 - 4
    photo/tests.py

    @@ -1,4 +0,0 @@
    1
    -from django.test import TestCase
    2
    -
    3
    -
    4
    -# Create your tests here.

    + 0 - 0
    photo/urls.py


    + 0 - 276
    photo/views.py

    @@ -1,276 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -
    3
    -from django.db import transaction
    4
    -from django.shortcuts import render
    5
    -from django_curtail_uuid import CurtailUUID
    6
    -from django_logit import logit
    7
    -from django_response import response
    8
    -from ipaddr import client_ip
    9
    -from rest_framework import viewsets
    10
    -from TimeConvert import TimeConvert as tc
    11
    -
    12
    -from account.models import LensmanInfo, UserInfo
    13
    -from group.models import GroupInfo, GroupPhotoInfo, GroupUserInfo
    14
    -from photo.models import PhotosInfo
    15
    -from photo.serializers import PhotosInfoSerializer
    16
    -from utils.error.errno_utils import LensmanStatusCode, PhotoStatusCode
    17
    -from utils.redis.connect import r
    18
    -from utils.redis.rgroup import get_group_info, set_group_info, set_group_users_info
    19
    -from utils.redis.rkeys import (GROUP_LAST_PHOTO_PK, GROUP_USERS_DELETED_SET, GROUP_USERS_PASSED_SET,
    20
    -                               GROUP_USERS_QUIT_SET, GROUP_USERS_REFUSED_SET, UUID_LIST)
    21
    -from utils.redis.rprice import get_lensman_price_fixed
    22
    -from utils.redis.ruuid import generate_uuids, update_uuids
    23
    -from utils.storage_qiniu_utils import file_save
    24
    -
    25
    -
    26
    -@logit
    27
    -def uuid_init(request):
    28
    -    """ 生成唯一标识 """
    29
    -    num = int(request.GET.get('num', 1000))
    30
    -
    31
    -    # 生成 UUID
    32
    -    generate_uuids(num)
    33
    -
    34
    -    return response(200, 'UUID Refresh Success', u'UUID 更新成功')
    35
    -
    36
    -
    37
    -# curl -X POST -F user_id=xxxxxxx -F num=100 http://api.pai.ai/uuid
    38
    -@logit
    39
    -@transaction.atomic
    40
    -def uuid(request):
    41
    -    """ 获取唯一标识 """
    42
    -    lensman_id = request.POST.get('user_id', '')
    43
    -    num = int(request.POST.get('num', 100))
    44
    -
    45
    -    # 从 Redis 中 Pop 中指定数量的 UUID
    46
    -    uuids, succeed, left = r.multi_pop(UUID_LIST, num)
    47
    -
    48
    -    # # 异步更新 UUID 数据库中状态
    49
    -    # if uuids:
    50
    -    #     async(update_uuids, lensman_id, uuids)
    51
    -    #
    52
    -    # # 当可用 UUID 数量少于 500 时, 异步创建
    53
    -    # if left < 500:
    54
    -    #     async(generate_uuids)
    55
    -
    56
    -    return response(200, 'Get UUID Success', u'获取唯一标识成功', uuids)
    57
    -
    58
    -
    59
    -# [How to do a PUT request with curl?](http://stackoverflow.com/questions/13782198/how-to-do-a-put-request-with-curl)
    60
    -# Unfortunately, the -T is no substitute for -X PUT if you want to specify parameters with -d or -F.
    61
    -# -T sends the content of a file via PUT. To achieve the GET after a redirect, add the parameter --location
    62
    -#
    63
    -# -F, --form <name=content>
    64
    -#               (HTTP)  This  lets  curl emulate a filled-in form in which a user has pressed the submit button. This causes curl to POST data
    65
    -#               using the Content-Type multipart/form-data according to RFC 2388. This enables uploading of binary files  etc.  To  force  the
    66
    -#               'content'  part  to  be a file, prefix the file name with an @ sign. To just get the content part from a file, prefix the file
    67
    -#               name with the symbol <. The difference between @ and < is then that @ makes a file get attached in the post as a file  upload,
    68
    -#               while the < makes a text field and just get the contents for that text field from a file.
    69
    -#
    70
    -# curl -X POST -F user_id=xxxxxxx -F session_id=xxxxxxx -F photo_id=xxxxxxx -F photo=@xxxxxxx.jpg http://api.pai.ai/photos/upload
    71
    -@logit
    72
    -def upload_photo(request):
    73
    -    """ 上传图片 """
    74
    -    lensman_id = request.POST.get('user_id', '')
    75
    -    session_id = request.POST.get('session_id', '')
    76
    -    photo_id = request.POST.get('photo_id', '')
    77
    -
    78
    -    photo = request.FILES.get('photo', '')
    79
    -
    80
    -    if not (lensman_id and session_id and photo):
    81
    -        return response(PhotoStatusCode.PARAMS_ERROR)
    82
    -
    83
    -    try:
    84
    -        LensmanInfo.objects.get(lensman_id=lensman_id)
    85
    -    except LensmanInfo.DoesNotExist:
    86
    -        return response(LensmanStatusCode.LENSMAN_NOT_FOUND)
    87
    -
    88
    -    photo_info = file_save(photo, prefix='photo', ext='.jpeg', watermark=True)
    89
    -
    90
    -    photo, created = PhotosInfo.objects.get_or_create(
    91
    -        lensman_id=lensman_id,
    92
    -        session_id=session_id,
    93
    -        photo_id=photo_id,
    94
    -        p_photo_path=photo_info.photo_watermark_path,
    95
    -        m_photo_path=photo_info.photo_path,
    96
    -    )
    97
    -
    98
    -    return response(200, 'Photo Upload Success', u'照片上传成功', photo.data)
    99
    -
    100
    -
    101
    -@logit
    102
    -@transaction.atomic
    103
    -def session_join_api(request):
    104
    -    """ Session 详情 """
    105
    -    user_id = request.POST.get('user_id', '')
    106
    -    session_id = request.POST.get('session_id', '')
    107
    -    lensman_id = request.POST.get('lensman_id', '')
    108
    -    nickname = request.POST.get('nickname', '')
    109
    -    current_id = -1
    110
    -
    111
    -    # 摄影师校验
    112
    -    try:
    113
    -        lensman = UserInfo.objects.get(user_id=lensman_id)
    114
    -    except UserInfo.DoesNotExist:
    115
    -        return response(LensmanStatusCode.LENSMAN_NOT_FOUND)
    116
    -
    117
    -    # 判断 user_id 是否存在,如果不存在,则直接分配帐户
    118
    -    user, user_created = UserInfo.objects.get_or_create(user_id=user_id, defaults={
    119
    -        'user_id': CurtailUUID.uuid(UserInfo, 'user_id'),
    120
    -        'user_status': UserInfo.ASSIGN,
    121
    -        'assign_ip': client_ip(request),
    122
    -        'assign_at': tc.utc_datetime(),
    123
    -    })
    124
    -    user_id = user.user_id
    125
    -
    126
    -    # 判断通过 session_id 创建的群组是否存在,如果不存在,则直接创建
    127
    -    group, group_created = GroupInfo.objects.select_for_update().get_or_create(session_id=session_id, group_from=GroupInfo.SESSION_GROUP, defaults={
    128
    -        'group_id': CurtailUUID.uuid(GroupInfo, 'group_id'),
    129
    -        # 'admin_id': lensman_id,
    130
    -        'group_name': lensman.final_nickname,
    131
    -        'group_default_avatar': 0,
    132
    -    })
    133
    -    group_id = group.group_id
    134
    -
    135
    -    # Redis 群组数据缓存
    136
    -    group_info = set_group_info(group) if group_created else get_group_info(group_id)
    137
    -
    138
    -    # 判断 group_id/user_id 的群组用户是否存在,如果不存在,则直接创建
    139
    -    group_user, group_user_created = GroupUserInfo.objects.get_or_create(group_id=group_id, user_id=user_id, defaults={
    140
    -        # 'current_id': int(r.get(GROUP_LAST_PHOTO_PK % group_id) or -1),
    141
    -        'current_id': current_id,  # 通过扫描 session_id 二维码进群的用户,默认可以查看该群组所有照片
    142
    -        'nickname': nickname or user.final_nickname,
    143
    -        'avatar': user.avatar,
    144
    -        # 'admin': group_created,
    145
    -        'user_status': GroupUserInfo.PASSED,
    146
    -        'passed_at': tc.utc_datetime(),
    147
    -    })
    148
    -    if not group_user_created:
    149
    -        group_user.current_id = current_id
    150
    -        group_user.user_status = GroupUserInfo.PASSED
    151
    -        group_user.save()
    152
    -
    153
    -    # 管理员处理
    154
    -    tobe_admin = not GroupUserInfo.objects.filter(admin=True, status=True).exists()
    155
    -    if tobe_admin:
    156
    -        group.admin_id = user_id
    157
    -        group.save()
    158
    -        group_user.admin = True
    159
    -        group_user.save()
    160
    -
    161
    -    # Redis 群组用户数据缓存
    162
    -    group_users = set_group_users_info(group)
    163
    -
    164
    -    # Redis 群组通过集合缓存
    165
    -    r.srem(GROUP_USERS_REFUSED_SET % group_id, user_id)
    166
    -    r.srem(GROUP_USERS_DELETED_SET % group_id, user_id)
    167
    -    r.srem(GROUP_USERS_QUIT_SET % group_id, user_id)
    168
    -    r.sadd(GROUP_USERS_PASSED_SET % group_id, user_id)
    169
    -
    170
    -    #
    171
    -    if group_created:
    172
    -        # 获取 Session 照片
    173
    -        photos = PhotosInfo.objects.filter(session_id=session_id, status=True)
    174
    -
    175
    -        # 获取摄影师定价
    176
    -        price_info = get_lensman_price_fixed(lensman_id)
    177
    -
    178
    -        group_photo = None
    179
    -        for photo in photos:
    180
    -            photo_info = file_save(photo_path=photo.p_photo_path, prefix='photo', ext='.jpeg', thumbnail=True)
    181
    -
    182
    -            # 群组照片记录创建
    183
    -            group_photo, created = GroupPhotoInfo.objects.get_or_create(
    184
    -                group_id=group_id,
    185
    -                user_id=user_id,
    186
    -                photo_md5=photo_info.photo_md5,
    187
    -                defaults={
    188
    -                    'nickname': user.final_nickname,
    189
    -                    'avatar': user.avatar,
    190
    -                    'photo_path': photo_info.photo_watermark_path,
    191
    -                    'has_watermark': True,
    192
    -                    'photo_w': photo_info.photo_w,
    193
    -                    'photo_h': photo_info.photo_h,
    194
    -                    'photo_thumbnail_path': photo_info.photo_thumbnail_path,
    195
    -                    'photo_thumbnail_w': photo_info.photo_thumbnail_w,
    196
    -                    'photo_thumbnail_h': photo_info.photo_thumbnail_h,
    197
    -                    'photo_thumbnail2_path': photo_info.photo_thumbnail2_path,
    198
    -                    'photo_thumbnail2_w': photo_info.photo_thumbnail2_w,
    199
    -                    'photo_thumbnail2_h': photo_info.photo_thumbnail2_h,
    200
    -                    'photo_from': GroupPhotoInfo.SESSION_GROUP,
    201
    -                    'session_id': photo.session_id,
    202
    -                    'lensman_id': photo.lensman_id,
    203
    -                    'lensman_photo_id': photo.photo_id,
    204
    -                    'nomark': price_info.get('nomark', 999),
    205
    -                    'origin': price_info.get('origin', 999),
    206
    -                }
    207
    -            )
    208
    -
    209
    -        if group_photo:
    210
    -            # 设置群组最后一张照片PK
    211
    -            r.set(GROUP_LAST_PHOTO_PK % group_id, group_photo.pk)
    212
    -
    213
    -            # Redis 群组数据缓存
    214
    -            set_group_info(group)
    215
    -
    216
    -    # 获取从 current_id 到 now 的群组照片列表
    217
    -    group_photos = GroupPhotoInfo.objects.filter(
    218
    -        group_id=group_id,
    219
    -        status=True,
    220
    -        pk__gt=group_user.current_id,
    221
    -    ).order_by(
    222
    -        '-pk'
    223
    -    )
    224
    -    latest_photo = group_photos.first()
    225
    -
    226
    -    return response(200, 'Apply Join Session Group Success', u'申请加入摄影师群成功', {
    227
    -        'current_id': latest_photo and latest_photo.pk or current_id,
    228
    -        'photos': [photo.photo_info(user_id) for photo in group_photos],
    229
    -        'group_id': group_id,
    230
    -        'group': group_info,
    231
    -        'user_id': user_id,
    232
    -        'users': group_users,
    233
    -    })
    234
    -
    235
    -
    236
    -@logit
    237
    -def session_detail(request, session_id):
    238
    -    photos = PhotosInfo.objects.filter(session_id=session_id, status=True)
    239
    -    return render(request, 'photo/session_detail.html', {'photos': photos})
    240
    -
    241
    -
    242
    -@logit
    243
    -def photo_standard(request, photo_id):
    244
    -    photo = PhotosInfo.objects.get(photo_id=photo_id)
    245
    -    return render(request, 'photo/photo_detail.html', {'photo_url': photo.p_photo_url})
    246
    -
    247
    -
    248
    -@logit
    249
    -def photo_standard_api(request, photo_id):
    250
    -    photo = PhotosInfo.objects.get(photo_id=photo_id)
    251
    -    return response(200, 'Get Photo Detail Success', u'获取照片详情成功', {
    252
    -        'photo': photo.detail,
    253
    -    })
    254
    -
    255
    -
    256
    -@logit
    257
    -def photo_medium(request, photo_id):
    258
    -    photo = PhotosInfo.objects.get(photo_id=photo_id)
    259
    -    return render(request, 'photo/photo_detail.html', {'photo_url': photo.m_photo_url})
    260
    -
    261
    -
    262
    -@logit
    263
    -def photo_large(request, photo_id):
    264
    -    photo = PhotosInfo.objects.get(photo_id=photo_id)
    265
    -    return render(request, 'photo/photo_detail.html', {'photo_url': photo.l_photo_url})
    266
    -
    267
    -
    268
    -@logit
    269
    -def photo_raw(request, photo_id):
    270
    -    photo = PhotosInfo.objects.get(photo_id=photo_id)
    271
    -    return render(request, 'photo/photo_detail.html', {'photo_url': photo.r_photo_url})
    272
    -
    273
    -
    274
    -class PhotoInfoViewSet(viewsets.ModelViewSet):
    275
    -    queryset = PhotosInfo.objects.all().order_by('-pk')
    276
    -    serializer_class = PhotosInfoSerializer

    + 0 - 103
    utils/error/errno_utils.py

    @@ -99,33 +99,6 @@ class MarketCodeStatusCode(BaseStatusCode):
    99 99
         """ 一物一码相关错误码 5050xx """
    100 100
         MARKET_CODE_NOT_FOUND = StatusCodeField(505001, 'Market Code Not Found', description=u'一物一码不存在')
    101 101
     
    102
    -
    103
    -class LensmanStatusCode(BaseStatusCode):
    104
    -    """ 摄影师相关错误码 4000xx """
    105
    -    LENSMAN_NOT_FOUND = StatusCodeField(400001, 'Lensman Not Found', description=u'摄影师不存在')
    106
    -    # 密码
    107
    -    LENSMAN_PASSWORD_ERROR = StatusCodeField(400002, 'Lensman Password Error', description=u'摄影师密码错误')
    108
    -    # 手机号
    109
    -    LENSMAN_PHONE_ALREADY_EXISTS = StatusCodeField(400005, 'Lensman Phone Already Exists', description=u'手机号已经存在')
    110
    -    # 状态
    111
    -    LENSMAN_ALREADY_NOT_UNVERIFIED = StatusCodeField(400010, 'Lensman Already Not Unverified', description=u'摄影师帐号已激活')
    112
    -    LENSMAN_NOT_ACTIVATED = StatusCodeField(400015, 'Lensman Not Activated', description=u'摄影师帐号未激活')
    113
    -    # 类别
    114
    -    LENSMAN_TYPE_NOT_EXISTS = StatusCodeField(400020, 'Lensman Type Not Exists', description=u'摄影师类别不存在')
    115
    -
    116
    -
    117
    -class TourGuideStatusCode(BaseStatusCode):
    118
    -    """ 导游相关错误码 4001xx """
    119
    -    TOURGUIDE_NOT_FOUND = StatusCodeField(400101, 'Tour Guide Not Found', description=u'导游不存在')
    120
    -    # 密码
    121
    -    TOURGUIDE_PASSWORD_ERROR = StatusCodeField(400102, 'Tour Guide Password Error', description=u'导游密码错误')
    122
    -    # 手机号
    123
    -    TOURGUIDE_PHONE_ALREADY_EXISTS = StatusCodeField(400105, 'Tour Guide Phone Already Exists', description=u'手机号已经存在')
    124
    -    # 状态
    125
    -    TOURGUIDE_ALREADY_NOT_UNVERIFIED = StatusCodeField(400110, 'Tour Guide Already Not Unverified', description=u'导游帐号已激活')
    126
    -    TOURGUIDE_NOT_ACTIVATED = StatusCodeField(400115, 'Tour Guide Not Activated', description=u'导游帐号未激活')
    127
    -
    128
    -
    129 102
     class AdministratorStatusCode(BaseStatusCode):
    130 103
         """ 操作员相关错误码 4002xx """
    131 104
         ADMINISTRATOR_NOT_FOUND = StatusCodeField(400201, 'Administrator Not Found', description=u'管理员不存在')
    @@ -177,86 +150,10 @@ class WechatStatusCode(BaseStatusCode):
    177 150
         UNIONID_NOT_FOUND = StatusCodeField(400702, 'Unionid Not Found', description=u'微信 UNIONID 不存在')
    178 151
         OPENID_NOT_FOUND = StatusCodeField(400703, 'OPENID Not Found', description=u'微信 OPENID 不存在')
    179 152
     
    180
    -
    181
    -class PhotoStatusCode(BaseStatusCode):
    182
    -    """ 照片相关错误码 4010xx """
    183
    -    PARAMS_ERROR = StatusCodeField(401001, 'Params Error', description=u'参数错误')
    184
    -
    185
    -
    186
    -class GroupStatusCode(BaseStatusCode):
    187
    -    """ 群组/团相关错误码 4020xx """
    188
    -    GROUP_NOT_FOUND = StatusCodeField(402001, 'Group Not Found', description=u'群组不存在')
    189
    -    GROUP_HAS_LOCKED = StatusCodeField(402002, 'Group Has Locked', description=u'群组已锁定')
    190
    -    # 管理员
    191
    -    NOT_GROUP_ADMIN = StatusCodeField(402010, 'Not Group Admin', description=u'非群组管理员')
    192
    -    NOT_GROUP_SUBADMIN = StatusCodeField(402011, 'Not Group Sub Admin', description=u'非群组协同管理员')
    193
    -    ADMIN_CANNOT_HANDLE_SELF = StatusCodeField(402012, 'Admin Cannot Handle Self', description=u'群组管理员无法操作自身')
    194
    -    # 旅行团
    195
    -    ONLY_ONE_ACTIVE_GROUP_ALLOWED = StatusCodeField(402040, 'Only One Active Group Allowed', description=u'只能创建一个活跃团')
    196
    -    ACTIVE_GROUP_NOT_FOUND = StatusCodeField(402041, 'Active Group Not Found', description=u'活跃团不存在')
    197
    -    GROUP_HAS_ENDED = StatusCodeField(402042, 'Group Has Ended', description=u'群组已结束')
    198
    -    # 其他
    199
    -    GROUP_PHOTO_NOT_EMPTY = StatusCodeField(402099, 'Group Photo Not Empty', description=u'群组照片不为空')
    200
    -
    201
    -
    202
    -class GroupUserStatusCode(BaseStatusCode):
    203
    -    """ 群组/团用户相关错误码 4021xx """
    204
    -    GROUP_USER_NOT_FOUND = StatusCodeField(402101, 'Group User Not Found', description=u'群组用户不存在')
    205
    -    GROUP_USER_HAS_DELETED = StatusCodeField(402102, 'Group User Has Deleted', description=u'群组用户被移除')
    206
    -    # 旅行团
    207
    -    USER_HAS_NOT_JOIN_GROUP = StatusCodeField(402131, 'User Has Not Join Group', description=u'用户未加入旅行团')
    208
    -
    209
    -
    210
    -class GroupPhotoStatusCode(BaseStatusCode):
    211
    -    """ 群组照片(飞图)相关错误码 4022xx """
    212
    -    GROUP_PHOTO_NOT_FOUND = StatusCodeField(402201, 'Group Photo Not Found', description=u'飞图不存在')
    213
    -    # 上传
    214
    -    DUPLICATE_UPLOAD = StatusCodeField(402210, 'Duplicate Upload', description=u'重复上传')
    215
    -    # 点赞
    216
    -    THUMB_UP_NOT_FOUND = StatusCodeField(402220, 'Thumb Up Not Found', description=u'未点赞')
    217
    -    DUPLICATE_THUMB_UP = StatusCodeField(402221, 'Duplicate Thumb Up', description=u'重复点赞')
    218
    -    # 评论
    219
    -    COMMENT_CONTENT_EMPTY = StatusCodeField(402230, 'Comment Content Empty', description=u'评论内容为空')
    220
    -
    221
    -
    222 153
     class ScreenStatusCode(BaseStatusCode):
    223 154
         """ 群组/团相关错误码 4030xx """
    224 155
         QRCODE_NOT_SCAN = StatusCodeField(403001, 'QRCode Not Scan', description=u'二维码未扫描')
    225 156
     
    226
    -
    227
    -class OrderStatusCode(BaseStatusCode):
    228
    -    """ 订单/支付相关错误码 4040xx """
    229
    -    WX_UNIFIED_ORDER_FAIL = StatusCodeField(404000, 'WX Unified Order Fail', description=u'微信统一下单失败')
    230
    -    WX_ORDER_NOT_FOUND = StatusCodeField(404001, 'WX Order Not Found', description=u'订单不存在')
    231
    -    WX_ORDER_NOT_PAY = StatusCodeField(404002, 'WX Order Not Pay', description=u'订单未支付')
    232
    -    WX_ORDER_PAYING = StatusCodeField(404003, 'WX Order Paying', description=u'订单支付中')
    233
    -    WX_ORDER_PAY_FAIL = StatusCodeField(404009, 'WX Order Pay Fail', description=u'微信支付失败')
    234
    -    SIGN_CHECK_FAIL = StatusCodeField(404010, 'Sign Check Fail', description=u'签名校验失败')
    235
    -    FEE_CHECK_FAIL = StatusCodeField(404011, 'FEE Check Fail', description=u'金额校验失败')
    236
    -    NO_DETAIL_PERMISSION = StatusCodeField(404015, 'No Detail Permission', description=u'无详情权限')
    237
    -    WX_ORDER_PAID_ALREADY_EXISTS = StatusCodeField(404020, 'WX Order Paid Already Exists', description=u'照片已购买')
    238
    -
    239
    -
    240
    -class PayStatusCode(BaseStatusCode):
    241
    -    """ 支付相关错误码 4041xx """
    242
    -
    243
    -
    244
    -class WithdrawStatusCode(BaseStatusCode):
    245
    -    """ 提现相关错误码 4042xx """
    246
    -    BALANCE_NOT_ENOUGH = StatusCodeField(404200, 'Balance Not Enough', description=u'提现金额不足')
    247
    -
    248
    -
    249
    -class MessageStatusCode(BaseStatusCode):
    250
    -    """ 消息相关错误码 4090xx """
    251
    -    MESSAGE_NOT_FOUND = StatusCodeField(409001, 'Message Not Found', description=u'消息不存在')
    252
    -
    253
    -
    254
    -class TokenStatusCode(BaseStatusCode):
    255
    -    """ 票据相关错误码 4090xx """
    256
    -    TOKEN_NOT_FOUND = StatusCodeField(409901, 'Token Not Found', description=u'票据不存在')
    257
    -    TOKEN_HAS_EXPIRED = StatusCodeField(409911, 'Token Has Expired', description=u'票据过期,请刷新重扫二维码')
    258
    -
    259
    -
    260 157
     class PermissionStatusCode(BaseStatusCode):
    261 158
         """ 4099xx 权限相关错误码 """
    262 159
         PERMISSION_DENIED = StatusCodeField(409900, 'Permission Denied', description=u'权限不足')

    + 0 - 22
    utils/redis/rbrief.py

    @@ -1,22 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -
    3
    -from isoweek import Week
    4
    -from TimeConvert import TimeConvert as tc
    5
    -
    6
    -from utils.redis.connect import r
    7
    -from utils.redis.rkeys import TODAY_INCOME, TOTAL_INCOME, WEEK_INCOME, WEEK_SOLD
    8
    -
    9
    -
    10
    -def set_brief_info(uid, ptype, fee, dt=None):
    11
    -    """ 更新简报信息 """
    12
    -    ymd, week = (tc.local_string(utc_dt=dt, format='%Y%m%d'), Week.withdate(dt)) if dt else (tc.local_string(format='%Y%m%d'), Week.thisweek().isoformat())
    13
    -
    14
    -    # 总收入
    15
    -    r.incr(TOTAL_INCOME % (uid, ptype), fee)
    16
    -    # 周收入
    17
    -    r.incr(WEEK_INCOME % (uid, ptype, week), fee)
    18
    -    # 日收入
    19
    -    r.incr(TODAY_INCOME % (uid, ptype, ymd), fee)
    20
    -
    21
    -    # 周售出
    22
    -    r.incr(WEEK_SOLD % (uid, ptype, week))

    + 0 - 58
    utils/redis/retrieve.py

    @@ -1,58 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -
    3
    -from group.models import GroupInfo, GroupPhotoInfo, GroupUserInfo, PhotoCommentInfo, PhotoThumbUpInfo
    4
    -from utils.redis.connect import r
    5
    -from utils.redis.rgroup import set_group_photo_data, set_group_users_info
    6
    -from utils.redis.rkeys import (GROUP_LAST_PHOTO_PK, GROUP_PHOTO_WATCHER_SET, GROUP_USERS_APPLYING_SET,
    7
    -                               GROUP_USERS_DELETED_SET, GROUP_USERS_PASSED_SET, GROUP_USERS_REFUSED_SET)
    8
    -
    9
    -
    10
    -def retrieve_group_data():
    11
    -    """ 群组数据 """
    12
    -    groups = GroupInfo.objects.filter(status=True)
    13
    -    for group in groups:
    14
    -        # 群组照片
    15
    -        set_group_photo_data(group.group_id)
    16
    -        # 群组用户
    17
    -        set_group_users_info(group)
    18
    -
    19
    -
    20
    -def retrieve_last_pk():
    21
    -    """ 群组最后一张照片PK """
    22
    -    groups = GroupInfo.objects.filter(status=True)
    23
    -    for group in groups:
    24
    -        group_photo = GroupPhotoInfo.objects.filter(group_id=group.group_id, status=True).last()
    25
    -        r.set(GROUP_LAST_PHOTO_PK % group.group_id, group_photo and group_photo.pk or -1)
    26
    -
    27
    -
    28
    -def retrieve_group_user_status():
    29
    -    """ 群组用户状态 """
    30
    -    group_users = GroupUserInfo.objects.filter(status=True)
    31
    -    for group_user in group_users:
    32
    -        group_id, user_id = group_user.group_id, group_user.user_id
    33
    -        if group_user.user_status == GroupUserInfo.PASSED:
    34
    -            r.sadd(GROUP_USERS_PASSED_SET % group_id, user_id)
    35
    -        elif group_user.user_status == GroupUserInfo.DELETED:
    36
    -            r.sadd(GROUP_USERS_DELETED_SET % group_id, user_id)
    37
    -        elif group_user.user_status == GroupUserInfo.APPLYING:
    38
    -            r.sadd(GROUP_USERS_APPLYING_SET % group_id, user_id)
    39
    -        elif group_user.user_status == GroupUserInfo.REFUSED:
    40
    -            r.sadd(GROUP_USERS_REFUSED_SET % group_id, user_id)
    41
    -
    42
    -
    43
    -def retrieve_group_photo_watchers():
    44
    -    group_photos = GroupPhotoInfo.objects.filter(status=True)
    45
    -    for group_photo in group_photos:
    46
    -        photo_comments = PhotoCommentInfo.objects.filter(photo_id=group_photo.photo_id, status=True)
    47
    -        for photo_comment in photo_comments:
    48
    -            r.sadd(GROUP_PHOTO_WATCHER_SET % group_photo.pk, photo_comment.user_id)
    49
    -        photo_thumbups = PhotoThumbUpInfo.objects.filter(photo_id=group_photo.photo_id, status=True)
    50
    -        for photo_thumbup in photo_thumbups:
    51
    -            r.sadd(GROUP_PHOTO_WATCHER_SET % group_photo.pk, photo_thumbup.user_id)
    52
    -
    53
    -
    54
    -def retrieve_redis_data():
    55
    -    retrieve_group_data()
    56
    -    retrieve_last_pk()
    57
    -    retrieve_group_user_status()
    58
    -    retrieve_group_photo_watchers()

    + 0 - 147
    utils/redis/rgroup.py

    @@ -1,147 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -
    3
    -from django.core.serializers.json import DjangoJSONEncoder
    4
    -
    5
    -from utils.redis.connect import r
    6
    -from utils.redis.rkeys import (GROUP_INFO, GROUP_PHOTO_COMMENT_LIST, GROUP_PHOTO_DATA, GROUP_PHOTO_THUMB_UP,
    7
    -                               GROUP_PHOTO_THUMB_UP_LIST, GROUP_PHOTO_WATCHER_SET, GROUP_USERS_INFO,
    8
    -                               GROUP_USERS_KV_INFO)
    9
    -
    10
    -
    11
    -def set_group_info(group):
    12
    -    """ 设置群组信息 """
    13
    -    r.setexjson(GROUP_INFO % group.group_id, r.REDIS_EXPIRED_ONE_MONTH, group.data, cls=DjangoJSONEncoder)
    14
    -    return group.data
    15
    -
    16
    -
    17
    -def set_group_info_by_id(group_id):
    18
    -    """ 设置群组信息 """
    19
    -    from group.models import GroupInfo
    20
    -    try:
    21
    -        group = GroupInfo.objects.get(group_id=group_id)
    22
    -    except GroupInfo.DoesNotExist:
    23
    -        return {}
    24
    -    return set_group_info(group)
    25
    -
    26
    -
    27
    -def get_group_info(group_id):
    28
    -    """ 获取群组信息 """
    29
    -    return r.getjson(GROUP_INFO % group_id) or set_group_info_by_id(group_id)
    30
    -
    31
    -
    32
    -# 群组用户信息相关
    33
    -
    34
    -
    35
    -def set_group_users_info(group):
    36
    -    """ 设置群组用户信息 """
    37
    -    group_users = group.users(admin=False)
    38
    -
    39
    -    group_users_data = {
    40
    -        'group_users': group_users,
    41
    -        'admin_id': group.admin_id,
    42
    -    }
    43
    -    r.setexjson(GROUP_USERS_INFO % group.group_id, r.REDIS_EXPIRED_ONE_MONTH, group_users_data, cls=DjangoJSONEncoder)
    44
    -
    45
    -    group_users_kv_data = {user_info.get('user_id', ''): user_info for user_info in group_users.get('passed', [])}
    46
    -    r.setexjson(GROUP_USERS_KV_INFO % group.group_id, r.REDIS_EXPIRED_ONE_MONTH, group_users_kv_data, cls=DjangoJSONEncoder)
    47
    -
    48
    -    return group_users_data, group_users_kv_data
    49
    -
    50
    -
    51
    -def set_group_users_info_by_id(group_id):
    52
    -    """ 设置群组用户信息 """
    53
    -    from group.models import GroupInfo
    54
    -    try:
    55
    -        group = GroupInfo.objects.get(group_id=group_id)
    56
    -    except GroupInfo.DoesNotExist:
    57
    -        return {}, {}
    58
    -    return set_group_users_info(group)
    59
    -
    60
    -
    61
    -def get_group_users_info(group_id, user_id):
    62
    -    """ 获取群组用户信息 """
    63
    -    group_users_data = r.getjson(GROUP_USERS_INFO % group_id) or set_group_users_info_by_id(group_id)[0]
    64
    -    group_users, admin_id = group_users_data.get('group_users', {}), group_users_data.get('admin_id', '')
    65
    -    if group_users and user_id != admin_id:
    66
    -        [group_users.pop(k) for k in ['applying_count', 'applying']]
    67
    -    return group_users
    68
    -
    69
    -
    70
    -def get_group_users_kv_info(group_id):
    71
    -    """ 获取群组用户信息 """
    72
    -    return r.getjson(GROUP_USERS_KV_INFO % group_id) or set_group_users_info_by_id(group_id)[1]
    73
    -
    74
    -
    75
    -# 群组照片相关
    76
    -
    77
    -
    78
    -def set_group_photo_data(group_id):
    79
    -    """ 设置群组照片数据信息 """
    80
    -    from group.models import GroupPhotoInfo
    81
    -    group_photos = GroupPhotoInfo.objects.filter(group_id=group_id, status=True)
    82
    -    group_photos = [photo.photo_data for photo in group_photos]
    83
    -    r.setjson(GROUP_PHOTO_DATA % group_id, group_photos)
    84
    -    return group_photos
    85
    -
    86
    -
    87
    -def get_group_photo_data(group_id):
    88
    -    """ 获取群组照片数据信息 """
    89
    -    return r.getjson(GROUP_PHOTO_DATA % group_id, default='[]') or set_group_photo_data(group_id)
    90
    -
    91
    -
    92
    -def set_group_photo_thumbup_flag(photo_id, user_id):
    93
    -    """ 设置群组照片用户点赞标识信息 """
    94
    -    r.setex(GROUP_PHOTO_THUMB_UP % (photo_id, user_id), r.REDIS_EXPIRED_ONE_MONTH, True)
    95
    -
    96
    -
    97
    -def del_group_photo_thumbup_flag(photo_id, user_id):
    98
    -    """ 删除群组照片用户点赞标识信息 """
    99
    -    r.delete(GROUP_PHOTO_THUMB_UP % (photo_id, user_id))
    100
    -
    101
    -
    102
    -def get_group_photo_thumbup_flag(photo_id, user_id):
    103
    -    """ 获取群组照片用户点赞标识信息 """
    104
    -    if r.exists(GROUP_PHOTO_THUMB_UP % (photo_id, user_id)):
    105
    -        return True
    106
    -
    107
    -    from group.models import PhotoThumbUpInfo
    108
    -    if PhotoThumbUpInfo.objects.filter(photo_id=photo_id, user_id=user_id, thumbup=True, status=True).exists():
    109
    -        set_group_photo_thumbup_flag(photo_id, user_id)
    110
    -        return True
    111
    -
    112
    -    return False
    113
    -
    114
    -
    115
    -def set_group_photo_comment_list(photo_id):
    116
    -    """ 设置群组照片用户评论列表 """
    117
    -    from group.models import PhotoCommentInfo
    118
    -    photo_comments = PhotoCommentInfo.objects.filter(photo_id=photo_id, status=True)
    119
    -    photo_comments = [comment.comment_info for comment in photo_comments]
    120
    -    r.setjson(GROUP_PHOTO_COMMENT_LIST % photo_id, photo_comments, cls=DjangoJSONEncoder)
    121
    -    return photo_comments
    122
    -
    123
    -
    124
    -def get_group_photo_comment_list(photo_id):
    125
    -    """ 获取群组照片用户评论列表 """
    126
    -    return r.getjson(GROUP_PHOTO_COMMENT_LIST % photo_id, default='[]') or set_group_photo_comment_list(photo_id)
    127
    -
    128
    -
    129
    -def set_group_photo_thumbup_list(photo_id):
    130
    -    """ 设置群组照片用户点赞列表 """
    131
    -    from group.models import PhotoThumbUpInfo
    132
    -    photo_thumbups = PhotoThumbUpInfo.objects.filter(photo_id=photo_id, thumbup=True, status=True)
    133
    -    photo_thumbups = [thumbup.thumbup_info for thumbup in photo_thumbups]
    134
    -    r.setjson(GROUP_PHOTO_THUMB_UP_LIST % photo_id, photo_thumbups, cls=DjangoJSONEncoder)
    135
    -    return photo_thumbups
    136
    -
    137
    -
    138
    -def get_group_photo_thumbup_list(photo_id):
    139
    -    """ 获取群组照片用户点赞列表 """
    140
    -    return r.getjson(GROUP_PHOTO_THUMB_UP_LIST % photo_id, default='[]') or set_group_photo_thumbup_list(photo_id)
    141
    -
    142
    -
    143
    -def get_group_photo_watchers(photo_id, discarders=None):
    144
    -    """ 获取群组照片用户关注列表 """
    145
    -    watchers = r.smembers(GROUP_PHOTO_WATCHER_SET % photo_id)
    146
    -    [watchers.discard(elem) for elem in discarders or []]
    147
    -    return watchers

    + 0 - 20
    utils/redis/rguest.py

    @@ -1,20 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -
    3
    -from utils.redis.connect import r
    4
    -from utils.redis.rkeys import GUEST_ENTRANCE_CONTROL_INFO
    5
    -
    6
    -
    7
    -def set_guest_entrance_control(gen):
    8
    -    """ 设置游客入口控制 """
    9
    -    r.setjson(GUEST_ENTRANCE_CONTROL_INFO % gen.src, gen.data)
    10
    -    return gen.data
    11
    -
    12
    -
    13
    -def get_guest_entrance_control(src=0):
    14
    -    """ 获取游客入口控制 """
    15
    -    return r.getjson(GUEST_ENTRANCE_CONTROL_INFO % src)
    16
    -
    17
    -
    18
    -def delete_guest_entrance_control(src=0):
    19
    -    """ 删除游客入口控制 """
    20
    -    return r.delete(GUEST_ENTRANCE_CONTROL_INFO % src)

    + 3 - 62
    utils/redis/rkeys.py

    @@ -1,71 +1,12 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -
    3
    -# 唯一标识相关
    4
    -UUID_LIST = 'uuid:list'  # List,唯一标识列表
    5
    -
    6
    -# 用户相关
    7
    -PROFILE_INFO = 'profile:info:%s'  # STRING,用户信息,user_id
    8
    -
    9
    -# 导游相关
    10
    -TOUR_GUIDE_GROUP_GEO_INFO = 'tour:guide:group:geo:info:%s'  # ZSET,旅游团地理位置信息,group_id
    11
    -TOUR_GUIDE_GROUP_GEO_SUBMIT_DT = 'tour:guide:group:geo:submit:dt:%s'  # ZSET,旅游团地理位置最后上传时间,group_id
    12
    -TOUR_GUIDE_GROUP_CUR_SESSION = 'tour:guide:group:cur:session:%s'  # STRING,旅游团当前Session,group_id,导游设置集合时间的时候更新
    13
    -TOUR_GUIDE_GROUP_CUR_GATHER_INFO = 'tour:guide:group:cur:gather:info:%s'  # STRING,旅游团当前Session,group_id,导游设置集合时间的时候更新
    14
    -TOUR_GUIDE_GROUP_USER_GEO_LIST = 'tour:guide:group:user:geo:list:%s:%s:%s'  # LIST,旅游团当前用户地理位置列表,group_id、session_id、user_id
    15
    -
    16
    -TOUR_GUIDE_GROUP_USER_OWN = 'tour:guide:group:user:own:%s'  # STRING,导游当前拥有的旅行团,user_id,导游创建旅行团的时候更新
    17
    -TOUR_GUIDE_GROUP_USER_BELONG = 'tour:guide:group:user:belong:%s'  # STRING,用户当前所属旅行团,user_id,用户加入旅行团的时候更新
    18
    -
    19
    -# 群组相关
    20
    -GROUP_INFO = 'group:info:%s'  # STRING,群组信息,group_id
    21
    -
    22
    -# 群组用户相关
    23
    -GROUP_USERS_INFO = 'group:users:info:%s'  # STRING,群组用户信息,group_id
    24
    -GROUP_USERS_KV_INFO = 'group:users:kv:info:%s'  # STRING,群组用户信息,group_id
    25
    -GROUP_USERS_APPLYING_SET = 'group:users:applying:set:%s'  # SET,群组用户申请集合,group_id
    26
    -GROUP_USERS_PASSED_SET = 'group:users:passed:set:%s'  # SET,群组用户通过集合,group_id
    27
    -GROUP_USERS_REFUSED_SET = 'group:users:refused:set:%s'  # SET,群组用户拒绝集合,group_id
    28
    -GROUP_USERS_DELETED_SET = 'group:users:deleted:set:%s'  # SET,群组用户移除集合,group_id
    29
    -GROUP_USERS_QUIT_SET = 'group:users:quit:set:%s'  # SET,群组用户退出集合,group_id
    30
    -
    31
    -# 群组照片相关
    32
    -GROUP_PHOTO_DATA = 'group:photo:data:%s'  # STRING,群组数据记录,group_id
    33
    -GROUP_PHOTO_THUMB_UP = 'group:photo:thumb:up:%s:%s'  # STRING,群组照片用户点赞记录,photo_id、user_id
    34
    -GROUP_PHOTO_COMMENT_LIST = 'group:photo:comment:list:%s'  # STRING,群组照片用户评论列表,photo_id
    35
    -GROUP_PHOTO_THUMB_UP_LIST = 'group:photo:thumb:up:list:%s'  # STRING,群组照片用户点赞列表,photo_id
    36
    -GROUP_PHOTO_WATCHER_SET = 'group:photo:watcher:set:%s'  # SET,群组照片用户关注集合,photo_id,关注即评论点赞
    37
    -GROUP_LAST_PHOTO_PK = 'group:last:photo:pk:%s'  # STRING,群组最后一张照片PK,group_id
    38
    -
    39
    -# 摄影师照片相关
    40
    -LENSMAN_PHOTO_ORDER_RECORD = 'lensman:photo:order:record:%s:%s'  # STRING,摄影师照片购买记录,photo_id、user_id
    41
    -
    42
    -# 摄影师简报相关
    43
    -# 收入
    44
    -TOTAL_INCOME = 'total:income:%s:%s'  # STRING,总收入,user_id、photo_type
    45
    -WEEK_INCOME = 'week:income:%s:%s:%s'  # STRING,周收入,user_id、photo_type、Week.thisweek().isoformat()
    46
    -TODAY_INCOME = 'today:income:%s:%s:%s'  # STRING,日收入,user_id、photo_type、tc.local_string(format='%Y%m%d')
    47
    -# 上传
    48
    -TODAY_UPLOAD_PHOTO_AMOUNT = 'today:upload:photo:amount:%s:%s'  # STRING,日上传照片数量,user_id、tc.local_string(format='%Y%m%d')
    49
    -# 售出
    50
    -WEEK_SOLD = 'week:sold:%s:%s:%s'  # STRING,周售出,user_id、photo_type、Week.thisweek().isoformat()
    51
    -
    52
    -# 摄影师定价相关
    53
    -LENSMAN_PHOTO_PRICE_FIXED = 'lensman:photo:price:fixed:%s'  # STRING,摄影师照片定价(单位:分),user_id
    54
    -
    55
    -# 系统消息相关
    56
    -SYSTEM_MESSAGE_READ_INFO = 'system:message:read:info:%s'  # STRING,系统消息读取信息,user_id
    57
    -SYSTEM_MESSAGE_DELETED_INFO = 'system:message:deleted:info:%s'  # STRING,系统消息删除信息,user_id
    58
    -
    59
    -# 游客入口相关
    60
    -GUEST_ENTRANCE_CONTROL_INFO = 'guest:entrance:control:info:%s'  # STRING,游客入口控制信息,src
    1
    +# -*- coding: utf-8 -*-'
    61 2
     
    62 3
     # APP 相关
    63 4
     LATEST_APP_INFO = 'latest:app:info:%s'  # STRING,最新 APP 信息,src
    64 5
     APP_SETTINGS_INFO = 'app:settings:info:%s:%s:%s'  # STRING,APP 设置信息,platform、channel、version
    65 6
     APP_PATCH_INFO = 'app:patch:info:%s:%s:%s'  # STRING,APP 补丁信息,platform、version、src
    66 7
     
    67
    -# BOX 相关
    68
    -BOX_PROGRAM_VERSION_INFO = 'box:program:version:info'  # STRING,BOX 程序版本信息
    8
    +# 用户相关
    9
    +PROFILE_INFO = 'profile:info:%s'  # STRING,用户信息,user_id
    69 10
     
    70 11
     # 小程序相关
    71 12
     MINI_PROGRAM_GIS_LIST = 'tamron:miniprogram:gis:list'

    + 0 - 32
    utils/redis/rmessage.py

    @@ -1,32 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -
    3
    -from utils.redis.connect import r
    4
    -from utils.redis.rkeys import SYSTEM_MESSAGE_DELETED_INFO, SYSTEM_MESSAGE_READ_INFO
    5
    -
    6
    -
    7
    -def set_system_message_read_info(user_id):
    8
    -    """ 设置系统消息读取信息 """
    9
    -    from message.models import SystemMessageReadInfo
    10
    -    read_messages = SystemMessageReadInfo.objects.filter(user_id=user_id, status=True)
    11
    -    read_message_ids = [msg.msg_id for msg in read_messages]
    12
    -    r.setexjson(SYSTEM_MESSAGE_READ_INFO % user_id, r.REDIS_EXPIRED_ONE_MONTH, read_message_ids)
    13
    -    return read_message_ids
    14
    -
    15
    -
    16
    -def get_system_message_read_info(user_id):
    17
    -    """ 获取系统消息读取信息 """
    18
    -    return r.getjson(SYSTEM_MESSAGE_READ_INFO % user_id, default='[]') or set_system_message_read_info(user_id)
    19
    -
    20
    -
    21
    -def set_system_message_delete_info(user_id):
    22
    -    """ 设置系统消息删除信息 """
    23
    -    from message.models import SystemMessageDeleteInfo
    24
    -    deleted_messages = SystemMessageDeleteInfo.objects.filter(user_id=user_id, status=True)
    25
    -    deleted_message_ids = [msg.msg_id for msg in deleted_messages]
    26
    -    r.setexjson(SYSTEM_MESSAGE_DELETED_INFO % user_id, r.REDIS_EXPIRED_ONE_MONTH, deleted_message_ids)
    27
    -    return deleted_message_ids
    28
    -
    29
    -
    30
    -def get_system_message_delete_info(user_id):
    31
    -    """ 获取系统消息删除信息 """
    32
    -    return r.getjson(SYSTEM_MESSAGE_DELETED_INFO % user_id, default='[]') or set_system_message_delete_info(user_id)

    + 0 - 0
    utils/redis/roperation/__init__.py


    + 0 - 20
    utils/redis/roperation/rbox_program_version.py

    @@ -1,20 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -
    3
    -from utils.redis.connect import r
    4
    -from utils.redis.rkeys import BOX_PROGRAM_VERSION_INFO
    5
    -
    6
    -
    7
    -def set_box_program_version():
    8
    -    """ 设置 BOX 程序版本信息 """
    9
    -    from operation.models import BoxProgramVersionInfo
    10
    -    try:
    11
    -        bpverion = BoxProgramVersionInfo.objects.filter(status=True)[0].data
    12
    -    except IndexError:
    13
    -        bpverion = {}
    14
    -    r.setjson(BOX_PROGRAM_VERSION_INFO, bpverion)
    15
    -    return bpverion
    16
    -
    17
    -
    18
    -def get_box_program_version():
    19
    -    """ 获取 BOX 程序版本信息 """
    20
    -    return r.getjson(BOX_PROGRAM_VERSION_INFO) or set_box_program_version()

    + 0 - 27
    utils/redis/rorder.py

    @@ -1,27 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -
    3
    -from django.core.serializers.json import DjangoJSONEncoder
    4
    -
    5
    -from utils.redis.connect import r
    6
    -from utils.redis.rkeys import LENSMAN_PHOTO_ORDER_RECORD
    7
    -
    8
    -
    9
    -def set_lensman_order_record(porder):
    10
    -    """ 设置摄影师照片购买记录 """
    11
    -    r.setexjson(LENSMAN_PHOTO_ORDER_RECORD % (porder.photo_id, porder.user_id), r.REDIS_EXPIRED_ONE_MONTH, porder.porder_info, cls=DjangoJSONEncoder)
    12
    -    return porder.porder_info
    13
    -
    14
    -
    15
    -def set_lensman_order_record_by_id(photo_id, user_id):
    16
    -    """ 设置摄影师照片购买记录 """
    17
    -    from group.models import GroupPhotoOrderInfo
    18
    -    try:
    19
    -        porder = GroupPhotoOrderInfo.objects.get(photo_id=photo_id, user_id=user_id)
    20
    -    except GroupPhotoOrderInfo.DoesNotExist:
    21
    -        return {}
    22
    -    return set_lensman_order_record(porder)
    23
    -
    24
    -
    25
    -def get_lensman_order_record(photo_id, user_id):
    26
    -    """ 获取摄影师照片购买记录 """
    27
    -    return r.getjson(LENSMAN_PHOTO_ORDER_RECORD % (photo_id, user_id)) or set_lensman_order_record_by_id(photo_id, user_id)

    + 0 - 27
    utils/redis/rprice.py

    @@ -1,27 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -
    3
    -from utils.redis.connect import r
    4
    -from utils.redis.rkeys import LENSMAN_PHOTO_PRICE_FIXED
    5
    -
    6
    -
    7
    -def set_lensman_price_fixed(user_id):
    8
    -    """ 设置摄影师价格设定 """
    9
    -    from account.models import LensmanInfo
    10
    -    try:
    11
    -        lensman = LensmanInfo.objects.get(lensman_id=user_id)
    12
    -    except LensmanInfo.DoesNotExist:
    13
    -        lensman = None
    14
    -
    15
    -    price_fixed = {
    16
    -        'nomark': (lensman and lensman.nomark) or 299,
    17
    -        'origin': (lensman and lensman.origin) or 999,
    18
    -    }
    19
    -
    20
    -    r.setjson(LENSMAN_PHOTO_PRICE_FIXED % user_id, price_fixed)
    21
    -
    22
    -    return price_fixed
    23
    -
    24
    -
    25
    -def get_lensman_price_fixed(user_id):
    26
    -    """ 获取摄影师价格设定 """
    27
    -    return r.getjson(LENSMAN_PHOTO_PRICE_FIXED % user_id) or set_lensman_price_fixed(user_id)

    + 0 - 19
    utils/redis/rtourguide.py

    @@ -1,19 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -
    3
    -from utils.redis.connect import r
    4
    -from utils.redis.rkeys import TOUR_GUIDE_GROUP_USER_OWN
    5
    -
    6
    -
    7
    -def set_tour_guide_own_group(user_id, group_id):
    8
    -    """ 设置导游拥有的旅行团 """
    9
    -    r.set(TOUR_GUIDE_GROUP_USER_OWN % user_id, group_id)
    10
    -
    11
    -
    12
    -def get_tour_guide_own_group(user_id):
    13
    -    """ 获取导游拥有的旅行团 """
    14
    -    return r.get(TOUR_GUIDE_GROUP_USER_OWN % user_id)
    15
    -
    16
    -
    17
    -def del_tour_guide_own_group(user_id):
    18
    -    """ 删除导游拥有的旅行团 """
    19
    -    return r.delete(TOUR_GUIDE_GROUP_USER_OWN % user_id)

    + 0 - 14
    utils/redis/rtouruser.py

    @@ -1,14 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -
    3
    -from utils.redis.connect import r
    4
    -from utils.redis.rkeys import TOUR_GUIDE_GROUP_USER_BELONG
    5
    -
    6
    -
    7
    -def set_tour_user_belong_group(user_id, group_id):
    8
    -    """ 设置旅行团成员所属的旅行团 """
    9
    -    r.set(TOUR_GUIDE_GROUP_USER_BELONG % user_id, group_id)
    10
    -
    11
    -
    12
    -def get_tour_user_belong_group(user_id):
    13
    -    """ 获取旅行团成员所属的旅行团 """
    14
    -    return r.get(TOUR_GUIDE_GROUP_USER_BELONG % user_id)

    + 0 - 22
    utils/redis/ruuid.py

    @@ -1,22 +0,0 @@
    1
    -# -*- coding: utf-8 -*-
    2
    -
    3
    -from django_curtail_uuid import CurtailUUID
    4
    -
    5
    -from photo.models import UUIDInfo
    6
    -from utils.redis.connect import r
    7
    -from utils.redis.rkeys import UUID_LIST
    8
    -
    9
    -
    10
    -def generate_uuid():
    11
    -    uuid = CurtailUUID.uuid(UUIDInfo)
    12
    -    UUIDInfo.objects.create(uuid=uuid)
    13
    -    return uuid
    14
    -
    15
    -
    16
    -def generate_uuids(num=1000):
    17
    -    uuids = [generate_uuid() for i in range(num)]
    18
    -    r.rpush(UUID_LIST, *uuids)
    19
    -
    20
    -
    21
    -def update_uuids(lensman_id, uuids):
    22
    -    UUIDInfo.objects.filter(uuid__in=uuids).update(lensman_id=lensman_id, status=False)

    kodo - Gogs: Go Git Service

    No Description

    huangqimin001: 3f783afcfc :art: Add marketcode iv 3 years ago
    ..
    migrations 4efb7f6f87 Statistic 7 years ago
    static 3f48aa7f9e :art: Add MaintenaceInfo relative 3 years ago
    __init__.py 4efb7f6f87 Statistic 7 years ago
    admin.py 4efb7f6f87 Statistic 7 years ago
    apps.py 4efb7f6f87 Statistic 7 years ago
    custom_message.py 8082cb995c :art: Custom Message 3 years ago
    init_express_company.py d6d555d47b :art: init_express_company 3 years ago
    market_code.py 3f783afcfc :art: Add marketcode iv 3 years ago
    models.py 4efb7f6f87 Statistic 7 years ago
    tests.py 4efb7f6f87 Statistic 7 years ago
    views.py e812ec3fb2 switch gis to tencent 5 years ago