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)
|
|
|
|
@@ -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()
|
|
|
|
@@ -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
|
+]
|
|
|
|
@@ -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
|
|
|
|
|
@@ -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)
|
|
|
|
@@ -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
|
+ ]
|
|
|
|
@@ -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='生日时间戳')
|
|
|
|
@@ -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
|