|
@@ -0,0 +1,270 @@
|
|
|
+# coding=utf-8
|
|
|
+from typing import TYPE_CHECKING, Optional
|
|
|
+import json
|
|
|
+import logging
|
|
|
+import datetime
|
|
|
+import hashlib
|
|
|
+from urlparse import urljoin
|
|
|
+
|
|
|
+import requests
|
|
|
+
|
|
|
+
|
|
|
+logger = logging.getLogger(__name__)
|
|
|
+
|
|
|
+
|
|
|
+class TianAnException(Exception):
|
|
|
+ def __init__(self, errCode, errMsg, client=None, request=None, response=None):
|
|
|
+ super(TianAnException, self).__init__(errMsg)
|
|
|
+
|
|
|
+ self.errCode = errCode
|
|
|
+ self.errMsg = errMsg
|
|
|
+ self.client = client
|
|
|
+ self.request = request
|
|
|
+ self.response = response
|
|
|
+
|
|
|
+ def __str__(self):
|
|
|
+ if self.client:
|
|
|
+ _repr = '{klass}(client: {client}, errCode: {errCode}, errMsg: {errMsg})'.format(
|
|
|
+ klass=self.__class__.__name__,
|
|
|
+ client=repr(self.client),
|
|
|
+ errCode=self.errCode,
|
|
|
+ errMsg=self.errMsg)
|
|
|
+ else:
|
|
|
+ _repr = '{klass}(errCode: {errCode}, errMsg: {errMsg})'.format(
|
|
|
+ klass=self.__class__.__name__,
|
|
|
+ errCode=self.errCode,
|
|
|
+ errMsg=self.errMsg)
|
|
|
+
|
|
|
+ return _repr
|
|
|
+
|
|
|
+ def __repr__(self):
|
|
|
+ return str(self)
|
|
|
+
|
|
|
+
|
|
|
+class Constant(object):
|
|
|
+ COMPANY_CODE = 1009
|
|
|
+ APP_KEY = "k1009yc83einjr9hpkc21i6hzecqw2n7ou"
|
|
|
+
|
|
|
+
|
|
|
+class TianAn(object):
|
|
|
+
|
|
|
+ URL_BASE = "http://47.96.41.38:8089/api/"
|
|
|
+
|
|
|
+ def __init__(self, companyCode, appKey, timeout=None, autoRetry=False):
|
|
|
+ self._companyCode = companyCode
|
|
|
+ self._appKey = appKey
|
|
|
+ self._timeout = timeout
|
|
|
+ self._autoRetry = autoRetry
|
|
|
+
|
|
|
+ def _request(self, method, path, **kwargs):
|
|
|
+ logger.info("[TianAn request] method = {}, path = {}, kwargs = {}".format(method, path, kwargs))
|
|
|
+ url = urljoin(self.URL_BASE, path)
|
|
|
+
|
|
|
+ headers = {
|
|
|
+ "Content-Type": "application/x-www-form-urlencoded",
|
|
|
+ }
|
|
|
+ kwargs.setdefault("params", {})
|
|
|
+ kwargs.setdefault("timeout", self._timeout)
|
|
|
+ processor = kwargs.pop("processor", None)
|
|
|
+
|
|
|
+ with requests.sessions.Session() as _session:
|
|
|
+ res = _session.request(
|
|
|
+ method=method,
|
|
|
+ url=url,
|
|
|
+ headers=headers,
|
|
|
+ **kwargs
|
|
|
+ )
|
|
|
+ try:
|
|
|
+ res.raise_for_status()
|
|
|
+ except requests.RequestException as rre:
|
|
|
+ logger.info("[{} send request] error! status code = {}, error = {}".format(self.__class__.__name__, res.status_code, rre))
|
|
|
+ raise TianAnException(
|
|
|
+ errCode='HTTP{}'.format(res.status_code),
|
|
|
+ errMsg=rre.message,
|
|
|
+ client=self,
|
|
|
+ request=rre.request,
|
|
|
+ response=rre.response
|
|
|
+ )
|
|
|
+
|
|
|
+ return self._handle_result(
|
|
|
+ res, method, url, processor, **kwargs
|
|
|
+ )
|
|
|
+
|
|
|
+ def _handle_result(self, res, method, url, processor, **kwargs):
|
|
|
+ result = json.loads(res.content.decode('utf-8', 'ignore'), strict=False)
|
|
|
+
|
|
|
+ logger.info("[TianAn _handle_result] method = {}, url = {}, result = {}".format(method, url, result))
|
|
|
+ if processor:
|
|
|
+ return processor(self, result)
|
|
|
+
|
|
|
+ if "code" in result and result["code"] == "0":
|
|
|
+ return result
|
|
|
+
|
|
|
+ # 重试机制待调试
|
|
|
+ if self._autoRetry:
|
|
|
+ return self._request(method, res.request.path_url, processor=processor, **kwargs)
|
|
|
+
|
|
|
+ raise TianAnException(
|
|
|
+ errCode=result.get("code"),
|
|
|
+ errMsg=result.get("msg"),
|
|
|
+ client=self
|
|
|
+ )
|
|
|
+
|
|
|
+ def _post(self, **kwargs):
|
|
|
+ return self._request("post", **kwargs)
|
|
|
+
|
|
|
+ def _get(self, **kwargs):
|
|
|
+ return self._request("get", **kwargs)
|
|
|
+
|
|
|
+ def _get_token(self, qydm=None, key=None, timestamp=None):
|
|
|
+ """
|
|
|
+ :param qydm: 企业代码 固定
|
|
|
+ :param key: 固定
|
|
|
+ :param timestamp: 时间戳 各位为 yyyy-MM-dd hh24:mm:ss
|
|
|
+ """
|
|
|
+ qydm = qydm or self._companyCode
|
|
|
+ key = key or self._appKey
|
|
|
+ timestamp = timestamp or datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
|
|
+ logger.debug("[TianAn get_token] qydm = {}, key = {}, timestamp = {}".format(qydm, key, timestamp))
|
|
|
+
|
|
|
+ s = "{qydm}{key}{timestamp}".format(
|
|
|
+ qydm=qydm, key=key, timestamp=timestamp
|
|
|
+ )
|
|
|
+ token = hashlib.md5(s.encode("utf-8")).hexdigest().lower()
|
|
|
+ logger.debug("[TianAn get_token] token = {}".format(token))
|
|
|
+
|
|
|
+ return token
|
|
|
+
|
|
|
+ def submit_charge_insurance(self, orderNo, logicalCode, startTime, province, city, area, address, finishTime=None):
|
|
|
+ qydm, nowtime = self._companyCode, datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
|
|
+ token = self._get_token(qydm, timestamp=nowtime)
|
|
|
+ data = {
|
|
|
+ "qydm": qydm,
|
|
|
+ "token": token,
|
|
|
+ "ddh": orderNo,
|
|
|
+ "sbh": logicalCode,
|
|
|
+ "kssj": startTime,
|
|
|
+ "jssj": finishTime or startTime,
|
|
|
+ "sheng": province,
|
|
|
+ "shi": city,
|
|
|
+ "xian": area,
|
|
|
+ "xxdz": address,
|
|
|
+ "nowtime": nowtime
|
|
|
+ }
|
|
|
+ return self._post(path="adddevdata", data=data)
|
|
|
+
|
|
|
+ def submit_site_insurance(self, logicalCode, partNums, addTime, address, devType=1, remarks=None):
|
|
|
+ """
|
|
|
+ :param logicalCode: 设备编号
|
|
|
+ :param partNums: 插座个数
|
|
|
+ :param addTime: 安装时间
|
|
|
+ :param address: 安装地址
|
|
|
+ :param devType: 设备类型 暂时固定为1
|
|
|
+ :param remarks: 备注 选填
|
|
|
+ """
|
|
|
+ qydm, nowtime = self._companyCode, datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
|
|
+ token = self._get_token(qydm, timestamp=nowtime)
|
|
|
+ data = {
|
|
|
+ "qydm": qydm,
|
|
|
+ "token": token,
|
|
|
+ "nowtime": nowtime,
|
|
|
+ "czlx": "add",
|
|
|
+ "sbbh": logicalCode,
|
|
|
+ "czgs": partNums,
|
|
|
+ "azsj": addTime,
|
|
|
+ "azwz": address,
|
|
|
+ "sblx": devType,
|
|
|
+ "beizhu": remarks or ""
|
|
|
+ }
|
|
|
+ return self._post(path="sbgl", data=data)
|
|
|
+
|
|
|
+ def edit_site_insurance(self, logicalCode, partNums, addTime, address, devType=1, remarks=None):
|
|
|
+ qydm, nowtime = self._companyCode, datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
|
|
+ token = self._get_token(qydm, timestamp=nowtime)
|
|
|
+ data = {
|
|
|
+ "qydm": qydm,
|
|
|
+ "token": token,
|
|
|
+ "nowtime": nowtime,
|
|
|
+ "czlx": "edit",
|
|
|
+ "sbbh": logicalCode,
|
|
|
+ "czgs": partNums,
|
|
|
+ "azsj": addTime,
|
|
|
+ "azwz": address,
|
|
|
+ "sblx": devType,
|
|
|
+ "beizhu": remarks or ""
|
|
|
+ }
|
|
|
+ return self._post(path="sbgl", data=data)
|
|
|
+
|
|
|
+ def del_site_insurance(self, logicalCode):
|
|
|
+ qydm, nowtime = self._companyCode, datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
|
|
+ token = self._get_token(qydm, timestamp=nowtime)
|
|
|
+ data = {
|
|
|
+ "qydm": qydm,
|
|
|
+ "token": token,
|
|
|
+ "nowtime": nowtime,
|
|
|
+ "czlx": "del",
|
|
|
+ "sbbh": logicalCode,
|
|
|
+ }
|
|
|
+ return self._post(path="sbgl", data=data)
|
|
|
+
|
|
|
+ def query_site_insurance(self, startTime, endTime): # type: (Optional[datetime.datetime, str], Optional[datetime.datetime, str]) -> list
|
|
|
+ """
|
|
|
+ :param startTime: 订单提交的起始日期
|
|
|
+ :param endTime: 订单提交的结束日期
|
|
|
+
|
|
|
+ 放回的rows
|
|
|
+ [
|
|
|
+ {
|
|
|
+ 'aymd': '20230403', 保单生成日期
|
|
|
+ 'bxdh': 'testbx66', 保单号
|
|
|
+ 'bxdhsbxxlist': [ # 对应的设备列表
|
|
|
+ {'sbbh': 'xxx'}, {'sbbh': 'xxxx'}
|
|
|
+ ],
|
|
|
+ 'bxjssj': '2024-04-03 14:45:47', # 保险开始时间
|
|
|
+ 'bxkssj': '2023-04-03 14:45:45', # 保险结束时间
|
|
|
+ 'bxqx': '1', # 期限 单位年
|
|
|
+ 'dysbnum': 2, # 对应的设备数量
|
|
|
+ 'qydm': '1003', # 企业代码 无用
|
|
|
+ 'sbxxbxdhbid': '2023040314461490434913954', 主键 遇到问题时候查询(售后)
|
|
|
+ 'scsjendymd': '20230331', 该保险单号对应的上传设备开始日期
|
|
|
+ 'scsjstartymd': '20230325' 该保险单号对应的上传设备结束日期
|
|
|
+ }
|
|
|
+ ]
|
|
|
+
|
|
|
+ """
|
|
|
+ qydm, nowtime = self._companyCode, datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
|
|
+ token = self._get_token(qydm, timestamp=nowtime)
|
|
|
+ if isinstance(startTime, (unicode, str)):
|
|
|
+ try:
|
|
|
+ startTime = datetime.datetime.strptime(startTime, "%Y-%m-%d")
|
|
|
+ except ValueError:
|
|
|
+ raise TianAnException(errCode="", errMsg=u"请传入正确的时间格式:%Y-%m-%d")
|
|
|
+
|
|
|
+ startTime = startTime.strftime("%Y%m%d")
|
|
|
+
|
|
|
+ if isinstance(endTime, (unicode, str)):
|
|
|
+ try:
|
|
|
+ endTime = datetime.datetime.strptime(endTime, "%Y-%m-%d")
|
|
|
+ except ValueError:
|
|
|
+ raise TianAnException(errCode="", errMsg=u"请传入正确的时间格式:%Y-%m-%d")
|
|
|
+
|
|
|
+ endTime = endTime.strftime("%Y%m%d")
|
|
|
+
|
|
|
+ data = {
|
|
|
+ "qydm": qydm,
|
|
|
+ "token": token,
|
|
|
+ "nowtime": nowtime,
|
|
|
+ "startymd": startTime,
|
|
|
+ "endymd": endTime,
|
|
|
+ }
|
|
|
+ result = self._post(path="getSbglBxdh", data=data)
|
|
|
+ if "rows" not in result:
|
|
|
+ raise TianAnException(errCode="", errMsg=u"未获取到数据")
|
|
|
+
|
|
|
+ return result["rows"]
|
|
|
+
|
|
|
+
|
|
|
+def get_client():
|
|
|
+ return TianAn(Constant.COMPANY_CODE, Constant.APP_KEY)
|
|
|
+
|
|
|
+
|