@@ -4,7 +4,7 @@ from curtail_uuid import CurtailUUID |
||
4 | 4 |
from django.contrib import admin |
5 | 5 |
from django.contrib.auth.hashers import make_password |
6 | 6 |
|
7 |
-from account.models import LensmanInfo, LensmanLoginLogInfo, UserInfo, UserLoginLogInfo |
|
7 |
+from account.models import LensmanIncomeExpensesInfo, LensmanInfo, LensmanLoginLogInfo, UserIncomeExpensesInfo, UserInfo, UserLoginLogInfo |
|
8 | 8 |
|
9 | 9 |
|
10 | 10 |
class LensmanInfoAdmin(admin.ModelAdmin): |
@@ -26,18 +26,30 @@ class LensmanLoginLogInfoAdmin(admin.ModelAdmin): |
||
26 | 26 |
list_display = ('lensman_id', 'login_ip', 'login_result', 'status', 'created_at', 'updated_at') |
27 | 27 |
|
28 | 28 |
|
29 |
+class LensmanIncomeExpensesInfoAdmin(admin.ModelAdmin): |
|
30 |
+ list_display = ('lensman_id', 'photo_id', 'type', 'amount', 'balance', 'remark', 'status', 'created_at', 'updated_at') |
|
31 |
+ list_filter = ('type', 'status') |
|
32 |
+ |
|
33 |
+ |
|
29 | 34 |
class UserInfoAdmin(admin.ModelAdmin): |
30 | 35 |
readonly_fields = ('user_id', ) |
31 |
- list_display = ('user_id', 'username', 'wx_uid', 'name', 'sex', 'phone', 'location', 'user_status', 'status', 'created_at', 'updated_at') |
|
36 |
+ list_display = ('user_id', 'user_from', 'username', 'wx_uid', 'name', 'sex', 'phone', 'location', 'user_status', 'status', 'created_at', 'updated_at') |
|
32 | 37 |
search_fields = ('name', 'phone', 'location') |
33 |
- list_filter = ('sex', 'status', 'user_status') |
|
38 |
+ list_filter = ('user_from', 'sex', 'user_status', 'status') |
|
34 | 39 |
|
35 | 40 |
|
36 | 41 |
class UserLoginLogInfoAdmin(admin.ModelAdmin): |
37 | 42 |
list_display = ('user_id', 'login_ip', 'login_result', 'status', 'created_at', 'updated_at') |
38 | 43 |
|
39 | 44 |
|
45 |
+class UserIncomeExpensesInfoAdmin(admin.ModelAdmin): |
|
46 |
+ list_display = ('user_id', 'photo_id', 'type', 'amount', 'balance', 'remark', 'status', 'created_at', 'updated_at') |
|
47 |
+ list_filter = ('type', 'status') |
|
48 |
+ |
|
49 |
+ |
|
40 | 50 |
admin.site.register(LensmanInfo, LensmanInfoAdmin) |
41 |
-admin.site.register(UserInfo, UserInfoAdmin) |
|
42 | 51 |
admin.site.register(LensmanLoginLogInfo, LensmanLoginLogInfoAdmin) |
52 |
+admin.site.register(LensmanIncomeExpensesInfo, LensmanIncomeExpensesInfoAdmin) |
|
53 |
+admin.site.register(UserInfo, UserInfoAdmin) |
|
43 | 54 |
admin.site.register(UserLoginLogInfo, UserLoginLogInfoAdmin) |
55 |
+admin.site.register(UserIncomeExpensesInfo, UserIncomeExpensesInfoAdmin) |
@@ -0,0 +1,72 @@ |
||
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 |
+ ('account', '0008_userinfo_unionid'), |
|
11 |
+ ] |
|
12 |
+ |
|
13 |
+ operations = [ |
|
14 |
+ migrations.CreateModel( |
|
15 |
+ name='LensmanIncomeExpensesInfo', |
|
16 |
+ fields=[ |
|
17 |
+ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), |
|
18 |
+ ('status', models.BooleanField(default=True, help_text='\u72b6\u6001', db_index=True, verbose_name='status')), |
|
19 |
+ ('created_at', models.DateTimeField(help_text='\u521b\u5efa\u65f6\u95f4', verbose_name='created_at', auto_now_add=True)), |
|
20 |
+ ('updated_at', models.DateTimeField(help_text='\u66f4\u65b0\u65f6\u95f4', verbose_name='updated_at', auto_now=True)), |
|
21 |
+ ('lensman_id', models.CharField(max_length=255, blank=True, help_text='\u6444\u5f71\u5e08\u552f\u4e00\u6807\u8bc6', null=True, verbose_name='lensman_id', db_index=True)), |
|
22 |
+ ('photo_id', models.CharField(max_length=255, blank=True, help_text='\u7167\u7247\u552f\u4e00\u6807\u8bc6', null=True, verbose_name='photo_id', db_index=True)), |
|
23 |
+ ('type', models.IntegerField(default=0, help_text='\u6536\u652f\u7c7b\u522b', verbose_name='type', choices=[(0, '\u6536\u5165'), (1, '\u652f\u51fa')])), |
|
24 |
+ ('amount', models.IntegerField(default=0, help_text='\u4f59\u989d\u589e\u51cf\u6570\u91cf(\u5206)', verbose_name='amount')), |
|
25 |
+ ('balance', models.IntegerField(default=0, help_text='\u4f59\u989d\u589e\u51cf\u540e\u6570\u91cf(\u5206)', verbose_name='balance')), |
|
26 |
+ ('remark', models.CharField(help_text='\u5907\u6ce8', max_length=255, null=True, verbose_name='remark', blank=True)), |
|
27 |
+ ], |
|
28 |
+ options={ |
|
29 |
+ 'verbose_name': 'lensmanincomeexpensesinfo', |
|
30 |
+ 'verbose_name_plural': 'lensmanincomeexpensesinfo', |
|
31 |
+ }, |
|
32 |
+ ), |
|
33 |
+ migrations.CreateModel( |
|
34 |
+ name='UserIncomeExpensesInfo', |
|
35 |
+ fields=[ |
|
36 |
+ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), |
|
37 |
+ ('status', models.BooleanField(default=True, help_text='\u72b6\u6001', db_index=True, verbose_name='status')), |
|
38 |
+ ('created_at', models.DateTimeField(help_text='\u521b\u5efa\u65f6\u95f4', verbose_name='created_at', auto_now_add=True)), |
|
39 |
+ ('updated_at', models.DateTimeField(help_text='\u66f4\u65b0\u65f6\u95f4', verbose_name='updated_at', auto_now=True)), |
|
40 |
+ ('user_id', models.CharField(max_length=255, blank=True, help_text='\u7528\u6237\u552f\u4e00\u6807\u8bc6', null=True, verbose_name='user_id', db_index=True)), |
|
41 |
+ ('photo_id', models.CharField(max_length=255, blank=True, help_text='\u7167\u7247\u552f\u4e00\u6807\u8bc6', null=True, verbose_name='photo_id', db_index=True)), |
|
42 |
+ ('type', models.IntegerField(default=0, help_text='\u6536\u652f\u7c7b\u522b', verbose_name='type', choices=[(0, '\u6536\u5165'), (1, '\u652f\u51fa')])), |
|
43 |
+ ('amount', models.IntegerField(default=0, help_text='\u4f59\u989d\u589e\u51cf\u6570\u91cf(\u5206)', verbose_name='amount')), |
|
44 |
+ ('balance', models.IntegerField(default=0, help_text='\u4f59\u989d\u589e\u51cf\u540e\u6570\u91cf(\u5206)', verbose_name='balance')), |
|
45 |
+ ('remark', models.CharField(help_text='\u5907\u6ce8', max_length=255, null=True, verbose_name='remark', blank=True)), |
|
46 |
+ ], |
|
47 |
+ options={ |
|
48 |
+ 'verbose_name': 'userincomeexpensesinfo', |
|
49 |
+ 'verbose_name_plural': 'userincomeexpensesinfo', |
|
50 |
+ }, |
|
51 |
+ ), |
|
52 |
+ migrations.AddField( |
|
53 |
+ model_name='lensmaninfo', |
|
54 |
+ name='balance', |
|
55 |
+ field=models.IntegerField(default=0, help_text='\u6444\u5f71\u5e08\u4f59\u989d(\u5206)', verbose_name='balance'), |
|
56 |
+ ), |
|
57 |
+ migrations.AddField( |
|
58 |
+ model_name='userinfo', |
|
59 |
+ name='balance', |
|
60 |
+ field=models.IntegerField(default=0, help_text='\u7528\u6237\u4f59\u989d(\u5206)', verbose_name='balance'), |
|
61 |
+ ), |
|
62 |
+ migrations.AlterField( |
|
63 |
+ model_name='lensmaninfo', |
|
64 |
+ name='proportion', |
|
65 |
+ field=models.FloatField(default=1.0, help_text='\u6444\u5f71\u5e08\u5206\u6210\u6bd4\u4f8b(0.0 ~ 1.0)', verbose_name='proportion'), |
|
66 |
+ ), |
|
67 |
+ migrations.AlterField( |
|
68 |
+ model_name='userinfo', |
|
69 |
+ name='user_from', |
|
70 |
+ field=models.IntegerField(default=0, help_text='\u7528\u6237\u6765\u6e90', verbose_name='user_from', choices=[(0, 'APP \u521b\u5efa\u7528\u6237'), (1, '\u5fae\u4fe1\u6388\u6743\u7528\u6237'), (9, '\u6e38\u5ba2\u7528\u6237')]), |
|
71 |
+ ), |
|
72 |
+ ] |
@@ -26,7 +26,9 @@ class LensmanInfo(CreateUpdateMixin): |
||
26 | 26 |
phone = models.CharField(_(u'phone'), max_length=255, blank=True, null=True, help_text=u'摄影师电话', db_index=True, unique=True) |
27 | 27 |
location = models.CharField(_(u'location'), max_length=255, blank=True, null=True, help_text=u'摄影师地址') |
28 | 28 |
|
29 |
- proportion = models.FloatField(_(u'proportion'), default=1.0, help_text=u'摄影师分成比例(0.0 ~ 1.0)') |
|
29 |
+ proportion = models.FloatField(_(u'proportion'), default=1.0, help_text=u'摄影师分成比例(0.0 ~ 1.0)') |
|
30 |
+ |
|
31 |
+ balance = models.IntegerField(_(u'balance'), default=0, help_text=u'摄影师余额(分)') |
|
30 | 32 |
|
31 | 33 |
signup_ip = models.CharField(_(u'signup_ip'), max_length=255, blank=True, null=True, help_text=_(u'注册IP')) |
32 | 34 |
login_ip = models.CharField(_(u'login_ip'), max_length=255, blank=True, null=True, help_text=_(u'登录IP')) |
@@ -63,13 +65,41 @@ class LensmanLoginLogInfo(CreateUpdateMixin): |
||
63 | 65 |
return unicode(self.pk) |
64 | 66 |
|
65 | 67 |
|
68 |
+class LensmanIncomeExpensesInfo(CreateUpdateMixin): |
|
69 |
+ INCOME = 0 |
|
70 |
+ EXPENSE = 1 |
|
71 |
+ |
|
72 |
+ TYPE = ( |
|
73 |
+ (INCOME, u'收入'), |
|
74 |
+ (EXPENSE, u'支出'), |
|
75 |
+ ) |
|
76 |
+ |
|
77 |
+ lensman_id = models.CharField(_(u'lensman_id'), max_length=255, blank=True, null=True, help_text=u'摄影师唯一标识', db_index=True) |
|
78 |
+ photo_id = models.CharField(_(u'photo_id'), max_length=255, blank=True, null=True, help_text=u'照片唯一标识', db_index=True) |
|
79 |
+ |
|
80 |
+ type = models.IntegerField(_(u'type'), choices=TYPE, default=INCOME, help_text=u'收支类别') |
|
81 |
+ amount = models.IntegerField(_(u'amount'), default=0, help_text=u'余额增减数量(分)') |
|
82 |
+ balance = models.IntegerField(_(u'balance'), default=0, help_text=u'余额增减后数量(分)') |
|
83 |
+ |
|
84 |
+ remark = models.CharField(_(u'remark'), max_length=255, blank=True, null=True, help_text=u'备注') |
|
85 |
+ |
|
86 |
+ class Meta: |
|
87 |
+ verbose_name = _(u'lensmanincomeexpensesinfo') |
|
88 |
+ verbose_name_plural = _(u'lensmanincomeexpensesinfo') |
|
89 |
+ |
|
90 |
+ def __unicode__(self): |
|
91 |
+ return unicode(self.pk) |
|
92 |
+ |
|
93 |
+ |
|
66 | 94 |
class UserInfo(CreateUpdateMixin): |
67 | 95 |
APP_USER = 0 |
68 | 96 |
WX_USER = 1 |
97 |
+ GUEST_USER = 9 |
|
69 | 98 |
|
70 | 99 |
USER_FROM = ( |
71 | 100 |
(APP_USER, u'APP 创建用户'), |
72 | 101 |
(WX_USER, u'微信授权用户'), |
102 |
+ (GUEST_USER, u'游客用户'), |
|
73 | 103 |
) |
74 | 104 |
|
75 | 105 |
UNVERIFIED = 0 |
@@ -115,6 +145,8 @@ class UserInfo(CreateUpdateMixin): |
||
115 | 145 |
city = models.CharField(_(u'city'), max_length=255, blank=True, null=True, help_text=u'用户城市') |
116 | 146 |
location = models.CharField(_(u'location'), max_length=255, blank=True, null=True, help_text=u'用户地址') |
117 | 147 |
|
148 |
+ balance = models.IntegerField(_(u'balance'), default=0, help_text=u'用户余额(分)') |
|
149 |
+ |
|
118 | 150 |
user_status = models.IntegerField(_(u'user_status'), choices=USER_STATUS, default=UNVERIFIED) |
119 | 151 |
|
120 | 152 |
assign_ip = models.CharField(_(u'assign_ip'), max_length=255, blank=True, null=True, help_text=_(u'分配IP')) |
@@ -170,3 +202,29 @@ class UserLoginLogInfo(CreateUpdateMixin): |
||
170 | 202 |
|
171 | 203 |
def __unicode__(self): |
172 | 204 |
return unicode(self.pk) |
205 |
+ |
|
206 |
+ |
|
207 |
+class UserIncomeExpensesInfo(CreateUpdateMixin): |
|
208 |
+ INCOME = 0 |
|
209 |
+ EXPENSE = 1 |
|
210 |
+ |
|
211 |
+ TYPE = ( |
|
212 |
+ (INCOME, u'收入'), |
|
213 |
+ (EXPENSE, u'支出'), |
|
214 |
+ ) |
|
215 |
+ |
|
216 |
+ user_id = models.CharField(_(u'user_id'), max_length=255, blank=True, null=True, help_text=u'用户唯一标识', db_index=True) |
|
217 |
+ photo_id = models.CharField(_(u'photo_id'), max_length=255, blank=True, null=True, help_text=u'照片唯一标识', db_index=True) |
|
218 |
+ |
|
219 |
+ type = models.IntegerField(_(u'type'), choices=TYPE, default=INCOME, help_text=u'收支类别') |
|
220 |
+ amount = models.IntegerField(_(u'amount'), default=0, help_text=u'余额增减数量(分)') |
|
221 |
+ balance = models.IntegerField(_(u'balance'), default=0, help_text=u'余额增减后数量(分)') |
|
222 |
+ |
|
223 |
+ remark = models.CharField(_(u'remark'), max_length=255, blank=True, null=True, help_text=u'备注') |
|
224 |
+ |
|
225 |
+ class Meta: |
|
226 |
+ verbose_name = _(u'userincomeexpensesinfo') |
|
227 |
+ verbose_name_plural = _(u'userincomeexpensesinfo') |
|
228 |
+ |
|
229 |
+ def __unicode__(self): |
|
230 |
+ return unicode(self.pk) |
@@ -1,6 +1,7 @@ |
||
1 | 1 |
# -*- coding: utf-8 -*- |
2 | 2 |
|
3 | 3 |
from curtail_uuid import CurtailUUID |
4 |
+from django.conf import settings |
|
4 | 5 |
from django.contrib.auth.hashers import check_password, make_password |
5 | 6 |
from django.contrib.auth.models import Group, User |
6 | 7 |
from django.http import JsonResponse |
@@ -207,6 +208,19 @@ def wx_authorize_api(request): |
||
207 | 208 |
}) |
208 | 209 |
|
209 | 210 |
|
211 |
+def guest_login_api(request): |
|
212 |
+ try: |
|
213 |
+ user = UserInfo.objects.get(user_id=settings.GUEST_USER_ID) |
|
214 |
+ except UserInfo.DoesNotExist: |
|
215 |
+ return response(UserStatusCode.GUEST_NOT_FOUND) |
|
216 |
+ |
|
217 |
+ return JsonResponse({ |
|
218 |
+ 'status': 200, |
|
219 |
+ 'message': u'Guest 登录成功', |
|
220 |
+ 'data': user.data, |
|
221 |
+ }) |
|
222 |
+ |
|
223 |
+ |
|
210 | 224 |
class UserViewSet(viewsets.ModelViewSet): |
211 | 225 |
""" |
212 | 226 |
API endpoint that allows users to be viewed or edited. |
@@ -18,6 +18,8 @@ urlpatterns = [ |
||
18 | 18 |
url(r'^u/login$', account_views.user_login_api, name='user_login_api'), # 用户登录 |
19 | 19 |
|
20 | 20 |
url(r'^u/wx/authorize$', account_views.wx_authorize_api, name='wx_authorize_api'), # 微信用户授权 |
21 |
+ |
|
22 |
+ url(r'^u/guest$', account_views.guest_login_api, name='guest_login_api'), # 游客登录 |
|
21 | 23 |
] |
22 | 24 |
|
23 | 25 |
# 群组相关 |
@@ -225,6 +225,7 @@ WECHAT_GET_OAUTH2_ACCESS_TOKEN = 'https://api.weixin.qq.com/sns/oauth2/access_to |
||
225 | 225 |
|
226 | 226 |
WECHAT_GET_USERINFO = 'https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s' |
227 | 227 |
|
228 |
+# 微信支付设置 |
|
228 | 229 |
WXPAY_NOTIFY_SUCCESS = '<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>' |
229 | 230 |
WXPAY_NOTIFY_FAIL = '<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[XML PARSE FAIL]]></return_msg></xml>' |
230 | 231 |
|
@@ -250,6 +251,9 @@ PAI2_HOME_MAX_ROWS = 400 # 首页照片最大数量, PAI2_HOME_PER_PAGE * PAI2_ |
||
250 | 251 |
# 群组设置 |
251 | 252 |
GROUP_PER_PAGE = 20 # 群组每页数量 |
252 | 253 |
|
254 |
+# 游客设置 |
|
255 |
+GUEST_USER_ID = 'guest' |
|
256 |
+ |
|
253 | 257 |
# 价格设置 |
254 | 258 |
LENSMAN_PHOTO_HAGGLE_MAX_TIMES = 3 # 摄影师照片最大砍价次数 |
255 | 259 |
|
@@ -26,6 +26,8 @@ class UserStatusCode(BaseStatusCode): |
||
26 | 26 |
USER_PASSWORD_ERROR = StatusCodeField(400102, u'User Password Error', description=u'用户密码错误') |
27 | 27 |
USERNAME_HAS_REGISTERED = StatusCodeField(400103, u'Username Has Registered', description=u'用户名已注册') |
28 | 28 |
|
29 |
+ GUEST_NOT_FOUND = StatusCodeField(400111, u'Guest Not Found', description=u'游客不存在') |
|
30 |
+ |
|
29 | 31 |
|
30 | 32 |
class PhotoStatusCode(BaseStatusCode): |
31 | 33 |
""" 照片相关错误码 4010xx """ |