num lines-num-old"> 8
+from django_response import response
9
+from pywe_miniapp import get_session_info, get_session_key, get_userinfo, store_session_key
10
+from pywe_storage import RedisStorage
11
+
12
+from account.models import UserInfo
13
+from utils.redis.connect import r
14
+
15
+
16
+WECHAT = settings.WECHAT
17
+logger = logging.getLogger('logit')
18
+
19
+
20
+@logit
21
+@transaction.atomic
22
+def get_userinfo_api(request):
23
+    appId = request.POST.get('appId', 'MINIAPP')
24
+
25
+    wxcfg = WECHAT.get(appId, {})
26
+
27
+    appid = wxcfg.get('appID')
28
+    secret = wxcfg.get('appsecret')
29
+
30
+    code = request.POST.get('code', '')
31
+    encryptedData = request.POST.get('encryptedData', '')
32
+    iv = request.POST.get('iv', '')
33
+
34
+    # {u'avatarUrl': u'http://wx.qlogo.cn/mmopen/vi_32/aSKcBBPpibyKNicHNTMM0qJVh8Kjgiak2AHWr8MHM4WgMEm7GFhsf8OYrySdbvAMvTsw3mo8ibKicsnfN5pRjl1p8HQ/0',
35
+    #  u'city': u'Guangzhou',
36
+    #  u'country': u'CN',
37
+    #  u'gender': 1,
38
+    #  u'language': u'zh_CN',
39
+    #  u'nickName': u'Band',
40
+    #  u'openId': u'oGZUI0egBJY1zhBYw2KhdUfwVJJE',
41
+    #  u'province': u'Guangdong',
42
+    #  u'unionId': u'ocMvos6NjeKLIBqg5Mr9QjxrP1FA',
43
+    #  u'watermark': {u'appid': u'wx4f4bc4dec97d474b', u'timestamp': 1477314187}}
44
+    session_key = get_session_key(appid=appid, secret=secret, code=code)
45
+    # Get Userinfo
46
+    userinfo = get_userinfo(appid=appid, secret=secret, code=code, session_key=session_key, encryptedData=encryptedData, iv=iv)
47
+
48
+    # Get or Create User
49
+    user, created = UserInfo.objects.select_for_update().get_or_create(unionid=userinfo.get('unionId', ''))
50
+
51
+    # Set User Key's Value
52
+    user.unionid = userinfo.get('unionId', '')
53
+    user.openid_miniapp = userinfo.get('openId', '')
54
+    user.sex = userinfo.get('gender', '')
55
+    user.nickname = userinfo.get('nickName', '')
56
+    user.avatar = userinfo.get('avatarUrl', '')
57
+    user.country = userinfo.get('country', '')
58
+    user.province = userinfo.get('province', '')
59
+    user.city = userinfo.get('city', '')
60
+    user.user_status = UserInfo.ACTIVATED
61
+    user.save()
62
+
63
+    # Store SessionKey
64
+    store_session_key(appid=appid, secret=secret, session_key=session_key, unid=user.user_id, storage=RedisStorage(r))
65
+    # Just for compatible because of store session_key has changed
66
+    store_session_key(appid=appid, secret=secret, session_key=session_key, unid='', storage=RedisStorage(r))
67
+
68
+    return response(200, 'Mini App Login Success', '微信小程序登录成功', user.data)
69
+
70
+
71
+@logit(res=True)
72
+@transaction.atomic
73
+def mini_login_api(request):
74
+    appId = request.POST.get('appId', 'MINIAPP')
75
+
76
+    wxcfg = WECHAT.get(appId, {})
77
+
78
+    appid = wxcfg.get('appID')
79
+    secret = wxcfg.get('appsecret')
80
+
81
+    code = request.POST.get('code', '')
82
+
83
+    # // 正常返回的JSON数据包
84
+    # {
85
+    #     "openid": "OPENID",
86
+    #     "session_key": "SESSIONKEY",
87
+    # }
88
+    #
89
+    # // 满足UnionID返回条件时,返回的JSON数据包
90
+    # {
91
+    #     "openid": "OPENID",
92
+    #     "session_key": "SESSIONKEY",
93
+    #     "unionid": "UNIONID"
94
+    # }
95
+    # // 错误时返回JSON数据包(示例为Code无效)
96
+    # {
97
+    #     "errcode": 40029,
98
+    #     "errmsg": "invalid code"
99
+    # }
100
+    session_info = get_session_info(appid=appid, secret=secret, code=code)
101
+    logger.debug(session_info)
102
+    session_key = session_info.get('session_key', '')
103
+    unionid = session_info.get('unionid', '')
104
+    openid = session_info.get('openid', '')
105
+
106
+    # Get or Create User
107
+    user, created = UserInfo.objects.select_for_update().get_or_create(openid_miniapp=openid)
108
+
109
+    # Set User Key's Value
110
+    if unionid:
111
+        user.unionid = unionid
112
+
113
+    user.user_status = UserInfo.ACTIVATED
114
+    user.save()
115
+
116
+    # Store SessionKey
117
+    store_session_key(appid=appid, secret=secret, session_key=session_key, unid=user.user_id, storage=RedisStorage(r))
118
+    # Just for compatible because of store session_key has changed
119
+    store_session_key(appid=appid, secret=secret, session_key=session_key, unid='', storage=RedisStorage(r))
120
+
121
+    return response(200, 'Mini App Login Success', '微信小程序登录成功', user.data)
122
+
123
+
124
+@logit
125
+@transaction.atomic
126
+def get_userinfo_api2(request):
127
+    user_id = request.POST.get('user_id', '')
128
+    appId = request.POST.get('appId', 'MINIAPP')
129
+
130
+    wxcfg = WECHAT.get(appId, {})
131
+
132
+    appid = wxcfg.get('appID')
133
+    secret = wxcfg.get('appsecret')
134
+
135
+    encryptedData = request.POST.get('encryptedData', '')
136
+    iv = request.POST.get('iv', '')
137
+
138
+    try:
139
+        user = UserInfo.objects.select_for_update().get(user_id=user_id, status=True)
140
+    except UserInfo.DoesNotExist:
141
+        return response()
142
+
143
+    # {u'avatarUrl': u'http://wx.qlogo.cn/mmopen/vi_32/aSKcBBPpibyKNicHNTMM0qJVh8Kjgiak2AHWr8MHM4WgMEm7GFhsf8OYrySdbvAMvTsw3mo8ibKicsnfN5pRjl1p8HQ/0',
144
+    #  u'city': u'Guangzhou',
145
+    #  u'country': u'CN',
146
+    #  u'gender': 1,
147
+    #  u'language': u'zh_CN',
148
+    #  u'nickName': u'Band',
149
+    #  u'openId': u'oGZUI0egBJY1zhBYw2KhdUfwVJJE',
150
+    #  u'province': u'Guangdong',
151
+    #  u'unionId': u'ocMvos6NjeKLIBqg5Mr9QjxrP1FA',
152
+    #  u'watermark': {u'appid': u'wx4f4bc4dec97d474b', u'timestamp': 1477314187}}
153
+    session_key = get_session_key(appid=appid, secret=secret, unid=user_id, storage=RedisStorage(r))
154
+    # Get Userinfo
155
+    userinfo = get_userinfo(appid=appid, secret=secret, session_key=session_key, encryptedData=encryptedData, iv=iv)
156
+
157
+    # Set User Key's Value
158
+    user.unionid = userinfo.get('unionId', '')
159
+    user.openid_miniapp = userinfo.get('openId', '')
160
+    user.sex = userinfo.get('gender', '')
161
+    user.nickname = userinfo.get('nickName', '')
162
+    user.avatar = userinfo.get('avatarUrl', '')
163
+    user.country = userinfo.get('country', '')
164
+    user.province = userinfo.get('province', '')
165
+    user.city = userinfo.get('city', '')
166
+    user.save()
167
+
168
+    return response(200, 'Mini App Get Userinfo Success', '微信小程序获取用户信息成功', user.data)

+ 44 - 1
api/point_views.py

@@ -6,7 +6,7 @@ from django_logit import logit
6 6
 from django_query import get_query_value
7 7
 from django_response import response
8 8
 
9
-from equipment.models import IsolationPointInfo
9
+from equipment.models import IsolationPointInfo, IsolationPointUserInfo, ThermometerEquipmentInfo
10 10
 from utils.error.errno_utils import IsolationPointStatusCode
11 11
 
12 12
 
@@ -24,3 +24,46 @@ def measure_window(request):
24 24
     point.save()
25 25
 
26 26
     return response()
27
+
28
+
29
+@logit
30
+def get_point_fields(request):
31
+    point_id = request.POST.get('point_id', '')
32
+
33
+    try:
34
+        point = IsolationPointInfo.objects.get(point_id=point_id, status=True)
35
+    except IsolationPointInfo.DoesNotExist:
36
+        return response(IsolationPointStatusCode.ISOLATIONPOINT_NOT_FOUND)
37
+
38
+    return response(data={
39
+        'fields': point.point_fields,
40
+    })
41
+
42
+
43
+@logit
44
+def save_point_fields(request):
45
+    point_id = request.POST.get('point_id', '')
46
+    user_id = request.POST.get('user_id', '')
47
+    fields = get_query_value(request, 'fields', val_cast_type='listjson')
48
+
49
+    IsolationPointUserInfo.objects.create(point_id=point_id, user_id=user_id, fields=fields)
50
+
51
+    return response()
52
+
53
+
54
+@logit
55
+def bind_eqpt(request):
56
+    macid = request.POST.get('macid', '')
57
+    point_id = request.POST.get('point_id', '')
58
+    user_id = request.POST.get('user_id', '')
59
+
60
+    try:
61
+        ipui = IsolationPointUserInfo.objects.get(point_id=point_id, user_id=user_id, status=True)
62
+    except IsolationPointUserInfo.DoesNotExist:
63
+        return response()
64
+
65
+    ThermometerEquipmentInfo.objects.update_or_create(macid=macid, defaults={
66
+        'ipui_pk': ipui.pk,
67
+    })
68
+
69
+    return response()

+ 14 - 1
api/urls.py

@@ -2,7 +2,7 @@
2 2
 
3 3
 from django.conf.urls import url
4 4
 
5
-from api import admin_views, eqpt_views, oauth_views, point_views
5
+from api import admin_views, eqpt_views, mini_views, oauth_views, point_views
6 6
 
7 7
 
8 8
 urlpatterns = [
@@ -31,3 +31,16 @@ urlpatterns += [
31 31
 urlpatterns += [
32 32
     url(r'^upload/temperature$', eqpt_views.upload_temperature, name='upload_temperature'),
33 33
 ]
34
+
35
+# Mini App
36
+urlpatterns += [
37
+    url(r'^mp/userinfo$', mini_views.get_userinfo_api, name='get_userinfo_api'),  # 获取用户信息
38
+    url(r'^mp/login$', mini_views.mini_login_api, name='mini_login_api'),  # 小程序登录
39
+    url(r'^mp/userinfo2$', mini_views.get_userinfo_api2, name='get_userinfo_api2'),  # 获取用户信息
40
+]
41
+
42
+urlpatterns += [
43
+    url(r'^mp/get_point_fields$', point_views.get_point_fields, name='get_point_fields'),
44
+    url(r'^mp/save_point_fields$', point_views.save_point_fields, name='save_point_fields'),
45
+    url(r'^mp/bind_eqpt$', point_views.bind_eqpt, name='bind_eqpt'),
46
+]

+ 1 - 0
commands/management/commands/mqtt.py

@@ -6,6 +6,7 @@ import time
6 6
 
7 7
 from django_six import CompatibilityBaseCommand
8 8
 from paho.mqtt import client as mqtt_client
9
+
9 10
 from api.eqpt_views import mqtt_upload_temperature
10 11
 
11 12
 

+ 9 - 4
equipment/admin.py

@@ -3,16 +3,20 @@
3 3
 from django.contrib import admin
4 4
 from django_admin import ReadOnlyModelAdmin
5 5
 
6
-from equipment.models import (IsolationPointInfo, ThermometerEquipmentInfo, ThermometerMeasureInfo,
7
-                              ThermometerMeasureLogInfo)
6
+from equipment.models import (IsolationPointInfo, IsolationPointUserInfo, ThermometerEquipmentInfo,
7
+                              ThermometerMeasureInfo, ThermometerMeasureLogInfo)
8 8
 
9 9
 
10 10
 class IsolationPointInfoAdmin(admin.ModelAdmin):
11
-    list_display = ('point_id', 'point_name', 'point_measure_window', 'status', 'updated_at', 'created_at')
11
+    list_display = ('point_id', 'point_name', 'point_measure_window', 'point_fields', 'limit_scene_qrcode_url', 'status', 'updated_at', 'created_at')
12
+
13
+
14
+class IsolationPointUserInfoAdmin(admin.ModelAdmin):
15
+    list_display = ('point_id', 'user_id', 'fields', 'status', 'updated_at', 'created_at')
12 16
 
13 17
 
14 18
 class ThermometerEquipmentInfoAdmin(ReadOnlyModelAdmin, admin.ModelAdmin):
15
-    list_display = ('eqpt_id', 'point_id', 'macid', 'sn', 'active_status', 'active_at', 'name', 'sex', 'birth_stamp', 'age', 'phone', 'remark', 'last_submit_at', 'eqpt_register_status', 'eqpt_register_result', 'status', 'updated_at', 'created_at')
19
+    list_display = ('eqpt_id', 'point_id', 'macid', 'sn', 'active_status', 'active_at', 'ipui_pk', 'name', 'sex', 'birth_stamp', 'age', 'phone', 'remark', 'last_submit_at', 'eqpt_register_status', 'eqpt_register_result', 'status', 'updated_at', 'created_at')
16 20
     list_filter = ('point_id', 'status')
17 21
 
18 22
 
@@ -27,6 +31,7 @@ class ThermometerMeasureLogInfoAdmin(ReadOnlyModelAdmin, admin.ModelAdmin):
27 31
 
28 32
 
29 33
 admin.site.register(IsolationPointInfo, IsolationPointInfoAdmin)
34
+admin.site.register(IsolationPointUserInfo, IsolationPointUserInfoAdmin)
30 35
 admin.site.register(ThermometerEquipmentInfo, ThermometerEquipmentInfoAdmin)
31 36
 admin.site.register(ThermometerMeasureInfo, ThermometerMeasureInfoAdmin)
32 37
 admin.site.register(ThermometerMeasureLogInfo, ThermometerMeasureLogInfoAdmin)

+ 46 - 0
equipment/migrations/0006_auto_20210812_1357.py

@@ -0,0 +1,46 @@
1
+# Generated by Django 3.2.6 on 2021-08-12 05:57
2
+
3
+from django.db import migrations, models
4
+import jsonfield.fields
5
+
6
+
7
+class Migration(migrations.Migration):
8
+
9
+    dependencies = [
10
+        ('equipment', '0005_thermometermeasureloginfo_temperature_src'),
11
+    ]
12
+
13
+    operations = [
14
+        migrations.AddField(
15
+            model_name='isolationpointinfo',
16
+            name='limit_scene_qrcode_url',
17
+            field=models.CharField(blank=True, help_text='字段二维码', max_length=255, null=True, verbose_name='limit_scene_qrcode_url'),
18
+        ),
19
+        migrations.AddField(
20
+            model_name='isolationpointinfo',
21
+            name='point_fields',
22
+            field=jsonfield.fields.JSONField(blank=True, default=[], help_text='字段列表', null=True, verbose_name='point_fields'),
23
+        ),
24
+        migrations.AddField(
25
+            model_name='thermometerequipmentinfo',
26
+            name='ipui_pk',
27
+            field=models.IntegerField(default=0, help_text='隔离点用户录入PK', verbose_name='ipui_pk'),
28
+        ),
29
+        migrations.CreateModel(
30
+            name='IsolationPointUserInfo',
31
+            fields=[
32
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
33
+                ('status', models.BooleanField(default=True, help_text='Status', verbose_name='status')),
34
+                ('created_at', models.DateTimeField(auto_now_add=True, help_text='Create Time', verbose_name='created_at')),
35
+                ('updated_at', models.DateTimeField(auto_now=True, help_text='Update Time', verbose_name='updated_at')),
36
+                ('point_id', models.CharField(blank=True, db_index=True, help_text='隔离点唯一标识', max_length=32, null=True, verbose_name='point_id')),
37
+                ('user_id', models.CharField(blank=True, db_index=True, help_text='用户唯一标识', max_length=32, null=True, verbose_name='user_id')),
38
+                ('fields', jsonfield.fields.JSONField(blank=True, default=[], help_text='字段信息', null=True, verbose_name='fields')),
39
+            ],
40
+            options={
41
+                'verbose_name': '隔离点用户录入信息',
42
+                'verbose_name_plural': '隔离点用户录入信息',
43
+                'unique_together': {('point_id', 'user_id')},
44
+            },
45
+        ),
46
+    ]

+ 39 - 0
equipment/models.py

@@ -11,9 +11,19 @@ from TimeConvert import TimeConvert as tc
11 11
 class IsolationPointInfo(BaseModelMixin):
12 12
     point_id = ShortUUIDField(_('point_id'), max_length=32, blank=True, null=True, help_text='隔离点唯一标识', db_index=True, unique=True)
13 13
     point_name = models.CharField(_('point_name'), max_length=255, blank=True, null=True, help_text='隔离点名称')
14
+
14 15
     # [{"start": "8:00", "end": "9:00"}, {"start": "12:00", "end": "14:00"}]
15 16
     point_measure_window = JSONField(_('point_measure_window'), default=[], blank=True, null=True, help_text='隔离点测温时间段')
16 17
 
18
+    # {
19
+    #     "type": "input",  # input, select, file
20
+    #     "name": "",
21
+    #     "options": ["男", "女"],  # type=select
22
+    # }
23
+    point_fields = JSONField(_('point_fields'), default=[], blank=True, null=True, help_text='字段列表')
24
+
25
+    limit_scene_qrcode_url = models.CharField(_('limit_scene_qrcode_url'), max_length=255, blank=True, null=True, help_text='字段二维码')
26
+
17 27
     class Meta:
18 28
         verbose_name = _('隔离点信息')
19 29
         verbose_name_plural = _('隔离点信息')
@@ -42,6 +52,33 @@ class IsolationPointInfo(BaseModelMixin):
42 52
         return ''
43 53
 
44 54
 
55
+class IsolationPointUserInfo(BaseModelMixin):
56
+    point_id = models.CharField(_('point_id'), max_length=32, blank=True, null=True, help_text='隔离点唯一标识', db_index=True)
57
+
58
+    user_id = models.CharField(_('user_id'), max_length=32, blank=True, null=True, help_text='用户唯一标识', db_index=True)
59
+
60
+    fields = JSONField(_('fields'), default=[], blank=True, null=True, help_text='字段信息')
61
+
62
+    class Meta:
63
+        verbose_name = _('隔离点用户录入信息')
64
+        verbose_name_plural = _('隔离点用户录入信息')
65
+
66
+        unique_together = (
67
+            ('point_id', 'user_id'),
68
+        )
69
+
70
+    def __unicode__(self):
71
+        return self.pk
72
+
73
+    @property
74
+    def data(self):
75
+        return {
76
+            'point_id': self.point_id,
77
+            'user_id': self.user_id,
78
+            'fields': self.fields,
79
+        }
80
+
81
+
45 82
 class ThermometerEquipmentInfo(BaseModelMixin):
46 83
     ONLINE = 1
47 84
     OFFLINE = 0
@@ -70,6 +107,8 @@ class ThermometerEquipmentInfo(BaseModelMixin):
70 107
     active_at = models.DateTimeField(_('active_at'), blank=True, null=True, help_text=_('激活时间'))
71 108
 
72 109
     # 用户基本信息
110
+    ipui_pk = models.IntegerField(_('ipui_pk'), default=0, help_text='隔离点用户录入PK')
111
+
73 112
     name = models.CharField(_('name'), max_length=255, blank=True, null=True, help_text='用户姓名')
74 113
     sex = models.IntegerField(_('sex'), choices=SexModelMixin.SEX_TUPLE, default=SexModelMixin.UNKNOWN, help_text='用户性别')
75 114
     birth_stamp = models.BigIntegerField(_('birth_stamp'), default=0, help_text='生日时间戳')

+ 2 - 0
requirements_pywe.txt

@@ -1,2 +1,4 @@
1
+pywe-miniapp==1.1.6
1 2
 pywe-oauth==1.1.1
2 3
 pywe-pay==1.0.14
4
+pywe-storage==1.0.1

update · 9b7e2c183c - Gogs: Go Git Service

update

FFIB 3 年 前
コミット
9b7e2c183c
共有1 個のファイルを変更した1 個の追加1 個の削除を含む
  1. 1 1
      equipment/models.py

+ 1 - 1
equipment/models.py

@@ -237,7 +237,7 @@ class IsolationPointUserInfo(BaseModelMixin):
237 237
             return '-'
238 238
 
239 239
         if today.day == self.detect_at.day and today.month == self.detect_at.month and today.year == self.detect_at.year:
240
-            return '-' if self.antigen_result == 2 else self.get_antigen_result_display()
240
+            return '-' if self.antigen_result == 2 else self.antigen_result
241 241
         else:
242 242
             return '-'
243 243