|
# -*- 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('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(pk=brandID)
except BrandInfo.DoesNotExist:
brand = None
except ValueError:
brand = None
if not brand:
try:
brand = BrandInfo.objects.get(brand_id=brandID)
except BrandInfo.DoesNotExist:
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,
})
|