新增摄影师积分体系

FFIB 1 jaar geleden
bovenliggende
commit
c0e75a540a

+ 40 - 0
account/migrations/0061_auto_20240327_1550.py

@@ -0,0 +1,40 @@
1
+# -*- coding: utf-8 -*-
2
+
3
+# Generated by Django 3.2.16 on 2024-03-27 07:50
4
+
5
+from django.db import migrations, models
6
+
7
+
8
+class Migration(migrations.Migration):
9
+
10
+    dependencies = [
11
+        ('account', '0060_auto_20240312_1350'),
12
+    ]
13
+
14
+    operations = [
15
+        migrations.CreateModel(
16
+            name='LensmanIntegralIncomeExpensesInfo',
17
+            fields=[
18
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
19
+                ('status', models.BooleanField(default=True, help_text='Status', verbose_name='status')),
20
+                ('created_at', models.DateTimeField(auto_now_add=True, help_text='Create Time', verbose_name='created_at')),
21
+                ('updated_at', models.DateTimeField(auto_now=True, help_text='Update Time', verbose_name='updated_at')),
22
+                ('user_id', models.CharField(blank=True, db_index=True, help_text='用户唯一标识', max_length=32, null=True, verbose_name='user_id')),
23
+                ('brand_id', models.CharField(blank=True, db_index=True, help_text='品牌唯一标识', max_length=32, null=True, verbose_name='brand_id')),
24
+                ('brand_name', models.CharField(blank=True, help_text='品牌名称', max_length=255, null=True, verbose_name='brand_name')),
25
+                ('integral', models.IntegerField(default=0, help_text='增减积分', verbose_name='integral')),
26
+                ('remark', models.CharField(blank=True, help_text='备注', max_length=255, null=True, verbose_name='remark')),
27
+                ('activity_id', models.CharField(blank=True, db_index=True, help_text='活动唯一标识', max_length=32, null=True, verbose_name='activity_id')),
28
+                ('expired_at', models.DateField(blank=True, help_text='积分过期日期', null=True, verbose_name='expired_at')),
29
+            ],
30
+            options={
31
+                'verbose_name': 'lensmanintegralincomeexpensesinfo',
32
+                'verbose_name_plural': 'lensmanintegralincomeexpensesinfo',
33
+            },
34
+        ),
35
+        migrations.AddField(
36
+            model_name='lensmaninfo',
37
+            name='integral',
38
+            field=models.IntegerField(default=0, help_text='摄影师积分', verbose_name='integral'),
39
+        ),
40
+    ]

+ 56 - 0
account/models.py

@@ -383,6 +383,7 @@ class LensmanInfo(BaseModelMixin):
383 383
 
384 384
     name = models.CharField(_(u'name'), max_length=255, blank=True, null=True, help_text=u'摄影师姓名')
385 385
     phone = models.CharField(_(u'phone'), max_length=11, blank=True, null=True, help_text=u'摄影师联系电话')
386
+    integral = models.IntegerField(_(u'integral'), default=0, help_text=u'摄影师积分')
386 387
 
387 388
     lensman_status = models.IntegerField(_(u'lensman_status'), choices=LENSMAN_STATUS, default=UNVERIFIED, help_text=u'摄影师状态', db_index=True)
388 389
 
@@ -412,6 +413,9 @@ class LensmanInfo(BaseModelMixin):
412 413
             'lensman_id': self.lensman_id,
413 414
             'name': self.name,
414 415
             'phone': self.phone,
416
+            'start_date': self.start_date,
417
+            'end_date': self.end_date,
418
+            'integral': self.integral,
415 419
             'is_expired': self.is_expired,
416 420
             'lensman_status': self.lensman_status,
417 421
         }
@@ -423,6 +427,7 @@ class LensmanInfo(BaseModelMixin):
423 427
             'user_id': self.user_id,
424 428
             'name': self.name,
425 429
             'phone': self.phone,
430
+            'integral': self.integral,
426 431
             'lensman_status': self.lensman_status,
427 432
             'start_date': self.start_date,
428 433
             'end_date': self.end_date,
@@ -496,3 +501,54 @@ class UserIntegralIncomeExpensesInfo(BaseModelMixin):
496 501
             'created_at': tc.local_string(utc_dt=self.created_at),
497 502
         }
498 503
     
504
+
505
+class LensmanIntegralIncomeExpensesInfo(BaseModelMixin):
506
+    user_id = models.CharField(_(u'user_id'), max_length=32, blank=True, null=True, help_text=u'用户唯一标识', db_index=True)
507
+
508
+    brand_id = models.CharField(_(u'brand_id'), max_length=32, blank=True, null=True, help_text=u'品牌唯一标识', db_index=True)
509
+    brand_name = models.CharField(_(u'brand_name'), max_length=255, blank=True, null=True, help_text=u'品牌名称')
510
+
511
+    integral = models.IntegerField(_(u'integral'), default=0, help_text=u'增减积分')
512
+    remark = models.CharField(_(u'remark'), max_length=255, blank=True, null=True, help_text=u'备注')
513
+
514
+    activity_id = models.CharField(_(u'activity_id'), max_length=32, blank=True, null=True, help_text=u'活动唯一标识', db_index=True)
515
+    expired_at = models.DateField(_(u'expired_at'), blank=True, null=True, help_text=u'积分过期日期')
516
+
517
+    class Meta:
518
+        verbose_name = _(u'lensmanintegralincomeexpensesinfo')
519
+        verbose_name_plural = _(u'lensmanintegralincomeexpensesinfo')
520
+
521
+    def __unicode__(self):
522
+        return '%d' % self.pk
523
+
524
+    @property
525
+    def admindata(self):
526
+        if self.activity_id:
527
+            act = MemberActivityInfo.objects.get(activity_id=self.activity_id)
528
+        else:
529
+            act = None
530
+
531
+        return {
532
+            'integral': self.integral,
533
+            'remark': self.remark,
534
+            'act_info': act.admindata if act else None,
535
+            'activity_id': self.activity_id,
536
+            'expired_at': self.expired_at if self.expired_at else '',
537
+            'created_at': tc.local_string(utc_dt=self.created_at),
538
+        }
539
+    
540
+    @property
541
+    def userdata(self):
542
+        if self.activity_id:
543
+            act = MemberActivityInfo.objects.get(activity_id=self.activity_id)
544
+        else:
545
+            act = None
546
+        
547
+        return {
548
+            'integral': self.integral,
549
+            'remark': self.remark,
550
+            'act_info': act.admindata if act else None,
551
+            'activity_id': self.activity_id,
552
+            'expired_at': self.expired_at if self.expired_at else '',
553
+            'created_at': tc.local_string(utc_dt=self.created_at),
554
+        }

+ 32 - 4
api/lensman_admin_views.py

@@ -2,13 +2,14 @@
2 2
 
3 3
 from __future__ import division
4 4
 
5
+from django.conf import settings
5 6
 from django_logit import logit
6 7
 from django_response import response
7 8
 from django.db.models import Q
8 9
 from paginator import pagination
9 10
 from TimeConvert import TimeConvert as tc
10 11
 
11
-from account.models import LensmanInfo, UserIntegralIncomeExpensesInfo
12
+from account.models import LensmanInfo, LensmanIntegralIncomeExpensesInfo
12 13
 from kodo.decorators import check_admin
13 14
 
14 15
 
@@ -90,9 +91,36 @@ def lensman_integral_list(request, administrator):
90 91
   except LensmanInfo.DoesNotExist:
91 92
     return response(200, 'Lensman Not Found', u'摄影师不存在')
92 93
   
93
-  integrals = UserIntegralIncomeExpensesInfo.objects.filter(user_id=user_id, integral_from=UserIntegralIncomeExpensesInfo.LENSMAN_ACTIVITY, status=True)
94
+  integrals = LensmanIntegralIncomeExpensesInfo.objects.filter(user_id=user_id, status=True)
94 95
 
95
-  integrals = [integral.lensman_admindata for integral in integrals]
96
+  integrals = [integral.admindata for integral in integrals]
96 97
   
97 98
 
98
-  return response(200, 'Get Lensman Integral List Success', u'获取摄影师积分列表成功', data=integrals)
99
+  return response(200, 'Get Lensman Integral List Success', u'获取摄影师积分列表成功', data=integrals)
100
+
101
+
102
+@logit
103
+def lensman_integral_update(request):
104
+    user_id = request.POST.get('user_id', '')
105
+    integral = int(request.POST.get('integral', 0))
106
+    remark = request.POST.get('remark', '')
107
+    brand_id = request.POST.get('brand_id') or settings.KODO_DEFAULT_BRAND_ID
108
+
109
+    try:
110
+      lensman = LensmanInfo.objects.get(user_id=user_id, status=True)
111
+    except LensmanInfo.DoesNotExist:
112
+      return response(200, 'Lensman Not Found', u'摄影师不存在')
113
+    
114
+    lensman.integral += integral
115
+    lensman.save()
116
+  
117
+    LensmanIntegralIncomeExpensesInfo.objects.create(
118
+      brand_id=brand_id,
119
+      user_id=user_id,
120
+      integral=integral,
121
+      remark=remark,
122
+      expired_at=lensman.end_date,
123
+    )
124
+
125
+    return response(200, 'Lensman Integral Update Success', u'摄影师积分更新成功')
126
+

+ 6 - 4
api/lensman_mp_views.py

@@ -2,10 +2,11 @@
2 2
 
3 3
 from __future__ import division
4 4
 
5
+from django.conf import settings
5 6
 from django_logit import logit
6 7
 from django_response import response
7 8
 
8
-from account.models import LensmanInfo, UserIntegralIncomeExpensesInfo
9
+from account.models import LensmanInfo, LensmanIntegralIncomeExpensesInfo
9 10
 
10 11
 @logit
11 12
 def lensman_register(request):
@@ -39,15 +40,16 @@ def lensman_detail(request):
39 40
 @logit
40 41
 def lensman_integral_list(request):
41 42
   user_id = request.POST.get('user_id', '')
43
+  brand_id = request.POST.get('brand_id') or settings.KODO_DEFAULT_BRAND_ID
42 44
 
43 45
   try:
44 46
     lensman = LensmanInfo.objects.get(user_id=user_id, status=True)
45 47
   except LensmanInfo.DoesNotExist:
46 48
     return response(200, 'Lensman Not Found', u'摄影师不存在')
47 49
   
48
-  integrals = UserIntegralIncomeExpensesInfo.objects.filter(user_id=user_id, integral_from=UserIntegralIncomeExpensesInfo.LENSMAN_ACTIVITY, status=True)
50
+  integrals = LensmanIntegralIncomeExpensesInfo.objects.filter(user_id=user_id, status=True)
49 51
 
50
-  integrals = [integral.lensman_userdata for integral in integrals]
52
+  integrals = [integral.userdata for integral in integrals]
51 53
   
52 54
 
53
-  return response(200, 'Get Lensman Integral List Success', u'获取摄影师积分列表成功', data=integrals)
55
+  return response(200, 'Get Lensman Integral List Success', u'获取摄影师积分列表成功', data=integrals)    

+ 1 - 0
api/urls.py

@@ -383,4 +383,5 @@ urlpatterns += [
383 383
     url(r'^admin/lensman/audit$', lensman_admin_views.lensman_audit, name='admin_lensman_audit'),
384 384
     url(r'^admin/lensman/update$', lensman_admin_views.lensman_update, name='admin_lensman_update'),
385 385
     url(r'^admin/lensman/integral/list$', lensman_admin_views.lensman_integral_list, name='admin_lensman_integral_list'),
386
+    url(r'^admin/lensman/integral/update$', lensman_admin_views.lensman_integral_update, name='admin_lensman_integral_update'),
386 387
 ]

+ 13 - 73
member/activity_admin_views.py

@@ -9,10 +9,9 @@ from django_response import response
9 9
 from paginator import pagination
10 10
 from TimeConvert import TimeConvert as tc
11 11
 
12
-from account.models import UserIntegralIncomeExpensesInfo, UserInfo, LensmanInfo
13
-from member.models import MemberActivityInfo, MemberActivitySignupInfo, MemberActivityContributionInfo, MemberActivityDataInfo
12
+from member.models import MemberActivityInfo, MemberActivitySignupInfo, MemberActivityContributionInfo
14 13
 from kodo.decorators import check_admin
15
-from utils.error.errno_utils import MemberActivityStatusCode, UserStatusCode
14
+from utils.error.errno_utils import MemberActivityStatusCode
16 15
 
17 16
 
18 17
 @check_admin
@@ -87,6 +86,8 @@ def activity_update(request, administrator):
87 86
     end_date = date = tc.to_date(request.POST.get('end_date', '') or settings.DEFAULT_END_DATE)
88 87
     start_display_date = tc.to_date(request.POST.get('start_display_date', '') or settings.DEFAULT_START_DATE)
89 88
     end_display_date = tc.to_date(request.POST.get('end_display_date', '') or settings.DEFAULT_END_DATE)
89
+    start_data_submit_date = tc.to_date(request.POST.get('start_data_submit_date', '') or settings.DEFAULT_START_DATE)
90
+    end_data_submit_date = tc.to_date(request.POST.get('end_data_submit_date', '') or settings.DEFAULT_END_DATE)
90 91
     city = request.POST.get('city', '')
91 92
     location = request.POST.get('location', '')
92 93
     integral = int(request.POST.get('integral', 0))
@@ -128,6 +129,8 @@ def activity_update(request, administrator):
128 129
     log.end_date = end_date
129 130
     log.start_display_date = start_display_date
130 131
     log.end_display_date = end_display_date
132
+    log.start_data_submit_date = start_data_submit_date
133
+    log.end_data_submit_date = end_data_submit_date
131 134
     log.city = city
132 135
     log.location = location
133 136
     log.integral = integral
@@ -166,6 +169,8 @@ def activity_create(request, administrator):
166 169
     end_date = date = tc.to_date(request.POST.get('end_date', '') or settings.DEFAULT_END_DATE)
167 170
     start_display_date = tc.to_date(request.POST.get('start_display_date', '') or settings.DEFAULT_START_DATE)
168 171
     end_display_date = tc.to_date(request.POST.get('end_display_date', '') or settings.DEFAULT_END_DATE)
172
+    start_data_submit_date = tc.to_date(request.POST.get('start_data_submit_date', '') or settings.DEFAULT_START_DATE)
173
+    end_data_submit_date = tc.to_date(request.POST.get('end_data_submit_date', '') or settings.DEFAULT_END_DATE)
169 174
     city = request.POST.get('city', '')
170 175
     location = request.POST.get('location', '')
171 176
     integral = int(request.POST.get('integral', 0))
@@ -201,6 +206,8 @@ def activity_create(request, administrator):
201 206
         end_date=end_date,
202 207
         start_display_date=start_display_date,
203 208
         end_display_date=end_display_date,
209
+        start_data_submit_date=start_data_submit_date,
210
+        end_data_submit_date=end_data_submit_date,
204 211
         city=city,
205 212
         location=location,
206 213
         integral=integral,
@@ -239,7 +246,7 @@ def activity_signup_list(request, administrator):
239 246
     num = int(request.POST.get('num', 20))
240 247
     query = request.POST.get('query', '')
241 248
     is_signin = request.POST.get('is_signin', False)
242
-    passed = request.POST.get('passed', '')
249
+    audit_status = request.POST.get('audit_status', '')
243 250
 
244 251
     logs = MemberActivitySignupInfo.objects.filter(activity_id=activity_id, status=True).exclude(fields='[]')
245 252
 
@@ -249,8 +256,8 @@ def activity_signup_list(request, administrator):
249 256
     if is_signin:
250 257
         logs = logs.filter(is_signin=is_signin)
251 258
     
252
-    if passed:
253
-        logs = logs.filter(passed=passed)
259
+    if audit_status:
260
+        logs = logs.filter(audit_status=audit_status)
254 261
 
255 262
 
256 263
     count = logs.count()
@@ -262,70 +269,3 @@ def activity_signup_list(request, administrator):
262 269
         'count': count,
263 270
         'left': left,
264 271
     })
265
-
266
-
267
-@check_admin
268
-def activity_signup_pass(request, administrator):
269
-    activity_id = request.POST.get('activity_id', '')
270
-    signup_id = request.POST.get('signup_id', '')
271
-
272
-    MemberActivitySignupInfo.objects.filter(activity_id=activity_id, signup_id=signup_id, status=True).update(passed=True)
273
-
274
-    return response(200, 'Member Activity Signup Passed Success', u'活动报名通过成功')
275
-
276
-
277
-@check_admin
278
-def activity_data_list(request, administrator):
279
-    activity_id = request.POST.get('activity_id', '')
280
-    page = int(request.POST.get('page', 1))
281
-    num = int(request.POST.get('num', 20))
282
-    query = request.POST.get('query', '')
283
-
284
-    logs = MemberActivityDataInfo.objects.filter(activity_id=activity_id, status=True)
285
-    if query:
286
-        logs = logs.filter(Q(lensman_name__icontains=query) | Q(lensman_phone__icontains=query))
287
-
288
-    count = logs.count()
289
-    logs, left = pagination(logs, page, num)
290
-    logs = [log.admindata for log in logs]
291
-    
292
-    return response(200, 'Get Member Activity Data List Success', u'获取会员活动数据列表成功', data={
293
-        'logs': logs,
294
-        'count': count,
295
-        'left': left,
296
-    })
297
-
298
-@check_admin
299
-def activity_integral_add(request, administrator):
300
-    activity_id = request.POST.get('activity_id', '')
301
-    user_id = request.POST.get('user_id', '')
302
-    lensman_id = request.POST.get('lensman_id', '')
303
-    integral = int(request.POST.get('integral', 0))
304
-    remark = request.POST.get('remark', '')
305
-    brand_id = request.POST.get('brand_id') or settings.KODO_DEFAULT_BRAND_ID
306
-
307
-    try:
308
-        user = UserInfo.objects.get(user_id=user_id, status=True)
309
-    except UserInfo.DoesNotExist:
310
-        return response(UserStatusCode.USER_NOT_FOUND)
311
-
312
-    try:
313
-        lensman = LensmanInfo.objects.get(lensman_id=lensman_id, status=True)
314
-    except LensmanInfo.DoesNotExist:
315
-        return response('400001', 'LensmanInfo Not Found', '摄影师不存在')
316
-
317
-    user.integral += integral
318
-    user.save()
319
-
320
-    UserIntegralIncomeExpensesInfo.objects.create(
321
-        brand_id=brand_id,
322
-        user_id=user_id,
323
-        integral_from=UserIntegralIncomeExpensesInfo.LENSMAN_ACTIVITY,
324
-        integral=integral,
325
-        final_integral=user.integral,
326
-        activity_id=activity_id,
327
-        remark=remark,
328
-        expired_at=lensman.end_date,
329
-    )
330
-
331
-    return response(200, 'Add Member Activity Integral Success', u'添加积分成功')

+ 0 - 48
member/activity_mp_views.py

@@ -129,54 +129,6 @@ def activity_signup_detail(request):
129 129
 
130 130
 
131 131
 @logit
132
-def activity_data_submit(request):
133
-    user_id = request.POST.get('user_id', '')
134
-    lensman_id = request.POST.get('lensman_id', '')
135
-    activity_id = request.POST.get('activity_id', '')
136
-    data_fields = request.POST.get('data_fields', '[]')
137
-
138
-    try:
139
-        act = MemberActivityInfo.objects.get(activity_id=activity_id, status=True)
140
-    except MemberActivityInfo.DoesNotExist:
141
-        return response(MemberActivityStatusCode.ACTIVITY_NOT_FOUND)
142
-    
143
-    try:
144
-        lensman = LensmanInfo.objects.get(lensman_id=lensman_id, status=True)
145
-    except LensmanInfo.DoesNotExist:
146
-        return response('400001', 'LensmanInfo Not Found', '摄影师不存在')
147
-
148
-    if lensman.is_expired:
149
-        return response(40001, 'Lensman Has Expired', '摄影师合作已到期')
150
-
151
-    MemberActivityDataInfo.objects.update_or_create(user_id=user_id, activity_id=activity_id, defaults={
152
-        'title': act.title,
153
-        'lensman_id': lensman_id,
154
-        'lensman_name': lensman.name,
155
-        'lensman_phone': lensman.phone,
156
-        'data_fields': data_fields,
157
-    })
158
-
159
-    return response(data={
160
-        'activity': act.data(user_id),
161
-    })
162
-
163
-
164
-@logit
165
-def activity_data_detail(request):
166
-    user_id = request.POST.get('user_id', '')
167
-    activity_id = request.POST.get('activity_id', '')
168
-
169
-    try:
170
-        data_info = MemberActivityDataInfo.objects.get(user_id=user_id, activity_id=activity_id, status=True)
171
-    except MemberActivityDataInfo.DoesNotExist:
172
-        return response()
173
-
174
-    return response(data={
175
-        'data_info': data_info.data,
176
-    })
177
-
178
-
179
-@logit
180 132
 def activity_contribute_create(request):
181 133
     brand_id = request.POST.get('brand_id') or settings.KODO_DEFAULT_BRAND_ID
182 134
     user_id = request.POST.get('user_id', '')

+ 4 - 4
member/admin_urls.py

@@ -2,7 +2,7 @@
2 2
 
3 3
 from django.conf.urls import url
4 4
 
5
-from member import activity_admin_views
5
+from member import activity_admin_views, lensman_activity_admin_views
6 6
 
7 7
 # activity
8 8
 urlpatterns = [
@@ -15,11 +15,11 @@ urlpatterns = [
15 15
 # activity signup
16 16
 urlpatterns += [
17 17
     url(r'^member/activity/signup/list$', activity_admin_views.activity_signup_list, name='admin_member_activity_signup_list'),
18
-    url(r'^member/activity/signup/pass$', activity_admin_views.activity_signup_pass, name='admin_member_activity_signup_pass'),
18
+    url(r'^member/activity/signup/audit$', lensman_activity_admin_views.activity_signup_audit, name='admin_member_activity_signup_audit'),
19 19
 ]
20 20
 
21 21
 #activity data
22 22
 urlpatterns += [
23
-    url(r'^member/activity/data/list$', activity_admin_views.activity_data_list, name='admin_member_activity_data_list'),
24
-    url(r'^member/activity/integral/add$', activity_admin_views.activity_integral_add, name='admin_member_activity_integral_add'),
23
+    url(r'^member/activity/data/list$', lensman_activity_admin_views.activity_data_list, name='admin_member_activity_data_list'),
24
+    url(r'^member/activity/integral/add$', lensman_activity_admin_views.activity_integral_add, name='admin_member_activity_integral_add'),
25 25
 ]

+ 78 - 0
member/lensman_activity_admin_views.py

@@ -0,0 +1,78 @@
1
+# -*- coding: utf-8 -*-
2
+
3
+from django.conf import settings
4
+from django.db.models import Q
5
+from django_logit import logit
6
+from django_response import response
7
+from paginator import pagination
8
+
9
+from account.models import LensmanIntegralIncomeExpensesInfo, UserInfo, LensmanInfo
10
+from member.models import  MemberActivitySignupInfo, MemberActivityDataInfo
11
+from kodo.decorators import check_admin
12
+from utils.error.errno_utils import UserStatusCode
13
+
14
+
15
+@check_admin
16
+def activity_signup_audit(request, administrator):
17
+    activity_id = request.POST.get('activity_id', '')
18
+    signup_id = request.POST.get('signup_id', '')
19
+    audit_status = request.POST.get('audit_status', 0)
20
+
21
+    MemberActivitySignupInfo.objects.filter(activity_id=activity_id, signup_id=signup_id, status=True).update(audit_status=audit_status)
22
+
23
+    return response(200, 'Member Activity Signup Audit Success', u'活动审核成功')
24
+
25
+
26
+@check_admin
27
+def activity_data_list(request, administrator):
28
+    activity_id = request.POST.get('activity_id', '')
29
+    page = int(request.POST.get('page', 1))
30
+    num = int(request.POST.get('num', 20))
31
+    query = request.POST.get('query', '')
32
+
33
+    logs = MemberActivityDataInfo.objects.filter(activity_id=activity_id, status=True)
34
+    if query:
35
+        logs = logs.filter(Q(lensman_name__icontains=query) | Q(lensman_phone__icontains=query))
36
+
37
+    count = logs.count()
38
+    logs, left = pagination(logs, page, num)
39
+    logs = [log.admindata for log in logs]
40
+    
41
+    return response(200, 'Get Member Activity Data List Success', u'获取会员活动数据列表成功', data={
42
+        'logs': logs,
43
+        'count': count,
44
+        'left': left,
45
+    })
46
+
47
+@check_admin
48
+def activity_integral_add(request, administrator):
49
+    activity_id = request.POST.get('activity_id', '')
50
+    user_id = request.POST.get('user_id', '')
51
+    lensman_id = request.POST.get('lensman_id', '')
52
+    integral = int(request.POST.get('integral', 0))
53
+    remark = request.POST.get('remark', '')
54
+    brand_id = request.POST.get('brand_id') or settings.KODO_DEFAULT_BRAND_ID
55
+
56
+    try:
57
+        user = UserInfo.objects.get(user_id=user_id, status=True)
58
+    except UserInfo.DoesNotExist:
59
+        return response(UserStatusCode.USER_NOT_FOUND)
60
+
61
+    try:
62
+        lensman = LensmanInfo.objects.get(lensman_id=lensman_id, status=True)
63
+    except LensmanInfo.DoesNotExist:
64
+        return response('400001', 'LensmanInfo Not Found', '摄影师不存在')
65
+
66
+    user.integral += integral
67
+    user.save()
68
+
69
+    LensmanIntegralIncomeExpensesInfo.objects.create(
70
+        brand_id=brand_id,
71
+        user_id=user_id,
72
+        integral=integral,
73
+        activity_id=activity_id,
74
+        remark=remark,
75
+        expired_at=lensman.end_date,
76
+    )
77
+
78
+    return response(200, 'Add Member Activity Integral Success', u'添加积分成功')

+ 82 - 0
member/lensman_activity_mp_views.py

@@ -0,0 +1,82 @@
1
+# -*- coding: utf-8 -*-
2
+
3
+from django.conf import settings
4
+from django_logit import logit
5
+from django.db.models import Q
6
+from django_response import response
7
+
8
+from account.models import LensmanInfo
9
+from member.models import MemberActivityInfo, MemberActivityDataInfo, MemberActivitySignupInfo
10
+from utils.error.errno_utils import MemberActivityStatusCode
11
+
12
+@logit
13
+def activity_data_submit(request):
14
+    user_id = request.POST.get('user_id', '')
15
+    lensman_id = request.POST.get('lensman_id', '')
16
+    activity_id = request.POST.get('activity_id', '')
17
+    data_fields = request.POST.get('data_fields', '[]')
18
+
19
+    try:
20
+        act = MemberActivityInfo.objects.get(activity_id=activity_id, status=True)
21
+    except MemberActivityInfo.DoesNotExist:
22
+        return response(MemberActivityStatusCode.ACTIVITY_NOT_FOUND)
23
+    
24
+    try:
25
+        lensman = LensmanInfo.objects.get(lensman_id=lensman_id, status=True)
26
+    except LensmanInfo.DoesNotExist:
27
+        return response('400001', 'LensmanInfo Not Found', '摄影师不存在')
28
+
29
+    if lensman.is_expired:
30
+        return response(40001, 'Lensman Has Expired', '摄影师合作已到期')
31
+
32
+    MemberActivityDataInfo.objects.update_or_create(user_id=user_id, activity_id=activity_id, defaults={
33
+        'title': act.title,
34
+        'lensman_id': lensman_id,
35
+        'lensman_name': lensman.name,
36
+        'lensman_phone': lensman.phone,
37
+        'data_fields': data_fields,
38
+    })
39
+
40
+    return response(data={
41
+        'activity': act.data(user_id),
42
+    })
43
+
44
+
45
+@logit
46
+def activity_data_detail(request):
47
+    user_id = request.POST.get('user_id', '')
48
+    activity_id = request.POST.get('activity_id', '')
49
+
50
+    try:
51
+        data_info = MemberActivityDataInfo.objects.get(user_id=user_id, activity_id=activity_id, status=True)
52
+    except MemberActivityDataInfo.DoesNotExist:
53
+        return response()
54
+
55
+    return response(data={
56
+        'data_info': data_info.data,
57
+    })
58
+
59
+
60
+@logit
61
+def activity_signup_message(request):
62
+    user_id = request.POST.get('user_id', '')
63
+
64
+    lensman_acts = MemberActivityInfo.objects.values_list('activity_id', flat=True).filter(activity_section=4, status=True)
65
+    infos = MemberActivitySignupInfo.objects.filter(Q(user_id=user_id) & Q(activity_id__in=lensman_acts) & Q(is_read=False)).exclude(audit_status=MemberActivitySignupInfo.UNAUDITED)
66
+
67
+    infos = [info.data for info in infos]
68
+
69
+    return response(data={
70
+        'messages': infos
71
+    })
72
+
73
+@logit
74
+def activity_signup_message_read(request):
75
+    user_id = request.POST.get('user_id', '')
76
+    signup_id = request.POST.get('signup_id', '')
77
+
78
+    MemberActivitySignupInfo.objects.filter(user_id=user_id, signup_id=signup_id).update(is_read=True)
79
+
80
+    return response(200, 'Activity Signup Message Has Read Success', '活动报名消息已读')
81
+
82
+                                 

+ 44 - 0
member/migrations/0070_auto_20240327_1550.py

@@ -0,0 +1,44 @@
1
+# -*- coding: utf-8 -*-
2
+
3
+# Generated by Django 3.2.16 on 2024-03-27 07:50
4
+
5
+from django.db import migrations, models
6
+
7
+
8
+class Migration(migrations.Migration):
9
+
10
+    dependencies = [
11
+        ('member', '0069_auto_20240312_1350'),
12
+    ]
13
+
14
+    operations = [
15
+        migrations.RemoveField(
16
+            model_name='memberactivitysignupinfo',
17
+            name='passed',
18
+        ),
19
+        migrations.AddField(
20
+            model_name='memberactivityinfo',
21
+            name='end_data_submit_date',
22
+            field=models.DateField(blank=True, help_text='活动数据提交截止日期', null=True, verbose_name='end_data_submit_date'),
23
+        ),
24
+        migrations.AddField(
25
+            model_name='memberactivityinfo',
26
+            name='start_data_submit_date',
27
+            field=models.DateField(blank=True, help_text='活动数据提交开始日期', null=True, verbose_name='start_data_submit_date'),
28
+        ),
29
+        migrations.AddField(
30
+            model_name='memberactivitysignupinfo',
31
+            name='audit_status',
32
+            field=models.IntegerField(choices=[(0, '未审核'), (1, '已通过'), (2, '未通过')], db_index=True, default=0, help_text='审核状态', verbose_name='audit_status'),
33
+        ),
34
+        migrations.AddField(
35
+            model_name='memberactivitysignupinfo',
36
+            name='is_read',
37
+            field=models.BooleanField(default=False, help_text='报名消息是否已读', verbose_name='is_read'),
38
+        ),
39
+        migrations.AlterField(
40
+            model_name='memberactivityinfo',
41
+            name='activity_section',
42
+            field=models.IntegerField(choices=[(0, 'Tamron Life'), (1, 'Tamron LRC直播课'), (2, '会员投稿'), (3, '其他'), (4, '摄影师')], db_index=True, default=3, help_text='活动分区', verbose_name='activity_section'),
43
+        ),
44
+    ]

+ 28 - 5
member/models.py

@@ -379,7 +379,7 @@ class MemberActivityInfo(BaseModelMixin, BrandInfoMixin):
379 379
         (1, u'Tamron LRC直播课'),
380 380
         (2, u'会员投稿'),
381 381
         (3, u'其他'),
382
-        (4, u'会员投稿'),
382
+        (4, u'摄影师'),
383 383
     )
384 384
 
385 385
     activity_id = ShortUUIDField(_(u'activity_id'), max_length=32, blank=True, help_text=u'活动唯一标识', db_index=True, unique=True)
@@ -395,6 +395,8 @@ class MemberActivityInfo(BaseModelMixin, BrandInfoMixin):
395 395
     end_date = models.DateField(_(u'end_date'), blank=True, null=True, help_text=u'活动报名截止日期')
396 396
     start_display_date = models.DateField(_(u'start_display_date'), blank=True, null=True, help_text=u'活动展示开始日期')
397 397
     end_display_date = models.DateField(_(u'end_display_date'), blank=True, null=True, help_text=u'活动展示截止日期')
398
+    start_data_submit_date = models.DateField(_(u'start_data_submit_date'), blank=True, null=True, help_text=u'活动数据提交开始日期')
399
+    end_data_submit_date = models.DateField(_(u'end_data_submit_date'), blank=True, null=True, help_text=u'活动数据提交截止日期')
398 400
 
399 401
     city = models.CharField(_(u'city'), max_length=255, blank=True, default='', help_text=u'活动城市')
400 402
     location = models.CharField(_(u'location'), max_length=255, blank=True, default='', help_text=u'活动地点')
@@ -507,7 +509,7 @@ class MemberActivityInfo(BaseModelMixin, BrandInfoMixin):
507 509
         return MemberActivityContributionInfo.objects.filter(user_id=user_id, activity_id=self.activity_id, status=True).exists()
508 510
     
509 511
     def is_signup_passed(self, user_id):
510
-        return MemberActivitySignupInfo.objects.filter(user_id=user_id, activity_id=self.activity_id, passed=True, status=True).exists()
512
+        return MemberActivitySignupInfo.objects.filter(user_id=user_id, activity_id=self.activity_id, audit_status=MemberActivitySignupInfo.PASSED, status=True).exists()
511 513
 
512 514
     @property
513 515
     def welfares(self):
@@ -544,6 +546,8 @@ class MemberActivityInfo(BaseModelMixin, BrandInfoMixin):
544 546
             'end_date': tc.local_date_string(self.end_date),
545 547
             'start_display_date': tc.local_date_string(self.start_display_date),
546 548
             'end_display_date': tc.local_date_string(self.end_display_date),
549
+            'start_data_submit_date': tc.local_date_string(self.start_data_submit_date),
550
+            'end_data_submit_date': tc.local_date_string(self.end_data_submit_date),
547 551
             'city': self.city,
548 552
             'location': self.location,
549 553
             'lat': self.lat,
@@ -590,6 +594,8 @@ class MemberActivityInfo(BaseModelMixin, BrandInfoMixin):
590 594
             'end_date': tc.local_date_string(self.end_date),
591 595
             'start_display_date': tc.local_date_string(self.start_display_date),
592 596
             'end_display_date': tc.local_date_string(self.end_display_date),
597
+            'start_data_submit_date': tc.local_date_string(self.start_data_submit_date),
598
+            'end_data_submit_date': tc.local_date_string(self.end_data_submit_date),
593 599
             'city': self.city,
594 600
             'location': self.location,
595 601
             'lat': self.lat,
@@ -638,6 +644,8 @@ class MemberActivityInfo(BaseModelMixin, BrandInfoMixin):
638 644
             'end_date': tc.local_date_string(self.end_date),
639 645
             'start_display_date': tc.local_date_string(self.start_display_date),
640 646
             'end_display_date': tc.local_date_string(self.end_display_date),
647
+            'start_data_submit_date': tc.local_date_string(self.start_data_submit_date),
648
+            'end_data_submit_date': tc.local_date_string(self.end_data_submit_date),
641 649
             'city': self.city,
642 650
             'location': self.location,
643 651
             'lat': self.lat,
@@ -685,6 +693,8 @@ class MemberActivityInfo(BaseModelMixin, BrandInfoMixin):
685 693
             'end_date': tc.local_date_string(self.end_date),
686 694
             'start_display_date': tc.local_date_string(self.start_display_date),
687 695
             'end_display_date': tc.local_date_string(self.end_display_date),
696
+            'start_data_submit_date': tc.local_date_string(self.start_data_submit_date),
697
+            'end_data_submit_date': tc.local_date_string(self.end_data_submit_date),
688 698
             'city': self.city,
689 699
             'location': self.location,
690 700
             'lat': self.lat,
@@ -723,6 +733,16 @@ class MemberActivityInfo(BaseModelMixin, BrandInfoMixin):
723 733
 
724 734
 
725 735
 class MemberActivitySignupInfo(BaseModelMixin, BrandInfoMixin):
736
+    UNAUDITED = 0
737
+    PASSED = 1
738
+    UNPASSED = 2
739
+
740
+    AUDIT_STATUS = (
741
+        (UNAUDITED, '未审核'),
742
+        (PASSED, '已通过'),
743
+        (UNPASSED, '未通过'),
744
+    )
745
+
726 746
     signup_id = ShortUUIDField(_(u'signup_id'), max_length=32, blank=True, null=True, help_text=u'活动报名唯一标识', db_index=True, unique=True)
727 747
 
728 748
     user_id = models.CharField(_(u'user_id'), max_length=32, blank=True, null=True, help_text=u'用户唯一标识', db_index=True)
@@ -738,10 +758,12 @@ class MemberActivitySignupInfo(BaseModelMixin, BrandInfoMixin):
738 758
 
739 759
     fields = JSONField(_(u'fields'), blank=True, null=True, default='[]', help_text=u'自定义报名字段')
740 760
 
741
-    passed = models.BooleanField(_(u'passed'), default=False, help_text=u'是否通过')
761
+    audit_status = models.IntegerField(_(u'audit_status'), choices=AUDIT_STATUS, default=UNAUDITED, help_text=u'审核状态', db_index=True)
742 762
 
743 763
     is_signin = models.BooleanField(_(u'is_signin'), default=False, help_text=u'是否已签到')
744 764
 
765
+    is_read = models.BooleanField(_(u'is_read'), default=False, help_text=u'报名消息是否已读')
766
+
745 767
     class Meta:
746 768
         verbose_name = _(u'会员活动报名信息')
747 769
         verbose_name_plural = _(u'会员活动报名信息')
@@ -756,6 +778,7 @@ class MemberActivitySignupInfo(BaseModelMixin, BrandInfoMixin):
756 778
     @property
757 779
     def final_avatar(self):
758 780
         return self.avatar and self.avatar.replace(settings.QINIU_FILE_URL_BEFORE, settings.QINIU_FILE_URL_AFTER).replace(settings.QINIU_FILE_URL_BEFORE2, settings.QINIU_FILE_URL_AFTER)
781
+    
759 782
 
760 783
     @property
761 784
     def data(self):
@@ -767,7 +790,7 @@ class MemberActivitySignupInfo(BaseModelMixin, BrandInfoMixin):
767 790
             'name': self.name,
768 791
             'phone': self.phone,
769 792
             'fields': json.loads(self.fields) if self.fields else [],
770
-            'passed': self.passed,
793
+            'audit_status': self.audit_status,
771 794
         }
772 795
 
773 796
     @property
@@ -783,7 +806,7 @@ class MemberActivitySignupInfo(BaseModelMixin, BrandInfoMixin):
783 806
             'phone': self.phone,
784 807
             'fields': json.loads(self.fields) if self.fields else [],
785 808
             'is_signin': self.is_signin,
786
-            'passed': self.passed,
809
+            'audit_status': self.audit_status,
787 810
         }
788 811
     
789 812
 class MemberActivityDataInfo(BaseModelMixin, BrandInfoMixin):

+ 9 - 3
member/mp_urls.py

@@ -2,7 +2,7 @@
2 2
 
3 3
 from django.conf.urls import url
4 4
 
5
-from member import activity_mp_views
5
+from member import activity_mp_views, lensman_activity_mp_views
6 6
 
7 7
 # activity
8 8
 urlpatterns = [
@@ -22,8 +22,8 @@ urlpatterns += [
22 22
 
23 23
 # activity data
24 24
 urlpatterns += [
25
-    url(r'^member/activity/data/submit$', activity_mp_views.activity_data_submit, name='mp_member_activity_data_submit'),  # 会员活动数据提交
26
-    url(r'^member/activity/data/detail$', activity_mp_views.activity_data_detail, name='mp_member_activity_data_detail'),  # 获取会员活动报名信息
25
+    url(r'^member/activity/data/submit$', lensman_activity_mp_views.activity_data_submit, name='mp_member_activity_data_submit'),  # 会员活动数据提交
26
+    url(r'^member/activity/data/detail$', lensman_activity_mp_views.activity_data_detail, name='mp_member_activity_data_detail'),  # 获取会员活动报名信息
27 27
 ]
28 28
 
29 29
 
@@ -36,3 +36,9 @@ urlpatterns += [
36 36
 
37 37
     url(r'^member/activity/contribute/detail/lastest$', activity_mp_views.activity_contribute_detail_lastest, name='member_activity_contribute_detail_lastest'),
38 38
 ]
39
+
40
+#activity message
41
+urlpatterns += [
42
+    url(r'^member/activity/signup/message$', lensman_activity_mp_views.activity_signup_message, name='mp_member_activity_signup_message'),
43
+    url(r'^member/activity/signup/message/read$', lensman_activity_mp_views.activity_signup_message_read, name='mp_member_activity_signup_message_read'),
44
+]