Add tour guide oauth

Brightcells 8 年之前
父节点
当前提交
8a213207ea

+ 39 - 2
account/admin.py

@@ -5,8 +5,8 @@ from django.contrib import admin
5 5
 from django.contrib.auth.hashers import make_password
6 6
 from django.db import transaction
7 7
 
8
-from account.models import (LensmanIncomeExpensesInfo, LensmanInfo, LensmanLoginLogInfo, UserIncomeExpensesInfo,
9
-                            UserInfo, UserLoginLogInfo)
8
+from account.models import (LensmanIncomeExpensesInfo, LensmanInfo, LensmanLoginLogInfo, TourGuideInfo,
9
+                            UserIncomeExpensesInfo, UserInfo, UserLoginLogInfo)
10 10
 
11 11
 
12 12
 class LensmanInfoAdmin(admin.ModelAdmin):
@@ -31,10 +31,12 @@ class LensmanInfoAdmin(admin.ModelAdmin):
31 31
             'sex': obj.sex,
32 32
             'phone': obj.phone,
33 33
             'location': obj.location,
34
+            'islensman': True,
34 35
             'user_status': obj.user_status,
35 36
         }
36 37
         user, created = UserInfo.objects.get_or_create(user_id=obj.lensman_id, defaults=fields)
37 38
         if not created:
39
+            fields.pop('user_from', None)
38 40
             for key, value in fields.iteritems():
39 41
                 setattr(user, key, value)
40 42
             user.save()
@@ -54,6 +56,40 @@ class LensmanIncomeExpensesInfoAdmin(admin.ModelAdmin):
54 56
     list_filter = ('type', 'status')
55 57
 
56 58
 
59
+class TourGuideInfoAdmin(admin.ModelAdmin):
60
+    readonly_fields = ('tourguide_id', )
61
+    list_display = ('tourguide_id', 'unionid', 'name', 'sex', 'phone', 'location', 'no', 'user_status', 'status', 'created_at', 'updated_at')
62
+    search_fields = ('name', 'phone', 'location', 'no')
63
+    list_filter = ('sex', 'user_status', 'status')
64
+
65
+    @transaction.atomic
66
+    def save_model(self, request, obj, form, change):
67
+        if not obj.tourguide_id:
68
+            try:
69
+                user_id = UserInfo.objects.select_for_update().get(unionid=obj.unionid).user_id
70
+            except UserInfo.DoesNotExist:
71
+                user_id = None
72
+            obj.tourguide_id = user_id or CurtailUUID.uuid(UserInfo, 'user_id')
73
+            obj.save()
74
+
75
+        fields = {
76
+            'user_from': UserInfo.TOURGUIDE_USER,
77
+            'unionid': obj.unionid,
78
+            'name': obj.name,
79
+            'sex': obj.sex,
80
+            'phone': obj.phone,
81
+            'location': obj.location,
82
+            'istourguide': True,
83
+            'user_status': obj.user_status,
84
+        }
85
+        user, created = UserInfo.objects.get_or_create(user_id=obj.tourguide_id, defaults=fields)
86
+        if not created:
87
+            fields.pop('user_from', None)
88
+            for key, value in fields.iteritems():
89
+                setattr(user, key, value)
90
+            user.save()
91
+
92
+
57 93
 class UserInfoAdmin(admin.ModelAdmin):
58 94
     readonly_fields = ('user_id', )
59 95
     list_display = ('user_id', 'user_from', 'username', 'openid', 'unionid', 'name', 'sex', 'nickname', 'phone', 'location', 'balance', 'user_status', 'status', 'created_at', 'updated_at')
@@ -73,6 +109,7 @@ class UserIncomeExpensesInfoAdmin(admin.ModelAdmin):
73 109
 admin.site.register(LensmanInfo, LensmanInfoAdmin)
74 110
 admin.site.register(LensmanLoginLogInfo, LensmanLoginLogInfoAdmin)
75 111
 admin.site.register(LensmanIncomeExpensesInfo, LensmanIncomeExpensesInfoAdmin)
112
+admin.site.register(TourGuideInfo, TourGuideInfoAdmin)
76 113
 admin.site.register(UserInfo, UserInfoAdmin)
77 114
 admin.site.register(UserLoginLogInfo, UserLoginLogInfoAdmin)
78 115
 admin.site.register(UserIncomeExpensesInfo, UserIncomeExpensesInfoAdmin)

+ 36 - 0
account/migrations/0020_tourguideinfo.py

@@ -0,0 +1,36 @@
1
+# -*- coding: utf-8 -*-
2
+from __future__ import unicode_literals
3
+
4
+from django.db import models, migrations
5
+
6
+
7
+class Migration(migrations.Migration):
8
+
9
+    dependencies = [
10
+        ('account', '0019_auto_20161024_1235'),
11
+    ]
12
+
13
+    operations = [
14
+        migrations.CreateModel(
15
+            name='TourGuideInfo',
16
+            fields=[
17
+                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
18
+                ('status', models.BooleanField(default=True, help_text='\u72b6\u6001', db_index=True, verbose_name='status')),
19
+                ('created_at', models.DateTimeField(help_text='\u521b\u5efa\u65f6\u95f4', verbose_name='created_at', auto_now_add=True)),
20
+                ('updated_at', models.DateTimeField(help_text='\u66f4\u65b0\u65f6\u95f4', verbose_name='updated_at', auto_now=True)),
21
+                ('tourguide_id', models.CharField(null=True, max_length=255, blank=True, help_text='\u5bfc\u6e38\u552f\u4e00\u6807\u8bc6', unique=True, verbose_name='tourguide_id', db_index=True)),
22
+                ('unionid', models.CharField(null=True, max_length=255, blank=True, help_text='\u5fae\u4fe1 Union ID', unique=True, verbose_name='unionid', db_index=True)),
23
+                ('name', models.CharField(help_text='\u5bfc\u6e38\u59d3\u540d', max_length=255, null=True, verbose_name='name', blank=True)),
24
+                ('sex', models.IntegerField(default=1, help_text='\u5bfc\u6e38\u6027\u522b', verbose_name='sex', choices=[(1, '\u7537'), (0, '\u5973')])),
25
+                ('phone', models.CharField(null=True, max_length=255, blank=True, help_text='\u5bfc\u6e38\u7535\u8bdd', unique=True, verbose_name='phone', db_index=True)),
26
+                ('location', models.CharField(help_text='\u5bfc\u6e38\u5730\u5740', max_length=255, null=True, verbose_name='location', blank=True)),
27
+                ('no', models.CharField(help_text='\u5bfc\u6e38\u8bc1\u7f16\u53f7', max_length=255, null=True, verbose_name='no', blank=True)),
28
+                ('user_status', models.IntegerField(default=0, verbose_name='user_status', 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')])),
29
+                ('refused_reason', models.TextField(help_text='\u5ba1\u6838\u62d2\u7edd\u539f\u56e0', null=True, verbose_name='refused_reason', blank=True)),
30
+            ],
31
+            options={
32
+                'verbose_name': 'tourguideinfo',
33
+                'verbose_name_plural': 'tourguideinfo',
34
+            },
35
+        ),
36
+    ]

+ 29 - 0
account/migrations/0021_auto_20161213_1639.py

@@ -0,0 +1,29 @@
1
+# -*- coding: utf-8 -*-
2
+from __future__ import unicode_literals
3
+
4
+from django.db import models, migrations
5
+
6
+
7
+class Migration(migrations.Migration):
8
+
9
+    dependencies = [
10
+        ('account', '0020_tourguideinfo'),
11
+    ]
12
+
13
+    operations = [
14
+        migrations.AddField(
15
+            model_name='userinfo',
16
+            name='islensman',
17
+            field=models.BooleanField(default=False, help_text='\u6444\u5f71\u5e08\uff1f', db_index=True, verbose_name='islensman'),
18
+        ),
19
+        migrations.AddField(
20
+            model_name='userinfo',
21
+            name='istourguide',
22
+            field=models.BooleanField(default=False, help_text='\u5bfc\u6e38\uff1f', db_index=True, verbose_name='istourguide'),
23
+        ),
24
+        migrations.AlterField(
25
+            model_name='userinfo',
26
+            name='user_from',
27
+            field=models.IntegerField(default=0, help_text='\u7528\u6237\u6765\u6e90', verbose_name='user_from', choices=[(0, 'APP \u521b\u5efa\u7528\u6237'), (1, '\u5fae\u4fe1\u6388\u6743\u7528\u6237'), (9, '\u6e38\u5ba2\u7528\u6237'), (10, '\u6444\u5f71\u5e08\u7528\u6237'), (11, '\u5bfc\u6e38\u7528\u6237')]),
28
+        ),
29
+    ]

+ 66 - 0
account/models.py

@@ -135,6 +135,64 @@ class LensmanIncomeExpensesInfo(CreateUpdateMixin):
135 135
         return unicode(self.pk)
136 136
 
137 137
 
138
+class TourGuideInfo(CreateUpdateMixin):
139
+    MALE = 1
140
+    FEMALE = 0
141
+
142
+    SEX_TYPE = (
143
+        (MALE, u'男'),
144
+        (FEMALE, u'女'),
145
+    )
146
+
147
+    REFUSED = -1
148
+    UNVERIFIED = 0
149
+    ACTIVATED = 1
150
+    DISABLED = 2
151
+    DELETED = 3
152
+    ASSIGN = 10
153
+
154
+    USER_STATUS = (
155
+        (REFUSED, u'已拒绝'),
156
+        (UNVERIFIED, u'未验证'),
157
+        (ACTIVATED, u'已激活'),
158
+        (DISABLED, u'已禁用'),
159
+        (DELETED, u'已删除'),
160
+        (ASSIGN, u'已分配'),
161
+    )
162
+
163
+    tourguide_id = models.CharField(_(u'tourguide_id'), max_length=255, blank=True, null=True, help_text=u'导游唯一标识', db_index=True, unique=True)
164
+
165
+    unionid = models.CharField(_(u'unionid'), max_length=255, blank=True, null=True, help_text=u'微信 Union ID', db_index=True, unique=True)
166
+
167
+    name = models.CharField(_(u'name'), max_length=255, blank=True, null=True, help_text=u'导游姓名')
168
+    sex = models.IntegerField(_(u'sex'), choices=SEX_TYPE, default=MALE, help_text=u'导游性别')
169
+    phone = models.CharField(_(u'phone'), max_length=255, blank=True, null=True, help_text=u'导游电话', db_index=True, unique=True)
170
+    location = models.CharField(_(u'location'), max_length=255, blank=True, null=True, help_text=u'导游地址')
171
+
172
+    no = models.CharField(_(u'no'), max_length=255, blank=True, null=True, help_text=u'导游证编号')
173
+
174
+    user_status = models.IntegerField(_(u'user_status'), choices=USER_STATUS, default=UNVERIFIED)
175
+    refused_reason = models.TextField(_(u'refused_reason'), blank=True, null=True, help_text=u'审核拒绝原因')
176
+
177
+    class Meta:
178
+        verbose_name = _(u'tourguideinfo')
179
+        verbose_name_plural = _(u'tourguideinfo')
180
+
181
+    def __unicode__(self):
182
+        return unicode(self.pk)
183
+
184
+    @property
185
+    def data(self):
186
+        return {
187
+            'name': self.name,
188
+            'sex': self.sex,
189
+            'phone': self.phone,
190
+            'location': self.location,
191
+            'status': self.user_status,
192
+            'refused_reason': self.refused_reason,
193
+        }
194
+
195
+
138 196
 class WechatInfo(CreateUpdateMixin):
139 197
     MALE = 1
140 198
     FEMALE = 0
@@ -167,12 +225,14 @@ class UserInfo(CreateUpdateMixin):
167 225
     WX_USER = 1
168 226
     GUEST_USER = 9
169 227
     LENSMAN_USER = 10
228
+    TOURGUIDE_USER = 11
170 229
 
171 230
     USER_FROM = (
172 231
         (APP_USER, u'APP 创建用户'),
173 232
         (WX_USER, u'微信授权用户'),
174 233
         (GUEST_USER, u'游客用户'),
175 234
         (LENSMAN_USER, u'摄影师用户'),
235
+        (TOURGUIDE_USER, u'导游用户'),
176 236
     )
177 237
 
178 238
     UNVERIFIED = 0
@@ -218,6 +278,10 @@ class UserInfo(CreateUpdateMixin):
218 278
     city = models.CharField(_(u'city'), max_length=255, blank=True, null=True, help_text=u'用户城市')
219 279
     location = models.CharField(_(u'location'), max_length=255, blank=True, null=True, help_text=u'用户地址')
220 280
 
281
+    # 用户身份
282
+    islensman = models.BooleanField(_(u'islensman'), default=False, help_text=_(u'摄影师?'), db_index=True)
283
+    istourguide = models.BooleanField(_(u'istourguide'), default=False, help_text=_(u'导游?'), db_index=True)
284
+
221 285
     balance = models.IntegerField(_(u'balance'), default=0, help_text=u'用户余额(分)')
222 286
     freeze_income_balance = models.IntegerField(_(u'freeze_income_balance'), default=0, help_text=u'用户收入冻结余额(分)')
223 287
     freeze_expense_balance = models.IntegerField(_(u'freeze_expense_balance'), default=0, help_text=u'用户支出冻结余额(分)')
@@ -250,6 +314,8 @@ class UserInfo(CreateUpdateMixin):
250 314
             return self.nickname
251 315
         elif self.user_from == self.LENSMAN_USER:
252 316
             return self.name
317
+        elif self.user_from == self.TOURGUIDE_USER:
318
+            return self.name
253 319
         return self.nickname
254 320
 
255 321
     @property

+ 48 - 0
account/tourguide_views.py

@@ -0,0 +1,48 @@
1
+# -*- coding: utf-8 -*-
2
+
3
+from __future__ import division
4
+
5
+from django.conf import settings
6
+from logit import logit
7
+
8
+from account.models import TourGuideInfo
9
+from utils.error.errno_utils import TourGuideStatusCode
10
+from utils.error.response_utils import response
11
+
12
+
13
+r = settings.REDIS_CACHE
14
+
15
+
16
+@logit
17
+def tourguide_submit_api(request):
18
+    """
19
+    导游信息提交
20
+    :param request:
21
+    :return:
22
+    """
23
+    unionid = request.POST.get('unionid', '')
24
+    openid = request.POST.get('openid', '')
25
+    phone = request.POST.get('phone', '')
26
+
27
+    if TourGuideInfo.objects.filter(phone=phone).exclude(unionid=unionid).exists():
28
+        return response(TourGuideStatusCode.TOURGUIDE_PHONE_ALREADY_EXISTS)
29
+
30
+    fields = {
31
+        'name': request.POST.get('name', ''),
32
+        'sex': int(request.POST.get('sex', 1)),
33
+        'phone': phone,
34
+        'location': request.POST.get('location', ''),
35
+        'no': request.POST.get('no', ''),
36
+        'user_status': TourGuideInfo.UNVERIFIED,
37
+    }
38
+
39
+    tourguide, created = TourGuideInfo.objects.get_or_create(unionid=unionid, defaults=fields)
40
+    # 状态为 UNVERIFIED 的允许修改, 其他需要登录摄影师 APP 进行信息的修改
41
+    if tourguide.user_status not in [TourGuideInfo.UNVERIFIED, TourGuideInfo.REFUSED]:
42
+        return response(TourGuideStatusCode.TOURGUIDE_ALREADY_NOT_UNVERIFIED)
43
+    if not created:
44
+        for key, value in fields.iteritems():
45
+            setattr(tourguide, key, value)
46
+        tourguide.save()
47
+
48
+    return response(200, 'Submit Success', u'提交成功', {})

+ 1 - 1
account/views.py

@@ -39,7 +39,7 @@ def lensman_login_api(request):
39 39
 
40 40
 @logit
41 41
 def user_is_registered_api(request):
42
-    return response(200, '', '', {
42
+    return response(200, data={
43 43
         'registered': UserInfo.objects.filter(username=request.POST.get('username', '')).exists(),
44 44
     })
45 45
 

+ 6 - 0
api/urls.py

@@ -3,6 +3,7 @@
3 3
 from django.conf.urls import url
4 4
 
5 5
 from account import views as account_views
6
+from account import tourguide_views
6 7
 from group import views as group_views
7 8
 from group import lensman_views
8 9
 from message import views as message_views
@@ -41,6 +42,11 @@ urlpatterns += [
41 42
     url(r'^l/origin_wanted$', lensman_views.lensman_origin_wanted_api, name='lensman_origin_wanted_api'),  # 摄影师原图订单
42 43
 ]
43 44
 
45
+# 导游相关
46
+urlpatterns += [
47
+    url(r'^t/submit$', tourguide_views.tourguide_submit_api, name='tourguide_submit_api'),  # 导游信息提交
48
+]
49
+
44 50
 # 群组相关
45 51
 urlpatterns += [
46 52
     url(r'^g/create$', group_views.group_create_api, name='group_create_api'),  # 群组创建

+ 213 - 0
page/templates/page/tourguide_oauth.html

@@ -0,0 +1,213 @@
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="https://res.wx.qq.com/open/libs/weui/0.4.3/weui.min.css" rel="stylesheet" type="text/css" />
13
+
14
+        <style>
15
+            input:required:invalid {
16
+                color: #E64340;
17
+            }
18
+            input:required:valid {
19
+                color: rgb(0, 0, 0);
20
+            }
21
+        </style>
22
+    </head>
23
+    <body>
24
+        <div class="container" >
25
+            <div class="weui_cells_title">基本信息</div>
26
+            <div class="weui_cells weui_cells_form">
27
+                <div class="weui_cell">
28
+                    <div class="weui_cell_hd"><label for="" class="weui_label">姓名</label></div>
29
+                    <div class="weui_cell_bd weui_cell_primary">
30
+                        <input id="name" class="weui_input" type="text" value="{{ tourguide_info.name }}" placeholder="请输入姓名" {% if not modified %}disabled{% endif %}>
31
+                    </div>
32
+                </div>
33
+                <div class="weui_cell weui_cell_select weui_select_after">
34
+                    <div class="weui_cell_hd"><label for="" class="weui_label">性别</label></div>
35
+                    <div class="weui_cell_bd weui_cell_primary">
36
+                        <select id="sex" class="weui_select" name="select" {% if not modified %}disabled{% endif %}>
37
+                            <option value="1" {% ifequal tourguide_info.sex 1 %}selected{% endifequal %}>男</option>
38
+                            <option value="0" {% ifequal tourguide_info.sex 0 %}selected{% endifequal %}>女</option>
39
+                        </select>
40
+                    </div>
41
+                </div>
42
+                <div class="weui_cell">
43
+                    <div class="weui_cell_hd"><label for="" class="weui_label">手机号</label></div>
44
+                    <div class="weui_cell_bd weui_cell_primary">
45
+                        <input id="phone" class="weui_input" type="text" required="required" pattern="[0-9]{11}" value="{{ tourguide_info.phone }}" placeholder="请输入手机号" {% if not modified %}disabled{% endif %}>
46
+                    </div>
47
+                </div>
48
+{#                <div class="weui_cell">#}
49
+{#                    <div class="weui_cell_hd"><label for="" class="weui_label">地址</label></div>#}
50
+{#                    <div class="weui_cell_bd weui_cell_primary">#}
51
+{#                        <input id="location" class="weui_input" type="text" value="{{ tourguide_info.location }}" placeholder="请输入地址" {% if not modified %}disabled{% endif %}>#}
52
+{#                    </div>#}
53
+{#                </div>#}
54
+                <div class="weui_cell">
55
+                    <div class="weui_cell_hd"><label for="" class="weui_label">导游证编号</label></div>
56
+                    <div class="weui_cell_bd weui_cell_primary">
57
+                        <input id="no" class="weui_input" type="text" required="required" value="{{ tourguide_info.no }}" placeholder="请输入导游证编号" {% if not modified %}disabled{% endif %}>
58
+                    </div>
59
+                </div>
60
+            </div>
61
+
62
+            {% if tourguide_info %}
63
+            <div class="weui_cells_title">审核状态</div>
64
+            <div class="weui_cells">
65
+                <div class="weui_cell">
66
+                    <div class="weui_cell_bd weui_cell_primary">
67
+                        <p>状态</p>
68
+                    </div>
69
+                    <div class="weui_cell_ft">
70
+                        {% ifequal tourguide_info.status -1 %}已拒绝{% endifequal %}
71
+                        {% ifequal tourguide_info.status 0 %}审核中{% endifequal %}
72
+                        {% ifequal tourguide_info.status 1 %}已激活{% endifequal %}
73
+                        {% ifequal tourguide_info.status 2 %}已禁用{% endifequal %}
74
+                        {% ifequal tourguide_info.status 3 %}已删除{% endifequal %}
75
+                    </div>
76
+                </div>
77
+            </div>
78
+            {% endif %}
79
+
80
+
81
+            {% ifequal tourguide_info.status -1 %}
82
+            <div class="weui_cells_title">拒绝原因</div>
83
+            <div class="weui_cells">
84
+                <div class="weui_panel_bd">
85
+                    <div class="weui_media_box weui_media_text">
86
+                        <p class="weui_media_desc">{{ tourguide_info.refused_reason|safe|linebreaks }}</p>
87
+                    </div>
88
+                </div>
89
+            </div>
90
+            {% endifequal %}
91
+
92
+            <br>
93
+
94
+            {% if modified %}<button id="submit" class="weui_btn weui_btn_warn">确认</button>{% endif %}
95
+
96
+            <div class="weui_dialog_alert" id="dialog" style="display: none">
97
+                <div class="weui_mask"></div>
98
+                <div class="weui_dialog">
99
+                    <div class="weui_dialog_hd"><strong id="title" class="weui_dialog_title">弹窗标题</strong></div>
100
+                    <div id="content" class="weui_dialog_bd">弹窗内容,告知当前页面信息等</div>
101
+                    <div class="weui_dialog_ft">
102
+                        <a href="javascript:;" class="weui_btn_dialog primary">确定</a>
103
+                    </div>
104
+                </div>
105
+            </div>
106
+
107
+            <div id="toast" style="display: none;">
108
+                <div class="weui_mask_transparent"></div>
109
+                <div class="weui_toast">
110
+                    <i class="weui_icon_toast"></i>
111
+                    <p class="weui_toast_content">已完成</p>
112
+                </div>
113
+            </div>
114
+        </div>
115
+
116
+        <script src="//cdn.bootcss.com/zepto/1.1.6/zepto.min.js"></script>
117
+        <script>
118
+            {% if modified %}
119
+            $(function() {
120
+                function getURLParameter(name) {
121
+                  return decodeURIComponent((new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)').exec(location.search) || [null, ''])[1].replace(/\+/g, '%20')) || null;
122
+                }
123
+
124
+                function show_error_dialog(title, content) {
125
+                    $('#dialog #title').text(title);
126
+                    $('#dialog #content').text(content);
127
+                    $('#dialog').show();
128
+                }
129
+
130
+                function data_check() {
131
+                    var unionid = getURLParameter('unionid');
132
+                    if (!unionid) {
133
+                        show_error_dialog('微信授权', '微信授权失败,请重新打开页面');
134
+                        return false;
135
+                    }
136
+
137
+                    var name = $('#name').val();
138
+                    if (!name) {
139
+                        show_error_dialog('姓名', '姓名错误,请检查重新输入');
140
+                        return false;
141
+                    }
142
+
143
+                    var phone_valid = $('#phone').is(':valid');
144
+                    if (!phone_valid) {
145
+                        show_error_dialog('手机号', '手机号错误,请检查重新输入');
146
+                        return false;
147
+                    }
148
+
149
+{#                    var location = $('#location').val();#}
150
+{#                    if (!location) {#}
151
+{#                        show_error_dialog('地址', '地址错误,请检查重新输入');#}
152
+{#                        return false;#}
153
+{#                    }#}
154
+
155
+                    var no = $('#no').val();
156
+                    if (!no) {
157
+                        show_error_dialog('编号', '导游证编号错误,请检查重新输入');
158
+                        return false;
159
+                    }
160
+
161
+                    return {
162
+                        unionid: unionid,
163
+                        openid: getURLParameter('openid'),
164
+                        name: name,
165
+                        sex: $('#sex option:checked').val(),
166
+                        phone: $('#phone').val(),
167
+{#                        location: location,#}
168
+                        no: no,
169
+                    }
170
+                }
171
+
172
+                $('#submit').click(function () {
173
+                    var check_result = data_check();
174
+                    if (check_result){
175
+                        $.ajax({
176
+                            type: 'POST',
177
+                            url: 't/submit',
178
+                            data: check_result,
179
+                            success: function(data) {
180
+                                if (data.status == 200) {
181
+                                    $('#toast').show();
182
+                                    setTimeout(function () {
183
+                                        $('#toast').hide();
184
+                                    }, 1000);
185
+                                    window.location.reload();
186
+                                } else {
187
+                                    show_error_dialog('错误', data.description);
188
+                                }
189
+                            }
190
+                        })
191
+                    }
192
+                });
193
+
194
+                $('#dialog .weui_btn_dialog').click(function () {
195
+                    $('#dialog').hide();
196
+                })
197
+            });
198
+            {% endif %}
199
+        </script>
200
+        <script type="text/javascript" src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
201
+        <script type="text/javascript" src="{% static 'pai2/js/jswe.js' %}?v=1"></script>
202
+        <script>
203
+            V.initWxData({
204
+                imgUrl: "http://pai.ai/static/pai2/img/paiai_96_96.png",
205
+                link: 'http://api.pai.ai/wx_oauth2?redirect_url=http://pai.ai/page/tourguide&scope=snsapi_base',
206
+                desc: "导游授权",
207
+                title: "导游授权",
208
+                timeLine: ""
209
+            }, true);
210
+            V.hideOptionMenu();
211
+        </script>
212
+    </body>
213
+</html>

+ 15 - 1
page/views.py

@@ -2,7 +2,7 @@
2 2
 
3 3
 from django.shortcuts import render
4 4
 
5
-from account.models import LensmanInfo
5
+from account.models import LensmanInfo, TourGuideInfo
6 6
 
7 7
 
8 8
 def user_agreement(request):
@@ -29,3 +29,17 @@ def lensman_oauth(request):
29 29
 
30 30
 def lensman_price(request):
31 31
     return render(request, 'page/lensman_price.html', {})
32
+
33
+
34
+def tourguide_oauth(request):
35
+    unionid = request.GET.get('unionid', '')
36
+
37
+    try:
38
+        tourguide = TourGuideInfo.objects.get(unionid=unionid)
39
+    except TourGuideInfo.DoesNotExist:
40
+        tourguide = None
41
+
42
+    return render(request, 'page/tourguide_oauth.html', {
43
+        'tourguide_info': tourguide and tourguide.data,
44
+        'modified': bool((not tourguide) or (tourguide and tourguide.user_status in [TourGuideInfo.UNVERIFIED, TourGuideInfo.REFUSED])),  # 是否可以更改信息
45
+    })

+ 8 - 0
pai2/urls.py

@@ -22,6 +22,7 @@ from django.contrib import admin
22 22
 from rest_framework import routers
23 23
 
24 24
 from account import views as account_views
25
+from account import tourguide_views
25 26
 from group import views as group_views
26 27
 from group import lensman_views
27 28
 from page import views as page_views
@@ -69,6 +70,8 @@ urlpatterns += [
69 70
 
70 71
     url(r'^page/lensman$', page_views.lensman_oauth, name='lensman_oauth'),  # 摄影师授权页面
71 72
     url(r'^page/price$', page_views.lensman_price, name='lensman_price'),  # 摄影师照片价格和分成规则
73
+
74
+    url(r'^page/tourguide$', page_views.tourguide_oauth, name='tourguide_oauth'),  # 导游授权页面
72 75
 ]
73 76
 
74 77
 urlpatterns += [
@@ -84,6 +87,11 @@ urlpatterns += [
84 87
     url(r'^page/l/submit$', lensman_views.lensman_submit_api, name='lensman_submit_api'),  # 摄影师信息提交
85 88
 ]
86 89
 
90
+# 导游相关
91
+urlpatterns += [
92
+    url(r'^page/t/submit$', tourguide_views.tourguide_submit_api, name='tourguide_submit_api'),  # 导游信息提交
93
+]
94
+
87 95
 # Wire up our API using automatic URL routing.
88 96
 # Additionally, we include login URLs for the browsable API.
89 97
 urlpatterns += [

+ 23 - 11
utils/error/errno_utils.py

@@ -15,25 +15,37 @@ class LensmanStatusCode(BaseStatusCode):
15 15
     LENSMAN_NOT_ACTIVATED = StatusCodeField(400015, u'Lensman Not Activated', description=u'摄影师帐号未激活')
16 16
 
17 17
 
18
+class TourGuideStatusCode(BaseStatusCode):
19
+    """ 导游相关错误码 4001xx """
20
+    TOURGUIDE_NOT_FOUND = StatusCodeField(400101, u'Tour Guide Not Found', description=u'导游不存在')
21
+    TOURGUIDE_PASSWORD_ERROR = StatusCodeField(400102, u'Tour Guide Password Error', description=u'导游密码错误')
22
+
23
+    TOURGUIDE_PHONE_ALREADY_EXISTS = StatusCodeField(400105, u'Tour Guide Phone Already Exists', description=u'手机号已经存在')
24
+
25
+    TOURGUIDE_ALREADY_NOT_UNVERIFIED = StatusCodeField(400110, u'Tour Guide Already Not Unverified', description=u'导游帐号已激活')
26
+
27
+    TOURGUIDE_NOT_ACTIVATED = StatusCodeField(400115, u'Tour Guide Not Activated', description=u'导游帐号未激活')
28
+
29
+
18 30
 class UserStatusCode(BaseStatusCode):
19
-    """ 用户相关错误码  4001xx """
20
-    USER_NOT_FOUND = StatusCodeField(400101, u'User Not Found', description=u'用户不存在')
21
-    USER_PASSWORD_ERROR = StatusCodeField(400102, u'User Password Error', description=u'用户密码错误')
22
-    USERNAME_HAS_REGISTERED = StatusCodeField(400103, u'Username Has Registered', description=u'用户名已注册')
31
+    """ 用户相关错误码  4005xx """
32
+    USER_NOT_FOUND = StatusCodeField(400501, u'User Not Found', description=u'用户不存在')
33
+    USER_PASSWORD_ERROR = StatusCodeField(400502, u'User Password Error', description=u'用户密码错误')
34
+    USERNAME_HAS_REGISTERED = StatusCodeField(400503, u'Username Has Registered', description=u'用户名已注册')
23 35
 
24
-    GUEST_NOT_ALLOWED = StatusCodeField(400111, u'Guest Not ALLOWED', description=u'游客登录未开启')
36
+    GUEST_NOT_ALLOWED = StatusCodeField(400511, u'Guest Not ALLOWED', description=u'游客登录未开启')
25 37
 
26 38
 
27 39
 class PhoneStatusCode(BaseStatusCode):
28
-    """ 手机相关错误码  4002xx """
29
-    PHONE_NOT_FOUND = StatusCodeField(400201, u'Phone Not Found', description=u'手机不存在')
40
+    """ 手机相关错误码  4006xx """
41
+    PHONE_NOT_FOUND = StatusCodeField(400601, u'Phone Not Found', description=u'手机不存在')
30 42
 
31 43
 
32 44
 class WechatStatusCode(BaseStatusCode):
33
-    """ 微信相关错误码  4003xx """
34
-    WECHAT_NOT_FOUND = StatusCodeField(400301, u'Wechat Not Found', description=u'微信不存在')
35
-    UNIONID_NOT_FOUND = StatusCodeField(400302, u'Unionid Not Found', description=u'微信 UNIONID 不存在')
36
-    OPENID_NOT_FOUND = StatusCodeField(400303, u'OPENID Not Found', description=u'微信 OPENID 不存在')
45
+    """ 微信相关错误码  4007xx """
46
+    WECHAT_NOT_FOUND = StatusCodeField(400701, u'Wechat Not Found', description=u'微信不存在')
47
+    UNIONID_NOT_FOUND = StatusCodeField(400702, u'Unionid Not Found', description=u'微信 UNIONID 不存在')
48
+    OPENID_NOT_FOUND = StatusCodeField(400703, u'OPENID Not Found', description=u'微信 OPENID 不存在')
37 49
 
38 50
 
39 51
 class PhotoStatusCode(BaseStatusCode):