| @@ -44,6 +44,7 @@ urlpatterns += [ | ||
| 44 | 44 | url(r'^f/thumbup/submit$', group_views.thumbup_submit_api, name='thumbup_submit_api'), # 飞图点赞提交 | 
| 45 | 45 | url(r'^f/thumbup/list$', group_views.thumbup_list_api, name='thumbup_list_api'), # 飞图点赞列表 | 
| 46 | 46 | url(r'^f/thumbup/cancel$', group_views.thumbup_cancel_api, name='thumbup_cancel_api'), # 飞图点赞取消 | 
| 47 | + url(r'^f/price$', group_views.lesman_photo_price, name='lesman_photo_price'), # 摄影师照片价格获取 | |
| 47 | 48 | ] | 
| 48 | 49 |  | 
| 49 | 50 | # 消息相关 | 
| @@ -78,6 +79,8 @@ urlpatterns += [ | ||
| 78 | 79 | urlpatterns += [ | 
| 79 | 80 | url(r'^wx/order_create$', pay_views.wx_order_create_api, name='wx_order_create_api'), # 订单创建 | 
| 80 | 81 | url(r'^wx/order_query$', pay_views.wx_order_query_api, name='wx_order_query_api'), # 订单查询 | 
| 82 | + url(r'^wx/order_list$', pay_views.wx_order_list_api, name='wx_order_list_api'), # 订单列表 | |
| 83 | + url(r'^wx/order_detail$', pay_views.wx_order_detail_api, name='wx_order_detail_api'), # 订单详情 | |
| 81 | 84 | url(r'^wx/notify_url$', pay_views.wx_notify_url_api, name='wx_notify_url_api'), # 支付异步通知回调地址 | 
| 82 | 85 | ] | 
| 83 | 86 |  | 
| @@ -26,6 +26,7 @@ from utils.redis.rkeys import ( | ||
| 26 | 26 | GROUP_USERS_QUIT_SET, | 
| 27 | 27 | ) | 
| 28 | 28 | from utils.redis.rkeys import GROUP_LAST_PHOTO_PK | 
| 29 | +from utils.redis.rkeys import LESMAN_PHOTO_PRICE, LESMAN_PHOTO_HAGGLE_TIMES | |
| 29 | 30 | from utils.redis.rgroup import set_group_info, get_group_info, set_group_users_info, get_group_users_info | 
| 30 | 31 | from utils.redis.rgroup import set_group_photo_thumbup_flag, del_group_photo_thumbup_flag, get_group_photo_thumbup_flag | 
| 31 | 32 |  | 
| @@ -36,6 +37,7 @@ from curtail_uuid import CurtailUUID | ||
| 36 | 37 | from TimeConvert import TimeConvert as tc | 
| 37 | 38 |  | 
| 38 | 39 | import os | 
| 40 | +import random | |
| 39 | 41 | import shortuuid | 
| 40 | 42 |  | 
| 41 | 43 |  | 
| @@ -898,6 +900,43 @@ def pai2_home_api(request): | ||
| 898 | 900 | }) | 
| 899 | 901 |  | 
| 900 | 902 |  | 
| 903 | +def lesman_photo_price(request): | |
| 904 | + """ | |
| 905 | + 摄影师照片价格获取 | |
| 906 | + :param request: | |
| 907 | + :return: | |
| 908 | + """ | |
| 909 | +    user_id = request.POST.get('user_id', '') | |
| 910 | +    photo_id = request.POST.get('photo_id', '') | |
| 911 | +    photo_type = request.POST.get('photo_type', 'nomark')  # nomakr for 去除水印, origin for 获取高清图 | |
| 912 | + | |
| 913 | + # 处理价格逻辑 | |
| 914 | + lesman_photo_price_key = LESMAN_PHOTO_PRICE % (user_id, photo_id, photo_type) | |
| 915 | + lesman_photo_haggle_times_key = LESMAN_PHOTO_HAGGLE_TIMES % (user_id, photo_id, photo_type) | |
| 916 | + # Redis 获取存储的价格 | |
| 917 | + price = float(r.get(lesman_photo_price_key) or 0) | |
| 918 | + if price: | |
| 919 | + haggle_times = int(r.get(lesman_photo_haggle_times_key) or 0) | |
| 920 | + # 砍价逻辑 | |
| 921 | + if haggle_times < settings.LESMAN_PHOTO_HAGGLE_MAX_TIMES: | |
| 922 | + price -= random.choice([0.5, 1]) | |
| 923 | + r.incr(lesman_photo_haggle_times_key) | |
| 924 | + else: | |
| 925 | + # 获取摄影师定价 | |
| 926 | + # TODO, 此处需要完整的摄影师定价 | |
| 927 | + price = 9.9 if photo_type == 'origin' else 6.6 | |
| 928 | + | |
| 929 | + r.set(lesman_photo_price_key, price) | |
| 930 | + | |
| 931 | +    return JsonResponse({ | |
| 932 | + 'status': 200, | |
| 933 | + 'message': u'获取价格成功', | |
| 934 | +        'data': { | |
| 935 | + photo_type: price | |
| 936 | + } | |
| 937 | + }) | |
| 938 | + | |
| 939 | + | |
| 901 | 940 | def group_detail(request, group_id): | 
| 902 | 941 |      return render(request, 'page/download.html', {}) | 
| 903 | 942 |  | 
| @@ -237,12 +237,18 @@ WATERMARK_LOGO = os.path.join(PROJ_DIR, 'static/pai2/img/paiai_96_96.png').repla | ||
| 237 | 237 | THUMBNAIL_MAX_WIDTH = 360 | 
| 238 | 238 |  | 
| 239 | 239 | # 首页设置 | 
| 240 | -PAI2_HOME_PER_PAGE = 20 | |
| 241 | -PAI2_HOME_MAX_PAGE = 20 | |
| 242 | -PAI2_HOME_MAX_ROWS = 400 # PAI2_HOME_PER_PAGE * PAI2_HOME_MAX_PAGE = 20 * 20 = 400 | |
| 240 | +PAI2_HOME_PER_PAGE = 20 # 首页照片每页数量 | |
| 241 | +PAI2_HOME_MAX_PAGE = 20 # 首页照片最大页数 | |
| 242 | +PAI2_HOME_MAX_ROWS = 400 # 首页照片最大数量, PAI2_HOME_PER_PAGE * PAI2_HOME_MAX_PAGE = 20 * 20 = 400 | |
| 243 | 243 |  | 
| 244 | 244 | # 群组设置 | 
| 245 | -GROUP_PER_PAGE = 20 | |
| 245 | +GROUP_PER_PAGE = 20 # 群组每页数量 | |
| 246 | + | |
| 247 | +# 价格设置 | |
| 248 | +LESMAN_PHOTO_HAGGLE_MAX_TIMES = 3 # 摄影师照片最大砍价次数 | |
| 249 | + | |
| 250 | +# 订单设置 | |
| 251 | +ORDER_NUM_PER_PAGE = 10 # 订单每页数量 | |
| 246 | 252 |  | 
| 247 | 253 | # 域名设置 | 
| 248 | 254 | DOMAIN = 'http://pai.ai' | 
| @@ -256,7 +262,7 @@ SYSTEM_MESSAGE_AVATAR = PAI2_LOGO_URL | ||
| 256 | 262 | COMMENT_MESSAGE_AVATAR = PAI2_LOGO_URL | 
| 257 | 263 | THUMBUP_MESSAGE_AVATAR = PAI2_LOGO_URL | 
| 258 | 264 |  | 
| 259 | -MESSAGE_NUM_PER_PAGE = 10 | |
| 265 | +MESSAGE_NUM_PER_PAGE = 10 # 消息每页数量 | |
| 260 | 266 |  | 
| 261 | 267 | try: | 
| 262 | 268 | from local_settings import * | 
| @@ -61,7 +61,9 @@ class OrderInfo(CreateUpdateMixin): | ||
| 61 | 61 | 'from_uid': self.from_uid, | 
| 62 | 62 | 'to_lid': self.to_lid, | 
| 63 | 63 | 'to_uid': self.to_uid, | 
| 64 | + 'body': self.body, | |
| 65 | + 'total_fee': self.total_fee, | |
| 64 | 66 | 'pay_status': self.pay_status, | 
| 65 | - 'paid_at': self.paid_at.replace(microsecond=0), | |
| 67 | + 'paid_at': self.paid_at and self.paid_at.replace(microsecond=0), | |
| 66 | 68 | 'created_at': self.created_at.replace(microsecond=0), | 
| 67 | 69 | } | 
| @@ -7,6 +7,8 @@ from django.shortcuts import HttpResponse | ||
| 7 | 7 |  | 
| 8 | 8 | from pay.models import OrderInfo | 
| 9 | 9 |  | 
| 10 | +from utils.page_utils import pagination | |
| 11 | + | |
| 10 | 12 | from utils.error.errno_utils import OrderStatusCode | 
| 11 | 13 | from utils.error.response_utils import response | 
| 12 | 14 |  | 
| @@ -163,6 +165,60 @@ def wx_order_query_api(request): | ||
| 163 | 165 |  | 
| 164 | 166 | @logit | 
| 165 | 167 | @transaction.atomic | 
| 168 | +def wx_order_list_api(request): | |
| 169 | + """ | |
| 170 | + 订单列表 | |
| 171 | + :param request: | |
| 172 | + :return: | |
| 173 | + """ | |
| 174 | +    user_id = request.POST.get('user_id', '') | |
| 175 | +    page = int(request.POST.get('page', 1)) | |
| 176 | +    num = int(request.POST.get('num', settings.ORDER_NUM_PER_PAGE)) | |
| 177 | + | |
| 178 | +    orders = OrderInfo.objects.filter(from_uid=user_id).order_by('-pk') | |
| 179 | + orders, left = pagination(orders, page, num) | |
| 180 | + orders = [order.data for order in orders] | |
| 181 | + | |
| 182 | +    return JsonResponse({ | |
| 183 | + 'status': 200, | |
| 184 | + 'message': u'获取订单列表成功', | |
| 185 | +        'data': { | |
| 186 | + 'orders': orders, | |
| 187 | + 'left': left, | |
| 188 | + }, | |
| 189 | + }) | |
| 190 | + | |
| 191 | + | |
| 192 | +@logit | |
| 193 | +@transaction.atomic | |
| 194 | +def wx_order_detail_api(request): | |
| 195 | + """ | |
| 196 | + 订单详情 | |
| 197 | + :param request: | |
| 198 | + :return: | |
| 199 | + """ | |
| 200 | +    user_id = request.POST.get('user_id', '') | |
| 201 | +    order_id = request.POST.get('order_id', '') | |
| 202 | + | |
| 203 | + try: | |
| 204 | + order = OrderInfo.objects.get(order_id=order_id) | |
| 205 | + except OrderInfo.DoesNotExist: | |
| 206 | + return response(OrderStatusCode.WX_ORDER_NOT_FOUND) | |
| 207 | + | |
| 208 | + if user_id not in [order.from_uid, order.to_lid, order.to_uid]: | |
| 209 | + return response(OrderStatusCode.NO_DETAIL_PERMISSION) | |
| 210 | + | |
| 211 | +    return JsonResponse({ | |
| 212 | + 'status': 200, | |
| 213 | + 'message': u'获取订单详情成功', | |
| 214 | +        'data': { | |
| 215 | + 'order': order.data, | |
| 216 | + }, | |
| 217 | + }) | |
| 218 | + | |
| 219 | + | |
| 220 | +@logit | |
| 221 | +@transaction.atomic | |
| 166 | 222 | def wx_notify_url_api(request): | 
| 167 | 223 | """ | 
| 168 | 224 | 支付异步通知回调地址 | 
| @@ -69,6 +69,7 @@ class OrderStatusCode(BaseStatusCode): | ||
| 69 | 69 | WX_ORDER_PAYING = StatusCodeField(404003, u'WX Order Paying', description=u'订单支付中') | 
| 70 | 70 | WX_ORDER_PAY_FAIL = StatusCodeField(404009, u'WX Order Pay Fail', description=u'微信支付失败') | 
| 71 | 71 | SIGN_CHECK_FAIL = StatusCodeField(404010, u'Sign Check Fail', description=u'签名校验失败') | 
| 72 | + NO_DETAIL_PERMISSION = StatusCodeField(404015, u'No Detail Permission', description=u'没有详情权限') | |
| 72 | 73 |  | 
| 73 | 74 |  | 
| 74 | 75 | class MessageStatusCode(BaseStatusCode): | 
| @@ -18,5 +18,9 @@ GROUP_USERS_QUIT_SET = 'group:users:quit:set:%s' # SET,群组用户退出集 | ||
| 18 | 18 | GROUP_PHOTO_THUMB_UP = 'group:photo:thumb:up:%s:%s' # STRING,群组照片用户点赞记录,photo_id、user_id | 
| 19 | 19 | GROUP_LAST_PHOTO_PK = 'group:last:photo:pk:%s' # STRING,群组最后一张照片PK,group_id | 
| 20 | 20 |  | 
| 21 | +# 摄影师照片相关 | |
| 22 | +LESMAN_PHOTO_PRICE = 'lesman:photo:price:%s:%s:%s' # STRING,摄影师照片价格,photo_id、user_id、photo_type | |
| 23 | +LESMAN_PHOTO_HAGGLE_TIMES = 'lesman:photo:haggle:times:%s:%s:%s' # STRING,摄影师照片价格,photo_id、user_id、photo_type | |
| 24 | + | |
| 21 | 25 | # 系统消息相关 | 
| 22 | 26 | SYSTEM_MESSAGE_DELETED_INFO = 'system:message:deleted:info:%s' # STRING,系统消息删除信息,user_id |