tr> 312
+    user.save()
313
+
314
+    # TODO: 立即推送模版消息(感谢您参加活动,获得的积分)
198 315
 
199 316
     return response(200, data={
200 317
         'activity': act.data,

+ 5 - 0
api/urls.py

@@ -304,12 +304,17 @@ urlpatterns += [
304 304
 
305 305
     url(r'^member/rights$', member_views.rights, name='member_rights'),
306 306
     url(r'^member/right/detail$', member_views.right_detail, name='member_right_detail'),
307
+
307 308
     url(r'^member/goods$', member_views.goods, name='member_goods'),
308 309
     url(r'^member/good/detail$', member_views.good_detail, name='member_good_detail'),
310
+    url(r'^member/good/exchange$', member_views.good_exchange, name='member_good_exchange'),
311
+
309 312
     url(r'^member/integrals$', member_views.integrals, name='member_integrals'),
310 313
 
311 314
     url(r'^member/activity/list$', member_views.activity_list, name='member_activity_list'),
312 315
     url(r'^member/activity/detail$', member_views.activity_detail, name='member_activity_detail'),
316
+    url(r'^member/activity/signup$', member_views.activity_signup, name='member_activity_signup'),
317
+    url(r'^member/activity/signin$', member_views.activity_signin, name='member_activity_signin'),
313 318
 
314 319
     url(r'^rights$', member_views.rights, name='rights'),
315 320
     url(r'^right/detail$', member_views.right_detail, name='right_detail'),

+ 6 - 6
kodo/settings.py

@@ -246,12 +246,12 @@ QINIU = {
246 246
     'secret_key': '05sCekniLCgM6-d_PxrH8sFjvEOsx3ev-FgS7R-k',
247 247
     'bucket_default': 'photo',
248 248
     'buckets': {
249
-        'original': 'http://orf3sfb8s.bkt.clouddn.com',
250
-        'photo': 'http://orf3lnlmb.bkt.clouddn.com',
251
-        'prettify': 'http://orzfu8zxw.bkt.clouddn.com',
252
-        'thumbnail': 'http://orf3ahvt6.bkt.clouddn.com',
253
-        'thumbnail2': 'http://orf3muf5n.bkt.clouddn.com',
254
-        'watermark': 'http://orf3qne9f.bkt.clouddn.com',
249
+        'original': 'http://original.img.pai.ai',
250
+        'photo': 'http://photo.img.pai.ai',
251
+        'prettify': 'http://prettify.img.pai.ai',
252
+        'thumbnail': 'http://thumbnail.img.pai.ai',
253
+        'thumbnail2': 'http://thumbnail2.img.pai.ai',
254
+        'watermark': 'http://watermark.img.pai.ai',
255 255
     }
256 256
 }
257 257
 

+ 8 - 2
kodo/urls.py

@@ -99,7 +99,13 @@ urlpatterns += [
99 99
     url(r'^page/', include('page.urls', namespace='page')),
100 100
 ]
101 101
 
102
-urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
103
-urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
102
+# Simditor编辑器
103
+urlpatterns += [
104
+    url(r'^simditor/', include('simditor.urls'))
105
+]
106
+
107
+if settings.DEBUG:
108
+    urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
109
+    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
104 110
 
105 111
 admin.site.site_header = u'[盈多]{}后台管理系统'.format(settings.KODO_BRAND_NAME)

+ 20 - 0
mch/migrations/0040_modelinfo_shot_member_name.py

@@ -0,0 +1,20 @@
1
+# -*- coding: utf-8 -*-
2
+# Generated by Django 1.11.26 on 2019-12-01 13:10
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
+        ('mch', '0039_auto_20191119_1348'),
12
+    ]
13
+
14
+    operations = [
15
+        migrations.AddField(
16
+            model_name='modelinfo',
17
+            name='shot_member_name',
18
+            field=models.CharField(blank=True, help_text='\u578b\u53f7\u5168\u540d\u79f0', max_length=255, null=True, verbose_name='shot_member_name'),
19
+        ),
20
+    ]

+ 36 - 2
member/admin.py

@@ -2,7 +2,7 @@
2 2
 
3 3
 from django.contrib import admin
4 4
 
5
-from member.models import GoodsInfo, MemberActivityInfo, ShotTypeInfo, RightInfo
5
+from member.models import GoodsInfo, GoodsOrderInfo, MemberActivityInfo, MemberActivitySigninInfo, MemberActivitySignupInfo, MemberCouponInfo, ShotTypeInfo, RightInfo
6 6
 from utils.redis.rshot import update_shot_member_data
7 7
 
8 8
 
@@ -11,6 +11,20 @@ class GoodsInfoAdmin(admin.ModelAdmin):
11 11
     list_filter = ('is_slider', 'status')
12 12
 
13 13
 
14
+class GoodsOrderInfoAdmin(admin.ModelAdmin):
15
+    list_display = ('order_id', 'user_id', 'good_id', 'good_type', 'title', 'name', 'phone', 'address', 'tracking_number', 'has_send_template_message', 'status', 'created_at', 'updated_at')
16
+
17
+    def save_model(self, request, obj, form, change):
18
+        obj.save()
19
+
20
+        if obj.has_send_template_message:
21
+            return
22
+
23
+        if obj.good_type == GoodsInfo.PHYSICAL:
24
+            # TODO: 立即推送模版消息,兑换成功,快递已发送(商品,快递单号,扣除的积分)
25
+            pass
26
+
27
+
14 28
 class RightInfoAdmin(admin.ModelAdmin):
15 29
     list_display = ('right_id', 'right_type', 'icon', 'title', 'subtitle', 'detail', 'level1', 'level2', 'level3', 'level4', 'level5',  'minlevel', 'position', 'status', 'created_at', 'updated_at')
16 30
     list_filter = ('right_type', 'status')
@@ -29,11 +43,31 @@ class ShotTypeInfoAdmin(admin.ModelAdmin):
29 43
 
30 44
 
31 45
 class MemberActivityInfoAdmin(admin.ModelAdmin):
32
-    list_display = ('title', 'subtitle', 'date', 'city', 'location', 'lat', 'lon', 'image', 'is_slider', 'slider_image', 'position', 'status', 'created_at', 'updated_at')
46
+    list_display = ('activity_id', 'title', 'subtitle', 'date', 'city', 'location', 'lat', 'lon', 'image', 'is_slider', 'slider_image', 'position', 'status', 'created_at', 'updated_at')
33 47
     list_filter = ('is_slider', 'status')
34 48
 
35 49
 
50
+class MemberActivitySignupInfoAdmin(admin.ModelAdmin):
51
+    list_display = ('signup_id', 'activity_id', 'title', 'name', 'phone', 'status', 'created_at', 'updated_at')
52
+
53
+
54
+class MemberActivitySignupInfoAdmin(admin.ModelAdmin):
55
+    list_display = ('signup_id', 'user_id', 'activity_id', 'title', 'name', 'phone', 'status', 'created_at', 'updated_at')
56
+
57
+
58
+class MemberActivitySigninInfoAdmin(admin.ModelAdmin):
59
+    list_display = ('signin_id', 'user_id', 'activity_id', 'title', 'status', 'created_at', 'updated_at')
60
+
61
+
62
+class MemberCouponInfoAdmin(admin.ModelAdmin):
63
+    list_display = ('coupon_id', 'user_id', 'coupon_type', 'coupon_start_at', 'coupon_expire_at', 'coupon_value', 'has_used', 'admin_id', 'used_at', 'status', 'created_at', 'updated_at')
64
+
65
+
36 66
 admin.site.register(GoodsInfo, GoodsInfoAdmin)
67
+admin.site.register(GoodsOrderInfo, GoodsOrderInfoAdmin)
37 68
 admin.site.register(RightInfo, RightInfoAdmin)
38 69
 admin.site.register(ShotTypeInfo, ShotTypeInfoAdmin)
39 70
 admin.site.register(MemberActivityInfo, MemberActivityInfoAdmin)
71
+admin.site.register(MemberActivitySignupInfo, MemberActivitySignupInfoAdmin)
72
+admin.site.register(MemberActivitySigninInfo, MemberActivitySigninInfoAdmin)
73
+admin.site.register(MemberCouponInfo, MemberCouponInfoAdmin)

+ 110 - 0
member/migrations/0006_auto_20191201_2110.py

@@ -0,0 +1,110 @@
1
+# -*- coding: utf-8 -*-
2
+# Generated by Django 1.11.26 on 2019-12-01 13:10
3
+from __future__ import unicode_literals
4
+
5
+from django.db import migrations, models
6
+import shortuuidfield.fields
7
+
8
+
9
+class Migration(migrations.Migration):
10
+
11
+    dependencies = [
12
+        ('member', '0005_memberactivityinfo_city'),
13
+    ]
14
+
15
+    operations = [
16
+        migrations.CreateModel(
17
+            name='GoodsOrderInfo',
18
+            fields=[
19
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
20
+                ('status', models.BooleanField(db_index=True, default=True, help_text='Status', verbose_name='status')),
21
+                ('created_at', models.DateTimeField(auto_now_add=True, help_text='Create Time', verbose_name='created_at')),
22
+                ('updated_at', models.DateTimeField(auto_now=True, help_text='Update Time', verbose_name='updated_at')),
23
+                ('order_id', shortuuidfield.fields.ShortUUIDField(blank=True, db_index=True, editable=False, help_text='\u8ba2\u5355\u552f\u4e00\u6807\u8bc6', max_length=22, null=True, unique=True)),
24
+                ('user_id', models.CharField(blank=True, db_index=True, help_text='\u7528\u6237\u552f\u4e00\u6807\u8bc6', max_length=32, null=True, verbose_name='user_id')),
25
+                ('good_id', models.CharField(blank=True, db_index=True, help_text='\u5546\u54c1\u552f\u4e00\u6807\u8bc6', max_length=32, null=True, verbose_name='good_id')),
26
+                ('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')),
27
+                ('title', models.CharField(blank=True, help_text='\u5546\u54c1\u540d\u79f0', max_length=255, null=True, verbose_name='title')),
28
+                ('name', models.CharField(blank=True, help_text='\u59d3\u540d', max_length=255, null=True, verbose_name='name')),
29
+                ('phone', models.CharField(blank=True, help_text='\u7535\u8bdd', max_length=255, null=True, verbose_name='phone')),
30
+                ('address', models.CharField(blank=True, help_text='\u5730\u5740', max_length=255, null=True, verbose_name='address')),
31
+                ('tracking_number', models.CharField(blank=True, help_text='\u5feb\u9012\u5355\u53f7', max_length=255, null=True, verbose_name='tracking_number')),
32
+                ('has_send_template_message', models.BooleanField(db_index=True, default=True, help_text='\u662f\u5426\u5df2\u53d1\u9001\u6a21\u7248\u6d88\u606f', verbose_name='has_send_template_message')),
33
+            ],
34
+            options={
35
+                'verbose_name': '\u4f1a\u5458\u5546\u54c1\u8ba2\u5355\u4fe1\u606f',
36
+                'verbose_name_plural': '\u4f1a\u5458\u5546\u54c1\u8ba2\u5355\u4fe1\u606f',
37
+            },
38
+        ),
39
+        migrations.CreateModel(
40
+            name='MemberActivitySigninInfo',
41
+            fields=[
42
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
43
+                ('status', models.BooleanField(db_index=True, default=True, help_text='Status', verbose_name='status')),
44
+                ('created_at', models.DateTimeField(auto_now_add=True, help_text='Create Time', verbose_name='created_at')),
45
+                ('updated_at', models.DateTimeField(auto_now=True, help_text='Update Time', verbose_name='updated_at')),
46
+                ('signin_id', shortuuidfield.fields.ShortUUIDField(blank=True, db_index=True, editable=False, help_text='\u6d3b\u52a8\u7b7e\u5230\u552f\u4e00\u6807\u8bc6', max_length=22, null=True, unique=True)),
47
+                ('user_id', models.CharField(blank=True, db_index=True, help_text='\u7528\u6237\u552f\u4e00\u6807\u8bc6', max_length=32, null=True, verbose_name='user_id')),
48
+                ('activity_id', models.CharField(blank=True, db_index=True, help_text='\u6d3b\u52a8\u552f\u4e00\u6807\u8bc6', max_length=32, null=True, verbose_name='activity_id')),
49
+                ('title', models.CharField(blank=True, help_text='\u6d3b\u52a8\u540d\u79f0', max_length=255, null=True, verbose_name='title')),
50
+            ],
51
+            options={
52
+                'verbose_name': '\u4f1a\u5458\u6d3b\u52a8\u7b7e\u5230\u4fe1\u606f',
53
+                'verbose_name_plural': '\u4f1a\u5458\u6d3b\u52a8\u7b7e\u5230\u4fe1\u606f',
54
+            },
55
+        ),
56
+        migrations.CreateModel(
57
+            name='MemberActivitySignupInfo',
58
+            fields=[
59
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
60
+                ('status', models.BooleanField(db_index=True, default=True, help_text='Status', verbose_name='status')),
61
+                ('created_at', models.DateTimeField(auto_now_add=True, help_text='Create Time', verbose_name='created_at')),
62
+                ('updated_at', models.DateTimeField(auto_now=True, help_text='Update Time', verbose_name='updated_at')),
63
+                ('signup_id', shortuuidfield.fields.ShortUUIDField(blank=True, db_index=True, editable=False, help_text='\u6d3b\u52a8\u62a5\u540d\u552f\u4e00\u6807\u8bc6', max_length=22, null=True, unique=True)),
64
+                ('user_id', models.CharField(blank=True, db_index=True, help_text='\u7528\u6237\u552f\u4e00\u6807\u8bc6', max_length=32, null=True, verbose_name='user_id')),
65
+                ('activity_id', models.CharField(blank=True, db_index=True, help_text='\u6d3b\u52a8\u552f\u4e00\u6807\u8bc6', max_length=32, null=True, verbose_name='activity_id')),
66
+                ('title', models.CharField(blank=True, help_text='\u6d3b\u52a8\u540d\u79f0', max_length=255, null=True, verbose_name='title')),
67
+                ('name', models.CharField(blank=True, help_text='\u59d3\u540d', max_length=255, null=True, verbose_name='name')),
68
+                ('phone', models.CharField(blank=True, help_text='\u7535\u8bdd', max_length=255, null=True, verbose_name='phone')),
69
+            ],
70
+            options={
71
+                'verbose_name': '\u4f1a\u5458\u6d3b\u52a8\u62a5\u540d\u4fe1\u606f',
72
+                'verbose_name_plural': '\u4f1a\u5458\u6d3b\u52a8\u62a5\u540d\u4fe1\u606f',
73
+            },
74
+        ),
75
+        migrations.CreateModel(
76
+            name='MemberCouponInfo',
77
+            fields=[
78
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
79
+                ('status', models.BooleanField(db_index=True, default=True, help_text='Status', verbose_name='status')),
80
+                ('created_at', models.DateTimeField(auto_now_add=True, help_text='Create Time', verbose_name='created_at')),
81
+                ('updated_at', models.DateTimeField(auto_now=True, help_text='Update Time', verbose_name='updated_at')),
82
+                ('coupon_id', shortuuidfield.fields.ShortUUIDField(blank=True, db_index=True, editable=False, help_text='\u5238\u552f\u4e00\u6807\u8bc6', max_length=22, null=True, unique=True)),
83
+                ('user_id', models.CharField(blank=True, db_index=True, help_text='\u7528\u6237\u552f\u4e00\u6807\u8bc6', max_length=32, null=True, verbose_name='user_id')),
84
+                ('coupon_type', models.IntegerField(choices=[(0, '\u6df1\u5ea6\u6e05\u6d01'), (1, '\u514d\u8d39\u8c03\u7126'), (2, '\u5916\u89c2\u6e05\u6d01'), (3, '\u610f\u5916\u7ef4\u4fee'), (4, '\u7ef4\u4fee\u4eba\u5de5')], db_index=True, default=0, help_text='\u5238\u7c7b\u578b', verbose_name='coupon_type')),
85
+                ('coupon_start_at', models.DateTimeField(blank=True, help_text='\u5238\u751f\u6548\u65f6\u95f4', null=True, verbose_name='coupon_start_at')),
86
+                ('coupon_expire_at', models.DateTimeField(blank=True, help_text='\u5238\u8fc7\u671f\u65f6\u95f4', null=True, verbose_name='coupon_expire_at')),
87
+                ('coupon_value', models.IntegerField(default=0, help_text='\u5238\u91d1\u989d\uff08\u5355\u4f4d\uff1a\u5206\uff09', verbose_name='coupon_value')),
88
+                ('has_used', models.BooleanField(db_index=True, default=False, help_text='\u662f\u5426\u5df2\u6838\u9500', verbose_name='has_used')),
89
+                ('admin_id', models.CharField(blank=True, db_index=True, help_text='\u6838\u9500\u5458\u552f\u4e00\u6807\u8bc6', max_length=32, null=True, verbose_name='admin_id')),
90
+                ('used_at', models.DateTimeField(blank=True, help_text='\u7ef4\u4fee\u5238\u6838\u9500\u65f6\u95f4', null=True, verbose_name='used_at')),
91
+            ],
92
+            options={
93
+                'verbose_name': '\u4f1a\u5458\u6d3b\u52a8\u7b7e\u5230\u4fe1\u606f',
94
+                'verbose_name_plural': '\u4f1a\u5458\u6d3b\u52a8\u7b7e\u5230\u4fe1\u606f',
95
+            },
96
+        ),
97
+        migrations.AddField(
98
+            model_name='memberactivityinfo',
99
+            name='activity_id',
100
+            field=shortuuidfield.fields.ShortUUIDField(blank=True, db_index=True, editable=False, help_text='\u6d3b\u52a8\u552f\u4e00\u6807\u8bc6', max_length=22, null=True, unique=True),
101
+        ),
102
+        migrations.AlterUniqueTogether(
103
+            name='memberactivitysignupinfo',
104
+            unique_together=set([('user_id', 'activity_id')]),
105
+        ),
106
+        migrations.AlterUniqueTogether(
107
+            name='memberactivitysignininfo',
108
+            unique_together=set([('user_id', 'activity_id')]),
109
+        ),
110
+    ]

+ 134 - 3
member/models.py

@@ -27,7 +27,7 @@ class GoodsInfo(BaseModelMixin):
27 27
 
28 28
     image = models.ImageField(_(u'image'), upload_to=upload_path, blank=True, null=True, help_text=u'商品图片')
29 29
 
30
-    is_slider = models.BooleanField(_(u'is_slider'), default=True, help_text=_(u'是否为轮播商品'), db_index=True)
30
+    is_slider = models.BooleanField(_(u'is_slider'), default=True, help_text=u'是否为轮播商品', db_index=True)
31 31
     slider_image = models.ImageField(_(u'slider_image'), upload_to=upload_path, blank=True, null=True, help_text=u'商品轮播图片')
32 32
 
33 33
     integral = models.IntegerField(_(u'integral'), default=99999, help_text=u'兑换所需积分')
@@ -76,6 +76,40 @@ class GoodsInfo(BaseModelMixin):
76 76
         }
77 77
 
78 78
 
79
+class GoodsOrderInfo(BaseModelMixin):
80
+    PHYSICAL = 0
81
+    VIRTUAL = 1
82
+
83
+    GOOD_TYPE_TUPLE = (
84
+        (PHYSICAL, u'实物'),
85
+        (VIRTUAL, u'虚拟'),
86
+    )
87
+
88
+    order_id = ShortUUIDField(_(u'order_id'), max_length=32, blank=True, null=True, help_text=u'订单唯一标识', db_index=True, unique=True)
89
+
90
+    user_id = models.CharField(_(u'user_id'), max_length=32, blank=True, null=True, help_text=u'用户唯一标识', db_index=True)
91
+
92
+    good_id = models.CharField(_(u'good_id'), max_length=32, blank=True, null=True, help_text=u'商品唯一标识', db_index=True)
93
+    good_type = models.IntegerField(_(u'good_type'), choices=GOOD_TYPE_TUPLE, default=VIRTUAL, help_text=u'商品类型', db_index=True)
94
+
95
+    title = models.CharField(_(u'title'), max_length=255, blank=True, null=True, help_text=u'商品名称')
96
+
97
+    name = models.CharField(_(u'name'), max_length=255, blank=True, null=True, help_text=u'姓名')
98
+    phone = models.CharField(_(u'phone'), max_length=255, blank=True, null=True, help_text=u'电话')
99
+    address = models.CharField(_(u'address'), max_length=255, blank=True, null=True, help_text=u'地址')
100
+
101
+    tracking_number = models.CharField(_(u'tracking_number'), max_length=255, blank=True, null=True, help_text=u'快递单号')
102
+
103
+    has_send_template_message = models.BooleanField(_(u'has_send_template_message'), default=True, help_text=u'是否已发送模版消息', db_index=True)
104
+
105
+    class Meta:
106
+        verbose_name = _(u'会员商品订单信息')
107
+        verbose_name_plural = _(u'会员商品订单信息')
108
+
109
+    def __unicode__(self):
110
+        return unicode(self.pk)
111
+
112
+
79 113
 class RightInfo(BaseModelMixin):
80 114
     PHYSICAL = 0
81 115
     VIRTUAL = 1
@@ -169,6 +203,8 @@ class ShotTypeInfo(BaseModelMixin):
169 203
 
170 204
 
171 205
 class MemberActivityInfo(BaseModelMixin):
206
+    activity_id = ShortUUIDField(_(u'activity_id'), max_length=32, blank=True, null=True, help_text=u'活动唯一标识', db_index=True, unique=True)
207
+
172 208
     title = models.CharField(_(u'title'), max_length=255, blank=True, null=True, help_text=u'活动名称')
173 209
     subtitle = models.CharField(_(u'subtitle'), max_length=255, blank=True, null=True, help_text=u'活动二级名称')
174 210
 
@@ -184,7 +220,7 @@ class MemberActivityInfo(BaseModelMixin):
184 220
 
185 221
     cover = models.ImageField(_(u'cover'), upload_to=upload_path, blank=True, null=True, help_text=u'活动列表图片')
186 222
 
187
-    is_slider = models.BooleanField(_(u'is_slider'), default=True, help_text=_(u'是否为轮播活动'), db_index=True)
223
+    is_slider = models.BooleanField(_(u'is_slider'), default=True, help_text=u'是否为轮播活动', db_index=True)
188 224
     slider_image = models.ImageField(_(u'slider_image'), upload_to=upload_path, blank=True, null=True, help_text=u'活动轮播图片')
189 225
 
190 226
     content_rich_text = RichTextField(_(u'content_rich_text'), blank=True, null=True, help_text=u'活动描述')
@@ -228,7 +264,8 @@ class MemberActivityInfo(BaseModelMixin):
228 264
     @property
229 265
     def data(self):
230 266
         return {
231
-            'id': self.pk,
267
+            'id': self.activity_id,
268
+            'activity_id': self.activity_id,
232 269
             'title': self.title,
233 270
             'subtitle': self.subtitle,
234 271
             'date': tc.local_string(self.date, '%Y-%m-%d'),
@@ -245,3 +282,97 @@ class MemberActivityInfo(BaseModelMixin):
245 282
             'state': 0,
246 283
             'is_signed': 0,
247 284
         }
285
+
286
+
287
+class MemberActivitySignupInfo(BaseModelMixin):
288
+    signup_id = ShortUUIDField(_(u'signup_id'), max_length=32, blank=True, null=True, help_text=u'活动报名唯一标识', db_index=True, unique=True)
289
+
290
+    user_id = models.CharField(_(u'user_id'), max_length=32, blank=True, null=True, help_text=u'用户唯一标识', db_index=True)
291
+
292
+    activity_id = models.CharField(_(u'activity_id'), max_length=32, blank=True, null=True, help_text=u'活动唯一标识', db_index=True)
293
+
294
+    title = models.CharField(_(u'title'), max_length=255, blank=True, null=True, help_text=u'活动名称')
295
+
296
+    name = models.CharField(_(u'name'), max_length=255, blank=True, null=True, help_text=u'姓名')
297
+    phone = models.CharField(_(u'phone'), max_length=255, blank=True, null=True, help_text=u'电话')
298
+
299
+    class Meta:
300
+        verbose_name = _(u'会员活动报名信息')
301
+        verbose_name_plural = _(u'会员活动报名信息')
302
+
303
+        unique_together = (
304
+            ('user_id', 'activity_id'),
305
+        )
306
+
307
+    def __unicode__(self):
308
+        return unicode(self.pk)
309
+
310
+
311
+class MemberActivitySigninInfo(BaseModelMixin):
312
+    signin_id = ShortUUIDField(_(u'signin_id'), max_length=32, blank=True, null=True, help_text=u'活动签到唯一标识', db_index=True, unique=True)
313
+
314
+    user_id = models.CharField(_(u'user_id'), max_length=32, blank=True, null=True, help_text=u'用户唯一标识', db_index=True)
315
+
316
+    activity_id = models.CharField(_(u'activity_id'), max_length=32, blank=True, null=True, help_text=u'活动唯一标识', db_index=True)
317
+
318
+    title = models.CharField(_(u'title'), max_length=255, blank=True, null=True, help_text=u'活动名称')
319
+
320
+    class Meta:
321
+        verbose_name = _(u'会员活动签到信息')
322
+        verbose_name_plural = _(u'会员活动签到信息')
323
+
324
+        unique_together = (
325
+            ('user_id', 'activity_id'),
326
+        )
327
+
328
+    def __unicode__(self):
329
+        return unicode(self.pk)
330
+
331
+
332
+class MemberCouponInfo(BaseModelMixin):
333
+    DEEP_CLEANING = 0
334
+    FREE_FOCUS = 1
335
+    CLEAN_APPEARANCE = 2
336
+    ACCIDENTAL_MAINTENANCE = 3
337
+    MAINTENANCE_MANPOWER = 4
338
+
339
+    COUPON_TYPE_TUPLE = (
340
+        (DEEP_CLEANING, u'深度清洁'),
341
+        (FREE_FOCUS, u'免费调焦'),
342
+        (CLEAN_APPEARANCE, u'外观清洁'),
343
+        (ACCIDENTAL_MAINTENANCE, u'意外维修'),
344
+        (MAINTENANCE_MANPOWER, u'维修人工')
345
+    )
346
+
347
+    coupon_id = ShortUUIDField(_(u'coupon_id'), max_length=32, blank=True, null=True, help_text=u'券唯一标识', db_index=True, unique=True)
348
+
349
+    user_id = models.CharField(_(u'user_id'), max_length=32, blank=True, null=True, help_text=u'用户唯一标识', db_index=True)
350
+
351
+    coupon_type = models.IntegerField(_(u'coupon_type'), choices=COUPON_TYPE_TUPLE, default=DEEP_CLEANING, help_text=u'券类型', db_index=True)
352
+    coupon_start_at = models.DateTimeField(_(u'coupon_start_at'), blank=True, null=True, help_text=u'券生效时间')
353
+    coupon_expire_at = models.DateTimeField(_(u'coupon_expire_at'), blank=True, null=True, help_text=u'券过期时间')
354
+    coupon_value = models.IntegerField(_(u'coupon_value'), default=0, help_text=u'券金额(单位:分)')
355
+
356
+    has_used = models.BooleanField(_(u'has_used'), default=False, help_text=u'是否已核销', db_index=True)
357
+    admin_id = models.CharField(_(u'admin_id'), max_length=32, blank=True, null=True, help_text=u'核销员唯一标识', db_index=True)
358
+    used_at = models.DateTimeField(_(u'used_at'), blank=True, null=True, help_text=u'维修券核销时间')
359
+
360
+    class Meta:
361
+        verbose_name = _(u'会员券信息')
362
+        verbose_name_plural = _(u'会员券信息')
363
+
364
+    def __unicode__(self):
365
+        return unicode(self.pk)
366
+
367
+    @property
368
+    def data(self):
369
+        return {
370
+            'coupon_id': self.coupon_id,
371
+            'coupon_type': self.coupon_type,
372
+            'coupon_start_at': tc.local_string(self.coupon_start_at, format='%Y%m%d'),
373
+            'coupon_expire_at': tc.local_string(self.coupon_expire_at, format='%Y%m%d'),
374
+            'coupon_value': self.coupon_value,
375
+            'has_used': self.has_used,
376
+            'admin_id': self.admin_id,
377
+            'used_at': tc.local_string(self.used_at, format='%Y%m%d'),
378
+        }

+ 1 - 1
simditor/views.py

@@ -59,7 +59,7 @@ def upload_handler(request):
59 59
                        'msg': '图片格式错误!'}
60 60
             return JsonResponse(retdata)
61 61
 
62
-    key = upload(uploaded_file.read()).get('key', '')
62
+    key = upload(uploaded_file.read())
63 63
     if not key:
64 64
         retdata = {'file_path': key, 'success': False, 'msg': '上传失败,请重试!'}
65 65
     else:

+ 18 - 0
utils/error/errno_utils.py

@@ -62,6 +62,24 @@ class ProductStatusCode(BaseStatusCode):
62 62
     PRODUCT_NOT_USED = StatusCodeField(502012, 'Product Not Used', description=u'产品未使用')
63 63
 
64 64
 
65
+class MemberGoodStatusCode(BaseStatusCode):
66
+    """ 会员商品相关错误码 5035xx """
67
+    GOOD_NOT_FOUND = StatusCodeField(503501, 'Good Not Found', description=u'商品不存在')
68
+
69
+    GOOD_NO_EXCHANGE_PERMISSION = StatusCodeField(503502, 'Good No Exchange Permission', description=u'商品无兑换权限')
70
+    GOOD_INTEGRAL_NOT_ENOUGH = StatusCodeField(503503, 'Good Integral Not Enough', description=u'商品兑换积分不足')
71
+
72
+
73
+class MemberRightStatusCode(BaseStatusCode):
74
+    """ 会员商品相关错误码 5036xx """
75
+    RIGHT_NOT_FOUND = StatusCodeField(503601, 'Right Not Found', description=u'权益不存在')
76
+
77
+
78
+class MemberActivityStatusCode(BaseStatusCode):
79
+    """ 会员活动相关错误码 5037xx """
80
+    ACTIVITY_NOT_FOUND = StatusCodeField(503701, 'Activity Not Found', description=u'活动不存在')
81
+
82
+
65 83
 class LensmanStatusCode(BaseStatusCode):
66 84
     """ 摄影师相关错误码 4000xx """
67 85
     LENSMAN_NOT_FOUND = StatusCodeField(400001, 'Lensman Not Found', description=u'摄影师不存在')

+ 1 - 1
utils/qiniucdn.py

@@ -39,7 +39,7 @@ def upload_file_path(path, key=None, mime_type='application/octet-stream', bucke
39 39
     return ret.get('key')
40 40
 
41 41
 
42
-def qiniu_file_url(key, bucket):
42
+def qiniu_file_url(key, bucket=QINIU['bucket_default']):
43 43
     if not key:
44 44
         return ''
45 45
     return '{}/{}'.format(QINIU['buckets'][bucket], key)

adminSystem - Gogs: Go Git Service

Keine Beschreibung

license 1.1KB

    MIT License Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.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.