views.py 102 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743
  1. # -*- coding: utf-8 -*-
  2. # !/usr/bin/env python
  3. """
  4. web.management.views
  5. ~~~~~~~~~
  6. """
  7. import datetime
  8. import logging
  9. import math
  10. import os
  11. import time,random
  12. from collections import Counter
  13. from itertools import groupby
  14. from operator import itemgetter
  15. import simplejson as json
  16. import xlrd
  17. from bson import ObjectId
  18. from django.conf import settings
  19. from django.contrib import auth
  20. from django.core.cache import cache
  21. from django.core.handlers.wsgi import WSGIRequest
  22. from mongoengine import Q
  23. from mongoengine.errors import NotUniqueError, MultipleObjectsReturned, DoesNotExist
  24. from typing import Iterable, Any, cast, Dict, Optional, TYPE_CHECKING
  25. from apilib import utils_datetime
  26. from apilib.monetary import RMB, Ratio, Percent
  27. from apilib.utils_datetime import to_datetime, dt_to_timestamp, date_to_datetime_ceiling, date_to_datetime_floor, \
  28. timestamp_timeformat
  29. from apilib.utils_json import JsonResponse
  30. from apps.web.ad.models import Advertisement, Advertiser
  31. from apps.web.agent import api
  32. from apps.web.agent.models import Agent
  33. from apps.web.agent.validation import agentSchema
  34. from apps.web.south_intf.zhejiang_fire import ZhejiangNorther, Company
  35. from apps.web.common.models import FAQ, District, WithdrawRecord
  36. from apps.web.common.proxy import ClientRechargeModelProxy, ClientDealerIncomeModelProxy, ClientConsumeModelProxy
  37. from apps.web.common.transaction import WithdrawStatus
  38. from apps.web.common.validation import PASSWORD_RE
  39. from apps.web.constant import Const, DEALER_CONSUMPTION_AGG_KIND_TRANSLATION, \
  40. DEALER_CONSUMPTION_AGG_KIND_UNIT, DeviceOnlineStatus,FAULT_RECORD_STATUS
  41. from apps.web.core import ROLE
  42. from apps.web.core.db import prepare_query
  43. from apps.web.core.exceptions import ServiceException, ManagerServiceTimeOutException, ManagerServiceSerialException
  44. from apps.web.core.helpers import ActionDeviceBuilder
  45. from apps.web.core.messages.sms import managerForgotPwdSMSProvider, \
  46. managerRegisterSMSProvider
  47. from apps.web.core.models import WechatPayApp, OfflineTask, AliApp
  48. from apps.web.core.networking import MessageSender
  49. from apps.web.core.sysparas import SysParas
  50. from apps.web.core.utils import DefaultJsonErrorResponse, JsonErrorResponse, JsonOkResponse
  51. from apps.web.dealer.models import Dealer, DealerRechargeRecord
  52. from apps.web.dealer.proxy import DealerIncomeProxy
  53. from apps.web.device.models import Device, Group, DeviceCommand, DeviceType, PortReport, DeviceDict, \
  54. ManagerInputDev,FaultRecord
  55. from apps.web.management import OfflineTaskType
  56. from apps.web.management.models import ManagerUpScoreRecord, Manager, DummyManagerData
  57. from apps.web.management.utils import get_dealerMap_by_managerId, query_total_dealer_income_top, get_feed_back_stats, \
  58. get_user_stats, query_device_consumption, query_device_income, query_user_consume_frequency
  59. from apps.web.report.models import DeviceDailyStat
  60. from apps.web.user.models import Card, MyUser, RechargeRecord, ServiceProgress, CardRechargeOrder, ConsumeRecord
  61. from apps.web.utils import permission_required, manager_login, advertisement_login, error_tolerate, role_from_user
  62. from taskmanager.mediator import task_caller
  63. if TYPE_CHECKING:
  64. from apps.web.common.models import UserSearchable
  65. from apps.web.core.db import CustomQuerySet
  66. logger = logging.getLogger(__name__)
  67. def login(request):
  68. # type: (WSGIRequest)->JsonResponse
  69. try:
  70. payload = json.loads(request.body)
  71. username, password = payload['username'], payload['password']
  72. if Manager.objects(username = username, domain = settings.MY_DOMAIN).first():
  73. return manager_login(request, logger, username, password)
  74. elif Advertisement.objects(username = username).first():
  75. return advertisement_login(request, logger, username, password)
  76. else:
  77. return JsonResponse({'result': 0, 'description': u'用户名或者密码错误', 'payload': {}})
  78. except Exception as e:
  79. logger.exception('manager login error = %s' % e)
  80. return JsonResponse({'result': 0, 'description': u'登录异常', 'payload': {}})
  81. def logout(request):
  82. # type: (WSGIRequest)->JsonResponse
  83. auth.logout(request)
  84. return JsonResponse({'result': 1})
  85. @error_tolerate(nil = DefaultJsonErrorResponse, logger = logger)
  86. @permission_required(ROLE.manager)
  87. def changePassword(request):
  88. # type: (WSGIRequest)->JsonResponse
  89. currentManager = request.user # type: cast(Manager)
  90. payload = json.loads(request.body)
  91. password = payload['password']
  92. if PASSWORD_RE.match(password) is None:
  93. return JsonErrorResponse(description = u'密码必须大于8位,只能是数字或字母或常见特殊符号')
  94. currentManager.set_password(payload['password'])
  95. return JsonResponse({'result': 1})
  96. #: 设备相关
  97. @permission_required(ROLE.manager)
  98. def getDevDetailList(request):
  99. # type: (WSGIRequest)->JsonResponse
  100. """
  101. 获取设备详情列表
  102. searchKey只能是经销商账号, 设备逻辑码
  103. """
  104. mid = str(request.user.id)
  105. pageIndex = int(request.GET.get('pageIndex', 1))
  106. pageSize = int(request.GET.get('pageSize', 10))
  107. dealerId = request.GET.get('dealerId', None)
  108. startLogicalCode = request.GET.get('startLogicalCode', None)
  109. endLogicalCode = request.GET.get('endLogicalCode', None)
  110. searchKey = request.GET.get('searchKey', None)
  111. dealerFilter = Q()
  112. if not dealerId:
  113. agentIds = [str(agent['_id']) for agent in Agent.get_collection().find({'managerId': mid}, {'_id': True})]
  114. dealerFilter &= Q(agentId__in = agentIds)
  115. if dealerId:
  116. dealerFilter &= Q(id = ObjectId(dealerId))
  117. dealerMap = {str(d['_id']): {'nickname': d['nickname'], 'username': d['username']} for d in
  118. Dealer.get_collection().find(dealerFilter.to_query(Dealer))}
  119. dealerIds = dealerMap.keys()
  120. if startLogicalCode and endLogicalCode and not searchKey:
  121. import re
  122. res = re.findall(r'\d+', '{},{}'.format(startLogicalCode, endLogicalCode))
  123. res = [int(res[0]), int(res[1])]
  124. if max(res) - min(res) > 1000:
  125. return JsonResponse({'result': 2, 'description': u'范围超过1000', 'payload': {}})
  126. start = min(res)
  127. logicalCode_user_input = []
  128. while start <= max(res):
  129. logicalCode_user_input.append(u'{}'.format(start))
  130. start += 1
  131. devices = Device.objects(ownerId__in = dealerIds, logicalCode__in = logicalCode_user_input)
  132. if len(devices) == 0:
  133. devices = Device.objects(ownerId__in = dealerIds)
  134. logicalCode_id = []
  135. for device in devices:
  136. if len(logicalCode_user_input):
  137. dev = re.findall(logicalCode_user_input[0], '{}'.format(device.logicalCode))
  138. if len(dev):
  139. logicalCode_user_input.pop(0)
  140. logicalCode_id.append(device.logicalCode)
  141. devices = Device.objects(ownerId__in = dealerIds, logicalCode__in = logicalCode_id)
  142. else:
  143. devices = Device.objects(ownerId__in = dealerIds).search(searchKey)
  144. total = devices.count()
  145. devNos = []
  146. groupIds = []
  147. for d in devices.paginate(pageIndex, pageSize):
  148. devNos.append(d['devNo'])
  149. if d['groupId']:
  150. groupIds.append(d['groupId'])
  151. groupDict = Group.get_groups_by_group_ids(groupIds)
  152. devs = Device.get_dev_by_nos(devNos) # type: Optional[Dict[str, DeviceDict]]
  153. dataList = []
  154. for devNo, dev in devs.items():
  155. if dev.ownerId not in dealerIds:
  156. continue
  157. group = groupDict.get(dev.groupId, {})
  158. item = {
  159. 'devName': dev.devNo,
  160. 'devType': dev.devType.get('name', u'未指定'),
  161. 'imei': dev.devNo,
  162. 'createdTime': dev['dateTimeAdded'],
  163. 'logicalCode': dev.logicalCode,
  164. 'dealerName': '',
  165. 'address': u'%s:%s' % (group.get('groupName'), group.get('address')),
  166. 'online': u'在线' if dev.online == DeviceOnlineStatus.DEV_STATUS_ONLINE else u'离线',
  167. 'detail': json.dumps(
  168. {
  169. u'设备类型编码': dev.devType.get('code', ''),
  170. u'设备驱动编码': dev.get('driverCode', ''),
  171. u'设备驱动版本': dev.get('driverVersion', ''),
  172. u'当前设备信号强度': dev.signal,
  173. u'设备IMEI': dev.imsi,
  174. u'设备SIM卡ICCID': dev.iccid,
  175. u'心跳间隔': dev['cycle'],
  176. u'脉冲间隔': dev['pulseInterval1'],
  177. u'待机电平': dev['battery'],
  178. u'备注': dev['remarks'],
  179. u'sim卡过期时间': dev.formatSimExpireDate,
  180. u'sim卡状态': dev.simStatus,
  181. u'脉冲宽度': dev['pulseWidth1'],
  182. u'套餐信息': dev.get('washConfig', {}),
  183. }, ensure_ascii = False, encoding = 'utf-8'),
  184. 'lastOffTime': dev.offTime,
  185. 'serverAddress': dev.server,
  186. 'signal': dev.signal,
  187. "disableDevice": dev.get("otherConf", {}).get("disableDevice", False)
  188. }
  189. if dev.ownerId:
  190. item.update(
  191. {'dealerName': u'%s %s' % (dealerMap[dev.ownerId]['nickname'], dealerMap[dev.ownerId]['username'])})
  192. dataList.append(item)
  193. return JsonResponse({
  194. 'result': 1,
  195. 'description': '',
  196. 'payload': {
  197. 'total': total,
  198. 'dataList': dataList
  199. }
  200. })
  201. @permission_required(ROLE.manager)
  202. def sendCommand(request):
  203. # type: (WSGIRequest)->JsonResponse
  204. """
  205. 给设备发送命令并实时返回结果
  206. :param request:
  207. :return:
  208. """
  209. payload = json.loads(request.body)
  210. devNo = payload.get("devNo")
  211. cmdID = payload.get("id")
  212. params = payload.get("params", list())
  213. dev = Device.get_dev(devNo)
  214. if not dev:
  215. return JsonErrorResponse(u"设备获取失败,请尝试重新发送指令")
  216. command = DeviceCommand.objects.filter(id = cmdID, role = request.user.role).first()
  217. if not command:
  218. return JsonErrorResponse(u"命令获取失败,请尝试重新发送指令")
  219. try:
  220. commandDict = command.package_command(dev, params)
  221. except Exception as e:
  222. logger.exception(u"dev <{}>, command <{}> , package command error <{}>".format(devNo, cmdID, e))
  223. return JsonErrorResponse(u"命令发送失败,请尝试重新发送指令")
  224. cmd = commandDict.get("cmd")
  225. try:
  226. result = MessageSender.send(dev, cmd = cmd, payload = commandDict, timeout = 20)
  227. if result.get("rst") == -1:
  228. raise ManagerServiceTimeOutException()
  229. if result.get("rst") == 1:
  230. raise ManagerServiceSerialException()
  231. except ServiceException as se:
  232. return JsonErrorResponse(description = se.result.get("description"))
  233. except Exception as e:
  234. logger.exception('failed to send command, error = %s where command was %s' % (e, str(command)))
  235. return JsonErrorResponse(description = u"指令发送异常")
  236. return JsonResponse({'result': 1, 'description': u'发送成功', 'payload': json.dumps(result)})
  237. def setDevicePristine(request):
  238. """
  239. 暂时不做,暂时不做解绑后防止代理商串货的限制
  240. 厂商侧强制解绑,将设备恢复到只有基本绑定关系等初始值的初始状态
  241. :param request:
  242. :return:
  243. """
  244. # payload = json.loads(request.body)
  245. # check if the devices belong to this manager
  246. return JsonResponse({'result': 0})
  247. #: 处理代理商
  248. @error_tolerate(nil = DefaultJsonErrorResponse)
  249. @permission_required(ROLE.manager)
  250. def addAgents(request):
  251. # type: (WSGIRequest)->JsonResponse
  252. """
  253. 后台给代理商开户
  254. :param request:
  255. :return:
  256. """
  257. currentManager = request.user # type: cast(Manager)
  258. primeAgent = Agent.objects(id = currentManager.primeAgentId).first()
  259. if not primeAgent:
  260. return JsonErrorResponse(description = u'厂商配置数据错误')
  261. payload = json.loads(request.body)
  262. payload.update(
  263. {
  264. 'productName': currentManager.brandName,
  265. 'productLogo': currentManager.logo,
  266. 'managerId': str(currentManager.id)
  267. }
  268. )
  269. payload.update({'trafficCardCost': primeAgent.trafficCardCost})
  270. if 'annualTrafficCost' in payload and payload['annualTrafficCost']:
  271. if RMB(payload['annualTrafficCost']) < primeAgent.trafficCardCost:
  272. return JsonErrorResponse(description = u'代理商流量卡费用下限不能小于流量卡成本价格({})'.format(primeAgent.trafficCardCost))
  273. else:
  274. payload.update({'annualTrafficCost': RMB(payload['annualTrafficCost'])})
  275. else:
  276. payload.update({'annualTrafficCost': primeAgent.trafficCardCost})
  277. payload.update({'withdrawFeeRatioCost': primeAgent.withdrawFeeRatioCost})
  278. if 'withdrawFeeRatio' in payload and payload['withdrawFeeRatio']:
  279. if Ratio(payload['withdrawFeeRatio']) < primeAgent.withdrawFeeRatioCost:
  280. return JsonErrorResponse(
  281. description = u'代理商提现费率不能小于提现费率成本价格(千分之{})'.format(primeAgent.withdrawFeeRatioCost))
  282. else:
  283. payload.update({'withdrawFeeRatio': Ratio(payload['withdrawFeeRatio'])})
  284. else:
  285. payload.update({'withdrawFeeRatio': primeAgent.withdrawFeeRatio})
  286. username = payload.pop('username')
  287. password = payload.pop('password', '1234567')
  288. try:
  289. Agent.create_user(username = username,
  290. password = password,
  291. adShow = currentManager.adShow,
  292. **payload)
  293. except NotUniqueError:
  294. return JsonErrorResponse(description = u'已存在相同信息的代理商')
  295. return JsonOkResponse()
  296. @error_tolerate(nil = DefaultJsonErrorResponse, logger = logger)
  297. @permission_required(ROLE.manager)
  298. def editAgents(request):
  299. # type: (WSGIRequest)->JsonResponse
  300. """
  301. 修改代理商信息
  302. :param request:
  303. :return:
  304. """
  305. payload = agentSchema(json.loads(request.body)) # type: dict
  306. agent = Agent.objects(id = str(payload['id'])).get() # type: Agent
  307. if 'annualTrafficCost' in payload and RMB(payload['annualTrafficCost']) < agent.trafficCardCost:
  308. return JsonErrorResponse(description=u'代理商流量卡费用下限不能小于流量卡成本价格({})'.format(agent.trafficCardCost))
  309. if 'withdrawFeeRatio' in payload and Ratio(payload['withdrawFeeRatio']) < agent.withdrawFeeRatioCost:
  310. return JsonErrorResponse(description=u'代理商提现费率下限不能低于提现费率成本价格(千分之{})'.format(agent.withdrawFeeRatioCost))
  311. if 'managerProfitShare' in payload and Percent(payload['managerProfitShare']) < Percent(0):
  312. return JsonErrorResponse(description=u"代理商设备经营收入比例不能小于0")
  313. updated = agent.update(**payload)
  314. if updated:
  315. return JsonOkResponse()
  316. else:
  317. return JsonErrorResponse(description = u'代理商设置失败')
  318. @error_tolerate(nil = DefaultJsonErrorResponse, logger = logger)
  319. @permission_required(ROLE.manager)
  320. def editAgentPassword(request):
  321. # type: (WSGIRequest)->JsonResponse
  322. try:
  323. payload = json.loads(request.body)
  324. agentId = payload.get('id')
  325. password = payload.get('password')
  326. agent = Agent.objects.get(id = agentId) # type: Agent
  327. agent.set_password(password)
  328. return JsonResponse({'result': 1, 'description': u'修改成功', 'payload': ''})
  329. except DoesNotExist:
  330. return JsonResponse({'result': 0, 'description': u'代理商不存在,请刷新后再试', 'payload': ''})
  331. @permission_required(ROLE.manager)
  332. def getDealersWithdrawalList(request):
  333. # type: (WSGIRequest)->JsonResponse
  334. """
  335. 获取经销商提现列表
  336. :param request:
  337. :return:
  338. """
  339. managerId = str(request.user.id)
  340. pageIndex = int(request.GET.get('pageIndex', 1))
  341. pageSize = int(request.GET.get('pageSize', 10))
  342. status = request.GET.get('status', None)
  343. searchKey = request.GET.get('searchKey', None)
  344. agentIds = [str(_['_id']) for _ in Agent.get_collection().find({'managerId': managerId}, {'_id': 1})]
  345. dealerIds = [str(_['_id']) for _ in Dealer.get_collection().find({'agentId': {'$in': agentIds}}, {'_id': 1})]
  346. query = WithdrawRecord.objects(ownerId__in = dealerIds, role = ROLE.dealer, status = int(status)).search(
  347. searchKey)._query
  348. front = (pageIndex - 1) if pageIndex >= 1 else 0
  349. records = WithdrawRecord.get_collection().find(query) \
  350. .sort('postTime', -1) \
  351. .skip(front * pageSize) \
  352. .limit(pageSize) # type: Iterable[dict]
  353. total = WithdrawRecord.objects(status = int(status), ownerId__in = dealerIds).search(searchKey).count()
  354. def norm(dict_, key):
  355. # type: (dict, str)->Any
  356. return dict_.get(key, '')
  357. dataList = [
  358. {
  359. 'name': norm(r, 'dealerName'),
  360. 'tel': norm(r, 'userTel'),
  361. 'dateTime': norm(r, 'postTime'),
  362. 'orderNo': norm(r, 'order'),
  363. 'actualPay': norm(r, 'actualPay'),
  364. 'cardId': norm(r, 'accountCode'),
  365. 'cardUserName': norm(r, 'cardUserName'),
  366. 'bankName': norm(r, 'parentBankName'),
  367. 'subBankName': norm(r, 'subBankName'),
  368. 'operResult': norm(r, 'status'),
  369. 'payType': norm(r, 'payType'),
  370. 'amount': norm(r, 'dealerBalance'),
  371. 'remarks': norm(r, 'remarks')
  372. }
  373. for r in records
  374. ]
  375. return JsonResponse(
  376. {
  377. 'result': 1,
  378. 'description': '',
  379. 'payload': {
  380. 'total': total,
  381. 'dataList': dataList
  382. }
  383. })
  384. @permission_required(ROLE.manager)
  385. def suspendDealer(request):
  386. """
  387. 对部分违反准则的经销商予以禁用
  388. :param request:
  389. :return:
  390. """
  391. return JsonErrorResponse(description = u'暂不支持')
  392. @error_tolerate(logger = logger)
  393. @permission_required(ROLE.manager)
  394. def updateDeviceCardExpireDate(request):
  395. payload = json.loads(request.body)
  396. expireDate = str(payload['expireDate'])
  397. devNoList = payload['idList']
  398. newExpire = to_datetime(expireDate, '%Y-%m-%d')
  399. Device.get_collection().update_many({'devNo': {'$in': devNoList}}, {'$set': {'expireDate': newExpire}}, upsert = False)
  400. Device.invalid_many_device_cache(devNoList)
  401. return JsonResponse({'result': 1, 'description': u'修改成功', 'payload': ''})
  402. # third parties
  403. def collectWechatSubscriptionChatEntries(request):
  404. # type: (WSGIRequest)->JsonResponse
  405. """
  406. 备份用户发往公众号的聊天记录(微信只保留三天),为了完整的追溯事件。有必要进行保留
  407. 此接口对应微信推送的请求
  408. :param request:
  409. :return:
  410. """
  411. def getNotificationList(request):
  412. # type: (WSGIRequest)->JsonResponse
  413. """
  414. 管理平台获取公告列表
  415. :param request:
  416. :return:
  417. """
  418. return JsonResponse(
  419. {
  420. "result": 1,
  421. "description": None,
  422. 'payload': {
  423. "total": 0,
  424. "dataList": []
  425. }
  426. }
  427. )
  428. # TODO 工人管理
  429. @permission_required(ROLE.manager)
  430. def getStaffDetailList(request):
  431. # type: (WSGIRequest)->JsonResponse
  432. return JsonResponse(
  433. {
  434. 'result': 0,
  435. 'description': None,
  436. 'payload': {
  437. 'dataList': []
  438. }
  439. }
  440. )
  441. # TODO 工人管理
  442. @permission_required(ROLE.manager, ROLE.supermanager)
  443. def getChargeList(request):
  444. # type: (WSGIRequest)->JsonResponse
  445. return JsonResponse(
  446. {
  447. 'result': 1,
  448. 'description': None,
  449. 'payload': {
  450. 'dataList': []
  451. }
  452. }
  453. )
  454. # TODO 添加通告消息
  455. @permission_required(ROLE.manager)
  456. def addNotice(request):
  457. # type: (WSGIRequest)->JsonResponse
  458. return JsonResponse(
  459. {
  460. 'result': 1,
  461. 'description': None,
  462. 'payload': {}
  463. }
  464. )
  465. # TODO 修改通告消息
  466. @permission_required(ROLE.manager)
  467. def editNotice(request):
  468. # type: (WSGIRequest)->JsonResponse
  469. return JsonResponse(
  470. {
  471. 'result': 1,
  472. 'description': None,
  473. 'payload': {}
  474. }
  475. )
  476. # TODO 删除通告消息
  477. @permission_required(ROLE.manager)
  478. def deleteNotice(request):
  479. # type: (WSGIRequest)->JsonResponse
  480. return JsonResponse(
  481. {
  482. 'result': 1,
  483. 'description': None,
  484. 'payload': {}
  485. }
  486. )
  487. #### FAQ
  488. @error_tolerate(nil = DefaultJsonErrorResponse)
  489. @permission_required(ROLE.manager)
  490. def getFAQDetailList(request):
  491. # type: (WSGIRequest)->JsonResponse
  492. """
  493. 管理平台获取FAQ列表
  494. :param request:
  495. :return:
  496. """
  497. mid = str(request.user.id)
  498. faqs = FAQ.objects(managerId = mid)
  499. return JsonResponse(
  500. {
  501. 'result': 1,
  502. 'description': None,
  503. 'payload': {
  504. 'dataList': [faq.to_dict() for faq in faqs]
  505. }
  506. }
  507. )
  508. @error_tolerate(nil = DefaultJsonErrorResponse)
  509. @permission_required(ROLE.manager)
  510. def addFAQ(request):
  511. # type: (WSGIRequest)->JsonResponse
  512. payload = json.loads(request.body)
  513. mid = str(request.user.id)
  514. payload.update({'managerId': mid})
  515. faq = FAQ(**payload).save()
  516. return JsonResponse(
  517. {
  518. 'result': 1 if faq else 0,
  519. 'description': None,
  520. 'payload': {}
  521. }
  522. )
  523. @permission_required(ROLE.manager)
  524. def editFAQ(request):
  525. # type: (WSGIRequest)->JsonResponse
  526. payload = json.loads(request.body)
  527. updated = FAQ.objects(id = str(payload['id'])).update(**payload)
  528. return JsonResponse(
  529. {
  530. 'result': 1 if updated else 0,
  531. 'description': None,
  532. 'payload': {}
  533. }
  534. )
  535. @error_tolerate(nil = DefaultJsonErrorResponse)
  536. @permission_required(ROLE.manager)
  537. def deleteFAQ(request):
  538. # type: (WSGIRequest)->JsonResponse
  539. ids = json.loads(request.body)['ids']
  540. map(lambda _: _.delete(), FAQ.objects(id__in = ids))
  541. return JsonResponse({'result': 1, 'description': '', 'payload': {}})
  542. @error_tolerate(nil = DefaultJsonErrorResponse)
  543. @permission_required(ROLE.manager)
  544. def onPoints(request):
  545. # type: (WSGIRequest)->JsonResponse
  546. payload = json.loads(request.body)
  547. coins = int(payload['coins'])
  548. devNo = Device.get_devNo_by_logicalCode(payload['logicalCode'])
  549. if not devNo:
  550. return JsonResponse({'result': 0, 'description': u'设备号不存在'})
  551. dev = Device.get_dev(devNo)
  552. try:
  553. dealer = Dealer.objects.get(id = ObjectId(dev['ownerId']))
  554. agent = Agent.objects.get(id = ObjectId(dealer.agentId))
  555. if agent.managerId != str(request.user.id):
  556. return JsonResponse({'result': 0, 'description': u'该设备不属于您的厂家哦!', 'payload': {}})
  557. except (MultipleObjectsReturned, DoesNotExist) as e:
  558. logger.exception('cannot get agent or dealer, error = %s' % (e,))
  559. return JsonResponse({'result': 0, 'description': u'没有找到经销商和代理商数据', 'payload': {}})
  560. packageId = ''
  561. for pid, conf in dev['washConfig'].items():
  562. if int(conf['coins']) == coins:
  563. packageId = pid
  564. break
  565. continue
  566. if not packageId:
  567. return JsonResponse(
  568. {
  569. 'result': 0,
  570. 'description': u'没有找到对应的套餐信息,请您重新选择其他分值.或者检查设备是否没有注册到系统',
  571. 'payload': {}
  572. }
  573. )
  574. smartBox = ActionDeviceBuilder.create_action_device(dev)
  575. try:
  576. smartBox.start(packageId)
  577. except ServiceException, e:
  578. logger.exception('start device(%s) failed error = %s' % (devNo, e.result.get('description')))
  579. return JsonResponse({'result': 0, 'description': e.result.get('description'), 'payload': {}})
  580. except Exception, e:
  581. logger.exception('start device(%s) failed error = %s' % (devNo, e))
  582. return JsonResponse({'result': 0, 'description': u'系统错误', 'payload': {}})
  583. dealer = Dealer.objects(id = dev['ownerId']).first()
  584. group = Group.get_group(dev['groupId'])
  585. record = ManagerUpScoreRecord(devNo = devNo,
  586. logicalCode = payload['logicalCode'],
  587. coins = coins,
  588. devTypeName = dev['devType']['name'],
  589. dealerTel = getattr(dealer, 'username', ''),
  590. dealerName = getattr(dealer, 'nickname', ''),
  591. address = group.get('address', ''),
  592. groupName = group['groupName'],
  593. managerId = str(request.user.id))
  594. record.save()
  595. return JsonResponse({'result': 1, 'description': u'上分成功!', 'payload': {}})
  596. @error_tolerate(nil = DefaultJsonErrorResponse)
  597. @permission_required(ROLE.manager)
  598. def onPointsRecords(request):
  599. # type: (WSGIRequest)->JsonResponse
  600. mid = str(request.user.id)
  601. pageIndex = int(request.GET.get('pageIndex', 1))
  602. pageSize = int(request.GET.get('pageSize', 10))
  603. records = ManagerUpScoreRecord.objects(managerId = mid).order_by('-createdTime')
  604. return JsonResponse(
  605. {
  606. 'result': 1,
  607. 'description': '',
  608. 'payload': {
  609. 'total': records.count(),
  610. 'dataList': [_.to_dict() for _ in records.skip((pageIndex - 1) * pageSize).limit(pageSize)]
  611. }
  612. })
  613. @error_tolerate(nil = DefaultJsonErrorResponse)
  614. @permission_required(ROLE.manager)
  615. def editDealerPassword(request):
  616. # type: (WSGIRequest)->JsonResponse
  617. try:
  618. payload = json.loads(request.body)
  619. dealerId = payload.get('id')
  620. password = payload.get('password')
  621. dealer = Dealer.objects.get(id = dealerId)
  622. dealer.set_password(password)
  623. return JsonResponse({'result': 1, 'description': u'修改成功', 'payload': ''})
  624. except DoesNotExist:
  625. return JsonResponse({'result': 0, 'description': u'经销商不存在,请刷新后再试', 'payload': ''})
  626. @error_tolerate(nil = DefaultJsonErrorResponse)
  627. @permission_required(ROLE.manager)
  628. def unlockDealer(request):
  629. # type: (WSGIRequest)->JsonResponse
  630. payload = json.loads(request.body)
  631. dealerId = payload.get('id')
  632. dealer = Dealer.objects.get(id = str(dealerId))
  633. dealer.unlock_login()
  634. return JsonResponse({'result': 1, 'description': u'解锁成功!'})
  635. @error_tolerate(nil = DefaultJsonErrorResponse)
  636. @permission_required(ROLE.manager)
  637. def unlockAgent(request):
  638. # type: (WSGIRequest)->JsonResponse
  639. payload = json.loads(request.body)
  640. agentId = payload.get('id')
  641. agent = Agent.objects.get(id = str(agentId))
  642. agent.unlock_login()
  643. return JsonResponse({'result': 1, 'description': u'解锁成功!'})
  644. @permission_required(ROLE.manager, ROLE.advertiser, ROLE.advertisement)
  645. def getCurrentUserInfo(request):
  646. # type: (WSGIRequest)->JsonResponse
  647. if request.user.is_authenticated():
  648. role = role_from_user(request.user)
  649. if role == ROLE.manager:
  650. manager = request.user # type: Manager
  651. else:
  652. mid = request.user.managerId
  653. manager = Manager.objects.get(id = ObjectId(mid)) # type: Manager
  654. return JsonResponse(
  655. {
  656. "result": 1,
  657. "description": "",
  658. "payload":
  659. {
  660. "nickname": request.user.nickname,
  661. "brandName": manager.brandName,
  662. "feature_map": manager.feature_boolean_map,
  663. "logo": manager.logo,
  664. "role": role
  665. }
  666. })
  667. else:
  668. return JsonResponse(
  669. {
  670. "result": 1,
  671. "description": "",
  672. "payload":
  673. {
  674. "nickname": "",
  675. "brandName": "管理后台",
  676. "logo": ""
  677. }
  678. })
  679. @error_tolerate(nil = DefaultJsonErrorResponse)
  680. @permission_required(ROLE.manager)
  681. def getManagerConfigs(request):
  682. # type: (WSGIRequest)->JsonResponse
  683. """
  684. 获取厂商定向配置项
  685. :param request:
  686. :return:
  687. """
  688. return JsonResponse({'result': 1, 'description': '', 'payload': {'configs': request.user.configs}})
  689. @error_tolerate(nil = DefaultJsonErrorResponse)
  690. @permission_required(ROLE.manager)
  691. def setManagerConfigs(request):
  692. # type: (WSGIRequest)->JsonResponse
  693. """
  694. 设置厂商定向配置项
  695. :param request:
  696. :return:
  697. """
  698. manager = request.user # type: cast(MyUser)
  699. payload = json.loads(request.body)
  700. manager.set_configs(payload['params'])
  701. return JsonResponse({'result': 1, 'description': u'更新成功', 'payload': {}})
  702. @error_tolerate(nil = DefaultJsonErrorResponse)
  703. @permission_required(ROLE.manager)
  704. def getCommandByDevice(request):
  705. # type: (WSGIRequest)->JsonResponse
  706. """
  707. 获取指令
  708. :param request:
  709. :return:
  710. """
  711. logicalCode = request.GET.get('logicalCode')
  712. commands = DeviceCommand.common_and_type_specific(logicalCode = logicalCode, commander = request.user)
  713. # dataList = [ {'name': c.name, 'command': c.template.safe_substitute(IMEI=device['devNo'])} for c in commands ]
  714. return JsonResponse({'result': 1, 'description': None, 'payload': {'dataList': commands}})
  715. ############
  716. #: 离线任务相关
  717. ############
  718. @error_tolerate(nil = DefaultJsonErrorResponse)
  719. @permission_required(ROLE.manager)
  720. def newOfflineTask(request):
  721. # type: (WSGIRequest)->JsonResponse
  722. """
  723. 新建离线任务
  724. :param request:
  725. :return:
  726. """
  727. return JsonResponse({'result': 1, 'description': None, 'payload': {}})
  728. @error_tolerate(nil = DefaultJsonErrorResponse)
  729. @permission_required(ROLE.manager)
  730. def getOfflineTaskList(request):
  731. # type: (WSGIRequest)->JsonResponse
  732. """
  733. 获取离线任务列表
  734. :param request:
  735. :return:
  736. """
  737. current_user = request.user # type: Manager
  738. page_index = int(request.GET.get('pageIndex', 1))
  739. page_size = int(request.GET.get('pageSize', 10))
  740. search_key = request.GET.get('searchKey', None)
  741. tasks = OfflineTask.objects(ownerId = current_user.id,
  742. role = current_user.role).search(search_key).order_by('-dateTimeAdded')
  743. total = tasks.count()
  744. return JsonOkResponse(
  745. payload = {
  746. 'dataList': [t.to_dict() for t in tasks.paginate(pageSize = page_size, pageIndex = page_index)],
  747. 'total': total
  748. })
  749. @error_tolerate(nil = DefaultJsonErrorResponse)
  750. @permission_required(ROLE.manager)
  751. def getOfflineTaskStatus(request):
  752. # type: (WSGIRequest)->JsonResponse
  753. task_id = request.GET.get('id')
  754. if not task_id:
  755. return JsonErrorResponse(description = u'查询ID为空')
  756. task = OfflineTask.objects(id = str(task_id)).get() # type: OfflineTask
  757. return JsonOkResponse(payload = task.status)
  758. #: 广告主相关
  759. @error_tolerate(nil = DefaultJsonErrorResponse)
  760. @permission_required(ROLE.manager)
  761. def getAdvertiserList(request):
  762. # type: (WSGIRequest)->JsonResponse
  763. """
  764. 获取广告主列表
  765. :param request:
  766. :return:
  767. """
  768. managerId = str(request.user.id)
  769. pageIndex = int(request.GET.get('pageIndex', 1))
  770. pageSize = int(request.GET.get('pageSize', 10))
  771. searchKey = request.GET.get('searchKey')
  772. activited = request.GET.get('activited')
  773. if activited:
  774. cursor = Advertiser.objects(managerId = managerId, activited = json.loads(activited))
  775. else:
  776. cursor = Advertiser.objects(managerId = managerId)
  777. total = cursor.count()
  778. advertisers = [_.to_dict() for _ in
  779. cursor.search(searchKey).order_by('-dateTimeAdded').paginate(pageIndex, pageSize)]
  780. return JsonResponse({'result': 1, 'description': None, 'payload': {'total': total, 'dataList': advertisers}})
  781. @error_tolerate(nil = DefaultJsonErrorResponse)
  782. @permission_required(ROLE.manager)
  783. def addAdvertiser(request):
  784. # type: (WSGIRequest)->JsonResponse
  785. """
  786. 管理员添加广告主
  787. :param request:
  788. :return:
  789. """
  790. payload = json.loads(request.body)
  791. payload['managerId'] = str(request.user.id)
  792. try:
  793. Advertiser.create_user(**payload)
  794. except NotUniqueError:
  795. return JsonResponse({'result': 0, 'description': u'手机号已经存在'})
  796. return JsonResponse({'result': 1, 'description': None, 'payload': {}})
  797. @error_tolerate(nil = DefaultJsonErrorResponse)
  798. @permission_required(ROLE.manager)
  799. def editAdvertiser(request):
  800. # type: (WSGIRequest)->JsonResponse
  801. """
  802. 编辑广告主
  803. :param request:
  804. :return:
  805. """
  806. payload = json.loads(request.body)
  807. advertiser = Advertiser.objects(id = payload.pop('id')).get() # type: Advertiser
  808. updated = advertiser.update(**payload)
  809. logger.info('{0!r} edited {1!r}, payload={2} updated={3}'.format(request.user, advertiser, payload, updated))
  810. return JsonResponse({'result': 1, 'description': u'编辑成功', 'payload': {}})
  811. @error_tolerate(nil = DefaultJsonErrorResponse)
  812. @permission_required(ROLE.manager)
  813. def toggleAdvertiserActivation(request):
  814. # type: (WSGIRequest)->JsonResponse
  815. """
  816. :param request:
  817. :return:
  818. """
  819. payload = json.loads(request.body)
  820. advertiser = Advertiser.objects(id = payload['id'], managerId = str(request.user.id)).first()
  821. if advertiser is None:
  822. return JsonResponse({'result': 0, 'description': u'广告主不存在'})
  823. updated = advertiser.update(activited = bool(payload['activited']))
  824. logger.info('{manager!r} toggled {advertiser!r} status from({old_value}) to ({new_value}) updated={updated}'
  825. .format(manager = request.user,
  826. advertiser = advertiser,
  827. old_value = advertiser.activited,
  828. new_value = payload['activited'],
  829. updated = updated))
  830. return JsonResponse({'result': 1, 'description': u'修改成功'})
  831. @error_tolerate(nil = DefaultJsonErrorResponse)
  832. @permission_required(ROLE.manager)
  833. def setAdvertiserQuota(request):
  834. # type: (WSGIRequest)->JsonResponse
  835. """
  836. 厂商配置广告商效果额度
  837. :param request:
  838. :return:
  839. """
  840. payload = json.loads(request.body)
  841. advertiser = Advertiser.objects(id = payload['id'], managerId = str(request.user.id)).first()
  842. if advertiser is None:
  843. return JsonResponse({'result': 0, 'description': u'广告主不存在'})
  844. old_quota = advertiser.quota
  845. quota = int(payload['quota'])
  846. if quota < 0 or quota > Const.A_HUNDRED_MILLION:
  847. return JsonResponse({'result': 0, 'description': u'额度不合法,最小等于0,最大等于1亿'})
  848. updated = advertiser.update(quota = quota)
  849. logger.info('{manager!r} updated {advertiser!r} quota from({old_quota}) to ({new_quota}) updated={updated}'
  850. .format(manager = request.user,
  851. advertiser = advertiser,
  852. old_quota = old_quota,
  853. new_quota = quota,
  854. updated = updated))
  855. return JsonResponse({'result': 1, 'description': u'配置成功'})
  856. @error_tolerate(nil = DefaultJsonErrorResponse)
  857. # @permission_required(ROLE.manager)
  858. def initCardsBalance(request):
  859. # type: (WSGIRequest)->JsonResponse
  860. payload = json.loads(request.body)
  861. startNo = payload['cardNoStart']
  862. endNo = payload['cardNoEnd']
  863. agentId = payload['agentId']
  864. balance = float(payload['money'])
  865. while int(endNo) >= int(startNo) > 0:
  866. try:
  867. Card.objects.filter(agentId = agentId, cardNo = str(startNo)).delete()
  868. newCard = Card(balance = balance, agentId = agentId, cardNo = str(startNo), cardType = 'ID')
  869. newCard.save()
  870. except Exception as e:
  871. logger.exception('initCardsBalance error=%s' % e)
  872. return JsonResponse({'result': 0, 'description': u'操作异常哦'})
  873. finally:
  874. startNo = int(startNo) + 1
  875. return JsonResponse({'result': 1, 'description': u'分配成功'})
  876. @error_tolerate(nil = DefaultJsonErrorResponse)
  877. @permission_required(ROLE.manager)
  878. def getChargeSIMCardSettlementList(request):
  879. # type: (WSGIRequest)->JsonResponse
  880. managerId = str(request.user.id)
  881. startTime = datetime.datetime.strptime(request.GET.get('startTime') + ' 00:00:00', '%Y-%m-%d %H:%M:%S')
  882. endTime = datetime.datetime.strptime(request.GET.get('endTime') + ' 23:59:59', '%Y-%m-%d %H:%M:%S')
  883. agentId = request.GET.get('agentId', '')
  884. dealerId = request.GET.get('dealerId', '')
  885. if agentId == '' and dealerId == '':
  886. agentsIdList = [str(_['_id']) for _ in Agent.get_collection().find({'managerId': managerId}, {'_id': 1})]
  887. dealersIdList = [str(_['_id']) for _ in
  888. Dealer.get_collection().find({'agentId': {'$in': agentsIdList}}, {'_id': 1})]
  889. simRechargeRecords = DealerRechargeRecord.objects(
  890. dealerId__in = dealersIdList,
  891. status = DealerRechargeRecord.PayState.Paid,
  892. finishedTime__gte = startTime,
  893. finishedTime__lte = endTime
  894. )
  895. elif agentId != '' and dealerId == '':
  896. dealersIdList = [str(_['_id']) for _ in Dealer.get_collection().find({'agentId': agentId}, {'_id': 1})]
  897. simRechargeRecords = DealerRechargeRecord.objects(
  898. dealerId__in = dealersIdList,
  899. status = DealerRechargeRecord.PayState.Paid,
  900. finishedTime__gte = startTime,
  901. finishedTime__lte = endTime
  902. )
  903. elif agentId != '' and dealerId != '':
  904. simRechargeRecords = DealerRechargeRecord.objects(
  905. dealerId = dealerId,
  906. status = DealerRechargeRecord.PayState.Paid,
  907. finishedTime__gte = startTime,
  908. finishedTime__lte = endTime
  909. )
  910. else:
  911. return JsonResponse({'result': 0, 'description': u'错误的查询方式'})
  912. pageIndex = int(request.GET.get('pageIndex', 1))
  913. pageSize = int(request.GET.get('pageSize', 10))
  914. dataList = []
  915. for simRechargeRecord in simRechargeRecords.order_by('-finishedTime').paginate(pageIndex,
  916. pageSize): # type: DealerRechargeRecord
  917. dealer = Dealer.objects(id = simRechargeRecord.dealerId).first()
  918. if not dealer:
  919. return JsonResponse({'result': 0, 'description': u'该经销商用户不存在'})
  920. agent = Agent.objects(id = dealer.agentId).first()
  921. if not agent:
  922. return JsonResponse({'result': 0, 'description': u'该代理商用户不存在'})
  923. device = Device.objects(devNo = simRechargeRecord.items[0]['devNo']).first()
  924. if not device:
  925. return JsonResponse({'result': 0, 'description': u'该设备信息不存在'})
  926. try:
  927. sumPrice = simRechargeRecord.sum_of_price
  928. except Exception as e:
  929. continue
  930. item = {
  931. 'orderNo': simRechargeRecord.orderNo,
  932. 'dealerName': dealer.nickname,
  933. 'dealerTel': dealer.username,
  934. 'agentName': agent.nickname,
  935. 'logicalCode': device.logicalCode,
  936. 'devType': device.devTypeName,
  937. 'dateTimeAdded': device.dateTimeAdded,
  938. 'chargeMoney': sumPrice,
  939. 'chargeTime': simRechargeRecord.to_js_timestamp(simRechargeRecord.finishedTime)
  940. }
  941. dataList.append(item)
  942. return JsonResponse(
  943. {
  944. 'result': 1,
  945. 'description': u'',
  946. 'payload': {
  947. 'total': simRechargeRecords.count(),
  948. 'dataList': dataList
  949. }
  950. }
  951. )
  952. @error_tolerate(nil = DefaultJsonErrorResponse)
  953. @permission_required(ROLE.manager)
  954. def getWithdrawSettlementList(request):
  955. # type: (WSGIRequest)->JsonResponse
  956. managerId = str(request.user.id)
  957. startTime = datetime.datetime.strptime(request.GET.get('startTime') + ' 00:00:00', '%Y-%m-%d %H:%M:%S')
  958. endTime = datetime.datetime.strptime(request.GET.get('endTime') + ' 23:59:59', '%Y-%m-%d %H:%M:%S')
  959. agentsIdList = [str(_['_id']) for _ in Agent.get_collection().find({'managerId': managerId}, {'_id': 1})]
  960. dealersIdList = [str(_['_id']) for _ in
  961. Dealer.get_collection().find({'agentId': {'$in': agentsIdList}}, {'_id': 1})]
  962. withdrawRecords = WithdrawRecord.objects(
  963. ownerId__in = dealersIdList, role = ROLE.dealer,
  964. status = WithdrawStatus.SUCCEEDED,
  965. postTime__gte = startTime,
  966. postTime__lte = endTime
  967. )
  968. pageIndex = int(request.GET.get('pageIndex', 1))
  969. pageSize = int(request.GET.get('pageSize', 10))
  970. dataList = []
  971. for withdrawRecord in withdrawRecords.order_by('-postTime').paginate(pageIndex, pageSize): # type: WithdrawRecord
  972. dealer = Dealer.objects(id = withdrawRecord.ownerId).first()
  973. if not dealer:
  974. return JsonResponse({'result': 0, 'description': u'该经销商用户不存在'})
  975. payload = {
  976. 'orderNo': withdrawRecord.order,
  977. 'dealerName': dealer.nickname,
  978. 'dealerTel': dealer.username,
  979. 'withdrawMoney': withdrawRecord.amount,
  980. 'withdrawTime': withdrawRecord.to_js_timestamp(withdrawRecord.postTime)
  981. }
  982. dataList.append(payload)
  983. return JsonResponse(
  984. {
  985. 'result': 1,
  986. 'description': u'',
  987. 'payload':
  988. {
  989. 'total': withdrawRecords.count(),
  990. 'dataList': dataList
  991. }
  992. }
  993. )
  994. @error_tolerate(nil = JsonErrorResponse(u'生成报表失败'))
  995. @permission_required(ROLE.manager)
  996. def exportExcel(request):
  997. # type: (WSGIRequest)->JsonResponse
  998. manager = request.user # type: cast(Manager)
  999. def get_offline_task_name(task_type, user, start_time, end_time):
  1000. tmp_list = [task_type]
  1001. tmp_list.append(user.username)
  1002. tmp_list.append(u'%s至%s' % (start_time, end_time))
  1003. tmp_list.append(str(utils_datetime.generate_timestamp_ex()))
  1004. offline_task_name = '-'.join(tmp_list)
  1005. return '-'.join(tmp_list).replace("/", "_")
  1006. query = prepare_query(request.GET)
  1007. queryAttrs = query.attrs
  1008. queryAttrs['managerId'] = str(manager.id)
  1009. queryAttrs['dateTimeAdded__lte'] = dt_to_timestamp(queryAttrs['dateTimeAdded__lte'])
  1010. queryAttrs['dateTimeAdded__gte'] = dt_to_timestamp(queryAttrs['dateTimeAdded__gte'])
  1011. if queryAttrs['type'] == 'settlementChargeCard':
  1012. task_type = OfflineTaskType.SIM_CHARGE
  1013. process_func_name = 'generate_simCharge_excel_report'
  1014. elif queryAttrs['type'] == 'settlementWithdraw':
  1015. task_type = OfflineTaskType.DEALER_WITHDRAW
  1016. process_func_name = 'generate_dealerWithDraw_excel_report'
  1017. elif queryAttrs['type'] == 'chargeCard':
  1018. task_type = OfflineTaskType.USER_RECHARGE_CARD
  1019. process_func_name = 'generate_biz_stats_for_manager'
  1020. elif queryAttrs['type'] == 'charge':
  1021. task_type = OfflineTaskType.USER_RECHARGE
  1022. process_func_name = 'generate_biz_stats_for_manager'
  1023. elif queryAttrs['type'] == 'consumption':
  1024. task_type = OfflineTaskType.CONSUME_ORDER_REPORT
  1025. process_func_name = 'manager_export_consume_order_excel_from_db'
  1026. else:
  1027. return JsonErrorResponse(description = u'不支持的导出类型')
  1028. offline_task_name = get_offline_task_name(
  1029. task_type = task_type,
  1030. user = manager,
  1031. start_time = query.raw.get('startTime', ''),
  1032. end_time = query.raw.get('endTime', ''))
  1033. file_path, offline_task = OfflineTask.issue_export_report(offline_task_name = offline_task_name,
  1034. process_func_name = process_func_name,
  1035. task_type = task_type,
  1036. userid = str(manager.id),
  1037. role = ROLE.manager)
  1038. task_caller(func_name = str(offline_task.process_func_name),
  1039. offline_task_id = str(offline_task.id),
  1040. filepath = file_path,
  1041. queryAttrs = queryAttrs)
  1042. return JsonResponse({
  1043. 'result': 1,
  1044. 'description': u'请前往离线任务查看任务处理情况',
  1045. 'payload': str(offline_task.id)
  1046. })
  1047. @permission_required(ROLE.manager)
  1048. def getDevMapChart(request):
  1049. # type: (WSGIRequest)->JsonResponse
  1050. currentManager = request.user # type: Manager
  1051. agentIdList = [str(_['_id']) for _ in
  1052. list(Agent.get_collection().find({'managerId': str(currentManager.id)}, {'_id': 1}))]
  1053. dealerIdList = [str(_['_id']) for _ in
  1054. list(Dealer.get_collection().find({'agentId': {'$in': agentIdList}}, {'_id': 1}))]
  1055. if currentManager.supports('show_for_jiuheng'):
  1056. devList = list(Device.get_collection().find(
  1057. {'ownerId': {'$in': dealerIdList}, 'devType.code': {'$in': ['100206', '100224', '100202']}},
  1058. {'_id': 0, 'devNo': 1, 'logicalCode': 1, 'cycle': 1, 'groupId': 1}
  1059. ))
  1060. else:
  1061. devList = list(Device.get_collection().find(
  1062. {'ownerId': {'$in': dealerIdList}},
  1063. {'_id': 0, 'devNo': 1, 'logicalCode': 1, 'cycle': 1, 'groupId': 1}
  1064. ))
  1065. group_id_list = list(set([dev['groupId'] for dev in devList]))
  1066. groups = Group.get_groups_by_group_ids(group_id_list)
  1067. def get_province(pvc):
  1068. if pvc == u'内蒙古自治区':
  1069. pvc = u'内蒙古'
  1070. elif pvc == u'黑龙江省':
  1071. pvc = u'黑龙江'
  1072. else:
  1073. pvc = pvc[0:2]
  1074. return pvc
  1075. busy = 0
  1076. online = 0
  1077. offline = 0
  1078. deviceDict = {}
  1079. for _ in devList:
  1080. deviceDict[_['devNo']] = {
  1081. 'logicalCode': _['logicalCode'],
  1082. 'cycle': _.get('cycle', Const.DEV_CYCLE_DEFAULT)
  1083. }
  1084. group = groups.get(_['groupId'])
  1085. if not group:
  1086. logger.error('{} has no group.'.format(_['devNo']))
  1087. province = u'未知'
  1088. else:
  1089. distinct_id = group.get('districtId')
  1090. if not distinct_id:
  1091. logger.error('{} has no distinct_id.'.format(_['devNo']))
  1092. else:
  1093. district = District.get_district(distinct_id)
  1094. if not district:
  1095. logger.error('distinct({}) of {} not exists.'.format(str(distinct_id), _['devNo']))
  1096. province = u'未知'
  1097. else:
  1098. province = district.split(' ')[0]
  1099. deviceDict[_['devNo']].update({'province': province})
  1100. counter = {}
  1101. for item in Device.get_many_device_status_cache(deviceDict).values():
  1102. device = DeviceDict(item) # type: DeviceDict
  1103. if device.status == 1:
  1104. busy += 1
  1105. if device.online == 1:
  1106. online += 1
  1107. elif device.online == 0:
  1108. offline += 1
  1109. province = device['province']
  1110. if province not in counter:
  1111. counter[province] = 0
  1112. counter[province] += 1
  1113. dataList = [{'name': get_province(province), 'value': count} for province, count in counter.items()]
  1114. if currentManager.id == ObjectId('59974b4b8732d6480fb699e5'):
  1115. return JsonResponse({'result': 1, 'description': u"", 'payload': {
  1116. "busy": int(offline*0.7),
  1117. "online": offline,
  1118. "offline": online-2000,
  1119. "dataList": dataList
  1120. }})
  1121. else:
  1122. return JsonResponse({'result': 1, 'description': u"", 'payload': {
  1123. "busy": busy,
  1124. "online": online,
  1125. "offline": offline,
  1126. "dataList": dataList
  1127. }})
  1128. @permission_required(ROLE.manager)
  1129. def getAllDeviceIncomeList(request):
  1130. # type: (WSGIRequest)->JsonResponse
  1131. def fake_response():
  1132. monthDataList = [{'lineCoins':90000,'payIncome':800000},{'lineCoins':90000,'payIncome':802000},{'lineCoins':90000,'payIncome':804000},
  1133. {'lineCoins':90000,'payIncome':806000},{'lineCoins':90000,'payIncome':808000},{'lineCoins':90000,'payIncome':810000},
  1134. {'lineCoins':90000,'payIncome':812000},{'lineCoins':90000,'payIncome':814000},{'lineCoins':90000,'payIncome':816000},
  1135. {'lineCoins':90000,'payIncome':818000},{'lineCoins':90000,'payIncome':820000},{'lineCoins':90000,'payIncome':822000},
  1136. {'lineCoins':90000,'payIncome':824000},{'lineCoins':90000,'payIncome':826000},{'lineCoins':90000,'payIncome':828000},
  1137. {'lineCoins':90000,'payIncome':830000},{'lineCoins':90000,'payIncome':832000},{'lineCoins':90000,'payIncome':834000},
  1138. {'lineCoins':90000,'payIncome':836000},{'lineCoins':90000,'payIncome':838000},{'lineCoins':90000,'payIncome':840000},
  1139. {'lineCoins':90000,'payIncome':842000},{'lineCoins':90000,'payIncome':844000},{'lineCoins':90000,'payIncome':846000},
  1140. {'lineCoins':90000,'payIncome':848000},{'lineCoins':90000,'payIncome':850000},{'lineCoins':90000,'payIncome':852000},
  1141. {'lineCoins':90000,'payIncome':854000},{'lineCoins':90000,'payIncome':856000},{'lineCoins':90000,'payIncome':858000},
  1142. ]
  1143. nowTime = datetime.datetime.now()
  1144. result = []
  1145. for ii in range(30):
  1146. result.append({'dateStr':(nowTime-datetime.timedelta(days=30-ii)).strftime('%Y-%m-%d'),'lineCoins':monthDataList[ii]['lineCoins']+random.randint(-2000,2000),'payIncome':monthDataList[ii]['payIncome']+random.randint(-10000,10000)})
  1147. return JsonResponse({'result': 1, 'description': None, 'payload': {'dataList': result[::-1]}})
  1148. if request.user.id == ObjectId('59974b4b8732d6480fb699e5'):
  1149. return fake_response()
  1150. data = cache.get('getAllDeviceIncomeList_%s' % request.user.id, None)
  1151. if data is not None:
  1152. return JsonResponse({'result': 1, 'description': None, 'payload': {'dataList': data}})
  1153. else:
  1154. currentManager = request.user # type: Manager
  1155. agentIdList = [str(_['_id']) for _ in
  1156. list(Agent.get_collection().find({'managerId': str(currentManager.id)}, {'_id': 1}))]
  1157. dealerIdList = [str(_['_id']) for _ in
  1158. list(Dealer.get_collection().find({'agentId': {'$in': agentIdList}}, {'_id': 1}))]
  1159. if currentManager.supports('show_for_jiuheng'):
  1160. dealerIdList = [str(_) for _ in Device.get_collection().find(
  1161. {'ownerId': {'$in': dealerIdList}, 'devType.code': {'$in': ['100206', '100224', '100202']}},
  1162. {'ownerId': 1}).distinct('ownerId')]
  1163. return JsonResponse(
  1164. {'result': 1, 'description': None, 'payload': {'dataList': query_device_income(dealerIdList)}})
  1165. @permission_required(ROLE.manager)
  1166. def getAllDeviceConsumption(request):
  1167. # type: (WSGIRequest)->JsonResponse
  1168. def fake_response():
  1169. result =[
  1170. {
  1171. 'consumptionList':[{'unit':u'百万度','name':u'电量','value':14},{'unit':u'百万','name':u'金币','value':28}],
  1172. 'dateStr':'2022-03'
  1173. },
  1174. {
  1175. 'consumptionList':[{'unit':u'百万度','name':u'电量','value':10},{'unit':u'百万','name':u'金币','value':20}],
  1176. 'dateStr':'2022-02'
  1177. },
  1178. {
  1179. 'consumptionList':[{'unit':u'百万度','name':u'电量','value':15},{'unit':u'百万','name':u'金币','value':30}],
  1180. 'dateStr':'2022-01'
  1181. },
  1182. {
  1183. 'consumptionList':[{'unit':u'百万度','name':u'电量','value':15},{'unit':u'百万','name':u'金币','value':29}],
  1184. 'dateStr':'2021-12'
  1185. },
  1186. {
  1187. 'consumptionList':[{'unit':u'百万度','name':u'电量','value':14},{'unit':u'百万','name':u'金币','value':28}],
  1188. 'dateStr':'2021-11'
  1189. },
  1190. {
  1191. 'consumptionList':[{'unit':u'百万度','name':u'电量','value':14},{'unit':u'百万','name':u'金币','value':28}],
  1192. 'dateStr':'2021-10'
  1193. }
  1194. ]
  1195. return JsonResponse({'result': 1, 'description': None, 'payload': {'dataList': result}})
  1196. if request.user.id == ObjectId('59974b4b8732d6480fb699e5'):
  1197. return fake_response()
  1198. data = cache.get('getAllDeviceConsumption_%s' % request.user.id, None)
  1199. if data is not None:
  1200. return JsonResponse({'result': 1, 'description': None, 'payload': {'dataList': data}})
  1201. else:
  1202. currentManager = request.user # type: Manager
  1203. agentIdList = [str(_['_id']) for _ in
  1204. list(Agent.get_collection().find({'managerId': str(currentManager.id)}, {'_id': 1}))]
  1205. dealerIdList = [str(_['_id']) for _ in
  1206. list(Dealer.get_collection().find({'agentId': {'$in': agentIdList}}, {'_id': 1}))]
  1207. if currentManager.supports('show_for_jiuheng'):
  1208. dealerIdList = [str(_) for _ in Device.get_collection().find(
  1209. {'ownerId': {'$in': dealerIdList}, 'devType.code': {'$in': ['100206', '100224', '100202']}},
  1210. {'ownerId': 1}).distinct('ownerId')]
  1211. return JsonResponse(
  1212. {'result': 1, 'description': None, 'payload': {'dataList': query_device_consumption(dealerIdList)}})
  1213. @permission_required(ROLE.manager)
  1214. def getAllUserStatistics(request):
  1215. # type: (WSGIRequest)->JsonResponse
  1216. currentManager = request.user # type: Manager
  1217. if currentManager.supports('dummy_big_data'):
  1218. item = DummyManagerData.objects(managerId = str(currentManager.id), dataKey = 'getAllUserStatistics').first()
  1219. if item:
  1220. return JsonResponse({'result': 1, 'description': None, 'payload': item.value})
  1221. else:
  1222. return JsonResponse({'result': 1, 'description': None, 'payload': {
  1223. "userCount": 320232,
  1224. "femaleCount": 37360,
  1225. "maleCount": 224162,
  1226. "todayActiveUsers": 24353
  1227. }})
  1228. data = cache.get('getAllUserStatistics_%s' % request.user.id, None)
  1229. if data is not None:
  1230. return JsonResponse({'result': 1, 'description': None, 'payload': data})
  1231. else:
  1232. agentIdList = [str(_['_id']) for _ in
  1233. list(Agent.get_collection().find({'managerId': str(currentManager.id)}, {'_id': 1}))]
  1234. dealerIdList = [str(_['_id']) for _ in
  1235. list(Dealer.get_collection().find({'agentId': {'$in': agentIdList}}, {'_id': 1}))]
  1236. return JsonResponse({'result': 1, 'description': None, 'payload': get_user_stats(dealerIdList)})
  1237. @permission_required(ROLE.manager)
  1238. def getAllFeedbackStatistics(request):
  1239. # type: (WSGIRequest)->JsonResponse
  1240. data = cache.get('getAllFeedbackStatistics_%s' % request.user.id, None)
  1241. if data is not None:
  1242. return JsonResponse({'result': 1, 'description': None, 'payload': data})
  1243. else:
  1244. currentManager = request.user # type: cast(Manager)
  1245. agentIdList = [str(_['_id']) for _ in
  1246. list(Agent.get_collection().find({'managerId': str(currentManager.id)}, {'_id': 1}))]
  1247. dealerIdList = [str(_['_id']) for _ in
  1248. list(Dealer.get_collection().find({'agentId': {'$in': agentIdList}}, {'_id': 1}))]
  1249. if currentManager.supports('show_for_jiuheng'):
  1250. dealerIdList = [str(_) for _ in Device.get_collection().find(
  1251. {'ownerId': {'$in': dealerIdList}, 'devType.code': {'$in': ['100206', '100224', '100202']}},
  1252. {'ownerId': 1}).distinct('ownerId')]
  1253. return JsonResponse({'result': 1, 'description': None, 'payload': get_feed_back_stats(dealerIdList)})
  1254. @permission_required(ROLE.manager)
  1255. def getDealerIncomeTotalTop(request):
  1256. # type: (WSGIRequest)->JsonResponse
  1257. data = cache.get('getDealerIncomeTotalTop_%s' % request.user.id, None)
  1258. if data is not None:
  1259. return JsonResponse({'result': 1, 'description': None, 'payload': {'dataList': data}})
  1260. else:
  1261. currentManager = request.user # type: cast(Manager)
  1262. agentIdList = [str(_['_id']) for _ in
  1263. list(Agent.get_collection().find({'managerId': str(currentManager.id)}, {'_id': 1}))]
  1264. dealerDict = {str(item['_id']): item['nickname'] for item in
  1265. Dealer.get_collection().find({'agentId': {'$in': agentIdList}}, {'_id': 1, 'nickname': 1})}
  1266. if currentManager.supports('show_for_jiuheng'):
  1267. dealerIdList = [str(_) for _ in Device.get_collection().find(
  1268. {'ownerId': {'$in': dealerDict.keys()}, 'devType.code': {'$in': ['100206', '100224', '100202']}},
  1269. {'ownerId': 1}).distinct('ownerId')]
  1270. for dealerId in dealerIdList:
  1271. dealerDict.pop(dealerId, None)
  1272. return JsonResponse({
  1273. 'result': 1,
  1274. 'description': None,
  1275. 'payload': {'dataList': query_total_dealer_income_top(dealerDict)}})
  1276. @permission_required(ROLE.manager)
  1277. def getUserConsumeFrequency(request):
  1278. # type: (WSGIRequest)->JsonResponse
  1279. currentManager = request.user
  1280. if currentManager.supports('dummy_big_data'):
  1281. item = DummyManagerData.objects(managerId = str(currentManager.id), dataKey = 'getUserConsumeFrequency').first()
  1282. if item:
  1283. return JsonResponse({'result': 1, 'description': None, 'payload': item.value})
  1284. else:
  1285. return JsonResponse({'result': 1, 'description': None, 'payload': {
  1286. 'dataList': [
  1287. {"name": "1次", "percent": 10},
  1288. {"name": "2-5次", "percent": 20},
  1289. {"name": "5-10次", "percent": 30},
  1290. {"name": "10-20次", "percent": 30},
  1291. {"name": "20+次", "percent": 10}
  1292. ]}})
  1293. else:
  1294. data = cache.get('getUserConsumeFrequency_%s' % request.user.id, None)
  1295. if data is not None:
  1296. return JsonResponse({'result': 1, 'description': None, 'payload': {'dataList': data}})
  1297. else:
  1298. agentIdList = [str(_['_id']) for _ in
  1299. list(Agent.get_collection().find({'managerId': str(currentManager.id)}, {'_id': 1}))]
  1300. dealerIdList = [str(_['_id']) for _ in
  1301. list(Dealer.get_collection().find({'agentId': {'$in': agentIdList}}, {'_id': 1}))]
  1302. return JsonResponse(
  1303. {'result': 1, 'description': None, 'payload': {'dataList': query_user_consume_frequency(dealerIdList)}})
  1304. @permission_required(ROLE.manager)
  1305. def getDevBeingUsedTrend(request):
  1306. # type: (WSGIRequest)->JsonResponse
  1307. def fake_response():
  1308. datalist = [{'devBeingUsed':50,'time':'00时'},{'devBeingUsed':50,'time':'01时'},{'devBeingUsed':49,'time':'02时'},
  1309. {'devBeingUsed':47,'time':'03时'},{'devBeingUsed':46,'time':'04时'},{'devBeingUsed':45,'time':'05时'},
  1310. {'devBeingUsed':39,'time':'06时'},{'devBeingUsed':35,'time':'07时'},{'devBeingUsed':30,'time':'08时'},
  1311. {'devBeingUsed':30,'time':'09时'},{'devBeingUsed':30,'time':'10时'},{'devBeingUsed':30,'time':'11时'},
  1312. {'devBeingUsed':28,'time':'12时'},{'devBeingUsed':30,'time':'13时'},{'devBeingUsed':33,'time':'14时'},
  1313. {'devBeingUsed':33,'time':'15时'},{'devBeingUsed':30,'time':'16时'},{'devBeingUsed':30,'time':'17时'},
  1314. {'devBeingUsed':30,'time':'18时'},{'devBeingUsed':39,'time':'19时'},{'devBeingUsed':45,'time':'20时'},
  1315. {'devBeingUsed':46,'time':'21时'},{'devBeingUsed':47,'time':'22时'},{'devBeingUsed':49,'time':'23时'}]
  1316. return JsonResponse(
  1317. {'result': 1, 'description': None, 'payload': {'___comment': '最近24小时内设备使用趋势图', 'dataList': datalist}})
  1318. if request.user.id == ObjectId('59974b4b8732d6480fb699e5'):
  1319. return fake_response()
  1320. data = cache.get('getDevBeingUsedTrend_%s' % request.user.id, None)
  1321. if data is not None:
  1322. return JsonResponse(
  1323. {'result': 1, 'description': None, 'payload': {'___comment': '最近24小时内设备使用趋势图', 'dataList': data}})
  1324. else:
  1325. currentManager = request.user
  1326. agentIdList = [str(_['_id']) for _ in
  1327. list(Agent.get_collection().find({'managerId': str(currentManager.id)}, {'_id': 1}))]
  1328. dealerIdList = [str(_['_id']) for _ in
  1329. list(Dealer.get_collection().find({'agentId': {'$in': agentIdList}}, {'_id': 1}))]
  1330. #
  1331. if currentManager.supports('show_for_jiuheng'):
  1332. devList = list(Device.get_collection().find(
  1333. {'ownerId': {'$in': dealerIdList}, 'devType.code': {'$in': ['100206', '100224', '100202']}},
  1334. {'devNo': 1, 'groupId': 1, '_id': 0}
  1335. ))
  1336. else:
  1337. devList = list(Device.get_collection().find(
  1338. {'ownerId': {'$in': dealerIdList}},
  1339. {'devNo': 1, 'groupId': 1, '_id': 0}
  1340. ))
  1341. devNoList = [_['devNo'] for _ in devList]
  1342. # 找前一天的数据
  1343. def get_hours_time(hoursStr):
  1344. return time.mktime(to_datetime(
  1345. (datetime.date.today() - datetime.timedelta(days = 1)).strftime('%Y-%m-%d') + hoursStr).timetuple())
  1346. yesterdayBegin = get_hours_time(' 00:00:00')
  1347. yesterdayEnd = get_hours_time(' 23:59:59')
  1348. serviceProgress = list(ServiceProgress.get_collection().find(
  1349. {'device_imei': {'$in': devNoList}, 'start_time': {'$gte': int(yesterdayBegin), '$lte': int(yesterdayEnd)}},
  1350. {'_id': 0, 'start_time': 1}
  1351. ))
  1352. dataList = []
  1353. for _ in range(24):
  1354. if _ < 9:
  1355. timeStr = '0' + str(_ + 1) + '时'
  1356. else:
  1357. timeStr = str(_ + 1) + '时'
  1358. dataList.append({
  1359. 'time': timeStr,
  1360. 'devBeingUsed': 0
  1361. })
  1362. for svs in serviceProgress:
  1363. for _ in range(24):
  1364. if _ < 10:
  1365. timeStr = ' ' + '0' + str(_)
  1366. else:
  1367. timeStr = ' ' + str(_)
  1368. begin = timeStr + ':00:00'
  1369. end = timeStr + ':59:59'
  1370. if get_hours_time(begin) <= svs['start_time'] <= get_hours_time(end):
  1371. dataList[_]['devBeingUsed'] += 1
  1372. return JsonResponse({'result': 1, 'description': None, 'payload': {
  1373. "___comment": "最近24小时内设备使用趋势图",
  1374. "dataList": dataList
  1375. }})
  1376. @permission_required(ROLE.manager)
  1377. def getRechargeRecords(request):
  1378. # type: (WSGIRequest)->JsonResponse
  1379. """
  1380. :param request:
  1381. :return:
  1382. """
  1383. currentManager = request.user # type: Manager
  1384. pageIndex = int(request.GET.get('pageIndex', 1))
  1385. pageSize = int(request.GET.get('pageSize', 10))
  1386. agentId = request.GET.get('agentId')
  1387. dealerId = request.GET.get('dealerId')
  1388. startTime = date_to_datetime_floor(request.GET.get('startTime'))
  1389. endTime = date_to_datetime_ceiling(request.GET.get('endTime'))
  1390. dealerMap = get_dealerMap_by_managerId(managerId = currentManager.id, agentId = agentId, dealerId = dealerId)
  1391. dealerIds = dealerMap.keys()
  1392. originRecords = ClientRechargeModelProxy.get_data_list(
  1393. startTime = startTime,
  1394. endTime = endTime,
  1395. ownerId__in = dealerIds,
  1396. via = 'recharge',
  1397. result = RechargeRecord.PayResult.SUCCESS) # type: CustomQuerySet
  1398. total = originRecords.count()
  1399. records = originRecords.paginate(pageIndex = pageIndex, pageSize = pageSize)
  1400. dataList = [
  1401. {
  1402. "orderNo": record.orderNo,
  1403. "gatewayOrderNo": record.wxOrderNo,
  1404. "userNickname": record.nickname,
  1405. "dealerName": dealerMap[record.ownerId]['nickname'],
  1406. "agentName": dealerMap[record.ownerId]['agentName'],
  1407. "logicalCode": record.logicalCode,
  1408. "devType": record.dev_type_name,
  1409. "chargeMoney": record.money,
  1410. "groupName": record.groupName,
  1411. "chargeTime": record.to_js_timestamp(record.dateTimeAdded)
  1412. }
  1413. for record in records
  1414. ]
  1415. cache.set('getRechargeRecords_%s' % currentManager.id, originRecords, 60 * 60)
  1416. return JsonOkResponse(payload = {'total': total, 'dataList': dataList})
  1417. @permission_required(ROLE.manager)
  1418. def getBusinessTrend(request):
  1419. currentManager = request.user
  1420. type = request.GET['type']
  1421. if type == u'charge':
  1422. cacheData = cache.get('getRechargeRecords_%s' % currentManager.id)
  1423. elif type == u'consumption':
  1424. cacheData = cache.get('getConsumptionRecord_%s' % currentManager.id)
  1425. else:
  1426. cacheData = None
  1427. if cacheData is not None:
  1428. timeData = [_.dateTimeAdded.strftime("%Y-%m-%d") for _ in cacheData]
  1429. dataListTemp = [{'date': k, 'value': v} for k, v in Counter(timeData).items()]
  1430. dataList = sorted(dataListTemp, key = lambda x: x['date'])
  1431. return JsonOkResponse(payload = {'dataList': dataList})
  1432. else:
  1433. return JsonErrorResponse(u'数据缓存超时, 请重新查询订单')
  1434. @permission_required(ROLE.manager)
  1435. def getUserActivityTrend(request):
  1436. currentManager = request.user
  1437. type = request.GET['type']
  1438. if type == u'charge':
  1439. cacheData = cache.get('getRechargeRecords_%s' % currentManager.id)
  1440. elif type == u'consumption':
  1441. cacheData = cache.get('getConsumptionRecord_%s' % currentManager.id)
  1442. else:
  1443. cacheData = None
  1444. if cacheData is not None:
  1445. timeAndUserData = [{_.dateTimeAdded.strftime("%Y-%m-%d"): _.openId} for _ in cacheData]
  1446. timeAndUserDataStr = list(set([json.dumps(_) for _ in timeAndUserData]))
  1447. timeAndUserDataTemp = [json.loads(_).keys()[0] for _ in timeAndUserDataStr]
  1448. dataListTemp = [{'date': k, 'value': v} for k, v in Counter(timeAndUserDataTemp).items()]
  1449. dataList = sorted(dataListTemp, key = lambda x: x['date'])
  1450. return JsonOkResponse(payload = {'dataList': dataList})
  1451. else:
  1452. return JsonErrorResponse(u'数据缓存超时, 请重新查询订单')
  1453. @permission_required(ROLE.manager)
  1454. def getConsumptionRecord(request):
  1455. currentManager = request.user
  1456. pageIndex = int(request.GET.get('pageIndex', 1))
  1457. pageSize = int(request.GET.get('pageSize', 10))
  1458. agentId = request.GET.get('agentId')
  1459. dealerId = request.GET.get('dealerId')
  1460. startTime = request.GET.get('startTime')
  1461. endTime = request.GET.get('endTime')
  1462. dealerMap = get_dealerMap_by_managerId(managerId = currentManager.id, agentId = agentId, dealerId = dealerId)
  1463. dealerIds = dealerMap.keys()
  1464. originRecords = ClientConsumeModelProxy.get_data_list(startTime = startTime,
  1465. endTime = endTime,
  1466. ownerId__in = dealerIds,
  1467. isNormal = True) # type: CustomQuerySet
  1468. total = originRecords.count()
  1469. records = originRecords.paginate(pageIndex = pageIndex, pageSize = pageSize)
  1470. dataList = [
  1471. {
  1472. "orderNo": record.orderNo,
  1473. "userNickname": record.nickname,
  1474. "dealerName": dealerMap[record.ownerId]['nickname'],
  1475. "agentName": dealerMap[record.ownerId]['agentName'],
  1476. "logicalCode": record.logicalCode,
  1477. "devType": record.dev_type_name,
  1478. "coins": record.coin,
  1479. "groupName": record.groupName,
  1480. "createdTime": record.to_js_timestamp(record.dateTimeAdded)
  1481. }
  1482. for record in records
  1483. ]
  1484. cache.set('getConsumptionRecord_%s' % currentManager.id, originRecords, 60 * 60)
  1485. return JsonOkResponse(payload = {'total': total, 'dataList': dataList})
  1486. @permission_required(ROLE.manager)
  1487. def getRechargeCardRecords(request):
  1488. # type: (WSGIRequest)->JsonResponse
  1489. currentManager = request.user # type: Manager
  1490. pageIndex = int(request.GET.get('pageIndex', 1))
  1491. pageSize = int(request.GET.get('pageSize', 10))
  1492. agentId = request.GET.get('agentId')
  1493. dealerId = request.GET.get('dealerId')
  1494. startTime = date_to_datetime_floor(request.GET.get('startTime'))
  1495. endTime = date_to_datetime_ceiling(request.GET.get('endTime'))
  1496. dealerMap = get_dealerMap_by_managerId(managerId = currentManager.id, agentId = agentId, dealerId = dealerId)
  1497. dealerIds = dealerMap.keys()
  1498. records = ClientRechargeModelProxy.get_data_list(
  1499. startTime = startTime,
  1500. endTime = endTime,
  1501. ownerId__in = dealerIds,
  1502. via = 'chargeCard',
  1503. result = RechargeRecord.PayResult.SUCCESS) # type: CustomQuerySet
  1504. total = records.count()
  1505. recordsByPage = records.paginate(pageIndex = pageIndex, pageSize = pageSize)
  1506. dataList = []
  1507. for record in recordsByPage: # type: RechargeRecord
  1508. order = CardRechargeOrder.get_by_rechargeRecord(record)
  1509. entry = {
  1510. "orderNo": record.orderNo,
  1511. "gatewayOrderNo": record.wxOrderNo,
  1512. "cardNo": order.cardNo if order else '',
  1513. "userNickname": record.nickname,
  1514. "dealerName": dealerMap[record.ownerId]['nickname'],
  1515. "agentName": dealerMap[record.ownerId]['agentName'],
  1516. "logicalCode": record.logicalCode,
  1517. "chargeMoney": record.money,
  1518. "groupName": record.groupName,
  1519. "chargeTime": record.to_js_timestamp(record.dateTimeAdded) if order else ''
  1520. }
  1521. dataList.append(entry)
  1522. return JsonOkResponse(payload = {'total': total, 'dataList': dataList})
  1523. @permission_required(ROLE.manager)
  1524. def setAgentBanner(request):
  1525. # type: (WSGIRequest)->JsonResponse
  1526. payload = json.loads(request.body)
  1527. agent = Agent.objects(id = str(payload['id'])).first()
  1528. if not agent:
  1529. return JsonErrorResponse(u'不存在的经销商')
  1530. agent.bannerList = payload.get('bannerImgList', [])
  1531. agent.save()
  1532. return JsonOkResponse()
  1533. @error_tolerate(nil = DefaultJsonErrorResponse)
  1534. def getCheckCode(request):
  1535. # type: (WSGIRequest)->JsonResponse
  1536. toNumber = request.GET.get('username', '123456')
  1537. manager = Manager.objects(username = toNumber).first()
  1538. if not manager:
  1539. return JsonErrorResponse(u'不存在的厂商')
  1540. productName = manager.brandName
  1541. status, msg = managerForgotPwdSMSProvider.get(phoneNumber = toNumber,
  1542. productName = productName,
  1543. vendor = SysParas.get_sms_vendor(manager.smsVendor))
  1544. if not status:
  1545. return JsonResponse({'result': 0, 'description': msg})
  1546. else:
  1547. return JsonResponse({'result': 1, 'description': ''})
  1548. @error_tolerate(nil = DefaultJsonErrorResponse)
  1549. def verifyForgetCode(request):
  1550. # type: (WSGIRequest)->JsonResponse
  1551. payload = json.loads(request.body)
  1552. username = payload.get('username', None)
  1553. code = payload.get('code', None)
  1554. password = payload.get('password', '')
  1555. manager = Manager.objects(username = username).first()
  1556. while True:
  1557. if manager is None:
  1558. response = JsonErrorResponse(u'该手机号尚未注册,请注册后再进行操作')
  1559. break
  1560. if password == "":
  1561. response = JsonErrorResponse(u"请输入密码")
  1562. break
  1563. status, desc = managerRegisterSMSProvider.verify(username, code)
  1564. if not status:
  1565. response = JsonErrorResponse(desc)
  1566. else:
  1567. manager.set_password(password)
  1568. manager.unlock_login()
  1569. response = JsonResponse({"result": 1, "description": None, "payload": {}})
  1570. break
  1571. return response
  1572. @error_tolerate(nil = DefaultJsonErrorResponse)
  1573. def editAgentZJFirePlatform(request):
  1574. payload = json.loads(request.body)
  1575. agentId = payload['id']
  1576. northPort = ":".join([payload.get("northIp", ""), payload.get("northPort", "")])
  1577. try:
  1578. norther = ZhejiangNorther.objects.get(tokenId = agentId)
  1579. norther.usernameFromHear = payload['loginUsername']
  1580. norther.passwordFromHear = payload['loginPassword']
  1581. norther.mqUser = payload['mqUsername']
  1582. norther.mqPassword = payload['mqPassword']
  1583. norther.serviceCodeFromNorth = payload['code']
  1584. norther.northPort = northPort
  1585. except Exception, e:
  1586. norther = ZhejiangNorther(usernameFromHear = payload['loginUsername'],
  1587. passwordFromHear = payload['loginPassword'],
  1588. mqUser = payload['mqUsername'],
  1589. mqPassword = payload['mqPassword'],
  1590. serviceCodeFromNorth = payload['code'],
  1591. tokenId = agentId,
  1592. northPort = northPort)
  1593. norther.save()
  1594. return JsonOkResponse()
  1595. @error_tolerate(nil = DefaultJsonErrorResponse)
  1596. def editDealerZJFirePlatform(request):
  1597. payload = json.loads(request.body)
  1598. dealerId = payload['id']
  1599. dealer = Dealer.objects.get(id = dealerId)
  1600. try:
  1601. company = Company.objects.get(ownerId = dealerId)
  1602. company.name = payload['companyName']
  1603. company.code = payload['companyCode']
  1604. company.address = payload['companyAddress']
  1605. company.contactName = payload['contactsName']
  1606. company.telephone = payload['contactsTel']
  1607. company.manufacturer = payload['deviceManufacturer']
  1608. company.dateTimeUpdated = datetime.datetime.now()
  1609. except Exception, e:
  1610. company = Company(
  1611. ownerId = payload['id'],
  1612. agentId = dealer.agentId,
  1613. name = payload['companyName'],
  1614. code = payload['companyCode'],
  1615. address = payload['companyAddress'],
  1616. contactName = payload['contactsName'],
  1617. telephone = payload['contactsTel'],
  1618. manufacturer = payload['deviceManufacturer'],
  1619. dateTimeAdded = datetime.datetime.now())
  1620. company.save()
  1621. return JsonOkResponse()
  1622. @error_tolerate(nil = DefaultJsonErrorResponse, logger = logger)
  1623. @permission_required(ROLE.manager)
  1624. def getAliApp(request):
  1625. # type: (WSGIRequest)->JsonResponse
  1626. """
  1627. 更改微信资金平台APP信息
  1628. :param request:
  1629. :return:
  1630. """
  1631. appid = str(request.GET.get('appid'))
  1632. app = AliApp.objects(appid = appid).first() # type: AliApp
  1633. if not app:
  1634. return JsonOkResponse(payload = {})
  1635. else:
  1636. return JsonOkResponse(payload = app.to_dict())
  1637. @error_tolerate(nil = DefaultJsonErrorResponse, logger = logger)
  1638. @permission_required(ROLE.manager)
  1639. def bindAliApp(request):
  1640. # type: (WSGIRequest)->JsonResponse
  1641. """
  1642. 绑定自定义支付宝
  1643. :param request:
  1644. :return:
  1645. """
  1646. payload = json.loads(request.body) # type: dict
  1647. return api.bindAliApp(payload)
  1648. @error_tolerate(nil = DefaultJsonErrorResponse, logger = logger)
  1649. @permission_required(ROLE.manager)
  1650. def bindWechatFund(request):
  1651. # type: (WSGIRequest)->JsonResponse
  1652. """
  1653. 绑定自定义微信公众号
  1654. :param request:
  1655. :return:
  1656. """
  1657. payload = json.loads(request.body) # type: dict
  1658. return api.bindWechatFund(payload)
  1659. @error_tolerate(nil = DefaultJsonErrorResponse, logger = logger)
  1660. @permission_required(ROLE.manager)
  1661. def bindWechatCust(request):
  1662. # type: (WSGIRequest)->JsonResponse
  1663. """
  1664. 绑定自定义微信公众号
  1665. :param request:
  1666. :return:
  1667. """
  1668. payload = json.loads(request.body) # type: dict
  1669. return api.bindWechatCust(payload)
  1670. @error_tolerate(nil = DefaultJsonErrorResponse, logger = logger)
  1671. @permission_required(ROLE.manager)
  1672. def getWechatFundApp(request):
  1673. # type: (WSGIRequest)->JsonResponse
  1674. """
  1675. 更改微信资金平台APP信息
  1676. :param request:
  1677. :return:
  1678. """
  1679. appid = request.GET.get('appid')
  1680. mchid = request.GET.get('mchid')
  1681. app = WechatPayApp.objects(appid = appid, mchid = mchid).first() # type: WechatPayApp
  1682. if not app:
  1683. return JsonOkResponse(payload = {})
  1684. else:
  1685. return JsonOkResponse(payload = app.to_dict())
  1686. @error_tolerate(nil = DefaultJsonErrorResponse, logger = logger)
  1687. @permission_required('Manager')
  1688. def getDeviceRealtimeData(request):
  1689. # type: (WSGIRequest)->JsonResponse
  1690. logicalCode = request.GET.get('logicalCode')
  1691. port = request.GET.get('port')
  1692. startTimeGet = request.GET.get('startTime')
  1693. endTimeGet = request.GET.get('endTime')
  1694. startTimeGet += ' 00:00:00'
  1695. endTimeGet += ' 23:59:59'
  1696. startTime = int(time.mktime(time.strptime(startTimeGet, "%Y-%m-%d %H:%M:%S")))
  1697. endTime = int(time.mktime(time.strptime(endTimeGet, "%Y-%m-%d %H:%M:%S")))
  1698. report = PortReport.get_collection().find({
  1699. 'time': {'$gte': startTime, '$lte': endTime},
  1700. 'logicalCode': logicalCode
  1701. }).sort('time', 1)
  1702. reportList = [i for i in report]
  1703. listLength = len(reportList)
  1704. responeData = {'dataList': []}
  1705. if listLength < 1000:
  1706. for _ in reportList:
  1707. electricity = _['portInfo'].get(port)['electricity']
  1708. portInfoDict = {
  1709. "dateStr": timestamp_timeformat(_['time']),
  1710. "voltage": 220,
  1711. "electricity": electricity,
  1712. "temperature": _['temperature'] if electricity else 0,
  1713. "status": _['portInfo'].get(port)['status']
  1714. }
  1715. responeData['dataList'].append(portInfoDict)
  1716. if listLength > 1000:
  1717. index = math.ceil(listLength / 1000)
  1718. for ii in range(1000):
  1719. num = ii * int(index)
  1720. for _ in reportList[num]:
  1721. electricity = _['portInfo'].get(port)['electricity']
  1722. portInfoDict = {
  1723. "dateStr": timestamp_timeformat(_['time']),
  1724. "voltage": 220,
  1725. "electricity": electricity,
  1726. "temperature": _['temperature'] if electricity else 0,
  1727. "status": _['portInfo'].get(port)['status']
  1728. }
  1729. responeData['dataList'].append(portInfoDict)
  1730. return JsonResponse({'result': 1, 'description': None, 'payload': responeData})
  1731. @error_tolerate(nil = DefaultJsonErrorResponse, logger = logger)
  1732. @permission_required(ROLE.manager)
  1733. def editDealer(request):
  1734. payload = json.loads(request.body)
  1735. username = payload.get('tel')
  1736. nickname = payload.get('name')
  1737. id = payload.get('id')
  1738. dealer = Dealer.objects.get(id = id)
  1739. dealer.username = username
  1740. dealer.nickname = nickname
  1741. dealer.save()
  1742. return JsonOkResponse()
  1743. @error_tolerate(nil = DefaultJsonErrorResponse, logger = logger)
  1744. @permission_required(ROLE.manager)
  1745. def getIncomeOrderList(request):
  1746. managerId = str(request.user.id)
  1747. startDate = request.GET.get('startTime', '')
  1748. endDate = request.GET.get('endTime', '')
  1749. agentId = request.GET.get('agentId', '')
  1750. dealerId = request.GET.get('dealerId', '')
  1751. dealersIdList = []
  1752. dealerDict = {}
  1753. if agentId == '' and dealerId == '':
  1754. agentDict = {}
  1755. agentsIdList = []
  1756. for agent in Agent.get_collection().find({'managerId': managerId}, {'_id': 1, 'username': 1, 'nickname': 1}):
  1757. agentDict[str(agent['_id'])] = '%s %s' % (agent['nickname'], agent['username'])
  1758. agentsIdList.append(str(agent['_id']))
  1759. for dealer in Dealer.get_collection().find({'agentId': {'$in': agentsIdList}},
  1760. {'_id': 1, 'username': 1, 'nickname': 1, 'agentId': 1}):
  1761. dealerDict[str(dealer['_id'])] = {'dealerName': '%s %s' % (dealer['nickname'], dealer['username']),
  1762. 'agentName': agentDict.get(dealer['agentId'], '')}
  1763. dealersIdList.append(str(dealer['_id']))
  1764. elif agentId != '' and dealerId == '':
  1765. agents = Agent.get_collection().find({'_id': ObjectId(agentId)}, {'_id': 1, 'username': 1, 'nickname': 1})
  1766. for dealer in Dealer.get_collection().find({'agentId': agentId},
  1767. {'_id': 1, 'username': 1, 'nickname': 1, 'agentId': 1}):
  1768. dealerDict[str(dealer['_id'])] = {'dealerName': '%s %s' % (dealer['nickname'], dealer['username']),
  1769. 'agentName': '%s %s' % (agents[0]['nickname'], agents[0]['username'])}
  1770. dealersIdList.append(str(dealer['_id']))
  1771. elif agentId != '' and dealerId != '':
  1772. agents = Agent.get_collection().find({'_id': ObjectId(agentId)}, {'_id': 1, 'username': 1, 'nickname': 1})
  1773. dealers = Dealer.get_collection().find({'_id': ObjectId(dealerId)},
  1774. {'_id': 1, 'username': 1, 'nickname': 1, 'agentId': 1})
  1775. dealerDict[str(dealers[0]['_id'])] = {'dealerName': '%s %s' % (dealers[0]['nickname'], dealers[0]['username']),
  1776. 'agentName': '%s %s' % (agents[0]['nickname'], agents[0]['username'])}
  1777. dealersIdList = [dealerId]
  1778. else:
  1779. return JsonResponse({'result': 0, 'description': u'错误的查询方式'})
  1780. records = ClientRechargeModelProxy.get_data_list(startTime = startDate, endTime = endDate,
  1781. ownerId__in = dealersIdList, result = 'success',
  1782. via__nin = ['sendcoin', 'refund']) # type: CustomQuerySet
  1783. pageIndex = int(request.GET.get('pageIndex', 1))
  1784. pageSize = int(request.GET.get('pageSize', 10))
  1785. chargeTypeDict = {'recharge': u'扫码充值', 'sendcoin': u'赠币', 'refund': u'退币', 'chargeCard': u'卡充值'}
  1786. total = records.count()
  1787. dataList = []
  1788. for rcd in records.paginate(pageIndex, pageSize):
  1789. # 检查下如果是卡充值,就需要检查是否已经完成整个流程
  1790. if rcd.via == 'chargeCard' and CardRechargeOrder.objects.filter(rechargeNo = rcd.id,
  1791. status = 'finished').count() == 0:
  1792. continue
  1793. try:
  1794. proxyRcd = ClientDealerIncomeModelProxy.get_one(ref_id = rcd.id,
  1795. groupId = rcd.groupId) # type: DealerIncomeProxy
  1796. user = MyUser.objects.filter(openId = rcd.openId).only('openId', 'nickname', 'sex', 'groupId').first()
  1797. sex = ''
  1798. if user.sex == 0:
  1799. sex = u'女'
  1800. elif user.sex == 1:
  1801. sex = u'男'
  1802. else:
  1803. pass
  1804. except Exception, e:
  1805. continue
  1806. amountDict = DealerIncomeProxy.get_agent_partner_amount(rcd.ownerId, proxyRcd.partition)
  1807. data = {
  1808. 'id': str(rcd.id),
  1809. 'amount': proxyRcd.actualAmountMap.get(rcd.ownerId),
  1810. 'orderAmount': rcd.money,
  1811. 'agentShareAmount': amountDict.get('agentAmount', 0),
  1812. 'partnerShareAmount': amountDict.get('partnerAmount', 0),
  1813. 'tradeType': chargeTypeDict.get(rcd.via, '-'),
  1814. 'gateway': rcd.gateway,
  1815. 'status': rcd.result,
  1816. 'userNickname': user.nickname,
  1817. 'userGender': sex,
  1818. 'groupName': rcd.groupName,
  1819. 'logicalCode': rcd.logicalCode,
  1820. 'devTypeName': rcd.dev_type_name,
  1821. 'createTime': rcd.dateTimeAdded.strftime(Const.DATETIME_FMT),
  1822. 'gatewayTradeNo': rcd.orderNo,
  1823. 'outTradeNo': rcd.wxOrderNo,
  1824. 'agentName': dealerDict.get(rcd.ownerId, {}).get('agentName', ''),
  1825. 'dealerName': dealerDict.get(rcd.ownerId, {}).get('dealerName', '')
  1826. }
  1827. dataList.append(data)
  1828. return JsonOkResponse(payload = {'total': total, 'dataList': dataList})
  1829. def getConsumptionOrderList(request):
  1830. pageIndex = int(request.GET.get('pageIndex'))
  1831. pageSize = int(request.GET.get('pageSize'))
  1832. managerId = str(request.user.id)
  1833. startDate = request.GET.get('startTime', '')
  1834. endDate = request.GET.get('endTime', '')
  1835. agentId = request.GET.get('agentId', '')
  1836. dealerId = request.GET.get('dealerId', '')
  1837. dealerDict = {}
  1838. dealersIdList = []
  1839. if agentId == '' and dealerId == '':
  1840. agentDict = {}
  1841. agentsIdList = []
  1842. for agent in Agent.get_collection().find({'managerId': managerId}, {'_id': 1, 'username': 1, 'nickname': 1}):
  1843. agentDict[str(agent['_id'])] = '%s %s' % (agent['nickname'], agent['username'])
  1844. agentsIdList.append(str(agent['_id']))
  1845. for dealer in Dealer.get_collection().find({'agentId': {'$in': agentsIdList}},
  1846. {'_id': 1, 'username': 1, 'nickname': 1, 'agentId': 1}):
  1847. dealerDict[str(dealer['_id'])] = {'dealerName': '%s %s' % (dealer['nickname'], dealer['username']),
  1848. 'agentName': agentDict.get(dealer['agentId'], '')}
  1849. dealersIdList.append(str(dealer['_id']))
  1850. elif agentId != '' and dealerId == '':
  1851. agents = Agent.get_collection().find({'_id': ObjectId(agentId)}, {'_id': 1, 'username': 1, 'nickname': 1})
  1852. for dealer in Dealer.get_collection().find({'agentId': agentId},
  1853. {'_id': 1, 'username': 1, 'nickname': 1, 'agentId': 1}):
  1854. dealerDict[str(dealer['_id'])] = {'dealerName': '%s %s' % (dealer['nickname'], dealer['username']),
  1855. 'agentName': '%s %s' % (agents[0]['nickname'], agents[0]['username'])}
  1856. dealersIdList.append(str(dealer['_id']))
  1857. elif agentId != '' and dealerId != '':
  1858. agents = Agent.get_collection().find({'_id': ObjectId(agentId)}, {'_id': 1, 'username': 1, 'nickname': 1})
  1859. dealers = Dealer.get_collection().find({'_id': ObjectId(dealerId)},
  1860. {'_id': 1, 'username': 1, 'nickname': 1, 'agentId': 1})
  1861. dealerDict[str(dealers[0]['_id'])] = {'dealerName': '%s %s' % (dealers[0]['nickname'], dealers[0]['username']),
  1862. 'agentName': '%s %s' % (agents[0]['nickname'], agents[0]['username'])}
  1863. dealersIdList = [dealerId]
  1864. else:
  1865. return JsonResponse({'result': 0, 'description': u'错误的查询方式'})
  1866. records = ClientConsumeModelProxy.get_data_list(startTime = startDate,
  1867. endTime = endDate,
  1868. ownerId__in = dealersIdList,
  1869. isNormal = True) # type: CustomQuerySet
  1870. dataList = []
  1871. for rcd in records.paginate(pageIndex, pageSize): # type:ConsumeRecord
  1872. try:
  1873. user = MyUser.objects.filter(openId = rcd.openId).only('openId', 'nickname', 'sex', 'groupId').first()
  1874. if user is None:
  1875. continue
  1876. sex = ''
  1877. if user.sex == 0:
  1878. sex = u'女'
  1879. elif user.sex == 1:
  1880. sex = u'男'
  1881. else:
  1882. pass
  1883. except Exception, e:
  1884. continue
  1885. desc = ' '
  1886. for key, value in rcd.servicedInfo.items():
  1887. if key not in DEALER_CONSUMPTION_AGG_KIND_TRANSLATION:
  1888. continue
  1889. desc += " %s:%s%s" % (
  1890. DEALER_CONSUMPTION_AGG_KIND_TRANSLATION.get(key), value, DEALER_CONSUMPTION_AGG_KIND_UNIT.get(key))
  1891. data = {
  1892. 'id': str(rcd.id),
  1893. 'createTime': rcd.created_date,
  1894. 'title': desc,
  1895. 'userNickname': user.nickname,
  1896. 'userGender': sex,
  1897. 'groupName': rcd.groupName,
  1898. 'logicalCode': rcd.logicalCode,
  1899. 'devTypeName': rcd.dev_type_name,
  1900. 'amount': rcd.coin,
  1901. 'agentName': dealerDict.get(rcd.ownerId, {}).get('agentName', ''),
  1902. 'dealerName': dealerDict.get(rcd.ownerId, {}).get('dealerName', '')
  1903. }
  1904. dataList.append(data)
  1905. return JsonOkResponse(payload = {'dataList': dataList, 'total': records.count()})
  1906. @permission_required(ROLE.manager)
  1907. def exportIncomeOrderList(request):
  1908. manager = request.user
  1909. def get_offline_task_name(task_type, user, **kwargs):
  1910. # type: (basestring, Dealer, Dict)->basestring
  1911. tmp_list = [task_type, user.username]
  1912. if 'logicalCode' in kwargs and kwargs['logicalCode']:
  1913. tmp_list.append(u'设备编号_%s' % (kwargs['logicalCode'],))
  1914. if 'groupId' in kwargs and kwargs['groupId']:
  1915. address = Group.get_group(kwargs['groupId']).get('address', '')
  1916. tmp_list.append(u'地址_%s' % (address,))
  1917. tmp_list.append(u'%s至%s' % (kwargs['startTime'], kwargs['endTime']))
  1918. tmp_list.append(str(utils_datetime.generate_timestamp_ex()))
  1919. return '-'.join(tmp_list).replace("/", "_")
  1920. query_dict = {
  1921. 'startTime': request.GET.get('startTime', '') + ' 00:00:00',
  1922. 'endTime': request.GET.get('endTime', '') + ' 23:59:59',
  1923. 'managerId': str(manager.id),
  1924. 'agentId': request.GET.get('agentId', ''),
  1925. 'dealerId': request.GET.get('dealerId', '')
  1926. }
  1927. offline_task_name = get_offline_task_name(
  1928. task_type = OfflineTaskType.CHARGE_ORDER_REPORT,
  1929. user = manager,
  1930. **query_dict)
  1931. file_path, offline_task = OfflineTask.issue_export_report(offline_task_name = offline_task_name,
  1932. process_func_name = 'manager_export_charge_order_excel_from_db',
  1933. task_type = OfflineTaskType.CHARGE_ORDER_REPORT,
  1934. userid = str(manager.id),
  1935. role = ROLE.manager)
  1936. logger.info('start making charge report=%s' % file_path)
  1937. task_caller(str(offline_task.process_func_name),
  1938. offline_task_id = str(offline_task.id),
  1939. filepath = file_path,
  1940. queryDict = query_dict)
  1941. return JsonResponse({
  1942. 'result': 1,
  1943. 'description': u"请前往离线任务查看任务处理情况",
  1944. 'payload': str(offline_task.id)
  1945. })
  1946. @permission_required(ROLE.manager)
  1947. def exportConsumptionOrderList(request):
  1948. manager = request.user
  1949. def get_offline_task_name(task_type, user, **kwargs):
  1950. # type: (basestring, Dealer, Dict)->basestring
  1951. tmp_list = [task_type, user.username]
  1952. if 'logicalCode' in kwargs and kwargs['logicalCode']:
  1953. tmp_list.append(u'设备编号_%s' % (kwargs['logicalCode'],))
  1954. if 'groupId' in kwargs and kwargs['groupId']:
  1955. address = Group.get_group(kwargs['groupId']).get('address', '')
  1956. tmp_list.append(u'地址_%s' % (address,))
  1957. tmp_list.append(u'%s至%s' % (kwargs['startTime'], kwargs['endTime']))
  1958. tmp_list.append(str(utils_datetime.generate_timestamp_ex()))
  1959. return '-'.join(tmp_list).replace("/", "_")
  1960. query_dict = {
  1961. 'startTime': request.GET.get('startTime', '') + ' 00:00:00',
  1962. 'endTime': request.GET.get('endTime', '') + ' 23:59:59',
  1963. 'managerId': str(manager.id),
  1964. 'agentId': request.GET.get('agentId', ''),
  1965. 'dealerId': request.GET.get('dealerId', '')
  1966. }
  1967. offline_task_name = get_offline_task_name(
  1968. task_type = OfflineTaskType.CONSUME_ORDER_REPORT,
  1969. user = manager,
  1970. **query_dict)
  1971. file_path, offline_task = OfflineTask.issue_export_report(offline_task_name = offline_task_name,
  1972. process_func_name = 'manager_export_consume_order_excel_from_db',
  1973. task_type = OfflineTaskType.CONSUME_ORDER_REPORT,
  1974. userid = str(manager.id),
  1975. role = ROLE.manager)
  1976. logger.info('start making consume report=%s' % file_path)
  1977. task_caller(str(offline_task.process_func_name),
  1978. offline_task_id = str(offline_task.id),
  1979. filepath = file_path,
  1980. queryDict = query_dict)
  1981. return JsonResponse({
  1982. 'result': 1,
  1983. 'description': u"请前往离线任务查看任务处理情况",
  1984. 'payload': str(offline_task.id)
  1985. })
  1986. def inputLogicalCodes(logicalCodes, managerId):
  1987. """
  1988. 录入的二维码保存数据库
  1989. :param logicalCodes: 逻辑码 >>> list
  1990. :param managerId: 厂商ID >>> str
  1991. :return: JsonResponse
  1992. """
  1993. for l in logicalCodes:
  1994. dev = Device.objects.filter(logicalCode = l).first()
  1995. if not dev:
  1996. return JsonResponse({'result': 0, 'description': u'无效的二维码编号'})
  1997. if dev.is_registered:
  1998. return JsonResponse({'result': 0, 'description': u'设备已经被注册!录入设备只能录入尚未注册的设备'})
  1999. data = {
  2000. "devNo": dev.devNo,
  2001. "logicalCode": l,
  2002. "managerId": managerId
  2003. }
  2004. try:
  2005. ManagerInputDev.objects.create(**data)
  2006. except Exception as e:
  2007. logger.exception(e)
  2008. return JsonResponse({'result': 0, 'description': u'注册设备出错!'})
  2009. return JsonResponse({'result': 1, 'description': u'录入成功!'})
  2010. @permission_required(ROLE.manager)
  2011. def inputEquipment(request):
  2012. """
  2013. 手动录入设备 只有厂商录入的设备 才能被旗下的经销商所绑定(温州郎鑫特性)
  2014. :param request: WSGIRequest
  2015. :return: JsonResponse
  2016. """
  2017. logicalCode = json.loads(request.body).get("logicalCode")
  2018. if logicalCode is None:
  2019. return JsonResponse({'result': 0, 'description': u'无效的二维码编号'})
  2020. return inputLogicalCodes([logicalCode], str(request.user.id))
  2021. @permission_required(ROLE.manager)
  2022. def getInputEquipments(request):
  2023. """
  2024. 获取厂商的录入设备列表(温州郎鑫特性)
  2025. :param request: WSGIRequest
  2026. :return: JsonResponse
  2027. """
  2028. pageIndex = int(request.GET.get("pageIndex", 1))
  2029. pageSize = int(request.GET.get("pageSize", 10))
  2030. managerId = str(request.user.id)
  2031. queryset = ManagerInputDev.objects.filter(managerId = managerId)
  2032. count = queryset.count()
  2033. dataList = list()
  2034. for item in queryset.skip((pageIndex - 1) * pageSize).limit(pageSize):
  2035. dev = Device.get_dev(item.devNo)
  2036. dealer = Dealer.get_dealer(dev.get("ownerId"))
  2037. group = Group.get_group(dev.get("groupId"))
  2038. tempData = {
  2039. "id": str(item.id),
  2040. "imei": item.devNo,
  2041. "logicalCode": item.logicalCode,
  2042. "devTypeName": dev.get("devType", {}).get('name'),
  2043. "inputTime": item.inputTime,
  2044. "createdTime": dev.get("dateTimeBinded"),
  2045. "dealerName": dealer.get("nickname") if dealer else "",
  2046. "dealerTel": dealer.get("username") if dealer else "",
  2047. "groupName": group.get("groupName") if group else ""
  2048. }
  2049. dataList.append(tempData)
  2050. payload = {
  2051. "count": count,
  2052. "dataList": dataList
  2053. }
  2054. return JsonResponse({'result': 1, 'description': '', "payload": payload})
  2055. @permission_required(ROLE.manager)
  2056. def deleteInputEquipment(request):
  2057. """
  2058. 删除厂商录入的设备(温州郎鑫特性)
  2059. :param request: WSGIRequest
  2060. :return: JsonResponse
  2061. """
  2062. logicalCodes = json.loads(request.body).get("logicalCode")
  2063. managerId = str(request.user.id)
  2064. for logicalCode in logicalCodes:
  2065. equip = ManagerInputDev.objects.filter(logicalCode = logicalCode, managerId = managerId)
  2066. if not equip:
  2067. return JsonResponse({'result': 0, 'description': u'未查找到设备'})
  2068. dev = Device.get_dev_by_l(logicalCode)
  2069. if not dev:
  2070. return JsonResponse({'result': 0, 'description': u'未查找到设备'})
  2071. if dev.is_registered:
  2072. return JsonResponse({'result': 0, 'description': u'设备已经被经销商注册,不能删除'})
  2073. try:
  2074. ManagerInputDev.objects.filter(logicalCode__in = logicalCodes).delete()
  2075. except Exception as e:
  2076. logger.exception(e)
  2077. return JsonResponse({'result': 0, 'description': u'删除设备错误'})
  2078. return JsonResponse({'result': 1, 'description': u'删除成功'})
  2079. @permission_required(ROLE.manager)
  2080. def uploadLogicalExcel(request):
  2081. """
  2082. 上传logical文件
  2083. :param request:
  2084. :return:
  2085. """
  2086. files = request.FILES.getlist('file')
  2087. if not len(files):
  2088. return JsonResponse({'result': 1, 'description': u'未知的逻辑码文件,请重新试试', 'payload': ''})
  2089. logicalFile = request.FILES.getlist('file')[0]
  2090. ext = os.path.splitext(logicalFile.name)[1]
  2091. if ext not in (".xls", ".xlsx"):
  2092. return JsonErrorResponse(description = u"上传失败,请重新上传excel文件!")
  2093. tempFile = xlrd.open_workbook(file_contents = logicalFile.read())
  2094. sh = tempFile.sheet_by_index(0)
  2095. logicalCodes = sh.row_values(0)
  2096. new_codes = list()
  2097. try:
  2098. for l in logicalCodes:
  2099. new_codes.append(str(int(l)))
  2100. except Exception as e:
  2101. logger.exception(e)
  2102. return inputLogicalCodes(new_codes, str(request.user.id))
  2103. @error_tolerate(logger = logger, nil = JsonErrorResponse(u'禁用设备失败'))
  2104. @permission_required(ROLE.manager)
  2105. def disableDevice(request):
  2106. """
  2107. 厂商禁用设备 昌源需求 下发协议到设备 设备端锁死
  2108. :param request:
  2109. :return:
  2110. """
  2111. payload = json.loads(request.body)
  2112. logicalcode_list = payload.get('logicalCode')
  2113. disable = payload.get('disable')
  2114. for logicalCode in logicalcode_list:
  2115. dev = Device.get_dev_by_logicalCode(logicalCode) # type: DeviceDict
  2116. if not dev:
  2117. logger.error(u'device with logicalCode<{}> is not exists.'.format(logicalCode))
  2118. return JsonErrorResponse(description = u'逻辑码{}对应的设备不存在'.format(logicalCode))
  2119. dealer = Dealer.objects(id = dev.ownerId).first() # type: Dealer
  2120. if not dealer:
  2121. logger.error(u'this device<{}> has invalid owner id<>'.format(repr(dev), dev.ownerId))
  2122. return JsonErrorResponse(description = u'逻辑码{}对应的设备经销商不存在'.format(logicalCode))
  2123. agent = Agent.objects(id = dealer.agentId).first() # type: Agent
  2124. if not agent:
  2125. logger.error(u'this device<{}> has invalid agent id<>'.format(repr(dev), dealer.agentId))
  2126. return JsonErrorResponse(description = u'逻辑码{}对应的设备代理商不存在'.format(logicalCode))
  2127. if agent.managerId != str(request.user.id):
  2128. return JsonErrorResponse(description = u'该设备不属于您的厂家哦!')
  2129. try:
  2130. smartBox = ActionDeviceBuilder.create_action_device(dev)
  2131. smartBox.set_dev_disable(disable)
  2132. Device.objects.filter(devNo = dev.devNo).update(otherConf__disableDevice = disable)
  2133. Device.invalid_device_cache(dev.devNo)
  2134. except ServiceException as e:
  2135. logger.exception('disable device({}) failed error = {}'.format(repr(dev), e.result.get('description')))
  2136. return JsonErrorResponse(description = u'禁用{}失败'.format(logicalCode))
  2137. return JsonOkResponse(description = u"操作成功")
  2138. @error_tolerate(logger = logger, nil = JsonErrorResponse(u'禁用设备失败'))
  2139. @permission_required(ROLE.manager)
  2140. def disableAllDevice(request):
  2141. """
  2142. 厂商禁用设备 昌源需求 下发协议到设备 设备端锁死
  2143. :param request:
  2144. :return:
  2145. """
  2146. payload = json.loads(request.body)
  2147. dealer_id = payload.get('dealerId')
  2148. disable = payload.get('disable')
  2149. dealer = Dealer.objects(id = dealer_id).first() # type: Dealer
  2150. if not dealer:
  2151. return JsonErrorResponse(description = u'备经销商不存在')
  2152. agent = Agent.objects(id = dealer.agentId).first() # type: Agent
  2153. if not agent:
  2154. return JsonErrorResponse(description = u'代理商不存在')
  2155. if agent.managerId != str(request.user.id):
  2156. return JsonErrorResponse(description = u'该设备不属于您的厂家哦!')
  2157. dev_no_list = [item['devNo'] for item in
  2158. Device.get_collection().find({'ownerId': dealer_id}, {'_id': 0, 'devNo': 1})]
  2159. devices = Device.get_dev_by_nos(dev_no_list)
  2160. for dev in devices.values():
  2161. try:
  2162. smartBox = ActionDeviceBuilder.create_action_device(dev)
  2163. smartBox.set_dev_disable(disable)
  2164. Device.objects.filter(devNo = dev.devNo).update(otherConf__disableDevice = disable)
  2165. Device.invalid_device_cache(dev.devNo)
  2166. except ServiceException as e:
  2167. logger.exception('disable device({}) failed error = {}'.format(repr(dev), e.result.get('description')))
  2168. return JsonErrorResponse(description = u'禁用{}失败'.format(dev.devNo))
  2169. return JsonOkResponse(description = u"操作成功")
  2170. @error_tolerate(logger = logger, nil = JsonErrorResponse(u"授权失败"))
  2171. @permission_required(ROLE.manager)
  2172. def dealerDisableDevice(request):
  2173. """
  2174. 授权经销商 能否进行禁用设备操作
  2175. :param request:
  2176. :return:
  2177. """
  2178. dealerId = request.GET.get("id", "")
  2179. grant = json.loads(request.GET.get("disable"))
  2180. dealer = Dealer.objects.filter(id = dealerId).first()
  2181. if not dealer:
  2182. return JsonErrorResponse(description = u"无有效的经销商")
  2183. features = dealer.features
  2184. if grant:
  2185. features.append("dealerDisableDevice")
  2186. else:
  2187. try:
  2188. features.remove("dealerDisableDevice")
  2189. except ValueError:
  2190. pass
  2191. Dealer.objects.filter(id = dealerId).update(features = features)
  2192. cache.delete(Dealer.cache_key(dealerId))
  2193. return JsonOkResponse(description = u"操作成功")
  2194. @permission_required(ROLE.manager)
  2195. def exportDealerDetailList(request):
  2196. def get_offline_task_name(task_type, user, **kwargs):
  2197. # type: (basestring, Dealer, Dict)->basestring
  2198. tmp_list = [task_type, user.username]
  2199. tmp_list.append(str(utils_datetime.generate_timestamp_ex()))
  2200. return '-'.join(tmp_list).replace("/", "_")
  2201. manager = request.user
  2202. query_dict = {"mid": str(request.user.id)}
  2203. offline_task_name = get_offline_task_name(
  2204. task_type = OfflineTaskType.DEALER_INFO_REPORT,
  2205. user = manager,
  2206. **query_dict)
  2207. file_path, offline_task = OfflineTask.issue_export_report(offline_task_name = offline_task_name,
  2208. process_func_name = 'manager_export_dealer_info_excel_from_db',
  2209. task_type = OfflineTaskType.DEALER_INFO_REPORT,
  2210. userid = str(manager.id),
  2211. role = ROLE.manager)
  2212. logger.info('start making charge report=%s' % file_path)
  2213. task_caller(str(offline_task.process_func_name),
  2214. offline_task_id = str(offline_task.id),
  2215. filepath = file_path,
  2216. queryDict = query_dict)
  2217. return JsonResponse({
  2218. 'result': 1,
  2219. 'description': u"请前往离线任务查看任务处理情况",
  2220. 'payload': str(offline_task.id)
  2221. })