@@ -1,6 +1,8 @@ |
||
1 | 1 |
# -*- coding: utf-8 -*- |
2 | 2 |
|
3 | 3 |
import logging |
4 |
+import requests |
|
5 |
+import json |
|
4 | 6 |
|
5 | 7 |
from django.core.paginator import Paginator |
6 | 8 |
from django.contrib.auth.hashers import check_password |
@@ -9,6 +11,10 @@ from django.db.models import Q |
||
9 | 11 |
from django_logit import logit |
10 | 12 |
from django_response import response |
11 | 13 |
from TimeConvert import TimeConvert as tc |
14 |
+from django.conf import settings |
|
15 |
+ |
|
16 |
+from pywe_token import access_token |
|
17 |
+from pywe_storage import RedisStorage |
|
12 | 18 |
|
13 | 19 |
from account.models import AdministratorInfo |
14 | 20 |
from goods.models import GoodsInfo, PackInfo |
@@ -17,9 +23,10 @@ from pay.models import OrderInfo |
||
17 | 23 |
from live.models import RoomInfo, RoomGoodsInfo, RoomOrderInfo, AnchorInfo, liveGoodsInfo |
18 | 24 |
from utils.error.errno_utils import AdministratorStatusCode, OrderStatusCode |
19 | 25 |
|
26 |
+from utils.redis.connect import r |
|
20 | 27 |
|
21 | 28 |
logger = logging.getLogger('logit') |
22 |
- |
|
29 |
+WECHAT = settings.WECHAT |
|
23 | 30 |
|
24 | 31 |
@logit(res=True) |
25 | 32 |
def login(request): |
@@ -48,7 +55,6 @@ def login(request): |
||
48 | 55 |
|
49 | 56 |
|
50 | 57 |
@logit(res=True) |
51 |
-@transaction.atomic |
|
52 | 58 |
def order_list(request): |
53 | 59 |
admin_id = request.POST.get('admin_id', '') |
54 | 60 |
kol_id = request.POST.get('kol_id', '') |
@@ -134,6 +140,7 @@ def order_update(request): |
||
134 | 140 |
|
135 | 141 |
return response(200, 'Order Update Success', '订单更新成功') |
136 | 142 |
|
143 |
+@logit(res=True) |
|
137 | 144 |
def live_goods_list(request): |
138 | 145 |
admin_id = request.POST.get('admin_id', '') |
139 | 146 |
page = request.POST.get('page', 1) |
@@ -154,6 +161,7 @@ def live_goods_list(request): |
||
154 | 161 |
'count': count, |
155 | 162 |
}) |
156 | 163 |
|
164 |
+@logit(res=True) |
|
157 | 165 |
def live_room_list(request): |
158 | 166 |
admin_id = request.POST.get('admin_id', '') |
159 | 167 |
page = request.POST.get('page', 1) |
@@ -172,4 +180,42 @@ def live_room_list(request): |
||
172 | 180 |
return response(200, 'Live Goods Success', u'直播商品库获取成功', data={ |
173 | 181 |
'rooms': rooms, |
174 | 182 |
'count': count, |
175 |
- }) |
|
183 |
+ }) |
|
184 |
+ |
|
185 |
+@logit(res=True) |
|
186 |
+def fetch_wx_room_list(request): |
|
187 |
+ admin_id = request.POST.get('admin_id', '') |
|
188 |
+ try: |
|
189 |
+ administrator = AdministratorInfo.objects.get(admin_id=admin_id, user_status=AdministratorInfo.ACTIVATED, status=True) |
|
190 |
+ except AdministratorInfo.DoesNotExist: |
|
191 |
+ return response(AdministratorStatusCode.ADMINISTRATOR_NOT_FOUND) |
|
192 |
+ |
|
193 |
+ |
|
194 |
+ wxcfg = WECHAT.get('MINIAPP', {}) |
|
195 |
+ |
|
196 |
+ appid = wxcfg.get('appID') |
|
197 |
+ secret = wxcfg.get('appsecret') |
|
198 |
+ token = access_token(appid, secret) |
|
199 |
+ |
|
200 |
+ rooms = RoomInfo.objects.filter(Q(live_status=101) | Q(live_status=102)) |
|
201 |
+ roominfos = requests.post(url=('http://api.weixin.qq.com/wxa/business/getliveinfo?access_token='+token), json={'start': rooms[0].room_id, 'limit': 100}) |
|
202 |
+ |
|
203 |
+ roominfos = json.loads(roominfos.text).get('room_info', {}) |
|
204 |
+ for roominfo in roominfos: |
|
205 |
+ anchor, _ = AnchorInfo.objects.get_or_create( |
|
206 |
+ anchor_name=roominfo.get('anchor_name') |
|
207 |
+ ) |
|
208 |
+ room, _ = RoomInfo.objects.get_or_create( |
|
209 |
+ room_id=roominfo.get('roomid') |
|
210 |
+ ) |
|
211 |
+ room.name = roominfo.get('name', '') |
|
212 |
+ room.live_status = roominfo.get('live_status', '') |
|
213 |
+ room.start_time = roominfo.get('start_time', '') |
|
214 |
+ room.end_time = roominfo.get('end_time', '') |
|
215 |
+ room.wx_cover_img = roominfo.get('cover_img', '') |
|
216 |
+ room.wx_share_img = roominfo.get('share_img', '') |
|
217 |
+ room.anchor_name = roominfo.get('anchor_name', '') |
|
218 |
+ room.anchor_id = anchor.anchor_id |
|
219 |
+ room.save() |
|
220 |
+ |
|
221 |
+ return response(200, 'Fetch wx Room List Success', u'微信直播间列表获取成功') |
@@ -40,7 +40,10 @@ urlpatterns += [ |
||
40 | 40 |
|
41 | 41 |
# 直播 |
42 | 42 |
url(r'^admin/live/goods/list$', admin_views.live_goods_list, name='live_goods_list'), # 直播商品库列表 |
43 |
- url(r'^admin/live/room/list$', admin_views.live_room_list, name='live_room_list'), # 直播商品库列表 |
|
43 |
+ url(r'^admin/live/room/list$', admin_views.live_room_list, name='live_room_list'), # 直播间列表 |
|
44 |
+ |
|
45 |
+ #微信直播 api |
|
46 |
+ url(r'^admin/live/wx/room/list$', admin_views.fetch_wx_room_list, name='fetch_wx_room_list'), # 微信直播间列表 |
|
44 | 47 |
] |
45 | 48 |
|
46 | 49 |
urlpatterns += [ |
@@ -0,0 +1,34 @@ |
||
1 |
+# Generated by Django 2.2.12 on 2020-05-20 08:23 |
|
2 |
+ |
|
3 |
+from django.db import migrations, models |
|
4 |
+import django_models_ext.fileext |
|
5 |
+ |
|
6 |
+ |
|
7 |
+class Migration(migrations.Migration): |
|
8 |
+ |
|
9 |
+ dependencies = [ |
|
10 |
+ ('live', '0007_auto_20200520_1347'), |
|
11 |
+ ] |
|
12 |
+ |
|
13 |
+ operations = [ |
|
14 |
+ migrations.AddField( |
|
15 |
+ model_name='roominfo', |
|
16 |
+ name='wx_cover_img', |
|
17 |
+ field=models.CharField(blank=True, db_index=True, help_text='微信直播背景墙', max_length=255, verbose_name='wx_cover_img'), |
|
18 |
+ ), |
|
19 |
+ migrations.AddField( |
|
20 |
+ model_name='roominfo', |
|
21 |
+ name='wx_share_img', |
|
22 |
+ field=models.CharField(blank=True, db_index=True, help_text='微信直播分享卡片图片', max_length=255, verbose_name='wx_share_img'), |
|
23 |
+ ), |
|
24 |
+ migrations.AlterField( |
|
25 |
+ model_name='roominfo', |
|
26 |
+ name='cover_img', |
|
27 |
+ field=models.ImageField(help_text='直播间背景墙', null=True, upload_to=django_models_ext.fileext.upload_path, verbose_name='cover_img'), |
|
28 |
+ ), |
|
29 |
+ migrations.AlterField( |
|
30 |
+ model_name='roominfo', |
|
31 |
+ name='share_img', |
|
32 |
+ field=models.ImageField(help_text='分享卡片图片', null=True, upload_to=django_models_ext.fileext.upload_path, verbose_name='share_img'), |
|
33 |
+ ), |
|
34 |
+ ] |
@@ -0,0 +1,48 @@ |
||
1 |
+# Generated by Django 2.2.12 on 2020-05-20 08:52 |
|
2 |
+ |
|
3 |
+from django.db import migrations, models |
|
4 |
+ |
|
5 |
+ |
|
6 |
+class Migration(migrations.Migration): |
|
7 |
+ |
|
8 |
+ dependencies = [ |
|
9 |
+ ('live', '0008_auto_20200520_1623'), |
|
10 |
+ ] |
|
11 |
+ |
|
12 |
+ operations = [ |
|
13 |
+ migrations.AlterField( |
|
14 |
+ model_name='livegoodsinfo', |
|
15 |
+ name='price', |
|
16 |
+ field=models.IntegerField(blank=True, help_text='price', verbose_name='price'), |
|
17 |
+ ), |
|
18 |
+ migrations.AlterField( |
|
19 |
+ model_name='livegoodsinfo', |
|
20 |
+ name='price2', |
|
21 |
+ field=models.IntegerField(blank=True, help_text='price2', verbose_name='price2'), |
|
22 |
+ ), |
|
23 |
+ migrations.AlterField( |
|
24 |
+ model_name='livegoodsinfo', |
|
25 |
+ name='price_type', |
|
26 |
+ field=models.IntegerField(blank=True, db_index=True, help_text='价格类型', verbose_name='price_type'), |
|
27 |
+ ), |
|
28 |
+ migrations.AlterField( |
|
29 |
+ model_name='roominfo', |
|
30 |
+ name='anchor_id', |
|
31 |
+ field=models.CharField(blank=True, help_text='主播唯一标识', max_length=32, verbose_name='anchor_id'), |
|
32 |
+ ), |
|
33 |
+ migrations.AlterField( |
|
34 |
+ model_name='roominfo', |
|
35 |
+ name='end_time', |
|
36 |
+ field=models.IntegerField(blank=True, db_index=True, help_text='直播计划结束时间', verbose_name='end_time'), |
|
37 |
+ ), |
|
38 |
+ migrations.AlterField( |
|
39 |
+ model_name='roominfo', |
|
40 |
+ name='live_status', |
|
41 |
+ field=models.IntegerField(blank=True, db_index=True, help_text='直播状态', verbose_name='live_status'), |
|
42 |
+ ), |
|
43 |
+ migrations.AlterField( |
|
44 |
+ model_name='roominfo', |
|
45 |
+ name='start_time', |
|
46 |
+ field=models.IntegerField(blank=True, db_index=True, help_text='直播计划开始时间', verbose_name='start_time'), |
|
47 |
+ ), |
|
48 |
+ ] |
@@ -0,0 +1,28 @@ |
||
1 |
+# Generated by Django 2.2.12 on 2020-05-20 09:16 |
|
2 |
+ |
|
3 |
+from django.db import migrations, models |
|
4 |
+ |
|
5 |
+ |
|
6 |
+class Migration(migrations.Migration): |
|
7 |
+ |
|
8 |
+ dependencies = [ |
|
9 |
+ ('live', '0009_auto_20200520_1652'), |
|
10 |
+ ] |
|
11 |
+ |
|
12 |
+ operations = [ |
|
13 |
+ migrations.AlterField( |
|
14 |
+ model_name='roominfo', |
|
15 |
+ name='end_time', |
|
16 |
+ field=models.IntegerField(blank=True, db_index=True, default=0, help_text='直播计划结束时间', verbose_name='end_time'), |
|
17 |
+ ), |
|
18 |
+ migrations.AlterField( |
|
19 |
+ model_name='roominfo', |
|
20 |
+ name='live_status', |
|
21 |
+ field=models.IntegerField(blank=True, db_index=True, default=0, help_text='直播状态', verbose_name='live_status'), |
|
22 |
+ ), |
|
23 |
+ migrations.AlterField( |
|
24 |
+ model_name='roominfo', |
|
25 |
+ name='start_time', |
|
26 |
+ field=models.IntegerField(blank=True, db_index=True, default=0, help_text='直播计划开始时间', verbose_name='start_time'), |
|
27 |
+ ), |
|
28 |
+ ] |
@@ -45,14 +45,16 @@ class AnchorInfo(BaseModelMixin): |
||
45 | 45 |
class RoomInfo(BaseModelMixin): |
46 | 46 |
room_id = models.CharField(_('anchor_id'), max_length=32, help_text='房间唯一标识', db_index=True, unique=True) |
47 | 47 |
name = models.CharField(_('name'), max_length=255, blank=True, help_text='直播房间名', db_index=True) |
48 |
- live_status = models.IntegerField(_('live_status'), help_text='直播状态', db_index=True) |
|
49 |
- start_time = models.IntegerField(_('start_time'), help_text='直播计划开始时间', db_index=True) |
|
50 |
- end_time = models.IntegerField(_('end_time'), help_text='直播计划结束时间', db_index=True) |
|
51 |
- cover_img = models.ImageField(_('cover_img'), upload_to=upload_path, help_text='直播间背景墙') |
|
48 |
+ live_status = models.IntegerField(_('live_status'), default=0, blank=True, help_text='直播状态', db_index=True) |
|
49 |
+ start_time = models.IntegerField(_('start_time'), default=0, blank=True, help_text='直播计划开始时间', db_index=True) |
|
50 |
+ end_time = models.IntegerField(_('end_time'), default=0, blank=True, help_text='直播计划结束时间', db_index=True) |
|
51 |
+ cover_img = models.ImageField(_('cover_img'), upload_to=upload_path, null=True, help_text='直播间背景墙') |
|
52 |
+ wx_cover_img = models.CharField(_('wx_cover_img'), blank=True, max_length=255, help_text='微信直播背景墙', db_index=True) |
|
53 |
+ share_img = models.ImageField(_('share_img'), upload_to=upload_path, null=True, help_text='分享卡片图片') |
|
54 |
+ wx_share_img = models.CharField(_('wx_share_img'), blank=True, max_length=255, help_text='微信直播分享卡片图片', db_index=True) |
|
55 |
+ |
|
56 |
+ anchor_id = models.CharField(_('anchor_id'), blank=True, max_length=32, help_text='主播唯一标识') |
|
52 | 57 |
anchor_name = models.CharField(_('anchor_name'), blank=True, max_length=255, help_text='主播名称', db_index=True) |
53 |
- share_img = models.ImageField(_('share_img'), upload_to=upload_path, help_text='分享卡片图片') |
|
54 |
- |
|
55 |
- anchor_id = models.CharField(_('anchor_id'), max_length=32, help_text='主播唯一标识') |
|
56 | 58 |
|
57 | 59 |
# "goods": [ |
58 | 60 |
# { |
@@ -93,8 +95,8 @@ class RoomInfo(BaseModelMixin): |
||
93 | 95 |
'room_id': self.room_id, |
94 | 96 |
'name': self.name, |
95 | 97 |
'live_status': self.live_status, |
96 |
- 'cover_img': self.cover_img_url, |
|
97 |
- 'share_img': self.share_img_url, |
|
98 |
+ 'cover_img': self.wx_cover_img, |
|
99 |
+ 'share_img': self.wx_share_img, |
|
98 | 100 |
} |
99 | 101 |
|
100 | 102 |
@property |
@@ -105,9 +107,9 @@ class RoomInfo(BaseModelMixin): |
||
105 | 107 |
'name': self.name, |
106 | 108 |
'live_status': self.live_status, |
107 | 109 |
'end_time': self.end_time, |
108 |
- 'cover_img': self.cover_img_url, |
|
110 |
+ 'cover_img': self.wx_cover_img, |
|
109 | 111 |
'anchor_name': self.anchor_name, |
110 |
- 'share_img': self.share_img_url, |
|
112 |
+ 'share_img': self.wx_share_img, |
|
111 | 113 |
'anchor_id': self.anchor_id, |
112 | 114 |
'anchor_name': anchor.anchor_name, |
113 | 115 |
'anchor_avatar': anchor.anchor_avatar_url |
@@ -137,9 +139,9 @@ class liveGoodsInfo(BaseModelMixin): |
||
137 | 139 |
name = models.CharField(_('name'), max_length=34, help_text='商品', blank=True, db_index=True) |
138 | 140 |
|
139 | 141 |
# 价格类型,1:一口价,2:价格区间,3:显示折扣价;1:一口价,只需要传入price,price2不传;2:价格区间,price字段为左边界,price2字段为右边界,price和price2必传。3:折扣价,price字段为原价,price2字段为现价, price和price2必传 |
140 |
- price_type = models.IntegerField(_('price_type'), help_text='价格类型', db_index=True) |
|
141 |
- price = models.IntegerField(_('price'), help_text='price') |
|
142 |
- price2 = models.IntegerField(_('price2'), help_text='price2') |
|
142 |
+ price_type = models.IntegerField(_('price_type'), blank=True, help_text='价格类型', db_index=True) |
|
143 |
+ price = models.IntegerField(_('price'), blank=True, help_text='price') |
|
144 |
+ price2 = models.IntegerField(_('price2'), blank=True, help_text='price2') |
|
143 | 145 |
url = models.CharField(_('url'), max_length=255, blank=True, help_text='小程序商品路径', db_index=True) |
144 | 146 |
|
145 | 147 |
class Meta: |
@@ -2,4 +2,5 @@ pywe_miniapp==1.1.5 |
||
2 | 2 |
pywe-oauth==1.1.1 |
3 | 3 |
pywe-pay==1.0.14 |
4 | 4 |
pywe-pay-notify==1.0.5 |
5 |
-pywe-response==1.0.1 |
|
5 |
+pywe-response==1.0.1 |
|
6 |
+pywe-token===1.3.1 |