No Description

member_views.py 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
  1. # -*- coding: utf-8 -*-
  2. from __future__ import division
  3. from django.conf import settings
  4. from django.db import transaction
  5. from django_logit import logit
  6. from django_query import get_query_value
  7. from django_response import response
  8. from paginator import pagination
  9. from TimeConvert import TimeConvert as tc
  10. from account.models import UserInfo
  11. from coupon.models import UserCouponInfo
  12. from member.models import (GoodsInfo, GoodsOrderInfo, MemberActivityInfo, MemberActivitySigninInfo,
  13. MemberActivitySignupInfo, RightInfo)
  14. from utils.error.errno_utils import (MemberActivityStatusCode, MemberCouponStatusCode, MemberGoodStatusCode, MemberRightStatusCode,
  15. UserStatusCode)
  16. from utils.redis.connect import r
  17. from utils.redis.rkeys import MEMBER_SEND_COUPON_LIST, MEMBER_UPGRADE_INFO
  18. from utils.redis.rshot import get_member_shot_data
  19. @logit
  20. def member(request):
  21. brand_id = request.POST.get('brand_id', settings.KODO_DEFAULT_BRAND_ID)
  22. user_id = request.POST.get('user_id', '')
  23. # 校验用户是否存在
  24. try:
  25. user = UserInfo.objects.get(user_id=user_id)
  26. except UserInfo.DoesNotExist:
  27. return response(UserStatusCode.USER_NOT_FOUND)
  28. rights = RightInfo.objects.filter(status=True).order_by('position')
  29. rights = [right.data for right in rights]
  30. goods = GoodsInfo.objects.filter(only_for_member=False, left_num__gt=0, status=True).order_by('position')
  31. goods = [good.data(user_id) for good in goods][:2]
  32. member_goods = GoodsInfo.objects.filter(only_for_member=True, left_num__gt=0, minlevel__lte=user.level, status=True).order_by('position')
  33. member_goods = [good.data(user_id) for good in member_goods]
  34. member_goods = [good for good in member_goods if not good['has_member_exchange']]
  35. upgrade_info, _ = r.getdel(MEMBER_UPGRADE_INFO % (brand_id, user_id))
  36. return response(200, data={
  37. 'nickname': user.final_nickname,
  38. 'avatar': user.avatar,
  39. 'integral': user.integral,
  40. 'freeze_integral': user.freeze_integral,
  41. 'final_integral': user.final_integral,
  42. 'shots_num': user.shots_num,
  43. 'level': user.level,
  44. 'rights': rights,
  45. 'goods': goods,
  46. 'member_goods': member_goods,
  47. 'has_upgrade': bool(upgrade_info),
  48. })
  49. @logit
  50. def rights(request):
  51. brand_id = request.POST.get('brand_id', settings.KODO_DEFAULT_BRAND_ID)
  52. user_id = request.POST.get('user_id', '')
  53. level = request.POST.get('level', '')
  54. # 校验用户是否存在
  55. try:
  56. user = UserInfo.objects.get(user_id=user_id)
  57. except UserInfo.DoesNotExist:
  58. return response(UserStatusCode.USER_NOT_FOUND)
  59. rights = RightInfo.objects.filter(status=True).order_by('position')
  60. rights = [right.data for right in rights]
  61. return response(200, data={
  62. 'nickname': user.final_nickname,
  63. 'avatar': user.avatar,
  64. 'integral': user.integral,
  65. 'freeze_integral': user.freeze_integral,
  66. 'final_integral': user.final_integral,
  67. 'shots_num': user.shots_num,
  68. 'level': user.level,
  69. 'rights': rights,
  70. })
  71. @logit
  72. def right_detail(request):
  73. brand_id = request.POST.get('brand_id', settings.KODO_DEFAULT_BRAND_ID)
  74. user_id = request.POST.get('user_id', '')
  75. right_id = request.POST.get('right_id', '')
  76. try:
  77. right = RightInfo.objects.get(right_id=right_id)
  78. except RightInfo.DoesNotExist:
  79. return response(MemberRightStatusCode.RIGHT_NOT_FOUND)
  80. return response(200, data={
  81. 'right': right.data,
  82. })
  83. @logit
  84. def goods(request):
  85. brand_id = request.POST.get('brand_id', settings.KODO_DEFAULT_BRAND_ID)
  86. user_id = request.POST.get('user_id', '')
  87. # 校验用户是否存在
  88. try:
  89. user = UserInfo.objects.get(user_id=user_id)
  90. except UserInfo.DoesNotExist:
  91. return response(UserStatusCode.USER_NOT_FOUND)
  92. raw_goods = GoodsInfo.objects.filter(only_for_member=False, left_num__gt=0, status=True).order_by('position', '-pk')
  93. banners = goods = []
  94. for good in raw_goods:
  95. if good.is_slider:
  96. banners.append(good.data(user_id))
  97. else:
  98. goods.append(good.data(user_id))
  99. return response(200, data={
  100. 'nickname': user.final_nickname,
  101. 'avatar': user.avatar,
  102. 'integral': user.integral,
  103. 'freeze_integral': user.freeze_integral,
  104. 'final_integral': user.final_integral,
  105. 'shots_num': user.shots_num,
  106. 'level': user.level,
  107. 'banners': banners,
  108. 'goods': goods,
  109. })
  110. @logit
  111. def good_detail(request):
  112. brand_id = request.POST.get('brand_id', settings.KODO_DEFAULT_BRAND_ID)
  113. user_id = request.POST.get('user_id', '')
  114. good_id = request.POST.get('good_id', '')
  115. # 校验用户是否存在
  116. try:
  117. user = UserInfo.objects.get(user_id=user_id)
  118. except UserInfo.DoesNotExist:
  119. return response(UserStatusCode.USER_NOT_FOUND)
  120. try:
  121. good = GoodsInfo.objects.get(good_id=good_id)
  122. except GoodsInfo.DoesNotExist:
  123. return response(MemberGoodStatusCode.GOOD_NOT_FOUND)
  124. return response(200, data={
  125. 'nickname': user.final_nickname,
  126. 'avatar': user.avatar,
  127. 'integral': user.integral,
  128. 'freeze_integral': user.freeze_integral,
  129. 'final_integral': user.final_integral,
  130. 'shots_num': user.shots_num,
  131. 'level': user.level,
  132. 'good': good.details(user_id),
  133. })
  134. @logit
  135. @transaction.atomic
  136. def good_exchange(request):
  137. brand_id = request.POST.get('brand_id', settings.KODO_DEFAULT_BRAND_ID)
  138. user_id = request.POST.get('user_id', '')
  139. good_id = request.POST.get('good_id', '')
  140. good_ids = get_query_value(request, 'good_ids', val_cast_type='listjson')
  141. name = request.POST.get('name', '')
  142. phone = request.POST.get('phone', '')
  143. address = request.POST.get('address', '')
  144. # 校验用户是否存在
  145. try:
  146. user = UserInfo.objects.select_for_update().get(user_id=user_id)
  147. except UserInfo.DoesNotExist:
  148. return response(UserStatusCode.USER_NOT_FOUND)
  149. if good_id:
  150. good_ids.append(good_id)
  151. goods = []
  152. for good_id in good_ids:
  153. try:
  154. good = GoodsInfo.objects.select_for_update().get(good_id=good_id)
  155. except GoodsInfo.DoesNotExist:
  156. return response(MemberGoodStatusCode.GOOD_NOT_FOUND)
  157. if good.left_num <= 0:
  158. return response(MemberGoodStatusCode.GOOD_STOCK_NOT_ENOUGH)
  159. if user.level < good.minlevel:
  160. return response(MemberGoodStatusCode.GOOD_NO_EXCHANGE_PERMISSION)
  161. if user.integral < good.integral:
  162. return response(MemberGoodStatusCode.GOOD_INTEGRAL_NOT_ENOUGH)
  163. user.integral -= good.integral
  164. user.save()
  165. good.left_num -= 1
  166. good.save()
  167. GoodsOrderInfo.objects.create(
  168. user_id=user_id,
  169. good_id=good_id,
  170. good_type=good.good_type,
  171. name=name,
  172. phone=phone,
  173. address=address,
  174. )
  175. if good.good_type == GoodsInfo.PHYSICAL:
  176. # TODO: 通知客服发快递
  177. pass
  178. else:
  179. # TODO: 发放虚拟商品
  180. if good.coupon_id:
  181. # 发放券
  182. r.rpushjson(MEMBER_SEND_COUPON_LIST, {
  183. 'brand_id': brand_id,
  184. 'user_id': user_id,
  185. 'coupon_id': good.coupon_id,
  186. })
  187. else:
  188. pass
  189. goods.append(good.data(user_id))
  190. return response(200, data={
  191. 'nickname': user.final_nickname,
  192. 'avatar': user.avatar,
  193. 'integral': user.integral,
  194. 'freeze_integral': user.freeze_integral,
  195. 'final_integral': user.final_integral,
  196. 'shots_num': user.shots_num,
  197. 'level': user.level,
  198. 'goods': goods,
  199. })
  200. @logit
  201. def coupons(request):
  202. brand_id = request.POST.get('brand_id', settings.KODO_DEFAULT_BRAND_ID)
  203. user_id = request.POST.get('user_id', '')
  204. page = request.POST.get('page', 1)
  205. num = request.POST.get('num', 20)
  206. coupons = UserCouponInfo.objects.filter(user_id=user_id, status=True).order_by('-pk')
  207. coupons, left = pagination(coupons, page, num)
  208. coupons = [coupon.data for coupon in coupons]
  209. return response(200, data={
  210. 'coupons': coupons,
  211. 'left': left,
  212. })
  213. @logit
  214. def user_coupon_detail(request):
  215. brand_id = request.POST.get('brand_id', settings.KODO_DEFAULT_BRAND_ID)
  216. user_coupon_id = request.POST.get('user_coupon_id', '')
  217. try:
  218. coupon = UserCouponInfo.objects.get(user_coupon_id=user_coupon_id, status=True)
  219. except UserCouponInfo.DoesNotExist:
  220. return response(MemberCouponStatusCode.USER_COUPON_NOT_FOUND)
  221. return response(200, data=coupon.data)
  222. @logit
  223. @transaction.atomic
  224. def user_coupon_use(request):
  225. brand_id = request.POST.get('brand_id', settings.KODO_DEFAULT_BRAND_ID)
  226. admin_id = request.POST.get('admin_id', '')
  227. user_coupon_id = request.POST.get('user_coupon_id', '')
  228. try:
  229. coupon = UserCouponInfo.objects.select_for_update().get(user_coupon_id=user_coupon_id, status=True)
  230. except UserCouponInfo.DoesNotExist:
  231. return response(MemberCouponStatusCode.USER_COUPON_NOT_FOUND)
  232. if not coupon.has_actived:
  233. return response(MemberCouponStatusCode.USER_COUPON_NOT_ACTIVED)
  234. if coupon.has_expired:
  235. return response(MemberCouponStatusCode.USER_COUPON_HAS_EXPIRED)
  236. if coupon.has_used:
  237. return response(MemberCouponStatusCode.USER_COUPON_HAS_USED)
  238. coupon.has_used = True
  239. coupon.admin_id = admin_id
  240. coupon.used_at = tc.utc_datetime()
  241. coupon.save()
  242. return response(200, data=coupon.data)
  243. @logit
  244. def integrals(request):
  245. brand_id = request.POST.get('brand_id', settings.KODO_DEFAULT_BRAND_ID)
  246. return response(200, data={
  247. 'shots_types': get_member_shot_data(),
  248. 'enable_photo_upvote_integral': True,
  249. 'mp_url': 'https://mp.weixin.qq.com/s/2K6PAnf3KrxtrP40-DBuww',
  250. 'photo_upvote_integrals': {
  251. 'headers': [u'排名', u'日', u'周', u'月'],
  252. 'ranks': [
  253. [u'第1名', '10', '20', '30'],
  254. [u'第2名', '5', '10', '15'],
  255. [u'第3名', '3', '6', '9'],
  256. [u'第4-10名', '1', '2', '3'],
  257. ]
  258. },
  259. 'enable_activity_integral': True,
  260. })
  261. @logit
  262. def activity_list(request):
  263. brand_id = request.POST.get('brand_id', settings.KODO_DEFAULT_BRAND_ID)
  264. user_id = request.POST.get('user_id', '')
  265. raw_activitys = MemberActivityInfo.objects.filter(status=True).order_by('-date')
  266. banners = []
  267. activitys = []
  268. for act in raw_activitys:
  269. if act.is_slider:
  270. banners.append(act.data(user_id))
  271. else:
  272. activitys.append(act.data(user_id))
  273. return response(200, data={
  274. 'banners': banners,
  275. 'activitys': activitys,
  276. })
  277. @logit
  278. def activity_detail(request):
  279. brand_id = request.POST.get('brand_id', settings.KODO_DEFAULT_BRAND_ID)
  280. user_id = request.POST.get('user_id', '')
  281. activity_id = request.POST.get('activity_id')
  282. try:
  283. act = MemberActivityInfo.objects.get(activity_id=activity_id, status=True)
  284. except MemberActivityInfo.DoesNotExist:
  285. return response(MemberActivityStatusCode.ACTIVITY_NOT_FOUND)
  286. return response(200, data={
  287. 'activity': act.details(user_id),
  288. })
  289. @logit
  290. def activity_signup(request):
  291. brand_id = request.POST.get('brand_id', settings.KODO_DEFAULT_BRAND_ID)
  292. user_id = request.POST.get('user_id', '')
  293. activity_id = request.POST.get('activity_id')
  294. name = request.POST.get('name', '')
  295. phone = request.POST.get('phone', '')
  296. try:
  297. act = MemberActivityInfo.objects.get(activity_id=activity_id, status=True)
  298. except MemberActivityInfo.DoesNotExist:
  299. return response(MemberActivityStatusCode.ACTIVITY_NOT_FOUND)
  300. MemberActivitySignupInfo.objects.update_or_create(user_id=user_id, activity_id=activity_id, defaults={
  301. 'title': act.title,
  302. 'name': name,
  303. 'phone': phone,
  304. })
  305. # TODO: 立即推送模版消息(报名成功,时间,地点)
  306. # TODO: 延迟(活动当天)推送模版消息(时间,地点)
  307. return response(200, data={
  308. 'activity': act.data(user_id),
  309. })
  310. @logit
  311. @transaction.atomic
  312. def activity_signin(request):
  313. brand_id = request.POST.get('brand_id', settings.KODO_DEFAULT_BRAND_ID)
  314. user_id = request.POST.get('user_id', '')
  315. activity_id = request.POST.get('activity_id')
  316. # 校验用户是否存在
  317. try:
  318. user = UserInfo.objects.select_for_update().get(user_id=user_id)
  319. except UserInfo.DoesNotExist:
  320. return response(UserStatusCode.USER_NOT_FOUND)
  321. try:
  322. act = MemberActivityInfo.objects.get(activity_id=activity_id, status=True)
  323. except MemberActivityInfo.DoesNotExist:
  324. return response(MemberActivityStatusCode.ACTIVITY_NOT_FOUND)
  325. MemberActivitySigninInfo.objects.update_or_create(user_id=user_id, activity_id=activity_id, defaults={
  326. 'title': act.title,
  327. })
  328. user.integral += act.integral
  329. user.save()
  330. # TODO: 立即推送模版消息(感谢您参加活动,获得的积分)
  331. return response(200, data={
  332. 'activity': act.data(user_id),
  333. })