@@ -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  |