ount pull-right"> BIN   simditor/static/simditor/images/emoji/date.png
  • BIN
      simditor/static/simditor/images/emoji/de.png
  • BIN
      simditor/static/simditor/images/emoji/deciduous_tree.png
  • BIN
      simditor/static/simditor/images/emoji/department_store.png
  • BIN
      simditor/static/simditor/images/emoji/diamond_shape_with_a_dot_inside.png
  • BIN
      simditor/static/simditor/images/emoji/diamonds.png
  • BIN
      simditor/static/simditor/images/emoji/disappointed.png
  • BIN
      simditor/static/simditor/images/emoji/dizzy.png
  • BIN
      simditor/static/simditor/images/emoji/dizzy_face.png
  • BIN
      simditor/static/simditor/images/emoji/do_not_litter.png
  • BIN
      simditor/static/simditor/images/emoji/dog.png
  • BIN
      simditor/static/simditor/images/emoji/dog2.png
  • BIN
      simditor/static/simditor/images/emoji/dollar.png
  • BIN
      simditor/static/simditor/images/emoji/dolls.png
  • BIN
      simditor/static/simditor/images/emoji/dolphin.png
  • BIN
      simditor/static/simditor/images/emoji/door.png
  • BIN
      simditor/static/simditor/images/emoji/doughnut.png
  • BIN
      simditor/static/simditor/images/emoji/dragon.png
  • BIN
      simditor/static/simditor/images/emoji/dragon_face.png
  • BIN
      simditor/static/simditor/images/emoji/dress.png
  • BIN
      simditor/static/simditor/images/emoji/dromedary_camel.png
  • BIN
      simditor/static/simditor/images/emoji/droplet.png
  • BIN
      simditor/static/simditor/images/emoji/dvd.png
  • BIN
      simditor/static/simditor/images/emoji/e-mail.png
  • BIN
      simditor/static/simditor/images/emoji/ear.png
  • BIN
      simditor/static/simditor/images/emoji/ear_of_rice.png
  • BIN
      simditor/static/simditor/images/emoji/earth_africa.png
  • BIN
      simditor/static/simditor/images/emoji/earth_americas.png
  • BIN
      simditor/static/simditor/images/emoji/earth_asia.png
  • BIN
      simditor/static/simditor/images/emoji/egg.png
  • BIN
      simditor/static/simditor/images/emoji/eggplant.png
  • BIN
      simditor/static/simditor/images/emoji/eight.png
  • BIN
      simditor/static/simditor/images/emoji/eight_pointed_black_star.png
  • BIN
      simditor/static/simditor/images/emoji/eight_spoked_asterisk.png
  • BIN
      simditor/static/simditor/images/emoji/eightball.png
  • BIN
      simditor/static/simditor/images/emoji/electric_plug.png
  • BIN
      simditor/static/simditor/images/emoji/elephant.png
  • BIN
      simditor/static/simditor/images/emoji/email.png
  • 0 0
      simditor/static/simditor/images/emoji/emojify.css
  • + 1 - 1
    account/admin.py

    @@ -8,7 +8,7 @@ from mch.models import ConsumeInfoSubmitLogInfo
    8 8
     
    9 9
     
    10 10
     class UserInfoAdmin(ChangeOnlyModelAdmin, admin.ModelAdmin):
    11
    -    list_display = ('user_id', 'nickname', 'phone', 'unionid', 'openid', 'openid_miniapp', 'location', 'balance', 'user_status', 'test_user', 'status', 'created_at', 'updated_at')
    11
    +    list_display = ('user_id', 'nickname', 'phone', 'unionid', 'openid', 'openid_miniapp', 'location', 'balance', 'integral', 'freeze_integral', 'user_status', 'test_user', 'status', 'created_at', 'updated_at')
    12 12
         list_filter = ('test_user', 'sex', 'user_status', 'status')
    13 13
         readonly_fields = ('user_id', )
    14 14
         search_fields = ('user_id', 'username', 'unionid', 'openid', 'openid_miniapp', 'name', 'phone', 'location')

    + 35 - 0
    account/migrations/0037_auto_20191119_1348.py

    @@ -0,0 +1,35 @@
    1
    +# -*- coding: utf-8 -*-
    2
    +# Generated by Django 1.11.26 on 2019-11-19 05:48
    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
    +        ('account', '0036_auto_20190826_1537'),
    12
    +    ]
    13
    +
    14
    +    operations = [
    15
    +        migrations.AddField(
    16
    +            model_name='userinfo',
    17
    +            name='freeze_integral',
    18
    +            field=models.IntegerField(default=0, help_text='\u4f1a\u5458\u51bb\u7ed3\u79ef\u5206', verbose_name='freeze_integral'),
    19
    +        ),
    20
    +        migrations.AddField(
    21
    +            model_name='userinfo',
    22
    +            name='integral',
    23
    +            field=models.IntegerField(default=0, help_text='\u4f1a\u5458\u79ef\u5206', verbose_name='integral'),
    24
    +        ),
    25
    +        migrations.AddField(
    26
    +            model_name='userinfo',
    27
    +            name='level',
    28
    +            field=models.IntegerField(choices=[(0, '\u975e\u4f1a\u5458'), (1, 'LRC\u4f1a\u5458'), (2, '\u94f6\u5361\u4f1a\u5458'), (3, '\u91d1\u5361\u4f1a\u5458'), (4, '\u767d\u91d1\u5361\u4f1a\u5458'), (5, '\u9ed1\u91d1\u5361\u4f1a\u5458')], default=0, help_text='\u4f1a\u5458\u7b49\u7ea7', verbose_name='level'),
    29
    +        ),
    30
    +        migrations.AddField(
    31
    +            model_name='userinfo',
    32
    +            name='shots_num',
    33
    +            field=models.IntegerField(default=0, help_text='\u4e3b\u6301\u955c\u5934\u6570', verbose_name='shots_num'),
    34
    +        ),
    35
    +    ]

    + 27 - 0
    account/models.py

    @@ -290,6 +290,22 @@ class UserInfo(BaseModelMixin, LensmanTypeBoolMixin):
    290 290
             (FEMALE, u'女'),
    291 291
         )
    292 292
     
    293
    +    MEMBER_NO = 0
    294
    +    MEMBER_LRC = 1
    295
    +    MEMBER_SILVER = 2
    296
    +    MEMBER_GOLD = 3
    297
    +    MEMBER_WHITE_GOLD = 4
    298
    +    MEMBER_BLACK_GOLD = 5
    299
    +
    300
    +    LEVEL_TUPLE = (
    301
    +        (MEMBER_NO, u'非会员'),
    302
    +        (MEMBER_LRC, u'LRC会员'),
    303
    +        (MEMBER_SILVER, u'银卡会员'),
    304
    +        (MEMBER_GOLD, u'金卡会员'),
    305
    +        (MEMBER_WHITE_GOLD, u'白金卡会员'),
    306
    +        (MEMBER_BLACK_GOLD, u'黑金卡会员'),
    307
    +    )
    308
    +
    293 309
         user_id = models.CharField(_(u'user_id'), max_length=32, blank=True, null=True, help_text=u'用户唯一标识', db_index=True, unique=True)
    294 310
     
    295 311
         user_from = models.IntegerField(_(u'user_from'), choices=USER_FROM, default=APP_USER, help_text=u'用户来源')
    @@ -341,6 +357,13 @@ class UserInfo(BaseModelMixin, LensmanTypeBoolMixin):
    341 357
     
    342 358
         test_user = models.BooleanField(_(u'test_user'), default=False, help_text=_(u'是否为测试用户'), db_index=True)
    343 359
     
    360
    +    # 会员信息
    361
    +    integral = models.IntegerField(_(u'integral'), default=0, help_text=u'会员积分')
    362
    +    freeze_integral = models.IntegerField(_(u'freeze_integral'), default=0, help_text=u'会员冻结积分')
    363
    +
    364
    +    shots_num = models.IntegerField(_(u'shots_num'), default=0, help_text=u'主持镜头数')
    365
    +    level = models.IntegerField(_(u'level'), choices=LEVEL_TUPLE, default=MEMBER_NO, help_text=u'会员等级')
    366
    +
    344 367
         class Meta:
    345 368
             verbose_name = _(u'userinfo')
    346 369
             verbose_name_plural = _(u'userinfo')
    @@ -349,6 +372,10 @@ class UserInfo(BaseModelMixin, LensmanTypeBoolMixin):
    349 372
             return unicode(self.pk)
    350 373
     
    351 374
         @property
    375
    +    def final_integral(self):
    376
    +        return self.integral + self.freeze_integral
    377
    +
    378
    +    @property
    352 379
         def final_nickname(self):
    353 380
             if self.user_from == self.APP_USER:
    354 381
                 return self.username

    + 200 - 0
    api/member_views.py

    @@ -0,0 +1,200 @@
    1
    +# -*- coding: utf-8 -*-
    2
    +
    3
    +from __future__ import division
    4
    +
    5
    +from django.conf import settings
    6
    +from django_logit import logit
    7
    +from django_response import response
    8
    +from paginator import pagination
    9
    +
    10
    +from account.models import UserInfo
    11
    +from member.models import GoodsInfo, MemberActivityInfo, RightInfo
    12
    +from utils.error.errno_utils import UserStatusCode
    13
    +from utils.redis.rshot import get_shot_member_data
    14
    +
    15
    +
    16
    +@logit
    17
    +def member(request):
    18
    +    brand_id = request.POST.get('brand_id', settings.KODO_DEFAULT_BRAND_ID)
    19
    +    user_id = request.POST.get('user_id', '')
    20
    +
    21
    +    # 校验用户是否存在
    22
    +    try:
    23
    +        user = UserInfo.objects.get(user_id=user_id)
    24
    +    except UserInfo.DoesNotExist:
    25
    +        return response(UserStatusCode.USER_NOT_FOUND)
    26
    +
    27
    +    rights = RightInfo.objects.filter(status=True).order_by('position')
    28
    +    rights = [right.data for right in rights]
    29
    +
    30
    +    goods = GoodsInfo.objects.filter(status=True).order_by('position')
    31
    +    goods = [good.data for good in goods]
    32
    +
    33
    +    return response(200, data={
    34
    +        'nickname': user.final_nickname,
    35
    +        'avatar': user.avatar,
    36
    +        'integral': user.integral,
    37
    +        'freeze_integral': user.freeze_integral,
    38
    +        'final_integral': user.final_integral,
    39
    +        'shots_num': user.shots_num,
    40
    +        'level': user.level,
    41
    +        'rights': rights,
    42
    +        'goods': goods,
    43
    +    })
    44
    +
    45
    +
    46
    +@logit
    47
    +def rights(request):
    48
    +    brand_id = request.POST.get('brand_id', settings.KODO_DEFAULT_BRAND_ID)
    49
    +    user_id = request.POST.get('user_id', '')
    50
    +    level = request.POST.get('level', '')
    51
    +
    52
    +    # 校验用户是否存在
    53
    +    try:
    54
    +        user = UserInfo.objects.get(user_id=user_id)
    55
    +    except UserInfo.DoesNotExist:
    56
    +        return response(UserStatusCode.USER_NOT_FOUND)
    57
    +
    58
    +    rights = RightInfo.objects.filter(status=True).order_by('position')
    59
    +    rights = [right.data for right in rights]
    60
    +
    61
    +    return response(200, data={
    62
    +        'nickname': user.final_nickname,
    63
    +        'avatar': user.avatar,
    64
    +        'integral': user.integral,
    65
    +        'freeze_integral': user.freeze_integral,
    66
    +        'final_integral': user.final_integral,
    67
    +        'shots_num': user.shots_num,
    68
    +        'level': user.level,
    69
    +        'rights': rights,
    70
    +    })
    71
    +
    72
    +
    73
    +@logit
    74
    +def right_detail(request):
    75
    +    brand_id = request.POST.get('brand_id', settings.KODO_DEFAULT_BRAND_ID)
    76
    +    user_id = request.POST.get('user_id', '')
    77
    +    right_id = request.POST.get('right_id', '')
    78
    +
    79
    +    try:
    80
    +        right = RightInfo.objects.get(right_id=right_id)
    81
    +    except RightInfo.DoesNotExist:
    82
    +        return response()
    83
    +
    84
    +    return response(200, data={
    85
    +        'right': right.data,
    86
    +    })
    87
    +
    88
    +
    89
    +@logit
    90
    +def goods(request):
    91
    +    brand_id = request.POST.get('brand_id', settings.KODO_DEFAULT_BRAND_ID)
    92
    +    user_id = request.POST.get('user_id', '')
    93
    +
    94
    +    # 校验用户是否存在
    95
    +    try:
    96
    +        user = UserInfo.objects.get(user_id=user_id)
    97
    +    except UserInfo.DoesNotExist:
    98
    +        return response(UserStatusCode.USER_NOT_FOUND)
    99
    +
    100
    +    raw_goods = GoodsInfo.objects.filter(status=True).order_by('position')
    101
    +    banners = goods = []
    102
    +    for good in raw_goods:
    103
    +        if good.is_slider:
    104
    +            banners.append(good.data)
    105
    +        else:
    106
    +            goods.append(good.data)
    107
    +
    108
    +    return response(200, data={
    109
    +        'nickname': user.final_nickname,
    110
    +        'avatar': user.avatar,
    111
    +        'integral': user.integral,
    112
    +        'freeze_integral': user.freeze_integral,
    113
    +        'final_integral': user.final_integral,
    114
    +        'shots_num': user.shots_num,
    115
    +        'level': user.level,
    116
    +        'banners': banners,
    117
    +        'goods': goods,
    118
    +    })
    119
    +
    120
    +
    121
    +@logit
    122
    +def good_detail(request):
    123
    +    brand_id = request.POST.get('brand_id', settings.KODO_DEFAULT_BRAND_ID)
    124
    +    user_id = request.POST.get('user_id', '')
    125
    +    good_id = request.POST.get('good_id', '')
    126
    +
    127
    +    # 校验用户是否存在
    128
    +    try:
    129
    +        user = UserInfo.objects.get(user_id=user_id)
    130
    +    except UserInfo.DoesNotExist:
    131
    +        return response(UserStatusCode.USER_NOT_FOUND)
    132
    +
    133
    +    try:
    134
    +        good = GoodsInfo.objects.get(good_id=good_id)
    135
    +    except GoodsInfo.DoesNotExist:
    136
    +        return response()
    137
    +
    138
    +    return response(200, data={
    139
    +        'nickname': user.final_nickname,
    140
    +        'avatar': user.avatar,
    141
    +        'integral': user.integral,
    142
    +        'freeze_integral': user.freeze_integral,
    143
    +        'final_integral': user.final_integral,
    144
    +        'shots_num': user.shots_num,
    145
    +        'level': user.level,
    146
    +        'good': good.data,
    147
    +    })
    148
    +
    149
    +
    150
    +@logit
    151
    +def integrals(request):
    152
    +    brand_id = request.POST.get('brand_id', settings.KODO_DEFAULT_BRAND_ID)
    153
    +
    154
    +    return response(200, data={
    155
    +        'shots_types': get_shot_member_data(),
    156
    +        'enable_photo_upvote_integral': True,
    157
    +        'photo_upvote_integrals': {
    158
    +            'headers': ['排名', '日', '周', '月'],
    159
    +            'ranks': [
    160
    +                ['第1名', '10', '20', '30'],
    161
    +                ['第2名', '5', '10', '15'],
    162
    +                ['第3名', '3', '6', '9'],
    163
    +                ['第4-10名', '1', '2', '3'],
    164
    +            ]
    165
    +        },
    166
    +        'enable_activity_integral': True,
    167
    +    })
    168
    +
    169
    +
    170
    +@logit
    171
    +def activity_list(request):
    172
    +    brand_id = request.POST.get('brand_id', settings.KODO_DEFAULT_BRAND_ID)
    173
    +
    174
    +    raw_activitys = MemberActivityInfo.objects.filter(status=True).order_by('position')
    175
    +    banners = activitys = []
    176
    +    for act in raw_activitys:
    177
    +        if act.is_slider:
    178
    +            banners.append(act.data)
    179
    +        else:
    180
    +            goods.append(act.data)
    181
    +
    182
    +    return response(200, data={
    183
    +        'banners': banners,
    184
    +        'activitys': activitys,
    185
    +    })
    186
    +
    187
    +
    188
    +@logit
    189
    +def activity_detail(request):
    190
    +    brand_id = request.POST.get('brand_id', settings.KODO_DEFAULT_BRAND_ID)
    191
    +    activity_id = request.POST.get('activity_id')
    192
    +
    193
    +    try:
    194
    +        act = MemberActivityInfo.objects.get(pk=activity_id, status=True)
    195
    +    except MemberActivityInfo.DoesNotExist:
    196
    +        return response()
    197
    +
    198
    +    return response(200, data={
    199
    +        'activity': act.data,
    200
    +    })

    + 21 - 2
    api/urls.py

    @@ -5,8 +5,8 @@ from django_file_upload import views as file_views
    5 5
     
    6 6
     from account import tourguide_views
    7 7
     from account import views as account_views
    8
    -from api import (admin_views, clerk_views, distributor_views, encrypt_views, mch_views, model_views, operator_views,
    9
    -                 sr_views)
    8
    +from api import (admin_views, clerk_views, distributor_views, encrypt_views, mch_views, member_views, model_views,
    9
    +                 operator_views, sr_views)
    10 10
     from box import views as box_views
    11 11
     from geo import views as geo_views
    12 12
     from group import (groupuser_views, lensman_views, tourguidegroup_views, tourguidegroupadmin_views,
    @@ -298,3 +298,22 @@ urlpatterns += [
    298 298
     urlpatterns += [
    299 299
         url(r'^supersr/sr/tj$', sales_views.supersr_sr_tj, name='supersr_sr_tj'),
    300 300
     ]
    301
    +
    302
    +urlpatterns += [
    303
    +    url(r'^member$', member_views.member, name='member'),
    304
    +
    305
    +    url(r'^member/rights$', member_views.rights, name='member_rights'),
    306
    +    url(r'^member/right/detail$', member_views.right_detail, name='member_right_detail'),
    307
    +    url(r'^member/goods$', member_views.goods, name='member_goods'),
    308
    +    url(r'^member/good/detail$', member_views.good_detail, name='member_good_detail'),
    309
    +    url(r'^member/integrals$', member_views.integrals, name='member_integrals'),
    310
    +
    311
    +    url(r'^member/activity/list$', member_views.activity_list, name='member_activity_list'),
    312
    +    url(r'^member/activity/detail$', member_views.activity_detail, name='member_activity_detail'),
    313
    +
    314
    +    url(r'^rights$', member_views.rights, name='rights'),
    315
    +    url(r'^right/detail$', member_views.right_detail, name='right_detail'),
    316
    +    url(r'^goods$', member_views.goods, name='goods'),
    317
    +    url(r'^good/detail$', member_views.good_detail, name='good_detail'),
    318
    +    url(r'^integrals$', member_views.integrals, name='integrals'),
    319
    +]

    + 25 - 0
    integral/migrations/0011_auto_20191119_1348.py

    @@ -0,0 +1,25 @@
    1
    +# -*- coding: utf-8 -*-
    2
    +# Generated by Django 1.11.26 on 2019-11-19 05:48
    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
    +        ('integral', '0010_auto_20190909_1456'),
    12
    +    ]
    13
    +
    14
    +    operations = [
    15
    +        migrations.AddField(
    16
    +            model_name='saleclerksubmitloginfo',
    17
    +            name='has_scan',
    18
    +            field=models.BooleanField(db_index=True, default=False, help_text='\u662f\u5426\u88ab\u6d88\u8d39\u8005\u626b\u8fc7', verbose_name='has_scan'),
    19
    +        ),
    20
    +        migrations.AddField(
    21
    +            model_name='saleclerksubmitloginfo',
    22
    +            name='trackingNo',
    23
    +            field=models.CharField(blank=True, help_text='\u5feb\u9012\u5355\u53f7', max_length=32, null=True, verbose_name='trackingNo'),
    24
    +        ),
    25
    +    ]

    + 21 - 0
    kodo/settings.py

    @@ -49,6 +49,7 @@ INSTALLED_APPS = (
    49 49
         'django_rlog',
    50 50
         'django_we',
    51 51
         'corsheaders',
    52
    +    'simditor',
    52 53
         'api',
    53 54
         'account',
    54 55
         'box',
    @@ -58,6 +59,7 @@ INSTALLED_APPS = (
    58 59
         'integral',
    59 60
         'logs',
    60 61
         'mch',
    62
    +    'member',
    61 63
         'message',
    62 64
         'miniapp',
    63 65
         'operation',
    @@ -346,6 +348,25 @@ CORS_ORIGIN_WHITELIST = (
    346 348
     )
    347 349
     CORS_ALLOW_CREDENTIALS = True
    348 350
     
    351
    +# 富文本编辑器
    352
    +SIMDITOR_UPLOAD_PATH = 'uploads/'
    353
    +SIMDITOR_TOOLBAR = [
    354
    +    'markdown', 'title', 'bold', 'italic', 'underline', 'strikethrough', 'fontScale',
    355
    +    'color', '|', 'ol', 'ul', 'blockquote', 'code', 'table', '|', 'link',
    356
    +    'image', 'hr', '|', 'indent', 'outdent', 'alignment', 'checklist', 'fullscreen', 'emoji'
    357
    +]
    358
    +SIMDITOR_CONFIGS = {
    359
    +    'toolbar': SIMDITOR_TOOLBAR,
    360
    +    'upload': {
    361
    +        'url': '/simditor/upload/',
    362
    +        'fileKey': 'upload',
    363
    +        'image_size': 1024 * 1024 * 4  # max image size 4MB
    364
    +    },
    365
    +    'emoji': {
    366
    +        'imagePath': '/static/simditor/images/emoji/'
    367
    +    }
    368
    +}
    369
    +
    349 370
     # 错误信息邮件设置
    350 371
     # Email address that error messages come from.
    351 372
     SERVER_EMAIL = 'kimi@pai.ai'

    + 8 - 1
    mch/admin.py

    @@ -10,6 +10,7 @@ from pysnippets.strsnippets import strip
    10 10
     
    11 11
     from mch.models import (ActivityInfo, AdministratorInfo, BrandInfo, ConsumeInfoSubmitLogInfo, DistributorInfo,
    12 12
                             LatestAppInfo, LatestAppScreenInfo, ModelInfo, OperatorInfo, SaleclerkInfo)
    13
    +from utils.redis.rshot import update_shot_member_data
    13 14
     
    14 15
     
    15 16
     class AdministratorInfoAdmin(admin.ModelAdmin):
    @@ -64,7 +65,7 @@ class BrandInfoAdmin(admin.ModelAdmin):
    64 65
     
    65 66
     class ModelInfoAdmin(admin.ModelAdmin):
    66 67
         list_display = ('brand_id', 'brand_name', 'jancode', 'model_id', 'model_name', 'model_uni_name', 'model_full_name', 'model_descr', 'category', 'warehouse', 'image', 'url', 'image2', 'factory_yuan', 'integral', 'position', 'display', 'status', 'created_at', 'updated_at')
    67
    -    list_filter = ('brand_name', 'category', 'warehouse', 'display', 'status')
    68
    +    list_filter = ('brand_name', 'category', 'warehouse', 'shot_type_id', 'display', 'status')
    68 69
         readonly_fields = ('brand_name', 'factory_fee')
    69 70
         search_fields = ('brand_id', 'brand_name', 'jancode', 'model_id', 'model_name', 'model_uni_name', 'model_full_name', 'model_descr', 'category', 'warehouse')
    70 71
     
    @@ -80,6 +81,12 @@ class ModelInfoAdmin(admin.ModelAdmin):
    80 81
     
    81 82
             obj.save()
    82 83
     
    84
    +        update_shot_member_data()
    85
    +
    86
    +    def delete_model(self, request, obj):
    87
    +        obj.delete()
    88
    +        update_shot_member_data()
    89
    +
    83 90
     
    84 91
     class ModelImageInfoAdmin(admin.ModelAdmin):
    85 92
         list_display = ('model_id', 'model_name', 'image', 'url', 'position', 'status', 'created_at', 'updated_at')

    + 36 - 0
    mch/migrations/0039_auto_20191119_1348.py

    @@ -0,0 +1,36 @@
    1
    +# -*- coding: utf-8 -*-
    2
    +# Generated by Django 1.11.26 on 2019-11-19 05:48
    3
    +from __future__ import unicode_literals
    4
    +
    5
    +from django.db import migrations, models
    6
    +import django_models_ext.fileext
    7
    +
    8
    +
    9
    +class Migration(migrations.Migration):
    10
    +
    11
    +    dependencies = [
    12
    +        ('mch', '0038_auto_20190826_1625'),
    13
    +    ]
    14
    +
    15
    +    operations = [
    16
    +        migrations.AddField(
    17
    +            model_name='modelinfo',
    18
    +            name='shot_member_image',
    19
    +            field=models.ImageField(blank=True, help_text='\u955c\u5934\u4f1a\u5458\u56fe\u7247', null=True, upload_to=django_models_ext.fileext.upload_path, verbose_name='shot_member_image'),
    20
    +        ),
    21
    +        migrations.AddField(
    22
    +            model_name='modelinfo',
    23
    +            name='shot_member_integral',
    24
    +            field=models.IntegerField(default=0, help_text='\u955c\u5934\u4f1a\u5458\u79ef\u5206', verbose_name='shot_member_integral'),
    25
    +        ),
    26
    +        migrations.AddField(
    27
    +            model_name='modelinfo',
    28
    +            name='shot_type_id',
    29
    +            field=models.CharField(blank=True, db_index=True, help_text='\u955c\u5934\u7c7b\u578b\u552f\u4e00\u6807\u8bc6', max_length=32, null=True, verbose_name='shot_type_id'),
    30
    +        ),
    31
    +        migrations.AddField(
    32
    +            model_name='saleclerkinfo',
    33
    +            name='is_online_sales',
    34
    +            field=models.BooleanField(db_index=True, default=False, help_text='\u662f\u5426\u4e3a\u7f51\u9500', verbose_name='is_online_sales'),
    35
    +        ),
    36
    +    ]

    + 21 - 0
    mch/models.py

    @@ -161,6 +161,10 @@ class ModelInfo(BaseModelMixin):
    161 161
     
    162 162
         is_important = models.BooleanField(_(u'is_important'), default=False, help_text=_(u'是否重要型号'), db_index=True)
    163 163
     
    164
    +    shot_type_id = models.CharField(_(u'shot_type_id'), max_length=32, blank=True, null=True, help_text=u'镜头类型唯一标识', db_index=True)
    165
    +    shot_member_integral = models.IntegerField(_(u'shot_member_integral'), default=0, help_text=u'镜头会员积分')
    166
    +    shot_member_image = models.ImageField(_(u'shot_member_image'), upload_to=upload_path, blank=True, null=True, help_text=u'镜头会员图片')
    167
    +
    164 168
         class Meta:
    165 169
             verbose_name = _(u'型号信息')
    166 170
             verbose_name_plural = _(u'型号信息')
    @@ -185,6 +189,14 @@ class ModelInfo(BaseModelMixin):
    185 189
             return upload_file_url(self.image2)
    186 190
     
    187 191
         @property
    192
    +    def shot_member_image_path(self):
    193
    +        return upload_file_path(self.shot_member_image)
    194
    +
    195
    +    @property
    196
    +    def shot_member_image_url(self):
    197
    +        return upload_file_url(self.shot_member_image)
    198
    +
    199
    +    @property
    188 200
         def data(self):
    189 201
             return {
    190 202
                 'jancode': self.jancode,
    @@ -228,6 +240,15 @@ class ModelInfo(BaseModelMixin):
    228 240
     
    229 241
         fulldata = admindata
    230 242
     
    243
    +    @property
    244
    +    def shot_member_data(self):
    245
    +        return {
    246
    +            'shot_id': self.model_id,
    247
    +            'shot_name': self.model_name,
    248
    +            'shot_image': self.shot_member_image_url,
    249
    +            'integral': self.shot_member_integral,
    250
    +        }
    251
    +
    231 252
     
    232 253
     class ModelImageInfo(BaseModelMixin):
    233 254
         model_id = models.CharField(_(u'model_id'), max_length=32, blank=True, null=True, help_text=u'型号唯一标识', db_index=True)

    + 0 - 0
    member/__init__.py


    + 38 - 0
    member/admin.py

    @@ -0,0 +1,38 @@
    1
    +# -*- coding: utf-8 -*-
    2
    +
    3
    +from django.contrib import admin
    4
    +
    5
    +from member.models import GoodsInfo, MemberActivityInfo, ShotTypeInfo, RightInfo
    6
    +from utils.redis.rshot import update_shot_member_data
    7
    +
    8
    +
    9
    +class GoodsInfoAdmin(admin.ModelAdmin):
    10
    +    list_display = ('good_id', 'good_type', 'title', 'desc', 'image', 'is_slider', 'slider_image', 'integral', 'fee', 'minlevel', 'position', 'status', 'created_at', 'updated_at')
    11
    +    list_filter = ('is_slider', 'status')
    12
    +
    13
    +
    14
    +class RightInfoAdmin(admin.ModelAdmin):
    15
    +    list_display = ('right_id', 'icon', 'title', 'subtitle', 'detail', 'minlevel', 'position', 'status', 'created_at', 'updated_at')
    16
    +
    17
    +
    18
    +class ShotTypeInfoAdmin(admin.ModelAdmin):
    19
    +    list_display = ('shot_type_id', 'shot_type_name', 'position', 'status', 'created_at', 'updated_at')
    20
    +
    21
    +    def save_model(self, request, obj, form, change):
    22
    +        obj.save()
    23
    +        update_shot_member_data()
    24
    +
    25
    +    def delete_model(self, request, obj):
    26
    +        obj.delete()
    27
    +        update_shot_member_data()
    28
    +
    29
    +
    30
    +class MemberActivityInfoAdmin(admin.ModelAdmin):
    31
    +    list_display = ('title', 'subtitle', 'date', 'location', 'image', 'is_slider', 'slider_image', 'position', 'status', 'created_at', 'updated_at')
    32
    +    list_filter = ('is_slider', 'status')
    33
    +
    34
    +
    35
    +admin.site.register(GoodsInfo, GoodsInfoAdmin)
    36
    +admin.site.register(RightInfo, RightInfoAdmin)
    37
    +admin.site.register(ShotTypeInfo, ShotTypeInfoAdmin)
    38
    +admin.site.register(MemberActivityInfo, MemberActivityInfoAdmin)

    + 8 - 0
    member/apps.py

    @@ -0,0 +1,8 @@
    1
    +# -*- coding: utf-8 -*-
    2
    +from __future__ import unicode_literals
    3
    +
    4
    +from django.apps import AppConfig
    5
    +
    6
    +
    7
    +class MemberConfig(AppConfig):
    8
    +    name = 'member'

    + 104 - 0
    member/migrations/0001_initial.py

    @@ -0,0 +1,104 @@
    1
    +# -*- coding: utf-8 -*-
    2
    +# Generated by Django 1.11.26 on 2019-11-19 05:48
    3
    +from __future__ import unicode_literals
    4
    +
    5
    +from django.db import migrations, models
    6
    +import django_models_ext.fileext
    7
    +import shortuuidfield.fields
    8
    +import simditor.fields
    9
    +
    10
    +
    11
    +class Migration(migrations.Migration):
    12
    +
    13
    +    initial = True
    14
    +
    15
    +    dependencies = [
    16
    +    ]
    17
    +
    18
    +    operations = [
    19
    +        migrations.CreateModel(
    20
    +            name='GoodsInfo',
    21
    +            fields=[
    22
    +                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
    23
    +                ('status', models.BooleanField(db_index=True, default=True, help_text='Status', verbose_name='status')),
    24
    +                ('created_at', models.DateTimeField(auto_now_add=True, help_text='Create Time', verbose_name='created_at')),
    25
    +                ('updated_at', models.DateTimeField(auto_now=True, help_text='Update Time', verbose_name='updated_at')),
    26
    +                ('good_id', shortuuidfield.fields.ShortUUIDField(blank=True, db_index=True, editable=False, help_text='\u5546\u54c1\u552f\u4e00\u6807\u8bc6', max_length=22, null=True, unique=True)),
    27
    +                ('good_type', models.IntegerField(choices=[(0, '\u5b9e\u7269'), (1, '\u865a\u62df')], db_index=True, default=1, help_text='\u5546\u54c1\u7c7b\u578b', verbose_name='good_type')),
    28
    +                ('title', models.CharField(blank=True, help_text='\u5546\u54c1\u540d\u79f0', max_length=255, null=True, verbose_name='title')),
    29
    +                ('desc', simditor.fields.RichTextField(blank=True, help_text='\u5546\u54c1\u63cf\u8ff0', null=True, verbose_name='desc')),
    30
    +                ('image', models.ImageField(blank=True, help_text='\u5546\u54c1\u56fe\u7247', null=True, upload_to=django_models_ext.fileext.upload_path, verbose_name='image')),
    31
    +                ('is_slider', models.BooleanField(db_index=True, default=True, help_text='\u662f\u5426\u4e3a\u8f6e\u64ad\u5546\u54c1', verbose_name='is_slider')),
    32
    +                ('slider_image', models.ImageField(blank=True, help_text='\u5546\u54c1\u8f6e\u64ad\u56fe\u7247', null=True, upload_to=django_models_ext.fileext.upload_path, verbose_name='slider_image')),
    33
    +                ('integral', models.IntegerField(default=99999, help_text='\u5151\u6362\u6240\u9700\u79ef\u5206', verbose_name='integral')),
    34
    +                ('fee', models.IntegerField(default=99999, help_text='\u5151\u6362\u9700\u989d\u5916\u652f\u4ed8\u91d1\u989d\uff0c\u5355\u4f4d\u5206', verbose_name='fee')),
    35
    +                ('minlevel', models.IntegerField(default=0, help_text='\u5151\u6362\u6700\u4f4e\u4f1a\u5458\u7ea7\u522b', verbose_name='minlevel')),
    36
    +                ('position', models.IntegerField(db_index=True, default=1, help_text='\u6392\u5e8f', verbose_name='position')),
    37
    +            ],
    38
    +            options={
    39
    +                'verbose_name': '\u5546\u54c1\u4fe1\u606f',
    40
    +                'verbose_name_plural': '\u5546\u54c1\u4fe1\u606f',
    41
    +            },
    42
    +        ),
    43
    +        migrations.CreateModel(
    44
    +            name='MemberActivityInfo',
    45
    +            fields=[
    46
    +                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
    47
    +                ('status', models.BooleanField(db_index=True, default=True, help_text='Status', verbose_name='status')),
    48
    +                ('created_at', models.DateTimeField(auto_now_add=True, help_text='Create Time', verbose_name='created_at')),
    49
    +                ('updated_at', models.DateTimeField(auto_now=True, help_text='Update Time', verbose_name='updated_at')),
    50
    +                ('title', models.CharField(blank=True, help_text='\u6d3b\u52a8\u540d\u79f0', max_length=255, null=True, verbose_name='title')),
    51
    +                ('subtitle', models.CharField(blank=True, help_text='\u6d3b\u52a8\u4e8c\u7ea7\u540d\u79f0', max_length=255, null=True, verbose_name='subtitle')),
    52
    +                ('date', models.DateField(blank=True, help_text='\u6d3b\u52a8\u65f6\u95f4', null=True, verbose_name='date')),
    53
    +                ('location', models.CharField(blank=True, help_text='\u6d3b\u52a8\u5730\u70b9', max_length=255, null=True, verbose_name='location')),
    54
    +                ('image', models.ImageField(blank=True, help_text='\u6d3b\u52a8\u5185\u5bb9\u56fe\u7247', null=True, upload_to=django_models_ext.fileext.upload_path, verbose_name='image')),
    55
    +                ('cover', models.ImageField(blank=True, help_text='\u6d3b\u52a8\u5217\u8868\u56fe\u7247', null=True, upload_to=django_models_ext.fileext.upload_path, verbose_name='cover')),
    56
    +                ('is_slider', models.BooleanField(db_index=True, default=True, help_text='\u662f\u5426\u4e3a\u8f6e\u64ad\u6d3b\u52a8', verbose_name='is_slider')),
    57
    +                ('slider_image', models.ImageField(blank=True, help_text='\u6d3b\u52a8\u8f6e\u64ad\u56fe\u7247', null=True, upload_to=django_models_ext.fileext.upload_path, verbose_name='slider_image')),
    58
    +                ('content_rich_text', simditor.fields.RichTextField(blank=True, help_text='\u6d3b\u52a8\u63cf\u8ff0', null=True, verbose_name='content_rich_text')),
    59
    +                ('share_img_link', models.CharField(blank=True, help_text='\u6d3b\u52a8\u56fe\u7247\u5206\u4eab', max_length=255, null=True, verbose_name='share_img_link')),
    60
    +                ('share_h5_link', models.CharField(blank=True, help_text='\u6d3b\u52a8H5\u5206\u4eab', max_length=255, null=True, verbose_name='share_h5_link')),
    61
    +                ('position', models.IntegerField(db_index=True, default=1, help_text='\u6392\u5e8f', verbose_name='position')),
    62
    +            ],
    63
    +            options={
    64
    +                'verbose_name': '\u4f1a\u5458\u6d3b\u52a8\u4fe1\u606f',
    65
    +                'verbose_name_plural': '\u4f1a\u5458\u6d3b\u52a8\u4fe1\u606f',
    66
    +            },
    67
    +        ),
    68
    +        migrations.CreateModel(
    69
    +            name='RightInfo',
    70
    +            fields=[
    71
    +                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
    72
    +                ('status', models.BooleanField(db_index=True, default=True, help_text='Status', verbose_name='status')),
    73
    +                ('created_at', models.DateTimeField(auto_now_add=True, help_text='Create Time', verbose_name='created_at')),
    74
    +                ('updated_at', models.DateTimeField(auto_now=True, help_text='Update Time', verbose_name='updated_at')),
    75
    +                ('right_id', shortuuidfield.fields.ShortUUIDField(blank=True, db_index=True, editable=False, help_text='\u6743\u76ca\u552f\u4e00\u6807\u8bc6', max_length=22, null=True, unique=True)),
    76
    +                ('icon', models.ImageField(blank=True, help_text='\u6743\u76ca\u56fe\u6807', null=True, upload_to=django_models_ext.fileext.upload_path, verbose_name='icon')),
    77
    +                ('title', models.CharField(blank=True, help_text='\u6743\u76ca\u540d\u79f0', max_length=255, null=True, verbose_name='title')),
    78
    +                ('subtitle', models.CharField(blank=True, help_text='\u6743\u76ca\u4e8c\u7ea7\u540d\u79f0', max_length=255, null=True, verbose_name='subtitle')),
    79
    +                ('detail', simditor.fields.RichTextField(blank=True, help_text='\u6743\u76ca\u8be6\u60c5', null=True, verbose_name='detail')),
    80
    +                ('minlevel', models.IntegerField(default=0, help_text='\u6743\u76ca\u6700\u4f4e\u4f1a\u5458\u7ea7\u522b', verbose_name='minlevel')),
    81
    +                ('position', models.IntegerField(db_index=True, default=1, help_text='\u6392\u5e8f', verbose_name='position')),
    82
    +            ],
    83
    +            options={
    84
    +                'verbose_name': '\u6743\u76ca\u4fe1\u606f',
    85
    +                'verbose_name_plural': '\u6743\u76ca\u4fe1\u606f',
    86
    +            },
    87
    +        ),
    88
    +        migrations.CreateModel(
    89
    +            name='ShotTypeInfo',
    90
    +            fields=[
    91
    +                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
    92
    +                ('status', models.BooleanField(db_index=True, default=True, help_text='Status', verbose_name='status')),
    93
    +                ('created_at', models.DateTimeField(auto_now_add=True, help_text='Create Time', verbose_name='created_at')),
    94
    +                ('updated_at', models.DateTimeField(auto_now=True, help_text='Update Time', verbose_name='updated_at')),
    95
    +                ('shot_type_id', shortuuidfield.fields.ShortUUIDField(blank=True, db_index=True, editable=False, help_text='\u955c\u5934\u7c7b\u578b\u552f\u4e00\u6807\u8bc6', max_length=22, null=True, unique=True)),
    96
    +                ('shot_type_name', models.CharField(blank=True, help_text='\u955c\u5934\u7c7b\u578b\u540d\u79f0', max_length=255, null=True, verbose_name='shot_type_name')),
    97
    +                ('position', models.IntegerField(db_index=True, default=1, help_text='\u6392\u5e8f', verbose_name='position')),
    98
    +            ],
    99
    +            options={
    100
    +                'verbose_name': '\u955c\u5934\u7c7b\u578b\u4fe1\u606f',
    101
    +                'verbose_name_plural': '\u955c\u5934\u7c7b\u578b\u4fe1\u606f',
    102
    +            },
    103
    +        ),
    104
    +    ]

    + 0 - 0
    member/migrations/__init__.py


    + 211 - 0
    member/models.py

    @@ -0,0 +1,211 @@
    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, upload_file_path, upload_file_url, upload_path
    6
    +from simditor.fields import RichTextField
    7
    +from shortuuidfield import ShortUUIDField
    8
    +
    9
    +from mch.models import ModelInfo
    10
    +
    11
    +
    12
    +class GoodsInfo(BaseModelMixin):
    13
    +    PHYSICAL = 0
    14
    +    VIRTUAL = 1
    15
    +
    16
    +    GOOD_TYPE_TUPLE = (
    17
    +        (PHYSICAL, u'实物'),
    18
    +        (VIRTUAL, u'虚拟'),
    19
    +    )
    20
    +
    21
    +    good_id = ShortUUIDField(_(u'good_id'), max_length=32, blank=True, null=True, help_text=u'商品唯一标识', db_index=True, unique=True)
    22
    +    good_type = models.IntegerField(_(u'good_type'), choices=GOOD_TYPE_TUPLE, default=VIRTUAL, help_text=u'商品类型', db_index=True)
    23
    +
    24
    +    title = models.CharField(_(u'title'), max_length=255, blank=True, null=True, help_text=u'商品名称')
    25
    +    desc = RichTextField(_(u'desc'), blank=True, null=True, help_text=u'商品描述')
    26
    +
    27
    +    image = models.ImageField(_(u'image'), upload_to=upload_path, blank=True, null=True, help_text=u'商品图片')
    28
    +
    29
    +    is_slider = models.BooleanField(_(u'is_slider'), default=True, help_text=_(u'是否为轮播商品'), db_index=True)
    30
    +    slider_image = models.ImageField(_(u'slider_image'), upload_to=upload_path, blank=True, null=True, help_text=u'商品轮播图片')
    31
    +
    32
    +    integral = models.IntegerField(_(u'integral'), default=99999, help_text=u'兑换所需积分')
    33
    +    fee = models.IntegerField(_(u'fee'), default=99999, help_text=u'兑换需额外支付金额,单位分')
    34
    +
    35
    +    minlevel = models.IntegerField(_(u'minlevel'), default=0, help_text=u'兑换最低会员级别')
    36
    +
    37
    +    position = models.IntegerField(_(u'position'), default=1, help_text=u'排序', db_index=True)
    38
    +
    39
    +    class Meta:
    40
    +        verbose_name = _(u'会员商品信息')
    41
    +        verbose_name_plural = _(u'会员商品信息')
    42
    +
    43
    +    def __unicode__(self):
    44
    +        return unicode(self.pk)
    45
    +
    46
    +    @property
    47
    +    def image_path(self):
    48
    +        return upload_file_path(self.image)
    49
    +
    50
    +    @property
    51
    +    def image_url(self):
    52
    +        return upload_file_url(self.image)
    53
    +
    54
    +    @property
    55
    +    def slider_image_path(self):
    56
    +        return upload_file_path(self.slider_image)
    57
    +
    58
    +    @property
    59
    +    def slider_image_url(self):
    60
    +        return upload_file_url(self.slider_image)
    61
    +
    62
    +    @property
    63
    +    def data(self):
    64
    +        return {
    65
    +            'good_id': self.good_id,
    66
    +            'good_type': self.good_type,
    67
    +            'title': self.title,
    68
    +            'desc': self.desc,
    69
    +            'image': self.image_url,
    70
    +            'slider_image': self.slider_image_url,
    71
    +            'integral': self.integral,
    72
    +            'fee': self.fee,
    73
    +            'minlevel': self.minlevel,
    74
    +            'able': True,
    75
    +        }
    76
    +
    77
    +
    78
    +class RightInfo(BaseModelMixin):
    79
    +    right_id = ShortUUIDField(_(u'right_id'), max_length=32, blank=True, null=True, help_text=u'权益唯一标识', db_index=True, unique=True)
    80
    +
    81
    +    icon = models.ImageField(_(u'icon'), upload_to=upload_path, blank=True, null=True, help_text=u'权益图标')
    82
    +    title = models.CharField(_(u'title'), max_length=255, blank=True, null=True, help_text=u'权益名称')
    83
    +    subtitle = models.CharField(_(u'subtitle'), max_length=255, blank=True, null=True, help_text=u'权益二级名称')
    84
    +    detail = RichTextField(_(u'detail'), blank=True, null=True, help_text=u'权益详情')
    85
    +
    86
    +    minlevel = models.IntegerField(_(u'minlevel'), default=0, help_text=u'权益最低会员级别')
    87
    +
    88
    +    position = models.IntegerField(_(u'position'), default=1, help_text=u'排序', db_index=True)
    89
    +
    90
    +    class Meta:
    91
    +        verbose_name = _(u'会员权益信息')
    92
    +        verbose_name_plural = _(u'会员权益信息')
    93
    +
    94
    +    def __unicode__(self):
    95
    +        return unicode(self.pk)
    96
    +
    97
    +    @property
    98
    +    def icon_path(self):
    99
    +        return upload_file_path(self.icon)
    100
    +
    101
    +    @property
    102
    +    def icon_url(self):
    103
    +        return upload_file_url(self.icon)
    104
    +
    105
    +    @property
    106
    +    def data(self):
    107
    +        return {
    108
    +            'right_id': self.right_id,
    109
    +            'icon': self.icon_url,
    110
    +            'title': self.title,
    111
    +            'subtitle': self.subtitle,
    112
    +            'detail': self.detail,
    113
    +            'minlevel': self.minlevel,
    114
    +            "able": True,
    115
    +            "left_num": 3,
    116
    +            "left_tip": 3,
    117
    +        }
    118
    +
    119
    +
    120
    +class ShotTypeInfo(BaseModelMixin):
    121
    +    shot_type_id = ShortUUIDField(_(u'shot_type_id'), max_length=32, blank=True, null=True, help_text=u'镜头类型唯一标识', db_index=True, unique=True)
    122
    +    shot_type_name = models.CharField(_(u'shot_type_name'), max_length=255, blank=True, null=True, help_text=u'镜头类型名称')
    123
    +
    124
    +    position = models.IntegerField(_(u'position'), default=1, help_text=u'排序', db_index=True)
    125
    +
    126
    +    class Meta:
    127
    +        verbose_name = _(u'镜头类型信息')
    128
    +        verbose_name_plural = _(u'镜头类型信息')
    129
    +
    130
    +    def __unicode__(self):
    131
    +        return unicode(self.pk)
    132
    +
    133
    +    @property
    134
    +    def shots(self):
    135
    +        models = ModelInfo.objects.filter(shot_type_id=self.shot_type_id, status=True)
    136
    +        return [model.shot_data for model in models]
    137
    +
    138
    +    @property
    139
    +    def data(self):
    140
    +        return {
    141
    +            'type_id': self.shot_type_id,
    142
    +            'type_name': self.shot_type_name,
    143
    +            'shots': self.shots,
    144
    +        }
    145
    +
    146
    +
    147
    +class MemberActivityInfo(BaseModelMixin):
    148
    +    title = models.CharField(_(u'title'), max_length=255, blank=True, null=True, help_text=u'活动名称')
    149
    +    subtitle = models.CharField(_(u'subtitle'), max_length=255, blank=True, null=True, help_text=u'活动二级名称')
    150
    +
    151
    +    date = models.DateField(_(u'date'), blank=True, null=True, help_text=u'活动时间')
    152
    +    location = models.CharField(_(u'location'), max_length=255, blank=True, null=True, help_text=u'活动地点')
    153
    +
    154
    +    image = models.ImageField(_(u'image'), upload_to=upload_path, blank=True, null=True, help_text=u'活动内容图片')
    155
    +
    156
    +    cover = models.ImageField(_(u'cover'), upload_to=upload_path, blank=True, null=True, help_text=u'活动列表图片')
    157
    +
    158
    +    is_slider = models.BooleanField(_(u'is_slider'), default=True, help_text=_(u'是否为轮播活动'), db_index=True)
    159
    +    slider_image = models.ImageField(_(u'slider_image'), upload_to=upload_path, blank=True, null=True, help_text=u'活动轮播图片')
    160
    +
    161
    +    content_rich_text = RichTextField(_(u'content_rich_text'), blank=True, null=True, help_text=u'活动描述')
    162
    +
    163
    +    share_img_link = models.CharField(_(u'share_img_link'), max_length=255, blank=True, null=True, help_text=u'活动图片分享')
    164
    +    share_h5_link = models.CharField(_(u'share_h5_link'), max_length=255, blank=True, null=True, help_text=u'活动H5分享')
    165
    +
    166
    +    position = models.IntegerField(_(u'position'), default=1, help_text=u'排序', db_index=True)
    167
    +
    168
    +    class Meta:
    169
    +        verbose_name = _(u'会员活动信息')
    170
    +        verbose_name_plural = _(u'会员活动信息')
    171
    +
    172
    +    def __unicode__(self):
    173
    +        return unicode(self.pk)
    174
    +
    175
    +    @property
    176
    +    def image_path(self):
    177
    +        return upload_file_path(self.image)
    178
    +
    179
    +    @property
    180
    +    def image_url(self):
    181
    +        return upload_file_url(self.image)
    182
    +
    183
    +    @property
    184
    +    def cover_path(self):
    185
    +        return upload_file_path(self.cover)
    186
    +
    187
    +    @property
    188
    +    def cover_url(self):
    189
    +        return upload_file_url(self.cover)
    190
    +
    191
    +    @property
    192
    +    def slider_image_path(self):
    193
    +        return upload_file_path(self.slider_image)
    194
    +
    195
    +    @property
    196
    +    def slider_image_url(self):
    197
    +        return upload_file_url(self.slider_image)
    198
    +
    199
    +    @property
    200
    +    def data(self):
    201
    +        return {
    202
    +            'id': self.pk,
    203
    +            'title': self.title,
    204
    +            'subtitle': self.subtitle,
    205
    +            'date': self.date,
    206
    +            'location': self.location,
    207
    +            'cover_url': self.cover_url,
    208
    +            'content_rich_text': self.content_rich_text,
    209
    +            'state': 0,
    210
    +            'is_signed': 0,
    211
    +        }

    + 7 - 0
    member/tests.py

    @@ -0,0 +1,7 @@
    1
    +# -*- coding: utf-8 -*-
    2
    +from __future__ import unicode_literals
    3
    +
    4
    +from django.test import TestCase
    5
    +
    6
    +
    7
    +# Create your tests here.

    + 7 - 0
    member/views.py

    @@ -0,0 +1,7 @@
    1
    +# -*- coding: utf-8 -*-
    2
    +from __future__ import unicode_literals
    3
    +
    4
    +from django.shortcuts import render
    5
    +
    6
    +
    7
    +# Create your views here.

    + 1 - 1
    pre/views.py

    @@ -2,11 +2,11 @@
    2 2
     
    3 3
     from __future__ import division
    4 4
     
    5
    +import xlrd
    5 6
     from django.conf import settings
    6 7
     from pysnippets.strsnippets import strip
    7 8
     from TimeConvert import TimeConvert as tc
    8 9
     
    9
    -import xlrd
    10 10
     from mch.models import BrandInfo, ConsumeInfoSubmitLogInfo, DistributorInfo, ModelInfo
    11 11
     from statistic.models import (ConsumeDistributorSaleStatisticInfo, ConsumeModelSaleStatisticInfo,
    12 12
                                   ConsumeProvinceSaleStatisticInfo, ConsumeSaleStatisticInfo, ConsumeUserStatisticInfo,

    + 4 - 4
    requirements.txt

    @@ -1,15 +1,15 @@
    1 1
     CodeConvert==2.0.5
    2
    -MySQL-python==1.2.5
    3 2
     Pillow==5.0.0
    4 3
     StatusCode==1.0.0
    5 4
     TimeConvert==1.5.0
    6
    -furl==2.0.0
    5
    +furl==2.1.0
    7 6
     isoweek==1.3.3
    8 7
     jsonfield==2.0.2
    9 8
     mock==2.0.0
    10 9
     monetary==1.0.3
    11
    -pysnippets==1.0.8
    12
    -qiniu==7.2.2
    10
    +mysqlclient==1.4.5
    11
    +pysnippets==1.1.2
    12
    +qiniu==7.2.6
    13 13
     requests==2.21.0
    14 14
     rlog==0.3
    15 15
     rsa==3.4.2

    + 6 - 6
    requirements_dj.txt

    @@ -1,20 +1,20 @@
    1
    -Django==1.11.25
    1
    +Django==1.11.26
    2 2
     django-admin==2.0.0
    3
    -django-cors-headers==2.4.0
    3
    +django-cors-headers==3.0.2
    4 4
     django-curtail-uuid==1.0.4
    5
    -django-detect==1.0.8
    5
    +django-detect==1.0.16
    6 6
     django-file-md5==1.0.3
    7 7
     django-file-upload==1.1.1
    8 8
     django-ip==1.0.2
    9
    -django-json-render==1.0.2
    9
    +django-json-render==1.0.3
    10 10
     django-json-response==1.1.5
    11 11
     django-logit==1.1.3
    12 12
     django-mobi==0.1.7
    13 13
     django-models-ext==1.1.9
    14 14
     django-multidomain==1.1.4
    15 15
     django-paginator2==1.1.3
    16
    -django-query==1.0.3
    17
    -django-redis-connector==1.0.1
    16
    +django-query==1.0.6
    17
    +django-redis-connector==1.0.3
    18 18
     django-response==1.1.1
    19 19
     django-rlog==1.0.7
    20 20
     django-shortuuidfield==0.1.3

    + 1 - 1
    requirements_pywe.txt

    @@ -4,7 +4,7 @@ pywe-jssdk==1.1.0
    4 4
     pywe-membercard==1.0.1
    5 5
     pywe-miniapp==1.1.5
    6 6
     pywe-oauth==1.0.7
    7
    -pywe-pay==1.0.12
    7
    +pywe-pay==1.0.13
    8 8
     pywe-pay-notify==1.0.4
    9 9
     pywe-response==1.0.1
    10 10
     pywe-sign==1.1.0

    + 1 - 1
    requirements_redis.txt

    @@ -1,3 +1,3 @@
    1
    -hiredis==1.0.0
    1
    +hiredis==1.0.1
    2 2
     redis==2.10.6
    3 3
     redis-extensions==1.2.5

    + 0 - 0
    simditor/__init__.py


    + 36 - 0
    simditor/fields.py

    @@ -0,0 +1,36 @@
    1
    +# -- coding: utf-8 --
    2
    +"""simditor fields."""
    3
    +from django import forms
    4
    +from django.db import models
    5
    +
    6
    +from .widgets import SimditorWidget
    7
    +
    8
    +
    9
    +class RichTextFormField(forms.fields.CharField):
    10
    +    """RichTextFormField."""
    11
    +
    12
    +    def __init__(self, *args, **kwargs):
    13
    +        kwargs.update(
    14
    +            {
    15
    +                'widget': SimditorWidget()
    16
    +            }
    17
    +        )
    18
    +        super(RichTextFormField, self).__init__(*args, **kwargs)
    19
    +
    20
    +
    21
    +class RichTextField(models.TextField):
    22
    +    """RichTextField."""
    23
    +
    24
    +    def __init__(self, *args, **kwargs):
    25
    +        super(RichTextField, self).__init__(*args, **kwargs)
    26
    +
    27
    +    def formfield(self, **kwargs):
    28
    +        defaults = {
    29
    +            'form_class': self._get_form_class()
    30
    +        }
    31
    +        defaults.update(kwargs)
    32
    +        return super(RichTextField, self).formfield(**defaults)
    33
    +
    34
    +    @staticmethod
    35
    +    def _get_form_class():
    36
    +        return RichTextFormField

    + 0 - 0
    simditor/image/__init__.py


    + 11 - 0
    simditor/image/dummy_backend.py

    @@ -0,0 +1,11 @@
    1
    +# -- coding: utf-8 --
    2
    +"""simditor image pillow_backend."""
    3
    +from __future__ import absolute_import
    4
    +
    5
    +from simditor import utils
    6
    +
    7
    +
    8
    +def image_verify(file_object):
    9
    +    """image_verify."""
    10
    +    if not utils.is_valid_image_extension(file_object.name):
    11
    +        raise utils.NotAnImageException

    + 28 - 0
    simditor/image/pillow_backend.py

    @@ -0,0 +1,28 @@
    1
    +# -- coding: utf-8 --
    2
    +"""simditor image pillow_backend."""
    3
    +from __future__ import absolute_import
    4
    +
    5
    +import os
    6
    +from io import BytesIO
    7
    +
    8
    +from django.core.files.storage import default_storage
    9
    +from django.core.files.uploadedfile import InMemoryUploadedFile
    10
    +
    11
    +from simditor import utils
    12
    +
    13
    +
    14
    +try:
    15
    +    from PIL import Image, ImageOps
    16
    +except ImportError:
    17
    +    import Image
    18
    +    import ImageOps
    19
    +
    20
    +
    21
    +THUMBNAIL_SIZE = (75, 75)
    22
    +
    23
    +
    24
    +def image_verify(f):
    25
    +    try:
    26
    +        Image.open(f).verify()
    27
    +    except IOError:
    28
    +        raise utils.NotAnImageException

    + 16 - 0
    simditor/image_processing.py

    @@ -0,0 +1,16 @@
    1
    +# -- coding: utf-8 --
    2
    +"""simditor image_processing."""
    3
    +from __future__ import absolute_import
    4
    +
    5
    +from django.conf import settings
    6
    +
    7
    +
    8
    +def get_backend():
    9
    +    """Get backend."""
    10
    +    backend = getattr(settings, 'SIMDITOR_IMAGE_BACKEND', None)
    11
    +
    12
    +    if backend == 'pillow':
    13
    +        from simditor.image import pillow_backend as backend
    14
    +    else:
    15
    +        from simditor.image import dummy_backend as backend
    16
    +    return backend

    BIN
    simditor/static/simditor/fonts/icomoon.eot


    + 11 - 0
    simditor/static/simditor/fonts/icomoon.svg

    @@ -0,0 +1,11 @@
    1
    +<?xml version="1.0" standalone="no"?>
    2
    +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
    3
    +<svg xmlns="http://www.w3.org/2000/svg">
    4
    +<metadata>Generated by IcoMoon</metadata>
    5
    +<defs>
    6
    +<font id="icomoon" horiz-adv-x="512">
    7
    +<font-face units-per-em="512" ascent="480" descent="-32" />
    8
    +<missing-glyph horiz-adv-x="512" />
    9
    +<glyph unicode="&#x20;" d="" horiz-adv-x="256" />
    10
    +<glyph unicode="&#xe600;" d="M438.624 86.624l-73.376 73.376-45.248-45.248 73.376-73.376-73.376-73.376h192v192zM192 480h-192v-192l73.376 73.376 72.688-72.624 45.248 45.248-72.688 72.624zM192 114.752l-45.248 45.248-73.376-73.376-73.376 73.376v-192h192l-73.376 73.376zM512 480h-192l73.376-73.376-72.688-72.624 45.248-45.248 72.688 72.624 73.376-73.376z" />
    11
    +</font></defs></svg>

    BIN
    simditor/static/simditor/fonts/icomoon.ttf


    BIN
    simditor/static/simditor/fonts/icomoon.woff


    + 82 - 0
    simditor/static/simditor/fonts/selection.json

    @@ -0,0 +1,82 @@
    1
    +{
    2
    +	"IcoMoonType": "selection",
    3
    +	"icons": [
    4
    +		{
    5
    +			"icon": {
    6
    +				"paths": [
    7
    +					"M877.248 786.752l-146.752-146.752-90.496 90.496 146.752 146.752-146.752 146.752h384v-384zM384 0h-384v384l146.752-146.752 145.376 145.248 90.496-90.496-145.376-145.248zM384 730.496l-90.496-90.496-146.752 146.752-146.752-146.752v384h384l-146.752-146.752zM1024 0h-384l146.752 146.752-145.376 145.248 90.496 90.496 145.376-145.248 146.752 146.752z"
    8
    +				],
    9
    +				"tags": [
    10
    +					"fullscreen",
    11
    +					"expand"
    12
    +				],
    13
    +				"grid": 16,
    14
    +				"attrs": []
    15
    +			},
    16
    +			"attrs": [],
    17
    +			"properties": {
    18
    +				"id": 99,
    19
    +				"order": 2,
    20
    +				"prevSize": 16,
    21
    +				"code": 58880,
    22
    +				"name": "fullscreen"
    23
    +			},
    24
    +			"setIdx": 1,
    25
    +			"setId": 6,
    26
    +			"iconIdx": 99
    27
    +		}
    28
    +	],
    29
    +	"height": 1024,
    30
    +	"metadata": {
    31
    +		"name": "icomoon"
    32
    +	},
    33
    +	"preferences": {
    34
    +		"fontPref": {
    35
    +			"prefix": "icon-",
    36
    +			"metadata": {
    37
    +				"fontFamily": "icomoon",
    38
    +				"majorVersion": 1,
    39
    +				"minorVersion": 0
    40
    +			},
    41
    +			"showGlyphs": true,
    42
    +			"metrics": {
    43
    +				"emSize": 512,
    44
    +				"baseline": 6.25,
    45
    +				"whitespace": 50
    46
    +			},
    47
    +			"resetPoint": 58880,
    48
    +			"showQuickUse": true,
    49
    +			"quickUsageToken": false,
    50
    +			"showMetrics": false,
    51
    +			"showMetadata": false,
    52
    +			"autoHost": true,
    53
    +			"embed": false,
    54
    +			"ie7": false,
    55
    +			"showSelector": false,
    56
    +			"showVersion": true
    57
    +		},
    58
    +		"imagePref": {
    59
    +			"color": 0,
    60
    +			"height": 32,
    61
    +			"columns": 16,
    62
    +			"margin": 16,
    63
    +			"png": false,
    64
    +			"sprites": true,
    65
    +			"prefix": "icon-"
    66
    +		},
    67
    +		"historySize": 100,
    68
    +		"showCodes": true,
    69
    +		"gridSize": 16,
    70
    +		"showLiga": false,
    71
    +		"showGrid": true,
    72
    +		"showGlyphs": true,
    73
    +		"showQuickUse": true,
    74
    +		"search": "",
    75
    +		"quickUsageToken": {
    76
    +			"UntitledProject1": "ZWEwOTk2NTRmNjMyOGQ1MzAwZWFiYmJlODViMWMzZDcjMiMxNDA3NzM0MTA2IyMj"
    77
    +		},
    78
    +		"showQuickUse2": true,
    79
    +		"showSVGs": true,
    80
    +		"fontHostingName": false
    81
    +	}
    82
    +}

    BIN
    simditor/static/simditor/images/emoji/+1.png


    BIN
    simditor/static/simditor/images/emoji/-1.png


    BIN
    simditor/static/simditor/images/emoji/100.png


    BIN
    simditor/static/simditor/images/emoji/109.png


    BIN
    simditor/static/simditor/images/emoji/1234.png


    BIN
    simditor/static/simditor/images/emoji/a.png


    BIN
    simditor/static/simditor/images/emoji/ab.png


    BIN
    simditor/static/simditor/images/emoji/abc.png


    BIN
    simditor/static/simditor/images/emoji/abcd.png


    BIN
    simditor/static/simditor/images/emoji/accept.png


    BIN
    simditor/static/simditor/images/emoji/aerial_tramway.png


    BIN
    simditor/static/simditor/images/emoji/airplane.png


    BIN
    simditor/static/simditor/images/emoji/alarm_clock.png


    BIN
    simditor/static/simditor/images/emoji/alien.png


    BIN
    simditor/static/simditor/images/emoji/ambulance.png


    BIN
    simditor/static/simditor/images/emoji/anchor.png


    BIN
    simditor/static/simditor/images/emoji/angel.png


    BIN
    simditor/static/simditor/images/emoji/anger.png


    BIN
    simditor/static/simditor/images/emoji/angry.png


    BIN
    simditor/static/simditor/images/emoji/anguished.png


    BIN
    simditor/static/simditor/images/emoji/ant.png


    BIN
    simditor/static/simditor/images/emoji/apple.png


    BIN
    simditor/static/simditor/images/emoji/aquarius.png


    BIN
    simditor/static/simditor/images/emoji/aries.png


    BIN
    simditor/static/simditor/images/emoji/arrow_backward.png


    BIN
    simditor/static/simditor/images/emoji/arrow_double_down.png


    BIN
    simditor/static/simditor/images/emoji/arrow_double_up.png


    BIN
    simditor/static/simditor/images/emoji/arrow_down.png


    BIN
    simditor/static/simditor/images/emoji/arrow_down_small.png


    BIN
    simditor/static/simditor/images/emoji/arrow_forward.png


    BIN
    simditor/static/simditor/images/emoji/arrow_heading_down.png


    BIN
    simditor/static/simditor/images/emoji/arrow_heading_up.png


    BIN
    simditor/static/simditor/images/emoji/arrow_left.png


    BIN
    simditor/static/simditor/images/emoji/arrow_lower_left.png


    BIN
    simditor/static/simditor/images/emoji/arrow_lower_right.png


    BIN
    simditor/static/simditor/images/emoji/arrow_right.png


    BIN
    simditor/static/simditor/images/emoji/arrow_right_hook.png


    BIN
    simditor/static/simditor/images/emoji/arrow_up.png


    BIN
    simditor/static/simditor/images/emoji/arrow_up_down.png


    BIN
    simditor/static/simditor/images/emoji/arrow_up_small.png


    BIN
    simditor/static/simditor/images/emoji/arrow_upper_left.png


    BIN
    simditor/static/simditor/images/emoji/arrow_upper_right.png


    BIN
    simditor/static/simditor/images/emoji/arrows_clockwise.png


    BIN
    simditor/static/simditor/images/emoji/arrows_counterclockwise.png


    BIN
    simditor/static/simditor/images/emoji/art.png


    BIN
    simditor/static/simditor/images/emoji/articulated_lorry.png


    BIN
    simditor/static/simditor/images/emoji/astonished.png


    BIN
    simditor/static/simditor/images/emoji/atm.png


    BIN
    simditor/static/simditor/images/emoji/b.png


    BIN
    simditor/static/simditor/images/emoji/baby.png


    BIN
    simditor/static/simditor/images/emoji/baby_bottle.png


    BIN
    simditor/static/simditor/images/emoji/baby_chick.png


    BIN
    simditor/static/simditor/images/emoji/baby_symbol.png


    BIN
    simditor/static/simditor/images/emoji/baggage_claim.png


    BIN
    simditor/static/simditor/images/emoji/balloon.png


    BIN
    simditor/static/simditor/images/emoji/ballot_box_with_check.png


    BIN
    simditor/static/simditor/images/emoji/bamboo.png


    BIN
    simditor/static/simditor/images/emoji/banana.png


    BIN
    simditor/static/simditor/images/emoji/bangbang.png


    BIN
    simditor/static/simditor/images/emoji/bank.png


    BIN
    simditor/static/simditor/images/emoji/bar_chart.png


    BIN
    simditor/static/simditor/images/emoji/barber.png


    BIN
    simditor/static/simditor/images/emoji/baseball.png


    BIN
    simditor/static/simditor/images/emoji/basketball.png


    BIN
    simditor/static/simditor/images/emoji/bath.png


    BIN
    simditor/static/simditor/images/emoji/bathtub.png


    BIN
    simditor/static/simditor/images/emoji/battery.png


    BIN
    simditor/static/simditor/images/emoji/bear.png


    BIN
    simditor/static/simditor/images/emoji/beer.png


    BIN
    simditor/static/simditor/images/emoji/beers.png


    BIN
    simditor/static/simditor/images/emoji/beetle.png


    BIN
    simditor/static/simditor/images/emoji/beginner.png


    BIN
    simditor/static/simditor/images/emoji/bell.png


    BIN
    simditor/static/simditor/images/emoji/bento.png


    BIN
    simditor/static/simditor/images/emoji/bicyclist.png


    BIN
    simditor/static/simditor/images/emoji/bike.png


    BIN
    simditor/static/simditor/images/emoji/bikini.png


    BIN
    simditor/static/simditor/images/emoji/bird.png


    BIN
    simditor/static/simditor/images/emoji/birthday.png


    BIN
    simditor/static/simditor/images/emoji/black_circle.png


    BIN
    simditor/static/simditor/images/emoji/black_joker.png


    BIN
    simditor/static/simditor/images/emoji/black_nib.png


    BIN
    simditor/static/simditor/images/emoji/black_square.png


    BIN
    simditor/static/simditor/images/emoji/black_square_button.png


    BIN
    simditor/static/simditor/images/emoji/blossom.png


    BIN
    simditor/static/simditor/images/emoji/blowfish.png


    BIN
    simditor/static/simditor/images/emoji/blue_book.png


    BIN
    simditor/static/simditor/images/emoji/blue_car.png


    BIN
    simditor/static/simditor/images/emoji/blue_heart.png


    BIN
    simditor/static/simditor/images/emoji/blush.png


    BIN
    simditor/static/simditor/images/emoji/boar.png


    BIN
    simditor/static/simditor/images/emoji/boat.png


    BIN
    simditor/static/simditor/images/emoji/bomb.png


    BIN
    simditor/static/simditor/images/emoji/book.png


    BIN
    simditor/static/simditor/images/emoji/bookmark.png


    BIN
    simditor/static/simditor/images/emoji/bookmark_tabs.png


    BIN
    simditor/static/simditor/images/emoji/books.png


    BIN
    simditor/static/simditor/images/emoji/boom.png


    BIN
    simditor/static/simditor/images/emoji/boot.png


    BIN
    simditor/static/simditor/images/emoji/bouquet.png


    BIN
    simditor/static/simditor/images/emoji/bow.png


    BIN
    simditor/static/simditor/images/emoji/bowling.png


    BIN
    simditor/static/simditor/images/emoji/bowtie.png


    BIN
    simditor/static/simditor/images/emoji/boy.png


    BIN
    simditor/static/simditor/images/emoji/bread.png


    BIN
    simditor/static/simditor/images/emoji/bride_with_veil.png


    BIN
    simditor/static/simditor/images/emoji/bridge_at_night.png


    BIN
    simditor/static/simditor/images/emoji/briefcase.png


    BIN
    simditor/static/simditor/images/emoji/broken_heart.png


    BIN
    simditor/static/simditor/images/emoji/bug.png


    BIN
    simditor/static/simditor/images/emoji/bulb.png


    BIN
    simditor/static/simditor/images/emoji/bullettrain_front.png


    BIN
    simditor/static/simditor/images/emoji/bullettrain_side.png


    BIN
    simditor/static/simditor/images/emoji/bus.png


    BIN
    simditor/static/simditor/images/emoji/busstop.png


    BIN
    simditor/static/simditor/images/emoji/bust_in_silhouette.png


    BIN
    simditor/static/simditor/images/emoji/busts_in_silhouette.png


    BIN
    simditor/static/simditor/images/emoji/cactus.png


    BIN
    simditor/static/simditor/images/emoji/cake.png


    BIN
    simditor/static/simditor/images/emoji/calendar.png


    BIN
    simditor/static/simditor/images/emoji/calling.png


    BIN
    simditor/static/simditor/images/emoji/camel.png


    BIN
    simditor/static/simditor/images/emoji/camera.png


    BIN
    simditor/static/simditor/images/emoji/cancer.png


    BIN
    simditor/static/simditor/images/emoji/candy.png


    BIN
    simditor/static/simditor/images/emoji/capital_abcd.png


    BIN
    simditor/static/simditor/images/emoji/capricorn.png


    BIN
    simditor/static/simditor/images/emoji/car.png


    BIN
    simditor/static/simditor/images/emoji/card_index.png


    BIN
    simditor/static/simditor/images/emoji/carousel_horse.png


    BIN
    simditor/static/simditor/images/emoji/cat.png


    BIN
    simditor/static/simditor/images/emoji/cat2.png


    BIN
    simditor/static/simditor/images/emoji/cd.png


    BIN
    simditor/static/simditor/images/emoji/chart.png


    BIN
    simditor/static/simditor/images/emoji/chart_with_downwards_trend.png


    BIN
    simditor/static/simditor/images/emoji/chart_with_upwards_trend.png


    BIN
    simditor/static/simditor/images/emoji/checkered_flag.png


    BIN
    simditor/static/simditor/images/emoji/cherries.png


    BIN
    simditor/static/simditor/images/emoji/cherry_blossom.png


    BIN
    simditor/static/simditor/images/emoji/chestnut.png


    BIN
    simditor/static/simditor/images/emoji/chicken.png


    BIN
    simditor/static/simditor/images/emoji/children_crossing.png


    BIN
    simditor/static/simditor/images/emoji/chocolate_bar.png


    BIN
    simditor/static/simditor/images/emoji/christmas_tree.png


    BIN
    simditor/static/simditor/images/emoji/church.png


    BIN
    simditor/static/simditor/images/emoji/cinema.png


    BIN
    simditor/static/simditor/images/emoji/circus_tent.png


    BIN
    simditor/static/simditor/images/emoji/city_sunrise.png


    BIN
    simditor/static/simditor/images/emoji/city_sunset.png


    BIN
    simditor/static/simditor/images/emoji/cl.png


    BIN
    simditor/static/simditor/images/emoji/clap.png


    BIN
    simditor/static/simditor/images/emoji/clapper.png


    BIN
    simditor/static/simditor/images/emoji/clipboard.png


    BIN
    simditor/static/simditor/images/emoji/clock1.png


    BIN
    simditor/static/simditor/images/emoji/clock10.png


    BIN
    simditor/static/simditor/images/emoji/clock1030.png


    BIN
    simditor/static/simditor/images/emoji/clock11.png


    BIN
    simditor/static/simditor/images/emoji/clock1130.png


    BIN
    simditor/static/simditor/images/emoji/clock12.png


    BIN
    simditor/static/simditor/images/emoji/clock1230.png


    BIN
    simditor/static/simditor/images/emoji/clock130.png


    BIN
    simditor/static/simditor/images/emoji/clock2.png


    BIN
    simditor/static/simditor/images/emoji/clock230.png


    BIN
    simditor/static/simditor/images/emoji/clock3.png


    BIN
    simditor/static/simditor/images/emoji/clock330.png


    BIN
    simditor/static/simditor/images/emoji/clock4.png


    BIN
    simditor/static/simditor/images/emoji/clock430.png


    BIN
    simditor/static/simditor/images/emoji/clock5.png


    BIN
    simditor/static/simditor/images/emoji/clock530.png


    BIN
    simditor/static/simditor/images/emoji/clock6.png


    BIN
    simditor/static/simditor/images/emoji/clock630.png


    BIN
    simditor/static/simditor/images/emoji/clock7.png


    BIN
    simditor/static/simditor/images/emoji/clock730.png


    BIN
    simditor/static/simditor/images/emoji/clock8.png


    BIN
    simditor/static/simditor/images/emoji/clock830.png


    BIN
    simditor/static/simditor/images/emoji/clock9.png


    BIN
    simditor/static/simditor/images/emoji/clock930.png


    BIN
    simditor/static/simditor/images/emoji/closed_book.png


    BIN
    simditor/static/simditor/images/emoji/closed_lock_with_key.png


    BIN
    simditor/static/simditor/images/emoji/closed_umbrella.png


    BIN
    simditor/static/simditor/images/emoji/cloud.png


    BIN
    simditor/static/simditor/images/emoji/clubs.png


    BIN
    simditor/static/simditor/images/emoji/cn.png


    BIN
    simditor/static/simditor/images/emoji/cocktail.png


    BIN
    simditor/static/simditor/images/emoji/coffee.png


    BIN
    simditor/static/simditor/images/emoji/cold_sweat.png


    BIN
    simditor/static/simditor/images/emoji/collision.png


    BIN
    simditor/static/simditor/images/emoji/computer.png


    BIN
    simditor/static/simditor/images/emoji/confetti_ball.png


    BIN
    simditor/static/simditor/images/emoji/confounded.png


    BIN
    simditor/static/simditor/images/emoji/confused.png


    BIN
    simditor/static/simditor/images/emoji/congratulations.png


    BIN
    simditor/static/simditor/images/emoji/construction.png


    BIN
    simditor/static/simditor/images/emoji/construction_worker.png


    BIN
    simditor/static/simditor/images/emoji/convenience_store.png


    BIN
    simditor/static/simditor/images/emoji/cookie.png


    BIN
    simditor/static/simditor/images/emoji/cool.png


    BIN
    simditor/static/simditor/images/emoji/cop.png


    BIN
    simditor/static/simditor/images/emoji/copyright.png


    BIN
    simditor/static/simditor/images/emoji/corn.png


    BIN
    simditor/static/simditor/images/emoji/couple.png


    BIN
    simditor/static/simditor/images/emoji/couple_with_heart.png


    BIN
    simditor/static/simditor/images/emoji/couplekiss.png


    BIN
    simditor/static/simditor/images/emoji/cow.png


    BIN
    simditor/static/simditor/images/emoji/cow2.png


    BIN
    simditor/static/simditor/images/emoji/credit_card.png


    BIN
    simditor/static/simditor/images/emoji/crocodile.png


    BIN
    simditor/static/simditor/images/emoji/crossed_flags.png


    BIN
    simditor/static/simditor/images/emoji/crown.png


    BIN
    simditor/static/simditor/images/emoji/cry.png


    BIN
    simditor/static/simditor/images/emoji/crying_cat_face.png


    BIN
    simditor/static/simditor/images/emoji/crystal_ball.png


    BIN
    simditor/static/simditor/images/emoji/cupid.png


    BIN
    simditor/static/simditor/images/emoji/curly_loop.png


    BIN
    simditor/static/simditor/images/emoji/currency_exchange.png


    BIN
    simditor/static/simditor/images/emoji/curry.png


    BIN
    simditor/static/simditor/images/emoji/custard.png


    BIN
    simditor/static/simditor/images/emoji/customs.png


    BIN
    simditor/static/simditor/images/emoji/cyclone.png


    BIN
    simditor/static/simditor/images/emoji/dancer.png


    BIN
    simditor/static/simditor/images/emoji/dancers.png


    BIN
    simditor/static/simditor/images/emoji/dango.png


    BIN
    simditor/static/simditor/images/emoji/dart.png


    BIN
    simditor/static/simditor/images/emoji/dash.png


    BIN
    simditor/static/simditor/images/emoji/date.png


    BIN
    simditor/static/simditor/images/emoji/de.png


    BIN
    simditor/static/simditor/images/emoji/deciduous_tree.png


    BIN
    simditor/static/simditor/images/emoji/department_store.png


    BIN
    simditor/static/simditor/images/emoji/diamond_shape_with_a_dot_inside.png


    BIN
    simditor/static/simditor/images/emoji/diamonds.png


    BIN
    simditor/static/simditor/images/emoji/disappointed.png


    BIN
    simditor/static/simditor/images/emoji/dizzy.png


    BIN
    simditor/static/simditor/images/emoji/dizzy_face.png


    BIN
    simditor/static/simditor/images/emoji/do_not_litter.png


    BIN
    simditor/static/simditor/images/emoji/dog.png


    BIN
    simditor/static/simditor/images/emoji/dog2.png


    BIN
    simditor/static/simditor/images/emoji/dollar.png


    BIN
    simditor/static/simditor/images/emoji/dolls.png


    BIN
    simditor/static/simditor/images/emoji/dolphin.png


    BIN
    simditor/static/simditor/images/emoji/door.png


    BIN
    simditor/static/simditor/images/emoji/doughnut.png


    BIN
    simditor/static/simditor/images/emoji/dragon.png


    BIN
    simditor/static/simditor/images/emoji/dragon_face.png


    BIN
    simditor/static/simditor/images/emoji/dress.png


    BIN
    simditor/static/simditor/images/emoji/dromedary_camel.png


    BIN
    simditor/static/simditor/images/emoji/droplet.png


    BIN
    simditor/static/simditor/images/emoji/dvd.png


    BIN
    simditor/static/simditor/images/emoji/e-mail.png


    BIN
    simditor/static/simditor/images/emoji/ear.png


    BIN
    simditor/static/simditor/images/emoji/ear_of_rice.png


    BIN
    simditor/static/simditor/images/emoji/earth_africa.png


    BIN
    simditor/static/simditor/images/emoji/earth_americas.png


    BIN
    simditor/static/simditor/images/emoji/earth_asia.png


    BIN
    simditor/static/simditor/images/emoji/egg.png


    BIN
    simditor/static/simditor/images/emoji/eggplant.png


    BIN
    simditor/static/simditor/images/emoji/eight.png


    BIN
    simditor/static/simditor/images/emoji/eight_pointed_black_star.png


    BIN
    simditor/static/simditor/images/emoji/eight_spoked_asterisk.png


    BIN
    simditor/static/simditor/images/emoji/eightball.png


    BIN
    simditor/static/simditor/images/emoji/electric_plug.png


    BIN
    simditor/static/simditor/images/emoji/elephant.png


    BIN
    simditor/static/simditor/images/emoji/email.png


    + 0 - 0
    simditor/static/simditor/images/emoji/emojify.css

    @@ -0,0 +1 @@

    adminSystem - Gogs: Go Git Service

    Няма описание

    LICENSE 1.1KB

      The MIT License (MIT) Copyright (c) 2014 Blake Embrey (hello@blakeembrey.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.