@@ -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 """ |