@@ -229,7 +229,8 @@ urlpatterns += [ |
||
| 229 | 229 |
url(r'^clerk/submit$', oauth_views.clerk_submit_api, name='clerk_submit_api'), # 店员信息提交 |
| 230 | 230 |
url(r'^clerk/sale/decrypt$', sale_views.clerk_sale_decrypt_api, name='clerk_sale_decrypt_api'), |
| 231 | 231 |
url(r'^clerk/sale/submit$', sale_views.clerk_sale_submit_api, name='clerk_sale_submit_api'), # 店员销售信息提交 |
| 232 |
- url(r'^clerk/integral/list$', sale_views.clerk_integral_list_api, name='clerk_integral_list_api'), # 店员销售积分列表 |
|
| 232 |
+ url(r'^clerk/integral/list$', sale_views.clerk_integral_list_api, name='clerk_integral_list_api'), # |
|
| 233 |
+ url(r'^clerk/consumer/impression$', sale_views.clerk_consumer_impression_api, name='clerk_consumer_impression_api'), |
|
| 233 | 234 |
] |
| 234 | 235 |
|
| 235 | 236 |
urlpatterns += [ |
@@ -4,7 +4,7 @@ from django.db import models |
||
| 4 | 4 |
from django.utils.translation import ugettext_lazy as _ |
| 5 | 5 |
from django_models_ext import BaseModelMixin, upload_path |
| 6 | 6 |
|
| 7 |
-from mch.models import ModelInfo |
|
| 7 |
+from mch.models import ConsumeImpressionInfo, ModelInfo |
|
| 8 | 8 |
|
| 9 | 9 |
|
| 10 | 10 |
class SaleclerkIntegralIncomeExpensesInfo(BaseModelMixin): |
@@ -64,12 +64,21 @@ class SaleclerkIntegralIncomeExpensesInfo(BaseModelMixin): |
||
| 64 | 64 |
return info |
| 65 | 65 |
|
| 66 | 66 |
@property |
| 67 |
+ def consumer_impression(self): |
|
| 68 |
+ try: |
|
| 69 |
+ impression = ConsumeImpressionInfo.objects.get(clerk_id=self.clerk_id, model_id=self.clerk_id, brand_id=self.brand_id, serialNo=self.code) |
|
| 70 |
+ except ConsumeImpressionInfo.DoesNotExist: |
|
| 71 |
+ impression = None |
|
| 72 |
+ return impression.data if impression else {}
|
|
| 73 |
+ |
|
| 74 |
+ @property |
|
| 67 | 75 |
def data(self): |
| 68 | 76 |
return {
|
| 69 | 77 |
'type': self.type, |
| 70 | 78 |
'integral': self.integral, |
| 71 | 79 |
'model_info': self.model_info, |
| 72 | 80 |
'modelName': self.model_name, |
| 81 |
+ 'consumer_impression': self.consumer_impression, |
|
| 73 | 82 |
'serialNo': self.code, |
| 74 | 83 |
'created_at': self.created_at, |
| 75 | 84 |
} |
@@ -8,7 +8,7 @@ from django_admin import AdvancedActionsModelAdmin, AdvancedExportExcelModelAdmi |
||
| 8 | 8 |
from django_models_ext import ProvinceShortModelMixin |
| 9 | 9 |
from pysnippets.strsnippets import strip |
| 10 | 10 |
|
| 11 |
-from mch.models import (ActivityInfo, AdministratorInfo, BrandInfo, ConsumeInfoSubmitLogInfo, DistributorInfo, |
|
| 11 |
+from mch.models import (ActivityInfo, AdministratorInfo, BrandInfo, ConsumeInfoSubmitLogInfo, ConsumeImpressionInfo, DistributorInfo, |
|
| 12 | 12 |
LatestAppInfo, LatestAppScreenInfo, ModelInfo, OperatorInfo, SaleclerkInfo) |
| 13 | 13 |
|
| 14 | 14 |
|
@@ -179,6 +179,11 @@ class LatestAppScreenInfoAdmin(admin.ModelAdmin): |
||
| 179 | 179 |
obj.save() |
| 180 | 180 |
|
| 181 | 181 |
|
| 182 |
+class ConsumeImpressionInfoAdmin(ReadOnlyModelAdmin, admin.ModelAdmin): |
|
| 183 |
+ list_display = ('clerk_id', 'brand_id', 'model_id', 'serialNo', 'sex', 'rage', 'identity', 'purpose', 'status', 'created_at', 'updated_at')
|
|
| 184 |
+ list_filter = ('sex', 'rage', 'status')
|
|
| 185 |
+ |
|
| 186 |
+ |
|
| 182 | 187 |
class ConsumeInfoSubmitLogInfoAdmin(ReadOnlyModelAdmin, admin.ModelAdmin): |
| 183 | 188 |
list_display = ('user_id', 'phone', 'lat', 'lon', 'serialNo', 'verifyResult', 'dupload', 'test_user', 'submit_during_activity', 'activity_id', 'coupon_expire_at', 'coupon_value', 'has_used', 'status', 'created_at', 'updated_at')
|
| 184 | 189 |
list_filter = ('brand_id', 'submit_during_activity', 'activity_id', 'dupload', 'test_user', 'verifyResult', 'has_used', 'status')
|
@@ -200,5 +205,6 @@ admin.site.register(SaleclerkInfo, SaleclerkInfoAdmin) |
||
| 200 | 205 |
# admin.site.register(BrandModelDistributorPriceInfo, BrandModelDistributorPriceInfoAdmin) |
| 201 | 206 |
admin.site.register(LatestAppInfo, LatestAppInfoAdmin) |
| 202 | 207 |
admin.site.register(LatestAppScreenInfo, LatestAppScreenInfoAdmin) |
| 208 |
+admin.site.register(ConsumeImpressionInfo, ConsumeImpressionInfoAdmin) |
|
| 203 | 209 |
admin.site.register(ConsumeInfoSubmitLogInfo, ConsumeInfoSubmitLogInfoAdmin) |
| 204 | 210 |
admin.site.register(ActivityInfo, ActivityInfoAdmin) |
@@ -0,0 +1,36 @@ |
||
| 1 |
+# -*- coding: utf-8 -*- |
|
| 2 |
+# Generated by Django 1.11.22 on 2019-07-21 15:19 |
|
| 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', '0038_modelinfo_image4'),
|
|
| 12 |
+ ] |
|
| 13 |
+ |
|
| 14 |
+ operations = [ |
|
| 15 |
+ migrations.CreateModel( |
|
| 16 |
+ name='ConsumeImpressionInfo', |
|
| 17 |
+ fields=[ |
|
| 18 |
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
|
| 19 |
+ ('status', models.BooleanField(db_index=True, 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 |
+ ('clerk_id', models.CharField(blank=True, db_index=True, help_text='\u5e97\u5458\u552f\u4e00\u6807\u8bc6', max_length=32, null=True, verbose_name='clerk_id')),
|
|
| 23 |
+ ('brand_id', models.CharField(blank=True, db_index=True, help_text='\u54c1\u724c\u552f\u4e00\u6807\u8bc6', max_length=32, null=True, verbose_name='brand_id')),
|
|
| 24 |
+ ('model_id', models.CharField(blank=True, db_index=True, help_text='\u578b\u53f7\u552f\u4e00\u6807\u8bc6', max_length=32, null=True, verbose_name='model_id')),
|
|
| 25 |
+ ('serialNo', models.CharField(blank=True, db_index=True, help_text='\u5e8f\u5217\u53f7', max_length=16, null=True, verbose_name='serialNo')),
|
|
| 26 |
+ ('sex', models.IntegerField(choices=[(0, '\u672a\u77e5'), (1, '\u7537'), (2, '\u5973')], default=0, help_text='\u6027\u522b', verbose_name='sex')),
|
|
| 27 |
+ ('rage', models.IntegerField(choices=[(0, '\u672a\u77e5'), (1, '20\u5c81\u4ee5\u4e0b'), (2, '20-40\u5c81'), (2, '40-60\u5c81'), (2, '60\u5c81\u4ee5\u4e0a')], default=0, help_text='\u5e74\u9f84\u6bb5', verbose_name='rage')),
|
|
| 28 |
+ ('identity', models.CharField(blank=True, help_text='\u8eab\u4efd', max_length=255, null=True, verbose_name='identity')),
|
|
| 29 |
+ ('purpose', models.CharField(blank=True, help_text='\u7528\u9014', max_length=255, null=True, verbose_name='purpose')),
|
|
| 30 |
+ ], |
|
| 31 |
+ options={
|
|
| 32 |
+ 'verbose_name': '\u5ba2\u6237\u5370\u8c61', |
|
| 33 |
+ 'verbose_name_plural': '\u5ba2\u6237\u5370\u8c61', |
|
| 34 |
+ }, |
|
| 35 |
+ ), |
|
| 36 |
+ ] |
@@ -410,6 +410,8 @@ class SaleclerkInfo(BaseModelMixin, SexModelMixin): |
||
| 410 | 410 |
'clerk_phone': self.clerk_phone, |
| 411 | 411 |
'num': self.num, |
| 412 | 412 |
'integral': self.integral, |
| 413 |
+ # TODO: |
|
| 414 |
+ 'month_integral': self.integral, |
|
| 413 | 415 |
'total_integral': self.total_integral, |
| 414 | 416 |
'status': self.user_status, |
| 415 | 417 |
'refused_reason': self.refused_reason, |
@@ -531,6 +533,58 @@ class LatestAppScreenInfo(BaseModelMixin): |
||
| 531 | 533 |
} |
| 532 | 534 |
|
| 533 | 535 |
|
| 536 |
+class ConsumeImpressionInfo(BaseModelMixin): |
|
| 537 |
+ UNKNOWN = 0 |
|
| 538 |
+ MALE = 1 |
|
| 539 |
+ FEMALE = 2 |
|
| 540 |
+ |
|
| 541 |
+ SEX_TUPLE = ( |
|
| 542 |
+ (UNKNOWN, u'未知'), |
|
| 543 |
+ (MALE, u'男'), |
|
| 544 |
+ (FEMALE, u'女'), |
|
| 545 |
+ ) |
|
| 546 |
+ |
|
| 547 |
+ LT20 = 1 |
|
| 548 |
+ GTE20LT40 = 2 |
|
| 549 |
+ GTE40LT60 = 2 |
|
| 550 |
+ GTE60 = 2 |
|
| 551 |
+ |
|
| 552 |
+ AGE_RANGE_TUPLE = ( |
|
| 553 |
+ (UNKNOWN, u'未知'), |
|
| 554 |
+ (LT20, u'20岁以下'), |
|
| 555 |
+ (GTE20LT40, u'20-40岁'), |
|
| 556 |
+ (GTE40LT60, u'40-60岁'), |
|
| 557 |
+ (GTE60, u'60岁以上'), |
|
| 558 |
+ ) |
|
| 559 |
+ |
|
| 560 |
+ clerk_id = models.CharField(_(u'clerk_id'), max_length=32, blank=True, null=True, help_text=u'店员唯一标识', db_index=True) |
|
| 561 |
+ |
|
| 562 |
+ brand_id = models.CharField(_(u'brand_id'), max_length=32, blank=True, null=True, help_text=u'品牌唯一标识', db_index=True) |
|
| 563 |
+ model_id = models.CharField(_(u'model_id'), max_length=32, blank=True, null=True, help_text=u'型号唯一标识', db_index=True) |
|
| 564 |
+ serialNo = models.CharField(_(u'serialNo'), max_length=16, blank=True, null=True, help_text=u'序列号', db_index=True) |
|
| 565 |
+ |
|
| 566 |
+ sex = models.IntegerField(_(u'sex'), choices=SEX_TUPLE, default=UNKNOWN, help_text=u'性别') |
|
| 567 |
+ rage = models.IntegerField(_(u'rage'), choices=AGE_RANGE_TUPLE, default=UNKNOWN, help_text=u'年龄段') |
|
| 568 |
+ identity = models.CharField(_(u'identity'), max_length=255, blank=True, null=True, help_text=u'身份') |
|
| 569 |
+ purpose = models.CharField(_(u'purpose'), max_length=255, blank=True, null=True, help_text=u'用途') |
|
| 570 |
+ |
|
| 571 |
+ class Meta: |
|
| 572 |
+ verbose_name = _(u'客户印象') |
|
| 573 |
+ verbose_name_plural = _(u'客户印象') |
|
| 574 |
+ |
|
| 575 |
+ def __unicode__(self): |
|
| 576 |
+ return unicode(self.pk) |
|
| 577 |
+ |
|
| 578 |
+ @property |
|
| 579 |
+ def data(self): |
|
| 580 |
+ return {
|
|
| 581 |
+ 'sex': self.sex, |
|
| 582 |
+ 'rage': self.rage, |
|
| 583 |
+ 'identity': self.identity, |
|
| 584 |
+ 'purpose': self.purpose, |
|
| 585 |
+ } |
|
| 586 |
+ |
|
| 587 |
+ |
|
| 534 | 588 |
class ConsumeInfoSubmitLogInfo(BaseModelMixin): |
| 535 | 589 |
user_id = models.CharField(_(u'user_id'), max_length=32, blank=True, null=True, help_text=u'用户唯一标识', db_index=True) |
| 536 | 590 |
|
@@ -12,7 +12,7 @@ from TimeConvert import TimeConvert as tc |
||
| 12 | 12 |
from account.models import UserInfo |
| 13 | 13 |
from logs.models import MchInfoDecryptLogInfo, MchInfoEncryptLogInfo |
| 14 | 14 |
from integral.models import SaleclerkIntegralIncomeExpensesInfo, SaleclerkSubmitLogInfo |
| 15 |
-from mch.models import ActivityInfo, BrandInfo, DistributorInfo, ModelInfo, SaleclerkInfo |
|
| 15 |
+from mch.models import ActivityInfo, BrandInfo, ConsumeImpressionInfo, DistributorInfo, ModelInfo, SaleclerkInfo |
|
| 16 | 16 |
from statistic.models import (DistributorSaleStatisticInfo, ModelSaleStatisticInfo, ProvinceSaleStatisticInfo, |
| 17 | 17 |
SaleclerkSaleStatisticInfo, SaleStatisticInfo) |
| 18 | 18 |
from utils.algorithm.b64 import b64_decrypt |
@@ -721,3 +721,43 @@ def clerk_integral_list_api(request): |
||
| 721 | 721 |
'integrals': integrals, |
| 722 | 722 |
'total_integral': clerk.integral, |
| 723 | 723 |
}) |
| 724 |
+ |
|
| 725 |
+ |
|
| 726 |
+@logit |
|
| 727 |
+def clerk_consumer_impression_api(request): |
|
| 728 |
+ user_id = request.POST.get('user_id', '')
|
|
| 729 |
+ brand_id = request.POST.get('brand_id', settings.KODO_DEFAULT_BRAND_ID)
|
|
| 730 |
+ model_id = request.POST.get('model_id', '')
|
|
| 731 |
+ serialNo = request.POST.get('SerialNo', '')
|
|
| 732 |
+ sex = request.POST.get('sex', 0)
|
|
| 733 |
+ rage = request.POST.get('rage', 0)
|
|
| 734 |
+ identity = request.POST.get('identity', '')
|
|
| 735 |
+ purpose = request.POST.get('purpose', '')
|
|
| 736 |
+ |
|
| 737 |
+ try: |
|
| 738 |
+ user = UserInfo.objects.get(user_id=user_id, status=True) |
|
| 739 |
+ except UserInfo.DoesNotExist: |
|
| 740 |
+ return response(SaleclerkStatusCode.CLERK_NOT_FOUND) |
|
| 741 |
+ |
|
| 742 |
+ try: |
|
| 743 |
+ brand = BrandInfo.objects.get(brand_id=brand_id) |
|
| 744 |
+ except BrandInfo.DoesNotExist: |
|
| 745 |
+ return response(ProductBrandStatusCode.BRAND_NOT_FOUND) |
|
| 746 |
+ |
|
| 747 |
+ try: |
|
| 748 |
+ clerk = SaleclerkInfo.objects.get(brand_id=brand.brand_id, unionid=user.unionid, status=True) |
|
| 749 |
+ except SaleclerkInfo.DoesNotExist: |
|
| 750 |
+ return response(SaleclerkStatusCode.CLERK_NOT_FOUND) |
|
| 751 |
+ |
|
| 752 |
+ ConsumeImpressionInfo.objects.create( |
|
| 753 |
+ clerk_id=clerk.clerk_id, |
|
| 754 |
+ brand_id=brand_id, |
|
| 755 |
+ model_id=model_id, |
|
| 756 |
+ serialNo=serialNo, |
|
| 757 |
+ sex=sex, |
|
| 758 |
+ rage=rage, |
|
| 759 |
+ identity=identity, |
|
| 760 |
+ purpose=purpose, |
|
| 761 |
+ ) |
|
| 762 |
+ |
|
| 763 |
+ return response() |