Brak opisu

mch_views.py 14KB

    # -*- coding: utf-8 -*- from __future__ import division import random from django.conf import settings from django.contrib.auth.hashers import check_password from django.db import transaction from django_logit import logit from django_response import response from pywe_miniapp import get_phone_number from pywe_storage import RedisStorage from TimeConvert import TimeConvert as tc from account.models import UserInfo from api.hb_views import exec_send_jsapi_hb from logs.models import MchInfoEncryptLogInfo from mch.models import (ActivityInfo, AdministratorInfo, BrandInfo, ConsumeInfoSubmitLogInfo, DistributorInfo, LatestAppInfo, LatestAppScreenInfo, ModelInfo, OperatorInfo) from statistic.models import ConsumeModelSaleStatisticInfo, ConsumeSaleStatisticInfo, ConsumeUserStatisticInfo from utils.error.errno_utils import (AdministratorStatusCode, OperatorStatusCode, ProductBrandStatusCode, ProductModelStatusCode, UserStatusCode) from utils.redis.connect import r from utils.redis.rkeys import MINI_PROGRAM_GIS_LIST, REDPACK_WAITING_SEND_LIST WECHAT = settings.WECHAT @logit def optor_login_api(request): brand_id = request.POST.get('brand_id', settings.KODO_DEFAULT_BRAND_ID) phone = request.POST.get('phone', '') password = request.POST.get('password', '') try: operator = OperatorInfo.objects.get(phone=phone, brand_id=brand_id, status=True) except OperatorInfo.DoesNotExist: return response(OperatorStatusCode.OPERATOR_NOT_FOUND) if operator.user_status == OperatorInfo.DISABLED: return response(OperatorStatusCode.OPERATOR_NOT_ACTIVATED) elif operator.user_status == OperatorInfo.DELETED: return response(OperatorStatusCode.OPERATOR_HAS_DELETED) if not check_password(password, operator.encryption): return response(OperatorStatusCode.OPERATOR_PASSWORD_ERROR) return response(200, 'Optor Login Success', u'操作员登录成功', data=operator.kododata) @logit def admin_login_api(request): phone = request.POST.get('phone', '') password = request.POST.get('password', '') try: administrator = AdministratorInfo.objects.get(phone=phone, status=True) except AdministratorInfo.DoesNotExist: return response(AdministratorStatusCode.ADMINISTRATOR_NOT_FOUND) if administrator.user_status == AdministratorInfo.DISABLED: return response(AdministratorStatusCode.ADMINISTRATOR_NOT_ACTIVATED) elif administrator.user_status == AdministratorInfo.DELETED: return response(AdministratorStatusCode.ADMINISTRATOR_HAS_DELETED) if not check_password(password, administrator.encryption): return response(AdministratorStatusCode.ADMINISTRATOR_PASSWORD_ERROR) request.session['admin_id'] = administrator.admin_id return response(200, 'Admin Login Success', u'管理员登录成功', data={ 'admin_id': administrator.admin_id, 'admin_type': administrator.admin_type, 'qrurl': settings.KODO_CLERK_AUTH_URL.format(administrator.brand_id), }) @logit def bmd_infos(request): optor_id = request.POST.get('optor_id', '') try: operator = OperatorInfo.objects.get(operator_id=optor_id, status=True) except OperatorInfo.DoesNotExist: return response(OperatorStatusCode.OPERATOR_NOT_FOUND) if operator.user_status == OperatorInfo.DISABLED: return response(OperatorStatusCode.OPERATOR_NOT_ACTIVATED) brands = BrandInfo.objects.filter(brand_id=operator.brand_id, status=True).order_by('position') brands = [brand.data for brand in brands] tmpmodels = ModelInfo.objects.filter(brand_id=operator.brand_id, display=True, status=True).order_by('position') models = [model.data for model in tmpmodels] # jancodes = {model.jancode: model.data for model in tmpmodels} distributors = DistributorInfo.objects.filter(brand_id=operator.brand_id, status=True).order_by('position') distributors = [distributor.data for distributor in distributors] return response(200, data={ 'optor_id': operator.operator_id, 'brands': brands, 'models': models, # 'jancodes': jancodes, 'distributors': distributors, }) @logit def brands_list(request): brands = BrandInfo.objects.filter(status=True).order_by('position') brands = [brand.data for brand in brands] return response(200, data={ 'brands': brands, }) @logit def models_list(request): models = ModelInfo.objects.filter(status=True).order_by('position') models = [model.data for model in models] return response(200, data={ 'models': models, }) @logit def distributors_list(request): distributors = DistributorInfo.objects.filter(status=True).order_by('position') distributors = [distributor.data for distributor in distributors] return response(200, data={ 'distributors': distributors, }) @logit def upgrade_api(request): """ APP 升级 """ brand_id = request.POST.get('brand_id', settings.KODO_DEFAULT_BRAND_ID) src = request.POST.get('src', '') if src == 'datascreen': latestappmodel = LatestAppScreenInfo else: latestappmodel = LatestAppInfo try: appinfo = latestappmodel.objects.filter(brand_id=brand_id, status=True)[0].adr except IndexError: appinfo = { 'latest_version_code': '', 'latest_version_name': '', 'latest_url': '', } return response(200, 'Get Latest App Success', u'获取最新版信息成功', { 'appinfo': appinfo, }) def getPhoneNumber(request): brand_id = request.POST.get('brand_id', settings.KODO_DEFAULT_BRAND_ID) user_id = request.POST.get('user_id', '') wxcfg = WECHAT.get('{}:MINIAPP'.format(brand_id), {}) appid = wxcfg.get('appID') secret = wxcfg.get('appsecret') # Just for compatible because of store session_key has changed session_key = None if user_id else RedisStorage(r).get('{0}:{1}:sessionKey'.format(appid, '')) iv = request.POST.get('iv', '') encryptedData = request.POST.get('encryptedData', '') # { # "phoneNumber": "13580006666", # "purePhoneNumber": "13580006666", # "countryCode": "86", # "watermark": # { # "appid": "APPID", # "timestamp": TIMESTAMP # } # } phone_number = get_phone_number(appid=appid, secret=secret, unid=user_id, session_key=session_key, encryptedData=encryptedData, iv=iv, storage=RedisStorage(r)) return phone_number.get('purePhoneNumber', '') @logit(res=True) def consumer_phone_api(request): return response(200, 'Get Consumer Phone Success', u'获取消费者手机号成功', { 'purePhoneNumber': getPhoneNumber(request), }) @logit(res=True) @transaction.atomic def consumer_info_api(request): user_id = request.POST.get('user_id', '') iv = request.POST.get('iv', '') encryptedData = request.POST.get('encryptedData', '') lat = request.POST.get('lat', .0) lon = request.POST.get('lon', .0) brandID = request.POST.get('brand_id', '') or request.POST.get('BrandID', '') modelID = request.POST.get('ModelID', '') distributorID = request.POST.get('DistributorID', '') serialNo = request.POST.get('SerialNo', '') verifyResult = request.POST.get('verifyResult', '') purePhoneNumber = request.POST.get('purePhoneNumber', '') if lat == 'undefined': lat = .0 if lon == 'undefined': lon = .0 # purePhoneNumber = purePhoneNumber or getPhoneNumber(request) # 校验用户是否存在 try: user = UserInfo.objects.get(user_id=user_id) except UserInfo.DoesNotExist: return response(UserStatusCode.USER_NOT_FOUND) # Tips: Change to update user's phone by membercard # 更新用户手机号 # user.phone = purePhoneNumber # user.save() try: brand = BrandInfo.objects.get(brand_id=brandID) except BrandInfo.DoesNotExist: brand = None if not brand: try: brand = BrandInfo.objects.get(pk=brandID) except BrandInfo.DoesNotExist: return response(ProductBrandStatusCode.BRAND_NOT_FOUND) except ValueError: return response(ProductBrandStatusCode.BRAND_NOT_FOUND) try: model = ModelInfo.objects.get(pk=modelID) except ModelInfo.DoesNotExist: return response(ProductModelStatusCode.MODEL_NOT_FOUND) except ValueError: return response(ProductModelStatusCode.MODEL_NOT_FOUND) # try: # distributor = DistributorInfo.objects.get(pk=distributorID) # except DistributorInfo.DoesNotExist: # return response(ProductDistributorStatusCode.DISTRIBUTOR_NOT_FOUND) # except ValueError: # return response(ProductDistributorStatusCode.DISTRIBUTOR_NOT_FOUND) dupload = ConsumeInfoSubmitLogInfo.objects.filter( brand_id=brand.brand_id, model_id=model.model_id, # distributor_id=distributor.distributor_id, distributor_id='', serialNo=serialNo, verifyResult=1, test_user=False, ).exists() if dupload: act = None during_activity = False else: act = ActivityInfo.objects.filter(status=True).order_by('-pk').first() during_activity = True if act and act.has_unexpired_activity(model.model_uni_name) else False # 记录用户信息提交记录 log = ConsumeInfoSubmitLogInfo.objects.create( user_id=user_id, phone=purePhoneNumber, iv=iv, encryptedData=encryptedData, lat=lat, lon=lon, brand_id=brand.brand_id, brand_name=brand.brand_name, model_id=model.model_id, model_name=model.model_name, # distributor_id=distributor.distributor_id, # distributor_name=distributor.distributor_name, distributor_id='', distributor_name='', serialNo=serialNo, verifyResult=verifyResult, dupload=dupload, submit_during_activity=during_activity, activity_id=act.pk if during_activity else 0, coupon_expire_at=act.coupon_expire_at if during_activity else None, coupon_value=act.coupon_value if during_activity else 0, test_user=user.test_user, ) if (not settings.CHECK_DUPLOAD_ENABLED) or (not user.test_user and not dupload): # TODO: Make statistic async ymd = tc.local_string(format='%Y%m%d') cusi, _ = ConsumeUserStatisticInfo.objects.get_or_create( brand_id=brand.brand_id, ymd=ymd, ) cusi.users = list(set(cusi.users + [log.user_id])) cusi.num = len(cusi.users) cusi.save() cusi, _ = ConsumeUserStatisticInfo.objects.get_or_create( brand_id=brand.brand_id, ymd=ymd[:6], ) cusi.users = list(set(cusi.users + [log.user_id])) cusi.num = len(cusi.users) cusi.save() cusi, _ = ConsumeUserStatisticInfo.objects.get_or_create( brand_id=brand.brand_id, ymd=ymd[:4], ) cusi.users = list(set(cusi.users + [log.user_id])) cusi.num = len(cusi.users) cusi.save() # 日销量统计 cssi, _ = ConsumeSaleStatisticInfo.objects.select_for_update().get_or_create( brand_id=brand.brand_id, ymd=ymd, ) cssi.num += 1 cssi.save() # 月销量统计 cssi, _ = ConsumeSaleStatisticInfo.objects.select_for_update().get_or_create( brand_id=brand.brand_id, ymd=ymd[:6], ) cssi.num += 1 cssi.save() # 年销量统计 cssi, _ = ConsumeSaleStatisticInfo.objects.select_for_update().get_or_create( brand_id=brand.brand_id, ymd=ymd[:4], ) cssi.num += 1 cssi.save() # 日型号销量统计 cmssi, _ = ConsumeModelSaleStatisticInfo.objects.select_for_update().get_or_create( brand_id=brand.brand_id, model_name=model.model_uni_name, ymd=ymd, ) cmssi.num += 1 cmssi.save() # 月型号销量统计 cmssi, _ = ConsumeModelSaleStatisticInfo.objects.select_for_update().get_or_create( brand_id=brand.brand_id, model_name=model.model_uni_name, ymd=ymd[:6], ) cmssi.num += 1 cmssi.save() # 年型号销量统计 cmssi, _ = ConsumeModelSaleStatisticInfo.objects.select_for_update().get_or_create( brand_id=brand.brand_id, model_name=model.model_uni_name, ymd=ymd[:4], ) cmssi.num += 1 cmssi.save() r.rpushjson(MINI_PROGRAM_GIS_LIST, { 'brand_id': log.brand_id, 'user_id': log.user_id, 'lat': log.lat, 'lon': log.lon, 'phone': log.phone, 'ymd': ymd, }) try: elog = MchInfoEncryptLogInfo.objects.select_for_update().get(sn=serialNo) except MchInfoEncryptLogInfo.DoesNotExist: elog = None except MchInfoEncryptLogInfo.MultipleObjectsReturned: elog = None if elog and (not dupload) and elog.is_send_redpack and (not elog.has_send_redpack) and (elog.redpack_amount or elog.redpack_max_amount): amount = elog.redpack_amount if elog.redpack_max_amount: amount = random.randint(100, elog.redpack_max_amount) if user.openid: exec_send_jsapi_hb(user, elog, amount) else: r.rpushjson(REDPACK_WAITING_SEND_LIST, { 'sn': serialNo, 'user_id': user.user_id, 'amount': amount, }) return response(200, 'Submit Consumer Info Success', u'提交消费者信息成功') @logit(res=True) @transaction.atomic def consumer_snlist_api(request): brand_id = request.POST.get('brand_id', settings.KODO_DEFAULT_BRAND_ID) user_id = request.POST.get('user_id', '') # 校验用户是否存在 try: user = UserInfo.objects.get(user_id=user_id) except UserInfo.DoesNotExist: return response(UserStatusCode.USER_NOT_FOUND) # 用户信息提交列表 logs = ConsumeInfoSubmitLogInfo.objects.filter(user_id=user_id, brand_id=brand_id, status=True).distinct() seen = set() seen_add = seen.add logs = [log.data for log in logs if not (log.serialNo in seen or seen_add(log.serialNo))] return response(200, 'Get Consumer Submit List Success', u'获取消费者提交列表成功', { 'logs': logs, })