views.py 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519
  1. import base64
  2. import datetime
  3. import json
  4. import time
  5. import traceback
  6. from django.http import JsonResponse
  7. from rest_framework.request import Request
  8. from rest_framework.response import Response
  9. from rest_framework.views import APIView
  10. import tools
  11. from wx import logic
  12. from wx.dbTools import DB_WX_GZH_User, DBYiXueUser, DBSysUser
  13. from wx.parsers import GZHParser, JsonParser
  14. from wx.wxModels import WXUserMsg, WXMenu, UserRequest, CalcNongLiRequest, GetSiZhuRequest, GetSiZhuByNongLiRequest, \
  15. GetSiZhuByTextsRequest, SaveUserRequest, LoadUserRequest, DeleteUserRequest, LoginRequest
  16. from yixue import Models, DataCenter
  17. from yixue.Models import BaseInfo
  18. def is_empty(s: str):
  19. return s is None or len(s) == 0
  20. # Create your views here.
  21. class GetAccessToken(APIView):
  22. def get(self, request):
  23. return Response(tools.__get_access_token__())
  24. class UpdateMenu(APIView):
  25. def post(self, request: Request):
  26. menu = WXMenu()
  27. menu.add_click_button("jinriyunshi", "jin_ri_yun_shi")
  28. tk = tools.__get_access_token__()
  29. print(tk)
  30. url = " https://api.weixin.qq.com/cgi-bin/menu/create?access_token=" + tk
  31. print(url)
  32. body = json.dumps(menu.obj, ensure_ascii=False)
  33. print(body)
  34. rsp = tools.sync_post(url, menu.obj)
  35. print(rsp.text)
  36. return Response(rsp.text)
  37. class RemoveMenu(APIView):
  38. pass
  39. # def user_view(request: Request):
  40. # return render(request, "wx/user_view.html")
  41. class UserMsg(APIView):
  42. parser_classes = [GZHParser]
  43. def post(self, request: Request):
  44. obj = json.loads(request.data)
  45. bean = WXUserMsg()
  46. for key in obj:
  47. if len(key) > 0:
  48. value = obj[key]
  49. setattr(bean, key, value)
  50. return Response(obj)
  51. class UrlCheck(APIView):
  52. parser_classes = [GZHParser]
  53. def get(self, request: Request):
  54. sign = request.GET.get("signature")
  55. echo_str = request.GET.get("echostr")
  56. timestamp = request.GET.get("timestamp")
  57. nonce = request.GET.get("nonce")
  58. token = "deanlai"
  59. # list = [token, timestamp, nonce]
  60. # list.sort()
  61. # sha1 = hashlib.sha1()
  62. # map(sha1.update, list)
  63. # hashcode = sha1.hexdigest()
  64. return Response(int(echo_str))
  65. def post(self, request: Request):
  66. obj = tools.xml_parser(request.data)
  67. bean = WXUserMsg.build_from(obj)
  68. content = ""
  69. try:
  70. if bean.Content == "今日运势":
  71. content = logic.get_lucky_day(bean.FromUserName)
  72. except Exception as e:
  73. print(e)
  74. print(bean)
  75. reply = WXUserMsg()
  76. reply.ToUserName = bean.FromUserName
  77. reply.FromUserName = bean.ToUserName
  78. reply.MsgType = bean.MsgType
  79. reply.CreateTime = int(time.time())
  80. reply.Content = content
  81. xml_data = tools.xml_build("xml", reply)
  82. xml_str = tools.xml_to_string(xml_data)
  83. print(xml_str)
  84. return Response(xml_str)
  85. class ApplyUserInfo(APIView):
  86. def post(self, request: Request):
  87. bean = UserRequest.build_from(request.data)
  88. msg = "您的信息已记录,请退出页面后再次点击【今日运势】"
  89. code = 0
  90. if is_empty(bean.open_id):
  91. code = -100
  92. msg = "未获取到用户信息,请退出页面重试或联系客服"
  93. elif is_empty(bean.user_name):
  94. code = -1
  95. msg = "用户姓名未填写"
  96. else:
  97. if DB_WX_GZH_User.check_exist(
  98. open_id=bean.open_id
  99. ):
  100. code = -100
  101. msg = "用户信息已存在,如需修改请联系客服"
  102. else:
  103. DB_WX_GZH_User.insert(
  104. open_id=bean.open_id,
  105. user_name=bean.user_name,
  106. is_man=bean.is_man,
  107. date_mode=bean.date_mode,
  108. born_year=bean.born_year,
  109. born_month=bean.born_month,
  110. born_day=bean.born_day,
  111. born_hour=bean.born_hour,
  112. born_minute=bean.born_minute,
  113. know_time=bean.know_time,
  114. born_sheng=bean.born_sheng,
  115. born_shi=bean.born_shi,
  116. born_qu=bean.born_qu,
  117. )
  118. return Response({"code": code, "msg": msg})
  119. def jia_mi(s: str):
  120. return base64.b64encode(s.encode("utf-8")).decode("utf-8")
  121. def jie_mi(s: str):
  122. return base64.b64decode(s).decode("utf-8")
  123. class LoginSystem(APIView):
  124. parser_classes = [JsonParser]
  125. def post(self, request):
  126. dt = json.loads(request.data)
  127. # print(dt)
  128. req = LoginRequest.build_from(dt)
  129. finger = req.userAgent + req.colorDepth + req.timezoneOffset + req.language
  130. user = DBSysUser.query_first_by(account=req.account, password=req.password)
  131. code = 200
  132. rsp = {}
  133. # 登录流程
  134. # 1、账号密码比对
  135. # 1-1、账号密码错误,直接返回
  136. # 1-2、账号密码正确,取得当前设备指纹,换算成cur_token
  137. # 1-2-1、数据库未记录设备指纹,更新设备指纹到数据库,在内存存入cur_token
  138. # 1-2-2、数据库已记录设备指纹,提取数据库存的设备指纹,换算成db_token,对比db_token和cur_token
  139. # 1-2-2-1、db_token 和 cur_token 不一致,表示更换了设备登录,此时要修改内存中的mem_token,确保旧的账号访问API失败
  140. # 1-2-2-2、db_token 和 cur_token 一致,表示同一设备登录
  141. if user is not None:
  142. cur_token = jia_mi(finger)
  143. if user.finger is None:
  144. # 第一次,记录设备信息
  145. DBSysUser.update(conditions=(DBSysUser.id == user.id), values={"finger": finger})
  146. DataCenter.set_token(user.id, cur_token)
  147. else:
  148. # 已记录登录的设备,则提取指纹,换算成db_token
  149. db_finger = user.finger
  150. db_token = jia_mi(db_finger)
  151. if db_token != cur_token:
  152. # 用户更换了登录设备,此时需要更新指纹,并记录更换设备的信息
  153. if user.allow_change_dev is True:
  154. ct = user.dev_change
  155. ct += 1
  156. DBSysUser.update(conditions=(DBSysUser.id == user.id),
  157. values={"finger": finger, "dev_change": ct})
  158. print("用户:", user.name, " 更换了登录设备,更换次数:", user.dev_change)
  159. DataCenter.set_token(user.id, cur_token)
  160. else:
  161. return JsonResponse({"code": -100, "data": {}}, json_dumps_params={'ensure_ascii': False})
  162. else:
  163. DataCenter.set_token(user.id, cur_token)
  164. rsp = {
  165. "name": user.name,
  166. "token": cur_token,
  167. "uid": user.id
  168. }
  169. else:
  170. # 账号密码错误
  171. code = -1
  172. return JsonResponse({"code": code, "data": rsp}, json_dumps_params={'ensure_ascii': False})
  173. class GetSiZhu(APIView):
  174. parser_classes = [JsonParser]
  175. def post(self, request: Request):
  176. '''
  177. request:{
  178. token:str
  179. isMan:bool
  180. year:int 年
  181. month:int 月
  182. day:int 日
  183. hourMode:int 2=未知
  184. hour:int 时
  185. minute:int 分
  186. areaMode:int
  187. sheng:str 省
  188. shi:str 市
  189. qu:str 区
  190. }
  191. 只接受新历(阳历)
  192. '''
  193. rsp = {}
  194. tm1 = datetime.datetime.now()
  195. print("receive request", tm1)
  196. try:
  197. dt = json.loads(request.data)
  198. # print(dt)
  199. req = GetSiZhuRequest.build_from(dt)
  200. if req.token is None:
  201. return JsonResponse({"code": -100, "data": {}})
  202. else:
  203. # 对比token是否发生了改变
  204. mem_token = DataCenter.get_token(req.uid)
  205. if mem_token is None:
  206. DataCenter.set_token(req.uid, req.token)
  207. elif mem_token != req.token:
  208. return JsonResponse({"code": -200, "data": {}})
  209. req.fix_data()
  210. result = logic.calc_si_zhu(req.year, req.month, req.day, req.hour, req.minute, req.sheng, req.shi, req.qu)
  211. tm13 = datetime.datetime.now()
  212. print("calc sizhu use:", tm13 - tm1)
  213. if result is not None:
  214. bazi = logic.build_bazi(result, req.isMan)
  215. bazi.base_info = BaseInfo()
  216. bazi.base_info.date_mode = 0
  217. bazi.base_info.year = req.year
  218. bazi.base_info.month = req.month
  219. bazi.base_info.day = req.day
  220. bazi.base_info.hour_mode = req.hourMode
  221. bazi.base_info.hour = req.hour
  222. bazi.base_info.minute = req.minute
  223. bazi.base_info.area_mode = req.areaMode
  224. bazi.base_info.sheng = req.sheng
  225. bazi.base_info.shi = req.shi
  226. bazi.base_info.qu = req.qu
  227. if req.hourMode == 2:
  228. bazi.tai_yang_shi = None
  229. rsp = bazi.to_response()
  230. except Exception as e:
  231. print(e)
  232. traceback.print_exc()
  233. return JsonResponse({"code": 200, "data": rsp})
  234. class GetSiZhuByNongLi(APIView):
  235. parser_classes = [JsonParser]
  236. def post(self, request: Request):
  237. '''
  238. request:{
  239. uid:int
  240. token:str
  241. isMan:bool
  242. year:int 年
  243. month:string 月 注意是字符串
  244. day:string 日 注意是字符串
  245. hourMode:int 2=未知
  246. hour:int 时
  247. minute:int 分
  248. areaMode:int
  249. sheng:str 省
  250. shi:str 市
  251. qu:str 区
  252. }
  253. 只接受农历(阴历)
  254. '''
  255. rsp = {}
  256. try:
  257. dt = json.loads(request.data)
  258. req = GetSiZhuByNongLiRequest.build_from(dt)
  259. if req.token is None:
  260. return JsonResponse({"code": -100, "data": {}})
  261. else:
  262. # 对比token是否发生了改变
  263. mem_token = DataCenter.get_token(req.uid)
  264. if mem_token is None:
  265. DataCenter.set_token(req.uid, req.token)
  266. elif mem_token != req.token:
  267. return JsonResponse({"code": -200, "data": {}})
  268. req.fix_data()
  269. xinli = logic.calc_nong_li(req.year, req.month, req.day)
  270. print("对应阳历:", xinli)
  271. result = logic.calc_si_zhu(req.year, xinli.month, xinli.day, req.hour, req.minute, req.sheng, req.shi,
  272. req.qu)
  273. if result is not None:
  274. bazi = logic.build_bazi(result, req.isMan)
  275. bazi.base_info = BaseInfo()
  276. bazi.base_info.date_mode = 1
  277. bazi.base_info.nongli_year = req.year
  278. bazi.base_info.nongli_month = req.month
  279. bazi.base_info.nongli_day = req.day
  280. bazi.base_info.hour_mode = req.hourMode
  281. bazi.base_info.hour = req.hour
  282. bazi.base_info.minute = req.minute
  283. bazi.base_info.area_mode = req.areaMode
  284. bazi.base_info.sheng = req.sheng
  285. bazi.base_info.shi = req.shi
  286. bazi.base_info.qu = req.qu
  287. if req.hourMode == 2:
  288. bazi.tai_yang_shi = None
  289. rsp = bazi.to_response()
  290. except Exception as e:
  291. print(e)
  292. traceback.print_exc()
  293. return JsonResponse({"code": 200, "data": rsp})
  294. class GetSiZhuByTexts(APIView):
  295. parser_classes = [JsonParser]
  296. def post(self, request: Request):
  297. '''
  298. request:{
  299. uid:int
  300. token:str
  301. isMan:bool
  302. niangan:str
  303. nianzhi:str
  304. yuegan:str
  305. yuezhi:str
  306. rigan:str
  307. rizhi:str
  308. shigan:str
  309. shizhi:str
  310. hourMode:int 1=未知
  311. }
  312. '''
  313. rsp = {}
  314. code = 200
  315. try:
  316. dt = json.loads(request.data)
  317. req = GetSiZhuByTextsRequest.build_from(dt)
  318. if req.token is None:
  319. return JsonResponse({"code": -100, "data": {}})
  320. else:
  321. # 对比token是否发生了改变
  322. mem_token = DataCenter.get_token(req.uid)
  323. if mem_token is None:
  324. DataCenter.set_token(req.uid, req.token)
  325. elif mem_token != req.token:
  326. return JsonResponse({"code": -200, "data": {}})
  327. sizhu_checker = logic.check_date_by_texts(req.niangan, req.nianzhi, req.yuegan, req.yuezhi, req.rigan,
  328. req.rizhi,
  329. req.shigan, req.shizhi)
  330. # print(sizhu_checker)
  331. result = Models.SiZhuResult()
  332. result.nian_gan = req.niangan
  333. result.nian_zhi = req.nianzhi
  334. result.yue_gan = req.yuegan
  335. result.yue_zhi = req.yuezhi
  336. result.ri_gan = req.rigan
  337. result.ri_zhi = req.rizhi
  338. result.shi_gan = req.shigan
  339. result.shi_zhi = req.shizhi
  340. result.sheng = "未知地区"
  341. result.shi = "-"
  342. result.qu = "-"
  343. result.tai_yang_shi = None
  344. if sizhu_checker.error:
  345. code = -1
  346. rsp = sizhu_checker.to_response()
  347. if req.ignoreError:
  348. pass
  349. else:
  350. pass
  351. else:
  352. if req.hourMode == 0:
  353. # print(sizhu_checker.adv_date[0])
  354. result.tai_yang_shi = datetime.datetime.strptime(sizhu_checker.adv_date[0], "%Y-%m-%d %H:%M")
  355. else:
  356. result.tai_yang_shi = datetime.datetime.strptime(sizhu_checker.adv_date[0] + " 0:00",
  357. "%Y-%m-%d %H:%M")
  358. result.shi_gan = "无"
  359. result.shi_zhi = "无"
  360. bazi = logic.build_bazi(result, req.isMan)
  361. bazi.base_info = BaseInfo()
  362. bazi.base_info.date_mode = 2
  363. bazi.base_info.nian_gan = req.niangan
  364. bazi.base_info.nian_zhi = req.nianzhi
  365. bazi.base_info.yue_gan = req.yuegan
  366. bazi.base_info.yue_zhi = req.yuezhi
  367. bazi.base_info.ri_gan = req.rigan
  368. bazi.base_info.ri_zhi = req.rizhi
  369. bazi.base_info.shi_gan = req.shigan
  370. bazi.base_info.shi_zhi = req.shizhi
  371. if req.hourMode == 1:
  372. bazi.tai_yang_shi = None
  373. rsp = bazi.to_response()
  374. except Exception as e:
  375. print(e)
  376. traceback.print_exc()
  377. return Response({"code": code, "data": rsp})
  378. class CalcNongLi(APIView):
  379. parser_classes = [JsonParser]
  380. def post(self, request: Request):
  381. '''
  382. request:{
  383. year:int
  384. month:str 农历月
  385. day:str 农历日
  386. }
  387. '''
  388. result = None
  389. try:
  390. dt = json.loads(request.data)
  391. req = CalcNongLiRequest.build_from(dt)
  392. result = logic.calc_nong_li(req.year, req.month, req.day)
  393. except Exception as e:
  394. print(e)
  395. traceback.print_exc()
  396. return Response({"code": 200, "data": result})
  397. class SaveUser(APIView):
  398. parser_classes = [JsonParser]
  399. def post(self, request: Request):
  400. rsp = []
  401. try:
  402. dt = json.loads(request.data)
  403. req = SaveUserRequest.build_from(dt)
  404. DBYiXueUser.insert(
  405. name=req.name, isMan=req.isMan, dateMode=req.dateMode, extra=req.extra, owner_id=req.owner_id,
  406. year=req.year, month=req.month, day=req.day,
  407. hourMode=req.hourMode, hour=req.hour, minute=req.minute,
  408. areaMode=req.areaMode, sheng=req.sheng, shi=req.shi, qu=req.qu,
  409. nongli_year=req.nongli_year, nongli_month=req.nongli_month, nongli_day=req.nongli_day,
  410. req_nian_gan=req.req_nian_gan, req_nian_zhi=req.req_nian_zhi,
  411. req_yue_gan=req.req_yue_gan, req_yue_zhi=req.req_yue_zhi,
  412. req_ri_gan=req.req_ri_gan, req_ri_zhi=req.req_ri_zhi,
  413. req_shi_gan=req.req_shi_gan, req_shi_zhi=req.req_shi_zhi,
  414. rsp_nian_gan=req.rsp_nian_gan, rsp_nian_zhi=req.rsp_nian_zhi,
  415. rsp_yue_gan=req.rsp_yue_gan, rsp_yue_zhi=req.rsp_yue_zhi,
  416. rsp_ri_gan=req.rsp_ri_gan, rsp_ri_zhi=req.rsp_ri_zhi,
  417. rsp_shi_gan=req.rsp_shi_gan, rsp_shi_zhi=req.rsp_shi_zhi,
  418. )
  419. data = DBYiXueUser.query_by(owner_id=req.owner_id)
  420. for dt in data:
  421. rsp.append(dt.to_json_object())
  422. except Exception as e:
  423. print(e)
  424. traceback.print_exc()
  425. return Response({"code": 200, "data": rsp})
  426. class LoadUser(APIView):
  427. parser_classes = [JsonParser]
  428. def post(self, request: Request):
  429. rsp = []
  430. try:
  431. dt = json.loads(request.data)
  432. req = LoadUserRequest.build_from(dt)
  433. data = DBYiXueUser.query_by(owner_id=req.owner_id)
  434. for dt in data:
  435. rsp.append(dt.to_json_object())
  436. except Exception as e:
  437. print(e)
  438. traceback.print_exc()
  439. return Response({"code": 200, "data": rsp})
  440. class DeleteUser(APIView):
  441. parser_classes = [JsonParser]
  442. def post(self, request: Request):
  443. rsp = []
  444. try:
  445. dt = json.loads(request.data)
  446. req = DeleteUserRequest.build_from(dt)
  447. DBYiXueUser.delete_by(id=req.user_id, owner_id=req.owner_id)
  448. data = DBYiXueUser.query_by(owner_id=req.owner_id)
  449. for dt in data:
  450. rsp.append(dt.to_json_object())
  451. except Exception as e:
  452. print(e)
  453. traceback.print_exc()
  454. return Response({"code": 200, "data": rsp})