add api lensman_origin_wanted_api/lensman_origin_photo_upload_api

Brightcells лет %!s(int64=8): %!d(string=назад)
Родитель
Сommit
6199c8f7ad

+ 2 - 0
api/urls.py

@@ -33,8 +33,10 @@ urlpatterns += [
33 33
     url(r'^l/wx/authorize$', lensman_views.lensman_wx_authorize_api, name='lensman_wx_authorize_api'),  # 微信用户授权
34 34
 
35 35
     url(r'^l/upload$', lensman_views.lensman_photo_upload_api, name='lensman_photo_upload_api'),  # 摄影师照片上传
36
+    url(r'^l/origin_upload$', lensman_views.lensman_origin_photo_upload_api, name='lensman_origin_photo_upload_api'),  # 摄影师原图上传
36 37
 
37 38
     url(r'^l/brief$', lensman_views.lensman_brief_api, name='lensman_brief_api'),  # 摄影师简报
39
+    url(r'^l/origin_wanted$', lensman_views.lensman_origin_wanted_api, name='lensman_origin_wanted_api'),  # 摄影师原图订单
38 40
 ]
39 41
 
40 42
 # 群组相关

+ 106 - 3
group/lensman_views.py

@@ -9,21 +9,23 @@ from curtail_uuid import CurtailUUID
9 9
 from django.conf import settings
10 10
 from django.contrib.auth.hashers import check_password
11 11
 from django.core.files.storage import default_storage
12
+from django.db import transaction
12 13
 from isoweek import Week
13 14
 from logit import logit
14 15
 from TimeConvert import TimeConvert as tc
15 16
 
16
-from account.models import LensmanInfo, UserInfo
17
-from group.models import GroupInfo, GroupPhotoInfo, GroupUserInfo
17
+from account.models import LensmanInfo, UserIncomeExpensesInfo, UserInfo
18
+from group.models import GroupInfo, GroupPhotoInfo, GroupPhotoOrderInfo, GroupUserInfo
18 19
 from message.models import SystemMessageInfo
19 20
 from pay.models import OrderInfo
20 21
 from photo.models import PhotosInfo
21
-from utils.error.errno_utils import LensmanStatusCode, UserStatusCode
22
+from utils.error.errno_utils import LensmanStatusCode, OrderStatusCode, UserStatusCode
22 23
 from utils.error.response_utils import response
23 24
 from utils.message_utils import system_messages
24 25
 from utils.page_utils import pagination
25 26
 from utils.redis.rgroup import get_group_info, get_group_users_info, set_group_info, set_group_users_info
26 27
 from utils.redis.rkeys import GROUP_LAST_PHOTO_PK, TODAY_INCOME, TODAY_UPLOAD_PHOTO_AMOUNT, WEEK_INCOME, WEEK_SOLD
28
+from utils.redis.rorder import set_lensman_order_record
27 29
 from utils.thumbnail_utils import make_thumbnail
28 30
 from utils.watermark_utils import watermark_wrap
29 31
 
@@ -254,6 +256,90 @@ def lensman_photo_upload_api(request):
254 256
 
255 257
 
256 258
 @logit
259
+@transaction.atomic
260
+def lensman_origin_photo_upload_api(request):
261
+    user_id = lensman_id = request.POST.get('user_id', '')
262
+    session_id = request.POST.get('session_id', '')
263
+
264
+    photo_id = request.POST.get('photo_id', '')
265
+
266
+    deleted = int(request.POST.get('deleted', 0))
267
+
268
+    photo = request.FILES.get('photo', '')
269
+
270
+    try:
271
+        order = OrderInfo.objects.get(session_id=session_id, lensman_photo_id=photo_id)
272
+    except OrderInfo.DoesNotExist:
273
+        return response(OrderStatusCode.WX_ORDER_NOT_FOUND)
274
+
275
+    if order.pay_status != OrderInfo.PAID:
276
+        return response(OrderStatusCode.WX_ORDER_NOT_PAY)
277
+
278
+    from_uid = order.from_uid
279
+    # 原图已删除, 处理退款逻辑
280
+    if deleted:
281
+        try:
282
+            user = UserInfo.objects.get(uid=from_uid)
283
+        except UserInfo.DoesNotExist:
284
+            pass
285
+
286
+        if user:
287
+            # 增加余额
288
+            user.balance += order.total_fee
289
+            user.save()
290
+            # 余额记录
291
+            UserIncomeExpensesInfo.objects.create(
292
+                user_id=from_uid,
293
+                photo_id=order.photo_id,
294
+                type=UserIncomeExpensesInfo.INCOME,
295
+                amount=order.total_fee,
296
+                balance=user.balance,
297
+                remark=u'高清图购买退款',
298
+            )
299
+
300
+        order.photo_status = OrderInfo.DELETED
301
+        order.reback_status = True
302
+        order.reback_at = tc.utc_datetime()
303
+        order.save()
304
+
305
+    if photo:
306
+        # 写 PhotosInfo 表
307
+        _, extension = os.path.splitext(photo.name)
308
+        extension = extension or 'jpeg'
309
+
310
+        r_photo_path = 'photo/{uuid}{extension}'.format(uuid=shortuuid.uuid(), extension=extension)
311
+
312
+        if default_storage.exists(r_photo_path):
313
+            default_storage.delete(r_photo_path)
314
+        default_storage.save(r_photo_path, photo)
315
+
316
+        PhotosInfo.objects.filter(
317
+            lensman_id=lensman_id,
318
+            session_id=session_id,
319
+            photo_id=photo_id,
320
+        ).update(
321
+            r_photo_path=r_photo_path
322
+        )
323
+
324
+        porder, created = GroupPhotoOrderInfo.objects.get_or_create(
325
+            group_id=order.group_id,
326
+            session_id=session_id,
327
+            user_id=from_uid,
328
+            photo_id=order.photo_id,
329
+            lensman_photo_id=photo_id,
330
+        )
331
+        porder.r_photo_path = r_photo_path
332
+        porder.save()
333
+
334
+        set_lensman_order_record(porder)
335
+
336
+        order.photo_status = OrderInfo.FETCHED
337
+        order.save()
338
+
339
+    return response(200, 'Lensman Upload Origin Photo Success', u'摄影师照片高清图上传成功')
340
+
341
+
342
+@logit
257 343
 def lensman_brief_api(request):
258 344
     user_id = request.POST.get('user_id', '')
259 345
 
@@ -289,3 +375,20 @@ def lensman_brief_api(request):
289 375
             'orders': orders,
290 376
         }
291 377
     })
378
+
379
+
380
+@logit
381
+def lensman_origin_wanted_api(request):
382
+    user_id = request.POST.get('user_id', '')
383
+
384
+    orders = OrderInfo.objects.filter(
385
+        to_uid=user_id,
386
+        photo_type=OrderInfo.ORIGIN,
387
+        photo_status=OrderInfo.WANTED,
388
+        status=True
389
+    ).order_by('pk')
390
+    wanted = [order.lensdata for order in orders]
391
+
392
+    return response(200, 'Get Origin Wanted Success', u'获取需要上传原图成功', {
393
+        'wanted': wanted
394
+    })

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

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

+ 3 - 1
group/models.py

@@ -231,10 +231,12 @@ class GroupPhotoInfo(CreateUpdateMixin):
231 231
 
232 232
 class GroupPhotoOrderInfo(CreateUpdateMixin):
233 233
     group_id = models.CharField(_(u'group_id'), max_length=255, blank=True, null=True, help_text=u'群组唯一标识', db_index=True)
234
+    session_id = models.CharField(_(u'session_id'), max_length=255, blank=True, null=True, help_text=u'照片组唯一标识,同 PhotosInfo 表', db_index=True)
234 235
     user_id = models.CharField(_(u'user_id'), max_length=255, blank=True, null=True, help_text=u'用户唯一标识', db_index=True)
235 236
     photo_id = models.CharField(_(u'photo_id'), max_length=255, blank=True, null=True, help_text=u'照片唯一标识', db_index=True)
237
+    lensman_photo_id = models.CharField(_(u'lensman_photo_id'), max_length=255, blank=True, null=True, help_text=u'摄影师照片唯一标识,同 PhotosInfo 表', db_index=True)
236 238
 
237
-    m_photo_path = models.CharField(_(u'm_photo_path'), max_length=255, blank=True, null=True, help_text=u'照片存放路径,控制器上传,无水印')
239
+    m_photo_path = models.CharField(_(u'm_photo_path'), max_length=255, blank=True, null=True, help_text=u'照片存放路径,Box上传,无水印')
238 240
     l_photo_path = models.CharField(_(u'l_photo_path'), max_length=255, blank=True, null=True, help_text=u'照片存放路径,美化大图')
239 241
     r_photo_path = models.CharField(_(u'r_photo_path'), max_length=255, blank=True, null=True, help_text=u'照片存放路径,高清大图')
240 242
 

+ 2 - 2
pay/admin.py

@@ -6,8 +6,8 @@ from pay.models import OrderInfo
6 6
 
7 7
 
8 8
 class OrderInfoAdmin(admin.ModelAdmin):
9
-    list_display = ('order_id', 'from_uid', 'to_uid', 'pay_status', 'paid_at', 'status', 'created_at', 'updated_at')
10
-    list_filter = ('pay_status', 'status')
9
+    list_display = ('order_id', 'photo_type', 'photo_status', 'from_uid', 'to_uid', 'pay_status', 'paid_at', 'reback_status', 'reback_at', 'status', 'created_at', 'updated_at')
10
+    list_filter = ('photo_type', 'photo_status', 'pay_status', 'reback_status', 'status')
11 11
 
12 12
 
13 13
 admin.site.register(OrderInfo, OrderInfoAdmin)

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

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

+ 23 - 2
pay/models.py

@@ -1,6 +1,5 @@
1 1
 # -*- coding: utf-8 -*-
2 2
 
3
-from django.conf import settings
4 3
 from django.db import models
5 4
 from django.utils.translation import ugettext_lazy as _
6 5
 from shortuuidfield import ShortUUIDField
@@ -18,6 +17,16 @@ class OrderInfo(CreateUpdateMixin):
18 17
         (ORIGIN, u'获取高清图'),
19 18
     )
20 19
 
20
+    WANTED = 0
21
+    FETCHED = 1
22
+    DELETED = 2
23
+
24
+    PHOTO_STATUS = (
25
+        (WANTED, u'待上传'),
26
+        (FETCHED, u'已上传'),
27
+        (DELETED, u'已删除'),
28
+    )
29
+
21 30
     """
22 31
     # Trade State of Wechat Query
23 32
     SUCCESS ——— 支付成功
@@ -44,10 +53,12 @@ class OrderInfo(CreateUpdateMixin):
44 53
     order_id = ShortUUIDField(_(u'order_id'), max_length=255, help_text=u'订单唯一标识', db_index=True)
45 54
 
46 55
     group_id = models.CharField(_(u'group_id'), max_length=255, blank=True, null=True, help_text=u'群组唯一标识', db_index=True)
56
+    session_id = models.CharField(_(u'session_id'), max_length=255, blank=True, null=True, help_text=u'照片组唯一标识,同 PhotosInfo 表', db_index=True)
47 57
     photo_id = models.CharField(_(u'photo_id'), max_length=255, blank=True, null=True, help_text=u'飞图唯一标识', db_index=True)
48 58
     lensman_photo_id = models.CharField(_(u'lensman_photo_id'), max_length=255, blank=True, null=True, help_text=u'摄影师照片唯一标识,同 PhotosInfo 表', db_index=True)
49 59
 
50
-    photo_type = models.IntegerField(_('photo_type'), choices=PHOTO_TYPE, default=NOMARK, help_text=u'购买照片类型')
60
+    photo_type = models.IntegerField(_('photo_type'), choices=PHOTO_TYPE, default=NOMARK, help_text=u'购买照片类型', db_index=True)
61
+    photo_status = models.IntegerField(_(u'photo_status'), choices=PHOTO_STATUS, default=WANTED, help_text=_(u'购买照片状态, 标识用户是否已经获得照片'), db_index=True)
51 62
 
52 63
     from_uid = models.CharField(_(u'from_uid'), max_length=255, help_text=u'付款用户唯一标识', db_index=True)
53 64
     to_uid = models.CharField(_(u'to_uid'), max_length=255, blank=True, null=True, help_text=u'收款用户唯一标识', db_index=True)
@@ -60,6 +71,9 @@ class OrderInfo(CreateUpdateMixin):
60 71
     pay_status = models.IntegerField(_(u'pay_status'), choices=PAY_STATUS, default=WAITING_PAY, help_text=u'支付状态', db_index=True)
61 72
     paid_at = models.DateTimeField(_(u'paid_at'), blank=True, null=True, help_text=_(u'支付时间'))
62 73
 
74
+    reback_status = models.BooleanField(_(u'reback_status'), default=False, help_text=u'退款状态', db_index=True)
75
+    reback_at = models.DateTimeField(_(u'reback_at'), blank=True, null=True, help_text=_(u'退款时间'))
76
+
63 77
     class Meta:
64 78
         verbose_name = _('orderinfo')
65 79
         verbose_name_plural = _('orderinfo')
@@ -85,3 +99,10 @@ class OrderInfo(CreateUpdateMixin):
85 99
             'paid_at': self.paid_at and self.paid_at.replace(microsecond=0),
86 100
             'created_at': self.created_at.replace(microsecond=0),
87 101
         }
102
+
103
+    @property
104
+    def lensdata(self):
105
+        return {
106
+            'session_id': self.session_id,
107
+            'photo_id': self.lensman_photo_id
108
+        }

+ 5 - 0
pay/views.py

@@ -70,6 +70,7 @@ def wx_order_create_api(request):
70 70
         photo_type=1 if photo_type == 'origin' else 0,
71 71
         from_uid=from_uid,
72 72
         to_uid=to_uid,
73
+        session_id=group_photo.session_id,
73 74
         total_fee=total_fee,
74 75
         trade_type=trade_type,
75 76
     )
@@ -103,14 +104,18 @@ def order_paid_success(order):
103 104
     if order.pay_status == OrderInfo.PAID:
104 105
         return
105 106
 
107
+    if order.photo_type == OrderInfo.NOMARK:
108
+        order.photo_status = OrderInfo.FETCHED
106 109
     order.pay_status = OrderInfo.PAID
107 110
     order.paid_at = tc.utc_datetime()
108 111
     order.save()
109 112
 
110 113
     porder, created = GroupPhotoOrderInfo.objects.get_or_create(
111 114
         group_id=order.group_id,
115
+        session_id=order.session_id,
112 116
         user_id=order.from_uid,
113 117
         photo_id=order.photo_id,
118
+        lensman_photo_id=order.lensman_photo_id,
114 119
     )
115 120
     photo = PhotosInfo.objects.get(
116 121
         photo_id=order.lensman_photo_id,

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

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

+ 2 - 2
photo/models.py

@@ -33,8 +33,8 @@ class PhotosInfo(CreateUpdateMixin):
33 33
     lensman_id = models.CharField(_(u'lensman_id'), max_length=255, blank=True, null=True, help_text=u'摄影师唯一标识', db_index=True)
34 34
     session_id = models.CharField(_(u'session_id'), max_length=255, blank=True, null=True, help_text=u'照片组唯一标识', db_index=True)
35 35
     photo_id = models.CharField(_(u'photo_id'), max_length=255, blank=True, null=True, help_text=u'照片唯一标识', db_index=True, unique=True)
36
-    p_photo_path = models.CharField(_(u'p_photo_path'), max_length=255, blank=True, null=True, help_text=u'照片存放路径,控制器上传,有水印,服务器添加')
37
-    m_photo_path = models.CharField(_(u'm_photo_path'), max_length=255, blank=True, null=True, help_text=u'照片存放路径,控制器上传,无水印')
36
+    p_photo_path = models.CharField(_(u'p_photo_path'), max_length=255, blank=True, null=True, help_text=u'照片存放路径,Box上传,有水印,服务器添加')
37
+    m_photo_path = models.CharField(_(u'm_photo_path'), max_length=255, blank=True, null=True, help_text=u'照片存放路径,Box上传,无水印')
38 38
     l_photo_path = models.CharField(_(u'l_photo_path'), max_length=255, blank=True, null=True, help_text=u'照片存放路径,美化大图')
39 39
     r_photo_path = models.CharField(_(u'r_photo_path'), max_length=255, blank=True, null=True, help_text=u'照片存放路径,高清大图')
40 40