拍爱

models.py 20KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425
  1. # -*- coding: utf-8 -*-
  2. from django.db import models
  3. from django.utils.translation import ugettext_lazy as _
  4. from models_ext import BaseModelMixin
  5. from shortuuidfield import ShortUUIDField
  6. from TimeConvert import TimeConvert as tc
  7. from pai2.basemodels import LensmanTypeMixin
  8. from photo.models import PhotosInfo
  9. from utils.qiniucdn import qiniu_file_url
  10. from utils.redis.rgroup import get_group_photo_thumbup_flag
  11. from utils.redis.rorder import get_lensman_order_record
  12. from utils.time_utils import origin_expired_stamps
  13. from utils.url_utils import share_url
  14. class GroupInfo(BaseModelMixin):
  15. APP_GROUP = 0
  16. SESSION_GROUP = 1
  17. TOURGUIDE_GROUP = 10
  18. GROUP_FROM = (
  19. (APP_GROUP, u'APP 建群'),
  20. (SESSION_GROUP, u'SESSION 建群'),
  21. (TOURGUIDE_GROUP, u'导游建群'),
  22. )
  23. group_id = models.CharField(_(u'group_id'), max_length=32, blank=True, null=True, help_text=u'群组唯一标识', db_index=True, unique=True)
  24. admin_id = models.CharField(_(u'admin_id'), max_length=32, blank=True, null=True, help_text=u'用户唯一标识', db_index=True)
  25. group_name = models.CharField(_(u'group_name'), max_length=255, blank=True, null=True, help_text=u'群组名称')
  26. group_default_avatar = models.IntegerField(_(u'group_default_avatar'), default=0, help_text=u'群组默认头像,0 - 255,水果头像')
  27. group_avatar = models.CharField(_(u'group_avatar'), max_length=255, blank=True, null=True, help_text=u'群组头像')
  28. group_desc = models.TextField(_(u'group_desc'), blank=True, null=True, help_text=u'群组描述')
  29. group_from = models.IntegerField(_(u'group_from'), choices=GROUP_FROM, default=APP_GROUP, help_text=u'群组来源')
  30. session_id = models.CharField(_(u'session_id'), max_length=32, blank=True, null=True, help_text=u'照片组唯一标识', db_index=True)
  31. group_lock = models.BooleanField(_(u'group_lock'), default=False, help_text=u'群组锁定')
  32. group_initio = models.BooleanField(_(u'group_initio'), default=False, help_text=u'群组查看照片从头开始')
  33. # 旅行团
  34. name = models.CharField(_(u'name'), max_length=255, blank=True, null=True, help_text=u'导游姓名')
  35. phone = models.CharField(_(u'phone'), max_length=16, blank=True, null=True, help_text=u'导游电话')
  36. started_at = models.DateTimeField(_(u'started_at'), blank=True, null=True, help_text=_(u'旅游团开始时间'))
  37. ended_at = models.DateTimeField(_(u'ended_at'), blank=True, null=True, help_text=_(u'旅游团结束时间'))
  38. total_persons = models.IntegerField(_(u'total_persons'), default=1, help_text=u'旅游团总人数')
  39. group_closed = models.BooleanField(_(u'group_closed'), default=False, help_text=u'旅游团关闭')
  40. gather_at = models.DateTimeField(_(u'gather_at'), blank=True, null=True, help_text=_(u'旅游团集合时间'))
  41. gather_lon = models.FloatField(_(u'gather_lon'), blank=True, null=True, help_text=_(u'旅游团集合经度'))
  42. gather_lat = models.FloatField(_(u'gather_lat'), blank=True, null=True, help_text=_(u'旅游团集合纬度'))
  43. gather_location = models.CharField(_(u'gather_location'), max_length=255, blank=True, null=True, help_text=u'旅游团集合地点')
  44. gather_screenshot = models.CharField(_(u'gather_screenshot'), max_length=32, blank=True, null=True, help_text=u'旅游团集合地点截图')
  45. attentions_path = models.CharField(_(u'attentions_path'), max_length=32, blank=True, null=True, help_text=u'注意事项照片存放路径')
  46. schedules_path = models.CharField(_(u'schedules_path'), max_length=32, blank=True, null=True, help_text=u'行程安排照片存放路径')
  47. class Meta:
  48. verbose_name = _(u'groupinfo')
  49. verbose_name_plural = _(u'groupinfo')
  50. unique_together = (('session_id', 'group_from'),)
  51. def __unicode__(self):
  52. return unicode(self.group_id)
  53. @property
  54. def group_avatar_url(self):
  55. return qiniu_file_url(self.group_avatar, bucket='photo')
  56. @property
  57. def group_attentions_url(self):
  58. return qiniu_file_url(self.attentions_path, bucket='photo')
  59. @property
  60. def group_schedules_url(self):
  61. return qiniu_file_url(self.schedules_path, bucket='photo')
  62. @property
  63. def gather_screenshot_url(self):
  64. return qiniu_file_url(self.gather_screenshot, bucket='photo')
  65. @property
  66. def group_photo_num(self):
  67. return GroupPhotoInfo.objects.filter(group_id=self.group_id, status=True).count()
  68. @property
  69. def data(self):
  70. return {
  71. 'group_id': self.group_id,
  72. 'admin_id': self.admin_id,
  73. 'group_name': self.group_name,
  74. 'group_default_avatar': self.group_default_avatar,
  75. 'group_avatar': self.group_avatar_url,
  76. 'group_desc': self.group_desc,
  77. 'group_from': self.group_from,
  78. 'group_lock': self.group_lock,
  79. 'group_initio': self.group_initio,
  80. 'group_photo_num': self.group_photo_num,
  81. 'name': self.name,
  82. 'phone': self.phone,
  83. 'started_at': tc.remove_microsecond(self.started_at),
  84. 'ended_at': tc.remove_microsecond(self.ended_at),
  85. 'total_persons': self.total_persons,
  86. 'gather_at': tc.remove_microsecond(self.gather_at),
  87. 'gather_lon': self.gather_lon,
  88. 'gather_lat': self.gather_lat,
  89. 'gather_location': self.gather_location,
  90. 'gather_screenshot': self.gather_screenshot_url,
  91. 'created_at': tc.remove_microsecond(self.created_at),
  92. 'banners': {
  93. 'attentions': self.group_attentions_url,
  94. 'schedules': self.group_schedules_url,
  95. },
  96. }
  97. def users(self, admin=True, user_id=None):
  98. all_users = GroupUserInfo.objects.filter(group_id=self.group_id, user_status__in=[GroupUserInfo.APPLYING, GroupUserInfo.PASSED], status=True)
  99. passed_users = all_users.filter(user_status=GroupUserInfo.PASSED)
  100. passed_count = passed_users.count()
  101. passed = [passed.user_info for passed in passed_users]
  102. if admin and self.admin_id != user_id:
  103. return {
  104. 'passed_count': passed_count,
  105. 'passed': passed,
  106. }
  107. applying_users = all_users.filter(user_status=GroupUserInfo.APPLYING)
  108. applying_count = applying_users.count()
  109. applying = [applying.user_info for applying in applying_users]
  110. return {
  111. 'applying_count': applying_count,
  112. 'passed_count': passed_count,
  113. 'applying': applying,
  114. 'passed': passed,
  115. }
  116. class GroupUserInfo(BaseModelMixin):
  117. APPLYING = 0
  118. PASSED = 1
  119. REFUSED = 2
  120. DELETED = 3
  121. QUIT = 4
  122. USER_STATUS = (
  123. (APPLYING, u'申请中'),
  124. (PASSED, u'已通过'),
  125. (REFUSED, u'已拒绝'),
  126. (DELETED, u'已删除'),
  127. (QUIT, u'已退出'),
  128. )
  129. group_id = models.CharField(_(u'group_id'), max_length=32, blank=True, null=True, help_text=u'群组唯一标识', db_index=True)
  130. user_id = models.CharField(_(u'user_id'), max_length=32, blank=True, null=True, help_text=u'用户唯一标识', db_index=True)
  131. current_id = models.IntegerField(_(u'current_id'), default=-1, help_text=u'当前群组照片ID')
  132. nickname = models.CharField(_(u'nickname'), max_length=255, blank=True, null=True, help_text=u'用户群组昵称')
  133. avatar = models.CharField(_(u'avatar'), max_length=255, blank=True, null=True, help_text=u'用户头像')
  134. admin = models.BooleanField(_(u'admin'), default=False, help_text=u'群组管理员')
  135. user_status = models.IntegerField(_(u'user_status'), choices=USER_STATUS, default=APPLYING)
  136. passed_at = models.DateTimeField(_(u'passed_at'), blank=True, null=True, help_text=_(u'通过时间'))
  137. refused_at = models.DateTimeField(_(u'refused_at'), blank=True, null=True, help_text=_(u'拒绝时间'))
  138. deleted_at = models.DateTimeField(_(u'deleted_at'), blank=True, null=True, help_text=_(u'删除时间'))
  139. quit_at = models.DateTimeField(_(u'quit_at'), blank=True, null=True, help_text=_(u'退出时间'))
  140. # 旅行团相关
  141. subadmin = models.BooleanField(_(u'subadmin'), default=False, help_text=u'副群组管理员')
  142. name = models.CharField(_(u'name'), max_length=255, blank=True, null=True, help_text=u'用户姓名')
  143. phone = models.CharField(_(u'phone'), max_length=16, blank=True, null=True, help_text=u'用户电话')
  144. relative_persons = models.IntegerField(_(u'relative_persons'), default=1, help_text=u'关联人数')
  145. authority = models.BooleanField(_(u'authority'), default=True, help_text=u'是否有定位权限')
  146. remark = models.CharField(_(u'remark'), max_length=255, blank=True, null=True, help_text=u'备注')
  147. admin_status = models.BooleanField(_(u'admin_status'), default=True, help_text=_(u'群组管理员状态'))
  148. class Meta:
  149. verbose_name = _(u'groupuserinfo')
  150. verbose_name_plural = _(u'groupuserinfo')
  151. unique_together = (('group_id', 'user_id'),)
  152. def __unicode__(self):
  153. return unicode(self.pk)
  154. @property
  155. def user_info(self):
  156. return {
  157. 'user_id': self.user_id,
  158. 'nickname': self.nickname,
  159. 'avatar': self.avatar,
  160. 'admin': self.admin,
  161. 'subadmin': self.subadmin,
  162. 'name': self.name,
  163. 'phone': self.phone,
  164. 'relative_persons': self.relative_persons,
  165. 'authority': self.authority,
  166. 'remark': self.remark,
  167. }
  168. @property
  169. def admin_info(self):
  170. return {
  171. 'user_id': self.user_id,
  172. 'nickname': self.nickname,
  173. 'avatar': self.avatar,
  174. 'admin': self.admin,
  175. 'subadmin': self.subadmin,
  176. 'name': self.name,
  177. 'phone': self.phone,
  178. 'relative_persons': self.relative_persons,
  179. 'authority': self.authority,
  180. 'remark': self.remark,
  181. 'status': self.admin_status,
  182. }
  183. class GroupPhotoInfo(BaseModelMixin, LensmanTypeMixin):
  184. APP_GROUP = 0
  185. SESSION_GROUP = 1
  186. PHOTO_FROM = (
  187. (APP_GROUP, u'APP 建群'),
  188. (SESSION_GROUP, u'SESSION 建群'),
  189. )
  190. photo_id = ShortUUIDField(_(u'photo_id'), max_length=32, help_text=u'照片唯一标识', db_index=True)
  191. group_id = models.CharField(_(u'group_id'), max_length=32, blank=True, null=True, help_text=u'群组唯一标识', db_index=True)
  192. user_id = models.CharField(_(u'user_id'), max_length=32, blank=True, null=True, help_text=u'用户唯一标识', db_index=True)
  193. nickname = models.CharField(_(u'nickname'), max_length=255, blank=True, null=True, help_text=u'用户群组昵称')
  194. avatar = models.CharField(_(u'avatar'), max_length=255, blank=True, null=True, help_text=u'用户头像')
  195. photo_md5 = models.CharField(_(u'photo_md5'), max_length=32, blank=True, null=True, help_text=u'照片 MD5', db_index=True)
  196. photo_path = models.CharField(_(u'photo_path'), max_length=32, blank=True, null=True, help_text=u'照片存放路径')
  197. has_watermark = models.BooleanField(_(u'has_watermark'), default=False, help_text=_(u'是否有水印'), db_index=True)
  198. photo_w = models.IntegerField(_(u'photo_w'), default=0, help_text=u'照片宽度')
  199. photo_h = models.IntegerField(_(u'photo_h'), default=0, help_text=u'照片高度')
  200. # 双列: 540, 40-50K
  201. photo_thumbnail_path = models.CharField(_(u'photo_thumbnail_path'), max_length=32, blank=True, null=True, help_text=u'照片缩略图存放路径')
  202. photo_thumbnail_w = models.IntegerField(_(u'photo_thumbnail_w'), default=0, help_text=u'照片缩略图宽度')
  203. photo_thumbnail_h = models.IntegerField(_(u'photo_thumbnail_h'), default=0, help_text=u'照片缩略图高度')
  204. # 单列: 1080, xx-100K
  205. photo_thumbnail2_path = models.CharField(_(u'photo_thumbnail2_path'), max_length=32, blank=True, null=True, help_text=u'照片缩略图存放路径')
  206. photo_thumbnail2_w = models.IntegerField(_(u'photo_thumbnail2_w'), default=0, help_text=u'照片缩略图宽度')
  207. photo_thumbnail2_h = models.IntegerField(_(u'photo_thumbnail2_h'), default=0, help_text=u'照片缩略图高度')
  208. comment_num = models.IntegerField(_(u'comment_num'), default=0, help_text=u'照片评论数量')
  209. thumbup_num = models.IntegerField(_(u'thumbup_num'), default=0, help_text=u'照片点赞数量')
  210. photo_from = models.IntegerField(_(u'photo_from'), choices=PHOTO_FROM, default=APP_GROUP, help_text=u'照片来源')
  211. session_id = models.CharField(_(u'session_id'), max_length=32, blank=True, null=True, help_text=u'照片组唯一标识,同 PhotosInfo 表', db_index=True)
  212. lensman_id = models.CharField(_(u'lensman_id'), max_length=32, blank=True, null=True, help_text=u'摄影师唯一标识,同 PhotosInfo 表', db_index=True)
  213. lensman_photo_id = models.CharField(_(u'lensman_photo_id'), max_length=32, blank=True, null=True, help_text=u'摄影师照片唯一标识,同 PhotosInfo 表', db_index=True)
  214. nomark = models.IntegerField(_(u'nomark'), default=299, help_text=u'摄影师照片无水印价格(分)')
  215. origin = models.IntegerField(_(u'origin'), default=999, help_text=u'摄影师照片高清图价格(分)')
  216. class Meta:
  217. verbose_name = _(u'groupphotoinfo')
  218. verbose_name_plural = _(u'groupphotoinfo')
  219. unique_together = (('group_id', 'user_id', 'photo_md5'),)
  220. def __unicode__(self):
  221. return unicode(self.pk)
  222. @property
  223. def photo_url(self):
  224. return qiniu_file_url(self.photo_path, bucket='watermark' if self.has_watermark else 'photo')
  225. @property
  226. def photo_thumbnail_url(self):
  227. return qiniu_file_url(self.photo_thumbnail_path, bucket='thumbnail')
  228. @property
  229. def photo_thumbnail2_url(self):
  230. return qiniu_file_url(self.photo_thumbnail2_path, bucket='thumbnail2')
  231. @property
  232. def photo_share_url(self):
  233. return share_url(self.photo_id)
  234. @property
  235. def photo_data(self):
  236. return {
  237. 'photo_id': self.photo_id,
  238. 'comment_num': self.comment_num,
  239. 'thumbup_num': self.thumbup_num,
  240. }
  241. def photo_info(self, user_id):
  242. try:
  243. group = GroupInfo.objects.get(group_id=self.group_id)
  244. except GroupInfo.DoesNotExist:
  245. group = None
  246. porder = get_lensman_order_record(self.photo_id, user_id) if self.photo_from == GroupPhotoInfo.SESSION_GROUP else {}
  247. created_at = self.created_at.replace(microsecond=0)
  248. return {
  249. 'group_id': group and group.group_id,
  250. 'group_name': group and group.group_name,
  251. 'group_default_avatar': group and group.group_default_avatar,
  252. 'group_avatar': group and group.group_avatar_url,
  253. 'group_from': group and group.group_from,
  254. 'photo_id': self.photo_id,
  255. 'photo_url': self.photo_url,
  256. 'photo_w': self.photo_w,
  257. 'photo_h': self.photo_h,
  258. 'photo_thumbnail_url': self.photo_thumbnail_url,
  259. 'photo_thumbnail_w': self.photo_thumbnail_w,
  260. 'photo_thumbnail_h': self.photo_thumbnail_h,
  261. 'photo_thumbnail2_url': self.photo_thumbnail2_url,
  262. 'photo_thumbnail2_w': self.photo_thumbnail2_w,
  263. 'photo_thumbnail2_h': self.photo_thumbnail2_h,
  264. 'photo_share_url': self.photo_share_url,
  265. 'user_id': self.user_id,
  266. 'nickname': self.nickname,
  267. 'avatar': self.avatar,
  268. 'comment_num': self.comment_num,
  269. 'thumbup': get_group_photo_thumbup_flag(self.pk, user_id),
  270. 'thumbup_num': self.thumbup_num,
  271. 'photo_from': self.photo_from,
  272. 'session_id': self.session_id,
  273. 'nomark': self.nomark,
  274. 'origin': self.origin,
  275. 'porder': porder,
  276. 'created_at': created_at,
  277. 'origin_expired_stamps': origin_expired_stamps(created_at, self.user_id),
  278. 'display_payment_btn': self.photo_from == self.SESSION_GROUP and self.lensman_type not in [self.OUTTAKE],
  279. }
  280. class GroupPhotoOrderInfo(BaseModelMixin):
  281. group_id = models.CharField(_(u'group_id'), max_length=32, blank=True, null=True, help_text=u'群组唯一标识', db_index=True)
  282. session_id = models.CharField(_(u'session_id'), max_length=32, blank=True, null=True, help_text=u'照片组唯一标识,同 PhotosInfo 表', db_index=True)
  283. user_id = models.CharField(_(u'user_id'), max_length=32, blank=True, null=True, help_text=u'用户唯一标识', db_index=True)
  284. photo_id = models.CharField(_(u'photo_id'), max_length=32, blank=True, null=True, help_text=u'照片唯一标识', db_index=True)
  285. lensman_photo_id = models.CharField(_(u'lensman_photo_id'), max_length=32, blank=True, null=True, help_text=u'摄影师照片唯一标识,同 PhotosInfo 表', db_index=True)
  286. m_photo_path = models.CharField(_(u'm_photo_path'), max_length=32, blank=True, null=True, help_text=u'照片存放路径,Box上传,无水印')
  287. l_photo_path = models.CharField(_(u'l_photo_path'), max_length=32, blank=True, null=True, help_text=u'照片存放路径,美化大图')
  288. r_photo_path = models.CharField(_(u'r_photo_path'), max_length=32, blank=True, null=True, help_text=u'照片存放路径,高清大图')
  289. class Meta:
  290. verbose_name = _(u'groupphotoorderinfo')
  291. verbose_name_plural = _(u'groupphotoorderinfo')
  292. unique_together = (('group_id', 'session_id', 'user_id', 'photo_id', 'lensman_photo_id'),)
  293. def __unicode__(self):
  294. return unicode(self.pk)
  295. @property
  296. def m_photo_url(self):
  297. return qiniu_file_url(self.m_photo_path, bucket='photo')
  298. @property
  299. def l_photo_url(self):
  300. return qiniu_file_url(self.l_photo_path, bucket='prettify')
  301. @property
  302. def r_photo_url(self):
  303. return qiniu_file_url(self.r_photo_path, bucket='original')
  304. @property
  305. def porder_info(self):
  306. return {
  307. 'm_photo_url': self.m_photo_url,
  308. 'l_photo_url': self.l_photo_url,
  309. 'r_photo_url': self.r_photo_url,
  310. }
  311. class PhotoCommentInfo(BaseModelMixin):
  312. photo_id = models.CharField(_(u'photo_id'), max_length=32, blank=True, null=True, help_text=u'飞图唯一标识', db_index=True)
  313. user_id = models.CharField(_(u'user_id'), max_length=32, blank=True, null=True, help_text=u'用户唯一标识', db_index=True)
  314. nickname = models.CharField(_(u'nickname'), max_length=255, blank=True, null=True, help_text=u'用户群组昵称')
  315. avatar = models.CharField(_(u'avatar'), max_length=255, blank=True, null=True, help_text=u'用户头像')
  316. to_uid = models.CharField(_(u'to_uid'), max_length=32, blank=True, null=True, help_text=u'被评论用户唯一标识', db_index=True)
  317. comment = models.TextField(_(u'comment'), blank=True, null=True, help_text=u'用户评论')
  318. class Meta:
  319. verbose_name = _(u'photocommentinfo')
  320. verbose_name_plural = _(u'photocommentinfo')
  321. def __unicode__(self):
  322. return unicode(self.pk)
  323. @property
  324. def comment_info(self):
  325. return {
  326. 'user_id': self.user_id,
  327. 'nickname': self.nickname,
  328. 'avatar': self.avatar,
  329. 'to_uid': self.to_uid,
  330. 'comment': self.comment,
  331. 'created_at': tc.remove_microsecond(self.created_at),
  332. }
  333. class PhotoThumbUpInfo(BaseModelMixin):
  334. photo_id = models.CharField(_(u'photo_id'), max_length=32, blank=True, null=True, help_text=u'飞图唯一标识', db_index=True)
  335. user_id = models.CharField(_(u'user_id'), max_length=32, blank=True, null=True, help_text=u'用户唯一标识', db_index=True)
  336. nickname = models.CharField(_(u'nickname'), max_length=255, blank=True, null=True, help_text=u'用户群组昵称')
  337. avatar = models.CharField(_(u'avatar'), max_length=255, blank=True, null=True, help_text=u'用户头像')
  338. thumbup = models.BooleanField(_(u'thumbup'), default=True, help_text=u'用户点赞', db_index=True)
  339. class Meta:
  340. verbose_name = _(u'photothumbupinfo')
  341. verbose_name_plural = _(u'photothumbupinfo')
  342. unique_together = (('photo_id', 'user_id'),)
  343. def __unicode__(self):
  344. return unicode(self.pk)
  345. @property
  346. def thumbup_info(self):
  347. return {
  348. 'user_id': self.user_id,
  349. 'nickname': self.nickname,
  350. 'avatar': self.avatar,
  351. }