diff --git a/dspt_api/urls.py b/dspt_api/urls.py index 1ac22a8..b56ed79 100644 --- a/dspt_api/urls.py +++ b/dspt_api/urls.py @@ -16,4 +16,5 @@ urlpatterns = [ path('get_suggest_params_timestamp', views.get_suggest_params_timestamp_by_api), path('set_user_data', views.set_user_select_data), path('clear_user_data', views.clear_user_select_data), + path('get_quan', views.get_quan), ] diff --git a/dspt_api/util/api/cinema_goods_pic.py b/dspt_api/util/api/cinema_goods_pic.py index ad4d545..6d9af05 100644 --- a/dspt_api/util/api/cinema_goods_pic.py +++ b/dspt_api/util/api/cinema_goods_pic.py @@ -1,5 +1,5 @@ from dspt_api.util.general.handle_redis import get_data_from_redis -from dspt_api.util.general.handle_goods import get_goods_list +from dspt_api.util.general.goods_list import get_goods_list import random diff --git a/dspt_api/util/api/order_buy_goods.py b/dspt_api/util/api/order_buy_goods.py index 89c4b84..201d185 100644 --- a/dspt_api/util/api/order_buy_goods.py +++ b/dspt_api/util/api/order_buy_goods.py @@ -1,6 +1,6 @@ from dspt_api.util.general.handle_redis import get_data_from_redis from dspt_api.util.general.get_order_num import general_order_num -from dspt_api.util.handle_goods import general_goods_param +from dspt_api.util.general.handle_goods import general_goods_param import time import random import json diff --git a/dspt_api/util/api/seat_check_coupon.py b/dspt_api/util/api/seat_check_coupon.py new file mode 100644 index 0000000..133adc9 --- /dev/null +++ b/dspt_api/util/api/seat_check_coupon.py @@ -0,0 +1,73 @@ +from dspt_api.util.general.handle_redis import get_data_from_redis +from dspt_api.util.general.get_order_num import general_order_num +from dspt_api.util.general.handle_goods import general_goods_param +from dspt_api.util.general.handle_ticket import get_ticket_price +import time +import random +import json + + +class ApiSeatCheckCoupon: + def __init__(self, **kwargs): + self.member_type = kwargs.get('member_type') + self.api = kwargs.get('api') + self.ip = kwargs.get('ip') + self.sale_type = kwargs.get('sale_type') + + def get_suggestion(self): + print('self.sale_type', self.sale_type) + if self.sale_type == 'ticket': + return self.get_play() + if self.sale_type == 'goods': + return self.get_goods() + if self.sale_type == 'all': + return self.get_play() + self.get_goods() + + def get_play(self): + # play_id + print('get_play') + request_api_play = {'name': '3.1.5 获取放映计划列表', 'path': 'cinema/plays'} + redis_key_api_play = f'dspt_api_{self.ip}_{self.member_type}_{request_api_play["path"]}' + result_play, _format_play, redis_data_play, _timestamp_play = get_data_from_redis(redis_key_api_play) + print('redis_data_play', redis_data_play) + if result_play: + play_data = random.choice(redis_data_play) + ticket_price, service_fee = get_ticket_price(play_data) + return [{'param': 'play_id', 'value': play_data['id'], 'is_checked': True, 'result': True}, + {'param': 'price', 'value': ticket_price, 'is_checked': True, 'result': True}, + {'param': 'seat_num', 'value': '1', 'is_checked': True, 'result': True}] + else: + return [{'param': 'play_id', 'value': redis_data_play + request_api_play["name"], 'is_checked': True, + 'result': True}, + {'param': 'price', 'value': '0.00', 'is_checked': True, 'result': True}, + {'param': 'seat_num', 'value': '1', 'is_checked': True, 'result': True}] + + def get_goods(self): + request_api = {'name': '3.2.1 获取卖品列表', 'path': 'cinema/goods'} + redis_key_api = f'dspt_api_{self.ip}_{self.member_type}_{request_api["path"]}' + result, _format, redis_data, _timestamp = get_data_from_redis(redis_key_api) + if result: + goods_data = random.choice(redis_data) + goods_info, cash = general_goods_param(goods_data) + print('ApiSeatCheckCoupon', goods_info) + coupon_goods = [self.format_goods(goods) for goods in goods_info] + return [ + {'param': 'goods', 'value': json.dumps(coupon_goods), 'is_checked': True, 'result': True, + 'timestamp': _timestamp}] + else: + # 返回推荐参数应该包含参数名,参数值,和是否勾选的状态 + # redis_data + request_api["name"] + return [ + {'param': 'goods', 'value': redis_data + request_api["name"], 'is_checked': True, 'result': True, + 'timestamp': _timestamp}, ] + + @staticmethod + def format_goods(goods): + goods['goods_type'] = goods['type'] + goods['sell_price'] = goods['price'] + goods.pop('type') + goods.pop('price') + return goods + + def get_timestamp(self): + return int(time.time() * 1000) diff --git a/dspt_api/util/api/ticket_refundv2.py b/dspt_api/util/api/ticket_refundv2.py new file mode 100644 index 0000000..e69de29 diff --git a/dspt_api/util/general/get_cinema_quan.py b/dspt_api/util/general/get_cinema_quan.py new file mode 100644 index 0000000..e936692 --- /dev/null +++ b/dspt_api/util/general/get_cinema_quan.py @@ -0,0 +1,110 @@ +from pickletools import opcodes + +import pymysql +from pymysql.cursors import DictCursor + +QUAN_SQL = sql = """ + SELECT cqi.cinema_quan_name, + cqi.cinema_allow_tickets_flag, + cqi.cinema_tickets_pay_type , + cqi.cinema_allow_retail_flag , + cqi.cinema_retail_pay_type, + m1.cinema_yushouquan_book_order, + m1.cinema_yushouquan_encrypt_barcode + FROM cinema_yushouquan_info m1 + LEFT JOIN cinema_yushouquan_info m2 + ON m1.cinema_yushouquan_id >m2.cinema_yushouquan_id AND m1.`cinema_yushouquan_book_order`=m2.`cinema_yushouquan_book_order` + left join cinema_quan_info cqi ON + cqi.cinema_quan_id = m1.cinema_quan_id + where m1.cinema_yushouquan_status = '5' + AND m1.cinema_yushouquan_active_flag = '1' + AND cqi.card_quan_channel = '2' + GROUP BY m2.`cinema_yushouquan_book_order`,m2.cinema_yushouquan_encrypt_barcode + HAVING COUNT(*)<10 + ORDER BY m1.cinema_yushouquan_book_order; + """ + +CARD_QUAN_SQL = "SELECT cqo.card_quan_order_id, cqi.cinema_quan_name, cqo.cinema_quan_id, cqo.quan_remain_nums, cqo.cinema_dead_time FROM cine.card_quan_order cqo LEFT JOIN cine.cinema_quan_info cqi ON cqo.cinema_quan_id = cqi.cinema_quan_id WHERE cqi.card_quan_channel = '2' AND cqo.quan_remain_nums > 0 AND cqo.cinema_dead_time >= NOW() AND cqo.cinema_card_num = %s;" + + +class GetQuan: + + def __init__(self, cinema_info): + self.cinema_db = cinema_info + + def get_quan(self): + db_conn = pymysql.connect(**self.cinema_db) + db_cursor = db_conn.cursor(DictCursor) + db_cursor.execute(QUAN_SQL) + quan_list = db_cursor.fetchall() + quan = [] + quan_label_list = [] + for q in quan_list: + quan_pay_type = [] + ticket = '' + goods = '' + if q['cinema_allow_tickets_flag'] == 1: + match q['cinema_tickets_pay_type']: + case 'zk': + ticket = '票<折扣>' + case 'dj': + ticket = '票<代金>' + case 'zq': + ticket = '票<最低票价>' + case 'dhbl': + ticket = '票<兑换>' + case 'zgxe': + ticket = '票<最高限额>' + quan_pay_type.append(ticket) + if q['cinema_allow_retail_flag'] == 1: + match q['cinema_retail_pay_type']: + case 'zk': + goods = '卖品<折扣>' + case 'dj': + goods = '卖品<代金>' + case 'dhbl': + goods = '卖品<兑换>' + quan_pay_type.append(goods) + quan_label_list_str = '(' + '+'.join(quan_pay_type) + ')' + label = (q['cinema_quan_name'] + ' ' + quan_label_list_str + ' -> ' + q['cinema_yushouquan_book_order']) + if label not in quan_label_list: + quan.append({ + 'label': label, + 'value': label, + 'options': [{'label': q['cinema_yushouquan_encrypt_barcode'], + 'value': q['cinema_yushouquan_encrypt_barcode']}], + }) + quan_label_list.append(label) + else: + for item in quan: + if item['label'] == label: + item['options'].append({'label': q['cinema_yushouquan_encrypt_barcode'], + 'value': q['cinema_yushouquan_encrypt_barcode']}) + + + # if quan['cinema_quan_name'] not in quan_dict.keys(): + # quan_dict[quan['cinema_quan_name']] = { + # 'rule': {'cinema_allow_tickets_flag': quan['cinema_allow_tickets_flag'], + # 'cinema_tickets_pay_type': quan['cinema_tickets_pay_type'], + # 'cinema_allow_retail_flag': quan['cinema_allow_retail_flag'], + # 'cinema_retail_pay_type': quan['cinema_retail_pay_type']}, + # 'order_num': [quan['cinema_yushouquan_book_order']], + # 'order': {quan['cinema_yushouquan_book_order']: [quan['cinema_yushouquan_encrypt_barcode']]} + # } + # else: + # if quan['cinema_yushouquan_book_order'] not in quan_dict[quan['cinema_quan_name']]['order_num']: + # quan_dict[quan['cinema_quan_name']]['order_num'].append(quan['cinema_yushouquan_book_order']) + # quan_dict[quan['cinema_quan_name']]['order'][quan['cinema_yushouquan_book_order']] = [ + # quan['cinema_yushouquan_encrypt_barcode']] + # else: + # quan_dict[quan['cinema_quan_name']]['order'][quan['cinema_yushouquan_book_order']].append( + # quan['cinema_yushouquan_encrypt_barcode']) + + return quan + + def get_card_quan(self, card_num): + db_conn = pymysql.connect(**self.cinema_db) + db_cursor = db_conn.cursor(DictCursor) + db_cursor.execute(CARD_QUAN_SQL, (card_num,)) + card_quan_list = db_cursor.fetchall() + return card_quan_list diff --git a/dspt_api/util/general/goods_list.py b/dspt_api/util/general/goods_list.py new file mode 100644 index 0000000..036a865 --- /dev/null +++ b/dspt_api/util/general/goods_list.py @@ -0,0 +1,12 @@ +def get_goods_list(goods_resp, _format): + goods_list = [] + if _format == 'json': + for goods_cate in goods_resp: + goods_list = goods_list + goods_cate['goods'] + if _format == 'xml': + for goods_cate in goods_resp['cate']: + if isinstance(goods_cate['goods']['item'], dict): + goods_list.append(goods_cate['goods']['item']) + else: + goods_list = goods_list + goods_cate['goods']['item'] + return goods_list diff --git a/dspt_api/util/general/handle_goods.py b/dspt_api/util/general/handle_goods.py index 036a865..fdc512c 100644 --- a/dspt_api/util/general/handle_goods.py +++ b/dspt_api/util/general/handle_goods.py @@ -1,12 +1,60 @@ -def get_goods_list(goods_resp, _format): +# 将接口请求的数据中卖品信息整理成列表结构 +def format_goods(_data): goods_list = [] - if _format == 'json': - for goods_cate in goods_resp: - goods_list = goods_list + goods_cate['goods'] - if _format == 'xml': - for goods_cate in goods_resp['cate']: - if isinstance(goods_cate['goods']['item'], dict): - goods_list.append(goods_cate['goods']['item']) - else: - goods_list = goods_list + goods_cate['goods']['item'] - return goods_list + for cate in _data['res']['data']: + for g in cate['goods']: + goods_list.append(g) + return {'res': {'status': _data['res']['status'], 'data': goods_list}} + + +# 将接口获取的卖品数据转化成请求参数格式 +def general_goods_param(_data): + params = [] + total_cash = 0 + for g in _data: + _num = g.get('buy_num', 1) + info = { + 'id': g['id'], + 'type': g['type'], + 'price': round(float(g.get('partnerPrice', g['onlinePrice'])) * _num, 2), + 'num': _num + } + if g['type'] == 'package' and g['packageType'] == '2': + add_price = 0 + optional_package = [] + for key, val in g['user_select'].items(): + member = [] + member_id = [] + for m in val['data']: + if m['id'] in member_id: + for item in member: + if item['id'] == m['id']: + item['num'] = item['num'] + 1 + add_price += round(float(m['addPrice']), 2) + else: + member.append({'id': m['id'], 'num': 1, 'add_price': m['addPrice']}) + member_id.append(m['id']) + add_price += round(float(m['addPrice']), 2) + optional_package.append({'index': key, 'members': member}) + info['optional_package'] = optional_package + info['price'] = round(info['price'] + add_price, 2) + total_cash = round(total_cash + info['price'] * _num, 2) + params.append(info) + if g.get('discount1', False): + total_discount = 0 + discount_list = [] + if g['discount1'] > 0: + total_discount = round(total_discount + g['discount1'], 2) + discount_list.append( + {"discount_price": g['discount1'], "discount_name": f"现金优惠券{str(g['discount1'])}元"}) + if g['discount2'] > 0: + total_discount = round(total_discount + g['discount2'], 2) + discount_list.append( + {"discount_price": g['discount2'], "discount_name": f"现金优惠券{str(g['discount2'])}元"}) + if len(discount_list) > 0: + info['discount_price'] = total_discount + info['discount_detail'] = discount_list + total_cash = round(total_cash - total_discount, 2) + + print('general_goods_param---------params', params) + return params, total_cash diff --git a/dspt_api/util/general/handle_ticket.py b/dspt_api/util/general/handle_ticket.py new file mode 100644 index 0000000..2a1a5af --- /dev/null +++ b/dspt_api/util/general/handle_ticket.py @@ -0,0 +1,18 @@ +def get_ticket_price(data, seat=None, ecard=None): + print('get_ticket_price-data', data) + if data.get('areaInfo') is None: + if data.get('partnerPrice') is None: + return data.get('marketPrice'), None + else: + return data.get('partnerPrice'), None + else: + if seat is None: + return data.get('partnerPrice'), None + else: + area_id = seat.get('areaId') + if ecard is None: + for area in data.get('areaInfo'): + if area.get('areaId') == area_id: + return area.get('areaPrice'), area.get('areaServiceFee') + else: + pass \ No newline at end of file diff --git a/dspt_api/util/random_params.py b/dspt_api/util/general/random_params.py similarity index 100% rename from dspt_api/util/random_params.py rename to dspt_api/util/general/random_params.py diff --git a/dspt_api/util/sign.py b/dspt_api/util/general/sign.py similarity index 100% rename from dspt_api/util/sign.py rename to dspt_api/util/general/sign.py diff --git a/dspt_api/util/suggest_params.py b/dspt_api/util/general/suggest_params.py similarity index 91% rename from dspt_api/util/suggest_params.py rename to dspt_api/util/general/suggest_params.py index 2a39c80..2360488 100644 --- a/dspt_api/util/suggest_params.py +++ b/dspt_api/util/general/suggest_params.py @@ -13,11 +13,12 @@ from dspt_api.util.api.order_buy_goods import ApiOrderBuyGoods from dspt_api.util.api.ecard_detail import ApiEcardDetail from dspt_api.util.api.ecard_order_detail import ApiEcardOrderDetail from dspt_api.util.api.ecard_seat_price import ApiEcardSeatPrice +from dspt_api.util.api.seat_check_coupon import ApiSeatCheckCoupon # 通过api来匹配不同的接口文件获取推荐 # 返回推荐参数应该包含参数名,参数值,和是否勾选的状态 -def suggest_params(member_type, api, ip): +def suggest_params(member_type, api, ip, **kwargs): data = {'member_type': member_type, 'api': api, 'ip': ip} params = [] # 非会员 @@ -66,6 +67,11 @@ def suggest_params(member_type, api, ip): if api == 'ecard/refund' and member_type == 'nonmember': print('ecard/refund') params = ApiEcardRefund(**data).get_suggestion() + if api == 'seat/check-coupon' and member_type == 'nonmember': + print('seat/check-coupon') + print("kwargs['sale_type']", kwargs['sale_type']) + data['sale_type'] = kwargs['sale_type'] + params = ApiSeatCheckCoupon(**data).get_suggestion() return params def suggest_params_timestamp(member_type, api, ip): @@ -117,4 +123,7 @@ def suggest_params_timestamp(member_type, api, ip): if api == 'ecard/refund' and member_type == 'nonmember': print('ecard/refund') _timestamps = ApiEcardRefund(**data).get_timestamp() + if api == 'seat/check-coupon' and member_type == 'nonmember': + print('seat/check-coupon') + _timestamps = ApiSeatCheckCoupon(**data).get_timestamp() return _timestamps \ No newline at end of file diff --git a/dspt_api/util/xml_util.py b/dspt_api/util/general/xml_util.py similarity index 100% rename from dspt_api/util/xml_util.py rename to dspt_api/util/general/xml_util.py diff --git a/dspt_api/util/handle_goods.py b/dspt_api/util/handle_goods.py deleted file mode 100644 index 29d75de..0000000 --- a/dspt_api/util/handle_goods.py +++ /dev/null @@ -1,50 +0,0 @@ -import json -import random - -from dspt_api.util.random_params import random_params - - -# 将接口请求的数据中卖品信息整理成列表结构 -def format_goods(_data): - goods_list = [] - for cate in _data['res']['data']: - for g in cate['goods']: - goods_list.append(g) - return {'res': {'status': _data['res']['status'], 'data': goods_list}} - - -# 将接口获取的卖品数据转化成请求参数格式 -def general_goods_param(_data): - params = [] - total_cash = 0 - for g in _data: - _num = g.get('buy_num', 1) - info = { - 'id': g['id'], - 'type': g['type'], - 'price': round(float(g.get('partnerPrice', g['onlinePrice'])) * _num, 2), - 'num': _num - } - if g['type'] == 'package' and g['packageType'] == '2': - add_price = 0 - optional_package = [] - for key, val in g['user_select'].items(): - member = [] - member_id = [] - for m in val['data']: - if m['id'] in member_id: - for item in member: - if item['id'] == m['id']: - item['num'] = item['num'] + 1 - add_price += round(float(m['addPrice']), 2) - else: - member.append({'id': m['id'], 'num': 1, 'add_price': m['addPrice']}) - member_id.append(m['id']) - add_price += round(float(m['addPrice']), 2) - optional_package.append({'index': key, 'members': member}) - info['optional_package'] = optional_package - info['price'] = round(info['price'] + add_price, 2) - total_cash = round(total_cash + info['price'] * _num, 2) - params.append(info) - print('general_goods_param---------params', params) - return params, total_cash diff --git a/dspt_api/views.py b/dspt_api/views.py index 45ddc30..6413df4 100644 --- a/dspt_api/views.py +++ b/dspt_api/views.py @@ -1,31 +1,33 @@ -import datetime import json import re import time import requests import urllib -import xml.etree.ElementTree from urllib.parse import urljoin from django.db.models import Q from django_filters.rest_framework import DjangoFilterBackend from django_redis import get_redis_connection -from rest_framework import filters from rest_framework import viewsets from django.views.decorators.csrf import csrf_exempt -from django.http.response import JsonResponse, HttpResponse +from django.http.response import JsonResponse # from rest_framework.response import Response from django.utils import timezone -from dspt_api.util.handle_goods import format_goods -from dspt_api.util.random_params import random_params -from dspt_api.util.sign import Sign +from dspt_api.util.general.handle_goods import format_goods +from dspt_api.util.general.random_params import random_params +from dspt_api.util.general.sign import Sign from dspt_api.models import EcChannel, EcEnv, EcApi, EcApiParams, EcCinemaIds, EcRequestLog, EcApiGroup from dspt_api.serializers import EcChannelSerializer, EcEnvSerializer, EcApiSerializer, EcApiParamsSerializer, \ EcCinemaIdsSerializer, EcRequestLogSerializer, EcApiGroupSerializer -from dspt_api.util.suggest_params import suggest_params, suggest_params_timestamp +from update.models import Cinema +from update.serializers import CinemaSerializer +from dspt_api.models import EcCinemaIds +from dspt_api.serializers import EcCinemaIdsSerializer +from dspt_api.util.general.suggest_params import suggest_params, suggest_params_timestamp from dspt_api.util.general.handle_xml_resp import HandleXmlResp from dspt_api.util.general.format_xml import format_xml +from dspt_api.util.general.get_cinema_quan import GetQuan # Create your views here. @@ -87,6 +89,7 @@ def handle_request(_request): member_type = req.get('member_type') api = req.get('api') params = json.loads(req.get('params')) + print('handle_request--req.get(params)', req.get('params')) resp_format = params['format'] try: base_url = EcEnv.objects.filter(Q(code=env) & Q(type=member_type)).values('host').first()['host'] @@ -142,7 +145,13 @@ def get_suggest_params_by_api(request): member_type = request.GET.get('member_type') api = request.GET.get('api') user_ip = request.META.get('REMOTE_ADDR') - params = suggest_params(member_type, api, user_ip) + sale_type = request.GET.get('options[sale_type]', None) + print() + print('sale_type', sale_type) + if sale_type is None: + params = suggest_params(member_type, api, user_ip) + else: + params = suggest_params(member_type, api, user_ip, **{'sale_type': sale_type}) return JsonResponse(params, safe=False) @@ -192,6 +201,7 @@ def send_request(request): # 获取返回类型结果 req = json.loads(request.body) params = json.loads(req.get('params')) + print('request_params', params) resp_format = params['format'] member_type = req.get('member_type') # 初始化redis @@ -211,7 +221,7 @@ def send_request(request): print('response', response.content) # 处理xml数据 - handled_data = '' + handled_data = {} response_data = '' if resp_format == 'json': response_data = response.text @@ -219,6 +229,10 @@ def send_request(request): if resp_format == 'xml': response_data = format_xml(re.sub(r'>\n?\s+?<', r'>\n<', response.text)) handled_data = HandleXmlResp(response.text).format_xml() + print('type(handled_data)', type(handled_data)) + if str(handled_data['res']['status']) == '0': + return JsonResponse({'format': resp_format, 'data': response_data, 'handled': json.dumps(handled_data)}) + # 卖品接口特殊处理去掉无用cate一层结构 if api == 'cinema/goods': handled_data = format_goods(handled_data) @@ -316,6 +330,34 @@ def clear_user_select_data(request): return JsonResponse({'result': 'fail'}) +@csrf_exempt +def get_quan(request): + """ + 请求链接 http://172.16.1.168:8000/ec/get_quan?cid=8125&card_num=81256932698071124424 + card_num 传参时查询电子券 + """ + cid = request.GET.get('cid') + card_num = request.GET.get('card_num', False) + ec_cinema_info = EcCinemaIds.objects.filter(cid=cid).first() + ec_cinema_data = EcCinemaIdsSerializer(ec_cinema_info).data + cinema_ip = ec_cinema_data.get('cinema_name') + cinema_info = Cinema.objects.filter(ip=cinema_ip).first() + cinema_data = CinemaSerializer(cinema_info).data + cinema_db = { + 'host': cinema_data.get('ip'), + 'user': cinema_data.get('db_user'), + 'password': cinema_data.get('db_pwd'), + 'port': 3306, + 'database': 'cine' + } + quan = GetQuan(cinema_db) + quan_data = { + 'quan': quan.get_quan(), + 'card_quan': quan.get_card_quan(card_num) if card_num else [] + } + return JsonResponse(quan_data) + + # 对外接口,用于给前端提供上次请求的数据,如果没有则返回数据库中的默认值 # 若果有些字段是依赖于其他接口返回值生成的则单独处理此接口, 单独处理逻辑在util目录下 @csrf_exempt