@logit

+ 8 - 1
api/urls.py

@@ -5,7 +5,7 @@ from django_file_upload import views as file_views
5 5
 
6 6
 from account import tourguide_views
7 7
 from account import views as account_views
8
-from api import distributor_views, encrypt_views, mch_views, model_views, operator_views
8
+from api import clerk_views, distributor_views, encrypt_views, mch_views, model_views, operator_views
9 9
 from box import views as box_views
10 10
 from geo import views as geo_views
11 11
 from group import (groupuser_views, lensman_views, tourguidegroup_views, tourguidegroupadmin_views,
@@ -254,3 +254,10 @@ urlpatterns += [
254 254
     url(r'^distributor/update$', distributor_views.distributor_update, name='distributor_update'),
255 255
     url(r'^distributor/list$', distributor_views.distributor_list, name='distributor_list'),
256 256
 ]
257
+
258
+urlpatterns += [
259
+    url(r'^clerk/add$', clerk_views.clerk_add, name='clerk_add'),
260
+    url(r'^clerk/delete$', clerk_views.clerk_delete, name='clerk_delete'),
261
+    url(r'^clerk/update$', clerk_views.clerk_update, name='clerk_update'),
262
+    url(r'^clerk/list$', clerk_views.clerk_list, name='clerk_list'),
263
+]

+ 16 - 1
mch/admin.py

@@ -8,8 +8,9 @@ from django_admin import DeleteModelAdmin, ReadOnlyModelAdmin
8 8
 from django_models_ext import ProvinceShortModelMixin
9 9
 from pysnippets.strsnippets import strip
10 10
 
11
+from integral.models import SaleclerkIntegralIncomeExpensesInfo, SaleclerkSubmitLogInfo
11 12
 from mch.models import (AdministratorInfo, BrandInfo, BrandModelDistributorPriceInfo, ConsumeInfoSubmitLogInfo,
12
-                        DistributorInfo, LatestAppInfo, ModelImageInfo, ModelInfo, OperatorInfo)
13
+                        DistributorInfo, LatestAppInfo, ModelImageInfo, ModelInfo, OperatorInfo, SaleclerkInfo)
13 14
 
14 15
 
15 16
 class AdministratorInfoAdmin(DeleteModelAdmin, admin.ModelAdmin):
@@ -109,6 +110,19 @@ class DistributorInfoAdmin(DeleteModelAdmin, admin.ModelAdmin):
109 110
         obj.save()
110 111
 
111 112
 
113
+class SaleclerkInfoAdmin(admin.ModelAdmin):
114
+    list_display = ('brand_id', 'brand_name', 'distributor_id', 'distributor_name', 'clerk_id', 'clerk_name', 'clerk_sex', 'clerk_phone', 'unionid', 'openid', 'integral', 'total_integral', 'user_status', 'test_user', 'status', 'created_at', 'updated_at')
115
+    list_filter = ('test_user', 'user_status', 'status')
116
+    search_fields = ('brand_id', 'brand_name', 'distributor_id', 'distributor_name', 'clerk_id', 'clerk_name', 'clerk_phone')
117
+
118
+    def save_model(self, request, obj, form, change):
119
+        obj.save()
120
+        if not obj.test_user:
121
+            return
122
+        SaleclerkIntegralIncomeExpensesInfo.objects.filter(franchiser_id=obj.franchiser_id).update(test_user=True)
123
+        SaleclerkSubmitLogInfo.objects.filter(franchiser_id=obj.franchiser_id).update(test_user=True)
124
+
125
+
112 126
 class BrandModelDistributorPriceInfoAdmin(DeleteModelAdmin, admin.ModelAdmin):
113 127
     list_display = ('brand_id', 'brand_name', 'model_id', 'model_name', 'distributor_id', 'distributor_name', 'factory_yuan', 'integral', 'status', 'created_at', 'updated_at')
114 128
     list_filter = ('brand_name', 'model_name', 'distributor_name', 'status')
@@ -165,6 +179,7 @@ admin.site.register(BrandInfo, BrandInfoAdmin)
165 179
 admin.site.register(ModelInfo, ModelInfoAdmin)
166 180
 # admin.site.register(ModelImageInfo, ModelImageInfoAdmin)
167 181
 admin.site.register(DistributorInfo, DistributorInfoAdmin)
182
+admin.site.register(SaleclerkInfo, SaleclerkInfoAdmin)
168 183
 # admin.site.register(BrandModelDistributorPriceInfo, BrandModelDistributorPriceInfoAdmin)
169 184
 admin.site.register(LatestAppInfo, LatestAppInfoAdmin)
170 185
 admin.site.register(ConsumeInfoSubmitLogInfo, ConsumeInfoSubmitLogInfoAdmin)

+ 46 - 0
mch/migrations/0019_saleclerkinfo.py

@@ -0,0 +1,46 @@
1
+# -*- coding: utf-8 -*-
2
+# Generated by Django 1.11.11 on 2018-05-14 10:28
3
+from __future__ import unicode_literals
4
+
5
+from django.db import migrations, models
6
+import shortuuidfield.fields
7
+
8
+
9
+class Migration(migrations.Migration):
10
+
11
+    dependencies = [
12
+        ('mch', '0018_auto_20180514_1519'),
13
+    ]
14
+
15
+    operations = [
16
+        migrations.CreateModel(
17
+            name='SaleclerkInfo',
18
+            fields=[
19
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
20
+                ('status', models.BooleanField(db_index=True, default=True, help_text='Status', verbose_name='status')),
21
+                ('created_at', models.DateTimeField(auto_now_add=True, help_text='Create Time', verbose_name='created_at')),
22
+                ('updated_at', models.DateTimeField(auto_now=True, help_text='Update Time', verbose_name='updated_at')),
23
+                ('sex', models.BooleanField(choices=[(1, '\u7537'), (0, '\u5973')], db_index=True, default=1, help_text='Sex', verbose_name='sex')),
24
+                ('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')),
25
+                ('brand_name', models.CharField(blank=True, help_text='\u54c1\u724c\u540d\u79f0', max_length=255, null=True, verbose_name='brand_name')),
26
+                ('distributor_id', models.CharField(blank=True, db_index=True, help_text='\u7ecf\u9500\u5546\u552f\u4e00\u6807\u8bc6', max_length=32, null=True, verbose_name='distributor_id')),
27
+                ('distributor_name', models.CharField(blank=True, help_text='\u7ecf\u9500\u5546\u540d\u79f0', max_length=32, null=True, verbose_name='distributor_name')),
28
+                ('clerk_id', shortuuidfield.fields.ShortUUIDField(blank=True, db_index=True, editable=False, help_text='\u5e97\u5458\u552f\u4e00\u6807\u8bc6', max_length=22, unique=True)),
29
+                ('clerk_name', models.CharField(blank=True, help_text='\u5e97\u5458\u540d\u79f0', max_length=32, null=True, verbose_name='clerk_name')),
30
+                ('clerk_sex', models.IntegerField(choices=[(1, '\u7537'), (0, '\u5973')], db_index=True, default=1, help_text='\u5e97\u5458\u6027\u522b', verbose_name='clerk_sex')),
31
+                ('clerk_phone', models.CharField(blank=True, help_text='\u5e97\u5458\u8054\u7cfb\u7535\u8bdd', max_length=11, null=True, verbose_name='clerk_phone')),
32
+                ('unionid', models.CharField(blank=True, db_index=True, help_text='\u5fae\u4fe1 UnionID', max_length=32, null=True, unique=True, verbose_name='unionid')),
33
+                ('openid', models.CharField(blank=True, db_index=True, help_text='\u5fae\u4fe1 OpenID', max_length=32, null=True, unique=True, verbose_name='openid')),
34
+                ('integral', models.IntegerField(default=0, help_text='\u79ef\u5206', verbose_name='integral')),
35
+                ('total_integral', models.IntegerField(default=0, help_text='\u5168\u90e8\u79ef\u5206', verbose_name='total_integral')),
36
+                ('user_status', models.IntegerField(choices=[(-1, '\u5df2\u62d2\u7edd'), (0, '\u672a\u9a8c\u8bc1'), (1, '\u5df2\u6fc0\u6d3b'), (2, '\u5df2\u7981\u7528'), (3, '\u5df2\u5220\u9664'), (10, '\u5df2\u5206\u914d')], db_index=True, default=0, help_text='\u7528\u6237\u72b6\u6001', verbose_name='user_status')),
37
+                ('refused_reason', models.TextField(blank=True, help_text='\u5ba1\u6838\u62d2\u7edd\u539f\u56e0', null=True, verbose_name='refused_reason')),
38
+                ('is_auth', models.BooleanField(db_index=True, default=False, help_text='\u662f\u5426\u5df2\u6388\u6743', verbose_name='is_auth')),
39
+                ('test_user', models.BooleanField(db_index=True, default=False, help_text='\u662f\u5426\u4e3a\u6d4b\u8bd5\u7528\u6237', verbose_name='test_user')),
40
+            ],
41
+            options={
42
+                'verbose_name': 'saleclerkinfo',
43
+                'verbose_name_plural': 'saleclerkinfo',
44
+            },
45
+        ),
46
+    ]

+ 66 - 1
mch/models.py

@@ -2,7 +2,8 @@
2 2
 
3 3
 from django.db import models
4 4
 from django.utils.translation import ugettext_lazy as _
5
-from django_models_ext import BaseModelMixin, ProvinceShortModelMixin, upload_file_path, upload_file_url, upload_path
5
+from django_models_ext import (BaseModelMixin, ProvinceShortModelMixin, SexModelMixin, upload_file_path,
6
+                               upload_file_url, upload_path)
6 7
 from shortuuidfield import ShortUUIDField
7 8
 
8 9
 
@@ -242,6 +243,70 @@ class DistributorInfo(BaseModelMixin):
242 243
         }
243 244
 
244 245
 
246
+class SaleclerkInfo(BaseModelMixin, SexModelMixin):
247
+    REFUSED = -1
248
+    UNVERIFIED = 0
249
+    ACTIVATED = 1
250
+    DISABLED = 2
251
+    DELETED = 3
252
+    ASSIGN = 10
253
+
254
+    USER_STATUS = (
255
+        (REFUSED, u'已拒绝'),
256
+        (UNVERIFIED, u'未验证'),
257
+        (ACTIVATED, u'已激活'),
258
+        (DISABLED, u'已禁用'),
259
+        (DELETED, u'已删除'),
260
+        (ASSIGN, u'已分配'),
261
+    )
262
+
263
+    brand_id = models.CharField(_(u'brand_id'), max_length=32, blank=True, null=True, help_text=u'品牌唯一标识', db_index=True)
264
+    brand_name = models.CharField(_(u'brand_name'), max_length=255, blank=True, null=True, help_text=u'品牌名称')
265
+
266
+    distributor_id = models.CharField(_(u'distributor_id'), max_length=32, blank=True, null=True, help_text=u'经销商唯一标识', db_index=True)
267
+    distributor_name = models.CharField(_(u'distributor_name'), max_length=32, blank=True, null=True, help_text=u'经销商名称')
268
+
269
+    clerk_id = ShortUUIDField(_(u'clerk_id'), max_length=32, help_text=u'店员唯一标识', db_index=True, unique=True)
270
+    clerk_name = models.CharField(_(u'clerk_name'), max_length=32, blank=True, null=True, help_text=u'店员名称')
271
+    clerk_sex = models.IntegerField(_(u'clerk_sex'), choices=SexModelMixin.SEX_TUPLE, default=SexModelMixin.MALE, help_text=u'店员性别', db_index=True)
272
+    clerk_phone = models.CharField(_(u'clerk_phone'), max_length=11, blank=True, null=True, help_text=u'店员联系电话')
273
+
274
+    unionid = models.CharField(_(u'unionid'), max_length=32, blank=True, null=True, help_text=u'微信 UnionID', db_index=True, unique=True)
275
+    openid = models.CharField(_(u'openid'), max_length=32, blank=True, null=True, help_text=u'微信 OpenID', db_index=True, unique=True)
276
+
277
+    integral = models.IntegerField(_(u'integral'), default=0, help_text=u'积分')
278
+    total_integral = models.IntegerField(_(u'total_integral'), default=0, help_text=u'全部积分')
279
+
280
+    user_status = models.IntegerField(_(u'user_status'), choices=USER_STATUS, default=UNVERIFIED, help_text=u'用户状态', db_index=True)
281
+    refused_reason = models.TextField(_(u'refused_reason'), blank=True, null=True, help_text=u'审核拒绝原因')
282
+
283
+    is_auth = models.BooleanField(_(u'is_auth'), default=False, help_text=_(u'是否已授权'), db_index=True)
284
+
285
+    test_user = models.BooleanField(_(u'test_user'), default=False, help_text=_(u'是否为测试用户'), db_index=True)
286
+
287
+    class Meta:
288
+        verbose_name = _(u'经销商销售员信息')
289
+        verbose_name_plural = _(u'经销商销售员信息')
290
+
291
+    def __unicode__(self):
292
+        return unicode(self.pk)
293
+
294
+    @property
295
+    def admindata(self):
296
+        return {
297
+            'distributor_id': self.distributor_id,
298
+            'distributor_name': self.distributor_name,
299
+            'clerk_id': self.clerk_id,
300
+            'clerk_name': self.clerk_name,
301
+            'clerk_sex': self.clerk_sex,
302
+            'clerk_phone': self.clerk_phone,
303
+            'integral': self.integral,
304
+            'status': self.user_status,
305
+            'refused_reason': self.refused_reason,
306
+            'is_auth': self.is_auth,
307
+        }
308
+
309
+
245 310
 class BrandModelDistributorPriceInfo(BaseModelMixin):
246 311
     brand_id = models.CharField(_(u'brand_id'), max_length=32, blank=True, null=True, help_text=u'品牌唯一标识', db_index=True)
247 312
     brand_name = models.CharField(_(u'brand_name'), max_length=255, blank=True, null=True, help_text=u'品牌名称')

kodo - Gogs: Go Git Service

Няма описание

basic.html 8.8KB

    {% load staticfiles %} <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <meta name="format-detection" content="telephone=no,email=no,address=no"> <meta name="viewport" content="width=device-width,initial-scale=1.0,user-scalable=no"> <meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" /> <meta http-equiv="Pragma" content="no-cache" /> <meta http-equiv="Expires" content="0" /> <title>{% block title %}{% endblock %}</title> <link href="//cdnjs.cloudflare.com/ajax/libs/pure/0.6.2/pure-min.css" rel="stylesheet"> <link href="//cdnjs.cloudflare.com/ajax/libs/flexslider/2.6.3/flexslider.min.css" rel="stylesheet"> <link href="//res.wx.qq.com/open/libs/weui/0.4.3/weui.min.css" rel="stylesheet" type="text/css" /> <link href="{% static 'page/css/flexslider.ext.css' %}" rel="stylesheet" type="text/css" /> <link href="{% static 'page/css/weui.ext.css' %}" rel="stylesheet" type="text/css" /> {% block link %}{% endblock %} <style> body { font-family: Microsoft YaHei,Helvetica Neue,Helvetica,Arial,sans-serif !important; background: #fff; } img { pointer-events: none; } .clickable { pointer-events: auto; } /* Input 自动填充后,移除 Chrome 默认黄色 */ input:-webkit-autofill { box-shadow: 0 0 0 1000px white inset !important; } .container { padding-bottom: 45px; } .text-center { text-align: center; } .empty { color: #999; padding: .9375rem 0; font-size: .625rem; } .text_ellipsis { overflow:hidden; white-space:nowrap; text-overflow: ellipsis; } .fl { float: left; } .fr { float: right; } .clearfix { zoom: 1; } .clearfix:after { content: "\200B"; display: block; height: 0; clear: both; } </style> {% block tohomecss %} <style> .tohome { width: 40px; height: 40px; background-color: rgba(139, 139, 139, 0.7); position: fixed; right: 10px; bottom: 20px; border-radius: 9999px; border-top-left-radius: 9999px; border-top-right-radius: 9999px; border-bottom-left-radius: 9999px; border-bottom-right-radius: 9999px; z-index: 99999999; } .tohome img { display: block; width: 18px; height: 13px; margin: 6px auto 2px; } .tohome p { color: #ffffff; } </style> {% endblock %} {% block css %}{% endblock %} <script> {% block rem %} //这段js的最后面有两个参数记得要设置,一个为设计稿实际宽度,一个为制作稿最大宽度,例如设计稿为750,最大宽度为750,则为(750,750) !function(e,t){function n(){var n=l.getBoundingClientRect().width;t=t||540,n>t&&(n=t);var i=100*n/e;r.innerHTML="html{font-size:"+i+"px;}"}var i,d=document,o=window,l=d.documentElement,r=document.createElement("style");if(l.firstElementChild)l.firstElementChild.appendChild(r);else{var a=d.createElement("div");a.appendChild(r),d.write(a.innerHTML),a=null}n(),o.addEventListener("resize",function(){clearTimeout(i),i=setTimeout(n,300)},!1),o.addEventListener("pageshow",function(e){e.persisted&&(clearTimeout(i),i=setTimeout(n,300))},!1),"complete"===d.readyState?d.body.style.fontSize="16px":d.addEventListener("DOMContentLoaded",function(e){d.body.style.fontSize="16px"},!1)}(750,750); {% endblock %} </script> </head> <body> {% block somehtml %}{% endblock %} <div class="container"> {% block container %}{% endblock %} {% block tohomehtml %} <div class="tohome"> <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAeCAMAAABzP0xhAAAAS1BMVEUAAAD///////////////////////////////////////////////////////////////////////////////////////////////+DmQsHAAAAGHRSTlMAoHDw+q0VCufg187DuI+OgGJUSDwyKCBlxSbJAAAAi0lEQVQ4y+3SuRKEIBBFUaQbcd+X9/9fOpRDjaXQGJnNiW/SiwpkmXpiW6C16Sav4dR5qtlKHMpNbhaCR4vUTIwfnuKNxoWONR1uunB0g4Cxt9EbRDSXVewVoqr9bNYCgmJV3kwQ0fxtRkYCj8oZ8GBQqieHIWByev9DEPjfeisy+mDk6Dy9/kevRR9/MjHbEpIcQAAAAABJRU5ErkJggg=="> <p style="text-align:center;font-size:8px">回首页</p> </div> {% endblock %} </div> {% block somehtml2 %}{% endblock %} <script> window.onerror = function(errorMessage, scriptURI, lineNo, columnNo, error) { // 构建错误对象 var errorObj = { lineNo: lineNo || null, columnNo: columnNo || null, scriptURI: scriptURI || null, errorMessage: errorMessage || null, stack: error && error.stack ? error.stack : null }; // 构建Http请求 if (XMLHttpRequest) { var xhr = new XMLHttpRequest(); xhr.open('post', '/e/report', true); xhr.setRequestHeader('Content-Type', 'application/json'); // 设置请求头 xhr.send(JSON.stringify(errorObj)); // 发送参数 } } </script> {# <script src="//cdnjs.cloudflare.com/ajax/libs/zepto/1.1.6/zepto.min.js"></script>#} <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/flexslider/2.6.3/jquery.flexslider-min.js"></script> {% block script %}{% endblock %} <script> // History 压入本地连接 function pushHistory() { var state = { title: "title", url: "#" }; window.history.pushState(state, "title", "#"); } pushHistory(); // 延时监听 setTimeout(function () { // 监听``返回``、``后退``、``上一页`` window.addEventListener("popstate", function (e) { if (confirm("确认退出") == true) { window.history.back(-1); } else { pushHistory(); } }, false); }, 300); </script> <script> {% block glbjs %}{% endblock %} $(function() { /** 格式化输入字符串**/ //用法: "hello{0}".format('world');返回'hello world' String.prototype.format= function(){ var args = arguments; return this.replace(/\{(\d+)\}/g,function(s,i){ return args[i]; }); } {% block flexsliderjs %} // 轮播图 $('.flexslider').flexslider({ slideshowSpeed: 2000, pauseOnHover: true, controlNav: false, directionNav: false, }); {% endblock %} {% block tohomejs %} // 返回首页 $('.tohome').click(function () { window.location.href = '{{ domain }}/page/nav?{{ params|safe }}' }) {% endblock %} {% block js %}{% endblock %} }); </script> <script type="text/javascript" src="//res.wx.qq.com/open/js/jweixin-1.2.0.js"></script> <script type="text/javascript" src="{% static 'machine/js/jswe-1.0.0.js' %}"></script> <script> {# V.initWxData({#} {# imgUrl: '{{ domain }}{% static 'page/img/logo.jpg' %}',#} {# link: 'http://hpsgift.hphcclub.com/we/ws',#} {# desc: '惠普销售红包系统',#} {# title: '惠普销售红包系统',#} {# timeLine: ''#} {# }, true);#} V.hideOptionMenu(); {% block jswe %}{% endblock %} </script> {% block scriptag %}{% endblock %} </body> </html>