@@ -5,7 +5,8 @@ from djadmin import ChangeOnlyModelAdmin, ReadOnlyModelAdmin  | 
            ||
| 5 | 5 | 
                from django.contrib import admin  | 
            
| 6 | 6 | 
                from django.db import transaction  | 
            
| 7 | 7 | 
                 | 
            
| 8 | 
                -from account.models import LensmanIncomeExpensesInfo, LensmanInfo, TourGuideInfo, UserIncomeExpensesInfo, UserInfo  | 
            |
| 8 | 
                +from account.models import (FranchiserInfo, LensmanIncomeExpensesInfo, LensmanInfo, SaleclerkInfo, TourGuideInfo,  | 
            |
| 9 | 
                + UserIncomeExpensesInfo, UserInfo)  | 
            |
| 9 | 10 | 
                 | 
            
| 10 | 11 | 
                 | 
            
| 11 | 12 | 
                class LensmanInfoAdmin(ChangeOnlyModelAdmin, admin.ModelAdmin):  | 
            
                @@ -104,8 +105,25 @@ class UserIncomeExpensesInfoAdmin(ReadOnlyModelAdmin, admin.ModelAdmin):  | 
            ||
| 104 | 105 | 
                     list_filter = ('type', 'status')
               | 
            
| 105 | 106 | 
                 | 
            
| 106 | 107 | 
                 | 
            
| 107 | 
                -admin.site.register(LensmanInfo, LensmanInfoAdmin)  | 
            |
| 108 | 
                -admin.site.register(LensmanIncomeExpensesInfo, LensmanIncomeExpensesInfoAdmin)  | 
            |
| 109 | 
                -admin.site.register(TourGuideInfo, TourGuideInfoAdmin)  | 
            |
| 110 | 
                -admin.site.register(UserInfo, UserInfoAdmin)  | 
            |
| 111 | 
                -admin.site.register(UserIncomeExpensesInfo, UserIncomeExpensesInfoAdmin)  | 
            |
| 108 | 
                +class FranchiserInfoAdmin(admin.ModelAdmin):  | 
            |
| 109 | 
                +    readonly_fields = ('franchiser_id', )
               | 
            |
| 110 | 
                +    list_display = ('franchiser_id', 'franchiser_name', 'franchiser_addr', 'franchiser_phone', 'franchiser_boss_name', 'franchiser_boss_phone', 'status', 'created_at', 'updated_at')
               | 
            |
| 111 | 
                +    search_fields = ('franchiser_id', 'franchiser_name', 'franchiser_addr', 'franchiser_phone', 'franchiser_boss_name', 'franchiser_boss_phone')
               | 
            |
| 112 | 
                +    list_filter = ('status', )
               | 
            |
| 113 | 
                +  | 
            |
| 114 | 
                +  | 
            |
| 115 | 
                +class SaleclerkInfoAdmin(admin.ModelAdmin):  | 
            |
| 116 | 
                +    readonly_fields = ('franchiser_id', )
               | 
            |
| 117 | 
                +    list_display = ('franchiser_id', 'clerk_id', 'clerk_name', 'clerk_sex', 'clerk_phone', 'user_status', 'status', 'created_at', 'updated_at')
               | 
            |
| 118 | 
                +    search_fields = ('franchiser_id', 'clerk_id', 'clerk_name', 'clerk_phone')
               | 
            |
| 119 | 
                +    list_filter = ('user_status', 'status')
               | 
            |
| 120 | 
                +  | 
            |
| 121 | 
                +  | 
            |
| 122 | 
                +# admin.site.register(LensmanInfo, LensmanInfoAdmin)  | 
            |
| 123 | 
                +# admin.site.register(LensmanIncomeExpensesInfo, LensmanIncomeExpensesInfoAdmin)  | 
            |
| 124 | 
                +# admin.site.register(TourGuideInfo, TourGuideInfoAdmin)  | 
            |
| 125 | 
                +# admin.site.register(UserInfo, UserInfoAdmin)  | 
            |
| 126 | 
                +# admin.site.register(UserIncomeExpensesInfo, UserIncomeExpensesInfoAdmin)  | 
            |
| 127 | 
                +  | 
            |
| 128 | 
                +admin.site.register(FranchiserInfo, FranchiserInfoAdmin)  | 
            |
| 129 | 
                +admin.site.register(SaleclerkInfo, SaleclerkInfoAdmin)  | 
            
                @@ -0,0 +1,60 @@  | 
            ||
| 1 | 
                +# -*- coding: utf-8 -*-  | 
            |
| 2 | 
                +# Generated by Django 1.11.9 on 2018-02-07 14:16  | 
            |
| 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 | 
                +        ('account', '0026_auto_20180103_0446'),
               | 
            |
| 13 | 
                + ]  | 
            |
| 14 | 
                +  | 
            |
| 15 | 
                + operations = [  | 
            |
| 16 | 
                + migrations.CreateModel(  | 
            |
| 17 | 
                + name='FranchiserInfo',  | 
            |
| 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 | 
                +                ('franchiser_id', shortuuidfield.fields.ShortUUIDField(blank=True, db_index=True, editable=False, help_text='\u7ecf\u9500\u5546\u552f\u4e00\u6807\u8bc6', max_length=22, unique=True)),
               | 
            |
| 24 | 
                +                ('franchiser_name', models.CharField(blank=True, help_text='\u7ecf\u9500\u5546\u540d\u79f0', max_length=32, null=True, verbose_name='franchiser_name')),
               | 
            |
| 25 | 
                +                ('franchiser_addr', models.CharField(blank=True, help_text='\u7ecf\u9500\u5546\u5730\u5740', max_length=32, null=True, verbose_name='franchiser_addr')),
               | 
            |
| 26 | 
                +                ('franchiser_phone', models.CharField(blank=True, help_text='\u7ecf\u9500\u5546\u8054\u7cfb\u7535\u8bdd', max_length=11, null=True, verbose_name='franchiser_phone')),
               | 
            |
| 27 | 
                +                ('franchiser_boss_name', models.CharField(blank=True, help_text='\u7ecf\u9500\u5546\u8001\u677f\u540d\u79f0', max_length=32, null=True, verbose_name='franchiser_boss_name')),
               | 
            |
| 28 | 
                +                ('franchiser_boss_phone', models.CharField(blank=True, help_text='\u7ecf\u9500\u5546\u8001\u677f\u8054\u7cfb\u7535\u8bdd', max_length=11, null=True, verbose_name='franchiser_boss_phone')),
               | 
            |
| 29 | 
                + ],  | 
            |
| 30 | 
                +            options={
               | 
            |
| 31 | 
                + 'verbose_name': '\u7ecf\u9500\u5546\u4fe1\u606f\u8868',  | 
            |
| 32 | 
                + 'verbose_name_plural': '\u7ecf\u9500\u5546\u4fe1\u606f\u8868',  | 
            |
| 33 | 
                + },  | 
            |
| 34 | 
                + ),  | 
            |
| 35 | 
                + migrations.CreateModel(  | 
            |
| 36 | 
                + name='SaleclerkInfo',  | 
            |
| 37 | 
                + fields=[  | 
            |
| 38 | 
                +                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
               | 
            |
| 39 | 
                +                ('status', models.BooleanField(db_index=True, default=True, help_text='Status', verbose_name='status')),
               | 
            |
| 40 | 
                +                ('created_at', models.DateTimeField(auto_now_add=True, help_text='Create Time', verbose_name='created_at')),
               | 
            |
| 41 | 
                +                ('updated_at', models.DateTimeField(auto_now=True, help_text='Update Time', verbose_name='updated_at')),
               | 
            |
| 42 | 
                +                ('sex', models.BooleanField(choices=[(1, '\u7537'), (0, '\u5973')], db_index=True, default=1, help_text='Sex', verbose_name='sex')),
               | 
            |
| 43 | 
                +                ('franchiser_id', models.CharField(blank=True, db_index=True, help_text='\u7ecf\u9500\u5546\u552f\u4e00\u6807\u8bc6', max_length=32, null=True, verbose_name='franchiser_id')),
               | 
            |
| 44 | 
                +                ('franchiser_name', models.CharField(blank=True, help_text='\u7ecf\u9500\u5546\u540d\u79f0', max_length=32, null=True, verbose_name='franchiser_name')),
               | 
            |
| 45 | 
                +                ('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)),
               | 
            |
| 46 | 
                +                ('clerk_name', models.CharField(blank=True, help_text='\u5e97\u5458\u540d\u79f0', max_length=32, null=True, verbose_name='clerk_name')),
               | 
            |
| 47 | 
                +                ('clerk_sex', models.IntegerField(choices=[(1, '\u7537'), (0, '\u5973')], db_index=True, default=1, help_text='\u5e97\u5458\u6027\u522b', verbose_name='clerk_sex')),
               | 
            |
| 48 | 
                +                ('clerk_phone', models.CharField(blank=True, help_text='\u5e97\u5458\u8054\u7cfb\u7535\u8bdd', max_length=11, null=True, verbose_name='clerk_phone')),
               | 
            |
| 49 | 
                +                ('openid', models.CharField(blank=True, db_index=True, help_text='\u5fae\u4fe1 OpenID', max_length=32, null=True, unique=True, verbose_name='openid')),
               | 
            |
| 50 | 
                +                ('unionid', models.CharField(blank=True, db_index=True, help_text='\u5fae\u4fe1 UnionID', max_length=32, null=True, unique=True, verbose_name='unionid')),
               | 
            |
| 51 | 
                +                ('integral', models.IntegerField(default=0, help_text='\u79ef\u5206', verbose_name='integral')),
               | 
            |
| 52 | 
                +                ('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')),
               | 
            |
| 53 | 
                +                ('refused_reason', models.TextField(blank=True, help_text='\u5ba1\u6838\u62d2\u7edd\u539f\u56e0', null=True, verbose_name='refused_reason')),
               | 
            |
| 54 | 
                + ],  | 
            |
| 55 | 
                +            options={
               | 
            |
| 56 | 
                + 'verbose_name': 'saleclerkinfo',  | 
            |
| 57 | 
                + 'verbose_name_plural': 'saleclerkinfo',  | 
            |
| 58 | 
                + },  | 
            |
| 59 | 
                + ),  | 
            |
| 60 | 
                + ]  | 
            
                @@ -3,7 +3,8 @@  | 
            ||
| 3 | 3 | 
                from django.db import models  | 
            
| 4 | 4 | 
                from django.utils.translation import ugettext_lazy as _  | 
            
| 5 | 5 | 
                from jsonfield import JSONField  | 
            
| 6 | 
                -from models_ext import BaseModelMixin  | 
            |
| 6 | 
                +from models_ext import BaseModelMixin, SexModelMixin  | 
            |
| 7 | 
                +from shortuuidfield import ShortUUIDField  | 
            |
| 7 | 8 | 
                 | 
            
| 8 | 9 | 
                from pai2.basemodels import LensmanTypeBoolMixin, LensmanTypeMixin  | 
            
| 9 | 10 | 
                 | 
            
                @@ -420,3 +421,80 @@ class UserIncomeExpensesInfo(BaseModelMixin):  | 
            ||
| 420 | 421 | 
                 | 
            
| 421 | 422 | 
                def __unicode__(self):  | 
            
| 422 | 423 | 
                return unicode(self.pk)  | 
            
| 424 | 
                +  | 
            |
| 425 | 
                +  | 
            |
| 426 | 
                +class FranchiserInfo(BaseModelMixin):  | 
            |
| 427 | 
                + franchiser_id = ShortUUIDField(_(u'franchiser_id'), max_length=32, help_text=u'经销商唯一标识', db_index=True, unique=True)  | 
            |
| 428 | 
                + franchiser_name = models.CharField(_(u'franchiser_name'), max_length=32, blank=True, null=True, help_text=u'经销商名称')  | 
            |
| 429 | 
                + franchiser_addr = models.CharField(_(u'franchiser_addr'), max_length=32, blank=True, null=True, help_text=u'经销商地址')  | 
            |
| 430 | 
                + franchiser_phone = models.CharField(_(u'franchiser_phone'), max_length=11, blank=True, null=True, help_text=u'经销商联系电话')  | 
            |
| 431 | 
                + franchiser_boss_name = models.CharField(_(u'franchiser_boss_name'), max_length=32, blank=True, null=True, help_text=u'经销商老板名称')  | 
            |
| 432 | 
                + franchiser_boss_phone = models.CharField(_(u'franchiser_boss_phone'), max_length=11, blank=True, null=True, help_text=u'经销商老板联系电话')  | 
            |
| 433 | 
                +  | 
            |
| 434 | 
                + class Meta:  | 
            |
| 435 | 
                + verbose_name = _(u'经销商信息表')  | 
            |
| 436 | 
                + verbose_name_plural = _(u'经销商信息表')  | 
            |
| 437 | 
                +  | 
            |
| 438 | 
                + def __unicode__(self):  | 
            |
| 439 | 
                + return unicode(self.pk)  | 
            |
| 440 | 
                +  | 
            |
| 441 | 
                + @property  | 
            |
| 442 | 
                + def data(self):  | 
            |
| 443 | 
                +        return {
               | 
            |
| 444 | 
                + 'franchiser_id': self.franchiser_id,  | 
            |
| 445 | 
                + 'franchiser_name': self.franchiser_name,  | 
            |
| 446 | 
                + }  | 
            |
| 447 | 
                +  | 
            |
| 448 | 
                +  | 
            |
| 449 | 
                +class SaleclerkInfo(BaseModelMixin, SexModelMixin):  | 
            |
| 450 | 
                + REFUSED = -1  | 
            |
| 451 | 
                + UNVERIFIED = 0  | 
            |
| 452 | 
                + ACTIVATED = 1  | 
            |
| 453 | 
                + DISABLED = 2  | 
            |
| 454 | 
                + DELETED = 3  | 
            |
| 455 | 
                + ASSIGN = 10  | 
            |
| 456 | 
                +  | 
            |
| 457 | 
                + USER_STATUS = (  | 
            |
| 458 | 
                + (REFUSED, u'已拒绝'),  | 
            |
| 459 | 
                + (UNVERIFIED, u'未验证'),  | 
            |
| 460 | 
                + (ACTIVATED, u'已激活'),  | 
            |
| 461 | 
                + (DISABLED, u'已禁用'),  | 
            |
| 462 | 
                + (DELETED, u'已删除'),  | 
            |
| 463 | 
                + (ASSIGN, u'已分配'),  | 
            |
| 464 | 
                + )  | 
            |
| 465 | 
                +  | 
            |
| 466 | 
                + franchiser_id = models.CharField(_(u'franchiser_id'), max_length=32, blank=True, null=True, help_text=u'经销商唯一标识', db_index=True)  | 
            |
| 467 | 
                + franchiser_name = models.CharField(_(u'franchiser_name'), max_length=32, blank=True, null=True, help_text=u'经销商名称')  | 
            |
| 468 | 
                + clerk_id = ShortUUIDField(_(u'clerk_id'), max_length=32, help_text=u'店员唯一标识', db_index=True, unique=True)  | 
            |
| 469 | 
                + clerk_name = models.CharField(_(u'clerk_name'), max_length=32, blank=True, null=True, help_text=u'店员名称')  | 
            |
| 470 | 
                + clerk_sex = models.IntegerField(_(u'clerk_sex'), choices=SexModelMixin.SEX_TUPLE, default=SexModelMixin.MALE, help_text=u'店员性别', db_index=True)  | 
            |
| 471 | 
                + clerk_phone = models.CharField(_(u'clerk_phone'), max_length=11, blank=True, null=True, help_text=u'店员联系电话')  | 
            |
| 472 | 
                +  | 
            |
| 473 | 
                + openid = models.CharField(_(u'openid'), max_length=32, blank=True, null=True, help_text=u'微信 OpenID', db_index=True, unique=True)  | 
            |
| 474 | 
                + unionid = models.CharField(_(u'unionid'), max_length=32, blank=True, null=True, help_text=u'微信 UnionID', db_index=True, unique=True)  | 
            |
| 475 | 
                +  | 
            |
| 476 | 
                + integral = models.IntegerField(_(u'integral'), default=0, help_text=u'积分')  | 
            |
| 477 | 
                +  | 
            |
| 478 | 
                + user_status = models.IntegerField(_(u'user_status'), choices=USER_STATUS, default=UNVERIFIED, help_text=u'用户状态', db_index=True)  | 
            |
| 479 | 
                + refused_reason = models.TextField(_(u'refused_reason'), blank=True, null=True, help_text=u'审核拒绝原因')  | 
            |
| 480 | 
                +  | 
            |
| 481 | 
                + class Meta:  | 
            |
| 482 | 
                + verbose_name = _(u'saleclerkinfo')  | 
            |
| 483 | 
                + verbose_name_plural = _(u'saleclerkinfo')  | 
            |
| 484 | 
                +  | 
            |
| 485 | 
                + def __unicode__(self):  | 
            |
| 486 | 
                + return unicode(self.pk)  | 
            |
| 487 | 
                +  | 
            |
| 488 | 
                + @property  | 
            |
| 489 | 
                + def data(self):  | 
            |
| 490 | 
                +        return {
               | 
            |
| 491 | 
                + 'franchiser_id': self.franchiser_id,  | 
            |
| 492 | 
                + 'franchiser_name': self.franchiser_name,  | 
            |
| 493 | 
                + 'clerk_id': self.clerk_id,  | 
            |
| 494 | 
                + 'clerk_name': self.clerk_name,  | 
            |
| 495 | 
                + 'clerk_sex': self.clerk_sex,  | 
            |
| 496 | 
                + 'clerk_phone': self.clerk_phone,  | 
            |
| 497 | 
                + 'integral': self.integral,  | 
            |
| 498 | 
                + 'status': self.user_status,  | 
            |
| 499 | 
                + 'refused_reason': self.refused_reason,  | 
            |
| 500 | 
                + }  | 
            
                @@ -13,6 +13,7 @@ from group import (groupuser_views, lensman_views, tourguidegroup_views, tourgui  | 
            ||
| 13 | 13 | 
                from message import views as message_views  | 
            
| 14 | 14 | 
                from miniapp import views as mini_views  | 
            
| 15 | 15 | 
                from operation import views as op_views  | 
            
| 16 | 
                +from page import oauth_views, sale_views  | 
            |
| 16 | 17 | 
                from pay import views as pay_views  | 
            
| 17 | 18 | 
                from photo import views as photo_views  | 
            
| 18 | 19 | 
                from server import server_views  | 
            
                @@ -207,3 +208,8 @@ urlpatterns += [  | 
            ||
| 207 | 208 | 
                urlpatterns += [  | 
            
| 208 | 209 | 
                url(r'^api/consumer_info$', mch_views.consumer_info_api, name='consumer_info_api'),  | 
            
| 209 | 210 | 
                ]  | 
            
| 211 | 
                +  | 
            |
| 212 | 
                +urlpatterns = [  | 
            |
| 213 | 
                + url(r'^clerk/submit$', oauth_views.clerk_submit_api, name='clerk_submit_api'), # 店员信息提交  | 
            |
| 214 | 
                + url(r'^clerk/sale/submit$', sale_views.clerk_sale_submit_api, name='clerk_sale_submit_api'), # 店员销售信息提交  | 
            |
| 215 | 
                +]  | 
            
                @@ -36,9 +36,9 @@ class PhotoThumbUpInfoAdmin(ReadOnlyModelAdmin, admin.ModelAdmin):  | 
            ||
| 36 | 36 | 
                     list_filter = ('thumbup', 'status')
               | 
            
| 37 | 37 | 
                 | 
            
| 38 | 38 | 
                 | 
            
| 39 | 
                -admin.site.register(GroupInfo, GroupInfoAdmin)  | 
            |
| 40 | 
                -admin.site.register(GroupUserInfo, GroupUserInfoAdmin)  | 
            |
| 41 | 
                -admin.site.register(GroupPhotoInfo, GroupPhotoInfoAdmin)  | 
            |
| 42 | 
                -admin.site.register(GroupPhotoOrderInfo, GroupPhotoOrderInfoAdmin)  | 
            |
| 43 | 
                -admin.site.register(PhotoCommentInfo, PhotoCommentInfoAdmin)  | 
            |
| 44 | 
                -admin.site.register(PhotoThumbUpInfo, PhotoThumbUpInfoAdmin)  | 
            |
| 39 | 
                +# admin.site.register(GroupInfo, GroupInfoAdmin)  | 
            |
| 40 | 
                +# admin.site.register(GroupUserInfo, GroupUserInfoAdmin)  | 
            |
| 41 | 
                +# admin.site.register(GroupPhotoInfo, GroupPhotoInfoAdmin)  | 
            |
| 42 | 
                +# admin.site.register(GroupPhotoOrderInfo, GroupPhotoOrderInfoAdmin)  | 
            |
| 43 | 
                +# admin.site.register(PhotoCommentInfo, PhotoCommentInfoAdmin)  | 
            |
| 44 | 
                +# admin.site.register(PhotoThumbUpInfo, PhotoThumbUpInfoAdmin)  | 
            
                @@ -0,0 +1,15 @@  | 
            ||
| 1 | 
                +# -*- coding: utf-8 -*-  | 
            |
| 2 | 
                +  | 
            |
| 3 | 
                +from django.contrib import admin  | 
            |
| 4 | 
                +  | 
            |
| 5 | 
                +from integral.models import SaleclerkIntegralIncomeExpensesInfo  | 
            |
| 6 | 
                +  | 
            |
| 7 | 
                +  | 
            |
| 8 | 
                +class SaleclerkIntegralIncomeExpensesInfoAdmin(admin.ModelAdmin):  | 
            |
| 9 | 
                +    readonly_fields = ('franchiser_id', 'clerk_id', 'type', 'code', 'integral', 'left_integral')
               | 
            |
| 10 | 
                +    list_display = ('franchiser_id', 'clerk_id', 'type', 'code', 'integral', 'left_integral', 'remark', 'status', 'created_at', 'updated_at')
               | 
            |
| 11 | 
                +    search_fields = ('code', 'remark')
               | 
            |
| 12 | 
                +    list_filter = ('franchiser_id', 'type', 'status')
               | 
            |
| 13 | 
                +  | 
            |
| 14 | 
                +  | 
            |
| 15 | 
                +admin.site.register(SaleclerkIntegralIncomeExpensesInfo, SaleclerkIntegralIncomeExpensesInfoAdmin)  | 
            
                @@ -0,0 +1,36 @@  | 
            ||
| 1 | 
                +# -*- coding: utf-8 -*-  | 
            |
| 2 | 
                +# Generated by Django 1.11.9 on 2018-02-07 14:16  | 
            |
| 3 | 
                +from __future__ import unicode_literals  | 
            |
| 4 | 
                +  | 
            |
| 5 | 
                +from django.db import migrations, models  | 
            |
| 6 | 
                +  | 
            |
| 7 | 
                +  | 
            |
| 8 | 
                +class Migration(migrations.Migration):  | 
            |
| 9 | 
                +  | 
            |
| 10 | 
                + initial = True  | 
            |
| 11 | 
                +  | 
            |
| 12 | 
                + dependencies = [  | 
            |
| 13 | 
                + ]  | 
            |
| 14 | 
                +  | 
            |
| 15 | 
                + operations = [  | 
            |
| 16 | 
                + migrations.CreateModel(  | 
            |
| 17 | 
                + name='SaleclerkIntegralIncomeExpensesInfo',  | 
            |
| 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 | 
                +                ('franchiser_id', models.CharField(blank=True, db_index=True, help_text='\u7ecf\u9500\u5546\u552f\u4e00\u6807\u8bc6', max_length=32, null=True, verbose_name='franchiser_id')),
               | 
            |
| 24 | 
                +                ('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')),
               | 
            |
| 25 | 
                +                ('type', models.IntegerField(choices=[(0, '\u6536\u5165'), (1, '\u652f\u51fa'), (2, '\u89e3\u51bb')], db_index=True, default=0, help_text='\u6536\u652f\u7c7b\u522b', verbose_name='type')),
               | 
            |
| 26 | 
                +                ('code', models.CharField(blank=True, db_index=True, help_text='\u673a\u8eab\u7801', max_length=32, null=True, verbose_name='code')),
               | 
            |
| 27 | 
                +                ('integral', models.IntegerField(default=0, help_text='\u589e\u51cf\u79ef\u5206', verbose_name='integral')),
               | 
            |
| 28 | 
                +                ('left_integral', models.IntegerField(default=0, help_text='\u79ef\u5206\u589e\u51cf\u540e\u6570\u91cf(\u5206)', verbose_name='left_integral')),
               | 
            |
| 29 | 
                +                ('remark', models.CharField(blank=True, help_text='\u5907\u6ce8', max_length=255, null=True, verbose_name='remark')),
               | 
            |
| 30 | 
                + ],  | 
            |
| 31 | 
                +            options={
               | 
            |
| 32 | 
                + 'verbose_name': 'saleclerkintegralincomeexpensesinfo',  | 
            |
| 33 | 
                + 'verbose_name_plural': 'saleclerkintegralincomeexpensesinfo',  | 
            |
| 34 | 
                + },  | 
            |
| 35 | 
                + ),  | 
            |
| 36 | 
                + ]  | 
            
                @@ -0,0 +1,35 @@  | 
            ||
| 1 | 
                +# -*- coding: utf-8 -*-  | 
            |
| 2 | 
                +  | 
            |
| 3 | 
                +from django.db import models  | 
            |
| 4 | 
                +from django.utils.translation import ugettext_lazy as _  | 
            |
| 5 | 
                +from models_ext import BaseModelMixin  | 
            |
| 6 | 
                +  | 
            |
| 7 | 
                +  | 
            |
| 8 | 
                +class SaleclerkIntegralIncomeExpensesInfo(BaseModelMixin):  | 
            |
| 9 | 
                + INCOME = 0  | 
            |
| 10 | 
                + EXPENSE = 1  | 
            |
| 11 | 
                + UNFREEZE = 2  | 
            |
| 12 | 
                +  | 
            |
| 13 | 
                + TYPE = (  | 
            |
| 14 | 
                + (INCOME, u'收入'),  | 
            |
| 15 | 
                + (EXPENSE, u'支出'),  | 
            |
| 16 | 
                + (UNFREEZE, u'解冻'),  | 
            |
| 17 | 
                + )  | 
            |
| 18 | 
                +  | 
            |
| 19 | 
                + franchiser_id = models.CharField(_(u'franchiser_id'), max_length=32, blank=True, null=True, help_text=u'经销商唯一标识', db_index=True)  | 
            |
| 20 | 
                + clerk_id = models.CharField(_(u'clerk_id'), max_length=32, blank=True, null=True, help_text=u'店员唯一标识', db_index=True)  | 
            |
| 21 | 
                +  | 
            |
| 22 | 
                + type = models.IntegerField(_(u'type'), choices=TYPE, default=INCOME, help_text=u'收支类别', db_index=True)  | 
            |
| 23 | 
                +  | 
            |
| 24 | 
                + code = models.CharField(_(u'code'), max_length=32, blank=True, null=True, help_text=u'机身码', db_index=True)  | 
            |
| 25 | 
                + integral = models.IntegerField(_(u'integral'), default=0, help_text=u'增减积分')  | 
            |
| 26 | 
                + left_integral = models.IntegerField(_(u'left_integral'), default=0, help_text=u'积分增减后数量(分)')  | 
            |
| 27 | 
                +  | 
            |
| 28 | 
                + remark = models.CharField(_(u'remark'), max_length=255, blank=True, null=True, help_text=u'备注')  | 
            |
| 29 | 
                +  | 
            |
| 30 | 
                + class Meta:  | 
            |
| 31 | 
                + verbose_name = _(u'saleclerkintegralincomeexpensesinfo')  | 
            |
| 32 | 
                + verbose_name_plural = _(u'saleclerkintegralincomeexpensesinfo')  | 
            |
| 33 | 
                +  | 
            |
| 34 | 
                + def __unicode__(self):  | 
            |
| 35 | 
                + return unicode(self.pk)  | 
            
                @@ -0,0 +1,4 @@  | 
            ||
| 1 | 
                +from django.test import TestCase  | 
            |
| 2 | 
                +  | 
            |
| 3 | 
                +  | 
            |
| 4 | 
                +# Create your tests here.  | 
            
                @@ -0,0 +1,4 @@  | 
            ||
| 1 | 
                +from django.shortcuts import render  | 
            |
| 2 | 
                +  | 
            |
| 3 | 
                +  | 
            |
| 4 | 
                +# Create your views here.  | 
            
                @@ -26,7 +26,7 @@ class SystemMessageDeleteInfoAdmin(ReadOnlyModelAdmin, admin.ModelAdmin):  | 
            ||
| 26 | 26 | 
                     list_filter = ('status', )
               | 
            
| 27 | 27 | 
                 | 
            
| 28 | 28 | 
                 | 
            
| 29 | 
                -admin.site.register(UserMessageInfo, UserMessageInfoAdmin)  | 
            |
| 30 | 
                -admin.site.register(SystemMessageInfo, SystemMessageInfoAdmin)  | 
            |
| 31 | 
                -admin.site.register(SystemMessageReadInfo, SystemMessageReadInfoAdmin)  | 
            |
| 32 | 
                -admin.site.register(SystemMessageDeleteInfo, SystemMessageDeleteInfoAdmin)  | 
            |
| 29 | 
                +# admin.site.register(UserMessageInfo, UserMessageInfoAdmin)  | 
            |
| 30 | 
                +# admin.site.register(SystemMessageInfo, SystemMessageInfoAdmin)  | 
            |
| 31 | 
                +# admin.site.register(SystemMessageReadInfo, SystemMessageReadInfoAdmin)  | 
            |
| 32 | 
                +# admin.site.register(SystemMessageDeleteInfo, SystemMessageDeleteInfoAdmin)  | 
            
                @@ -169,10 +169,10 @@ class BoxProgramVersionInfoAdmin(admin.ModelAdmin):  | 
            ||
| 169 | 169 | 
                set_box_program_version()  | 
            
| 170 | 170 | 
                 | 
            
| 171 | 171 | 
                 | 
            
| 172 | 
                -admin.site.register(LatestAppInfo, LatestAppInfoAdmin)  | 
            |
| 173 | 
                -admin.site.register(PatchInfo, PatchInfoAdmin)  | 
            |
| 174 | 
                -admin.site.register(APPSettingsInfo, APPSettingsInfoAdmin)  | 
            |
| 175 | 
                -admin.site.register(SplashInfo, SplashInfoAdmin)  | 
            |
| 176 | 
                -admin.site.register(FeedbackInfo, FeedbackInfoAdmin)  | 
            |
| 177 | 
                -admin.site.register(GuestEntranceControlInfo, GuestEntranceControlInfoAdmin)  | 
            |
| 178 | 
                -admin.site.register(BoxProgramVersionInfo, BoxProgramVersionInfoAdmin)  | 
            |
| 172 | 
                +# admin.site.register(LatestAppInfo, LatestAppInfoAdmin)  | 
            |
| 173 | 
                +# admin.site.register(PatchInfo, PatchInfoAdmin)  | 
            |
| 174 | 
                +# admin.site.register(APPSettingsInfo, APPSettingsInfoAdmin)  | 
            |
| 175 | 
                +# admin.site.register(SplashInfo, SplashInfoAdmin)  | 
            |
| 176 | 
                +# admin.site.register(FeedbackInfo, FeedbackInfoAdmin)  | 
            |
| 177 | 
                +# admin.site.register(GuestEntranceControlInfo, GuestEntranceControlInfoAdmin)  | 
            |
| 178 | 
                +# admin.site.register(BoxProgramVersionInfo, BoxProgramVersionInfoAdmin)  | 
            
                @@ -0,0 +1,22 @@  | 
            ||
| 1 | 
                +# -*- coding: utf-8 -*-  | 
            |
| 2 | 
                +  | 
            |
| 3 | 
                +from __future__ import division  | 
            |
| 4 | 
                +  | 
            |
| 5 | 
                +from django.conf import settings  | 
            |
| 6 | 
                +from django.shortcuts import render  | 
            |
| 7 | 
                +  | 
            |
| 8 | 
                +from account.models import SaleclerkInfo  | 
            |
| 9 | 
                +  | 
            |
| 10 | 
                +  | 
            |
| 11 | 
                +def clerk_info_oauth(request):  | 
            |
| 12 | 
                +    unionid = request.GET.get('unionid', '')
               | 
            |
| 13 | 
                +  | 
            |
| 14 | 
                + try:  | 
            |
| 15 | 
                + clerk = SaleclerkInfo.objects.get(unionid=unionid)  | 
            |
| 16 | 
                + except SaleclerkInfo.DoesNotExist:  | 
            |
| 17 | 
                + clerk = None  | 
            |
| 18 | 
                +  | 
            |
| 19 | 
                +    return render(request, 'page/clerk_info.html', {
               | 
            |
| 20 | 
                + 'domain': settings.DOMAIN,  | 
            |
| 21 | 
                + 'clerk_info': clerk and clerk.data,  | 
            |
| 22 | 
                + })  | 
            
                @@ -1,9 +1,14 @@  | 
            ||
| 1 | 1 | 
                # -*- coding: utf-8 -*-  | 
            
| 2 | 2 | 
                 | 
            
| 3 | 
                +from django.conf import settings  | 
            |
| 4 | 
                +from django.db import transaction  | 
            |
| 3 | 5 | 
                from django.shortcuts import render  | 
            
| 6 | 
                +from django_response import response  | 
            |
| 4 | 7 | 
                from json_render import json_render  | 
            
| 8 | 
                +from logit import logit  | 
            |
| 5 | 9 | 
                 | 
            
| 6 | 
                -from account.models import LensmanInfo, TourGuideInfo  | 
            |
| 10 | 
                +from account.models import FranchiserInfo, LensmanInfo, SaleclerkInfo, TourGuideInfo  | 
            |
| 11 | 
                +from utils.error.errno_utils import FranchiserStatusCode, SaleclerkStatusCode  | 
            |
| 7 | 12 | 
                from utils.redis.connect import r  | 
            
| 8 | 13 | 
                 | 
            
| 9 | 14 | 
                 | 
            
                @@ -48,3 +53,61 @@ def login_qrcode(request):  | 
            ||
| 48 | 53 | 
                }  | 
            
| 49 | 54 | 
                 | 
            
| 50 | 55 | 
                return json_render(request, 'page/login_qrcode.html', data)  | 
            
| 56 | 
                +  | 
            |
| 57 | 
                +  | 
            |
| 58 | 
                +def clerk_oauth(request):  | 
            |
| 59 | 
                +    unionid = request.GET.get('unionid', '')
               | 
            |
| 60 | 
                +  | 
            |
| 61 | 
                + chisers = FranchiserInfo.objects.filter(status=True)  | 
            |
| 62 | 
                + chisers = [chiser.data for chiser in chisers]  | 
            |
| 63 | 
                +  | 
            |
| 64 | 
                + try:  | 
            |
| 65 | 
                + clerk = SaleclerkInfo.objects.get(unionid=unionid)  | 
            |
| 66 | 
                + except SaleclerkInfo.DoesNotExist:  | 
            |
| 67 | 
                + clerk = None  | 
            |
| 68 | 
                +  | 
            |
| 69 | 
                +    return render(request, 'page/clerk_oauth.html', {
               | 
            |
| 70 | 
                + 'domain': settings.DOMAIN,  | 
            |
| 71 | 
                + 'chisers': chisers,  | 
            |
| 72 | 
                + 'clerk_info': clerk and clerk.data,  | 
            |
| 73 | 
                + 'modified': bool((not clerk) or (clerk and clerk.user_status in [SaleclerkInfo.UNVERIFIED, SaleclerkInfo.REFUSED])), # 是否可以更改信息  | 
            |
| 74 | 
                + })  | 
            |
| 75 | 
                +  | 
            |
| 76 | 
                +  | 
            |
| 77 | 
                +@logit  | 
            |
| 78 | 
                +@transaction.atomic  | 
            |
| 79 | 
                +def clerk_submit_api(request):  | 
            |
| 80 | 
                + """ 店员授权信息提交 """  | 
            |
| 81 | 
                +    unionid = request.POST.get('unionid', '')
               | 
            |
| 82 | 
                +    openid = request.POST.get('openid', '')
               | 
            |
| 83 | 
                +    phone = request.POST.get('phone', '')
               | 
            |
| 84 | 
                +    chiser = request.POST.get('chiser', '')
               | 
            |
| 85 | 
                +  | 
            |
| 86 | 
                + if SaleclerkInfo.objects.filter(clerk_phone=phone).exclude(unionid=unionid).exists():  | 
            |
| 87 | 
                + return response(SaleclerkStatusCode.CLERK_PHONE_ALREADY_EXISTS)  | 
            |
| 88 | 
                +  | 
            |
| 89 | 
                + try:  | 
            |
| 90 | 
                + franchiser = FranchiserInfo.objects.get(franchiser_id=chiser)  | 
            |
| 91 | 
                + except FranchiserInfo.DoesNotExist:  | 
            |
| 92 | 
                + return response(FranchiserStatusCode.CHISER_NOT_FOUND)  | 
            |
| 93 | 
                +  | 
            |
| 94 | 
                +    fields = {
               | 
            |
| 95 | 
                + 'franchiser_id': chiser,  | 
            |
| 96 | 
                + 'franchiser_name': franchiser.franchiser_name,  | 
            |
| 97 | 
                +        'clerk_name': request.POST.get('name', ''),
               | 
            |
| 98 | 
                +        'clerk_sex': int(request.POST.get('sex', 1)),
               | 
            |
| 99 | 
                + 'clerk_phone': phone,  | 
            |
| 100 | 
                + 'openid': openid,  | 
            |
| 101 | 
                + 'user_status': SaleclerkInfo.UNVERIFIED,  | 
            |
| 102 | 
                + }  | 
            |
| 103 | 
                +  | 
            |
| 104 | 
                + lensman, created = SaleclerkInfo.objects.select_for_update().get_or_create(unionid=unionid, defaults=fields)  | 
            |
| 105 | 
                + # 状态为 UNVERIFIED 的允许修改, 其他需要登录摄影师 APP 进行信息的修改  | 
            |
| 106 | 
                + if lensman.user_status not in [SaleclerkInfo.UNVERIFIED, SaleclerkInfo.REFUSED]:  | 
            |
| 107 | 
                + return response(SaleclerkInfo.LENSMAN_ALREADY_NOT_UNVERIFIED)  | 
            |
| 108 | 
                + if not created:  | 
            |
| 109 | 
                + for key, value in fields.iteritems():  | 
            |
| 110 | 
                + setattr(lensman, key, value)  | 
            |
| 111 | 
                + lensman.save()  | 
            |
| 112 | 
                +  | 
            |
| 113 | 
                +    return response(200, 'Submit Success', u'提交成功', {})
               | 
            
                @@ -0,0 +1,121 @@  | 
            ||
| 1 | 
                +# -*- coding: utf-8 -*-  | 
            |
| 2 | 
                +  | 
            |
| 3 | 
                +from __future__ import division  | 
            |
| 4 | 
                +  | 
            |
| 5 | 
                +from django.conf import settings  | 
            |
| 6 | 
                +from django.db import transaction  | 
            |
| 7 | 
                +from django.shortcuts import render  | 
            |
| 8 | 
                +from django_response import response  | 
            |
| 9 | 
                +from logit import logit  | 
            |
| 10 | 
                +  | 
            |
| 11 | 
                +from account.models import SaleclerkInfo  | 
            |
| 12 | 
                +from integral.models import SaleclerkIntegralIncomeExpensesInfo  | 
            |
| 13 | 
                +from product.models import ProductCodeSubmitLogInfo, ProductInfo, ProductModelInfo  | 
            |
| 14 | 
                +from utils.error.errno_utils import ProductModelStatusCode, ProductStatusCode, SaleclerkStatusCode  | 
            |
| 15 | 
                +  | 
            |
| 16 | 
                +  | 
            |
| 17 | 
                +def clerk_sale_oauth(request):  | 
            |
| 18 | 
                +    unionid = request.GET.get('unionid', '')
               | 
            |
| 19 | 
                +  | 
            |
| 20 | 
                + models = ProductModelInfo.objects.filter(status=True)  | 
            |
| 21 | 
                + models = [model.data for model in models]  | 
            |
| 22 | 
                +  | 
            |
| 23 | 
                + try:  | 
            |
| 24 | 
                + clerk = SaleclerkInfo.objects.get(unionid=unionid)  | 
            |
| 25 | 
                + except SaleclerkInfo.DoesNotExist:  | 
            |
| 26 | 
                + clerk = None  | 
            |
| 27 | 
                +  | 
            |
| 28 | 
                +    return render(request, 'page/clerk_sale.html', {
               | 
            |
| 29 | 
                + 'domain': settings.DOMAIN,  | 
            |
| 30 | 
                + 'models': models,  | 
            |
| 31 | 
                + 'clerk_info': clerk and clerk.data,  | 
            |
| 32 | 
                + })  | 
            |
| 33 | 
                +  | 
            |
| 34 | 
                +  | 
            |
| 35 | 
                +@logit  | 
            |
| 36 | 
                +@transaction.atomic  | 
            |
| 37 | 
                +def clerk_sale_submit_api(request):  | 
            |
| 38 | 
                + """ 店员信息提交 """  | 
            |
| 39 | 
                +    step = int(request.POST.get('step', 1))
               | 
            |
| 40 | 
                +  | 
            |
| 41 | 
                +    clerk_id = request.POST.get('clerk_id', '')
               | 
            |
| 42 | 
                +    model_id = request.POST.get('model_id', '')
               | 
            |
| 43 | 
                +    mount = request.POST.get('mount', 'NO')
               | 
            |
| 44 | 
                +    code = request.POST.get('code', '')
               | 
            |
| 45 | 
                +    name = request.POST.get('name', '')
               | 
            |
| 46 | 
                +    sex = int(request.POST.get('sex', 1))
               | 
            |
| 47 | 
                +    age = int(request.POST.get('age', 1))
               | 
            |
| 48 | 
                +    phone = request.POST.get('phone', '')
               | 
            |
| 49 | 
                +  | 
            |
| 50 | 
                + # 店员是否存在  | 
            |
| 51 | 
                + try:  | 
            |
| 52 | 
                + clerk = SaleclerkInfo.objects.select_for_update().get(clerk_id=clerk_id)  | 
            |
| 53 | 
                + except SaleclerkInfo.DoesNotExist:  | 
            |
| 54 | 
                + return response(SaleclerkStatusCode.CLERK_NOT_FOUND)  | 
            |
| 55 | 
                +  | 
            |
| 56 | 
                + # 店员是否激活  | 
            |
| 57 | 
                + if clerk.user_status != SaleclerkInfo.ACTIVATED:  | 
            |
| 58 | 
                + return response(SaleclerkStatusCode.CLERK_NOT_ACTIVATED)  | 
            |
| 59 | 
                +  | 
            |
| 60 | 
                + # 型号是否存在  | 
            |
| 61 | 
                + try:  | 
            |
| 62 | 
                + model = ProductModelInfo.objects.get(model_id=model_id)  | 
            |
| 63 | 
                + except ProductModelInfo.DoesNotExist:  | 
            |
| 64 | 
                + return response(ProductModelStatusCode.MODEL_NOT_FOUND)  | 
            |
| 65 | 
                +  | 
            |
| 66 | 
                + # 记录销售提交记录  | 
            |
| 67 | 
                + ProductCodeSubmitLogInfo.objects.create(  | 
            |
| 68 | 
                + model_id=model.model_id,  | 
            |
| 69 | 
                + model_name=model.model_name,  | 
            |
| 70 | 
                + mount=mount,  | 
            |
| 71 | 
                + code=code,  | 
            |
| 72 | 
                + franchiser_id=clerk.franchiser_id,  | 
            |
| 73 | 
                + clerk_id=clerk.clerk_id,  | 
            |
| 74 | 
                + consumer_name=name,  | 
            |
| 75 | 
                + consumer_sex=sex,  | 
            |
| 76 | 
                + consumer_age=age,  | 
            |
| 77 | 
                + consumer_phone=phone,  | 
            |
| 78 | 
                + )  | 
            |
| 79 | 
                +  | 
            |
| 80 | 
                + # 产品是否存在  | 
            |
| 81 | 
                + try:  | 
            |
| 82 | 
                + product = ProductInfo.objects.select_for_update().get(model_id=model_id, mount=mount, code=code)  | 
            |
| 83 | 
                + except ProductInfo.DoesNotExist:  | 
            |
| 84 | 
                + return response(ProductStatusCode.PRODUCT_NOT_FOUND)  | 
            |
| 85 | 
                +  | 
            |
| 86 | 
                + # 产品是否使用  | 
            |
| 87 | 
                + if step == 1 and product.code_status:  | 
            |
| 88 | 
                + return response(ProductStatusCode.PRODUCT_HAS_USED)  | 
            |
| 89 | 
                + if step == 2 and not product.code_status:  | 
            |
| 90 | 
                + return response(ProductStatusCode.PRODUCT_NOT_USED)  | 
            |
| 91 | 
                +  | 
            |
| 92 | 
                + # 产品使用  | 
            |
| 93 | 
                + product.code_status = True  | 
            |
| 94 | 
                + product.integral_status = True  | 
            |
| 95 | 
                + product.franchiser_id = clerk.franchiser_id  | 
            |
| 96 | 
                + product.clerk_id = clerk.clerk_id  | 
            |
| 97 | 
                + if 'name' in request.POST:  | 
            |
| 98 | 
                + product.consumer_name = name  | 
            |
| 99 | 
                + if 'sex' in request.POST:  | 
            |
| 100 | 
                + product.consumer_sex = sex  | 
            |
| 101 | 
                + if 'age' in request.POST:  | 
            |
| 102 | 
                + product.consumer_age = age  | 
            |
| 103 | 
                + if 'phone' in request.POST:  | 
            |
| 104 | 
                + product.consumer_phone = phone  | 
            |
| 105 | 
                + product.save()  | 
            |
| 106 | 
                +  | 
            |
| 107 | 
                + # 店员积分  | 
            |
| 108 | 
                + clerk.integral += product.integral  | 
            |
| 109 | 
                + clerk.save()  | 
            |
| 110 | 
                +  | 
            |
| 111 | 
                + # 店员积分记录  | 
            |
| 112 | 
                + SaleclerkIntegralIncomeExpensesInfo.objects.create(  | 
            |
| 113 | 
                + franchiser_id=clerk.franchiser_id,  | 
            |
| 114 | 
                + clerk_id=clerk.clerk_id,  | 
            |
| 115 | 
                + type=SaleclerkIntegralIncomeExpensesInfo.INCOME,  | 
            |
| 116 | 
                + code=code,  | 
            |
| 117 | 
                + integral=product.integral,  | 
            |
| 118 | 
                + left_integral=clerk.integral,  | 
            |
| 119 | 
                + )  | 
            |
| 120 | 
                +  | 
            |
| 121 | 
                +    return response(200, 'Submit Success', u'提交成功', {})
               | 
            
                @@ -0,0 +1,67 @@  | 
            ||
| 1 | 
                +/* Input valid or invalid */  | 
            |
| 2 | 
                +input:required:invalid {
               | 
            |
| 3 | 
                + color: #E64340;  | 
            |
| 4 | 
                +}  | 
            |
| 5 | 
                +input:required:valid {
               | 
            |
| 6 | 
                + color: rgb(0, 0, 0);  | 
            |
| 7 | 
                +}  | 
            |
| 8 | 
                +/* Input Placeholder */  | 
            |
| 9 | 
                + input::-webkit-input-placeholder, textarea::-webkit-input-placeholder {
               | 
            |
| 10 | 
                + font-size: 13px;  | 
            |
| 11 | 
                +}  | 
            |
| 12 | 
                +input:-moz-placeholder, textarea:-moz-placeholder {
               | 
            |
| 13 | 
                + font-size: 13px;  | 
            |
| 14 | 
                +}  | 
            |
| 15 | 
                +input::-moz-placeholder, textarea::-moz-placeholder {
               | 
            |
| 16 | 
                + font-size: 13px;  | 
            |
| 17 | 
                +}  | 
            |
| 18 | 
                +input:-ms-input-placeholder, textarea:-ms-input-placeholder {
               | 
            |
| 19 | 
                + font-size: 13px;  | 
            |
| 20 | 
                +}  | 
            |
| 21 | 
                +/* Radio Cells */  | 
            |
| 22 | 
                +.radio_cells {
               | 
            |
| 23 | 
                + margin-top: 0;  | 
            |
| 24 | 
                + margin-left: 15px;  | 
            |
| 25 | 
                +}  | 
            |
| 26 | 
                +.radio_cells label {
               | 
            |
| 27 | 
                + padding: 8px 10px;  | 
            |
| 28 | 
                + font-size: 15px;  | 
            |
| 29 | 
                +}  | 
            |
| 30 | 
                +/*.radio_cells>div:first-child .quartern:after {*/
               | 
            |
| 31 | 
                + /*border-left: none;*/  | 
            |
| 32 | 
                +/*}*/  | 
            |
| 33 | 
                +.radio_cells>div:last-child .quartern:after {
               | 
            |
| 34 | 
                + border-right: none;  | 
            |
| 35 | 
                +}  | 
            |
| 36 | 
                +/* Quartern */  | 
            |
| 37 | 
                +.quartern {
               | 
            |
| 38 | 
                + width: 25%;  | 
            |
| 39 | 
                + box-sizing: border-box;  | 
            |
| 40 | 
                + text-align: center;  | 
            |
| 41 | 
                + border-radius: 5px;  | 
            |
| 42 | 
                + float: left;  | 
            |
| 43 | 
                +}  | 
            |
| 44 | 
                +.quartern:after {
               | 
            |
| 45 | 
                + content: " ";  | 
            |
| 46 | 
                + width: 200%;  | 
            |
| 47 | 
                + height: 200%;  | 
            |
| 48 | 
                + position: absolute;  | 
            |
| 49 | 
                + top: 0;  | 
            |
| 50 | 
                + left: 0;  | 
            |
| 51 | 
                + border-right: 1px solid rgba(0, 0, 0, 0.2);  | 
            |
| 52 | 
                + /*border-width: 0 1px 0 1px;*/  | 
            |
| 53 | 
                + /*border-color: rgba(0, 0, 0, 0.2);*/  | 
            |
| 54 | 
                + /*border-style: solid;*/  | 
            |
| 55 | 
                + -webkit-transform: scale(0.5);  | 
            |
| 56 | 
                + transform: scale(0.5);  | 
            |
| 57 | 
                + -webkit-transform-origin: 0 0;  | 
            |
| 58 | 
                + transform-origin: 0 0;  | 
            |
| 59 | 
                + box-sizing: border-box;  | 
            |
| 60 | 
                + border-radius: 10px;  | 
            |
| 61 | 
                +}  | 
            |
| 62 | 
                +/* Radio Checked Relative */  | 
            |
| 63 | 
                +.weui_check:checked + .quartern {
               | 
            |
| 64 | 
                + color: white;  | 
            |
| 65 | 
                + background: #04BE02;  | 
            |
| 66 | 
                + border-width: 0;  | 
            |
| 67 | 
                +}  | 
            
                @@ -0,0 +1,65 @@  | 
            ||
| 1 | 
                +{% load staticfiles %}
               | 
            |
| 2 | 
                +  | 
            |
| 3 | 
                +<!DOCTYPE html>  | 
            |
| 4 | 
                +<html lang="zh-CN">  | 
            |
| 5 | 
                + <head>  | 
            |
| 6 | 
                + <meta charset="utf-8">  | 
            |
| 7 | 
                + <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">  | 
            |
| 8 | 
                + <meta name="format-detection" content="telephone=no,email=no,address=no">  | 
            |
| 9 | 
                + <meta name="viewport" content="width=device-width,initial-scale=1.0,user-scalable=no">  | 
            |
| 10 | 
                + <title>我的积分</title>  | 
            |
| 11 | 
                +  | 
            |
| 12 | 
                + <link href="//res.wx.qq.com/open/libs/weui/0.4.3/weui.min.css" rel="stylesheet" type="text/css" />  | 
            |
| 13 | 
                +        <link href="{% static 'page/css/weui.ext.css' %}?v=1" rel="stylesheet" type="text/css" />
               | 
            |
| 14 | 
                + </head>  | 
            |
| 15 | 
                + <body>  | 
            |
| 16 | 
                + <div class="container" >  | 
            |
| 17 | 
                + <div class="weui_cells_title">基本信息</div>  | 
            |
| 18 | 
                + <div class="weui_cells weui_cells_form">  | 
            |
| 19 | 
                + <div class="weui_cell">  | 
            |
| 20 | 
                + <div class="weui_cell_hd"><label for="" class="weui_label">经销商</label></div>  | 
            |
| 21 | 
                + <div class="weui_cell_bd weui_cell_primary">  | 
            |
| 22 | 
                +                        <label for="" class="weui_textarea">{{ clerk_info.franchiser_name }}</label>
               | 
            |
| 23 | 
                + </div>  | 
            |
| 24 | 
                + </div>  | 
            |
| 25 | 
                + <div class="weui_cell">  | 
            |
| 26 | 
                + <div class="weui_cell_hd"><label for="" class="weui_label">姓名</label></div>  | 
            |
| 27 | 
                + <div class="weui_cell_bd weui_cell_primary">  | 
            |
| 28 | 
                +                        <label for="" class="weui_textarea">{{ clerk_info.clerk_name }}</label>
               | 
            |
| 29 | 
                + </div>  | 
            |
| 30 | 
                + </div>  | 
            |
| 31 | 
                + <div class="weui_cell">  | 
            |
| 32 | 
                + <div class="weui_cell_hd"><label for="" class="weui_label">性别</label></div>  | 
            |
| 33 | 
                + <div class="weui_cell_bd weui_cell_primary">  | 
            |
| 34 | 
                +                        <label for="" class="weui_textarea">{% ifequal clerk_info.clerk_sex 1 %}男{% else %}女{% endifequal %}</label>
               | 
            |
| 35 | 
                + </div>  | 
            |
| 36 | 
                + </div>  | 
            |
| 37 | 
                + <div class="weui_cell">  | 
            |
| 38 | 
                + <div class="weui_cell_hd"><label for="" class="weui_label">手机号</label></div>  | 
            |
| 39 | 
                + <div class="weui_cell_bd weui_cell_primary">  | 
            |
| 40 | 
                +                        <label for="" class="weui_textarea">{{ clerk_info.clerk_phone }}</label>
               | 
            |
| 41 | 
                + </div>  | 
            |
| 42 | 
                + </div>  | 
            |
| 43 | 
                + <div class="weui_cell">  | 
            |
| 44 | 
                + <div class="weui_cell_hd"><label for="" class="weui_label">积分</label></div>  | 
            |
| 45 | 
                + <div class="weui_cell_bd weui_cell_primary">  | 
            |
| 46 | 
                +                        <label for="" class="weui_textarea">{{ clerk_info.integral }}</label>
               | 
            |
| 47 | 
                + </div>  | 
            |
| 48 | 
                + </div>  | 
            |
| 49 | 
                + </div>  | 
            |
| 50 | 
                + </div>  | 
            |
| 51 | 
                +  | 
            |
| 52 | 
                + <script type="text/javascript" src="//res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>  | 
            |
| 53 | 
                +        <script type="text/javascript" src="{% static 'pai2/js/jswe-0.0.4.js' %}"></script>
               | 
            |
| 54 | 
                + <script>  | 
            |
| 55 | 
                +            V.initWxData({
               | 
            |
| 56 | 
                + imgUrl: 'http://pai.ai/static/pai2/img/paiai_96_96.png',  | 
            |
| 57 | 
                + link: 'http://pai.ai/w/o?r=http%3A%2F%2Fkodo.xfoto.com.cn%2Fp%2Fclerk%2Finfo',  | 
            |
| 58 | 
                + desc: '店员授权',  | 
            |
| 59 | 
                + title: '店员授权',  | 
            |
| 60 | 
                + timeLine: ''  | 
            |
| 61 | 
                + }, true);  | 
            |
| 62 | 
                + V.hideOptionMenu();  | 
            |
| 63 | 
                + </script>  | 
            |
| 64 | 
                + </body>  | 
            |
| 65 | 
                +</html>  | 
            
                @@ -0,0 +1,191 @@  | 
            ||
| 1 | 
                +{% load staticfiles %}
               | 
            |
| 2 | 
                +  | 
            |
| 3 | 
                +<!DOCTYPE html>  | 
            |
| 4 | 
                +<html lang="zh-CN">  | 
            |
| 5 | 
                + <head>  | 
            |
| 6 | 
                + <meta charset="utf-8">  | 
            |
| 7 | 
                + <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">  | 
            |
| 8 | 
                + <meta name="format-detection" content="telephone=no,email=no,address=no">  | 
            |
| 9 | 
                + <meta name="viewport" content="width=device-width,initial-scale=1.0,user-scalable=no">  | 
            |
| 10 | 
                + <title>店员授权</title>  | 
            |
| 11 | 
                +  | 
            |
| 12 | 
                + <link href="//res.wx.qq.com/open/libs/weui/0.4.3/weui.min.css" rel="stylesheet" type="text/css" />  | 
            |
| 13 | 
                +        <link href="{% static 'page/css/weui.ext.css' %}?v=1" rel="stylesheet" type="text/css" />
               | 
            |
| 14 | 
                + </head>  | 
            |
| 15 | 
                + <body>  | 
            |
| 16 | 
                + <div class="container" >  | 
            |
| 17 | 
                + <div class="weui_cells_title">基本信息</div>  | 
            |
| 18 | 
                + <div class="weui_cells weui_cells_form">  | 
            |
| 19 | 
                + <div class="weui_cell weui_cell_select weui_select_after">  | 
            |
| 20 | 
                + <div class="weui_cell_hd"><label for="" class="weui_label">经销商</label></div>  | 
            |
| 21 | 
                + <div class="weui_cell_bd weui_cell_primary">  | 
            |
| 22 | 
                +                        <select id="chiser" class="weui_select" name="select" {% if not modified %}disabled{% endif %}>
               | 
            |
| 23 | 
                +                            {% for chiser in chisers %}
               | 
            |
| 24 | 
                +                            <option value="{{ chiser.franchiser_id }}" {% ifequal chiser.franchiser_id clerk_info.franchiser_id %}selected{% endifequal %}>{{ chiser.franchiser_name }}</option>
               | 
            |
| 25 | 
                +                            {% endfor %}
               | 
            |
| 26 | 
                + </select>  | 
            |
| 27 | 
                + </div>  | 
            |
| 28 | 
                + </div>  | 
            |
| 29 | 
                + <div class="weui_cell">  | 
            |
| 30 | 
                + <div class="weui_cell_hd"><label for="" class="weui_label">姓名</label></div>  | 
            |
| 31 | 
                + <div class="weui_cell_bd weui_cell_primary">  | 
            |
| 32 | 
                +                        <input id="name" class="weui_input" type="text" value="{{ clerk_info.clerk_name }}" placeholder="请输入姓名" {% if not modified %}disabled{% endif %}>
               | 
            |
| 33 | 
                + </div>  | 
            |
| 34 | 
                + </div>  | 
            |
| 35 | 
                + <div class="weui_cell weui_cell_select weui_select_after">  | 
            |
| 36 | 
                + <div class="weui_cell_hd"><label for="" class="weui_label">性别</label></div>  | 
            |
| 37 | 
                + <div class="weui_cell_bd weui_cell_primary">  | 
            |
| 38 | 
                +                        <select id="sex" class="weui_select" name="select" {% if not modified %}disabled{% endif %}>
               | 
            |
| 39 | 
                +                            <option value="1" {% ifequal clerk_info.clerk_sex 1 %}selected{% endifequal %}>男</option>
               | 
            |
| 40 | 
                +                            <option value="0" {% ifequal clerk_info.clerk_sex 0 %}selected{% endifequal %}>女</option>
               | 
            |
| 41 | 
                + </select>  | 
            |
| 42 | 
                + </div>  | 
            |
| 43 | 
                + </div>  | 
            |
| 44 | 
                + <div class="weui_cell">  | 
            |
| 45 | 
                + <div class="weui_cell_hd"><label for="" class="weui_label">手机号</label></div>  | 
            |
| 46 | 
                + <div class="weui_cell_bd weui_cell_primary">  | 
            |
| 47 | 
                +                        <input id="phone" class="weui_input" type="text" required="required" pattern="[0-9]{11}" value="{{ clerk_info.clerk_phone }}" placeholder="请输入手机号" {% if not modified %}disabled{% endif %}>
               | 
            |
| 48 | 
                + </div>  | 
            |
| 49 | 
                + </div>  | 
            |
| 50 | 
                + </div>  | 
            |
| 51 | 
                +  | 
            |
| 52 | 
                +            {% if clerk_info %}
               | 
            |
| 53 | 
                + <div class="weui_cells_title">审核状态</div>  | 
            |
| 54 | 
                + <div class="weui_cells">  | 
            |
| 55 | 
                + <div class="weui_cell">  | 
            |
| 56 | 
                + <div class="weui_cell_bd weui_cell_primary">  | 
            |
| 57 | 
                + <p>状态</p>  | 
            |
| 58 | 
                + </div>  | 
            |
| 59 | 
                + <div class="weui_cell_ft">  | 
            |
| 60 | 
                +                        {% ifequal clerk_info.status -1 %}已拒绝{% endifequal %}
               | 
            |
| 61 | 
                +                        {% ifequal clerk_info.status 0 %}审核中{% endifequal %}
               | 
            |
| 62 | 
                +                        {% ifequal clerk_info.status 1 %}已激活{% endifequal %}
               | 
            |
| 63 | 
                +                        {% ifequal clerk_info.status 2 %}已禁用{% endifequal %}
               | 
            |
| 64 | 
                +                        {% ifequal clerk_info.status 3 %}已删除{% endifequal %}
               | 
            |
| 65 | 
                + </div>  | 
            |
| 66 | 
                + </div>  | 
            |
| 67 | 
                + </div>  | 
            |
| 68 | 
                +            {% endif %}
               | 
            |
| 69 | 
                +  | 
            |
| 70 | 
                +  | 
            |
| 71 | 
                +            {% ifequal clerk_info.status -1 %}
               | 
            |
| 72 | 
                + <div class="weui_cells_title">拒绝原因</div>  | 
            |
| 73 | 
                + <div class="weui_cells">  | 
            |
| 74 | 
                + <div class="weui_panel_bd">  | 
            |
| 75 | 
                + <div class="weui_media_box weui_media_text">  | 
            |
| 76 | 
                +                        <p class="weui_media_desc">{{ clerk_info.refused_reason|safe|linebreaks }}</p>
               | 
            |
| 77 | 
                + </div>  | 
            |
| 78 | 
                + </div>  | 
            |
| 79 | 
                + </div>  | 
            |
| 80 | 
                +            {% endifequal %}
               | 
            |
| 81 | 
                +  | 
            |
| 82 | 
                + <br>  | 
            |
| 83 | 
                +  | 
            |
| 84 | 
                +            {% if modified %}<button id="submit" class="weui_btn weui_btn_warn">确认</button>{% endif %}
               | 
            |
| 85 | 
                +  | 
            |
| 86 | 
                + <div class="weui_dialog_alert" id="dialog" style="display: none">  | 
            |
| 87 | 
                + <div class="weui_mask"></div>  | 
            |
| 88 | 
                + <div class="weui_dialog">  | 
            |
| 89 | 
                + <div class="weui_dialog_hd"><strong id="title" class="weui_dialog_title">弹窗标题</strong></div>  | 
            |
| 90 | 
                + <div id="content" class="weui_dialog_bd">弹窗内容,告知当前页面信息等</div>  | 
            |
| 91 | 
                + <div class="weui_dialog_ft">  | 
            |
| 92 | 
                + <a href="javascript:;" class="weui_btn_dialog primary">确定</a>  | 
            |
| 93 | 
                + </div>  | 
            |
| 94 | 
                + </div>  | 
            |
| 95 | 
                + </div>  | 
            |
| 96 | 
                +  | 
            |
| 97 | 
                + <div id="toast" style="display: none;">  | 
            |
| 98 | 
                + <div class="weui_mask_transparent"></div>  | 
            |
| 99 | 
                + <div class="weui_toast">  | 
            |
| 100 | 
                + <i class="weui_icon_toast"></i>  | 
            |
| 101 | 
                + <p class="weui_toast_content">已完成</p>  | 
            |
| 102 | 
                + </div>  | 
            |
| 103 | 
                + </div>  | 
            |
| 104 | 
                + </div>  | 
            |
| 105 | 
                +  | 
            |
| 106 | 
                + <script src="//cdn.bootcss.com/zepto/1.1.6/zepto.min.js"></script>  | 
            |
| 107 | 
                + <script>  | 
            |
| 108 | 
                +            {% if modified %}
               | 
            |
| 109 | 
                +            $(function() {
               | 
            |
| 110 | 
                +                function getURLParameter(name) {
               | 
            |
| 111 | 
                +                  return decodeURIComponent((new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)').exec(location.search) || [null, ''])[1].replace(/\+/g, '%20')) || null;
               | 
            |
| 112 | 
                + }  | 
            |
| 113 | 
                +  | 
            |
| 114 | 
                +                function show_error_dialog(title, content) {
               | 
            |
| 115 | 
                +                    $('#dialog #title').text(title);
               | 
            |
| 116 | 
                +                    $('#dialog #content').text(content);
               | 
            |
| 117 | 
                +                    $('#dialog').show();
               | 
            |
| 118 | 
                + }  | 
            |
| 119 | 
                +  | 
            |
| 120 | 
                +                function data_check() {
               | 
            |
| 121 | 
                +                    var unionid = getURLParameter('unionid');
               | 
            |
| 122 | 
                +                    if (!unionid) {
               | 
            |
| 123 | 
                +                        show_error_dialog('微信授权', '微信授权失败,请重新打开页面');
               | 
            |
| 124 | 
                + return false;  | 
            |
| 125 | 
                + }  | 
            |
| 126 | 
                +  | 
            |
| 127 | 
                +                    var name = $('#name').val();
               | 
            |
| 128 | 
                +                    if (!name) {
               | 
            |
| 129 | 
                +                        show_error_dialog('姓名', '姓名错误,请检查重新输入');
               | 
            |
| 130 | 
                + return false;  | 
            |
| 131 | 
                + }  | 
            |
| 132 | 
                +  | 
            |
| 133 | 
                +                    var phone = $('#phone').val();
               | 
            |
| 134 | 
                +                    var phone_valid = $('#phone').is(':valid');
               | 
            |
| 135 | 
                +                    if (!(phone && phone_valid)) {
               | 
            |
| 136 | 
                +                        show_error_dialog('手机号', '手机号错误,请检查重新输入');
               | 
            |
| 137 | 
                + return false;  | 
            |
| 138 | 
                + }  | 
            |
| 139 | 
                +  | 
            |
| 140 | 
                +                    return {
               | 
            |
| 141 | 
                + unionid: unionid,  | 
            |
| 142 | 
                +                        openid: getURLParameter('openid'),
               | 
            |
| 143 | 
                +                        chiser: $('#chiser option:checked').val(),
               | 
            |
| 144 | 
                + name: name,  | 
            |
| 145 | 
                +                        sex: $('#sex option:checked').val(),
               | 
            |
| 146 | 
                + phone: phone,  | 
            |
| 147 | 
                + }  | 
            |
| 148 | 
                + }  | 
            |
| 149 | 
                +  | 
            |
| 150 | 
                +                $('#submit').click(function () {
               | 
            |
| 151 | 
                + var check_result = data_check();  | 
            |
| 152 | 
                +                    if (check_result){
               | 
            |
| 153 | 
                +                        $.ajax({
               | 
            |
| 154 | 
                + type: 'POST',  | 
            |
| 155 | 
                +                            url: '{{ domain }}/api/clerk/submit',
               | 
            |
| 156 | 
                + data: check_result,  | 
            |
| 157 | 
                +                            success: function(data) {
               | 
            |
| 158 | 
                +                                if (data.status == 200) {
               | 
            |
| 159 | 
                +                                    $('#toast').show();
               | 
            |
| 160 | 
                +                                    setTimeout(function () {
               | 
            |
| 161 | 
                +                                        $('#toast').hide();
               | 
            |
| 162 | 
                + }, 1000);  | 
            |
| 163 | 
                + window.location.reload();  | 
            |
| 164 | 
                +                                } else {
               | 
            |
| 165 | 
                +                                    show_error_dialog('错误', data.description);
               | 
            |
| 166 | 
                + }  | 
            |
| 167 | 
                + }  | 
            |
| 168 | 
                + })  | 
            |
| 169 | 
                + }  | 
            |
| 170 | 
                + });  | 
            |
| 171 | 
                +  | 
            |
| 172 | 
                +                $('#dialog .weui_btn_dialog').click(function () {
               | 
            |
| 173 | 
                +                    $('#dialog').hide();
               | 
            |
| 174 | 
                + })  | 
            |
| 175 | 
                + });  | 
            |
| 176 | 
                +            {% endif %}
               | 
            |
| 177 | 
                + </script>  | 
            |
| 178 | 
                + <script type="text/javascript" src="//res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>  | 
            |
| 179 | 
                +        <script type="text/javascript" src="{% static 'pai2/js/jswe-0.0.4.js' %}"></script>
               | 
            |
| 180 | 
                + <script>  | 
            |
| 181 | 
                +            V.initWxData({
               | 
            |
| 182 | 
                + imgUrl: 'http://pai.ai/static/pai2/img/paiai_96_96.png',  | 
            |
| 183 | 
                + link: 'http://pai.ai/w/o?r=http%3A%2F%2Fkodo.xfoto.com.cn%2Fp%2Fclerk',  | 
            |
| 184 | 
                + desc: '店员授权',  | 
            |
| 185 | 
                + title: '店员授权',  | 
            |
| 186 | 
                + timeLine: ''  | 
            |
| 187 | 
                + }, true);  | 
            |
| 188 | 
                + V.hideOptionMenu();  | 
            |
| 189 | 
                + </script>  | 
            |
| 190 | 
                + </body>  | 
            |
| 191 | 
                +</html>  | 
            
                @@ -0,0 +1,366 @@  | 
            ||
| 1 | 
                +{% load staticfiles %}
               | 
            |
| 2 | 
                +  | 
            |
| 3 | 
                +<!DOCTYPE html>  | 
            |
| 4 | 
                +<html lang="zh-CN">  | 
            |
| 5 | 
                + <head>  | 
            |
| 6 | 
                + <meta charset="utf-8">  | 
            |
| 7 | 
                + <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">  | 
            |
| 8 | 
                + <meta name="format-detection" content="telephone=no,email=no,address=no">  | 
            |
| 9 | 
                + <meta name="viewport" content="width=device-width,initial-scale=1.0,user-scalable=no">  | 
            |
| 10 | 
                + <title>店员销售</title>  | 
            |
| 11 | 
                +  | 
            |
| 12 | 
                + <link href="//res.wx.qq.com/open/libs/weui/0.4.3/weui.min.css" rel="stylesheet" type="text/css" />  | 
            |
| 13 | 
                +        <link href="{% static 'page/css/weui.ext.css' %}?v=1" rel="stylesheet" type="text/css" />
               | 
            |
| 14 | 
                + </head>  | 
            |
| 15 | 
                + <body>  | 
            |
| 16 | 
                + <div class="container" >  | 
            |
| 17 | 
                + <div id="machine_info">  | 
            |
| 18 | 
                + <div class="weui_cells_title">机器信息</div>  | 
            |
| 19 | 
                + <div class="weui_cells weui_cells_form">  | 
            |
| 20 | 
                + <div class="weui_cell">  | 
            |
| 21 | 
                + <div class="weui_cell_hd"><label for="" class="weui_label">型号</label></div>  | 
            |
| 22 | 
                + <div class="weui_cell_bd weui_cell_primary">  | 
            |
| 23 | 
                + <input id="model" class="weui_input" type="text" value="" placeholder="请选择相机型号" disabled>  | 
            |
| 24 | 
                + </div>  | 
            |
| 25 | 
                + </div>  | 
            |
| 26 | 
                + <div id="model_radio" class="weui_cells weui_cells_radio radio_cells">  | 
            |
| 27 | 
                +                        {% for model in models %}
               | 
            |
| 28 | 
                + <div>  | 
            |
| 29 | 
                +                            <input type="radio" class="weui_check" name="model" id="{{ model.model_id }}" value="{{ model.model_id }}" {% if forloop.first %}checked="checked"{% endif %}>
               | 
            |
| 30 | 
                +                            <label class="weui_cell weui_check_label quartern" for="{{ model.model_id }}">
               | 
            |
| 31 | 
                +                                <div class="weui_cell_bd weui_cell_primary">{{ model.model_name }}</div>
               | 
            |
| 32 | 
                + </label>  | 
            |
| 33 | 
                + </div>  | 
            |
| 34 | 
                +                        {% endfor %}
               | 
            |
| 35 | 
                + </div>  | 
            |
| 36 | 
                + <div class="weui_cell">  | 
            |
| 37 | 
                + <div class="weui_cell_hd"><label for="" class="weui_label">卡口</label></div>  | 
            |
| 38 | 
                + <div class="weui_cell_bd weui_cell_primary">  | 
            |
| 39 | 
                + <input id="mount" class="weui_input" type="text" value="" placeholder="请选择相机卡口" disabled>  | 
            |
| 40 | 
                + </div>  | 
            |
| 41 | 
                + </div>  | 
            |
| 42 | 
                + <div id="mount_radio" class="weui_cells weui_cells_radio radio_cells">  | 
            |
| 43 | 
                + <div>  | 
            |
| 44 | 
                + <input type="radio" class="weui_check" name="mount" id="e" value="E" checked="checked">  | 
            |
| 45 | 
                + <label class="weui_cell weui_check_label quartern" for="e">  | 
            |
| 46 | 
                + <div class="weui_cell_bd weui_cell_primary">E</div>  | 
            |
| 47 | 
                + </label>  | 
            |
| 48 | 
                + </div>  | 
            |
| 49 | 
                + <div>  | 
            |
| 50 | 
                + <input type="radio" class="weui_check" name="mount" id="n" value="N">  | 
            |
| 51 | 
                + <label class="weui_cell weui_check_label quartern" for="n">  | 
            |
| 52 | 
                + <div class="weui_cell_bd weui_cell_primary">N</div>  | 
            |
| 53 | 
                + </label>  | 
            |
| 54 | 
                + </div>  | 
            |
| 55 | 
                + <div>  | 
            |
| 56 | 
                + <input type="radio" class="weui_check" name="mount" id="s" value="S">  | 
            |
| 57 | 
                + <label class="weui_cell weui_check_label quartern" for="s">  | 
            |
| 58 | 
                + <div class="weui_cell_bd weui_cell_primary">S</div>  | 
            |
| 59 | 
                + </label>  | 
            |
| 60 | 
                + </div>  | 
            |
| 61 | 
                + <div>  | 
            |
| 62 | 
                + <input type="radio" class="weui_check" name="mount" id="p" value="P">  | 
            |
| 63 | 
                + <label class="weui_cell weui_check_label quartern" for="p">  | 
            |
| 64 | 
                + <div class="weui_cell_bd weui_cell_primary">P</div>  | 
            |
| 65 | 
                + </label>  | 
            |
| 66 | 
                + </div>  | 
            |
| 67 | 
                + </div>  | 
            |
| 68 | 
                + <div class="weui_cell">  | 
            |
| 69 | 
                + <div class="weui_cell_hd"><label for="" class="weui_label">机身码</label></div>  | 
            |
| 70 | 
                + <div class="weui_cell_bd weui_cell_primary">  | 
            |
| 71 | 
                + <input id="code" class="weui_input" type="text" value="" placeholder="请输入机身码">  | 
            |
| 72 | 
                + </div>  | 
            |
| 73 | 
                + <div class="weui_cell_ft">  | 
            |
| 74 | 
                + <a id="scan" href="javascript:;" class="weui_btn weui_btn_mini weui_btn_default">扫码</a>  | 
            |
| 75 | 
                + </div>  | 
            |
| 76 | 
                + </div>  | 
            |
| 77 | 
                + </div>  | 
            |
| 78 | 
                +  | 
            |
| 79 | 
                + <br>  | 
            |
| 80 | 
                +  | 
            |
| 81 | 
                + <button id="submit1" class="weui_btn weui_btn_warn">确认</button>  | 
            |
| 82 | 
                + </div>  | 
            |
| 83 | 
                +  | 
            |
| 84 | 
                + <div id="customer_info" style="display: none;">  | 
            |
| 85 | 
                + <div class="weui_cells_title">消费者信息</div>  | 
            |
| 86 | 
                + <div class="weui_cells weui_cells_form">  | 
            |
| 87 | 
                + <div class="weui_cell">  | 
            |
| 88 | 
                + <div class="weui_cell_hd"><label for="" class="weui_label">姓名</label></div>  | 
            |
| 89 | 
                + <div class="weui_cell_bd weui_cell_primary">  | 
            |
| 90 | 
                + <input id="name" class="weui_input" type="text" value="" placeholder="请输入消费者姓名">  | 
            |
| 91 | 
                + </div>  | 
            |
| 92 | 
                + </div>  | 
            |
| 93 | 
                + <div class="weui_cell">  | 
            |
| 94 | 
                + <div class="weui_cell_hd"><label for="" class="weui_label">性别</label></div>  | 
            |
| 95 | 
                + <div class="weui_cell_bd weui_cell_primary">  | 
            |
| 96 | 
                + <input id="sex" class="weui_input" type="text" value="" placeholder="请选择消费者性别" disabled>  | 
            |
| 97 | 
                + </div>  | 
            |
| 98 | 
                + </div>  | 
            |
| 99 | 
                + <div id="sex_radio" class="weui_cells weui_cells_radio radio_cells">  | 
            |
| 100 | 
                + <div>  | 
            |
| 101 | 
                + <input type="radio" class="weui_check" name="sex" id="male" value="1" checked="checked">  | 
            |
| 102 | 
                + <label class="weui_cell weui_check_label quartern" for="male">  | 
            |
| 103 | 
                + <div class="weui_cell_bd weui_cell_primary">先生</div>  | 
            |
| 104 | 
                + </label>  | 
            |
| 105 | 
                + </div>  | 
            |
| 106 | 
                + <div>  | 
            |
| 107 | 
                + <input type="radio" class="weui_check" name="sex" id="female" value="0">  | 
            |
| 108 | 
                + <label class="weui_cell weui_check_label quartern" for="female">  | 
            |
| 109 | 
                + <div class="weui_cell_bd weui_cell_primary">女士</div>  | 
            |
| 110 | 
                + </label>  | 
            |
| 111 | 
                + </div>  | 
            |
| 112 | 
                + </div>  | 
            |
| 113 | 
                + <div class="weui_cell">  | 
            |
| 114 | 
                + <div class="weui_cell_hd"><label for="" class="weui_label">年龄段</label></div>  | 
            |
| 115 | 
                + <div class="weui_cell_bd weui_cell_primary">  | 
            |
| 116 | 
                + <input id="age" class="weui_input" type="text" value="" placeholder="请选择消费者年龄段" disabled>  | 
            |
| 117 | 
                + </div>  | 
            |
| 118 | 
                + </div>  | 
            |
| 119 | 
                + <div id="age_radio" class="weui_cells weui_cells_radio radio_cells">  | 
            |
| 120 | 
                + <div>  | 
            |
| 121 | 
                + <input type="radio" class="weui_check" name="age" id="age1" value="1" checked="checked">  | 
            |
| 122 | 
                + <label class="weui_cell weui_check_label quartern" for="age1">  | 
            |
| 123 | 
                + <div class="weui_cell_bd weui_cell_primary">20岁以下</div>  | 
            |
| 124 | 
                + </label>  | 
            |
| 125 | 
                + </div>  | 
            |
| 126 | 
                + <div>  | 
            |
| 127 | 
                + <input type="radio" class="weui_check" name="age" id="age2" value="2">  | 
            |
| 128 | 
                + <label class="weui_cell weui_check_label quartern" for="age2">  | 
            |
| 129 | 
                + <div class="weui_cell_bd weui_cell_primary">20~30岁</div>  | 
            |
| 130 | 
                + </label>  | 
            |
| 131 | 
                + </div>  | 
            |
| 132 | 
                + <div>  | 
            |
| 133 | 
                + <input type="radio" class="weui_check" name="age" id="age3" value="3">  | 
            |
| 134 | 
                + <label class="weui_cell weui_check_label quartern" for="age3">  | 
            |
| 135 | 
                + <div class="weui_cell_bd weui_cell_primary">30~40岁</div>  | 
            |
| 136 | 
                + </label>  | 
            |
| 137 | 
                + </div>  | 
            |
| 138 | 
                + <div>  | 
            |
| 139 | 
                + <input type="radio" class="weui_check" name="age" id="age4" value="4">  | 
            |
| 140 | 
                + <label class="weui_cell weui_check_label quartern" for="age4">  | 
            |
| 141 | 
                + <div class="weui_cell_bd weui_cell_primary">40~50岁</div>  | 
            |
| 142 | 
                + </label>  | 
            |
| 143 | 
                + </div>  | 
            |
| 144 | 
                + <div>  | 
            |
| 145 | 
                + <input type="radio" class="weui_check" name="age" id="age5" value="5">  | 
            |
| 146 | 
                + <label class="weui_cell weui_check_label quartern" for="age5">  | 
            |
| 147 | 
                + <div class="weui_cell_bd weui_cell_primary">50岁以上</div>  | 
            |
| 148 | 
                + </label>  | 
            |
| 149 | 
                + </div>  | 
            |
| 150 | 
                + </div>  | 
            |
| 151 | 
                + <div class="weui_cell">  | 
            |
| 152 | 
                + <div class="weui_cell_hd"><label for="" class="weui_label">手机号</label></div>  | 
            |
| 153 | 
                + <div class="weui_cell_bd weui_cell_primary">  | 
            |
| 154 | 
                +                            <input id="phone" class="weui_input" type="text" required="required" pattern="1[0-9]{10}" value="" placeholder="请输入消费者手机号">
               | 
            |
| 155 | 
                + </div>  | 
            |
| 156 | 
                + </div>  | 
            |
| 157 | 
                + </div>  | 
            |
| 158 | 
                +  | 
            |
| 159 | 
                + <br>  | 
            |
| 160 | 
                +  | 
            |
| 161 | 
                + <button id="submit2" class="weui_btn weui_btn_warn">确认</button>  | 
            |
| 162 | 
                + </div>  | 
            |
| 163 | 
                +  | 
            |
| 164 | 
                + <div class="weui_dialog_alert" id="dialog" style="display: none">  | 
            |
| 165 | 
                + <div class="weui_mask"></div>  | 
            |
| 166 | 
                + <div class="weui_dialog">  | 
            |
| 167 | 
                + <div class="weui_dialog_hd"><strong id="title" class="weui_dialog_title">弹窗标题</strong></div>  | 
            |
| 168 | 
                + <div id="content" class="weui_dialog_bd">弹窗内容,告知当前页面信息等</div>  | 
            |
| 169 | 
                + <div class="weui_dialog_ft">  | 
            |
| 170 | 
                + <a href="javascript:;" class="weui_btn_dialog primary">确定</a>  | 
            |
| 171 | 
                + </div>  | 
            |
| 172 | 
                + </div>  | 
            |
| 173 | 
                + </div>  | 
            |
| 174 | 
                +  | 
            |
| 175 | 
                + <div class="weui_dialog_alert" id="dialog2" style="display: none">  | 
            |
| 176 | 
                + <div class="weui_mask"></div>  | 
            |
| 177 | 
                + <div class="weui_dialog">  | 
            |
| 178 | 
                + <div class="weui_dialog_hd"><strong id="title" class="weui_dialog_title">弹窗标题</strong></div>  | 
            |
| 179 | 
                + <div id="content" class="weui_dialog_bd">弹窗内容,告知当前页面信息等</div>  | 
            |
| 180 | 
                + <div class="weui_dialog_ft">  | 
            |
| 181 | 
                + <a href="javascript:;" class="weui_btn_dialog primary">确定</a>  | 
            |
| 182 | 
                + </div>  | 
            |
| 183 | 
                + </div>  | 
            |
| 184 | 
                + </div>  | 
            |
| 185 | 
                +  | 
            |
| 186 | 
                + <div class="weui_dialog_alert" id="dialog3" style="display: none">  | 
            |
| 187 | 
                + <div class="weui_mask"></div>  | 
            |
| 188 | 
                + <div class="weui_dialog">  | 
            |
| 189 | 
                + <div class="weui_dialog_hd"><strong id="title" class="weui_dialog_title">弹窗标题</strong></div>  | 
            |
| 190 | 
                + <div id="content" class="weui_dialog_bd">弹窗内容,告知当前页面信息等</div>  | 
            |
| 191 | 
                + <div class="weui_dialog_ft">  | 
            |
| 192 | 
                + <a href="javascript:;" class="weui_btn_dialog primary">确定</a>  | 
            |
| 193 | 
                + </div>  | 
            |
| 194 | 
                + </div>  | 
            |
| 195 | 
                + </div>  | 
            |
| 196 | 
                +  | 
            |
| 197 | 
                + <div id="toast" style="display: none;">  | 
            |
| 198 | 
                + <div class="weui_mask_transparent"></div>  | 
            |
| 199 | 
                + <div class="weui_toast">  | 
            |
| 200 | 
                + <i class="weui_icon_toast"></i>  | 
            |
| 201 | 
                + <p class="weui_toast_content">已完成</p>  | 
            |
| 202 | 
                + </div>  | 
            |
| 203 | 
                + </div>  | 
            |
| 204 | 
                + </div>  | 
            |
| 205 | 
                +  | 
            |
| 206 | 
                + <script src="//cdn.bootcss.com/zepto/1.1.6/zepto.min.js"></script>  | 
            |
| 207 | 
                + <script>  | 
            |
| 208 | 
                +            $(function() {
               | 
            |
| 209 | 
                +                function show_error_dialog(title, content) {
               | 
            |
| 210 | 
                +                    $('#dialog #title').text(title);
               | 
            |
| 211 | 
                +                    $('#dialog #content').text(content);
               | 
            |
| 212 | 
                +                    $('#dialog').show();
               | 
            |
| 213 | 
                + }  | 
            |
| 214 | 
                +  | 
            |
| 215 | 
                +                function show_error_dialog2(title, content) {
               | 
            |
| 216 | 
                +                    $('#dialog2 #title').text(title);
               | 
            |
| 217 | 
                +                    $('#dialog2 #content').text(content);
               | 
            |
| 218 | 
                +                    $('#dialog2').show();
               | 
            |
| 219 | 
                + }  | 
            |
| 220 | 
                +  | 
            |
| 221 | 
                +                function show_error_dialog3(title, content) {
               | 
            |
| 222 | 
                +                    $('#dialog3 #title').text(title);
               | 
            |
| 223 | 
                +                    $('#dialog3 #content').text(content);
               | 
            |
| 224 | 
                +                    $('#dialog3').show();
               | 
            |
| 225 | 
                + }  | 
            |
| 226 | 
                +  | 
            |
| 227 | 
                +                function data_check() {
               | 
            |
| 228 | 
                +                    var clerk_id = "{{ clerk_info.clerk_id }}";
               | 
            |
| 229 | 
                +                    if (!clerk_id) {
               | 
            |
| 230 | 
                +                        show_error_dialog('微信授权', '微信授权失败,请重新打开页面');
               | 
            |
| 231 | 
                + return false;  | 
            |
| 232 | 
                + }  | 
            |
| 233 | 
                +  | 
            |
| 234 | 
                +                    var code = $('#code').val();
               | 
            |
| 235 | 
                +                    if (!code) {
               | 
            |
| 236 | 
                +                        show_error_dialog('机身码', '机身码错误,请检查重新输入');
               | 
            |
| 237 | 
                + return false;  | 
            |
| 238 | 
                + }  | 
            |
| 239 | 
                +  | 
            |
| 240 | 
                +                    return {
               | 
            |
| 241 | 
                + step: 1,  | 
            |
| 242 | 
                + clerk_id: clerk_id,  | 
            |
| 243 | 
                +                        model_id: $("#model_radio input[name='model']:checked").val(),
               | 
            |
| 244 | 
                +                        mount: $("#mount_radio input[name='mount']:checked").val(),
               | 
            |
| 245 | 
                + code: code,  | 
            |
| 246 | 
                + }  | 
            |
| 247 | 
                + }  | 
            |
| 248 | 
                +  | 
            |
| 249 | 
                +                function data_check2() {
               | 
            |
| 250 | 
                +                    var clerk_id = "{{ clerk_info.clerk_id }}";
               | 
            |
| 251 | 
                +                    if (!clerk_id) {
               | 
            |
| 252 | 
                +                        show_error_dialog('微信授权', '微信授权失败,请重新打开页面');
               | 
            |
| 253 | 
                + return false;  | 
            |
| 254 | 
                + }  | 
            |
| 255 | 
                +  | 
            |
| 256 | 
                +                    var code = $('#code').val();
               | 
            |
| 257 | 
                +                    if (!code) {
               | 
            |
| 258 | 
                +                        show_error_dialog('机身码', '机身码错误,请检查重新输入');
               | 
            |
| 259 | 
                + return false;  | 
            |
| 260 | 
                + }  | 
            |
| 261 | 
                +  | 
            |
| 262 | 
                +                    var name = $('#name').val();
               | 
            |
| 263 | 
                +                    if (!name) {
               | 
            |
| 264 | 
                +                        show_error_dialog('姓名', '姓名错误,请检查重新输入');
               | 
            |
| 265 | 
                + return false;  | 
            |
| 266 | 
                + }  | 
            |
| 267 | 
                +  | 
            |
| 268 | 
                +                    var phone = $('#phone').val();
               | 
            |
| 269 | 
                +                    var phone_valid = $('#phone').is(':valid');
               | 
            |
| 270 | 
                +                    if (!(phone && phone_valid)) {
               | 
            |
| 271 | 
                +                        show_error_dialog('手机号', '手机号错误,请检查重新输入');
               | 
            |
| 272 | 
                + return false;  | 
            |
| 273 | 
                + }  | 
            |
| 274 | 
                +  | 
            |
| 275 | 
                +                    return {
               | 
            |
| 276 | 
                + step: 2,  | 
            |
| 277 | 
                + clerk_id: clerk_id,  | 
            |
| 278 | 
                +                        model_id: $("#model_radio input[name='model']:checked").val(),
               | 
            |
| 279 | 
                +                        mount: $("#mount_radio input[name='mount']:checked").val(),
               | 
            |
| 280 | 
                + code: code,  | 
            |
| 281 | 
                + name: name,  | 
            |
| 282 | 
                +                        sex: $("#sex_radio input[name='sex']:checked").val(),
               | 
            |
| 283 | 
                +                        age: $("#age_radio input[name='age']:checked").val(),
               | 
            |
| 284 | 
                + phone: phone,  | 
            |
| 285 | 
                + }  | 
            |
| 286 | 
                + }  | 
            |
| 287 | 
                +  | 
            |
| 288 | 
                +                $('#submit1').click(function () {
               | 
            |
| 289 | 
                + var check_result = data_check();  | 
            |
| 290 | 
                +                    if (check_result){
               | 
            |
| 291 | 
                +                        $.ajax({
               | 
            |
| 292 | 
                + type: 'POST',  | 
            |
| 293 | 
                +                            url: '{{ domain }}/api/clerk/sale/submit',
               | 
            |
| 294 | 
                + data: check_result,  | 
            |
| 295 | 
                +                            success: function(data) {
               | 
            |
| 296 | 
                +                                if (data.status == 200) {
               | 
            |
| 297 | 
                +{#                                    $('#toast').show();#}
               | 
            |
| 298 | 
                +{#                                    setTimeout(function () {#}
               | 
            |
| 299 | 
                +{#                                        $('#toast').hide();#}
               | 
            |
| 300 | 
                +{#                                    }, 1000);#}
               | 
            |
| 301 | 
                +                                    show_error_dialog2('成功', '机器信息提交成功');
               | 
            |
| 302 | 
                +                                } else {
               | 
            |
| 303 | 
                +                                    show_error_dialog('错误', data.description);
               | 
            |
| 304 | 
                + }  | 
            |
| 305 | 
                + }  | 
            |
| 306 | 
                + })  | 
            |
| 307 | 
                + }  | 
            |
| 308 | 
                + });  | 
            |
| 309 | 
                +  | 
            |
| 310 | 
                +                $('#submit2').click(function () {
               | 
            |
| 311 | 
                + var check_result = data_check2();  | 
            |
| 312 | 
                +                    if (check_result){
               | 
            |
| 313 | 
                +                        $.ajax({
               | 
            |
| 314 | 
                + type: 'POST',  | 
            |
| 315 | 
                +                            url: '{{ domain }}/api/clerk/sale/submit',
               | 
            |
| 316 | 
                + data: check_result,  | 
            |
| 317 | 
                +                            success: function(data) {
               | 
            |
| 318 | 
                +                                if (data.status == 200) {
               | 
            |
| 319 | 
                +                                    show_error_dialog3('成功', '消费者信息提交成功');
               | 
            |
| 320 | 
                +                                } else {
               | 
            |
| 321 | 
                +                                    show_error_dialog('错误', data.description);
               | 
            |
| 322 | 
                + }  | 
            |
| 323 | 
                + }  | 
            |
| 324 | 
                + })  | 
            |
| 325 | 
                + }  | 
            |
| 326 | 
                + });  | 
            |
| 327 | 
                +  | 
            |
| 328 | 
                +                $('#dialog .weui_btn_dialog').click(function () {
               | 
            |
| 329 | 
                +                    $('#dialog').hide();
               | 
            |
| 330 | 
                + })  | 
            |
| 331 | 
                +  | 
            |
| 332 | 
                +                $('#dialog2 .weui_btn_dialog').click(function () {
               | 
            |
| 333 | 
                +                    $('#dialog2').hide();
               | 
            |
| 334 | 
                +                    $('#machine_info').hide();
               | 
            |
| 335 | 
                +                    $('#customer_info').show();
               | 
            |
| 336 | 
                + })  | 
            |
| 337 | 
                +  | 
            |
| 338 | 
                +                $('#dialog3 .weui_btn_dialog').click(function () {
               | 
            |
| 339 | 
                +                    $('#dialog').hide();
               | 
            |
| 340 | 
                + window.location.reload();  | 
            |
| 341 | 
                + })  | 
            |
| 342 | 
                + });  | 
            |
| 343 | 
                + </script>  | 
            |
| 344 | 
                + <script type="text/javascript" src="//res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>  | 
            |
| 345 | 
                +        <script type="text/javascript" src="{% static 'pai2/js/jswe-0.0.4.js' %}"></script>
               | 
            |
| 346 | 
                + <script>  | 
            |
| 347 | 
                +            V.initWxData({
               | 
            |
| 348 | 
                + imgUrl: 'http://pai.ai/static/pai2/img/paiai_96_96.png',  | 
            |
| 349 | 
                + link: 'http://pai.ai/w/o?r=http%3A%2F%2Fkodo.xfoto.com.cn%2Fp%2Fclerk%2Fsale',  | 
            |
| 350 | 
                + desc: '店员授权',  | 
            |
| 351 | 
                + title: '店员授权',  | 
            |
| 352 | 
                + timeLine: ''  | 
            |
| 353 | 
                + }, true);  | 
            |
| 354 | 
                + V.hideOptionMenu();  | 
            |
| 355 | 
                +  | 
            |
| 356 | 
                +            $('#scan').click(function () {
               | 
            |
| 357 | 
                +                V.scanQRCode({
               | 
            |
| 358 | 
                + needResult: 1  | 
            |
| 359 | 
                + });  | 
            |
| 360 | 
                + });  | 
            |
| 361 | 
                +            V.wxScanQRCodeSuccess = function (res) {
               | 
            |
| 362 | 
                +                $('#code').val(V.parseScanQRCodeResultStr(res.resultStr));
               | 
            |
| 363 | 
                + }  | 
            |
| 364 | 
                + </script>  | 
            |
| 365 | 
                + </body>  | 
            |
| 366 | 
                +</html>  | 
            
                @@ -190,7 +190,7 @@  | 
            ||
| 190 | 190 | 
                <script>  | 
            
| 191 | 191 | 
                             V.initWxData({
               | 
            
| 192 | 192 | 
                imgUrl: "http://pai.ai/static/pai2/img/paiai_96_96.png",  | 
            
| 193 | 
                - link: 'http://pai.ai/we/we_oauth2?redirect_url=http://pai.ai/page/lensman&scope=snsapi_userinfo',  | 
            |
| 193 | 
                + link: 'http://pai.ai/w/o?r=http%3A%2F%2Fpai.ai%2Fp%2Flensman',  | 
            |
| 194 | 194 | 
                desc: "摄影师授权",  | 
            
| 195 | 195 | 
                title: "摄影师授权",  | 
            
| 196 | 196 | 
                timeLine: ""  | 
            
                @@ -51,7 +51,7 @@  | 
            ||
| 51 | 51 | 
                <script>  | 
            
| 52 | 52 | 
                             V.initWxData({
               | 
            
| 53 | 53 | 
                imgUrl: "http://pai.ai/static/pai2/img/paiai_96_96.png",  | 
            
| 54 | 
                - link: 'http://pai.ai/we/we_oauth2?redirect_url=http://pai.ai/page/loginqr&scope=snsapi_userinfo',  | 
            |
| 54 | 
                + link: 'http://pai.ai/w/o?r=http%3A%2F%2Fpai.ai%2Fp%2Floginqr',  | 
            |
| 55 | 55 | 
                desc: "授权登录",  | 
            
| 56 | 56 | 
                title: "授权登录",  | 
            
| 57 | 57 | 
                timeLine: ""  | 
            
                @@ -252,7 +252,7 @@  | 
            ||
| 252 | 252 | 
                <script>  | 
            
| 253 | 253 | 
                             V.initWxData({
               | 
            
| 254 | 254 | 
                imgUrl: "http://pai.ai/static/pai2/img/paiai_96_96.png",  | 
            
| 255 | 
                - link: 'http://pai.ai/we/we_oauth2?redirect_url=http://pai.ai/page/tourguide&scope=snsapi_userinfo',  | 
            |
| 255 | 
                + link: 'http://pai.ai/w/o?r=http%3A%2F%2Fpai.ai%2Fp%2Ftourguide',  | 
            |
| 256 | 256 | 
                desc: "导游授权",  | 
            
| 257 | 257 | 
                title: "导游授权",  | 
            
| 258 | 258 | 
                timeLine: ""  | 
            
                @@ -4,7 +4,7 @@ from django.conf.urls import url  | 
            ||
| 4 | 4 | 
                 | 
            
| 5 | 5 | 
                from account import tourguide_views  | 
            
| 6 | 6 | 
                from group import lensman_views  | 
            
| 7 | 
                -from page import oauth_views, page_views  | 
            |
| 7 | 
                +from page import info_views, oauth_views, page_views, sale_views  | 
            |
| 8 | 8 | 
                 | 
            
| 9 | 9 | 
                 | 
            
| 10 | 10 | 
                urlpatterns = [  | 
            
                @@ -28,3 +28,9 @@ urlpatterns += [  | 
            ||
| 28 | 28 | 
                urlpatterns += [  | 
            
| 29 | 29 | 
                url(r'^t/submit$', tourguide_views.tourguide_submit_api, name='tourguide_submit_api'), # 导游信息提交  | 
            
| 30 | 30 | 
                ]  | 
            
| 31 | 
                +  | 
            |
| 32 | 
                +urlpatterns = [  | 
            |
| 33 | 
                + url(r'^clerk$', oauth_views.clerk_oauth, name='clerk_oauth'), # 店员授权页面  | 
            |
| 34 | 
                + url(r'^clerk/sale$', sale_views.clerk_sale_oauth, name='clerk_sale_oauth'), # 店员销售授权页面  | 
            |
| 35 | 
                + url(r'^clerk/info$', info_views.clerk_info_oauth, name='clerk_info_oauth'), # 店员信息授权页面  | 
            |
| 36 | 
                +]  | 
            
                @@ -43,8 +43,8 @@ INSTALLED_APPS = (  | 
            ||
| 43 | 43 | 
                'django.contrib.sessions',  | 
            
| 44 | 44 | 
                'django.contrib.messages',  | 
            
| 45 | 45 | 
                'django.contrib.staticfiles',  | 
            
| 46 | 
                - 'rest_framework',  | 
            |
| 47 | 
                - 'django_q',  | 
            |
| 46 | 
                + # 'rest_framework',  | 
            |
| 47 | 
                + # 'django_q',  | 
            |
| 48 | 48 | 
                'django_rlog',  | 
            
| 49 | 49 | 
                'django_uniapi',  | 
            
| 50 | 50 | 
                'django_we',  | 
            
                @@ -53,6 +53,7 @@ INSTALLED_APPS = (  | 
            ||
| 53 | 53 | 
                'account',  | 
            
| 54 | 54 | 
                'box',  | 
            
| 55 | 55 | 
                'group',  | 
            
| 56 | 
                + 'integral',  | 
            |
| 56 | 57 | 
                'mch',  | 
            
| 57 | 58 | 
                'message',  | 
            
| 58 | 59 | 
                'miniapp',  | 
            
                @@ -60,6 +61,7 @@ INSTALLED_APPS = (  | 
            ||
| 60 | 61 | 
                'page',  | 
            
| 61 | 62 | 
                'pay',  | 
            
| 62 | 63 | 
                'photo',  | 
            
| 64 | 
                + 'product',  | 
            |
| 63 | 65 | 
                'server',  | 
            
| 64 | 66 | 
                'website',  | 
            
| 65 | 67 | 
                )  | 
            
                @@ -79,12 +81,12 @@ MIDDLEWARE_CLASSES = (  | 
            ||
| 79 | 81 | 
                'mobi.middleware.MobileDetectionMiddleware',  | 
            
| 80 | 82 | 
                )  | 
            
| 81 | 83 | 
                 | 
            
| 82 | 
                -MIDDLEWARE_CLASSES += ('multidomain.middleware.DomainMiddleware', )
               | 
            |
| 83 | 
                -  | 
            |
| 84 | 
                -URL_CONFIG = (  | 
            |
| 85 | 
                - # (r'^(.+\.)?xfoto\.com\.cn', 'pai2.urls_www'),  | 
            |
| 86 | 
                - (r'^(.+\.)?api\.pai\.ai', 'pai2.urls_api'),  | 
            |
| 87 | 
                -)  | 
            |
| 84 | 
                +# MIDDLEWARE_CLASSES += ('multidomain.middleware.DomainMiddleware', )
               | 
            |
| 85 | 
                +#  | 
            |
| 86 | 
                +# URL_CONFIG = (  | 
            |
| 87 | 
                +# # (r'^(.+\.)?xfoto\.com\.cn', 'pai2.urls_www'),  | 
            |
| 88 | 
                +# (r'^(.+\.)?api\.pai\.ai', 'pai2.urls_api'),  | 
            |
| 89 | 
                +# )  | 
            |
| 88 | 90 | 
                 | 
            
| 89 | 91 | 
                ROOT_URLCONF = 'pai2.urls'  | 
            
| 90 | 92 | 
                 | 
            
                @@ -121,7 +123,7 @@ DATABASES = {
               | 
            ||
| 121 | 123 | 
                # CREATE DATABASE pai2 DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;  | 
            
| 122 | 124 | 
                     'default': {
               | 
            
| 123 | 125 | 
                'ENGINE': 'django.db.backends.mysql',  | 
            
| 124 | 
                - 'NAME': 'pai2',  | 
            |
| 126 | 
                + 'NAME': 'kodo',  | 
            |
| 125 | 127 | 
                'USER': 'root',  | 
            
| 126 | 128 | 
                'PASSWORD': '',  | 
            
| 127 | 129 | 
                'CONN_MAX_AGE': 600,  | 
            
                @@ -385,18 +387,18 @@ THUMBUP_MESSAGE_AVATAR = PAI2_LOGO_URL  | 
            ||
| 385 | 387 | 
                # Redis 连接  | 
            
| 386 | 388 | 
                 REDIS_CACHE = connector(REDIS.get('default', {}))
               | 
            
| 387 | 389 | 
                 | 
            
| 388 | 
                -Q_CLUSTER = {
               | 
            |
| 389 | 
                - 'name': 'pai2',  | 
            |
| 390 | 
                - 'workers': 8,  | 
            |
| 391 | 
                - 'recycle': 500,  | 
            |
| 392 | 
                - 'timeout': 60,  | 
            |
| 393 | 
                - 'compress': True,  | 
            |
| 394 | 
                - 'cpu_affinity': 1,  | 
            |
| 395 | 
                - 'save_limit': 250,  | 
            |
| 396 | 
                - 'queue_limit': 500,  | 
            |
| 397 | 
                - 'label': 'Django Q',  | 
            |
| 398 | 
                - 'redis_conn': REDIS_CACHE,  | 
            |
| 399 | 
                -}  | 
            |
| 390 | 
                +# Q_CLUSTER = {
               | 
            |
| 391 | 
                +# 'name': 'pai2',  | 
            |
| 392 | 
                +# 'workers': 8,  | 
            |
| 393 | 
                +# 'recycle': 500,  | 
            |
| 394 | 
                +# 'timeout': 60,  | 
            |
| 395 | 
                +# 'compress': True,  | 
            |
| 396 | 
                +# 'cpu_affinity': 1,  | 
            |
| 397 | 
                +# 'save_limit': 250,  | 
            |
| 398 | 
                +# 'queue_limit': 500,  | 
            |
| 399 | 
                +# 'label': 'Django Q',  | 
            |
| 400 | 
                +# 'redis_conn': REDIS_CACHE,  | 
            |
| 401 | 
                +# }  | 
            |
| 400 | 402 | 
                 | 
            
| 401 | 403 | 
                 DJLOGIT = {
               | 
            
| 402 | 404 | 
                'level': 'DEBUG',  | 
            
                @@ -29,51 +29,51 @@ from photo import views as photo_views  | 
            ||
| 29 | 29 | 
                from website import views as website_views  | 
            
| 30 | 30 | 
                 | 
            
| 31 | 31 | 
                 | 
            
| 32 | 
                -router = routers.DefaultRouter()  | 
            |
| 33 | 
                -# router.register(r'users', account_views.UserViewSet)  | 
            |
| 34 | 
                -# router.register(r'groups', account_views.GroupViewSet)  | 
            |
| 35 | 
                -  | 
            |
| 36 | 
                -router.register(r'lensmans', account_views.LensmanInfoViewSet)  | 
            |
| 37 | 
                -router.register(r'users', account_views.UserInfoViewSet)  | 
            |
| 38 | 
                -  | 
            |
| 39 | 
                -router.register(r'groups', group_views.GroupInfoViewSet)  | 
            |
| 40 | 
                -router.register(r'group_users', group_views.GroupUserInfoViewSet)  | 
            |
| 41 | 
                -router.register(r'group_photos', group_views.GroupPhotoInfoViewSet)  | 
            |
| 42 | 
                -  | 
            |
| 43 | 
                -router.register(r'photos', photo_views.PhotoInfoViewSet)  | 
            |
| 32 | 
                +# router = routers.DefaultRouter()  | 
            |
| 33 | 
                +# # router.register(r'users', account_views.UserViewSet)  | 
            |
| 34 | 
                +# # router.register(r'groups', account_views.GroupViewSet)  | 
            |
| 35 | 
                +#  | 
            |
| 36 | 
                +# router.register(r'lensmans', account_views.LensmanInfoViewSet)  | 
            |
| 37 | 
                +# router.register(r'users', account_views.UserInfoViewSet)  | 
            |
| 38 | 
                +#  | 
            |
| 39 | 
                +# router.register(r'groups', group_views.GroupInfoViewSet)  | 
            |
| 40 | 
                +# router.register(r'group_users', group_views.GroupUserInfoViewSet)  | 
            |
| 41 | 
                +# router.register(r'group_photos', group_views.GroupPhotoInfoViewSet)  | 
            |
| 42 | 
                +#  | 
            |
| 43 | 
                +# router.register(r'photos', photo_views.PhotoInfoViewSet)  | 
            |
| 44 | 44 | 
                 | 
            
| 45 | 45 | 
                urlpatterns = [  | 
            
| 46 | 46 | 
                url(r'^pai2admin/', include(admin.site.urls)),  | 
            
| 47 | 47 | 
                ]  | 
            
| 48 | 48 | 
                 | 
            
| 49 | 
                -urlpatterns += [  | 
            |
| 50 | 
                -    # url(r'^api/', include('api.urls', namespace='api')),
               | 
            |
| 51 | 
                - url(r'^s/(?P<session_id>\w+)$', photo_views.session_detail, name='session_detail'), # Session 详情  | 
            |
| 52 | 
                - url(r'^p/(?P<photo_id>\w+)$', photo_views.photo_standard, name='photo_standard'), # standard thumbnail, available for free  | 
            |
| 53 | 
                - url(r'^m/(?P<photo_id>\w+)$', photo_views.photo_medium, name='photo_medium'), # medium/mobile version, without watermark, login or paid by others  | 
            |
| 54 | 
                - url(r'^l/(?P<photo_id>\w+)$', photo_views.photo_large, name='photo_large'), # large, might support server side panning later, login required  | 
            |
| 55 | 
                - url(r'^r/(?P<photo_id>\w+)$', photo_views.photo_raw, name='photo_raw'), # raw image, only for finishers  | 
            |
| 56 | 
                -]  | 
            |
| 57 | 
                -  | 
            |
| 58 | 
                -urlpatterns += [  | 
            |
| 59 | 
                - url(r'^g/(?P<group_id>\w+)$', grouppage_views.group_detail, name='group_detail'), # 群组详情(拍爱用户端下载页)  | 
            |
| 60 | 
                -]  | 
            |
| 61 | 
                -  | 
            |
| 62 | 
                -urlpatterns += [  | 
            |
| 63 | 
                - url(r'^gp/(?P<photo_id>\w+)$', grouppage_views.group_photo_detail, name='group_photo_detail'), # 群组照片详情  | 
            |
| 64 | 
                -]  | 
            |
| 65 | 
                -  | 
            |
| 66 | 
                -urlpatterns += [  | 
            |
| 67 | 
                - url(r'^tg/(?P<admin_id>\w+)$', grouppage_views.tgu_group_detail, name='tgu_group_detail'), # 旅行团详情(拍爱导游端下载页)  | 
            |
| 68 | 
                -]  | 
            |
| 69 | 
                -  | 
            |
| 70 | 
                -urlpatterns += [  | 
            |
| 71 | 
                - url(r'^tgu/(?P<admin_id>\w+)$', grouppage_views.tgu_group_user_detail, name='tgu_group_user_detail'), # 旅行团成员详情(拍爱用户端下载页)  | 
            |
| 72 | 
                -]  | 
            |
| 73 | 
                -  | 
            |
| 74 | 
                -urlpatterns += [  | 
            |
| 75 | 
                - url(r'^$', website_views.pai2_home, name='pai2_home'), # 官网首页  | 
            |
| 76 | 
                -]  | 
            |
| 49 | 
                +# urlpatterns += [  | 
            |
| 50 | 
                +#     # url(r'^api/', include('api.urls', namespace='api')),
               | 
            |
| 51 | 
                +# url(r'^s/(?P<session_id>\w+)$', photo_views.session_detail, name='session_detail'), # Session 详情  | 
            |
| 52 | 
                +# url(r'^p/(?P<photo_id>\w+)$', photo_views.photo_standard, name='photo_standard'), # standard thumbnail, available for free  | 
            |
| 53 | 
                +# url(r'^m/(?P<photo_id>\w+)$', photo_views.photo_medium, name='photo_medium'), # medium/mobile version, without watermark, login or paid by others  | 
            |
| 54 | 
                +# url(r'^l/(?P<photo_id>\w+)$', photo_views.photo_large, name='photo_large'), # large, might support server side panning later, login required  | 
            |
| 55 | 
                +# url(r'^r/(?P<photo_id>\w+)$', photo_views.photo_raw, name='photo_raw'), # raw image, only for finishers  | 
            |
| 56 | 
                +# ]  | 
            |
| 57 | 
                +#  | 
            |
| 58 | 
                +# urlpatterns += [  | 
            |
| 59 | 
                +# url(r'^g/(?P<group_id>\w+)$', grouppage_views.group_detail, name='group_detail'), # 群组详情(拍爱用户端下载页)  | 
            |
| 60 | 
                +# ]  | 
            |
| 61 | 
                +#  | 
            |
| 62 | 
                +# urlpatterns += [  | 
            |
| 63 | 
                +# url(r'^gp/(?P<photo_id>\w+)$', grouppage_views.group_photo_detail, name='group_photo_detail'), # 群组照片详情  | 
            |
| 64 | 
                +# ]  | 
            |
| 65 | 
                +#  | 
            |
| 66 | 
                +# urlpatterns += [  | 
            |
| 67 | 
                +# url(r'^tg/(?P<admin_id>\w+)$', grouppage_views.tgu_group_detail, name='tgu_group_detail'), # 旅行团详情(拍爱导游端下载页)  | 
            |
| 68 | 
                +# ]  | 
            |
| 69 | 
                +#  | 
            |
| 70 | 
                +# urlpatterns += [  | 
            |
| 71 | 
                +# url(r'^tgu/(?P<admin_id>\w+)$', grouppage_views.tgu_group_user_detail, name='tgu_group_user_detail'), # 旅行团成员详情(拍爱用户端下载页)  | 
            |
| 72 | 
                +# ]  | 
            |
| 73 | 
                +#  | 
            |
| 74 | 
                +# urlpatterns += [  | 
            |
| 75 | 
                +# url(r'^$', website_views.pai2_home, name='pai2_home'), # 官网首页  | 
            |
| 76 | 
                +# ]  | 
            |
| 77 | 77 | 
                 | 
            
| 78 | 78 | 
                # Mini App  | 
            
| 79 | 79 | 
                urlpatterns += [  | 
            
                @@ -83,14 +83,20 @@ urlpatterns += [  | 
            ||
| 83 | 83 | 
                # Wire up our API using automatic URL routing.  | 
            
| 84 | 84 | 
                # Additionally, we include login URLs for the browsable API.  | 
            
| 85 | 85 | 
                urlpatterns += [  | 
            
| 86 | 
                - url(r'^api/', include(router.urls)),  | 
            |
| 87 | 
                -    url(r'^page/', include('page.urls', namespace='page')),
               | 
            |
| 86 | 
                + # url(r'^restapi/', include(router.urls)),  | 
            |
| 88 | 87 | 
                     url(r'^uniapi/', include('django_uniapi.urls', namespace='uniapi')),
               | 
            
| 88 | 
                +    url(r'^api/', include('api.urls', namespace='api')),
               | 
            |
| 89 | 
                +    url(r'^w/', include('django_we.urls', namespace='shortwechat')),
               | 
            |
| 89 | 90 | 
                     url(r'^we/', include('django_we.urls', namespace='wechat')),
               | 
            
| 90 | 91 | 
                     url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))
               | 
            
| 91 | 92 | 
                ]  | 
            
| 92 | 93 | 
                 | 
            
| 94 | 
                +urlpatterns += [  | 
            |
| 95 | 
                +    url(r'^p/', include('page.urls', namespace='shortpage')),
               | 
            |
| 96 | 
                +    url(r'^page/', include('page.urls', namespace='page')),
               | 
            |
| 97 | 
                +]  | 
            |
| 98 | 
                +  | 
            |
| 93 | 99 | 
                urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)  | 
            
| 94 | 100 | 
                urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)  | 
            
| 95 | 101 | 
                 | 
            
| 96 | 
                -admin.site.site_header = u'[拍爱]后台管理系统'  | 
            |
| 102 | 
                +admin.site.site_header = u'[盈多]后台管理系统'  | 
            
                @@ -13,4 +13,4 @@ class OrderInfoAdmin(ReadOnlyModelAdmin, admin.ModelAdmin):  | 
            ||
| 13 | 13 | 
                     search_fields = ('prepay_id', 'transaction_id', 'group_id', 'session_id', 'photo_id', 'lensman_photo_id', 'from_uid', 'to_uid')
               | 
            
| 14 | 14 | 
                 | 
            
| 15 | 15 | 
                 | 
            
| 16 | 
                -admin.site.register(OrderInfo, OrderInfoAdmin)  | 
            |
| 16 | 
                +# admin.site.register(OrderInfo, OrderInfoAdmin)  | 
            
                @@ -20,6 +20,6 @@ class PhotosInfoAdmin(admin.ModelAdmin):  | 
            ||
| 20 | 20 | 
                     list_filter = ('lensman_id', 'status')
               | 
            
| 21 | 21 | 
                 | 
            
| 22 | 22 | 
                 | 
            
| 23 | 
                -admin.site.register(UUIDInfo, UUIDInfoAdmin)  | 
            |
| 24 | 
                -admin.site.register(PhotosInfo, PhotosInfoAdmin)  | 
            |
| 25 | 
                -admin.site.register(PhotoUUIDInfo, PhotoUUIDInfoAdmin)  | 
            |
| 23 | 
                +# admin.site.register(UUIDInfo, UUIDInfoAdmin)  | 
            |
| 24 | 
                +# admin.site.register(PhotosInfo, PhotosInfoAdmin)  | 
            |
| 25 | 
                +# admin.site.register(PhotoUUIDInfo, PhotoUUIDInfoAdmin)  | 
            
                @@ -3,7 +3,7 @@  | 
            ||
| 3 | 3 | 
                from curtail_uuid import CurtailUUID  | 
            
| 4 | 4 | 
                from django.db import transaction  | 
            
| 5 | 5 | 
                from django.shortcuts import render  | 
            
| 6 | 
                -from django_q.tasks import async  | 
            |
| 6 | 
                +# from django_q.tasks import async  | 
            |
| 7 | 7 | 
                from django_response import response  | 
            
| 8 | 8 | 
                from ipaddr import client_ip  | 
            
| 9 | 9 | 
                from logit import logit  | 
            
                @@ -46,13 +46,13 @@ def uuid(request):  | 
            ||
| 46 | 46 | 
                # 从 Redis 中 Pop 中指定数量的 UUID  | 
            
| 47 | 47 | 
                uuids, succeed, left = r.multi_pop(UUID_LIST, num)  | 
            
| 48 | 48 | 
                 | 
            
| 49 | 
                - # 异步更新 UUID 数据库中状态  | 
            |
| 50 | 
                - if uuids:  | 
            |
| 51 | 
                - async(update_uuids, lensman_id, uuids)  | 
            |
| 52 | 
                -  | 
            |
| 53 | 
                - # 当可用 UUID 数量少于 500 时, 异步创建  | 
            |
| 54 | 
                - if left < 500:  | 
            |
| 55 | 
                - async(generate_uuids)  | 
            |
| 49 | 
                + # # 异步更新 UUID 数据库中状态  | 
            |
| 50 | 
                + # if uuids:  | 
            |
| 51 | 
                + # async(update_uuids, lensman_id, uuids)  | 
            |
| 52 | 
                + #  | 
            |
| 53 | 
                + # # 当可用 UUID 数量少于 500 时, 异步创建  | 
            |
| 54 | 
                + # if left < 500:  | 
            |
| 55 | 
                + # async(generate_uuids)  | 
            |
| 56 | 56 | 
                 | 
            
| 57 | 57 | 
                return response(200, 'Get UUID Success', u'获取唯一标识成功', uuids)  | 
            
| 58 | 58 | 
                 | 
            
                @@ -0,0 +1,29 @@  | 
            ||
| 1 | 
                +# -*- coding: utf-8 -*-  | 
            |
| 2 | 
                +  | 
            |
| 3 | 
                +from django.contrib import admin  | 
            |
| 4 | 
                +  | 
            |
| 5 | 
                +from product.models import ProductCodeSubmitLogInfo, ProductInfo, ProductModelInfo  | 
            |
| 6 | 
                +  | 
            |
| 7 | 
                +  | 
            |
| 8 | 
                +class ProductModelInfoAdmin(admin.ModelAdmin):  | 
            |
| 9 | 
                +    readonly_fields = ('model_id', )
               | 
            |
| 10 | 
                +    list_display = ('model_id', 'model_name', 'integral', 'has_mount', 'status', 'created_at', 'updated_at')
               | 
            |
| 11 | 
                +    search_fields = ('model_id', 'model_name')
               | 
            |
| 12 | 
                +    list_filter = ('has_mount', 'status')
               | 
            |
| 13 | 
                +  | 
            |
| 14 | 
                +  | 
            |
| 15 | 
                +class ProductInfoAdmin(admin.ModelAdmin):  | 
            |
| 16 | 
                +    list_display = ('model_id', 'model_name', 'code', 'code_status', 'integral', 'integral_status', 'franchiser_id', 'clerk_id', 'consumer_name', 'consumer_sex', 'consumer_age', 'consumer_phone', 'status', 'created_at', 'updated_at')
               | 
            |
| 17 | 
                +    search_fields = ('model_id', 'model_name', 'code', 'consumer_name', 'consumer_phone')
               | 
            |
| 18 | 
                +    list_filter = ('code_status', 'integral_status', 'franchiser_id', 'consumer_sex', 'status')
               | 
            |
| 19 | 
                +  | 
            |
| 20 | 
                +  | 
            |
| 21 | 
                +class ProductCodeSubmitLogInfoAdmin(admin.ModelAdmin):  | 
            |
| 22 | 
                +    list_display = ('model_id', 'model_name', 'mount', 'code', 'franchiser_id', 'clerk_id', 'consumer_name', 'consumer_sex', 'consumer_age', 'consumer_phone', 'status', 'created_at', 'updated_at')
               | 
            |
| 23 | 
                +    search_fields = ('model_id', 'model_name', 'code', 'consumer_name', 'consumer_phone')
               | 
            |
| 24 | 
                +    list_filter = ('step', 'mount', 'franchiser_id', 'consumer_sex', 'status')
               | 
            |
| 25 | 
                +  | 
            |
| 26 | 
                +  | 
            |
| 27 | 
                +admin.site.register(ProductModelInfo, ProductModelInfoAdmin)  | 
            |
| 28 | 
                +admin.site.register(ProductInfo, ProductInfoAdmin)  | 
            |
| 29 | 
                +admin.site.register(ProductCodeSubmitLogInfo, ProductCodeSubmitLogInfoAdmin)  | 
            
                @@ -0,0 +1,86 @@  | 
            ||
| 1 | 
                +# -*- coding: utf-8 -*-  | 
            |
| 2 | 
                +# Generated by Django 1.11.9 on 2018-02-07 14:16  | 
            |
| 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 | 
                + initial = True  | 
            |
| 12 | 
                +  | 
            |
| 13 | 
                + dependencies = [  | 
            |
| 14 | 
                + ]  | 
            |
| 15 | 
                +  | 
            |
| 16 | 
                + operations = [  | 
            |
| 17 | 
                + migrations.CreateModel(  | 
            |
| 18 | 
                + name='ProductCodeSubmitLogInfo',  | 
            |
| 19 | 
                + fields=[  | 
            |
| 20 | 
                +                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
               | 
            |
| 21 | 
                +                ('status', models.BooleanField(db_index=True, default=True, help_text='Status', verbose_name='status')),
               | 
            |
| 22 | 
                +                ('created_at', models.DateTimeField(auto_now_add=True, help_text='Create Time', verbose_name='created_at')),
               | 
            |
| 23 | 
                +                ('updated_at', models.DateTimeField(auto_now=True, help_text='Update Time', verbose_name='updated_at')),
               | 
            |
| 24 | 
                +                ('sex', models.BooleanField(choices=[(1, '\u7537'), (0, '\u5973')], db_index=True, default=1, help_text='Sex', verbose_name='sex')),
               | 
            |
| 25 | 
                +                ('step', models.IntegerField(db_index=True, default=1, help_text='\u63d0\u4ea4\u6b65\u9aa4', verbose_name='step')),
               | 
            |
| 26 | 
                +                ('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')),
               | 
            |
| 27 | 
                +                ('model_name', models.CharField(blank=True, db_index=True, help_text='\u578b\u53f7\u540d\u79f0', max_length=32, null=True, verbose_name='model_name')),
               | 
            |
| 28 | 
                +                ('mount', models.CharField(blank=True, db_index=True, help_text='\u5361\u53e3', max_length=255, null=True, verbose_name='mount')),
               | 
            |
| 29 | 
                +                ('code', models.CharField(blank=True, help_text='\u673a\u8eab\u7801', max_length=32, null=True, verbose_name='code')),
               | 
            |
| 30 | 
                +                ('franchiser_id', models.CharField(blank=True, db_index=True, help_text='\u7ecf\u9500\u5546\u552f\u4e00\u6807\u8bc6', max_length=32, null=True, verbose_name='franchiser_id')),
               | 
            |
| 31 | 
                +                ('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')),
               | 
            |
| 32 | 
                +                ('consumer_name', models.CharField(blank=True, help_text='\u6d88\u8d39\u8005\u540d\u79f0', max_length=32, null=True, verbose_name='consumer_name')),
               | 
            |
| 33 | 
                +                ('consumer_sex', models.IntegerField(choices=[(1, '\u7537'), (0, '\u5973')], db_index=True, default=1, help_text='\u6d88\u8d39\u8005\u6027\u522b', verbose_name='consumer_sex')),
               | 
            |
| 34 | 
                +                ('consumer_age', models.IntegerField(default=0, help_text='\u6d88\u8d39\u8005\u5e74\u9f84', verbose_name='consumer_age')),
               | 
            |
| 35 | 
                +                ('consumer_phone', models.CharField(blank=True, help_text='\u6d88\u8d39\u8005\u8054\u7cfb\u7535\u8bdd', max_length=11, null=True, verbose_name='consumer_phone')),
               | 
            |
| 36 | 
                + ],  | 
            |
| 37 | 
                +            options={
               | 
            |
| 38 | 
                + 'verbose_name': 'productcodesubmitloginfo',  | 
            |
| 39 | 
                + 'verbose_name_plural': 'productcodesubmitloginfo',  | 
            |
| 40 | 
                + },  | 
            |
| 41 | 
                + ),  | 
            |
| 42 | 
                + migrations.CreateModel(  | 
            |
| 43 | 
                + name='ProductInfo',  | 
            |
| 44 | 
                + fields=[  | 
            |
| 45 | 
                +                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
               | 
            |
| 46 | 
                +                ('status', models.BooleanField(db_index=True, default=True, help_text='Status', verbose_name='status')),
               | 
            |
| 47 | 
                +                ('created_at', models.DateTimeField(auto_now_add=True, help_text='Create Time', verbose_name='created_at')),
               | 
            |
| 48 | 
                +                ('updated_at', models.DateTimeField(auto_now=True, help_text='Update Time', verbose_name='updated_at')),
               | 
            |
| 49 | 
                +                ('sex', models.BooleanField(choices=[(1, '\u7537'), (0, '\u5973')], db_index=True, default=1, help_text='Sex', verbose_name='sex')),
               | 
            |
| 50 | 
                +                ('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')),
               | 
            |
| 51 | 
                +                ('model_name', models.CharField(blank=True, db_index=True, help_text='\u578b\u53f7\u540d\u79f0', max_length=32, null=True, verbose_name='model_name')),
               | 
            |
| 52 | 
                +                ('mount', models.CharField(blank=True, db_index=True, help_text='\u5361\u53e3', max_length=32, null=True, verbose_name='mount')),
               | 
            |
| 53 | 
                +                ('code', models.CharField(blank=True, help_text='\u673a\u8eab\u7801', max_length=32, null=True, verbose_name='code')),
               | 
            |
| 54 | 
                +                ('code_status', models.BooleanField(db_index=True, default=False, help_text='\u673a\u8eab\u7801\u72b6\u6001, True\u5df2\u4f7f\u7528\uff0cFalse\u672a\u4f7f\u7528', verbose_name='code_status')),
               | 
            |
| 55 | 
                +                ('integral', models.IntegerField(default=0, help_text='\u79ef\u5206', verbose_name='integral')),
               | 
            |
| 56 | 
                +                ('integral_status', models.BooleanField(db_index=True, default=False, help_text='\u79ef\u5206\u72b6\u6001, True\u5df2\u79ef\u5206\uff0cFalse\u672a\u79ef\u5206', verbose_name='integral_status')),
               | 
            |
| 57 | 
                +                ('franchiser_id', models.CharField(blank=True, db_index=True, help_text='\u7ecf\u9500\u5546\u552f\u4e00\u6807\u8bc6', max_length=32, null=True, verbose_name='franchiser_id')),
               | 
            |
| 58 | 
                +                ('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')),
               | 
            |
| 59 | 
                +                ('consumer_name', models.CharField(blank=True, help_text='\u6d88\u8d39\u8005\u540d\u79f0', max_length=32, null=True, verbose_name='consumer_name')),
               | 
            |
| 60 | 
                +                ('consumer_sex', models.IntegerField(choices=[(1, '\u7537'), (0, '\u5973')], db_index=True, default=1, help_text='\u6d88\u8d39\u8005\u6027\u522b', verbose_name='consumer_sex')),
               | 
            |
| 61 | 
                +                ('consumer_age', models.IntegerField(default=0, help_text='\u6d88\u8d39\u8005\u5e74\u9f84', verbose_name='consumer_age')),
               | 
            |
| 62 | 
                +                ('consumer_phone', models.CharField(blank=True, help_text='\u6d88\u8d39\u8005\u8054\u7cfb\u7535\u8bdd', max_length=11, null=True, verbose_name='consumer_phone')),
               | 
            |
| 63 | 
                + ],  | 
            |
| 64 | 
                +            options={
               | 
            |
| 65 | 
                + 'verbose_name': 'productinfo',  | 
            |
| 66 | 
                + 'verbose_name_plural': 'productinfo',  | 
            |
| 67 | 
                + },  | 
            |
| 68 | 
                + ),  | 
            |
| 69 | 
                + migrations.CreateModel(  | 
            |
| 70 | 
                + name='ProductModelInfo',  | 
            |
| 71 | 
                + fields=[  | 
            |
| 72 | 
                +                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
               | 
            |
| 73 | 
                +                ('status', models.BooleanField(db_index=True, default=True, help_text='Status', verbose_name='status')),
               | 
            |
| 74 | 
                +                ('created_at', models.DateTimeField(auto_now_add=True, help_text='Create Time', verbose_name='created_at')),
               | 
            |
| 75 | 
                +                ('updated_at', models.DateTimeField(auto_now=True, help_text='Update Time', verbose_name='updated_at')),
               | 
            |
| 76 | 
                +                ('model_id', shortuuidfield.fields.ShortUUIDField(blank=True, db_index=True, editable=False, help_text='\u578b\u53f7\u552f\u4e00\u6807\u8bc6', max_length=22, unique=True)),
               | 
            |
| 77 | 
                +                ('model_name', models.CharField(blank=True, help_text='\u578b\u53f7\u540d\u79f0', max_length=32, null=True, unique=True, verbose_name='model_name')),
               | 
            |
| 78 | 
                +                ('integral', models.IntegerField(default=0, help_text='\u578b\u53f7\u79ef\u5206', verbose_name='integral')),
               | 
            |
| 79 | 
                +                ('has_mount', models.BooleanField(db_index=True, default=True, help_text='\u662f\u5426\u6709\u5361\u53e3', verbose_name='has_mount')),
               | 
            |
| 80 | 
                + ],  | 
            |
| 81 | 
                +            options={
               | 
            |
| 82 | 
                + 'verbose_name': '\u4ea7\u54c1\u578b\u53f7\u4fe1\u606f',  | 
            |
| 83 | 
                + 'verbose_name_plural': '\u4ea7\u54c1\u578b\u53f7\u4fe1\u606f',  | 
            |
| 84 | 
                + },  | 
            |
| 85 | 
                + ),  | 
            |
| 86 | 
                + ]  | 
            
                @@ -0,0 +1,88 @@  | 
            ||
| 1 | 
                +# -*- coding: utf-8 -*-  | 
            |
| 2 | 
                +  | 
            |
| 3 | 
                +from django.db import models  | 
            |
| 4 | 
                +from django.utils.translation import ugettext_lazy as _  | 
            |
| 5 | 
                +from models_ext import BaseModelMixin, SexModelMixin  | 
            |
| 6 | 
                +from shortuuidfield import ShortUUIDField  | 
            |
| 7 | 
                +  | 
            |
| 8 | 
                +  | 
            |
| 9 | 
                +class ProductModelInfo(BaseModelMixin):  | 
            |
| 10 | 
                + model_id = ShortUUIDField(_(u'model_id'), max_length=32, help_text=u'型号唯一标识', db_index=True, unique=True)  | 
            |
| 11 | 
                + model_name = models.CharField(_(u'model_name'), max_length=32, blank=True, null=True, help_text=u'型号名称', unique=True)  | 
            |
| 12 | 
                + integral = models.IntegerField(_(u'integral'), default=0, help_text=u'型号积分')  | 
            |
| 13 | 
                + has_mount = models.BooleanField(_(u'has_mount'), default=True, help_text=u'是否有卡口', db_index=True)  | 
            |
| 14 | 
                +  | 
            |
| 15 | 
                + class Meta:  | 
            |
| 16 | 
                + verbose_name = _(u'产品型号信息')  | 
            |
| 17 | 
                + verbose_name_plural = _(u'产品型号信息')  | 
            |
| 18 | 
                +  | 
            |
| 19 | 
                + def __unicode__(self):  | 
            |
| 20 | 
                + return unicode(self.pk)  | 
            |
| 21 | 
                +  | 
            |
| 22 | 
                + @property  | 
            |
| 23 | 
                + def data(self):  | 
            |
| 24 | 
                +        return {
               | 
            |
| 25 | 
                + 'model_id': self.model_id,  | 
            |
| 26 | 
                + 'model_name': self.model_name,  | 
            |
| 27 | 
                + 'integral': self.integral,  | 
            |
| 28 | 
                + 'has_mount': self.has_mount,  | 
            |
| 29 | 
                + }  | 
            |
| 30 | 
                +  | 
            |
| 31 | 
                +  | 
            |
| 32 | 
                +class ProductInfo(BaseModelMixin, SexModelMixin):  | 
            |
| 33 | 
                + model_id = models.CharField(_(u'model_id'), max_length=32, blank=True, null=True, help_text=u'型号唯一标识', db_index=True)  | 
            |
| 34 | 
                + model_name = models.CharField(_(u'model_name'), max_length=32, blank=True, null=True, help_text=u'型号名称', db_index=True)  | 
            |
| 35 | 
                +  | 
            |
| 36 | 
                + mount = models.CharField(_(u'mount'), max_length=32, blank=True, null=True, help_text=u'卡口', db_index=True)  | 
            |
| 37 | 
                + code = models.CharField(_(u'code'), max_length=32, blank=True, null=True, help_text=u'机身码')  | 
            |
| 38 | 
                + code_status = models.BooleanField(_(u'code_status'), default=False, help_text=u'机身码状态, True已使用,False未使用', db_index=True)  | 
            |
| 39 | 
                +  | 
            |
| 40 | 
                + integral = models.IntegerField(_(u'integral'), default=0, help_text=u'积分')  | 
            |
| 41 | 
                + integral_status = models.BooleanField(_(u'integral_status'), default=False, help_text=u'积分状态, True已积分,False未积分', db_index=True)  | 
            |
| 42 | 
                +  | 
            |
| 43 | 
                + franchiser_id = models.CharField(_(u'franchiser_id'), max_length=32, blank=True, null=True, help_text=u'经销商唯一标识', db_index=True)  | 
            |
| 44 | 
                + clerk_id = models.CharField(_(u'clerk_id'), max_length=32, blank=True, null=True, help_text=u'店员唯一标识', db_index=True)  | 
            |
| 45 | 
                +  | 
            |
| 46 | 
                + consumer_name = models.CharField(_(u'consumer_name'), max_length=32, blank=True, null=True, help_text=u'消费者名称')  | 
            |
| 47 | 
                + consumer_sex = models.IntegerField(_(u'consumer_sex'), choices=SexModelMixin.SEX_TUPLE, default=SexModelMixin.MALE, help_text=u'消费者性别', db_index=True)  | 
            |
| 48 | 
                + consumer_age = models.IntegerField(_(u'consumer_age'), default=0, help_text=u'消费者年龄')  | 
            |
| 49 | 
                + consumer_phone = models.CharField(_(u'consumer_phone'), max_length=11, blank=True, null=True, help_text=u'消费者联系电话')  | 
            |
| 50 | 
                +  | 
            |
| 51 | 
                + class Meta:  | 
            |
| 52 | 
                + verbose_name = _(u'productinfo')  | 
            |
| 53 | 
                + verbose_name_plural = _(u'productinfo')  | 
            |
| 54 | 
                +  | 
            |
| 55 | 
                + def __unicode__(self):  | 
            |
| 56 | 
                + return unicode(self.pk)  | 
            |
| 57 | 
                +  | 
            |
| 58 | 
                + @property  | 
            |
| 59 | 
                + def data(self):  | 
            |
| 60 | 
                +        return {
               | 
            |
| 61 | 
                + 'model_id': self.model_id,  | 
            |
| 62 | 
                + 'model_name': self.model_name,  | 
            |
| 63 | 
                + 'code': self.code,  | 
            |
| 64 | 
                + }  | 
            |
| 65 | 
                +  | 
            |
| 66 | 
                +  | 
            |
| 67 | 
                +class ProductCodeSubmitLogInfo(BaseModelMixin, SexModelMixin):  | 
            |
| 68 | 
                + step = models.IntegerField(_(u'step'), default=1, help_text=u'提交步骤', db_index=True)  | 
            |
| 69 | 
                +  | 
            |
| 70 | 
                + model_id = models.CharField(_(u'model_id'), max_length=32, blank=True, null=True, help_text=u'型号唯一标识', db_index=True)  | 
            |
| 71 | 
                + model_name = models.CharField(_(u'model_name'), max_length=32, blank=True, null=True, help_text=u'型号名称', db_index=True)  | 
            |
| 72 | 
                + mount = models.CharField(_(u'mount'), max_length=255, blank=True, null=True, help_text=u'卡口', db_index=True)  | 
            |
| 73 | 
                + code = models.CharField(_(u'code'), max_length=32, blank=True, null=True, help_text=u'机身码')  | 
            |
| 74 | 
                +  | 
            |
| 75 | 
                + franchiser_id = models.CharField(_(u'franchiser_id'), max_length=32, blank=True, null=True, help_text=u'经销商唯一标识', db_index=True)  | 
            |
| 76 | 
                + clerk_id = models.CharField(_(u'clerk_id'), max_length=32, blank=True, null=True, help_text=u'店员唯一标识', db_index=True)  | 
            |
| 77 | 
                +  | 
            |
| 78 | 
                + consumer_name = models.CharField(_(u'consumer_name'), max_length=32, blank=True, null=True, help_text=u'消费者名称')  | 
            |
| 79 | 
                + consumer_sex = models.IntegerField(_(u'consumer_sex'), choices=SexModelMixin.SEX_TUPLE, default=SexModelMixin.MALE, help_text=u'消费者性别', db_index=True)  | 
            |
| 80 | 
                + consumer_age = models.IntegerField(_(u'consumer_age'), default=0, help_text=u'消费者年龄')  | 
            |
| 81 | 
                + consumer_phone = models.CharField(_(u'consumer_phone'), max_length=11, blank=True, null=True, help_text=u'消费者联系电话')  | 
            |
| 82 | 
                +  | 
            |
| 83 | 
                + class Meta:  | 
            |
| 84 | 
                + verbose_name = _(u'productcodesubmitloginfo')  | 
            |
| 85 | 
                + verbose_name_plural = _(u'productcodesubmitloginfo')  | 
            |
| 86 | 
                +  | 
            |
| 87 | 
                + def __unicode__(self):  | 
            |
| 88 | 
                + return unicode(self.pk)  | 
            
                @@ -0,0 +1,4 @@  | 
            ||
| 1 | 
                +from django.test import TestCase  | 
            |
| 2 | 
                +  | 
            |
| 3 | 
                +  | 
            |
| 4 | 
                +# Create your tests here.  | 
            
                @@ -0,0 +1,4 @@  | 
            ||
| 1 | 
                +from django.shortcuts import render  | 
            |
| 2 | 
                +  | 
            |
| 3 | 
                +  | 
            |
| 4 | 
                +# Create your views here.  | 
            
                @@ -3,6 +3,34 @@  | 
            ||
| 3 | 3 | 
                from StatusCode import BaseStatusCode, StatusCodeField  | 
            
| 4 | 4 | 
                 | 
            
| 5 | 5 | 
                 | 
            
| 6 | 
                +class FranchiserStatusCode(BaseStatusCode):  | 
            |
| 7 | 
                + """ 经销商相关错误码 5000xx """  | 
            |
| 8 | 
                + CHISER_NOT_FOUND = StatusCodeField(500001, 'Chiser Not Found', description=u'经销商不存在')  | 
            |
| 9 | 
                +  | 
            |
| 10 | 
                +  | 
            |
| 11 | 
                +class SaleclerkStatusCode(BaseStatusCode):  | 
            |
| 12 | 
                + """ 店员相关错误码 5001xx """  | 
            |
| 13 | 
                + CLERK_NOT_FOUND = StatusCodeField(500101, 'Clerk Not Found', description=u'店员不存在')  | 
            |
| 14 | 
                + # 手机号  | 
            |
| 15 | 
                + CLERK_PHONE_ALREADY_EXISTS = StatusCodeField(500105, 'Clerk Phone Already Exists', description=u'手机号已经存在')  | 
            |
| 16 | 
                + # 状态  | 
            |
| 17 | 
                + CLERK_ALREADY_NOT_UNVERIFIED = StatusCodeField(500110, 'Clerk Already Not Unverified', description=u'店员帐号已激活')  | 
            |
| 18 | 
                + CLERK_NOT_ACTIVATED = StatusCodeField(500115, 'Clerk Not Activated', description=u'店员帐号未激活')  | 
            |
| 19 | 
                +  | 
            |
| 20 | 
                +  | 
            |
| 21 | 
                +class ProductModelStatusCode(BaseStatusCode):  | 
            |
| 22 | 
                + """ 型号相关错误码 5010xx """  | 
            |
| 23 | 
                + MODEL_NOT_FOUND = StatusCodeField(501001, 'Model Not Found', description=u'型号不存在')  | 
            |
| 24 | 
                +  | 
            |
| 25 | 
                +  | 
            |
| 26 | 
                +class ProductStatusCode(BaseStatusCode):  | 
            |
| 27 | 
                + """ 产品相关错误码 5020xx """  | 
            |
| 28 | 
                + PRODUCT_NOT_FOUND = StatusCodeField(502001, 'Product Not Found', description=u'产品不存在')  | 
            |
| 29 | 
                + # 状态  | 
            |
| 30 | 
                + PRODUCT_HAS_USED = StatusCodeField(502011, 'Product Has Used', description=u'产品已使用')  | 
            |
| 31 | 
                + PRODUCT_NOT_USED = StatusCodeField(502012, 'Product Not Used', description=u'产品未使用')  | 
            |
| 32 | 
                +  | 
            |
| 33 | 
                +  | 
            |
| 6 | 34 | 
                class LensmanStatusCode(BaseStatusCode):  | 
            
| 7 | 35 | 
                """ 摄影师相关错误码 4000xx """  | 
            
| 8 | 36 | 
                LENSMAN_NOT_FOUND = StatusCodeField(400001, 'Lensman Not Found', description=u'摄影师不存在')  |