拍爱

lensman_views.py 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415
  1. # -*- coding: utf-8 -*-
  2. from __future__ import division
  3. from curtail_uuid import CurtailUUID
  4. from django.contrib.auth.hashers import check_password
  5. from django.db import transaction
  6. from isoweek import Week
  7. from logit import logit
  8. from paginator import pagination
  9. from TimeConvert import TimeConvert as tc
  10. from account.models import LensmanInfo, UserIncomeExpensesInfo, UserInfo
  11. from group.models import GroupInfo, GroupPhotoInfo, GroupPhotoOrderInfo
  12. from message.models import SystemMessageInfo
  13. from pay.models import OrderInfo
  14. from photo.models import PhotosInfo
  15. from utils.error.errno_utils import LensmanStatusCode, OrderStatusCode, UserStatusCode
  16. from utils.error.response_utils import response
  17. from utils.message_utils import system_messages
  18. from utils.redis.connect import r
  19. from utils.redis.rbrief import set_brief_info
  20. from utils.redis.rgroup import set_group_info, set_group_info_by_id
  21. from utils.redis.rkeys import GROUP_LAST_PHOTO_PK, TODAY_INCOME, TODAY_UPLOAD_PHOTO_AMOUNT, WEEK_INCOME, WEEK_SOLD
  22. from utils.redis.rlock import upload_lock
  23. from utils.redis.rorder import set_lensman_order_record
  24. from utils.redis.rprice import get_lensman_price_fixed, set_lensman_price_fixed
  25. from utils.redis.rprofile import set_profile_info
  26. from utils.storage_utils import file_save
  27. @logit
  28. def lensman_submit_api(request):
  29. """ 摄影师信息提交 """
  30. unionid = request.POST.get('unionid', '')
  31. openid = request.POST.get('openid', '')
  32. phone = request.POST.get('phone', '')
  33. if LensmanInfo.objects.filter(phone=phone).exclude(unionid=unionid).exists():
  34. return response(LensmanStatusCode.LENSMAN_PHONE_ALREADY_EXISTS)
  35. fields = {
  36. 'name': request.POST.get('name', ''),
  37. 'sex': int(request.POST.get('sex', 1)),
  38. 'phone': phone,
  39. 'location': request.POST.get('location', ''),
  40. 'user_status': LensmanInfo.UNVERIFIED,
  41. }
  42. lensman, created = LensmanInfo.objects.get_or_create(unionid=unionid, defaults=fields)
  43. # 状态为 UNVERIFIED 的允许修改, 其他需要登录摄影师 APP 进行信息的修改
  44. if lensman.user_status not in [LensmanInfo.UNVERIFIED, LensmanInfo.REFUSED]:
  45. return response(LensmanStatusCode.LENSMAN_ALREADY_NOT_UNVERIFIED)
  46. if not created:
  47. for key, value in fields.iteritems():
  48. setattr(lensman, key, value)
  49. lensman.save()
  50. return response(200, 'Submit Success', u'提交成功', {})
  51. @logit
  52. def lensman_login_api(request):
  53. """ 摄影师登录 """
  54. username = request.POST.get('username', '')
  55. password = request.POST.get('password', '')
  56. try:
  57. lensman = LensmanInfo.objects.get(username=username, status=True)
  58. except LensmanInfo.DoesNotExist:
  59. return response(LensmanStatusCode.LENSMAN_NOT_FOUND)
  60. if not check_password(password, lensman.encryption):
  61. return response(LensmanStatusCode.LENSMAN_PASSWORD_ERROR)
  62. try:
  63. user = UserInfo.objects.get(user_id=lensman.lensman_id, status=True)
  64. except UserInfo.DoesNotExist:
  65. return response(LensmanStatusCode.LENSMAN_NOT_FOUND)
  66. return response(200, 'Login Success', u'登录成功', user.data)
  67. @logit
  68. def lensman_wx_authorize_api(request):
  69. unionid = request.POST.get('unionid', '')
  70. openid = request.POST.get('openid', '')
  71. sex = request.POST.get('sex', 0)
  72. nickname = request.POST.get('nickname', '') or request.POST.get('screen_name', '')
  73. avatar = request.POST.get('headimgurl', '') or request.POST.get('profile_image_url', '')
  74. country = request.POST.get('country', '')
  75. province = request.POST.get('province', '')
  76. city = request.POST.get('city', '')
  77. try:
  78. user = UserInfo.objects.get(unionid=unionid, islensman=True, status=True)
  79. except UserInfo.DoesNotExist:
  80. return response(LensmanStatusCode.LENSMAN_NOT_FOUND)
  81. if user.user_status != UserInfo.ACTIVATED:
  82. return response(LensmanStatusCode.LENSMAN_NOT_ACTIVATED)
  83. user.openid = openid
  84. user.sex = sex
  85. user.nickname = nickname
  86. user.avatar = avatar
  87. user.country = country
  88. user.province = province
  89. user.city = city
  90. user.save()
  91. set_profile_info(user)
  92. return response(200, 'Lensman Login Success', u'摄影师登录成功', user.data)
  93. @logit
  94. def lensman_price_fix_api(request):
  95. lensman_id = request.POST.get('user_id', '')
  96. nomark = request.POST.get('nomark', 299)
  97. origin = request.POST.get('origin', 999)
  98. # 用户校验
  99. try:
  100. lensman = LensmanInfo.objects.get(lensman_id=lensman_id, status=True)
  101. except LensmanInfo.DoesNotExist:
  102. return response(UserStatusCode.USER_NOT_FOUND)
  103. if 'nomark' in request.POST:
  104. lensman.nomark = nomark
  105. if 'origin' in request.POST:
  106. lensman.origin = origin
  107. lensman.save()
  108. set_lensman_price_fixed(lensman_id)
  109. return response(200, 'Lensman Price Fix Success', u'摄影师定价修改成功')
  110. @logit
  111. def lensman_photo_upload_api(request):
  112. """ 摄影师照片上传 """
  113. user_id = lensman_id = request.POST.get('user_id', '')
  114. nickname = request.POST.get('nickname', '')
  115. group_id = request.POST.get('group_id', '')
  116. session_id = request.POST.get('session_id', '')
  117. photo_id = request.POST.get('photo_id', '')
  118. photo = request.FILES.get('photo', '')
  119. # 用户校验
  120. try:
  121. user = UserInfo.objects.get(user_id=user_id, status=True)
  122. except UserInfo.DoesNotExist:
  123. return response(UserStatusCode.USER_NOT_FOUND)
  124. if not group_id:
  125. # 判断通过 session_id 创建的群组是否存在,如果不存在,则直接创建
  126. group, group_created = GroupInfo.objects.get_or_create(session_id=session_id, group_from=GroupInfo.SESSION_GROUP, defaults={
  127. 'group_id': CurtailUUID.uuid(GroupInfo, 'group_id'),
  128. 'admin_id': user_id,
  129. 'group_name': user.final_nickname,
  130. 'group_default_avatar': 0,
  131. })
  132. # Redis 群组数据缓存
  133. if group_created:
  134. set_group_info(group)
  135. group_id = group.group_id
  136. if photo and upload_lock(group_id, user_id, photo):
  137. # 写 PhotosInfo 表
  138. photo_info = file_save(photo, prefix='photo', ext='jpeg', watermark=True, thumbnail=True)
  139. photo, created = PhotosInfo.objects.get_or_create(
  140. lensman_id=lensman_id,
  141. session_id=session_id,
  142. photo_id=photo_id,
  143. )
  144. photo.m_photo_path = photo_info.photo_path
  145. photo.p_photo_path = photo_info.photo_watermark_path
  146. photo.save()
  147. # 获取摄影师定价
  148. price_info = get_lensman_price_fixed(user_id)
  149. # 写 GroupPhotoInfo 表
  150. group_photo, created = GroupPhotoInfo.objects.get_or_create(
  151. group_id=group_id,
  152. user_id=user_id,
  153. photo_md5=photo_info.photo_md5,
  154. defaults={
  155. 'nickname': user.final_nickname,
  156. 'avatar': user.avatar,
  157. 'photo_path': photo_info.photo_path,
  158. 'photo_w': photo_info.photo_w,
  159. 'photo_h': photo_info.photo_h,
  160. 'photo_thumbnail_path': photo_info.photo_thumbnail_path,
  161. 'photo_thumbnail_w': photo_info.photo_thumbnail_w,
  162. 'photo_thumbnail_h': photo_info.photo_thumbnail_h,
  163. 'photo_thumbnail2_path': photo_info.photo_thumbnail2_path,
  164. 'photo_thumbnail2_w': photo_info.photo_thumbnail2_w,
  165. 'photo_thumbnail2_h': photo_info.photo_thumbnail2_h,
  166. 'photo_from': GroupPhotoInfo.SESSION_GROUP,
  167. 'session_id': photo.session_id,
  168. 'lensman_id': photo.lensman_id,
  169. 'lensman_photo_id': photo.photo_id,
  170. 'nomark': price_info.get('nomark', 999),
  171. 'origin': price_info.get('origin', 999),
  172. }
  173. )
  174. if created:
  175. # 设置群组最后一张照片PK
  176. r.set(GROUP_LAST_PHOTO_PK % group_id, group_photo.pk)
  177. # 更新今日上传照片数量
  178. r.incr(TODAY_UPLOAD_PHOTO_AMOUNT % (user_id, tc.local_string(format='%Y%m%d')))
  179. # Redis 群组数据缓存
  180. set_group_info_by_id(group_id)
  181. return response(200, 'Lensman Upload Photo Success', u'摄影师照片上传成功', {
  182. 'group_id': group_id,
  183. })
  184. @logit
  185. @transaction.atomic
  186. def lensman_origin_photo_upload_api(request):
  187. order_id = request.POST.get('order_id', '')
  188. user_id = lensman_id = request.POST.get('user_id', '')
  189. session_id = request.POST.get('session_id', '')
  190. photo_id = request.POST.get('photo_id', '')
  191. deleted = int(request.POST.get('deleted', 0))
  192. photo = request.FILES.get('photo', '')
  193. try:
  194. order = OrderInfo.objects.select_for_update().get(order_id=order_id, pay_status=OrderInfo.PAID)
  195. except OrderInfo.DoesNotExist:
  196. return response(OrderStatusCode.WX_ORDER_NOT_FOUND)
  197. # 原图已删除, 处理退款逻辑
  198. if deleted and order.photo_status == OrderInfo.WANTED:
  199. # 用户余额增加
  200. try:
  201. from_user = UserInfo.objects.select_for_update().get(user_id=order.from_uid)
  202. except UserInfo.DoesNotExist:
  203. pass
  204. if from_user:
  205. # 余额增加
  206. from_user.balance += order.total_fee
  207. from_user.save()
  208. # 余额记录
  209. UserIncomeExpensesInfo.objects.create(
  210. user_id=order.from_uid,
  211. photo_id=order.photo_id,
  212. type=UserIncomeExpensesInfo.INCOME,
  213. amount=order.total_fee,
  214. balance=from_user.balance,
  215. freeze_income_amount=0,
  216. freeze_income_balance=from_user.freeze_income_balance,
  217. remark=u'高清图购买退款',
  218. )
  219. # 摄影师余额减少
  220. try:
  221. to_user = UserInfo.objects.select_for_update().get(user_id=order.to_uid)
  222. except UserInfo.DoesNotExist:
  223. pass
  224. if to_user:
  225. # 余额减少
  226. to_user.freeze_income_balance -= order.total_fee
  227. to_user.save()
  228. # 余额记录
  229. UserIncomeExpensesInfo.objects.create(
  230. user_id=order.to_uid,
  231. photo_id=order.photo_id,
  232. type=UserIncomeExpensesInfo.EXPENSE,
  233. amount=order.total_fee,
  234. balance=to_user.balance,
  235. freeze_income_amount=0,
  236. freeze_income_balance=to_user.freeze_income_balance,
  237. remark=u'高清图购买退款',
  238. )
  239. # 更新订单状态
  240. order.photo_status = OrderInfo.DELETED
  241. order.reback_status = True
  242. order.reback_at = tc.utc_datetime()
  243. order.save()
  244. if photo and upload_lock(order_id, user_id, photo):
  245. # 写 PhotosInfo 表
  246. photo_info = file_save(photo, prefix='photo', ext='jpeg')
  247. PhotosInfo.objects.filter(
  248. lensman_id=lensman_id,
  249. session_id=session_id,
  250. photo_id=photo_id,
  251. ).update(
  252. r_photo_path=photo_info.photo_path
  253. )
  254. porder, created = GroupPhotoOrderInfo.objects.select_for_update().get_or_create(
  255. group_id=order.group_id,
  256. session_id=session_id,
  257. user_id=order.from_uid,
  258. photo_id=order.photo_id,
  259. lensman_photo_id=photo_id,
  260. )
  261. porder.r_photo_path = photo_info.photo_path
  262. porder.save()
  263. set_lensman_order_record(porder)
  264. # 摄影师余额解冻
  265. try:
  266. to_user = UserInfo.objects.select_for_update().get(user_id=order.to_uid)
  267. except UserInfo.DoesNotExist:
  268. pass
  269. if to_user:
  270. # 余额解冻
  271. to_user.balance += order.total_fee
  272. to_user.freeze_income_balance -= order.total_fee
  273. to_user.save()
  274. # Redis 数值更新
  275. set_brief_info(order.to_uid, order.photo_type, order.total_fee, dt=order.created_at)
  276. # 余额记录
  277. UserIncomeExpensesInfo.objects.create(
  278. user_id=order.to_uid,
  279. photo_id=order.photo_id,
  280. type=UserIncomeExpensesInfo.UNFREEZE,
  281. amount=order.total_fee,
  282. balance=to_user.balance,
  283. freeze_income_amount=order.total_fee,
  284. freeze_income_balance=to_user.freeze_income_balance,
  285. remark=u'高清图购买退款',
  286. )
  287. order.photo_status = OrderInfo.FETCHED
  288. order.save()
  289. return response(200, 'Lensman Upload Origin Photo Success', u'摄影师照片高清图上传成功')
  290. @logit
  291. def lensman_brief_api(request):
  292. user_id = request.POST.get('user_id', '')
  293. ymd = tc.local_string(format='%Y%m%d')
  294. week = Week.thisweek().isoformat()
  295. # 周收入
  296. origin_week_income = int(r.get(WEEK_INCOME % (user_id, OrderInfo.ORIGIN, week)) or 0)
  297. # 日收入
  298. nomark_today_income = int(r.get(TODAY_INCOME % (user_id, OrderInfo.NOMARK, ymd)) or 0)
  299. # 日上传
  300. today_upload = int(r.get(TODAY_UPLOAD_PHOTO_AMOUNT % (user_id, ymd)) or 0)
  301. # 周售出
  302. week_sold = int(r.get(WEEK_SOLD % (user_id, OrderInfo.ORIGIN, ymd)) or 0)
  303. # 摄影师端系统消息
  304. systems = system_messages(user_id, SystemMessageInfo.PAIAI_LENSMAN)
  305. systems, left = pagination(systems, 1, 10)
  306. systems = [msg.msg_info(user_id) for msg in systems]
  307. # 照片购买记录
  308. orders = OrderInfo.objects.filter(to_uid=user_id, pay_status=OrderInfo.PAID, status=True).order_by('-pk')
  309. orders, left = pagination(orders, 1, 10)
  310. orders = [order.data(user_id) for order in orders]
  311. # 获取摄影师定价
  312. price_fixed = get_lensman_price_fixed(user_id)
  313. return response(200, 'Get Lensman Brief Success', u'获取摄影师简报成功', {
  314. 'origin_week_income': origin_week_income,
  315. 'nomark_today_income': nomark_today_income,
  316. 'today_upload': today_upload,
  317. 'week_sold': week_sold,
  318. 'messages': {
  319. 'system': systems,
  320. 'orders': orders,
  321. },
  322. 'price_fixed': price_fixed,
  323. })
  324. @logit
  325. def lensman_origin_wanted_api(request):
  326. user_id = request.POST.get('user_id', '')
  327. orders = OrderInfo.objects.filter(
  328. to_uid=user_id,
  329. photo_type=OrderInfo.ORIGIN,
  330. photo_status=OrderInfo.WANTED,
  331. pay_status=OrderInfo.PAID,
  332. status=True
  333. ).order_by('pk')
  334. wanted = [order.lensdata for order in orders]
  335. return response(200, 'Get Origin Wanted Success', u'获取需要上传原图成功', {
  336. 'wanted': wanted
  337. })