29
+                'verbose_name': '\u7ecf\u9500\u5546\u9500\u91cf\u7edf\u8ba1',
30
+                'verbose_name_plural': '\u7ecf\u9500\u5546\u9500\u91cf\u7edf\u8ba1',
31
+            },
32
+        ),
33
+        migrations.CreateModel(
34
+            name='ModelSaleStatisticInfo',
35
+            fields=[
36
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
37
+                ('status', models.BooleanField(db_index=True, default=True, help_text='Status', verbose_name='status')),
38
+                ('created_at', models.DateTimeField(auto_now_add=True, help_text='Create Time', verbose_name='created_at')),
39
+                ('updated_at', models.DateTimeField(auto_now=True, help_text='Update Time', verbose_name='updated_at')),
40
+                ('model_id', models.CharField(db_index=True, help_text='\u578b\u53f7\u552f\u4e00\u6807\u8bc6', max_length=32, verbose_name='model_id')),
41
+                ('model_name', models.CharField(blank=True, help_text='\u578b\u53f7\u540d\u79f0', max_length=255, null=True, verbose_name='model_name')),
42
+                ('ymd', models.CharField(blank=True, db_index=True, help_text='\u5e74\u6708\u65e5', max_length=8, null=True, verbose_name='ymd')),
43
+                ('num', models.IntegerField(default=0, help_text='\u6570\u91cf', verbose_name='num')),
44
+            ],
45
+            options={
46
+                'verbose_name': '\u578b\u53f7\u9500\u91cf\u7edf\u8ba1',
47
+                'verbose_name_plural': '\u578b\u53f7\u9500\u91cf\u7edf\u8ba1',
48
+            },
49
+        ),
50
+        migrations.CreateModel(
51
+            name='RegisterStatisticInfo',
52
+            fields=[
53
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
54
+                ('status', models.BooleanField(db_index=True, default=True, help_text='Status', verbose_name='status')),
55
+                ('created_at', models.DateTimeField(auto_now_add=True, help_text='Create Time', verbose_name='created_at')),
56
+                ('updated_at', models.DateTimeField(auto_now=True, help_text='Update Time', verbose_name='updated_at')),
57
+                ('ymd', models.CharField(blank=True, db_index=True, help_text='\u5e74\u6708\u65e5', max_length=8, null=True, verbose_name='ymd')),
58
+                ('num', models.IntegerField(default=0, help_text='\u6570\u91cf', verbose_name='num')),
59
+            ],
60
+            options={
61
+                'verbose_name': '\u6ce8\u518c\u7528\u6237\u7edf\u8ba1',
62
+                'verbose_name_plural': '\u6ce8\u518c\u7528\u6237\u7edf\u8ba1',
63
+            },
64
+        ),
65
+        migrations.CreateModel(
66
+            name='SaleStatisticInfo',
67
+            fields=[
68
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
69
+                ('status', models.BooleanField(db_index=True, default=True, help_text='Status', verbose_name='status')),
70
+                ('created_at', models.DateTimeField(auto_now_add=True, help_text='Create Time', verbose_name='created_at')),
71
+                ('updated_at', models.DateTimeField(auto_now=True, help_text='Update Time', verbose_name='updated_at')),
72
+                ('ymd', models.CharField(blank=True, db_index=True, help_text='\u5e74\u6708\u65e5', max_length=8, null=True, verbose_name='ymd')),
73
+                ('num', models.IntegerField(default=0, help_text='\u6570\u91cf', verbose_name='num')),
74
+            ],
75
+            options={
76
+                'verbose_name': '\u9500\u91cf\u7edf\u8ba1',
77
+                'verbose_name_plural': '\u9500\u91cf\u7edf\u8ba1',
78
+            },
79
+        ),
80
+    ]

+ 0 - 0
statistic/migrations/__init__.py


+ 89 - 0
statistic/models.py

@@ -0,0 +1,89 @@
1
+# -*- coding: utf-8 -*-
2
+
3
+from django.db import models
4
+from django.utils.translation import ugettext_lazy as _
5
+from django_models_ext import BaseModelMixin
6
+
7
+
8
+class RegisterStatisticInfo(BaseModelMixin):
9
+    ymd = models.CharField(_(u'ymd'), max_length=8, blank=True, null=True, help_text=u'年月日', db_index=True)  # 例:20171208, tc.local_string(format='%Y%m%d')
10
+    num = models.IntegerField(_(u'num'), default=0, help_text=u'数量')
11
+
12
+    class Meta:
13
+        verbose_name = _(u'注册用户统计')
14
+        verbose_name_plural = _(u'注册用户统计')
15
+
16
+    def __unicode__(self):
17
+        return unicode(self.pk)
18
+
19
+    @property
20
+    def data(self):
21
+        return {
22
+            'ymd': self.ymd,
23
+            'num': self.num,
24
+        }
25
+
26
+
27
+class SaleStatisticInfo(BaseModelMixin):
28
+    ymd = models.CharField(_(u'ymd'), max_length=8, blank=True, null=True, help_text=u'年月日', db_index=True)  # 例:20171208, tc.local_string(format='%Y%m%d')
29
+    num = models.IntegerField(_(u'num'), default=0, help_text=u'数量')
30
+
31
+    class Meta:
32
+        verbose_name = _(u'销量统计')
33
+        verbose_name_plural = _(u'销量统计')
34
+
35
+    def __unicode__(self):
36
+        return unicode(self.pk)
37
+
38
+    @property
39
+    def data(self):
40
+        return {
41
+            'ymd': self.ymd,
42
+            'num': self.num,
43
+        }
44
+
45
+
46
+class ModelSaleStatisticInfo(BaseModelMixin):
47
+    model_id = models.CharField(_(u'model_id'), max_length=32, help_text=u'型号唯一标识', db_index=True)
48
+    model_name = models.CharField(_(u'model_name'), max_length=255, blank=True, null=True, help_text=u'型号名称')
49
+    ymd = models.CharField(_(u'ymd'), max_length=8, blank=True, null=True, help_text=u'年月日', db_index=True)  # 例:20171208, tc.local_string(format='%Y%m%d')
50
+    num = models.IntegerField(_(u'num'), default=0, help_text=u'数量')
51
+
52
+    class Meta:
53
+        verbose_name = _(u'型号销量统计')
54
+        verbose_name_plural = _(u'型号销量统计')
55
+
56
+    def __unicode__(self):
57
+        return unicode(self.pk)
58
+
59
+    @property
60
+    def data(self):
61
+        return {
62
+            'model_id': self.model_id,
63
+            'model_name': self.model_name,
64
+            'ymd': self.ymd,
65
+            'num': self.num,
66
+        }
67
+
68
+
69
+class DistributorSaleStatisticInfo(BaseModelMixin):
70
+    distributor_id = models.CharField(_(u'distributor_id'), max_length=32, help_text=u'经销商唯一标识', db_index=True)
71
+    distributor_name = models.CharField(_(u'distributor_name'), max_length=255, blank=True, null=True, help_text=u'经销商名称')
72
+    ymd = models.CharField(_(u'ymd'), max_length=8, blank=True, null=True, help_text=u'年月日', db_index=True)  # 例:20171208, tc.local_string(format='%Y%m%d')
73
+    num = models.IntegerField(_(u'num'), default=0, help_text=u'数量')
74
+
75
+    class Meta:
76
+        verbose_name = _(u'经销商销量统计')
77
+        verbose_name_plural = _(u'经销商销量统计')
78
+
79
+    def __unicode__(self):
80
+        return unicode(self.pk)
81
+
82
+    @property
83
+    def data(self):
84
+        return {
85
+            'distributor_id': self.distributor_id,
86
+            'distributor_name': self.distributor_name,
87
+            'ymd': self.ymd,
88
+            'num': self.num,
89
+        }

+ 7 - 0
statistic/tests.py

@@ -0,0 +1,7 @@
1
+# -*- coding: utf-8 -*-
2
+from __future__ import unicode_literals
3
+
4
+from django.test import TestCase
5
+
6
+
7
+# Create your tests here.

+ 50 - 0
statistic/views.py

@@ -0,0 +1,50 @@
1
+# -*- coding: utf-8 -*-
2
+
3
+from django_logit import logit
4
+from django_response import response
5
+from TimeConvert import TimeConvert as tc
6
+
7
+from statistic.models import (DistributorSaleStatisticInfo, ModelSaleStatisticInfo, RegisterStatisticInfo,
8
+                              SaleStatisticInfo)
9
+
10
+
11
+@logit
12
+def tj_data(request):
13
+    ymd = tc.local_string(format='%Y%m%d')
14
+
15
+    # 注册用户统计 & 今日注册用户
16
+    try:
17
+        register_num = RegisterStatisticInfo.objects.get(ymd=ymd).num
18
+    except RegisterStatisticInfo.DoesNotExist:
19
+        register_num = 0
20
+
21
+    # 注册用户数趋势
22
+    register_trends = RegisterStatisticInfo.objects.filter(status=True).order_by('-pk')[:30]
23
+    register_trends = [r.data for r in register_trends]
24
+
25
+    # 销量统计 & 今日销量
26
+    try:
27
+        sale_num = SaleStatisticInfo.objects.get(ymd=ymd).num
28
+    except RegisterStatisticInfo.DoesNotExist:
29
+        sale_num = 0
30
+
31
+    # 商品销量趋势
32
+    sale_trends = SaleStatisticInfo.objects.filter(status=True).order_by('-pk')[:30]
33
+    sale_trends = [s.data for s in sale_trends]
34
+
35
+    # 型号销量统计 & 热销商品榜
36
+    model_sales = ModelSaleStatisticInfo.objects.filter(status=True).order_by('-num')[:3]
37
+    model_sales = [m.data for m in model_sales]
38
+
39
+    # 经销商销量统计 & 经销商榜
40
+    distributor_sales = DistributorSaleStatisticInfo.objects.filter(status=True).order_by('-num')[:3]
41
+    distributor_sales = [d.data for d in distributor_sales]
42
+
43
+    return response(200, 'Get TJ Data Success', u'获取统计数据成功', {
44
+        'register_num': register_num,
45
+        'register_trends': register_trends,
46
+        'sale_num': sale_num,
47
+        'sale_trends': sale_trends,
48
+        'model_sales': model_sales,
49
+        'distributor_sales': distributor_sales,
50
+    })

+ 5 - 0
utils/error/errno_utils.py

@@ -25,6 +25,11 @@ class ProductModelStatusCode(BaseStatusCode):
25 25
     MODEL_NOT_FOUND = StatusCodeField(501001, 'Model Not Found', description=u'型号不存在')
26 26
 
27 27
 
28
+class ProductDistributorStatusCode(BaseStatusCode):
29
+    """ 经销商相关错误码 5011xx """
30
+    DISTRIBUTOR_NOT_FOUND = StatusCodeField(501101, 'Distributor Not Found', description=u'经销商不存在')
31
+
32
+
28 33
 class ProductStatusCode(BaseStatusCode):
29 34
     """ 产品相关错误码 5020xx """
30 35
     PRODUCT_NOT_FOUND = StatusCodeField(502001, 'Product Not Found', description=u'产品不存在')

kodo - Gogs: Go Git Service

Нет описания

huangqimin001: 5f51d36155 :art: ComplementCodeLogInfo image upload qiniu лет %!s(int64=5): %!d(string=назад)
account c01f5a3b5b :art: Add coupon_expire_at лет %!s(int64=5): %!d(string=назад)
api c19cbf5477 url add admin лет %!s(int64=5): %!d(string=назад)
commands 5f51d36155 :art: ComplementCodeLogInfo image upload qiniu лет %!s(int64=5): %!d(string=назад)
coupon e7da55aaf2 :art: Add complement_code лет %!s(int64=5): %!d(string=назад)
docs 212e3994d1 MP verify file лет %!s(int64=9): %!d(string=назад)
guideline 88b564d033 fix coercing to Unicode: need string or buffer, long found лет %!s(int64=6): %!d(string=назад)
integral 020c5c128d :art: everyday_continue_send_user_coupon лет %!s(int64=5): %!d(string=назад)
kodo 3f783afcfc :art: Add marketcode iv лет %!s(int64=5): %!d(string=назад)
logs 5f51d36155 :art: ComplementCodeLogInfo image upload qiniu лет %!s(int64=5): %!d(string=назад)
maintenance e683ad2315 express_list maintenance_list 排序 лет %!s(int64=5): %!d(string=назад)
marketcode 88b564d033 fix coercing to Unicode: need string or buffer, long found лет %!s(int64=6): %!d(string=назад)
mch 1b420a2fba ConsumeInfoSubmitLogInfo adminuserdata 新增返回 model_id лет %!s(int64=5): %!d(string=назад)
member aa2144ebb6 :art: RightInfoAdmin лет %!s(int64=5): %!d(string=назад)
miniapp 1244a5a931 :art: Update MEMBER_CARD_ID_TAMRON лет %!s(int64=5): %!d(string=назад)
operation e7da55aaf2 :art: Add complement_code лет %!s(int64=5): %!d(string=назад)
page a77de03be7 update clerk_sale_submit_api лет %!s(int64=5): %!d(string=назад)
pre 3f783afcfc :art: Add marketcode iv лет %!s(int64=5): %!d(string=назад)
sales 88b564d033 fix coercing to Unicode: need string or buffer, long found лет %!s(int64=6): %!d(string=назад)
server 018d52f61d Update package django_xxx лет %!s(int64=8): %!d(string=назад)
shells 6270484a89 :art: fix_user_coupon_info лет %!s(int64=5): %!d(string=назад)
simditor 3e9628d0c9 iSort & Pycodestyle лет %!s(int64=6): %!d(string=назад)
staff e7da55aaf2 :art: Add complement_code лет %!s(int64=5): %!d(string=назад)
statistic 88b564d033 fix coercing to Unicode: need string or buffer, long found лет %!s(int64=6): %!d(string=назад)
utils 77224d884a :art: Support maintenance_tracking_info_subscribe лет %!s(int64=5): %!d(string=назад)
website 597ee33ba6 Pai2 => Kodo лет %!s(int64=8): %!d(string=назад)
.editorconfig 4defb80fdc gogs first init лет %!s(int64=11): %!d(string=назад)
.gitignore 4ce7f5c87b :art: Member Relative APIs лет %!s(int64=7): %!d(string=назад)
.isort.cfg afcdf74a49 add api group_data_api лет %!s(int64=10): %!d(string=назад)
TODO.md d31ffaa118 Update TODO лет %!s(int64=9): %!d(string=назад)
check.sh 95c1d32792 put isort and pep8 in check.sh лет %!s(int64=10): %!d(string=назад)
isort.sh 3e9628d0c9 iSort & Pycodestyle лет %!s(int64=6): %!d(string=назад)
manage.py 597ee33ba6 Pai2 => Kodo лет %!s(int64=8): %!d(string=назад)
pep8.sh 511533855d Change oauth to use http лет %!s(int64=9): %!d(string=назад)
requirements.txt 22a8246c88 :art: init_express_company лет %!s(int64=5): %!d(string=назад)
requirements_deploy.txt 873b42cb2f :art: TimeConvert local_string utc_dt лет %!s(int64=6): %!d(string=назад)
requirements_dev.txt 926f0ef06a Update requirements_xxx.txt лет %!s(int64=8): %!d(string=назад)
requirements_dj.txt fccbd76d05 :art: Update requirement.txt лет %!s(int64=5): %!d(string=назад)
requirements_pywe.txt 4239c95bdf :art: Update requirements.txt лет %!s(int64=5): %!d(string=назад)
requirements_redis.txt 4239c95bdf :art: Update requirements.txt лет %!s(int64=5): %!d(string=назад)
sysctl.sh 34c6774438 Opt лет %!s(int64=8): %!d(string=назад)