-from __future__ import unicode_literals
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('pay', '0012_auto_20201130_0131'),
- ]
-
- operations = [
- migrations.AlterField(
- model_name='orderinfo',
- name='reback_status',
- field=models.BooleanField(default=False, help_text='\u9000\u6b3e\u72b6\u6001', verbose_name='reback_status'),
- ),
- ]
@@ -1,123 +0,0 @@ |
||
| 1 |
-# -*- coding: utf-8 -*- |
|
| 2 |
- |
|
| 3 |
-from django.db import models |
|
| 4 |
-from django.utils.translation import ugettext_lazy as _ |
|
| 5 |
-from django_models_ext import BaseModelMixin |
|
| 6 |
-from shortuuidfield import ShortUUIDField |
|
| 7 |
-from TimeConvert import TimeConvert as tc |
|
| 8 |
- |
|
| 9 |
-from group.models import GroupPhotoInfo |
|
| 10 |
- |
|
| 11 |
- |
|
| 12 |
-class OrderInfo(BaseModelMixin): |
|
| 13 |
- NOMARK = 0 |
|
| 14 |
- ORIGIN = 1 |
|
| 15 |
- |
|
| 16 |
- PHOTO_TYPE = ( |
|
| 17 |
- (NOMARK, u'去除水印'), |
|
| 18 |
- (ORIGIN, u'获取高清图'), |
|
| 19 |
- ) |
|
| 20 |
- |
|
| 21 |
- WANTED = 0 |
|
| 22 |
- FETCHED = 1 |
|
| 23 |
- DELETED = 2 |
|
| 24 |
- |
|
| 25 |
- PHOTO_STATUS = ( |
|
| 26 |
- (WANTED, u'待上传'), |
|
| 27 |
- (FETCHED, u'已上传'), |
|
| 28 |
- (DELETED, u'已删除'), |
|
| 29 |
- ) |
|
| 30 |
- |
|
| 31 |
- """ |
|
| 32 |
- # Trade State of Wechat Query |
|
| 33 |
- SUCCESS ——— 支付成功 |
|
| 34 |
- REFUND ——— 转入退款 |
|
| 35 |
- NOTPAY ——— 未支付 |
|
| 36 |
- CLOSED ——— 已关闭 |
|
| 37 |
- REVOKED ——— 已撤销(刷卡支付) |
|
| 38 |
- USERPAYING ——— 用户支付中 |
|
| 39 |
- PAYERROR ——— 支付失败(其他原因,如银行返回失败) |
|
| 40 |
- """ |
|
| 41 |
- |
|
| 42 |
- WAITING_PAY = 0 |
|
| 43 |
- PAID = 1 |
|
| 44 |
- FAIL = 2 |
|
| 45 |
- # DELETED = 9 |
|
| 46 |
- |
|
| 47 |
- PAY_STATUS = ( |
|
| 48 |
- (WAITING_PAY, u'待支付'), |
|
| 49 |
- (PAID, u'已支付'), |
|
| 50 |
- (FAIL, u'已失败'), |
|
| 51 |
- # (DELETED, u'已删除'), |
|
| 52 |
- ) |
|
| 53 |
- |
|
| 54 |
- order_id = ShortUUIDField(_(u'order_id'), max_length=32, help_text=u'订单唯一标识', db_index=True) |
|
| 55 |
- |
|
| 56 |
- prepay_id = models.CharField(_(u'prepay_id'), max_length=64, blank=True, null=True, help_text=u'预支付交易会话标识') |
|
| 57 |
- transaction_id = models.CharField(_(u'transaction_id'), max_length=32, blank=True, null=True, help_text=u'交易单号') |
|
| 58 |
- |
|
| 59 |
- group_id = models.CharField(_(u'group_id'), max_length=32, blank=True, null=True, help_text=u'群组唯一标识', db_index=True) |
|
| 60 |
- session_id = models.CharField(_(u'session_id'), max_length=32, blank=True, null=True, help_text=u'照片组唯一标识,同 PhotosInfo 表', db_index=True) |
|
| 61 |
- photo_id = models.CharField(_(u'photo_id'), max_length=32, blank=True, null=True, help_text=u'飞图唯一标识', db_index=True) |
|
| 62 |
- lensman_photo_id = models.CharField(_(u'lensman_photo_id'), max_length=32, blank=True, null=True, help_text=u'摄影师照片唯一标识,同 PhotosInfo 表', db_index=True) |
|
| 63 |
- |
|
| 64 |
- photo_type = models.IntegerField(_(u'photo_type'), choices=PHOTO_TYPE, default=NOMARK, help_text=u'购买照片类型', db_index=True) |
|
| 65 |
- photo_status = models.IntegerField(_(u'photo_status'), choices=PHOTO_STATUS, default=WANTED, help_text=_(u'购买照片状态, 标识用户是否已经获得照片'), db_index=True) |
|
| 66 |
- |
|
| 67 |
- from_uid = models.CharField(_(u'from_uid'), max_length=32, help_text=u'付款用户唯一标识', db_index=True) |
|
| 68 |
- to_uid = models.CharField(_(u'to_uid'), max_length=32, blank=True, null=True, help_text=u'收款用户唯一标识', db_index=True) |
|
| 69 |
- |
|
| 70 |
- body = models.CharField(_(u'body'), max_length=255, blank=True, null=True, help_text=u'商品描述') |
|
| 71 |
- total_fee = models.IntegerField(_(u'total_fee'), default=0, help_text=u'总金额') |
|
| 72 |
- |
|
| 73 |
- trade_type = models.CharField(_(u'trade_type'), max_length=255, blank=True, null=True, help_text=u'支付方式') |
|
| 74 |
- |
|
| 75 |
- pay_status = models.IntegerField(_(u'pay_status'), choices=PAY_STATUS, default=WAITING_PAY, help_text=u'支付状态', db_index=True) |
|
| 76 |
- paid_at = models.DateTimeField(_(u'paid_at'), blank=True, null=True, help_text=_(u'支付时间')) |
|
| 77 |
- |
|
| 78 |
- reback_status = models.BooleanField(_(u'reback_status'), default=False, help_text=u'退款状态') |
|
| 79 |
- reback_at = models.DateTimeField(_(u'reback_at'), blank=True, null=True, help_text=_(u'退款时间')) |
|
| 80 |
- |
|
| 81 |
- # 微信统一下单 |
|
| 82 |
- unifiedorder_result = models.TextField(_(u'unifiedorder_result'), blank=True, null=True, help_text=_(u'统一下单结果')) |
|
| 83 |
- # 微信支付回调 |
|
| 84 |
- notify_msg = models.TextField(_(u'notify_msg'), blank=True, null=True, help_text=u'回调信息') |
|
| 85 |
- |
|
| 86 |
- class Meta: |
|
| 87 |
- verbose_name = _(u'orderinfo') |
|
| 88 |
- verbose_name_plural = _(u'orderinfo') |
|
| 89 |
- |
|
| 90 |
- def __unicode__(self): |
|
| 91 |
- return u'{0.pk}'.format(self)
|
|
| 92 |
- |
|
| 93 |
- def data(self, user_id=None): |
|
| 94 |
- try: |
|
| 95 |
- group_photo = GroupPhotoInfo.objects.get(photo_id=self.photo_id) |
|
| 96 |
- except GroupPhotoInfo.DoesNotExist: |
|
| 97 |
- group_photo = None |
|
| 98 |
- return {
|
|
| 99 |
- 'order_id': self.order_id, |
|
| 100 |
- 'from_uid': self.from_uid, |
|
| 101 |
- 'group_id': self.group_id, |
|
| 102 |
- 'photo_id': self.photo_id, |
|
| 103 |
- 'group_photo_info': group_photo and group_photo.photo_info(user_id), |
|
| 104 |
- 'to_uid': self.to_uid, |
|
| 105 |
- 'body': self.body, |
|
| 106 |
- 'total_fee': self.total_fee, |
|
| 107 |
- 'pay_status': self.pay_status, |
|
| 108 |
- 'paid_at': tc.remove_microsecond(self.paid_at), |
|
| 109 |
- 'created_at': tc.remove_microsecond(self.created_at), |
|
| 110 |
- } |
|
| 111 |
- |
|
| 112 |
- @property |
|
| 113 |
- def lensdata(self, user_id=None): |
|
| 114 |
- try: |
|
| 115 |
- group_photo = GroupPhotoInfo.objects.get(photo_id=self.photo_id) |
|
| 116 |
- except GroupPhotoInfo.DoesNotExist: |
|
| 117 |
- group_photo = None |
|
| 118 |
- return {
|
|
| 119 |
- 'order_id': self.order_id, |
|
| 120 |
- 'session_id': self.session_id, |
|
| 121 |
- 'photo_id': self.lensman_photo_id, |
|
| 122 |
- 'group_photo_info': group_photo and group_photo.photo_info(user_id), |
|
| 123 |
- } |
@@ -1,4 +0,0 @@ |
||
| 1 |
-from django.test import TestCase |
|
| 2 |
- |
|
| 3 |
- |
|
| 4 |
-# Create your tests here. |
@@ -1,344 +0,0 @@ |
||
| 1 |
-# -*- coding: utf-8 -*- |
|
| 2 |
- |
|
| 3 |
-from django.conf import settings |
|
| 4 |
-from django.db import transaction |
|
| 5 |
-from django.shortcuts import HttpResponse |
|
| 6 |
-from django_logit import logit |
|
| 7 |
-from django_response import response |
|
| 8 |
-from paginator import pagination |
|
| 9 |
-from pywe_exception import WeChatPayException |
|
| 10 |
-from pywe_pay import WeChatPay |
|
| 11 |
-from pywe_pay_notify import check_pay_notify |
|
| 12 |
-from pywe_response import WXPAY_NOTIFY_FAIL, WXPAY_NOTIFY_SUCCESS |
|
| 13 |
-from pywe_sign import check_signature |
|
| 14 |
-from TimeConvert import TimeConvert as tc |
|
| 15 |
- |
|
| 16 |
-from account.models import UserIncomeExpensesInfo, UserInfo |
|
| 17 |
-from group.models import GroupPhotoInfo, GroupPhotoOrderInfo |
|
| 18 |
-from pay.models import OrderInfo |
|
| 19 |
-from photo.models import PhotosInfo |
|
| 20 |
-from utils.error.errno_utils import (GroupPhotoStatusCode, OrderStatusCode, UserStatusCode, WechatStatusCode, |
|
| 21 |
- WithdrawStatusCode) |
|
| 22 |
-from utils.price_utils import get_group_photo_price |
|
| 23 |
-from utils.redis.rbrief import set_brief_info |
|
| 24 |
-from utils.redis.rorder import set_lensman_order_record |
|
| 25 |
-from utils.wx_utils import get_trade_type, get_user_openid |
|
| 26 |
- |
|
| 27 |
- |
|
| 28 |
-WECHAT = settings.WECHAT |
|
| 29 |
- |
|
| 30 |
- |
|
| 31 |
-@logit |
|
| 32 |
-@transaction.atomic |
|
| 33 |
-def wx_order_create_api(request): |
|
| 34 |
- """ 订单创建 """ |
|
| 35 |
- group_id = request.POST.get('group_id', '')
|
|
| 36 |
- user_id = request.POST.get('user_id', '')
|
|
| 37 |
- photo_id = request.POST.get('photo_id', '')
|
|
| 38 |
- photo_type = request.POST.get('photo_type', 'nomark') # nomark for 去除水印, origin for 获取高清图
|
|
| 39 |
- |
|
| 40 |
- photo_type_int = OrderInfo.ORIGIN if photo_type == 'origin' else OrderInfo.NOMARK |
|
| 41 |
- |
|
| 42 |
- # 用户校验 |
|
| 43 |
- try: |
|
| 44 |
- user = UserInfo.objects.get(user_id=user_id) |
|
| 45 |
- except UserInfo.DoesNotExist: |
|
| 46 |
- return response(UserStatusCode.USER_NOT_FOUND) |
|
| 47 |
- |
|
| 48 |
- # 群组照片校验 |
|
| 49 |
- try: |
|
| 50 |
- group_photo = GroupPhotoInfo.objects.get(photo_id=photo_id, status=True) |
|
| 51 |
- except GroupPhotoInfo.DoesNotExist: |
|
| 52 |
- return response(GroupPhotoStatusCode.GROUP_PHOTO_NOT_FOUND) |
|
| 53 |
- |
|
| 54 |
- # 判断是否重复购买 |
|
| 55 |
- if OrderInfo.objects.filter(photo_id=photo_id, photo_type=photo_type_int, from_uid=user_id, pay_status=OrderInfo.PAID, status=True).exists(): |
|
| 56 |
- return response(OrderStatusCode.WX_ORDER_PAID_ALREADY_EXISTS) |
|
| 57 |
- |
|
| 58 |
- body = request.POST.get('body', '') # 商品描述
|
|
| 59 |
- total_fee = int(request.POST.get('total_fee', 0)) # 总金额,单位分
|
|
| 60 |
- |
|
| 61 |
- # 金额校验 |
|
| 62 |
- if get_group_photo_price(group_photo, photo_type) != total_fee: |
|
| 63 |
- return response(OrderStatusCode.FEE_CHECK_FAIL) |
|
| 64 |
- |
|
| 65 |
- # 获取 from_uid, to_uid |
|
| 66 |
- from_uid = user_id |
|
| 67 |
- to_uid = group_photo.lensman_id or group_photo.user_id |
|
| 68 |
- |
|
| 69 |
- # JSAPI--公众号支付、NATIVE--原生扫码支付、APP--app支付,统一下单接口trade_type的传参可参考这里 |
|
| 70 |
- trade_type = request.POST.get('trade_type', '')
|
|
| 71 |
- |
|
| 72 |
- # 根据 trade_type 获取 wechat 配置 |
|
| 73 |
- wxcfg = WECHAT.get(trade_type, {})
|
|
| 74 |
- # WeChatPay 初始化 |
|
| 75 |
- wxpay = WeChatPay(wxcfg.get('appID'), wxcfg.get('apiKey'), wxcfg.get('mchID'))
|
|
| 76 |
- |
|
| 77 |
- # 生成订单 |
|
| 78 |
- order = OrderInfo.objects.create( |
|
| 79 |
- group_id=group_id, |
|
| 80 |
- photo_id=photo_id, |
|
| 81 |
- lensman_photo_id=group_photo.lensman_photo_id, |
|
| 82 |
- photo_type=photo_type_int, |
|
| 83 |
- from_uid=from_uid, |
|
| 84 |
- to_uid=to_uid, |
|
| 85 |
- session_id=group_photo.session_id, |
|
| 86 |
- total_fee=total_fee, |
|
| 87 |
- trade_type=trade_type, |
|
| 88 |
- ) |
|
| 89 |
- |
|
| 90 |
- try: |
|
| 91 |
- prepay_data = wxpay.order.create( |
|
| 92 |
- body=body, |
|
| 93 |
- notify_url=settings.API_DOMAIN + '/wx/notify_url', |
|
| 94 |
- out_trade_no=order.order_id, |
|
| 95 |
- total_fee=total_fee, |
|
| 96 |
- trade_type=get_trade_type(trade_type), |
|
| 97 |
- openid=get_user_openid(user, trade_type), # 可选,用户在商户appid下的唯一标识。trade_type=JSAPI,此参数必传 |
|
| 98 |
- ) |
|
| 99 |
- except WeChatPayException as e: |
|
| 100 |
- order.unifiedorder_result = e.message |
|
| 101 |
- order.save() |
|
| 102 |
- return response(OrderStatusCode.WX_UNIFIED_ORDER_FAIL) |
|
| 103 |
- |
|
| 104 |
- prepay_id = prepay_data.get('prepay_id', '')
|
|
| 105 |
- order.prepay_id = prepay_id |
|
| 106 |
- order.save() |
|
| 107 |
- |
|
| 108 |
- if trade_type == 'JSAPI' or trade_type == 'MINIAPP': |
|
| 109 |
- wxpay_params = wxpay.jsapi.get_jsapi_params(prepay_id) |
|
| 110 |
- elif trade_type == 'APP': |
|
| 111 |
- wxpay_params = wxpay.order.get_appapi_params(prepay_id) |
|
| 112 |
- |
|
| 113 |
- return response(200, 'Order Create Success', u'订单创建成功', {
|
|
| 114 |
- 'order_id': order.order_id, |
|
| 115 |
- 'prepay_id': prepay_id, |
|
| 116 |
- 'wxpay_params': wxpay_params, |
|
| 117 |
- }) |
|
| 118 |
- |
|
| 119 |
- |
|
| 120 |
-def order_paid_success(order): |
|
| 121 |
- if order.pay_status == OrderInfo.PAID: |
|
| 122 |
- return |
|
| 123 |
- |
|
| 124 |
- if order.photo_type == OrderInfo.NOMARK: |
|
| 125 |
- order.photo_status = OrderInfo.FETCHED |
|
| 126 |
- order.pay_status = OrderInfo.PAID |
|
| 127 |
- order.paid_at = tc.utc_datetime() |
|
| 128 |
- order.save() |
|
| 129 |
- |
|
| 130 |
- porder, created = GroupPhotoOrderInfo.objects.select_for_update().get_or_create( |
|
| 131 |
- group_id=order.group_id, |
|
| 132 |
- session_id=order.session_id, |
|
| 133 |
- user_id=order.from_uid, |
|
| 134 |
- photo_id=order.photo_id, |
|
| 135 |
- lensman_photo_id=order.lensman_photo_id, |
|
| 136 |
- ) |
|
| 137 |
- photo = PhotosInfo.objects.get( |
|
| 138 |
- lensman_id=order.to_uid, |
|
| 139 |
- session_id=order.session_id, |
|
| 140 |
- photo_id=order.lensman_photo_id, |
|
| 141 |
- ) |
|
| 142 |
- if order.photo_type == OrderInfo.NOMARK: |
|
| 143 |
- porder.m_photo_path = photo.m_photo_path |
|
| 144 |
- elif order.photo_type == OrderInfo.ORIGIN: |
|
| 145 |
- porder.r_photo_path = photo.r_photo_path |
|
| 146 |
- porder.save() |
|
| 147 |
- |
|
| 148 |
- set_lensman_order_record(porder) |
|
| 149 |
- |
|
| 150 |
- to_uid = order.to_uid |
|
| 151 |
- total_fee = order.total_fee |
|
| 152 |
- |
|
| 153 |
- try: |
|
| 154 |
- user = UserInfo.objects.select_for_update().get(user_id=to_uid) |
|
| 155 |
- except UserInfo.DoesNotExist: |
|
| 156 |
- return |
|
| 157 |
- |
|
| 158 |
- if order.photo_type == OrderInfo.NOMARK: |
|
| 159 |
- # 余额增加 |
|
| 160 |
- amount, freeze_income_amount = total_fee, 0 |
|
| 161 |
- user.balance += amount |
|
| 162 |
- # Redis 数值更新 |
|
| 163 |
- set_brief_info(to_uid, order.photo_type, total_fee) |
|
| 164 |
- # 余额记录 |
|
| 165 |
- UserIncomeExpensesInfo.objects.create( |
|
| 166 |
- user_id=to_uid, |
|
| 167 |
- photo_id=order.photo_id, |
|
| 168 |
- type=UserIncomeExpensesInfo.INCOME, |
|
| 169 |
- amount=amount, |
|
| 170 |
- balance=user.balance, |
|
| 171 |
- freeze_income_amount=freeze_income_amount, |
|
| 172 |
- freeze_income_balance=user.freeze_income_balance, |
|
| 173 |
- remark=u'图片购买', |
|
| 174 |
- ) |
|
| 175 |
- elif order.photo_type == OrderInfo.ORIGIN: |
|
| 176 |
- amount, freeze_income_amount = 0, total_fee |
|
| 177 |
- user.freeze_income_balance += freeze_income_amount |
|
| 178 |
- user.save() |
|
| 179 |
- |
|
| 180 |
- |
|
| 181 |
-def order_paid_fail(order): |
|
| 182 |
- if order.pay_status == OrderInfo.FAIL: |
|
| 183 |
- return |
|
| 184 |
- |
|
| 185 |
- order.pay_status = OrderInfo.FAIL |
|
| 186 |
- order.save() |
|
| 187 |
- |
|
| 188 |
- |
|
| 189 |
-@logit |
|
| 190 |
-@transaction.atomic |
|
| 191 |
-def wx_order_query_api(request): |
|
| 192 |
- """ 订单查询 """ |
|
| 193 |
- order_id = request.POST.get('order_id', '')
|
|
| 194 |
- transaction_id = request.POST.get('transaction_id', '')
|
|
| 195 |
- |
|
| 196 |
- try: |
|
| 197 |
- order = OrderInfo.objects.select_for_update().get(order_id=order_id, status=True) |
|
| 198 |
- except OrderInfo.DoesNotExist: |
|
| 199 |
- return response(OrderStatusCode.WX_ORDER_NOT_FOUND) |
|
| 200 |
- |
|
| 201 |
- if order.pay_status == OrderInfo.PAID: |
|
| 202 |
- return response(200, 'Order Pay Success', u'订单支付成功') |
|
| 203 |
- elif order.pay_status == OrderInfo.FAIL: |
|
| 204 |
- return response(OrderStatusCode.WX_ORDER_PAY_FAIL) |
|
| 205 |
- |
|
| 206 |
- # 根据 trade_type 获取 wechat 配置 |
|
| 207 |
- wxcfg = WECHAT.get(order.trade_type, {})
|
|
| 208 |
- # WeChatPay 初始化 |
|
| 209 |
- wxpay = WeChatPay(wxcfg.get('appID'), wxcfg.get('apiKey'), wxcfg.get('mchID'))
|
|
| 210 |
- |
|
| 211 |
- # 订单查询 |
|
| 212 |
- query_data = wxpay.order.query(transaction_id, order_id) |
|
| 213 |
- # 签名校验 |
|
| 214 |
- if not check_signature(query_data, wxcfg.get('apiKey')):
|
|
| 215 |
- return response(OrderStatusCode.SIGN_CHECK_FAIL) |
|
| 216 |
- |
|
| 217 |
- order.notify_msg = query_data |
|
| 218 |
- order.transaction_id = query_data.get('transaction_id', '')
|
|
| 219 |
- order.save() |
|
| 220 |
- |
|
| 221 |
- # 交易状态 |
|
| 222 |
- trade_state = query_data.get('trade_state')
|
|
| 223 |
- # 订单状态判断更新 |
|
| 224 |
- if trade_state == 'SUCCESS': # 订单支付成功 |
|
| 225 |
- order_paid_success(order) |
|
| 226 |
- return response(200, 'Order Pay Success', u'订单支付成功') |
|
| 227 |
- elif trade_state == 'NOTPAY': # 订单未支付 |
|
| 228 |
- return response(OrderStatusCode.WX_ORDER_NOT_PAY) |
|
| 229 |
- elif trade_state == 'USERPAYING': # 订单支付中 |
|
| 230 |
- return response(OrderStatusCode.WX_ORDER_PAYING) |
|
| 231 |
- else: # 订单支付失败 |
|
| 232 |
- order_paid_fail(order) |
|
| 233 |
- return response(OrderStatusCode.WX_ORDER_PAY_FAIL) |
|
| 234 |
- |
|
| 235 |
- |
|
| 236 |
-@logit |
|
| 237 |
-@transaction.atomic |
|
| 238 |
-def wx_order_list_api(request): |
|
| 239 |
- """ 订单列表 """ |
|
| 240 |
- user_id = request.POST.get('user_id', '')
|
|
| 241 |
- page = int(request.POST.get('page', 1))
|
|
| 242 |
- num = int(request.POST.get('num', settings.ORDER_NUM_PER_PAGE))
|
|
| 243 |
- |
|
| 244 |
- orders = OrderInfo.objects.filter(from_uid=user_id, pay_status=OrderInfo.PAID, status=True).order_by('-pk')
|
|
| 245 |
- orders, left = pagination(orders, page, num) |
|
| 246 |
- orders = [order.data(user_id) for order in orders] |
|
| 247 |
- |
|
| 248 |
- return response(200, 'Get Order List Success', u'获取订单列表成功', {
|
|
| 249 |
- 'orders': orders, |
|
| 250 |
- 'left': left, |
|
| 251 |
- }) |
|
| 252 |
- |
|
| 253 |
- |
|
| 254 |
-@logit |
|
| 255 |
-@transaction.atomic |
|
| 256 |
-def wx_order_detail_api(request): |
|
| 257 |
- """ 订单详情 """ |
|
| 258 |
- user_id = request.POST.get('user_id', '')
|
|
| 259 |
- order_id = request.POST.get('order_id', '')
|
|
| 260 |
- |
|
| 261 |
- try: |
|
| 262 |
- order = OrderInfo.objects.get(order_id=order_id, status=True) |
|
| 263 |
- except OrderInfo.DoesNotExist: |
|
| 264 |
- return response(OrderStatusCode.WX_ORDER_NOT_FOUND) |
|
| 265 |
- |
|
| 266 |
- if user_id not in [order.from_uid, order.to_uid]: |
|
| 267 |
- return response(OrderStatusCode.NO_DETAIL_PERMISSION) |
|
| 268 |
- |
|
| 269 |
- return response(200, 'Get Order Detail Success', u'获取订单详情成功', order.data(user_id)) |
|
| 270 |
- |
|
| 271 |
- |
|
| 272 |
-@logit |
|
| 273 |
-@transaction.atomic |
|
| 274 |
-def wx_notify_url_api(request): |
|
| 275 |
- """ 支付异步通知回调地址 """ |
|
| 276 |
- notify_data, success = check_pay_notify(request.body, wx_configs=settings.WECHAT) |
|
| 277 |
- if not success: |
|
| 278 |
- return HttpResponse(WXPAY_NOTIFY_FAIL) |
|
| 279 |
- |
|
| 280 |
- try: |
|
| 281 |
- order = OrderInfo.objects.select_for_update().get(order_id=notify_data.get('out_trade_no', ''), status=True)
|
|
| 282 |
- except OrderInfo.DoesNotExist: |
|
| 283 |
- return HttpResponse(WXPAY_NOTIFY_FAIL) |
|
| 284 |
- |
|
| 285 |
- order.notify_msg = request.body |
|
| 286 |
- order.transaction_id = notify_data.get('transaction_id', '')
|
|
| 287 |
- order.save() |
|
| 288 |
- |
|
| 289 |
- result_code = notify_data.get('result_code', '')
|
|
| 290 |
- if result_code == 'SUCCESS': |
|
| 291 |
- order_paid_success(order) |
|
| 292 |
- else: |
|
| 293 |
- order_paid_fail(order) |
|
| 294 |
- |
|
| 295 |
- return HttpResponse(WXPAY_NOTIFY_SUCCESS) |
|
| 296 |
- |
|
| 297 |
- |
|
| 298 |
-@logit |
|
| 299 |
-@transaction.atomic |
|
| 300 |
-def wx_balance_withdraw_api(request): |
|
| 301 |
- user_id = request.POST.get('user_id', '')
|
|
| 302 |
- |
|
| 303 |
- # 用户校验 |
|
| 304 |
- try: |
|
| 305 |
- user = UserInfo.objects.select_for_update().get(user_id=user_id) |
|
| 306 |
- except UserInfo.DoesNotExist: |
|
| 307 |
- return response(UserStatusCode.USER_NOT_FOUND) |
|
| 308 |
- |
|
| 309 |
- # JSAPI--公众号支付、NATIVE--原生扫码支付、APP--app支付,统一下单接口trade_type的传参可参考这里 |
|
| 310 |
- trade_type = request.POST.get('trade_type', '')
|
|
| 311 |
- # TRANSFER--企业付款、PACKET--现金红包, 余额提现接口withdraw_type的传参可参考这里 |
|
| 312 |
- withdraw_type = request.POST.get('withdraw_type', 'TRANSFER')
|
|
| 313 |
- amount = int(request.POST.get('amount', 0))
|
|
| 314 |
- |
|
| 315 |
- if not user.openid: |
|
| 316 |
- return response(WechatStatusCode.OPENID_NOT_FOUND) |
|
| 317 |
- |
|
| 318 |
- if user.balance < amount: |
|
| 319 |
- return response(WithdrawStatusCode.BALANCE_NOT_ENOUGH) |
|
| 320 |
- |
|
| 321 |
- # 根据 trade_type 获取 wechat 配置 |
|
| 322 |
- wxcfg = WECHAT.get(trade_type, {})
|
|
| 323 |
- # WeChatPay 初始化 |
|
| 324 |
- wxpay = WeChatPay(wxcfg.get('appID'), wxcfg.get('apiKey'), wxcfg.get('mchID'), mch_cert=wxcfg.get('mch_cert'), mch_key=wxcfg.get('mch_key'))
|
|
| 325 |
- |
|
| 326 |
- if withdraw_type == 'TRANSFER': |
|
| 327 |
- ret_data = wxpay.transfer.transfer(user.openid, amount, u'摄影师余额提现,企业付款', check_name='NO_CHECK') |
|
| 328 |
- elif withdraw_type == 'PACKET': |
|
| 329 |
- wxrpk = wxcfg.get('redpack', {})
|
|
| 330 |
- ret_data = wxpay.redpack.send( |
|
| 331 |
- user.openid, |
|
| 332 |
- amount, |
|
| 333 |
- send_name=wxrpk.get('SEND_NAME'),
|
|
| 334 |
- nick_name=wxrpk.get('NICK_NAME'),
|
|
| 335 |
- act_name=wxrpk.get('ACT_NAME'),
|
|
| 336 |
- wishing=wxrpk.get('WISHING'),
|
|
| 337 |
- remark=wxrpk.get('REMARK'),
|
|
| 338 |
- ) |
|
| 339 |
- |
|
| 340 |
- # 根据 ret_data 判断是否提现成功, 成功则减余额, 失败则提示 |
|
| 341 |
- user.balance -= amount |
|
| 342 |
- user.save() |
|
| 343 |
- |
|
| 344 |
- return response(200, 'Withdraw Success', u'提现成功', {})
|
@@ -1,25 +0,0 @@ |
||
| 1 |
-# -*- coding: utf-8 -*- |
|
| 2 |
- |
|
| 3 |
-from django.contrib import admin |
|
| 4 |
- |
|
| 5 |
-from photo.models import PhotosInfo, PhotoUUIDInfo, UUIDInfo |
|
| 6 |
- |
|
| 7 |
- |
|
| 8 |
-class UUIDInfoAdmin(admin.ModelAdmin): |
|
| 9 |
- list_display = ('uuid', 'lensman_id', 'status', 'created_at', 'updated_at')
|
|
| 10 |
- list_filter = ('lensman_id', 'status')
|
|
| 11 |
- |
|
| 12 |
- |
|
| 13 |
-class PhotoUUIDInfoAdmin(admin.ModelAdmin): |
|
| 14 |
- list_display = ('photo_md5', 'photo_path', 'photo_watermark_path', 'photo_thumbnail_path', 'photo_thumbnail2_path', 'status', 'created_at', 'updated_at')
|
|
| 15 |
- list_filter = ('status', )
|
|
| 16 |
- |
|
| 17 |
- |
|
| 18 |
-class PhotosInfoAdmin(admin.ModelAdmin): |
|
| 19 |
- list_display = ('lensman_id', 'session_id', 'photo_id', 'p_photo_path', 'm_photo_path', 'l_photo_path', 'r_photo_path', 'status', 'created_at', 'updated_at')
|
|
| 20 |
- list_filter = ('lensman_id', 'status')
|
|
| 21 |
- |
|
| 22 |
- |
|
| 23 |
-# admin.site.register(UUIDInfo, UUIDInfoAdmin) |
|
| 24 |
-# admin.site.register(PhotosInfo, PhotosInfoAdmin) |
|
| 25 |
-# admin.site.register(PhotoUUIDInfo, PhotoUUIDInfoAdmin) |
@@ -1,34 +0,0 @@ |
||
| 1 |
-# -*- coding: utf-8 -*- |
|
| 2 |
-from __future__ import unicode_literals |
|
| 3 |
- |
|
| 4 |
-from django.db import models, migrations |
|
| 5 |
- |
|
| 6 |
- |
|
| 7 |
-class Migration(migrations.Migration): |
|
| 8 |
- |
|
| 9 |
- dependencies = [ |
|
| 10 |
- ] |
|
| 11 |
- |
|
| 12 |
- operations = [ |
|
| 13 |
- migrations.CreateModel( |
|
| 14 |
- name='PhotosInfo', |
|
| 15 |
- fields=[ |
|
| 16 |
- ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
|
|
| 17 |
- ('status', models.BooleanField(default=True, help_text='\u72b6\u6001', verbose_name='status')),
|
|
| 18 |
- ('created_at', models.DateTimeField(help_text='\u521b\u5efa\u65f6\u95f4', verbose_name='created_at', auto_now_add=True)),
|
|
| 19 |
- ('updated_at', models.DateTimeField(help_text='\u66f4\u65b0\u65f6\u95f4', verbose_name='updated_at', auto_now=True)),
|
|
| 20 |
- ('lesman_id', models.CharField(max_length=255, blank=True, help_text='\u6444\u5f71\u5e08\u552f\u4e00\u6807\u8bc6', null=True, verbose_name='lesman_id', db_index=True)),
|
|
| 21 |
- ('session_id', models.CharField(max_length=255, blank=True, help_text='\u7167\u7247\u7ec4\u552f\u4e00\u6807\u8bc6', null=True, verbose_name='session_id', db_index=True)),
|
|
| 22 |
- ('photo_id', models.CharField(null=True, max_length=255, blank=True, help_text='\u7167\u7247\u552f\u4e00\u6807\u8bc6', unique=True, verbose_name='photo_id', db_index=True)),
|
|
| 23 |
- ('photo_path', models.CharField(help_text='\u7167\u7247\u5b58\u653e\u8def\u5f84', max_length=255, null=True, verbose_name='photo_path', blank=True)),
|
|
| 24 |
- ], |
|
| 25 |
- options={
|
|
| 26 |
- 'verbose_name': 'photosinfo', |
|
| 27 |
- 'verbose_name_plural': 'photosinfo', |
|
| 28 |
- }, |
|
| 29 |
- ), |
|
| 30 |
- migrations.AlterIndexTogether( |
|
| 31 |
- name='photosinfo', |
|
| 32 |
- index_together=set([('lesman_id', 'session_id')]),
|
|
| 33 |
- ), |
|
| 34 |
- ] |
@@ -1,27 +0,0 @@ |
||
| 1 |
-# -*- coding: utf-8 -*- |
|
| 2 |
-from __future__ import unicode_literals |
|
| 3 |
- |
|
| 4 |
-from django.db import models, migrations |
|
| 5 |
- |
|
| 6 |
- |
|
| 7 |
-class Migration(migrations.Migration): |
|
| 8 |
- |
|
| 9 |
- dependencies = [ |
|
| 10 |
- ('photo', '0001_initial'),
|
|
| 11 |
- ] |
|
| 12 |
- |
|
| 13 |
- operations = [ |
|
| 14 |
- migrations.AddField( |
|
| 15 |
- model_name='photosinfo', |
|
| 16 |
- name='lensman_id', |
|
| 17 |
- field=models.CharField(max_length=255, blank=True, help_text='\u6444\u5f71\u5e08\u552f\u4e00\u6807\u8bc6', null=True, verbose_name='lensman_id', db_index=True), |
|
| 18 |
- ), |
|
| 19 |
- migrations.AlterIndexTogether( |
|
| 20 |
- name='photosinfo', |
|
| 21 |
- index_together=set([('lensman_id', 'session_id')]),
|
|
| 22 |
- ), |
|
| 23 |
- migrations.RemoveField( |
|
| 24 |
- model_name='photosinfo', |
|
| 25 |
- name='lesman_id', |
|
| 26 |
- ), |
|
| 27 |
- ] |
@@ -1,29 +0,0 @@ |
||
| 1 |
-# -*- coding: utf-8 -*- |
|
| 2 |
-from __future__ import unicode_literals |
|
| 3 |
- |
|
| 4 |
-from django.db import models, migrations |
|
| 5 |
- |
|
| 6 |
- |
|
| 7 |
-class Migration(migrations.Migration): |
|
| 8 |
- |
|
| 9 |
- dependencies = [ |
|
| 10 |
- ('photo', '0002_auto_20151113_1419'),
|
|
| 11 |
- ] |
|
| 12 |
- |
|
| 13 |
- operations = [ |
|
| 14 |
- migrations.CreateModel( |
|
| 15 |
- name='UUIDInfo', |
|
| 16 |
- fields=[ |
|
| 17 |
- ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
|
|
| 18 |
- ('status', models.BooleanField(default=True, help_text='\u72b6\u6001', verbose_name='status')),
|
|
| 19 |
- ('created_at', models.DateTimeField(help_text='\u521b\u5efa\u65f6\u95f4', verbose_name='created_at', auto_now_add=True)),
|
|
| 20 |
- ('updated_at', models.DateTimeField(help_text='\u66f4\u65b0\u65f6\u95f4', verbose_name='updated_at', auto_now=True)),
|
|
| 21 |
- ('uuid', models.CharField(null=True, max_length=22, blank=True, help_text='\u552f\u4e00\u6807\u8bc6', unique=True, verbose_name='uuid', db_index=True)),
|
|
| 22 |
- ('lensman_id', models.CharField(max_length=255, blank=True, help_text='\u6444\u5f71\u5e08\u552f\u4e00\u6807\u8bc6', null=True, verbose_name='lensman_id', db_index=True)),
|
|
| 23 |
- ], |
|
| 24 |
- options={
|
|
| 25 |
- 'verbose_name': 'uuidinfo', |
|
| 26 |
- 'verbose_name_plural': 'uuidinfo', |
|
| 27 |
- }, |
|
| 28 |
- ), |
|
| 29 |
- ] |
@@ -1,19 +0,0 @@ |
||
| 1 |
-# -*- coding: utf-8 -*- |
|
| 2 |
-from __future__ import unicode_literals |
|
| 3 |
- |
|
| 4 |
-from django.db import models, migrations |
|
| 5 |
- |
|
| 6 |
- |
|
| 7 |
-class Migration(migrations.Migration): |
|
| 8 |
- |
|
| 9 |
- dependencies = [ |
|
| 10 |
- ('photo', '0003_uuidinfo'),
|
|
| 11 |
- ] |
|
| 12 |
- |
|
| 13 |
- operations = [ |
|
| 14 |
- migrations.AddField( |
|
| 15 |
- model_name='photosinfo', |
|
| 16 |
- name='photo_name', |
|
| 17 |
- field=models.CharField(help_text='\u7167\u7247\u5b58\u653e\u540d\u79f0', max_length=255, null=True, verbose_name='photo_name', blank=True), |
|
| 18 |
- ), |
|
| 19 |
- ] |
@@ -1,42 +0,0 @@ |
||
| 1 |
-# -*- coding: utf-8 -*- |
|
| 2 |
-from __future__ import unicode_literals |
|
| 3 |
- |
|
| 4 |
-from django.db import models, migrations |
|
| 5 |
- |
|
| 6 |
- |
|
| 7 |
-class Migration(migrations.Migration): |
|
| 8 |
- |
|
| 9 |
- dependencies = [ |
|
| 10 |
- ('photo', '0004_photosinfo_photo_name'),
|
|
| 11 |
- ] |
|
| 12 |
- |
|
| 13 |
- operations = [ |
|
| 14 |
- migrations.RemoveField( |
|
| 15 |
- model_name='photosinfo', |
|
| 16 |
- name='photo_name', |
|
| 17 |
- ), |
|
| 18 |
- migrations.RemoveField( |
|
| 19 |
- model_name='photosinfo', |
|
| 20 |
- name='photo_path', |
|
| 21 |
- ), |
|
| 22 |
- migrations.AddField( |
|
| 23 |
- model_name='photosinfo', |
|
| 24 |
- name='l_photo_path', |
|
| 25 |
- field=models.CharField(help_text='\u7167\u7247\u5b58\u653e\u8def\u5f84', max_length=255, null=True, verbose_name='l_photo_path', blank=True), |
|
| 26 |
- ), |
|
| 27 |
- migrations.AddField( |
|
| 28 |
- model_name='photosinfo', |
|
| 29 |
- name='m_photo_path', |
|
| 30 |
- field=models.CharField(help_text='\u7167\u7247\u5b58\u653e\u8def\u5f84', max_length=255, null=True, verbose_name='m_photo_path', blank=True), |
|
| 31 |
- ), |
|
| 32 |
- migrations.AddField( |
|
| 33 |
- model_name='photosinfo', |
|
| 34 |
- name='p_photo_path', |
|
| 35 |
- field=models.CharField(help_text='\u7167\u7247\u5b58\u653e\u8def\u5f84', max_length=255, null=True, verbose_name='p_photo_path', blank=True), |
|
| 36 |
- ), |
|
| 37 |
- migrations.AddField( |
|
| 38 |
- model_name='photosinfo', |
|
| 39 |
- name='r_photo_path', |
|
| 40 |
- field=models.CharField(help_text='\u7167\u7247\u5b58\u653e\u8def\u5f84', max_length=255, null=True, verbose_name='r_photo_path', blank=True), |
|
| 41 |
- ), |
|
| 42 |
- ] |
@@ -1,24 +0,0 @@ |
||
| 1 |
-# -*- coding: utf-8 -*- |
|
| 2 |
-from __future__ import unicode_literals |
|
| 3 |
- |
|
| 4 |
-from django.db import models, migrations |
|
| 5 |
- |
|
| 6 |
- |
|
| 7 |
-class Migration(migrations.Migration): |
|
| 8 |
- |
|
| 9 |
- dependencies = [ |
|
| 10 |
- ('photo', '0005_auto_20151207_1811'),
|
|
| 11 |
- ] |
|
| 12 |
- |
|
| 13 |
- operations = [ |
|
| 14 |
- migrations.AlterField( |
|
| 15 |
- model_name='photosinfo', |
|
| 16 |
- name='status', |
|
| 17 |
- field=models.BooleanField(default=True, help_text='\u72b6\u6001', db_index=True, verbose_name='status'), |
|
| 18 |
- ), |
|
| 19 |
- migrations.AlterField( |
|
| 20 |
- model_name='uuidinfo', |
|
| 21 |
- name='status', |
|
| 22 |
- field=models.BooleanField(default=True, help_text='\u72b6\u6001', db_index=True, verbose_name='status'), |
|
| 23 |
- ), |
|
| 24 |
- ] |
@@ -1,34 +0,0 @@ |
||
| 1 |
-# -*- coding: utf-8 -*- |
|
| 2 |
-from __future__ import unicode_literals |
|
| 3 |
- |
|
| 4 |
-from django.db import models, migrations |
|
| 5 |
- |
|
| 6 |
- |
|
| 7 |
-class Migration(migrations.Migration): |
|
| 8 |
- |
|
| 9 |
- dependencies = [ |
|
| 10 |
- ('photo', '0006_auto_20160120_1830'),
|
|
| 11 |
- ] |
|
| 12 |
- |
|
| 13 |
- operations = [ |
|
| 14 |
- migrations.AlterField( |
|
| 15 |
- model_name='photosinfo', |
|
| 16 |
- name='l_photo_path', |
|
| 17 |
- field=models.CharField(help_text='\u7167\u7247\u5b58\u653e\u8def\u5f84\uff0c\u7f8e\u5316\u5927\u56fe', max_length=255, null=True, verbose_name='l_photo_path', blank=True), |
|
| 18 |
- ), |
|
| 19 |
- migrations.AlterField( |
|
| 20 |
- model_name='photosinfo', |
|
| 21 |
- name='m_photo_path', |
|
| 22 |
- field=models.CharField(help_text='\u7167\u7247\u5b58\u653e\u8def\u5f84\uff0c\u63a7\u5236\u5668\u4e0a\u4f20\uff0c\u65e0\u6c34\u5370', max_length=255, null=True, verbose_name='m_photo_path', blank=True), |
|
| 23 |
- ), |
|
| 24 |
- migrations.AlterField( |
|
| 25 |
- model_name='photosinfo', |
|
| 26 |
- name='p_photo_path', |
|
| 27 |
- field=models.CharField(help_text='\u7167\u7247\u5b58\u653e\u8def\u5f84\uff0c\u63a7\u5236\u5668\u4e0a\u4f20\uff0c\u6709\u6c34\u5370\uff0c\u670d\u52a1\u5668\u6dfb\u52a0', max_length=255, null=True, verbose_name='p_photo_path', blank=True), |
|
| 28 |
- ), |
|
| 29 |
- migrations.AlterField( |
|
| 30 |
- model_name='photosinfo', |
|
| 31 |
- name='r_photo_path', |
|
| 32 |
- field=models.CharField(help_text='\u7167\u7247\u5b58\u653e\u8def\u5f84\uff0c\u9ad8\u6e05\u5927\u56fe', max_length=255, null=True, verbose_name='r_photo_path', blank=True), |
|
| 33 |
- ), |
|
| 34 |
- ] |
@@ -1,24 +0,0 @@ |
||
| 1 |
-# -*- coding: utf-8 -*- |
|
| 2 |
-from __future__ import unicode_literals |
|
| 3 |
- |
|
| 4 |
-from django.db import models, migrations |
|
| 5 |
- |
|
| 6 |
- |
|
| 7 |
-class Migration(migrations.Migration): |
|
| 8 |
- |
|
| 9 |
- dependencies = [ |
|
| 10 |
- ('photo', '0007_auto_20160422_1322'),
|
|
| 11 |
- ] |
|
| 12 |
- |
|
| 13 |
- operations = [ |
|
| 14 |
- migrations.AlterField( |
|
| 15 |
- model_name='photosinfo', |
|
| 16 |
- name='m_photo_path', |
|
| 17 |
- field=models.CharField(help_text='\u7167\u7247\u5b58\u653e\u8def\u5f84\uff0cBox\u4e0a\u4f20\uff0c\u65e0\u6c34\u5370', max_length=255, null=True, verbose_name='m_photo_path', blank=True), |
|
| 18 |
- ), |
|
| 19 |
- migrations.AlterField( |
|
| 20 |
- model_name='photosinfo', |
|
| 21 |
- name='p_photo_path', |
|
| 22 |
- field=models.CharField(help_text='\u7167\u7247\u5b58\u653e\u8def\u5f84\uff0cBox\u4e0a\u4f20\uff0c\u6709\u6c34\u5370\uff0c\u670d\u52a1\u5668\u6dfb\u52a0', max_length=255, null=True, verbose_name='p_photo_path', blank=True), |
|
| 23 |
- ), |
|
| 24 |
- ] |
@@ -1,23 +0,0 @@ |
||
| 1 |
-# -*- coding: utf-8 -*- |
|
| 2 |
-from __future__ import unicode_literals |
|
| 3 |
- |
|
| 4 |
-from django.db import models, migrations |
|
| 5 |
- |
|
| 6 |
- |
|
| 7 |
-class Migration(migrations.Migration): |
|
| 8 |
- |
|
| 9 |
- dependencies = [ |
|
| 10 |
- ('photo', '0008_auto_20160901_1439'),
|
|
| 11 |
- ] |
|
| 12 |
- |
|
| 13 |
- operations = [ |
|
| 14 |
- migrations.AlterField( |
|
| 15 |
- model_name='photosinfo', |
|
| 16 |
- name='photo_id', |
|
| 17 |
- field=models.CharField(max_length=255, blank=True, help_text='\u7167\u7247\u552f\u4e00\u6807\u8bc6', null=True, verbose_name='photo_id', db_index=True), |
|
| 18 |
- ), |
|
| 19 |
- migrations.AlterUniqueTogether( |
|
| 20 |
- name='photosinfo', |
|
| 21 |
- unique_together=set([('lensman_id', 'session_id', 'photo_id')]),
|
|
| 22 |
- ), |
|
| 23 |
- ] |
@@ -1,29 +0,0 @@ |
||
| 1 |
-# -*- coding: utf-8 -*- |
|
| 2 |
-from __future__ import unicode_literals |
|
| 3 |
- |
|
| 4 |
-from django.db import models, migrations |
|
| 5 |
- |
|
| 6 |
- |
|
| 7 |
-class Migration(migrations.Migration): |
|
| 8 |
- |
|
| 9 |
- dependencies = [ |
|
| 10 |
- ('photo', '0009_auto_20160907_1018'),
|
|
| 11 |
- ] |
|
| 12 |
- |
|
| 13 |
- operations = [ |
|
| 14 |
- migrations.CreateModel( |
|
| 15 |
- name='PhotoUUIDInfo', |
|
| 16 |
- fields=[ |
|
| 17 |
- ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
|
|
| 18 |
- ('status', models.BooleanField(default=True, help_text='\u72b6\u6001', db_index=True, verbose_name='status')),
|
|
| 19 |
- ('created_at', models.DateTimeField(help_text='\u521b\u5efa\u65f6\u95f4', verbose_name='created_at', auto_now_add=True)),
|
|
| 20 |
- ('updated_at', models.DateTimeField(help_text='\u66f4\u65b0\u65f6\u95f4', verbose_name='updated_at', auto_now=True)),
|
|
| 21 |
- ('photo_md5', models.CharField(null=True, max_length=255, blank=True, help_text='\u7167\u7247\u552f\u4e00\u6807\u8bc6', unique=True, verbose_name='photo_md5', db_index=True)),
|
|
| 22 |
- ('photo_path', models.CharField(help_text='\u7167\u7247\u8def\u5f84', max_length=255, null=True, verbose_name='photo_path', blank=True)),
|
|
| 23 |
- ], |
|
| 24 |
- options={
|
|
| 25 |
- 'verbose_name': 'photouuidinfo', |
|
| 26 |
- 'verbose_name_plural': 'photouuidinfo', |
|
| 27 |
- }, |
|
| 28 |
- ), |
|
| 29 |
- ] |
@@ -1,69 +0,0 @@ |
||
| 1 |
-# -*- coding: utf-8 -*- |
|
| 2 |
-from __future__ import unicode_literals |
|
| 3 |
- |
|
| 4 |
-from django.db import models, migrations |
|
| 5 |
- |
|
| 6 |
- |
|
| 7 |
-class Migration(migrations.Migration): |
|
| 8 |
- |
|
| 9 |
- dependencies = [ |
|
| 10 |
- ('photo', '0010_photouuidinfo'),
|
|
| 11 |
- ] |
|
| 12 |
- |
|
| 13 |
- operations = [ |
|
| 14 |
- migrations.AddField( |
|
| 15 |
- model_name='photouuidinfo', |
|
| 16 |
- name='photo_h', |
|
| 17 |
- field=models.IntegerField(default=0, help_text='\u7167\u7247\u9ad8\u5ea6', verbose_name='photo_h'), |
|
| 18 |
- ), |
|
| 19 |
- migrations.AddField( |
|
| 20 |
- model_name='photouuidinfo', |
|
| 21 |
- name='photo_thumbnail2_h', |
|
| 22 |
- field=models.IntegerField(default=0, help_text='\u7167\u7247\u7f29\u7565\u56fe\u9ad8\u5ea6', verbose_name='photo_thumbnail2_h'), |
|
| 23 |
- ), |
|
| 24 |
- migrations.AddField( |
|
| 25 |
- model_name='photouuidinfo', |
|
| 26 |
- name='photo_thumbnail2_path', |
|
| 27 |
- field=models.CharField(help_text='\u7167\u7247\u7f29\u7565\u56fe\u5b58\u653e\u8def\u5f84', max_length=255, null=True, verbose_name='photo_thumbnail2_path', blank=True), |
|
| 28 |
- ), |
|
| 29 |
- migrations.AddField( |
|
| 30 |
- model_name='photouuidinfo', |
|
| 31 |
- name='photo_thumbnail2_w', |
|
| 32 |
- field=models.IntegerField(default=0, help_text='\u7167\u7247\u7f29\u7565\u56fe\u5bbd\u5ea6', verbose_name='photo_thumbnail2_w'), |
|
| 33 |
- ), |
|
| 34 |
- migrations.AddField( |
|
| 35 |
- model_name='photouuidinfo', |
|
| 36 |
- name='photo_thumbnail_h', |
|
| 37 |
- field=models.IntegerField(default=0, help_text='\u7167\u7247\u7f29\u7565\u56fe\u9ad8\u5ea6', verbose_name='photo_thumbnail_h'), |
|
| 38 |
- ), |
|
| 39 |
- migrations.AddField( |
|
| 40 |
- model_name='photouuidinfo', |
|
| 41 |
- name='photo_thumbnail_path', |
|
| 42 |
- field=models.CharField(help_text='\u7167\u7247\u7f29\u7565\u56fe\u5b58\u653e\u8def\u5f84', max_length=255, null=True, verbose_name='photo_thumbnail_path', blank=True), |
|
| 43 |
- ), |
|
| 44 |
- migrations.AddField( |
|
| 45 |
- model_name='photouuidinfo', |
|
| 46 |
- name='photo_thumbnail_w', |
|
| 47 |
- field=models.IntegerField(default=0, help_text='\u7167\u7247\u7f29\u7565\u56fe\u5bbd\u5ea6', verbose_name='photo_thumbnail_w'), |
|
| 48 |
- ), |
|
| 49 |
- migrations.AddField( |
|
| 50 |
- model_name='photouuidinfo', |
|
| 51 |
- name='photo_w', |
|
| 52 |
- field=models.IntegerField(default=0, help_text='\u7167\u7247\u5bbd\u5ea6', verbose_name='photo_w'), |
|
| 53 |
- ), |
|
| 54 |
- migrations.AddField( |
|
| 55 |
- model_name='photouuidinfo', |
|
| 56 |
- name='photo_watermark_h', |
|
| 57 |
- field=models.IntegerField(default=0, help_text='\u7167\u7247\u6c34\u5370\u56fe\u9ad8\u5ea6', verbose_name='photo_watermark_h'), |
|
| 58 |
- ), |
|
| 59 |
- migrations.AddField( |
|
| 60 |
- model_name='photouuidinfo', |
|
| 61 |
- name='photo_watermark_path', |
|
| 62 |
- field=models.CharField(help_text='\u7167\u7247\u5b58\u653e\u8def\u5f84\uff0cBox\u4e0a\u4f20\uff0c\u6709\u6c34\u5370\uff0c\u670d\u52a1\u5668\u6dfb\u52a0', max_length=255, null=True, verbose_name='photo_watermark_path', blank=True), |
|
| 63 |
- ), |
|
| 64 |
- migrations.AddField( |
|
| 65 |
- model_name='photouuidinfo', |
|
| 66 |
- name='photo_watermark_w', |
|
| 67 |
- field=models.IntegerField(default=0, help_text='\u7167\u7247\u6c34\u5370\u56fe\u5bbd\u5ea6', verbose_name='photo_watermark_w'), |
|
| 68 |
- ), |
|
| 69 |
- ] |
@@ -1,60 +0,0 @@ |
||
| 1 |
-# -*- coding: utf-8 -*- |
|
| 2 |
-# Generated by Django 1.11.3 on 2018-01-01 14:20 |
|
| 3 |
-from __future__ import unicode_literals |
|
| 4 |
- |
|
| 5 |
-from django.db import migrations, models |
|
| 6 |
- |
|
| 7 |
- |
|
| 8 |
-class Migration(migrations.Migration): |
|
| 9 |
- |
|
| 10 |
- dependencies = [ |
|
| 11 |
- ('photo', '0011_auto_20170119_1207'),
|
|
| 12 |
- ] |
|
| 13 |
- |
|
| 14 |
- operations = [ |
|
| 15 |
- migrations.AlterField( |
|
| 16 |
- model_name='photosinfo', |
|
| 17 |
- name='created_at', |
|
| 18 |
- field=models.DateTimeField(auto_now_add=True, help_text='Create Time', verbose_name='created_at'), |
|
| 19 |
- ), |
|
| 20 |
- migrations.AlterField( |
|
| 21 |
- model_name='photosinfo', |
|
| 22 |
- name='status', |
|
| 23 |
- field=models.BooleanField(db_index=True, default=True, help_text='Status', verbose_name='status'), |
|
| 24 |
- ), |
|
| 25 |
- migrations.AlterField( |
|
| 26 |
- model_name='photosinfo', |
|
| 27 |
- name='updated_at', |
|
| 28 |
- field=models.DateTimeField(auto_now=True, help_text='Update Time', verbose_name='updated_at'), |
|
| 29 |
- ), |
|
| 30 |
- migrations.AlterField( |
|
| 31 |
- model_name='photouuidinfo', |
|
| 32 |
- name='created_at', |
|
| 33 |
- field=models.DateTimeField(auto_now_add=True, help_text='Create Time', verbose_name='created_at'), |
|
| 34 |
- ), |
|
| 35 |
- migrations.AlterField( |
|
| 36 |
- model_name='photouuidinfo', |
|
| 37 |
- name='status', |
|
| 38 |
- field=models.BooleanField(db_index=True, default=True, help_text='Status', verbose_name='status'), |
|
| 39 |
- ), |
|
| 40 |
- migrations.AlterField( |
|
| 41 |
- model_name='photouuidinfo', |
|
| 42 |
- name='updated_at', |
|
| 43 |
- field=models.DateTimeField(auto_now=True, help_text='Update Time', verbose_name='updated_at'), |
|
| 44 |
- ), |
|
| 45 |
- migrations.AlterField( |
|
| 46 |
- model_name='uuidinfo', |
|
| 47 |
- name='created_at', |
|
| 48 |
- field=models.DateTimeField(auto_now_add=True, help_text='Create Time', verbose_name='created_at'), |
|
| 49 |
- ), |
|
| 50 |
- migrations.AlterField( |
|
| 51 |
- model_name='uuidinfo', |
|
| 52 |
- name='status', |
|
| 53 |
- field=models.BooleanField(db_index=True, default=True, help_text='Status', verbose_name='status'), |
|
| 54 |
- ), |
|
| 55 |
- migrations.AlterField( |
|
| 56 |
- model_name='uuidinfo', |
|
| 57 |
- name='updated_at', |
|
| 58 |
- field=models.DateTimeField(auto_now=True, help_text='Update Time', verbose_name='updated_at'), |
|
| 59 |
- ), |
|
| 60 |
- ] |
@@ -1,80 +0,0 @@ |
||
| 1 |
-# -*- coding: utf-8 -*- |
|
| 2 |
-# Generated by Django 1.11.3 on 2018-01-02 20:46 |
|
| 3 |
-from __future__ import unicode_literals |
|
| 4 |
- |
|
| 5 |
-from django.db import migrations, models |
|
| 6 |
- |
|
| 7 |
- |
|
| 8 |
-class Migration(migrations.Migration): |
|
| 9 |
- |
|
| 10 |
- dependencies = [ |
|
| 11 |
- ('photo', '0012_auto_20180101_2220'),
|
|
| 12 |
- ] |
|
| 13 |
- |
|
| 14 |
- operations = [ |
|
| 15 |
- migrations.AlterField( |
|
| 16 |
- model_name='photosinfo', |
|
| 17 |
- name='l_photo_path', |
|
| 18 |
- field=models.CharField(blank=True, help_text='\u7167\u7247\u5b58\u653e\u8def\u5f84\uff0c\u7f8e\u5316\u5927\u56fe', max_length=32, null=True, verbose_name='l_photo_path'), |
|
| 19 |
- ), |
|
| 20 |
- migrations.AlterField( |
|
| 21 |
- model_name='photosinfo', |
|
| 22 |
- name='lensman_id', |
|
| 23 |
- field=models.CharField(blank=True, db_index=True, help_text='\u6444\u5f71\u5e08\u552f\u4e00\u6807\u8bc6', max_length=32, null=True, verbose_name='lensman_id'), |
|
| 24 |
- ), |
|
| 25 |
- migrations.AlterField( |
|
| 26 |
- model_name='photosinfo', |
|
| 27 |
- name='m_photo_path', |
|
| 28 |
- field=models.CharField(blank=True, help_text='\u7167\u7247\u5b58\u653e\u8def\u5f84\uff0cBox\u4e0a\u4f20\uff0c\u65e0\u6c34\u5370', max_length=32, null=True, verbose_name='m_photo_path'), |
|
| 29 |
- ), |
|
| 30 |
- migrations.AlterField( |
|
| 31 |
- model_name='photosinfo', |
|
| 32 |
- name='p_photo_path', |
|
| 33 |
- field=models.CharField(blank=True, help_text='\u7167\u7247\u5b58\u653e\u8def\u5f84\uff0cBox\u4e0a\u4f20\uff0c\u6709\u6c34\u5370\uff0c\u670d\u52a1\u5668\u6dfb\u52a0', max_length=32, null=True, verbose_name='p_photo_path'), |
|
| 34 |
- ), |
|
| 35 |
- migrations.AlterField( |
|
| 36 |
- model_name='photosinfo', |
|
| 37 |
- name='photo_id', |
|
| 38 |
- field=models.CharField(blank=True, db_index=True, help_text='\u7167\u7247\u552f\u4e00\u6807\u8bc6', max_length=32, null=True, verbose_name='photo_id'), |
|
| 39 |
- ), |
|
| 40 |
- migrations.AlterField( |
|
| 41 |
- model_name='photosinfo', |
|
| 42 |
- name='r_photo_path', |
|
| 43 |
- field=models.CharField(blank=True, help_text='\u7167\u7247\u5b58\u653e\u8def\u5f84\uff0c\u9ad8\u6e05\u5927\u56fe', max_length=32, null=True, verbose_name='r_photo_path'), |
|
| 44 |
- ), |
|
| 45 |
- migrations.AlterField( |
|
| 46 |
- model_name='photosinfo', |
|
| 47 |
- name='session_id', |
|
| 48 |
- field=models.CharField(blank=True, db_index=True, help_text='\u7167\u7247\u7ec4\u552f\u4e00\u6807\u8bc6', max_length=32, null=True, verbose_name='session_id'), |
|
| 49 |
- ), |
|
| 50 |
- migrations.AlterField( |
|
| 51 |
- model_name='photouuidinfo', |
|
| 52 |
- name='photo_md5', |
|
| 53 |
- field=models.CharField(blank=True, db_index=True, help_text='\u7167\u7247\u552f\u4e00\u6807\u8bc6', max_length=32, null=True, unique=True, verbose_name='photo_md5'), |
|
| 54 |
- ), |
|
| 55 |
- migrations.AlterField( |
|
| 56 |
- model_name='photouuidinfo', |
|
| 57 |
- name='photo_path', |
|
| 58 |
- field=models.CharField(blank=True, help_text='\u7167\u7247\u8def\u5f84', max_length=32, null=True, verbose_name='photo_path'), |
|
| 59 |
- ), |
|
| 60 |
- migrations.AlterField( |
|
| 61 |
- model_name='photouuidinfo', |
|
| 62 |
- name='photo_thumbnail2_path', |
|
| 63 |
- field=models.CharField(blank=True, help_text='\u7167\u7247\u7f29\u7565\u56fe\u5b58\u653e\u8def\u5f84', max_length=32, null=True, verbose_name='photo_thumbnail2_path'), |
|
| 64 |
- ), |
|
| 65 |
- migrations.AlterField( |
|
| 66 |
- model_name='photouuidinfo', |
|
| 67 |
- name='photo_thumbnail_path', |
|
| 68 |
- field=models.CharField(blank=True, help_text='\u7167\u7247\u7f29\u7565\u56fe\u5b58\u653e\u8def\u5f84', max_length=32, null=True, verbose_name='photo_thumbnail_path'), |
|
| 69 |
- ), |
|
| 70 |
- migrations.AlterField( |
|
| 71 |
- model_name='photouuidinfo', |
|
| 72 |
- name='photo_watermark_path', |
|
| 73 |
- field=models.CharField(blank=True, help_text='\u7167\u7247\u5b58\u653e\u8def\u5f84\uff0cBox\u4e0a\u4f20\uff0c\u6709\u6c34\u5370\uff0c\u670d\u52a1\u5668\u6dfb\u52a0', max_length=32, null=True, verbose_name='photo_watermark_path'), |
|
| 74 |
- ), |
|
| 75 |
- migrations.AlterField( |
|
| 76 |
- model_name='uuidinfo', |
|
| 77 |
- name='lensman_id', |
|
| 78 |
- field=models.CharField(blank=True, db_index=True, help_text='\u6444\u5f71\u5e08\u552f\u4e00\u6807\u8bc6', max_length=32, null=True, verbose_name='lensman_id'), |
|
| 79 |
- ), |
|
| 80 |
- ] |
@@ -1,28 +0,0 @@ |
||
| 1 |
-# Generated by Django 2.2.15 on 2020-11-29 17:31 |
|
| 2 |
- |
|
| 3 |
-from django.db import migrations, models |
|
| 4 |
- |
|
| 5 |
- |
|
| 6 |
-class Migration(migrations.Migration): |
|
| 7 |
- |
|
| 8 |
- dependencies = [ |
|
| 9 |
- ('photo', '0013_auto_20180103_0446'),
|
|
| 10 |
- ] |
|
| 11 |
- |
|
| 12 |
- operations = [ |
|
| 13 |
- migrations.AlterField( |
|
| 14 |
- model_name='photosinfo', |
|
| 15 |
- name='status', |
|
| 16 |
- field=models.BooleanField(default=True, help_text='Status', verbose_name='status'), |
|
| 17 |
- ), |
|
| 18 |
- migrations.AlterField( |
|
| 19 |
- model_name='photouuidinfo', |
|
| 20 |
- name='status', |
|
| 21 |
- field=models.BooleanField(default=True, help_text='Status', verbose_name='status'), |
|
| 22 |
- ), |
|
| 23 |
- migrations.AlterField( |
|
| 24 |
- model_name='uuidinfo', |
|
| 25 |
- name='status', |
|
| 26 |
- field=models.BooleanField(default=True, help_text='Status', verbose_name='status'), |
|
| 27 |
- ), |
|
| 28 |
- ] |
@@ -1,114 +0,0 @@ |
||
| 1 |
-# -*- coding: utf-8 -*- |
|
| 2 |
- |
|
| 3 |
-from django.db import models |
|
| 4 |
-from django.utils.translation import ugettext_lazy as _ |
|
| 5 |
-from django_models_ext import BaseModelMixin |
|
| 6 |
- |
|
| 7 |
-from utils.qiniucdn import qiniu_file_url |
|
| 8 |
- |
|
| 9 |
- |
|
| 10 |
-class UUIDInfo(BaseModelMixin): |
|
| 11 |
- uuid = models.CharField(_(u'uuid'), max_length=22, blank=True, null=True, help_text=u'唯一标识', db_index=True, unique=True) |
|
| 12 |
- lensman_id = models.CharField(_(u'lensman_id'), max_length=32, blank=True, null=True, help_text=u'摄影师唯一标识', db_index=True) |
|
| 13 |
- |
|
| 14 |
- class Meta: |
|
| 15 |
- verbose_name = _('uuidinfo')
|
|
| 16 |
- verbose_name_plural = _('uuidinfo')
|
|
| 17 |
- |
|
| 18 |
- def __unicode__(self): |
|
| 19 |
- return u'{0.pk}'.format(self)
|
|
| 20 |
- |
|
| 21 |
- @property |
|
| 22 |
- def data(self): |
|
| 23 |
- return {
|
|
| 24 |
- 'pk': self.pk, |
|
| 25 |
- 'uuid': self.uuid, |
|
| 26 |
- 'lensman_id': self.lensman_id, |
|
| 27 |
- } |
|
| 28 |
- |
|
| 29 |
- |
|
| 30 |
-class PhotoUUIDInfo(BaseModelMixin): |
|
| 31 |
- photo_md5 = models.CharField(_(u'photo_md5'), max_length=32, blank=True, null=True, help_text=u'照片唯一标识', db_index=True, unique=True) |
|
| 32 |
- |
|
| 33 |
- photo_path = models.CharField(_(u'photo_path'), max_length=32, blank=True, null=True, help_text=u'照片路径') |
|
| 34 |
- photo_w = models.IntegerField(_(u'photo_w'), default=0, help_text=u'照片宽度') |
|
| 35 |
- photo_h = models.IntegerField(_(u'photo_h'), default=0, help_text=u'照片高度') |
|
| 36 |
- |
|
| 37 |
- photo_watermark_path = models.CharField(_(u'photo_watermark_path'), max_length=32, blank=True, null=True, help_text=u'照片存放路径,Box上传,有水印,服务器添加') |
|
| 38 |
- photo_watermark_w = models.IntegerField(_(u'photo_watermark_w'), default=0, help_text=u'照片水印图宽度') |
|
| 39 |
- photo_watermark_h = models.IntegerField(_(u'photo_watermark_h'), default=0, help_text=u'照片水印图高度') |
|
| 40 |
- |
|
| 41 |
- photo_thumbnail_path = models.CharField(_(u'photo_thumbnail_path'), max_length=32, blank=True, null=True, help_text=u'照片缩略图存放路径') |
|
| 42 |
- photo_thumbnail_w = models.IntegerField(_(u'photo_thumbnail_w'), default=0, help_text=u'照片缩略图宽度') |
|
| 43 |
- photo_thumbnail_h = models.IntegerField(_(u'photo_thumbnail_h'), default=0, help_text=u'照片缩略图高度') |
|
| 44 |
- |
|
| 45 |
- photo_thumbnail2_path = models.CharField(_(u'photo_thumbnail2_path'), max_length=32, blank=True, null=True, help_text=u'照片缩略图存放路径') |
|
| 46 |
- photo_thumbnail2_w = models.IntegerField(_(u'photo_thumbnail2_w'), default=0, help_text=u'照片缩略图宽度') |
|
| 47 |
- photo_thumbnail2_h = models.IntegerField(_(u'photo_thumbnail2_h'), default=0, help_text=u'照片缩略图高度') |
|
| 48 |
- |
|
| 49 |
- class Meta: |
|
| 50 |
- verbose_name = _('photouuidinfo')
|
|
| 51 |
- verbose_name_plural = _('photouuidinfo')
|
|
| 52 |
- |
|
| 53 |
- def __unicode__(self): |
|
| 54 |
- return u'{0.pk}'.format(self)
|
|
| 55 |
- |
|
| 56 |
- |
|
| 57 |
-class PhotosInfo(BaseModelMixin): |
|
| 58 |
- lensman_id = models.CharField(_(u'lensman_id'), max_length=32, blank=True, null=True, help_text=u'摄影师唯一标识', db_index=True) |
|
| 59 |
- session_id = models.CharField(_(u'session_id'), max_length=32, blank=True, null=True, help_text=u'照片组唯一标识', db_index=True) |
|
| 60 |
- photo_id = models.CharField(_(u'photo_id'), max_length=32, blank=True, null=True, help_text=u'照片唯一标识', db_index=True) |
|
| 61 |
- p_photo_path = models.CharField(_(u'p_photo_path'), max_length=32, blank=True, null=True, help_text=u'照片存放路径,Box上传,有水印,服务器添加') |
|
| 62 |
- m_photo_path = models.CharField(_(u'm_photo_path'), max_length=32, blank=True, null=True, help_text=u'照片存放路径,Box上传,无水印') |
|
| 63 |
- l_photo_path = models.CharField(_(u'l_photo_path'), max_length=32, blank=True, null=True, help_text=u'照片存放路径,美化大图') |
|
| 64 |
- r_photo_path = models.CharField(_(u'r_photo_path'), max_length=32, blank=True, null=True, help_text=u'照片存放路径,高清大图') |
|
| 65 |
- |
|
| 66 |
- class Meta: |
|
| 67 |
- verbose_name = _('photosinfo')
|
|
| 68 |
- verbose_name_plural = _('photosinfo')
|
|
| 69 |
- |
|
| 70 |
- index_together = [ |
|
| 71 |
- ['lensman_id', 'session_id'], |
|
| 72 |
- ] |
|
| 73 |
- |
|
| 74 |
- unique_together = ( |
|
| 75 |
- ('lensman_id', 'session_id', 'photo_id'),
|
|
| 76 |
- ) |
|
| 77 |
- |
|
| 78 |
- def __unicode__(self): |
|
| 79 |
- return u'{0.pk}'.format(self)
|
|
| 80 |
- |
|
| 81 |
- @property |
|
| 82 |
- def p_photo_url(self): |
|
| 83 |
- return qiniu_file_url(self.p_photo_path, bucket='watermark') |
|
| 84 |
- |
|
| 85 |
- @property |
|
| 86 |
- def m_photo_url(self): |
|
| 87 |
- return qiniu_file_url(self.m_photo_path, bucket='photo') |
|
| 88 |
- |
|
| 89 |
- @property |
|
| 90 |
- def l_photo_url(self): |
|
| 91 |
- return qiniu_file_url(self.l_photo_path, bucket='prettify') |
|
| 92 |
- |
|
| 93 |
- @property |
|
| 94 |
- def r_photo_url(self): |
|
| 95 |
- return qiniu_file_url(self.r_photo_path, bucket='original') |
|
| 96 |
- |
|
| 97 |
- @property |
|
| 98 |
- def data(self): |
|
| 99 |
- return {
|
|
| 100 |
- 'pk': self.pk, |
|
| 101 |
- 'user_id': self.lensman_id, |
|
| 102 |
- 'session_id': self.session_id, |
|
| 103 |
- 'photo_id': self.photo_id, |
|
| 104 |
- } |
|
| 105 |
- |
|
| 106 |
- @property |
|
| 107 |
- def detail(self): |
|
| 108 |
- return {
|
|
| 109 |
- 'pk': self.pk, |
|
| 110 |
- 'user_id': self.lensman_id, |
|
| 111 |
- 'session_id': self.session_id, |
|
| 112 |
- 'photo_id': self.photo_id, |
|
| 113 |
- 'photo_url': self.p_photo_url, |
|
| 114 |
- } |
@@ -1,11 +0,0 @@ |
||
| 1 |
-# -*- coding: utf-8 -*- |
|
| 2 |
- |
|
| 3 |
-from rest_framework import serializers |
|
| 4 |
- |
|
| 5 |
-from photo.models import PhotosInfo |
|
| 6 |
- |
|
| 7 |
- |
|
| 8 |
-class PhotosInfoSerializer(serializers.HyperlinkedModelSerializer): |
|
| 9 |
- class Meta: |
|
| 10 |
- model = PhotosInfo |
|
| 11 |
- fields = ('lensman_id', 'session_id', 'photo_id', 'p_photo_path', 'm_photo_path', 'l_photo_path', 'r_photo_path', 'created_at')
|
@@ -1,61 +0,0 @@ |
||
| 1 |
-{% load staticfiles %}
|
|
| 2 |
- |
|
| 3 |
-<!DOCTYPE html> |
|
| 4 |
-<html lang="zh-CN"> |
|
| 5 |
- <head> |
|
| 6 |
- <meta charset="utf-8"> |
|
| 7 |
- <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> |
|
| 8 |
- <meta name="format-detection" content="telephone=no,email=no,address=no"> |
|
| 9 |
- <meta name="viewport" content="width=device-width,initial-scale=1.0,user-scalable=no"> |
|
| 10 |
- <title>照片详情</title> |
|
| 11 |
- <style> |
|
| 12 |
- body {position:absolute;top:0;right:0;bottom:0;left:0;margin:0;font-family:"Microsoft YaHei","sans-serif","Microsoft Sans Serif","Microsoft JhengHei UI";background:#fff6e6;color:gray}
|
|
| 13 |
- img {width:100%}
|
|
| 14 |
- |
|
| 15 |
- /* For Download Section */ |
|
| 16 |
- .download_section {position:fixed;right:0;bottom:0;left:0;height:55px;padding:5px;background:#f0f0f0;box-sizing:border-box}
|
|
| 17 |
- .kodo_icon {width:45px;height:45px;float:left}
|
|
| 18 |
- .kodo_icon>img {width:100%;height:100%}
|
|
| 19 |
- .kodo_desc {height:45px;padding:5px 0 0 5px;float:left}
|
|
| 20 |
- .kodo_name {padding-top:2px;font-size:14px;text-align:left}
|
|
| 21 |
- .kodo_des {padding-top:2px;font-size:12px;line-height:23px;color:#8f8f8f;text-align:left}
|
|
| 22 |
- .kodo_download {position:relative;top:5px;width:100px;height:35px;line-height:35px;text-align:center;background:#d13621;color:#fff;border-radius:5px;float:right;text-decoration:none}
|
|
| 23 |
- /* For PC */ |
|
| 24 |
- body, .download_section {
|
|
| 25 |
- max-width: 414px !important; |
|
| 26 |
- margin: 0 auto !important; |
|
| 27 |
- } |
|
| 28 |
- </style> |
|
| 29 |
- </head> |
|
| 30 |
- <body> |
|
| 31 |
- <div class="container"> |
|
| 32 |
- <article class="text-center"> |
|
| 33 |
- <img src="{{ photo_url }}">
|
|
| 34 |
- </article> |
|
| 35 |
- </div> |
|
| 36 |
- |
|
| 37 |
- <div id="download_section" class="download_section"> |
|
| 38 |
- <div class="kodo_icon"> |
|
| 39 |
- <img src="{% static 'kodo/img/paiai_96_96.png' %}">
|
|
| 40 |
- </div> |
|
| 41 |
- <div class="kodo_desc"> |
|
| 42 |
- <div class="kodo_name">拍爱</div> |
|
| 43 |
- <div class="kodo_des">即拍即分享</div> |
|
| 44 |
- </div> |
|
| 45 |
- <a href="https://api.pai.ai/op/download" target="_blank" id="kodo_download" class="kodo_download">立即下载</a> |
|
| 46 |
- </div> |
|
| 47 |
- |
|
| 48 |
- <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/zepto/1.1.6/zepto.min.js"></script> |
|
| 49 |
- <script type="text/javascript" src="//res.wx.qq.com/open/js/jweixin-1.2.0.js"></script> |
|
| 50 |
- <script type="text/javascript" src="{% static 'kodo/js/jswe-0.0.4.js' %}"></script>
|
|
| 51 |
- <script> |
|
| 52 |
- V.initWxData({
|
|
| 53 |
- imgUrl: "http://pai.ai/static/kodo/img/paiai_96_96.png", |
|
| 54 |
- link: window.location.href, |
|
| 55 |
- desc: "我使用拍爱分享了一张美图,你也快来试试吧", |
|
| 56 |
- title: "拍爱", |
|
| 57 |
- timeLine: "" |
|
| 58 |
- }, true); |
|
| 59 |
- </script> |
|
| 60 |
- </body> |
|
| 61 |
-</html> |
@@ -1,63 +0,0 @@ |
||
| 1 |
-{% load staticfiles %}
|
|
| 2 |
- |
|
| 3 |
-<!DOCTYPE html> |
|
| 4 |
-<html lang="zh-CN"> |
|
| 5 |
- <head> |
|
| 6 |
- <meta charset="utf-8"> |
|
| 7 |
- <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> |
|
| 8 |
- <meta name="format-detection" content="telephone=no,email=no,address=no"> |
|
| 9 |
- <meta name="viewport" content="width=device-width,initial-scale=1.0,user-scalable=no"> |
|
| 10 |
- <title>照片列表</title> |
|
| 11 |
- <style> |
|
| 12 |
- body {position:absolute;top:0;right:0;bottom:0;left:0;margin:0;font-family:"Microsoft YaHei","sans-serif","Microsoft Sans Serif","Microsoft JhengHei UI";background:#fff6e6;color:gray}
|
|
| 13 |
- img {width:100%}
|
|
| 14 |
- |
|
| 15 |
- /* For Download Section */ |
|
| 16 |
- .download_section {position:fixed;right:0;bottom:0;left:0;height:55px;padding:5px;background:#f0f0f0;box-sizing:border-box}
|
|
| 17 |
- .kodo_icon {width:45px;height:45px;float:left}
|
|
| 18 |
- .kodo_icon>img {width:100%;height:100%}
|
|
| 19 |
- .kodo_desc {height:45px;padding:5px 0 0 5px;float:left}
|
|
| 20 |
- .kodo_name {padding-top:2px;font-size:14px;text-align:left}
|
|
| 21 |
- .kodo_des {padding-top:2px;font-size:12px;line-height:23px;color:#8f8f8f;text-align:left}
|
|
| 22 |
- .kodo_download {position:relative;top:5px;width:100px;height:35px;line-height:35px;text-align:center;background:#d13621;color:#fff;border-radius:5px;float:right;text-decoration:none}
|
|
| 23 |
- /* For PC */ |
|
| 24 |
- body, .download_section {
|
|
| 25 |
- max-width: 414px !important; |
|
| 26 |
- margin: 0 auto !important; |
|
| 27 |
- } |
|
| 28 |
- </style> |
|
| 29 |
- </head> |
|
| 30 |
- <body> |
|
| 31 |
- <div class="container"> |
|
| 32 |
- <article class="text-center"> |
|
| 33 |
- {% for photo in photos %}
|
|
| 34 |
- <div><img src="{{ photo.p_photo_url }}"></div>
|
|
| 35 |
- {% endfor %}
|
|
| 36 |
- </article> |
|
| 37 |
- </div> |
|
| 38 |
- |
|
| 39 |
- <div id="download_section" class="download_section"> |
|
| 40 |
- <div class="kodo_icon"> |
|
| 41 |
- <img src="{% static 'kodo/img/paiai_96_96.png' %}">
|
|
| 42 |
- </div> |
|
| 43 |
- <div class="kodo_desc"> |
|
| 44 |
- <div class="kodo_name">拍爱</div> |
|
| 45 |
- <div class="kodo_des">即拍即分享</div> |
|
| 46 |
- </div> |
|
| 47 |
- <a href="https://api.pai.ai/op/download" target="_blank" id="kodo_download" class="kodo_download">立即下载</a> |
|
| 48 |
- </div> |
|
| 49 |
- |
|
| 50 |
- <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/zepto/1.1.6/zepto.min.js"></script> |
|
| 51 |
- <script type="text/javascript" src="//res.wx.qq.com/open/js/jweixin-1.2.0.js"></script> |
|
| 52 |
- <script type="text/javascript" src="{% static 'kodo/js/jswe-0.0.4.js' %}"></script>
|
|
| 53 |
- <script> |
|
| 54 |
- V.initWxData({
|
|
| 55 |
- imgUrl: "http://pai.ai/static/kodo/img/paiai_96_96.png", |
|
| 56 |
- link: window.location.href, |
|
| 57 |
- desc: "我使用拍爱分享了一张美图,你也快来试试吧", |
|
| 58 |
- title: "拍爱", |
|
| 59 |
- timeLine: "" |
|
| 60 |
- }, true); |
|
| 61 |
- </script> |
|
| 62 |
- </body> |
|
| 63 |
-</html> |
@@ -1,4 +0,0 @@ |
||
| 1 |
-from django.test import TestCase |
|
| 2 |
- |
|
| 3 |
- |
|
| 4 |
-# Create your tests here. |
@@ -1,276 +0,0 @@ |
||
| 1 |
-# -*- coding: utf-8 -*- |
|
| 2 |
- |
|
| 3 |
-from django.db import transaction |
|
| 4 |
-from django.shortcuts import render |
|
| 5 |
-from django_curtail_uuid import CurtailUUID |
|
| 6 |
-from django_logit import logit |
|
| 7 |
-from django_response import response |
|
| 8 |
-from ipaddr import client_ip |
|
| 9 |
-from rest_framework import viewsets |
|
| 10 |
-from TimeConvert import TimeConvert as tc |
|
| 11 |
- |
|
| 12 |
-from account.models import LensmanInfo, UserInfo |
|
| 13 |
-from group.models import GroupInfo, GroupPhotoInfo, GroupUserInfo |
|
| 14 |
-from photo.models import PhotosInfo |
|
| 15 |
-from photo.serializers import PhotosInfoSerializer |
|
| 16 |
-from utils.error.errno_utils import LensmanStatusCode, PhotoStatusCode |
|
| 17 |
-from utils.redis.connect import r |
|
| 18 |
-from utils.redis.rgroup import get_group_info, set_group_info, set_group_users_info |
|
| 19 |
-from utils.redis.rkeys import (GROUP_LAST_PHOTO_PK, GROUP_USERS_DELETED_SET, GROUP_USERS_PASSED_SET, |
|
| 20 |
- GROUP_USERS_QUIT_SET, GROUP_USERS_REFUSED_SET, UUID_LIST) |
|
| 21 |
-from utils.redis.rprice import get_lensman_price_fixed |
|
| 22 |
-from utils.redis.ruuid import generate_uuids, update_uuids |
|
| 23 |
-from utils.storage_qiniu_utils import file_save |
|
| 24 |
- |
|
| 25 |
- |
|
| 26 |
-@logit |
|
| 27 |
-def uuid_init(request): |
|
| 28 |
- """ 生成唯一标识 """ |
|
| 29 |
- num = int(request.GET.get('num', 1000))
|
|
| 30 |
- |
|
| 31 |
- # 生成 UUID |
|
| 32 |
- generate_uuids(num) |
|
| 33 |
- |
|
| 34 |
- return response(200, 'UUID Refresh Success', u'UUID 更新成功') |
|
| 35 |
- |
|
| 36 |
- |
|
| 37 |
-# curl -X POST -F user_id=xxxxxxx -F num=100 http://api.pai.ai/uuid |
|
| 38 |
-@logit |
|
| 39 |
-@transaction.atomic |
|
| 40 |
-def uuid(request): |
|
| 41 |
- """ 获取唯一标识 """ |
|
| 42 |
- lensman_id = request.POST.get('user_id', '')
|
|
| 43 |
- num = int(request.POST.get('num', 100))
|
|
| 44 |
- |
|
| 45 |
- # 从 Redis 中 Pop 中指定数量的 UUID |
|
| 46 |
- uuids, succeed, left = r.multi_pop(UUID_LIST, num) |
|
| 47 |
- |
|
| 48 |
- # # 异步更新 UUID 数据库中状态 |
|
| 49 |
- # if uuids: |
|
| 50 |
- # async(update_uuids, lensman_id, uuids) |
|
| 51 |
- # |
|
| 52 |
- # # 当可用 UUID 数量少于 500 时, 异步创建 |
|
| 53 |
- # if left < 500: |
|
| 54 |
- # async(generate_uuids) |
|
| 55 |
- |
|
| 56 |
- return response(200, 'Get UUID Success', u'获取唯一标识成功', uuids) |
|
| 57 |
- |
|
| 58 |
- |
|
| 59 |
-# [How to do a PUT request with curl?](http://stackoverflow.com/questions/13782198/how-to-do-a-put-request-with-curl) |
|
| 60 |
-# Unfortunately, the -T is no substitute for -X PUT if you want to specify parameters with -d or -F. |
|
| 61 |
-# -T sends the content of a file via PUT. To achieve the GET after a redirect, add the parameter --location |
|
| 62 |
-# |
|
| 63 |
-# -F, --form <name=content> |
|
| 64 |
-# (HTTP) This lets curl emulate a filled-in form in which a user has pressed the submit button. This causes curl to POST data |
|
| 65 |
-# using the Content-Type multipart/form-data according to RFC 2388. This enables uploading of binary files etc. To force the |
|
| 66 |
-# 'content' part to be a file, prefix the file name with an @ sign. To just get the content part from a file, prefix the file |
|
| 67 |
-# name with the symbol <. The difference between @ and < is then that @ makes a file get attached in the post as a file upload, |
|
| 68 |
-# while the < makes a text field and just get the contents for that text field from a file. |
|
| 69 |
-# |
|
| 70 |
-# curl -X POST -F user_id=xxxxxxx -F session_id=xxxxxxx -F photo_id=xxxxxxx -F photo=@xxxxxxx.jpg http://api.pai.ai/photos/upload |
|
| 71 |
-@logit |
|
| 72 |
-def upload_photo(request): |
|
| 73 |
- """ 上传图片 """ |
|
| 74 |
- lensman_id = request.POST.get('user_id', '')
|
|
| 75 |
- session_id = request.POST.get('session_id', '')
|
|
| 76 |
- photo_id = request.POST.get('photo_id', '')
|
|
| 77 |
- |
|
| 78 |
- photo = request.FILES.get('photo', '')
|
|
| 79 |
- |
|
| 80 |
- if not (lensman_id and session_id and photo): |
|
| 81 |
- return response(PhotoStatusCode.PARAMS_ERROR) |
|
| 82 |
- |
|
| 83 |
- try: |
|
| 84 |
- LensmanInfo.objects.get(lensman_id=lensman_id) |
|
| 85 |
- except LensmanInfo.DoesNotExist: |
|
| 86 |
- return response(LensmanStatusCode.LENSMAN_NOT_FOUND) |
|
| 87 |
- |
|
| 88 |
- photo_info = file_save(photo, prefix='photo', ext='.jpeg', watermark=True) |
|
| 89 |
- |
|
| 90 |
- photo, created = PhotosInfo.objects.get_or_create( |
|
| 91 |
- lensman_id=lensman_id, |
|
| 92 |
- session_id=session_id, |
|
| 93 |
- photo_id=photo_id, |
|
| 94 |
- p_photo_path=photo_info.photo_watermark_path, |
|
| 95 |
- m_photo_path=photo_info.photo_path, |
|
| 96 |
- ) |
|
| 97 |
- |
|
| 98 |
- return response(200, 'Photo Upload Success', u'照片上传成功', photo.data) |
|
| 99 |
- |
|
| 100 |
- |
|
| 101 |
-@logit |
|
| 102 |
-@transaction.atomic |
|
| 103 |
-def session_join_api(request): |
|
| 104 |
- """ Session 详情 """ |
|
| 105 |
- user_id = request.POST.get('user_id', '')
|
|
| 106 |
- session_id = request.POST.get('session_id', '')
|
|
| 107 |
- lensman_id = request.POST.get('lensman_id', '')
|
|
| 108 |
- nickname = request.POST.get('nickname', '')
|
|
| 109 |
- current_id = -1 |
|
| 110 |
- |
|
| 111 |
- # 摄影师校验 |
|
| 112 |
- try: |
|
| 113 |
- lensman = UserInfo.objects.get(user_id=lensman_id) |
|
| 114 |
- except UserInfo.DoesNotExist: |
|
| 115 |
- return response(LensmanStatusCode.LENSMAN_NOT_FOUND) |
|
| 116 |
- |
|
| 117 |
- # 判断 user_id 是否存在,如果不存在,则直接分配帐户 |
|
| 118 |
- user, user_created = UserInfo.objects.get_or_create(user_id=user_id, defaults={
|
|
| 119 |
- 'user_id': CurtailUUID.uuid(UserInfo, 'user_id'), |
|
| 120 |
- 'user_status': UserInfo.ASSIGN, |
|
| 121 |
- 'assign_ip': client_ip(request), |
|
| 122 |
- 'assign_at': tc.utc_datetime(), |
|
| 123 |
- }) |
|
| 124 |
- user_id = user.user_id |
|
| 125 |
- |
|
| 126 |
- # 判断通过 session_id 创建的群组是否存在,如果不存在,则直接创建 |
|
| 127 |
- group, group_created = GroupInfo.objects.select_for_update().get_or_create(session_id=session_id, group_from=GroupInfo.SESSION_GROUP, defaults={
|
|
| 128 |
- 'group_id': CurtailUUID.uuid(GroupInfo, 'group_id'), |
|
| 129 |
- # 'admin_id': lensman_id, |
|
| 130 |
- 'group_name': lensman.final_nickname, |
|
| 131 |
- 'group_default_avatar': 0, |
|
| 132 |
- }) |
|
| 133 |
- group_id = group.group_id |
|
| 134 |
- |
|
| 135 |
- # Redis 群组数据缓存 |
|
| 136 |
- group_info = set_group_info(group) if group_created else get_group_info(group_id) |
|
| 137 |
- |
|
| 138 |
- # 判断 group_id/user_id 的群组用户是否存在,如果不存在,则直接创建 |
|
| 139 |
- group_user, group_user_created = GroupUserInfo.objects.get_or_create(group_id=group_id, user_id=user_id, defaults={
|
|
| 140 |
- # 'current_id': int(r.get(GROUP_LAST_PHOTO_PK % group_id) or -1), |
|
| 141 |
- 'current_id': current_id, # 通过扫描 session_id 二维码进群的用户,默认可以查看该群组所有照片 |
|
| 142 |
- 'nickname': nickname or user.final_nickname, |
|
| 143 |
- 'avatar': user.avatar, |
|
| 144 |
- # 'admin': group_created, |
|
| 145 |
- 'user_status': GroupUserInfo.PASSED, |
|
| 146 |
- 'passed_at': tc.utc_datetime(), |
|
| 147 |
- }) |
|
| 148 |
- if not group_user_created: |
|
| 149 |
- group_user.current_id = current_id |
|
| 150 |
- group_user.user_status = GroupUserInfo.PASSED |
|
| 151 |
- group_user.save() |
|
| 152 |
- |
|
| 153 |
- # 管理员处理 |
|
| 154 |
- tobe_admin = not GroupUserInfo.objects.filter(admin=True, status=True).exists() |
|
| 155 |
- if tobe_admin: |
|
| 156 |
- group.admin_id = user_id |
|
| 157 |
- group.save() |
|
| 158 |
- group_user.admin = True |
|
| 159 |
- group_user.save() |
|
| 160 |
- |
|
| 161 |
- # Redis 群组用户数据缓存 |
|
| 162 |
- group_users = set_group_users_info(group) |
|
| 163 |
- |
|
| 164 |
- # Redis 群组通过集合缓存 |
|
| 165 |
- r.srem(GROUP_USERS_REFUSED_SET % group_id, user_id) |
|
| 166 |
- r.srem(GROUP_USERS_DELETED_SET % group_id, user_id) |
|
| 167 |
- r.srem(GROUP_USERS_QUIT_SET % group_id, user_id) |
|
| 168 |
- r.sadd(GROUP_USERS_PASSED_SET % group_id, user_id) |
|
| 169 |
- |
|
| 170 |
- # |
|
| 171 |
- if group_created: |
|
| 172 |
- # 获取 Session 照片 |
|
| 173 |
- photos = PhotosInfo.objects.filter(session_id=session_id, status=True) |
|
| 174 |
- |
|
| 175 |
- # 获取摄影师定价 |
|
| 176 |
- price_info = get_lensman_price_fixed(lensman_id) |
|
| 177 |
- |
|
| 178 |
- group_photo = None |
|
| 179 |
- for photo in photos: |
|
| 180 |
- photo_info = file_save(photo_path=photo.p_photo_path, prefix='photo', ext='.jpeg', thumbnail=True) |
|
| 181 |
- |
|
| 182 |
- # 群组照片记录创建 |
|
| 183 |
- group_photo, created = GroupPhotoInfo.objects.get_or_create( |
|
| 184 |
- group_id=group_id, |
|
| 185 |
- user_id=user_id, |
|
| 186 |
- photo_md5=photo_info.photo_md5, |
|
| 187 |
- defaults={
|
|
| 188 |
- 'nickname': user.final_nickname, |
|
| 189 |
- 'avatar': user.avatar, |
|
| 190 |
- 'photo_path': photo_info.photo_watermark_path, |
|
| 191 |
- 'has_watermark': True, |
|
| 192 |
- 'photo_w': photo_info.photo_w, |
|
| 193 |
- 'photo_h': photo_info.photo_h, |
|
| 194 |
- 'photo_thumbnail_path': photo_info.photo_thumbnail_path, |
|
| 195 |
- 'photo_thumbnail_w': photo_info.photo_thumbnail_w, |
|
| 196 |
- 'photo_thumbnail_h': photo_info.photo_thumbnail_h, |
|
| 197 |
- 'photo_thumbnail2_path': photo_info.photo_thumbnail2_path, |
|
| 198 |
- 'photo_thumbnail2_w': photo_info.photo_thumbnail2_w, |
|
| 199 |
- 'photo_thumbnail2_h': photo_info.photo_thumbnail2_h, |
|
| 200 |
- 'photo_from': GroupPhotoInfo.SESSION_GROUP, |
|
| 201 |
- 'session_id': photo.session_id, |
|
| 202 |
- 'lensman_id': photo.lensman_id, |
|
| 203 |
- 'lensman_photo_id': photo.photo_id, |
|
| 204 |
- 'nomark': price_info.get('nomark', 999),
|
|
| 205 |
- 'origin': price_info.get('origin', 999),
|
|
| 206 |
- } |
|
| 207 |
- ) |
|
| 208 |
- |
|
| 209 |
- if group_photo: |
|
| 210 |
- # 设置群组最后一张照片PK |
|
| 211 |
- r.set(GROUP_LAST_PHOTO_PK % group_id, group_photo.pk) |
|
| 212 |
- |
|
| 213 |
- # Redis 群组数据缓存 |
|
| 214 |
- set_group_info(group) |
|
| 215 |
- |
|
| 216 |
- # 获取从 current_id 到 now 的群组照片列表 |
|
| 217 |
- group_photos = GroupPhotoInfo.objects.filter( |
|
| 218 |
- group_id=group_id, |
|
| 219 |
- status=True, |
|
| 220 |
- pk__gt=group_user.current_id, |
|
| 221 |
- ).order_by( |
|
| 222 |
- '-pk' |
|
| 223 |
- ) |
|
| 224 |
- latest_photo = group_photos.first() |
|
| 225 |
- |
|
| 226 |
- return response(200, 'Apply Join Session Group Success', u'申请加入摄影师群成功', {
|
|
| 227 |
- 'current_id': latest_photo and latest_photo.pk or current_id, |
|
| 228 |
- 'photos': [photo.photo_info(user_id) for photo in group_photos], |
|
| 229 |
- 'group_id': group_id, |
|
| 230 |
- 'group': group_info, |
|
| 231 |
- 'user_id': user_id, |
|
| 232 |
- 'users': group_users, |
|
| 233 |
- }) |
|
| 234 |
- |
|
| 235 |
- |
|
| 236 |
-@logit |
|
| 237 |
-def session_detail(request, session_id): |
|
| 238 |
- photos = PhotosInfo.objects.filter(session_id=session_id, status=True) |
|
| 239 |
- return render(request, 'photo/session_detail.html', {'photos': photos})
|
|
| 240 |
- |
|
| 241 |
- |
|
| 242 |
-@logit |
|
| 243 |
-def photo_standard(request, photo_id): |
|
| 244 |
- photo = PhotosInfo.objects.get(photo_id=photo_id) |
|
| 245 |
- return render(request, 'photo/photo_detail.html', {'photo_url': photo.p_photo_url})
|
|
| 246 |
- |
|
| 247 |
- |
|
| 248 |
-@logit |
|
| 249 |
-def photo_standard_api(request, photo_id): |
|
| 250 |
- photo = PhotosInfo.objects.get(photo_id=photo_id) |
|
| 251 |
- return response(200, 'Get Photo Detail Success', u'获取照片详情成功', {
|
|
| 252 |
- 'photo': photo.detail, |
|
| 253 |
- }) |
|
| 254 |
- |
|
| 255 |
- |
|
| 256 |
-@logit |
|
| 257 |
-def photo_medium(request, photo_id): |
|
| 258 |
- photo = PhotosInfo.objects.get(photo_id=photo_id) |
|
| 259 |
- return render(request, 'photo/photo_detail.html', {'photo_url': photo.m_photo_url})
|
|
| 260 |
- |
|
| 261 |
- |
|
| 262 |
-@logit |
|
| 263 |
-def photo_large(request, photo_id): |
|
| 264 |
- photo = PhotosInfo.objects.get(photo_id=photo_id) |
|
| 265 |
- return render(request, 'photo/photo_detail.html', {'photo_url': photo.l_photo_url})
|
|
| 266 |
- |
|
| 267 |
- |
|
| 268 |
-@logit |
|
| 269 |
-def photo_raw(request, photo_id): |
|
| 270 |
- photo = PhotosInfo.objects.get(photo_id=photo_id) |
|
| 271 |
- return render(request, 'photo/photo_detail.html', {'photo_url': photo.r_photo_url})
|
|
| 272 |
- |
|
| 273 |
- |
|
| 274 |
-class PhotoInfoViewSet(viewsets.ModelViewSet): |
|
| 275 |
- queryset = PhotosInfo.objects.all().order_by('-pk')
|
|
| 276 |
- serializer_class = PhotosInfoSerializer |
@@ -99,33 +99,6 @@ class MarketCodeStatusCode(BaseStatusCode): |
||
| 99 | 99 |
""" 一物一码相关错误码 5050xx """ |
| 100 | 100 |
MARKET_CODE_NOT_FOUND = StatusCodeField(505001, 'Market Code Not Found', description=u'一物一码不存在') |
| 101 | 101 |
|
| 102 |
- |
|
| 103 |
-class LensmanStatusCode(BaseStatusCode): |
|
| 104 |
- """ 摄影师相关错误码 4000xx """ |
|
| 105 |
- LENSMAN_NOT_FOUND = StatusCodeField(400001, 'Lensman Not Found', description=u'摄影师不存在') |
|
| 106 |
- # 密码 |
|
| 107 |
- LENSMAN_PASSWORD_ERROR = StatusCodeField(400002, 'Lensman Password Error', description=u'摄影师密码错误') |
|
| 108 |
- # 手机号 |
|
| 109 |
- LENSMAN_PHONE_ALREADY_EXISTS = StatusCodeField(400005, 'Lensman Phone Already Exists', description=u'手机号已经存在') |
|
| 110 |
- # 状态 |
|
| 111 |
- LENSMAN_ALREADY_NOT_UNVERIFIED = StatusCodeField(400010, 'Lensman Already Not Unverified', description=u'摄影师帐号已激活') |
|
| 112 |
- LENSMAN_NOT_ACTIVATED = StatusCodeField(400015, 'Lensman Not Activated', description=u'摄影师帐号未激活') |
|
| 113 |
- # 类别 |
|
| 114 |
- LENSMAN_TYPE_NOT_EXISTS = StatusCodeField(400020, 'Lensman Type Not Exists', description=u'摄影师类别不存在') |
|
| 115 |
- |
|
| 116 |
- |
|
| 117 |
-class TourGuideStatusCode(BaseStatusCode): |
|
| 118 |
- """ 导游相关错误码 4001xx """ |
|
| 119 |
- TOURGUIDE_NOT_FOUND = StatusCodeField(400101, 'Tour Guide Not Found', description=u'导游不存在') |
|
| 120 |
- # 密码 |
|
| 121 |
- TOURGUIDE_PASSWORD_ERROR = StatusCodeField(400102, 'Tour Guide Password Error', description=u'导游密码错误') |
|
| 122 |
- # 手机号 |
|
| 123 |
- TOURGUIDE_PHONE_ALREADY_EXISTS = StatusCodeField(400105, 'Tour Guide Phone Already Exists', description=u'手机号已经存在') |
|
| 124 |
- # 状态 |
|
| 125 |
- TOURGUIDE_ALREADY_NOT_UNVERIFIED = StatusCodeField(400110, 'Tour Guide Already Not Unverified', description=u'导游帐号已激活') |
|
| 126 |
- TOURGUIDE_NOT_ACTIVATED = StatusCodeField(400115, 'Tour Guide Not Activated', description=u'导游帐号未激活') |
|
| 127 |
- |
|
| 128 |
- |
|
| 129 | 102 |
class AdministratorStatusCode(BaseStatusCode): |
| 130 | 103 |
""" 操作员相关错误码 4002xx """ |
| 131 | 104 |
ADMINISTRATOR_NOT_FOUND = StatusCodeField(400201, 'Administrator Not Found', description=u'管理员不存在') |
@@ -177,86 +150,10 @@ class WechatStatusCode(BaseStatusCode): |
||
| 177 | 150 |
UNIONID_NOT_FOUND = StatusCodeField(400702, 'Unionid Not Found', description=u'微信 UNIONID 不存在') |
| 178 | 151 |
OPENID_NOT_FOUND = StatusCodeField(400703, 'OPENID Not Found', description=u'微信 OPENID 不存在') |
| 179 | 152 |
|
| 180 |
- |
|
| 181 |
-class PhotoStatusCode(BaseStatusCode): |
|
| 182 |
- """ 照片相关错误码 4010xx """ |
|
| 183 |
- PARAMS_ERROR = StatusCodeField(401001, 'Params Error', description=u'参数错误') |
|
| 184 |
- |
|
| 185 |
- |
|
| 186 |
-class GroupStatusCode(BaseStatusCode): |
|
| 187 |
- """ 群组/团相关错误码 4020xx """ |
|
| 188 |
- GROUP_NOT_FOUND = StatusCodeField(402001, 'Group Not Found', description=u'群组不存在') |
|
| 189 |
- GROUP_HAS_LOCKED = StatusCodeField(402002, 'Group Has Locked', description=u'群组已锁定') |
|
| 190 |
- # 管理员 |
|
| 191 |
- NOT_GROUP_ADMIN = StatusCodeField(402010, 'Not Group Admin', description=u'非群组管理员') |
|
| 192 |
- NOT_GROUP_SUBADMIN = StatusCodeField(402011, 'Not Group Sub Admin', description=u'非群组协同管理员') |
|
| 193 |
- ADMIN_CANNOT_HANDLE_SELF = StatusCodeField(402012, 'Admin Cannot Handle Self', description=u'群组管理员无法操作自身') |
|
| 194 |
- # 旅行团 |
|
| 195 |
- ONLY_ONE_ACTIVE_GROUP_ALLOWED = StatusCodeField(402040, 'Only One Active Group Allowed', description=u'只能创建一个活跃团') |
|
| 196 |
- ACTIVE_GROUP_NOT_FOUND = StatusCodeField(402041, 'Active Group Not Found', description=u'活跃团不存在') |
|
| 197 |
- GROUP_HAS_ENDED = StatusCodeField(402042, 'Group Has Ended', description=u'群组已结束') |
|
| 198 |
- # 其他 |
|
| 199 |
- GROUP_PHOTO_NOT_EMPTY = StatusCodeField(402099, 'Group Photo Not Empty', description=u'群组照片不为空') |
|
| 200 |
- |
|
| 201 |
- |
|
| 202 |
-class GroupUserStatusCode(BaseStatusCode): |
|
| 203 |
- """ 群组/团用户相关错误码 4021xx """ |
|
| 204 |
- GROUP_USER_NOT_FOUND = StatusCodeField(402101, 'Group User Not Found', description=u'群组用户不存在') |
|
| 205 |
- GROUP_USER_HAS_DELETED = StatusCodeField(402102, 'Group User Has Deleted', description=u'群组用户被移除') |
|
| 206 |
- # 旅行团 |
|
| 207 |
- USER_HAS_NOT_JOIN_GROUP = StatusCodeField(402131, 'User Has Not Join Group', description=u'用户未加入旅行团') |
|
| 208 |
- |
|
| 209 |
- |
|
| 210 |
-class GroupPhotoStatusCode(BaseStatusCode): |
|
| 211 |
- """ 群组照片(飞图)相关错误码 4022xx """ |
|
| 212 |
- GROUP_PHOTO_NOT_FOUND = StatusCodeField(402201, 'Group Photo Not Found', description=u'飞图不存在') |
|
| 213 |
- # 上传 |
|
| 214 |
- DUPLICATE_UPLOAD = StatusCodeField(402210, 'Duplicate Upload', description=u'重复上传') |
|
| 215 |
- # 点赞 |
|
| 216 |
- THUMB_UP_NOT_FOUND = StatusCodeField(402220, 'Thumb Up Not Found', description=u'未点赞') |
|
| 217 |
- DUPLICATE_THUMB_UP = StatusCodeField(402221, 'Duplicate Thumb Up', description=u'重复点赞') |
|
| 218 |
- # 评论 |
|
| 219 |
- COMMENT_CONTENT_EMPTY = StatusCodeField(402230, 'Comment Content Empty', description=u'评论内容为空') |
|
| 220 |
- |
|
| 221 |
- |
|
| 222 | 153 |
class ScreenStatusCode(BaseStatusCode): |
| 223 | 154 |
""" 群组/团相关错误码 4030xx """ |
| 224 | 155 |
QRCODE_NOT_SCAN = StatusCodeField(403001, 'QRCode Not Scan', description=u'二维码未扫描') |
| 225 | 156 |
|
| 226 |
- |
|
| 227 |
-class OrderStatusCode(BaseStatusCode): |
|
| 228 |
- """ 订单/支付相关错误码 4040xx """ |
|
| 229 |
- WX_UNIFIED_ORDER_FAIL = StatusCodeField(404000, 'WX Unified Order Fail', description=u'微信统一下单失败') |
|
| 230 |
- WX_ORDER_NOT_FOUND = StatusCodeField(404001, 'WX Order Not Found', description=u'订单不存在') |
|
| 231 |
- WX_ORDER_NOT_PAY = StatusCodeField(404002, 'WX Order Not Pay', description=u'订单未支付') |
|
| 232 |
- WX_ORDER_PAYING = StatusCodeField(404003, 'WX Order Paying', description=u'订单支付中') |
|
| 233 |
- WX_ORDER_PAY_FAIL = StatusCodeField(404009, 'WX Order Pay Fail', description=u'微信支付失败') |
|
| 234 |
- SIGN_CHECK_FAIL = StatusCodeField(404010, 'Sign Check Fail', description=u'签名校验失败') |
|
| 235 |
- FEE_CHECK_FAIL = StatusCodeField(404011, 'FEE Check Fail', description=u'金额校验失败') |
|
| 236 |
- NO_DETAIL_PERMISSION = StatusCodeField(404015, 'No Detail Permission', description=u'无详情权限') |
|
| 237 |
- WX_ORDER_PAID_ALREADY_EXISTS = StatusCodeField(404020, 'WX Order Paid Already Exists', description=u'照片已购买') |
|
| 238 |
- |
|
| 239 |
- |
|
| 240 |
-class PayStatusCode(BaseStatusCode): |
|
| 241 |
- """ 支付相关错误码 4041xx """ |
|
| 242 |
- |
|
| 243 |
- |
|
| 244 |
-class WithdrawStatusCode(BaseStatusCode): |
|
| 245 |
- """ 提现相关错误码 4042xx """ |
|
| 246 |
- BALANCE_NOT_ENOUGH = StatusCodeField(404200, 'Balance Not Enough', description=u'提现金额不足') |
|
| 247 |
- |
|
| 248 |
- |
|
| 249 |
-class MessageStatusCode(BaseStatusCode): |
|
| 250 |
- """ 消息相关错误码 4090xx """ |
|
| 251 |
- MESSAGE_NOT_FOUND = StatusCodeField(409001, 'Message Not Found', description=u'消息不存在') |
|
| 252 |
- |
|
| 253 |
- |
|
| 254 |
-class TokenStatusCode(BaseStatusCode): |
|
| 255 |
- """ 票据相关错误码 4090xx """ |
|
| 256 |
- TOKEN_NOT_FOUND = StatusCodeField(409901, 'Token Not Found', description=u'票据不存在') |
|
| 257 |
- TOKEN_HAS_EXPIRED = StatusCodeField(409911, 'Token Has Expired', description=u'票据过期,请刷新重扫二维码') |
|
| 258 |
- |
|
| 259 |
- |
|
| 260 | 157 |
class PermissionStatusCode(BaseStatusCode): |
| 261 | 158 |
""" 4099xx 权限相关错误码 """ |
| 262 | 159 |
PERMISSION_DENIED = StatusCodeField(409900, 'Permission Denied', description=u'权限不足') |
@@ -1,22 +0,0 @@ |
||
| 1 |
-# -*- coding: utf-8 -*- |
|
| 2 |
- |
|
| 3 |
-from isoweek import Week |
|
| 4 |
-from TimeConvert import TimeConvert as tc |
|
| 5 |
- |
|
| 6 |
-from utils.redis.connect import r |
|
| 7 |
-from utils.redis.rkeys import TODAY_INCOME, TOTAL_INCOME, WEEK_INCOME, WEEK_SOLD |
|
| 8 |
- |
|
| 9 |
- |
|
| 10 |
-def set_brief_info(uid, ptype, fee, dt=None): |
|
| 11 |
- """ 更新简报信息 """ |
|
| 12 |
- ymd, week = (tc.local_string(utc_dt=dt, format='%Y%m%d'), Week.withdate(dt)) if dt else (tc.local_string(format='%Y%m%d'), Week.thisweek().isoformat()) |
|
| 13 |
- |
|
| 14 |
- # 总收入 |
|
| 15 |
- r.incr(TOTAL_INCOME % (uid, ptype), fee) |
|
| 16 |
- # 周收入 |
|
| 17 |
- r.incr(WEEK_INCOME % (uid, ptype, week), fee) |
|
| 18 |
- # 日收入 |
|
| 19 |
- r.incr(TODAY_INCOME % (uid, ptype, ymd), fee) |
|
| 20 |
- |
|
| 21 |
- # 周售出 |
|
| 22 |
- r.incr(WEEK_SOLD % (uid, ptype, week)) |
@@ -1,58 +0,0 @@ |
||
| 1 |
-# -*- coding: utf-8 -*- |
|
| 2 |
- |
|
| 3 |
-from group.models import GroupInfo, GroupPhotoInfo, GroupUserInfo, PhotoCommentInfo, PhotoThumbUpInfo |
|
| 4 |
-from utils.redis.connect import r |
|
| 5 |
-from utils.redis.rgroup import set_group_photo_data, set_group_users_info |
|
| 6 |
-from utils.redis.rkeys import (GROUP_LAST_PHOTO_PK, GROUP_PHOTO_WATCHER_SET, GROUP_USERS_APPLYING_SET, |
|
| 7 |
- GROUP_USERS_DELETED_SET, GROUP_USERS_PASSED_SET, GROUP_USERS_REFUSED_SET) |
|
| 8 |
- |
|
| 9 |
- |
|
| 10 |
-def retrieve_group_data(): |
|
| 11 |
- """ 群组数据 """ |
|
| 12 |
- groups = GroupInfo.objects.filter(status=True) |
|
| 13 |
- for group in groups: |
|
| 14 |
- # 群组照片 |
|
| 15 |
- set_group_photo_data(group.group_id) |
|
| 16 |
- # 群组用户 |
|
| 17 |
- set_group_users_info(group) |
|
| 18 |
- |
|
| 19 |
- |
|
| 20 |
-def retrieve_last_pk(): |
|
| 21 |
- """ 群组最后一张照片PK """ |
|
| 22 |
- groups = GroupInfo.objects.filter(status=True) |
|
| 23 |
- for group in groups: |
|
| 24 |
- group_photo = GroupPhotoInfo.objects.filter(group_id=group.group_id, status=True).last() |
|
| 25 |
- r.set(GROUP_LAST_PHOTO_PK % group.group_id, group_photo and group_photo.pk or -1) |
|
| 26 |
- |
|
| 27 |
- |
|
| 28 |
-def retrieve_group_user_status(): |
|
| 29 |
- """ 群组用户状态 """ |
|
| 30 |
- group_users = GroupUserInfo.objects.filter(status=True) |
|
| 31 |
- for group_user in group_users: |
|
| 32 |
- group_id, user_id = group_user.group_id, group_user.user_id |
|
| 33 |
- if group_user.user_status == GroupUserInfo.PASSED: |
|
| 34 |
- r.sadd(GROUP_USERS_PASSED_SET % group_id, user_id) |
|
| 35 |
- elif group_user.user_status == GroupUserInfo.DELETED: |
|
| 36 |
- r.sadd(GROUP_USERS_DELETED_SET % group_id, user_id) |
|
| 37 |
- elif group_user.user_status == GroupUserInfo.APPLYING: |
|
| 38 |
- r.sadd(GROUP_USERS_APPLYING_SET % group_id, user_id) |
|
| 39 |
- elif group_user.user_status == GroupUserInfo.REFUSED: |
|
| 40 |
- r.sadd(GROUP_USERS_REFUSED_SET % group_id, user_id) |
|
| 41 |
- |
|
| 42 |
- |
|
| 43 |
-def retrieve_group_photo_watchers(): |
|
| 44 |
- group_photos = GroupPhotoInfo.objects.filter(status=True) |
|
| 45 |
- for group_photo in group_photos: |
|
| 46 |
- photo_comments = PhotoCommentInfo.objects.filter(photo_id=group_photo.photo_id, status=True) |
|
| 47 |
- for photo_comment in photo_comments: |
|
| 48 |
- r.sadd(GROUP_PHOTO_WATCHER_SET % group_photo.pk, photo_comment.user_id) |
|
| 49 |
- photo_thumbups = PhotoThumbUpInfo.objects.filter(photo_id=group_photo.photo_id, status=True) |
|
| 50 |
- for photo_thumbup in photo_thumbups: |
|
| 51 |
- r.sadd(GROUP_PHOTO_WATCHER_SET % group_photo.pk, photo_thumbup.user_id) |
|
| 52 |
- |
|
| 53 |
- |
|
| 54 |
-def retrieve_redis_data(): |
|
| 55 |
- retrieve_group_data() |
|
| 56 |
- retrieve_last_pk() |
|
| 57 |
- retrieve_group_user_status() |
|
| 58 |
- retrieve_group_photo_watchers() |
@@ -1,147 +0,0 @@ |
||
| 1 |
-# -*- coding: utf-8 -*- |
|
| 2 |
- |
|
| 3 |
-from django.core.serializers.json import DjangoJSONEncoder |
|
| 4 |
- |
|
| 5 |
-from utils.redis.connect import r |
|
| 6 |
-from utils.redis.rkeys import (GROUP_INFO, GROUP_PHOTO_COMMENT_LIST, GROUP_PHOTO_DATA, GROUP_PHOTO_THUMB_UP, |
|
| 7 |
- GROUP_PHOTO_THUMB_UP_LIST, GROUP_PHOTO_WATCHER_SET, GROUP_USERS_INFO, |
|
| 8 |
- GROUP_USERS_KV_INFO) |
|
| 9 |
- |
|
| 10 |
- |
|
| 11 |
-def set_group_info(group): |
|
| 12 |
- """ 设置群组信息 """ |
|
| 13 |
- r.setexjson(GROUP_INFO % group.group_id, r.REDIS_EXPIRED_ONE_MONTH, group.data, cls=DjangoJSONEncoder) |
|
| 14 |
- return group.data |
|
| 15 |
- |
|
| 16 |
- |
|
| 17 |
-def set_group_info_by_id(group_id): |
|
| 18 |
- """ 设置群组信息 """ |
|
| 19 |
- from group.models import GroupInfo |
|
| 20 |
- try: |
|
| 21 |
- group = GroupInfo.objects.get(group_id=group_id) |
|
| 22 |
- except GroupInfo.DoesNotExist: |
|
| 23 |
- return {}
|
|
| 24 |
- return set_group_info(group) |
|
| 25 |
- |
|
| 26 |
- |
|
| 27 |
-def get_group_info(group_id): |
|
| 28 |
- """ 获取群组信息 """ |
|
| 29 |
- return r.getjson(GROUP_INFO % group_id) or set_group_info_by_id(group_id) |
|
| 30 |
- |
|
| 31 |
- |
|
| 32 |
-# 群组用户信息相关 |
|
| 33 |
- |
|
| 34 |
- |
|
| 35 |
-def set_group_users_info(group): |
|
| 36 |
- """ 设置群组用户信息 """ |
|
| 37 |
- group_users = group.users(admin=False) |
|
| 38 |
- |
|
| 39 |
- group_users_data = {
|
|
| 40 |
- 'group_users': group_users, |
|
| 41 |
- 'admin_id': group.admin_id, |
|
| 42 |
- } |
|
| 43 |
- r.setexjson(GROUP_USERS_INFO % group.group_id, r.REDIS_EXPIRED_ONE_MONTH, group_users_data, cls=DjangoJSONEncoder) |
|
| 44 |
- |
|
| 45 |
- group_users_kv_data = {user_info.get('user_id', ''): user_info for user_info in group_users.get('passed', [])}
|
|
| 46 |
- r.setexjson(GROUP_USERS_KV_INFO % group.group_id, r.REDIS_EXPIRED_ONE_MONTH, group_users_kv_data, cls=DjangoJSONEncoder) |
|
| 47 |
- |
|
| 48 |
- return group_users_data, group_users_kv_data |
|
| 49 |
- |
|
| 50 |
- |
|
| 51 |
-def set_group_users_info_by_id(group_id): |
|
| 52 |
- """ 设置群组用户信息 """ |
|
| 53 |
- from group.models import GroupInfo |
|
| 54 |
- try: |
|
| 55 |
- group = GroupInfo.objects.get(group_id=group_id) |
|
| 56 |
- except GroupInfo.DoesNotExist: |
|
| 57 |
- return {}, {}
|
|
| 58 |
- return set_group_users_info(group) |
|
| 59 |
- |
|
| 60 |
- |
|
| 61 |
-def get_group_users_info(group_id, user_id): |
|
| 62 |
- """ 获取群组用户信息 """ |
|
| 63 |
- group_users_data = r.getjson(GROUP_USERS_INFO % group_id) or set_group_users_info_by_id(group_id)[0] |
|
| 64 |
- group_users, admin_id = group_users_data.get('group_users', {}), group_users_data.get('admin_id', '')
|
|
| 65 |
- if group_users and user_id != admin_id: |
|
| 66 |
- [group_users.pop(k) for k in ['applying_count', 'applying']] |
|
| 67 |
- return group_users |
|
| 68 |
- |
|
| 69 |
- |
|
| 70 |
-def get_group_users_kv_info(group_id): |
|
| 71 |
- """ 获取群组用户信息 """ |
|
| 72 |
- return r.getjson(GROUP_USERS_KV_INFO % group_id) or set_group_users_info_by_id(group_id)[1] |
|
| 73 |
- |
|
| 74 |
- |
|
| 75 |
-# 群组照片相关 |
|
| 76 |
- |
|
| 77 |
- |
|
| 78 |
-def set_group_photo_data(group_id): |
|
| 79 |
- """ 设置群组照片数据信息 """ |
|
| 80 |
- from group.models import GroupPhotoInfo |
|
| 81 |
- group_photos = GroupPhotoInfo.objects.filter(group_id=group_id, status=True) |
|
| 82 |
- group_photos = [photo.photo_data for photo in group_photos] |
|
| 83 |
- r.setjson(GROUP_PHOTO_DATA % group_id, group_photos) |
|
| 84 |
- return group_photos |
|
| 85 |
- |
|
| 86 |
- |
|
| 87 |
-def get_group_photo_data(group_id): |
|
| 88 |
- """ 获取群组照片数据信息 """ |
|
| 89 |
- return r.getjson(GROUP_PHOTO_DATA % group_id, default='[]') or set_group_photo_data(group_id) |
|
| 90 |
- |
|
| 91 |
- |
|
| 92 |
-def set_group_photo_thumbup_flag(photo_id, user_id): |
|
| 93 |
- """ 设置群组照片用户点赞标识信息 """ |
|
| 94 |
- r.setex(GROUP_PHOTO_THUMB_UP % (photo_id, user_id), r.REDIS_EXPIRED_ONE_MONTH, True) |
|
| 95 |
- |
|
| 96 |
- |
|
| 97 |
-def del_group_photo_thumbup_flag(photo_id, user_id): |
|
| 98 |
- """ 删除群组照片用户点赞标识信息 """ |
|
| 99 |
- r.delete(GROUP_PHOTO_THUMB_UP % (photo_id, user_id)) |
|
| 100 |
- |
|
| 101 |
- |
|
| 102 |
-def get_group_photo_thumbup_flag(photo_id, user_id): |
|
| 103 |
- """ 获取群组照片用户点赞标识信息 """ |
|
| 104 |
- if r.exists(GROUP_PHOTO_THUMB_UP % (photo_id, user_id)): |
|
| 105 |
- return True |
|
| 106 |
- |
|
| 107 |
- from group.models import PhotoThumbUpInfo |
|
| 108 |
- if PhotoThumbUpInfo.objects.filter(photo_id=photo_id, user_id=user_id, thumbup=True, status=True).exists(): |
|
| 109 |
- set_group_photo_thumbup_flag(photo_id, user_id) |
|
| 110 |
- return True |
|
| 111 |
- |
|
| 112 |
- return False |
|
| 113 |
- |
|
| 114 |
- |
|
| 115 |
-def set_group_photo_comment_list(photo_id): |
|
| 116 |
- """ 设置群组照片用户评论列表 """ |
|
| 117 |
- from group.models import PhotoCommentInfo |
|
| 118 |
- photo_comments = PhotoCommentInfo.objects.filter(photo_id=photo_id, status=True) |
|
| 119 |
- photo_comments = [comment.comment_info for comment in photo_comments] |
|
| 120 |
- r.setjson(GROUP_PHOTO_COMMENT_LIST % photo_id, photo_comments, cls=DjangoJSONEncoder) |
|
| 121 |
- return photo_comments |
|
| 122 |
- |
|
| 123 |
- |
|
| 124 |
-def get_group_photo_comment_list(photo_id): |
|
| 125 |
- """ 获取群组照片用户评论列表 """ |
|
| 126 |
- return r.getjson(GROUP_PHOTO_COMMENT_LIST % photo_id, default='[]') or set_group_photo_comment_list(photo_id) |
|
| 127 |
- |
|
| 128 |
- |
|
| 129 |
-def set_group_photo_thumbup_list(photo_id): |
|
| 130 |
- """ 设置群组照片用户点赞列表 """ |
|
| 131 |
- from group.models import PhotoThumbUpInfo |
|
| 132 |
- photo_thumbups = PhotoThumbUpInfo.objects.filter(photo_id=photo_id, thumbup=True, status=True) |
|
| 133 |
- photo_thumbups = [thumbup.thumbup_info for thumbup in photo_thumbups] |
|
| 134 |
- r.setjson(GROUP_PHOTO_THUMB_UP_LIST % photo_id, photo_thumbups, cls=DjangoJSONEncoder) |
|
| 135 |
- return photo_thumbups |
|
| 136 |
- |
|
| 137 |
- |
|
| 138 |
-def get_group_photo_thumbup_list(photo_id): |
|
| 139 |
- """ 获取群组照片用户点赞列表 """ |
|
| 140 |
- return r.getjson(GROUP_PHOTO_THUMB_UP_LIST % photo_id, default='[]') or set_group_photo_thumbup_list(photo_id) |
|
| 141 |
- |
|
| 142 |
- |
|
| 143 |
-def get_group_photo_watchers(photo_id, discarders=None): |
|
| 144 |
- """ 获取群组照片用户关注列表 """ |
|
| 145 |
- watchers = r.smembers(GROUP_PHOTO_WATCHER_SET % photo_id) |
|
| 146 |
- [watchers.discard(elem) for elem in discarders or []] |
|
| 147 |
- return watchers |
@@ -1,20 +0,0 @@ |
||
| 1 |
-# -*- coding: utf-8 -*- |
|
| 2 |
- |
|
| 3 |
-from utils.redis.connect import r |
|
| 4 |
-from utils.redis.rkeys import GUEST_ENTRANCE_CONTROL_INFO |
|
| 5 |
- |
|
| 6 |
- |
|
| 7 |
-def set_guest_entrance_control(gen): |
|
| 8 |
- """ 设置游客入口控制 """ |
|
| 9 |
- r.setjson(GUEST_ENTRANCE_CONTROL_INFO % gen.src, gen.data) |
|
| 10 |
- return gen.data |
|
| 11 |
- |
|
| 12 |
- |
|
| 13 |
-def get_guest_entrance_control(src=0): |
|
| 14 |
- """ 获取游客入口控制 """ |
|
| 15 |
- return r.getjson(GUEST_ENTRANCE_CONTROL_INFO % src) |
|
| 16 |
- |
|
| 17 |
- |
|
| 18 |
-def delete_guest_entrance_control(src=0): |
|
| 19 |
- """ 删除游客入口控制 """ |
|
| 20 |
- return r.delete(GUEST_ENTRANCE_CONTROL_INFO % src) |
@@ -1,71 +1,12 @@ |
||
| 1 |
-# -*- coding: utf-8 -*- |
|
| 2 |
- |
|
| 3 |
-# 唯一标识相关 |
|
| 4 |
-UUID_LIST = 'uuid:list' # List,唯一标识列表 |
|
| 5 |
- |
|
| 6 |
-# 用户相关 |
|
| 7 |
-PROFILE_INFO = 'profile:info:%s' # STRING,用户信息,user_id |
|
| 8 |
- |
|
| 9 |
-# 导游相关 |
|
| 10 |
-TOUR_GUIDE_GROUP_GEO_INFO = 'tour:guide:group:geo:info:%s' # ZSET,旅游团地理位置信息,group_id |
|
| 11 |
-TOUR_GUIDE_GROUP_GEO_SUBMIT_DT = 'tour:guide:group:geo:submit:dt:%s' # ZSET,旅游团地理位置最后上传时间,group_id |
|
| 12 |
-TOUR_GUIDE_GROUP_CUR_SESSION = 'tour:guide:group:cur:session:%s' # STRING,旅游团当前Session,group_id,导游设置集合时间的时候更新 |
|
| 13 |
-TOUR_GUIDE_GROUP_CUR_GATHER_INFO = 'tour:guide:group:cur:gather:info:%s' # STRING,旅游团当前Session,group_id,导游设置集合时间的时候更新 |
|
| 14 |
-TOUR_GUIDE_GROUP_USER_GEO_LIST = 'tour:guide:group:user:geo:list:%s:%s:%s' # LIST,旅游团当前用户地理位置列表,group_id、session_id、user_id |
|
| 15 |
- |
|
| 16 |
-TOUR_GUIDE_GROUP_USER_OWN = 'tour:guide:group:user:own:%s' # STRING,导游当前拥有的旅行团,user_id,导游创建旅行团的时候更新 |
|
| 17 |
-TOUR_GUIDE_GROUP_USER_BELONG = 'tour:guide:group:user:belong:%s' # STRING,用户当前所属旅行团,user_id,用户加入旅行团的时候更新 |
|
| 18 |
- |
|
| 19 |
-# 群组相关 |
|
| 20 |
-GROUP_INFO = 'group:info:%s' # STRING,群组信息,group_id |
|
| 21 |
- |
|
| 22 |
-# 群组用户相关 |
|
| 23 |
-GROUP_USERS_INFO = 'group:users:info:%s' # STRING,群组用户信息,group_id |
|
| 24 |
-GROUP_USERS_KV_INFO = 'group:users:kv:info:%s' # STRING,群组用户信息,group_id |
|
| 25 |
-GROUP_USERS_APPLYING_SET = 'group:users:applying:set:%s' # SET,群组用户申请集合,group_id |
|
| 26 |
-GROUP_USERS_PASSED_SET = 'group:users:passed:set:%s' # SET,群组用户通过集合,group_id |
|
| 27 |
-GROUP_USERS_REFUSED_SET = 'group:users:refused:set:%s' # SET,群组用户拒绝集合,group_id |
|
| 28 |
-GROUP_USERS_DELETED_SET = 'group:users:deleted:set:%s' # SET,群组用户移除集合,group_id |
|
| 29 |
-GROUP_USERS_QUIT_SET = 'group:users:quit:set:%s' # SET,群组用户退出集合,group_id |
|
| 30 |
- |
|
| 31 |
-# 群组照片相关 |
|
| 32 |
-GROUP_PHOTO_DATA = 'group:photo:data:%s' # STRING,群组数据记录,group_id |
|
| 33 |
-GROUP_PHOTO_THUMB_UP = 'group:photo:thumb:up:%s:%s' # STRING,群组照片用户点赞记录,photo_id、user_id |
|
| 34 |
-GROUP_PHOTO_COMMENT_LIST = 'group:photo:comment:list:%s' # STRING,群组照片用户评论列表,photo_id |
|
| 35 |
-GROUP_PHOTO_THUMB_UP_LIST = 'group:photo:thumb:up:list:%s' # STRING,群组照片用户点赞列表,photo_id |
|
| 36 |
-GROUP_PHOTO_WATCHER_SET = 'group:photo:watcher:set:%s' # SET,群组照片用户关注集合,photo_id,关注即评论点赞 |
|
| 37 |
-GROUP_LAST_PHOTO_PK = 'group:last:photo:pk:%s' # STRING,群组最后一张照片PK,group_id |
|
| 38 |
- |
|
| 39 |
-# 摄影师照片相关 |
|
| 40 |
-LENSMAN_PHOTO_ORDER_RECORD = 'lensman:photo:order:record:%s:%s' # STRING,摄影师照片购买记录,photo_id、user_id |
|
| 41 |
- |
|
| 42 |
-# 摄影师简报相关 |
|
| 43 |
-# 收入 |
|
| 44 |
-TOTAL_INCOME = 'total:income:%s:%s' # STRING,总收入,user_id、photo_type |
|
| 45 |
-WEEK_INCOME = 'week:income:%s:%s:%s' # STRING,周收入,user_id、photo_type、Week.thisweek().isoformat() |
|
| 46 |
-TODAY_INCOME = 'today:income:%s:%s:%s' # STRING,日收入,user_id、photo_type、tc.local_string(format='%Y%m%d') |
|
| 47 |
-# 上传 |
|
| 48 |
-TODAY_UPLOAD_PHOTO_AMOUNT = 'today:upload:photo:amount:%s:%s' # STRING,日上传照片数量,user_id、tc.local_string(format='%Y%m%d') |
|
| 49 |
-# 售出 |
|
| 50 |
-WEEK_SOLD = 'week:sold:%s:%s:%s' # STRING,周售出,user_id、photo_type、Week.thisweek().isoformat() |
|
| 51 |
- |
|
| 52 |
-# 摄影师定价相关 |
|
| 53 |
-LENSMAN_PHOTO_PRICE_FIXED = 'lensman:photo:price:fixed:%s' # STRING,摄影师照片定价(单位:分),user_id |
|
| 54 |
- |
|
| 55 |
-# 系统消息相关 |
|
| 56 |
-SYSTEM_MESSAGE_READ_INFO = 'system:message:read:info:%s' # STRING,系统消息读取信息,user_id |
|
| 57 |
-SYSTEM_MESSAGE_DELETED_INFO = 'system:message:deleted:info:%s' # STRING,系统消息删除信息,user_id |
|
| 58 |
- |
|
| 59 |
-# 游客入口相关 |
|
| 60 |
-GUEST_ENTRANCE_CONTROL_INFO = 'guest:entrance:control:info:%s' # STRING,游客入口控制信息,src |
|
| 1 |
+# -*- coding: utf-8 -*-' |
|
| 61 | 2 |
|
| 62 | 3 |
# APP 相关 |
| 63 | 4 |
LATEST_APP_INFO = 'latest:app:info:%s' # STRING,最新 APP 信息,src |
| 64 | 5 |
APP_SETTINGS_INFO = 'app:settings:info:%s:%s:%s' # STRING,APP 设置信息,platform、channel、version |
| 65 | 6 |
APP_PATCH_INFO = 'app:patch:info:%s:%s:%s' # STRING,APP 补丁信息,platform、version、src |
| 66 | 7 |
|
| 67 |
-# BOX 相关 |
|
| 68 |
-BOX_PROGRAM_VERSION_INFO = 'box:program:version:info' # STRING,BOX 程序版本信息 |
|
| 8 |
+# 用户相关 |
|
| 9 |
+PROFILE_INFO = 'profile:info:%s' # STRING,用户信息,user_id |
|
| 69 | 10 |
|
| 70 | 11 |
# 小程序相关 |
| 71 | 12 |
MINI_PROGRAM_GIS_LIST = 'tamron:miniprogram:gis:list' |
@@ -1,32 +0,0 @@ |
||
| 1 |
-# -*- coding: utf-8 -*- |
|
| 2 |
- |
|
| 3 |
-from utils.redis.connect import r |
|
| 4 |
-from utils.redis.rkeys import SYSTEM_MESSAGE_DELETED_INFO, SYSTEM_MESSAGE_READ_INFO |
|
| 5 |
- |
|
| 6 |
- |
|
| 7 |
-def set_system_message_read_info(user_id): |
|
| 8 |
- """ 设置系统消息读取信息 """ |
|
| 9 |
- from message.models import SystemMessageReadInfo |
|
| 10 |
- read_messages = SystemMessageReadInfo.objects.filter(user_id=user_id, status=True) |
|
| 11 |
- read_message_ids = [msg.msg_id for msg in read_messages] |
|
| 12 |
- r.setexjson(SYSTEM_MESSAGE_READ_INFO % user_id, r.REDIS_EXPIRED_ONE_MONTH, read_message_ids) |
|
| 13 |
- return read_message_ids |
|
| 14 |
- |
|
| 15 |
- |
|
| 16 |
-def get_system_message_read_info(user_id): |
|
| 17 |
- """ 获取系统消息读取信息 """ |
|
| 18 |
- return r.getjson(SYSTEM_MESSAGE_READ_INFO % user_id, default='[]') or set_system_message_read_info(user_id) |
|
| 19 |
- |
|
| 20 |
- |
|
| 21 |
-def set_system_message_delete_info(user_id): |
|
| 22 |
- """ 设置系统消息删除信息 """ |
|
| 23 |
- from message.models import SystemMessageDeleteInfo |
|
| 24 |
- deleted_messages = SystemMessageDeleteInfo.objects.filter(user_id=user_id, status=True) |
|
| 25 |
- deleted_message_ids = [msg.msg_id for msg in deleted_messages] |
|
| 26 |
- r.setexjson(SYSTEM_MESSAGE_DELETED_INFO % user_id, r.REDIS_EXPIRED_ONE_MONTH, deleted_message_ids) |
|
| 27 |
- return deleted_message_ids |
|
| 28 |
- |
|
| 29 |
- |
|
| 30 |
-def get_system_message_delete_info(user_id): |
|
| 31 |
- """ 获取系统消息删除信息 """ |
|
| 32 |
- return r.getjson(SYSTEM_MESSAGE_DELETED_INFO % user_id, default='[]') or set_system_message_delete_info(user_id) |
@@ -1,20 +0,0 @@ |
||
| 1 |
-# -*- coding: utf-8 -*- |
|
| 2 |
- |
|
| 3 |
-from utils.redis.connect import r |
|
| 4 |
-from utils.redis.rkeys import BOX_PROGRAM_VERSION_INFO |
|
| 5 |
- |
|
| 6 |
- |
|
| 7 |
-def set_box_program_version(): |
|
| 8 |
- """ 设置 BOX 程序版本信息 """ |
|
| 9 |
- from operation.models import BoxProgramVersionInfo |
|
| 10 |
- try: |
|
| 11 |
- bpverion = BoxProgramVersionInfo.objects.filter(status=True)[0].data |
|
| 12 |
- except IndexError: |
|
| 13 |
- bpverion = {}
|
|
| 14 |
- r.setjson(BOX_PROGRAM_VERSION_INFO, bpverion) |
|
| 15 |
- return bpverion |
|
| 16 |
- |
|
| 17 |
- |
|
| 18 |
-def get_box_program_version(): |
|
| 19 |
- """ 获取 BOX 程序版本信息 """ |
|
| 20 |
- return r.getjson(BOX_PROGRAM_VERSION_INFO) or set_box_program_version() |
@@ -1,27 +0,0 @@ |
||
| 1 |
-# -*- coding: utf-8 -*- |
|
| 2 |
- |
|
| 3 |
-from django.core.serializers.json import DjangoJSONEncoder |
|
| 4 |
- |
|
| 5 |
-from utils.redis.connect import r |
|
| 6 |
-from utils.redis.rkeys import LENSMAN_PHOTO_ORDER_RECORD |
|
| 7 |
- |
|
| 8 |
- |
|
| 9 |
-def set_lensman_order_record(porder): |
|
| 10 |
- """ 设置摄影师照片购买记录 """ |
|
| 11 |
- r.setexjson(LENSMAN_PHOTO_ORDER_RECORD % (porder.photo_id, porder.user_id), r.REDIS_EXPIRED_ONE_MONTH, porder.porder_info, cls=DjangoJSONEncoder) |
|
| 12 |
- return porder.porder_info |
|
| 13 |
- |
|
| 14 |
- |
|
| 15 |
-def set_lensman_order_record_by_id(photo_id, user_id): |
|
| 16 |
- """ 设置摄影师照片购买记录 """ |
|
| 17 |
- from group.models import GroupPhotoOrderInfo |
|
| 18 |
- try: |
|
| 19 |
- porder = GroupPhotoOrderInfo.objects.get(photo_id=photo_id, user_id=user_id) |
|
| 20 |
- except GroupPhotoOrderInfo.DoesNotExist: |
|
| 21 |
- return {}
|
|
| 22 |
- return set_lensman_order_record(porder) |
|
| 23 |
- |
|
| 24 |
- |
|
| 25 |
-def get_lensman_order_record(photo_id, user_id): |
|
| 26 |
- """ 获取摄影师照片购买记录 """ |
|
| 27 |
- return r.getjson(LENSMAN_PHOTO_ORDER_RECORD % (photo_id, user_id)) or set_lensman_order_record_by_id(photo_id, user_id) |
@@ -1,27 +0,0 @@ |
||
| 1 |
-# -*- coding: utf-8 -*- |
|
| 2 |
- |
|
| 3 |
-from utils.redis.connect import r |
|
| 4 |
-from utils.redis.rkeys import LENSMAN_PHOTO_PRICE_FIXED |
|
| 5 |
- |
|
| 6 |
- |
|
| 7 |
-def set_lensman_price_fixed(user_id): |
|
| 8 |
- """ 设置摄影师价格设定 """ |
|
| 9 |
- from account.models import LensmanInfo |
|
| 10 |
- try: |
|
| 11 |
- lensman = LensmanInfo.objects.get(lensman_id=user_id) |
|
| 12 |
- except LensmanInfo.DoesNotExist: |
|
| 13 |
- lensman = None |
|
| 14 |
- |
|
| 15 |
- price_fixed = {
|
|
| 16 |
- 'nomark': (lensman and lensman.nomark) or 299, |
|
| 17 |
- 'origin': (lensman and lensman.origin) or 999, |
|
| 18 |
- } |
|
| 19 |
- |
|
| 20 |
- r.setjson(LENSMAN_PHOTO_PRICE_FIXED % user_id, price_fixed) |
|
| 21 |
- |
|
| 22 |
- return price_fixed |
|
| 23 |
- |
|
| 24 |
- |
|
| 25 |
-def get_lensman_price_fixed(user_id): |
|
| 26 |
- """ 获取摄影师价格设定 """ |
|
| 27 |
- return r.getjson(LENSMAN_PHOTO_PRICE_FIXED % user_id) or set_lensman_price_fixed(user_id) |
@@ -1,19 +0,0 @@ |
||
| 1 |
-# -*- coding: utf-8 -*- |
|
| 2 |
- |
|
| 3 |
-from utils.redis.connect import r |
|
| 4 |
-from utils.redis.rkeys import TOUR_GUIDE_GROUP_USER_OWN |
|
| 5 |
- |
|
| 6 |
- |
|
| 7 |
-def set_tour_guide_own_group(user_id, group_id): |
|
| 8 |
- """ 设置导游拥有的旅行团 """ |
|
| 9 |
- r.set(TOUR_GUIDE_GROUP_USER_OWN % user_id, group_id) |
|
| 10 |
- |
|
| 11 |
- |
|
| 12 |
-def get_tour_guide_own_group(user_id): |
|
| 13 |
- """ 获取导游拥有的旅行团 """ |
|
| 14 |
- return r.get(TOUR_GUIDE_GROUP_USER_OWN % user_id) |
|
| 15 |
- |
|
| 16 |
- |
|
| 17 |
-def del_tour_guide_own_group(user_id): |
|
| 18 |
- """ 删除导游拥有的旅行团 """ |
|
| 19 |
- return r.delete(TOUR_GUIDE_GROUP_USER_OWN % user_id) |
@@ -1,14 +0,0 @@ |
||
| 1 |
-# -*- coding: utf-8 -*- |
|
| 2 |
- |
|
| 3 |
-from utils.redis.connect import r |
|
| 4 |
-from utils.redis.rkeys import TOUR_GUIDE_GROUP_USER_BELONG |
|
| 5 |
- |
|
| 6 |
- |
|
| 7 |
-def set_tour_user_belong_group(user_id, group_id): |
|
| 8 |
- """ 设置旅行团成员所属的旅行团 """ |
|
| 9 |
- r.set(TOUR_GUIDE_GROUP_USER_BELONG % user_id, group_id) |
|
| 10 |
- |
|
| 11 |
- |
|
| 12 |
-def get_tour_user_belong_group(user_id): |
|
| 13 |
- """ 获取旅行团成员所属的旅行团 """ |
|
| 14 |
- return r.get(TOUR_GUIDE_GROUP_USER_BELONG % user_id) |
@@ -1,22 +0,0 @@ |
||
| 1 |
-# -*- coding: utf-8 -*- |
|
| 2 |
- |
|
| 3 |
-from django_curtail_uuid import CurtailUUID |
|
| 4 |
- |
|
| 5 |
-from photo.models import UUIDInfo |
|
| 6 |
-from utils.redis.connect import r |
|
| 7 |
-from utils.redis.rkeys import UUID_LIST |
|
| 8 |
- |
|
| 9 |
- |
|
| 10 |
-def generate_uuid(): |
|
| 11 |
- uuid = CurtailUUID.uuid(UUIDInfo) |
|
| 12 |
- UUIDInfo.objects.create(uuid=uuid) |
|
| 13 |
- return uuid |
|
| 14 |
- |
|
| 15 |
- |
|
| 16 |
-def generate_uuids(num=1000): |
|
| 17 |
- uuids = [generate_uuid() for i in range(num)] |
|
| 18 |
- r.rpush(UUID_LIST, *uuids) |
|
| 19 |
- |
|
| 20 |
- |
|
| 21 |
-def update_uuids(lensman_id, uuids): |
|
| 22 |
- UUIDInfo.objects.filter(uuid__in=uuids).update(lensman_id=lensman_id, status=False) |