No Description

member_views.py 28KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789
  1. # -*- coding: utf-8 -*-
  2. from __future__ import division
  3. from django.conf import settings
  4. from django.db import transaction
  5. from django.db.models import Sum
  6. from django_logit import logit
  7. from django_query import get_query_value
  8. from django_response import response
  9. from paginator import pagination
  10. from pywe_miniapp import get_shareinfo
  11. from pywe_storage import RedisStorage
  12. from TimeConvert import TimeConvert as tc
  13. from account.models import UserInfo, UserIntegralIncomeExpensesInfo
  14. from coupon.models import UserCouponInfo
  15. from member.models import (GoodsInfo, GoodsOrderInfo, MemberActivityContributionInfo,
  16. MemberActivityContributionWelfareUnlockingInfo, MemberActivityGroupShareInfo,
  17. MemberActivityInfo, MemberActivitySigninInfo, MemberActivitySignupInfo, RightInfo)
  18. from utils.error.errno_utils import (MemberActivityContributionStatusCode,
  19. MemberActivityContributionWelfareUnblockingStatusCode, MemberActivityStatusCode,
  20. MemberCouponStatusCode, MemberGoodStatusCode, MemberRightStatusCode,
  21. PermissionStatusCode, UserStatusCode)
  22. from utils.redis.connect import r
  23. from utils.redis.rkeys import MEMBER_SEND_COUPON_LIST, MEMBER_UPGRADE_INFO
  24. from utils.redis.rshot import get_member_shot_data
  25. WECHAT = settings.WECHAT
  26. @logit
  27. def member(request):
  28. brand_id = request.POST.get('brand_id') or settings.KODO_DEFAULT_BRAND_ID
  29. user_id = request.POST.get('user_id', '')
  30. # 校验用户是否存在
  31. try:
  32. user = UserInfo.objects.get(user_id=user_id)
  33. except UserInfo.DoesNotExist:
  34. return response(UserStatusCode.USER_NOT_FOUND)
  35. rights = RightInfo.objects.filter(status=True).order_by('position')
  36. rights = [right.data for right in rights]
  37. goods = GoodsInfo.objects.filter(only_for_member=False, left_num__gt=0, status=True).order_by('position')
  38. goods = [good.data(user_id) for good in goods][:2]
  39. member_goods = GoodsInfo.objects.filter(only_for_member=True, left_num__gt=0, minlevel__lte=user.level, status=True).order_by('position')
  40. member_goods = [good.data(user_id) for good in member_goods]
  41. member_goods = [good for good in member_goods if not good['has_member_exchange']]
  42. upgrade_info, _ = r.getdel(MEMBER_UPGRADE_INFO % (brand_id, user_id))
  43. return response(data={
  44. 'nickname': user.final_nickname,
  45. 'avatar': user.final_avatar,
  46. 'integral': user.integral,
  47. 'freeze_integral': user.freeze_integral,
  48. 'final_integral': user.final_integral,
  49. 'shots_num': user.shots_num,
  50. 'level': user.level,
  51. 'rights': rights,
  52. 'goods': goods,
  53. 'member_goods': member_goods,
  54. 'has_upgrade': bool(upgrade_info),
  55. })
  56. @logit
  57. def rights(request):
  58. brand_id = request.POST.get('brand_id') or settings.KODO_DEFAULT_BRAND_ID
  59. user_id = request.POST.get('user_id', '')
  60. level = request.POST.get('level', '')
  61. # 校验用户是否存在
  62. try:
  63. user = UserInfo.objects.get(user_id=user_id)
  64. except UserInfo.DoesNotExist:
  65. return response(UserStatusCode.USER_NOT_FOUND)
  66. rights = RightInfo.objects.filter(status=True).order_by('position')
  67. rights = [right.data for right in rights]
  68. return response(data={
  69. 'nickname': user.final_nickname,
  70. 'avatar': user.final_avatar,
  71. 'integral': user.integral,
  72. 'freeze_integral': user.freeze_integral,
  73. 'final_integral': user.final_integral,
  74. 'shots_num': user.shots_num,
  75. 'level': user.level,
  76. 'rights': rights,
  77. })
  78. @logit
  79. def right_detail(request):
  80. brand_id = request.POST.get('brand_id') or settings.KODO_DEFAULT_BRAND_ID
  81. user_id = request.POST.get('user_id', '')
  82. right_id = request.POST.get('right_id', '')
  83. try:
  84. right = RightInfo.objects.get(right_id=right_id)
  85. except RightInfo.DoesNotExist:
  86. return response(MemberRightStatusCode.RIGHT_NOT_FOUND)
  87. return response(data={
  88. 'right': right.data,
  89. })
  90. @logit
  91. def goods(request):
  92. brand_id = request.POST.get('brand_id') or settings.KODO_DEFAULT_BRAND_ID
  93. user_id = request.POST.get('user_id', '')
  94. # 校验用户是否存在
  95. try:
  96. user = UserInfo.objects.get(user_id=user_id)
  97. except UserInfo.DoesNotExist:
  98. return response(UserStatusCode.USER_NOT_FOUND)
  99. raw_goods = GoodsInfo.objects.filter(only_for_member=False, left_num__gt=0, good_state=GoodsInfo.SHELVES, status=True).order_by('position', '-pk')
  100. banners = goods = []
  101. for good in raw_goods:
  102. if good.is_slider:
  103. banners.append(good.data(user_id))
  104. else:
  105. goods.append(good.data(user_id))
  106. return response(data={
  107. 'nickname': user.final_nickname,
  108. 'avatar': user.final_avatar,
  109. 'integral': user.integral,
  110. 'freeze_integral': user.freeze_integral,
  111. 'final_integral': user.final_integral,
  112. 'shots_num': user.shots_num,
  113. 'level': user.level,
  114. 'banners': banners,
  115. 'goods': goods,
  116. })
  117. @logit
  118. def good_detail(request):
  119. brand_id = request.POST.get('brand_id') or settings.KODO_DEFAULT_BRAND_ID
  120. user_id = request.POST.get('user_id', '')
  121. good_id = request.POST.get('good_id', '')
  122. # 校验用户是否存在
  123. try:
  124. user = UserInfo.objects.get(user_id=user_id)
  125. except UserInfo.DoesNotExist:
  126. return response(UserStatusCode.USER_NOT_FOUND)
  127. try:
  128. good = GoodsInfo.objects.get(good_id=good_id)
  129. except GoodsInfo.DoesNotExist:
  130. return response(MemberGoodStatusCode.GOOD_NOT_FOUND)
  131. return response(data={
  132. 'nickname': user.final_nickname,
  133. 'avatar': user.final_avatar,
  134. 'integral': user.integral,
  135. 'freeze_integral': user.freeze_integral,
  136. 'final_integral': user.final_integral,
  137. 'shots_num': user.shots_num,
  138. 'level': user.level,
  139. 'good': good.details(user_id),
  140. })
  141. @logit
  142. @transaction.atomic
  143. def good_exchange(request):
  144. brand_id = request.POST.get('brand_id') or settings.KODO_DEFAULT_BRAND_ID
  145. user_id = request.POST.get('user_id', '')
  146. good_id = request.POST.get('good_id', '')
  147. good_ids = get_query_value(request, 'good_ids', val_cast_type='listjson')
  148. name = request.POST.get('name', '')
  149. phone = request.POST.get('phone', '')
  150. address = request.POST.get('address', '')
  151. # 校验用户是否存在
  152. try:
  153. user = UserInfo.objects.select_for_update().get(user_id=user_id)
  154. except UserInfo.DoesNotExist:
  155. return response(UserStatusCode.USER_NOT_FOUND)
  156. if good_id:
  157. good_ids.append(good_id)
  158. goods = []
  159. for good_id in good_ids:
  160. try:
  161. good = GoodsInfo.objects.select_for_update().get(good_id=good_id)
  162. except GoodsInfo.DoesNotExist:
  163. return response(MemberGoodStatusCode.GOOD_NOT_FOUND)
  164. if good.left_num <= 0:
  165. return response(MemberGoodStatusCode.GOOD_STOCK_NOT_ENOUGH)
  166. if user.level < good.minlevel:
  167. return response(MemberGoodStatusCode.GOOD_NO_EXCHANGE_PERMISSION)
  168. if user.integral < good.integral:
  169. return response(MemberGoodStatusCode.GOOD_INTEGRAL_NOT_ENOUGH)
  170. # 校验重复兑换
  171. if good.only_once and GoodsOrderInfo.objects.filter(user_id=user_id, good_id=good_id, status=True).exists():
  172. return response(MemberGoodStatusCode.GOOD_EXCHANGE_ONLY_ONCE)
  173. if good.good_type == GoodsInfo.PHYSICAL and address == '':
  174. return response(MemberGoodStatusCode.GOOD_NO_ADDRESS)
  175. user.integral -= good.integral
  176. user.save()
  177. good.left_num -= 1
  178. good.save()
  179. GoodsOrderInfo.objects.create(
  180. user_id=user_id,
  181. good_id=good_id,
  182. good_type=good.good_type,
  183. title=good.title,
  184. relate_good_title=good.relate_good_title,
  185. name=name,
  186. phone=phone,
  187. address=address,
  188. integral=good.integral,
  189. )
  190. if good.good_type == GoodsInfo.PHYSICAL:
  191. # TODO: 通知客服发快递
  192. pass
  193. else:
  194. # TODO: 发放虚拟商品
  195. if good.coupon_id:
  196. # 发放券
  197. r.rpushjson(MEMBER_SEND_COUPON_LIST, {
  198. 'brand_id': brand_id,
  199. 'user_id': user_id,
  200. 'coupon_id': good.coupon_id,
  201. })
  202. else:
  203. pass
  204. goods.append(good.data(user_id))
  205. return response(data={
  206. 'nickname': user.final_nickname,
  207. 'avatar': user.final_avatar,
  208. 'integral': user.integral,
  209. 'freeze_integral': user.freeze_integral,
  210. 'final_integral': user.final_integral,
  211. 'shots_num': user.shots_num,
  212. 'level': user.level,
  213. 'goods': goods,
  214. })
  215. @logit
  216. def coupons(request):
  217. brand_id = request.POST.get('brand_id') or settings.KODO_DEFAULT_BRAND_ID
  218. user_id = request.POST.get('user_id', '')
  219. page = request.POST.get('page', 1)
  220. num = request.POST.get('num', 20)
  221. coupons = UserCouponInfo.objects.filter(user_id=user_id, status=True).order_by('-pk')
  222. coupons, left = pagination(coupons, page, num)
  223. coupons = [coupon.data for coupon in coupons]
  224. return response(data={
  225. 'coupons': coupons,
  226. 'left': left,
  227. })
  228. @logit
  229. def user_coupon_detail(request):
  230. brand_id = request.POST.get('brand_id') or settings.KODO_DEFAULT_BRAND_ID
  231. user_coupon_id = request.POST.get('user_coupon_id', '')
  232. try:
  233. coupon = UserCouponInfo.objects.get(user_coupon_id=user_coupon_id, status=True)
  234. except UserCouponInfo.DoesNotExist:
  235. return response(MemberCouponStatusCode.USER_COUPON_NOT_FOUND)
  236. return response(data=coupon.data)
  237. @logit
  238. @transaction.atomic
  239. def user_coupon_use(request):
  240. brand_id = request.POST.get('brand_id') or settings.KODO_DEFAULT_BRAND_ID
  241. admin_id = request.POST.get('admin_id', '')
  242. user_coupon_id = request.POST.get('user_coupon_id', '')
  243. try:
  244. coupon = UserCouponInfo.objects.select_for_update().get(user_coupon_id=user_coupon_id, status=True)
  245. except UserCouponInfo.DoesNotExist:
  246. return response(MemberCouponStatusCode.USER_COUPON_NOT_FOUND)
  247. if not coupon.has_actived:
  248. return response(MemberCouponStatusCode.USER_COUPON_NOT_ACTIVED)
  249. if coupon.has_expired:
  250. return response(MemberCouponStatusCode.USER_COUPON_HAS_EXPIRED)
  251. if coupon.has_used:
  252. return response(MemberCouponStatusCode.USER_COUPON_HAS_USED)
  253. coupon.has_used = True
  254. coupon.admin_id = admin_id
  255. coupon.used_at = tc.utc_datetime()
  256. coupon.save()
  257. return response(data=coupon.data)
  258. @logit
  259. def integrals(request):
  260. brand_id = request.POST.get('brand_id') or settings.KODO_DEFAULT_BRAND_ID
  261. return response(data={
  262. 'shots_types': get_member_shot_data(),
  263. 'enable_photo_upvote_integral': True,
  264. 'mp_url': 'https://mp.weixin.qq.com/s/2K6PAnf3KrxtrP40-DBuww',
  265. 'photo_upvote_integrals': {
  266. 'headers': [u'排名', u'日', u'周', u'月'],
  267. 'ranks': [
  268. [u'第1名', '10', '20', '30'],
  269. [u'第2名', '5', '10', '15'],
  270. [u'第3名', '3', '6', '9'],
  271. [u'第4-10名', '1', '2', '3'],
  272. ]
  273. },
  274. 'enable_activity_integral': True,
  275. })
  276. @logit
  277. def activity_list(request):
  278. brand_id = request.POST.get('brand_id') or settings.KODO_DEFAULT_BRAND_ID
  279. user_id = request.POST.get('user_id', '')
  280. raw_activitys = MemberActivityInfo.objects.filter(activity_state=1, status=True).order_by('-date')
  281. banners = []
  282. activitys = []
  283. for act in raw_activitys:
  284. if act.is_slider:
  285. banners.append(act.data(user_id))
  286. else:
  287. activitys.append(act.data(user_id))
  288. return response(data={
  289. 'banners': banners,
  290. 'activitys': activitys,
  291. })
  292. @logit
  293. def activity_detail(request):
  294. brand_id = request.POST.get('brand_id') or settings.KODO_DEFAULT_BRAND_ID
  295. user_id = request.POST.get('user_id', '')
  296. activity_id = request.POST.get('activity_id', '')
  297. try:
  298. act = MemberActivityInfo.objects.get(activity_id=activity_id, status=True)
  299. except MemberActivityInfo.DoesNotExist:
  300. return response(MemberActivityStatusCode.ACTIVITY_NOT_FOUND)
  301. return response(data={
  302. 'activity': act.details(user_id),
  303. })
  304. @logit
  305. def activity_signup(request):
  306. brand_id = request.POST.get('brand_id') or settings.KODO_DEFAULT_BRAND_ID
  307. user_id = request.POST.get('user_id', '')
  308. activity_id = request.POST.get('activity_id', '')
  309. avatar = request.POST.get('avatar', '')
  310. name = request.POST.get('name', '')
  311. phone = request.POST.get('phone', '')
  312. try:
  313. act = MemberActivityInfo.objects.get(activity_id=activity_id, status=True)
  314. except MemberActivityInfo.DoesNotExist:
  315. return response(MemberActivityStatusCode.ACTIVITY_NOT_FOUND)
  316. MemberActivitySignupInfo.objects.update_or_create(user_id=user_id, activity_id=activity_id, defaults={
  317. 'title': act.title,
  318. 'name': name,
  319. 'avatar': avatar,
  320. 'phone': phone,
  321. })
  322. MemberActivityContributionInfo.objects.filter(user_id=user_id, activity_id=activity_id).update(user_name=name, user_avatar=avatar)
  323. # TODO: 立即推送模版消息(报名成功,时间,地点)
  324. # TODO: 延迟(活动当天)推送模版消息(时间,地点)
  325. return response(data={
  326. 'activity': act.data(user_id),
  327. })
  328. @logit
  329. def activity_signup_info(request):
  330. brand_id = request.POST.get('brand_id') or settings.KODO_DEFAULT_BRAND_ID
  331. user_id = request.POST.get('user_id', '')
  332. activity_id = request.POST.get('activity_id', '')
  333. try:
  334. signup_info = MemberActivitySignupInfo.objects.get(user_id=user_id, activity_id=activity_id, status=True)
  335. except MemberActivitySignupInfo.DoesNotExist:
  336. return response()
  337. try:
  338. contribution = MemberActivityContributionInfo.objects.get(user_id=user_id, activity_id=activity_id, content_type=0, status=True)
  339. except MemberActivityContributionInfo.DoesNotExist:
  340. return response(MemberActivityContributionStatusCode.ACTIVITY_CONTRIBUTION_NOT_FOUND)
  341. return response(data={
  342. 'signup_info': signup_info.data,
  343. 'contribution': contribution.data
  344. })
  345. @logit
  346. @transaction.atomic
  347. def activity_signin(request):
  348. brand_id = request.POST.get('brand_id') or settings.KODO_DEFAULT_BRAND_ID
  349. user_id = request.POST.get('user_id', '')
  350. activity_id = request.POST.get('activity_id', '')
  351. # 校验用户是否存在
  352. try:
  353. user = UserInfo.objects.select_for_update().get(user_id=user_id)
  354. except UserInfo.DoesNotExist:
  355. return response(UserStatusCode.USER_NOT_FOUND)
  356. try:
  357. act = MemberActivityInfo.objects.get(activity_id=activity_id, status=True)
  358. except MemberActivityInfo.DoesNotExist:
  359. return response(MemberActivityStatusCode.ACTIVITY_NOT_FOUND)
  360. MemberActivitySigninInfo.objects.update_or_create(user_id=user_id, activity_id=activity_id, defaults={
  361. 'title': act.title,
  362. })
  363. user.integral += act.integral
  364. user.save()
  365. # TODO: 立即推送模版消息(感谢您参加活动,获得的积分)
  366. return response(data={
  367. 'activity': act.data(user_id),
  368. })
  369. def get_group_share_info_integral(activity_id, share_user_id, open_gid, group_share_integral, group_share_max_integral):
  370. # 校验该分享人是否已领取该群积分
  371. if open_gid:
  372. has_integral = MemberActivityGroupShareInfo.objects.filter(activity_id=activity_id, share_user_id=share_user_id, open_gid=open_gid, is_integral=True).exists()
  373. else:
  374. has_integral = MemberActivityGroupShareInfo.objects.filter(activity_id=activity_id, share_user_id=share_user_id, is_integral=True).exists()
  375. if has_integral:
  376. return False, 0
  377. # 校验该分享人是否已领取该活动积分上限
  378. total_integral = MemberActivityGroupShareInfo.objects.filter(activity_id=activity_id, share_user_id=share_user_id).aggregate(Sum('integral')).get('integral__sum', 0) or 0
  379. if total_integral + group_share_integral > group_share_max_integral:
  380. return False, 0
  381. return True, group_share_integral
  382. @logit
  383. @transaction.atomic
  384. def activity_group_share(request):
  385. brand_id = request.POST.get('brand_id') or settings.KODO_DEFAULT_BRAND_ID
  386. share_user_id = request.POST.get('share_user_id', '')
  387. click_user_id = request.POST.get('click_user_id', '')
  388. activity_id = request.POST.get('activity_id', '')
  389. iv = request.POST.get('iv', '')
  390. encryptedData = request.POST.get('encryptedData', '')
  391. open_gid = None
  392. if iv and encryptedData:
  393. wxcfg = WECHAT.get('MINIAPP', {})
  394. appid = wxcfg.get('appID')
  395. secret = wxcfg.get('appsecret')
  396. # {
  397. # "openGId": "OPENGID"
  398. # }
  399. shareinfo = get_shareinfo(appid=appid, secret=secret, unid=click_user_id, session_key=None, encryptedData=encryptedData, iv=iv, storage=RedisStorage(r))
  400. open_gid = shareinfo.get('openGId')
  401. if not open_gid:
  402. return response()
  403. try:
  404. user = UserInfo.objects.select_for_update().get(user_id=share_user_id, status=True)
  405. except UserInfo.DoesNotExist:
  406. return response(UserStatusCode.USER_NOT_FOUND)
  407. try:
  408. act = MemberActivityInfo.objects.select_for_update().get(activity_id=activity_id, status=True)
  409. except MemberActivityInfo.DoesNotExist:
  410. return response(MemberActivityStatusCode.ACTIVITY_NOT_FOUND)
  411. isOffline = act.activity_state != 1 or act.final_state == '已结束'
  412. # 判断是否给积分 & 给多少积分
  413. is_integral, integral = get_group_share_info_integral(act.activity_id, share_user_id, open_gid, act.group_share_integral, act.group_share_max_integral)
  414. # 活动未结束,则给用户加积分
  415. if is_integral:
  416. MemberActivityGroupShareInfo.objects.create(**{
  417. 'brand_id': act.brand_id,
  418. 'brand_name': act.brand_name,
  419. 'share_user_id': share_user_id,
  420. 'click_user_id': click_user_id,
  421. 'open_gid': open_gid,
  422. 'activity_id': activity_id,
  423. 'title': act.title,
  424. 'is_integral': is_integral,
  425. 'integral': 0 if isOffline else integral,
  426. })
  427. if not isOffline:
  428. user.integral += integral
  429. user.save()
  430. if isOffline:
  431. return response(400002, 'Activity has been offline', '会员活动已下线')
  432. return response()
  433. @logit
  434. def activity_contribute(request):
  435. brand_id = request.POST.get('brand_id') or settings.KODO_DEFAULT_BRAND_ID
  436. user_id = request.POST.get('user_id', '')
  437. activity_id = request.POST.get('activity_id', '')
  438. content_type = get_query_value(request, 'content_type', val_cast_type='int')
  439. title = request.POST.get('title', '')
  440. content = request.POST.get('content', '')
  441. images = get_query_value(request, 'images', val_cast_type='listjson')
  442. video_url = request.POST.get('video_url', '')
  443. # 校验用户是否存在
  444. try:
  445. UserInfo.objects.get(user_id=user_id)
  446. except UserInfo.DoesNotExist:
  447. return response(UserStatusCode.USER_NOT_FOUND)
  448. try:
  449. signup_info = MemberActivitySignupInfo.objects.get(user_id=user_id, activity_id=activity_id, status=True)
  450. except MemberActivitySignupInfo.DoesNotExist:
  451. signup_info = None
  452. contribution = MemberActivityContributionInfo.objects.create(
  453. brand_id=brand_id,
  454. user_id=user_id,
  455. activity_id=activity_id,
  456. content_type=content_type,
  457. title=title,
  458. content=content,
  459. images=images,
  460. video_url=video_url,
  461. user_name=signup_info.name if signup_info else '',
  462. user_avatar=signup_info.final_avatar if signup_info else '',
  463. )
  464. return response(data={
  465. 'contribution': contribution.data,
  466. })
  467. @logit
  468. def activity_contribute_update(request):
  469. brand_id = request.POST.get('brand_id') or settings.KODO_DEFAULT_BRAND_ID
  470. user_id = request.POST.get('user_id', '')
  471. activity_id = request.POST.get('activity_id', '')
  472. content_type = get_query_value(request, 'content_type', val_cast_type='int')
  473. contribution_id = request.POST.get('contribution_id', '')
  474. title = request.POST.get('title', '')
  475. content = request.POST.get('content', '')
  476. images = get_query_value(request, 'images', val_cast_type='listjson')
  477. video_url = request.POST.get('video_url', '')
  478. # 校验用户是否存在
  479. try:
  480. UserInfo.objects.get(user_id=user_id)
  481. except UserInfo.DoesNotExist:
  482. return response(UserStatusCode.USER_NOT_FOUND)
  483. try:
  484. signup_info = MemberActivitySignupInfo.objects.get(user_id=user_id, activity_id=activity_id, status=True)
  485. except MemberActivitySignupInfo.DoesNotExist:
  486. signup_info = None
  487. contribution, _ = MemberActivityContributionInfo.objects.update_or_create(brand_id=brand_id, user_id=user_id, activity_id=activity_id, contribution_id=contribution_id, defaults={
  488. 'title': title,
  489. 'content': content,
  490. 'images': images,
  491. 'video_url': video_url,
  492. 'user_name': signup_info.name if signup_info else '',
  493. 'user_avatar': signup_info.final_avatar if signup_info else '',
  494. 'audit_status': 0,
  495. })
  496. return response(data={
  497. 'contribution': contribution.data,
  498. })
  499. @logit
  500. def activity_contribute_list(request):
  501. brand_id = request.POST.get('brand_id') or settings.KODO_DEFAULT_BRAND_ID
  502. user_id = request.POST.get('user_id', '')
  503. main_activity_id = request.POST.get('main_activity_id', '')
  504. activity_id = request.POST.get('activity_id', '')
  505. content_type = get_query_value(request, 'content_type', val_cast_type='int')
  506. is_myself = get_query_value(request, 'is_myself', val_cast_type='int')
  507. audit_status = get_query_value(request, 'audit_status', val_cast_type='int')
  508. is_audit_pass = get_query_value(request, 'is_audit_pass', val_cast_type='int')
  509. is_selected = get_query_value(request, 'is_selected', val_cast_type='int')
  510. page = request.POST.get('page', 1)
  511. num = request.POST.get('num', 20)
  512. if main_activity_id:
  513. contributions = MemberActivityContributionInfo.objects.filter(main_activity_id=main_activity_id, status=True)
  514. else:
  515. contributions = MemberActivityContributionInfo.objects.filter(activity_id=activity_id, status=True)
  516. if 'content_type' in request.POST:
  517. contributions = contributions.filter(content_type=content_type)
  518. if 'is_myself' in request.POST:
  519. if is_myself:
  520. contributions = contributions.filter(user_id=user_id)
  521. else:
  522. contributions = contributions.exclude(user_id=user_id)
  523. if 'audit_status' in request.POST:
  524. contributions = contributions.filter(audit_status=audit_status)
  525. if 'is_audit_pass' in request.POST:
  526. if is_audit_pass:
  527. contributions = contributions.filter(audit_status=MemberActivityContributionInfo.AUDIT_PASS)
  528. else:
  529. contributions = contributions.exclude(audit_status=MemberActivityContributionInfo.AUDIT_PASS)
  530. if 'is_selected' in request.POST:
  531. contributions = contributions.filter(is_selected=is_selected)
  532. contributions = contributions.order_by('-pk')
  533. contributions, left = pagination(contributions, page, num)
  534. contributions = [contribution.data for contribution in contributions]
  535. return response(data={
  536. 'contributions': contributions,
  537. 'left': left,
  538. })
  539. @logit
  540. def activity_contribute_detail(request):
  541. brand_id = request.POST.get('brand_id') or settings.KODO_DEFAULT_BRAND_ID
  542. contribution_id = request.POST.get('contribution_id', '')
  543. try:
  544. contribution = MemberActivityContributionInfo.objects.get(contribution_id=contribution_id, status=True)
  545. except MemberActivityContributionInfo.DoesNotExist:
  546. return response(MemberActivityContributionStatusCode.ACTIVITY_CONTRIBUTION_NOT_FOUND)
  547. return response(data=contribution.data)
  548. @logit
  549. def activity_contribute_welfare_unlocking_list(request):
  550. brand_id = request.POST.get('brand_id') or settings.KODO_DEFAULT_BRAND_ID
  551. user_id = request.POST.get('user_id', '')
  552. page = request.POST.get('page', 1)
  553. num = request.POST.get('num', 20)
  554. unlockings = MemberActivityContributionWelfareUnlockingInfo.objects.filter(user_id=user_id, is_handled=False, status=True).order_by('-pk')
  555. unlockings, left = pagination(unlockings, page, num)
  556. unlockings = [unlocking.data for unlocking in unlockings]
  557. return response(data={
  558. 'unlockings': unlockings,
  559. 'left': left,
  560. })
  561. @logit
  562. def activity_contribute_welfare_unlocking_detail(request):
  563. brand_id = request.POST.get('brand_id') or settings.KODO_DEFAULT_BRAND_ID
  564. unlocking_id = request.POST.get('unlocking_id', '')
  565. user_id = request.POST.get('user_id', '')
  566. try:
  567. unlocking = MemberActivityContributionWelfareUnlockingInfo.objects.get(unlocking_id=unlocking_id, status=True)
  568. except MemberActivityContributionWelfareUnlockingInfo.DoesNotExist:
  569. return response(MemberActivityContributionWelfareUnblockingStatusCode.ACTIVITY_CONTRIBUTION_WELFARE_UNBLOCKING_NOT_FOUND)
  570. if user_id != unlocking.user_id:
  571. return response(PermissionStatusCode.PERMISSION_DENIED)
  572. return response(data=unlocking.data)
  573. @logit
  574. @transaction.atomic
  575. def activity_contribute_welfare_unlocking_update(request):
  576. brand_id = request.POST.get('brand_id') or settings.KODO_DEFAULT_BRAND_ID
  577. unlocking_id = request.POST.get('unlocking_id', '')
  578. user_id = request.POST.get('user_id', '')
  579. name = request.POST.get('name', '')
  580. phone = request.POST.get('phone', '')
  581. address = request.POST.get('address', '')
  582. try:
  583. unlocking = MemberActivityContributionWelfareUnlockingInfo.objects.select_for_update().get(unlocking_id=unlocking_id, status=True)
  584. except MemberActivityContributionWelfareUnlockingInfo.DoesNotExist:
  585. return response(MemberActivityContributionWelfareUnblockingStatusCode.ACTIVITY_CONTRIBUTION_WELFARE_UNBLOCKING_NOT_FOUND)
  586. if user_id != unlocking.user_id:
  587. return response(PermissionStatusCode.PERMISSION_DENIED)
  588. if name:
  589. unlocking.name = name
  590. if phone:
  591. unlocking.phone = phone
  592. if address:
  593. unlocking.address = address
  594. unlocking.is_handled = True
  595. unlocking.save()
  596. return response(200, 'Update Member Activity Contribute Welfare Unblocking Success', u'更新会员活动投稿福利解锁成功')
  597. @logit
  598. @transaction.atomic
  599. def activity_contribute_welfare_unlocking_handled(request):
  600. brand_id = request.POST.get('brand_id') or settings.KODO_DEFAULT_BRAND_ID
  601. unlocking_id = request.POST.get('unlocking_id', '')
  602. user_id = request.POST.get('user_id', '')
  603. try:
  604. unlocking = MemberActivityContributionWelfareUnlockingInfo.objects.select_for_update().get(unlocking_id=unlocking_id, status=True)
  605. except MemberActivityContributionWelfareUnlockingInfo.DoesNotExist:
  606. return response(MemberActivityContributionWelfareUnblockingStatusCode.ACTIVITY_CONTRIBUTION_WELFARE_UNBLOCKING_NOT_FOUND)
  607. if unlocking.is_handled:
  608. return response(MemberActivityContributionWelfareUnblockingStatusCode.ACTIVITY_CONTRIBUTION_WELFARE_UNBLOCKING_HAS_HANDLED)
  609. if user_id != unlocking.user_id:
  610. return response(PermissionStatusCode.PERMISSION_DENIED)
  611. unlocking.is_handled = True
  612. unlocking.save()
  613. if unlocking.welfare_type == MemberActivityContributionWelfareUnlockingInfo.WELFARE_INTEGRAL:
  614. try:
  615. user = UserInfo.objects.select_for_update().get(user_id=user_id, status=True)
  616. except UserInfo.DoesNotExist:
  617. return response(UserStatusCode.USER_NOT_FOUND)
  618. user.integral += unlocking.welfare_value
  619. user.save()
  620. UserIntegralIncomeExpensesInfo.objects.create(
  621. brand_id=brand_id,
  622. user_id=user_id,
  623. integral_from=UserIntegralIncomeExpensesInfo.MEMBER_ACTIVITY_CONTRIBUTION_WELFARE,
  624. integral=unlocking.welfare_value,
  625. final_integral=user.integral,
  626. remark=unlocking.id,
  627. )
  628. return response(200, 'Update Member Activity Contribute Welfare Unblocking Success', u'处理会员活动投稿福利解锁成功')