369697a8 by 周伟奇

fix merge

2 parents db2ce2cf ec8b39ff
......@@ -1649,3 +1649,69 @@ CA_COMPARE_FIELD = {
}
CONTRACT_SHEET_NAME = '合同'
# ------------------CMS--------------------------------------
BANK_INFO_MAP = (
('accountNo', 'bankAccountDetails.accountNo'),
('bankName', 'bankAccountDetails.bankName'),
('accountHolderName', 'bankAccountDetails.accountHolderName'),
)
VEHICLE_INFO_MAP = (
('vehicleStatus', 'vehicleStatus'),
('vinNo', 'vehicleInformation.vinNo'),
('dealer', 'dealerName'),
('vehicleTransactionAmount', 'totalFinanceAmount'),
)
CORPORATE_INFO_MAP = (
('firstIdType', ),
('firstIdNo', ),
('companyName', ),
('legalRepName', ),
('businessLicenseNo', ),
('organizationCreditCode', ),
('taxRegistrationCertificateNo', ),
('establishmentDate', ),
('businessLicenseDueDate', ),
)
INDIVIDUAL_INFO_MAP = (
('applicantType', 'applicantInformation.applicantType'),
('customerType', 'applicantInformation.customersubType'),
('idType', 'applicantInformation.IDInformation.idType'),
('customerName', 'applicantInformation.name'),
('idNum', 'applicantInformation.IDInformation.idNum'),
('dateOfBirth', 'applicantInformation.dateOfBirth'),
('idExpiryDate', 'applicantInformation.IDInformation.idExpiryDate'),
('hukouProvince', ),
('hukouCity', ),
('secondIdType', 'applicantInformation.IDInformation.idType'),
('secondIdNum', 'applicantInformation.IDInformation.idNum'),
('companyName', ),
('registeredCapital', ),
('selfEmployedSubType', ),
)
CMS_TO_POS = [
('bank_info', BANK_INFO_MAP),
('vehicle_info', VEHICLE_INFO_MAP),
('corporate_cus_info', CORPORATE_INFO_MAP),
('individual_cus_info', INDIVIDUAL_INFO_MAP),
]
TENANT_MAP = {
AFC_PREFIX: 1,
HIL_PREFIX: 2,
}
APPLICANT_TYPE_MAP = {
'Borrower': 'CUSTR',
'Co Borrower': 'COAPP',
'Guarantor': 'GAUTR1',
'Mortgager': 'GAUTR2'
}
......
......@@ -13,9 +13,14 @@ class OCR2Exception(Exception):
class OCR4Exception(Exception):
pass
class LTGTException(Exception):
pass
class GCAPException(Exception):
pass
class CMSException(Exception):
pass
......
......@@ -244,6 +244,33 @@ class HILSEComparisonInfo(models.Model):
# 比对信息表
class AFCSECMSInfo(models.Model):
id = models.BigAutoField(primary_key=True, verbose_name="id") # 主键
application_id = models.CharField(max_length=64, verbose_name="申请id") # 索引
content = models.TextField(verbose_name="CMS信息")
update_time = models.DateTimeField(auto_now=True, verbose_name='修改时间')
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间') # 索引
class Meta:
managed = False
db_table = 'afc_se_cms_info'
situ_db_label = 'afc'
# 比对信息表
class HILSECMSInfo(models.Model):
id = models.BigAutoField(primary_key=True, verbose_name="id") # 主键
application_id = models.CharField(max_length=64, verbose_name="申请id") # 索引
content = models.TextField(verbose_name="CMS信息")
update_time = models.DateTimeField(auto_now=True, verbose_name='修改时间')
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间') # 索引
class Meta:
managed = False
db_table = 'hil_se_cms_info'
# 比对信息表
class HILComparisonInfo(models.Model):
id = models.BigAutoField(primary_key=True, verbose_name="id") # 主键
uniq_seq = models.CharField(max_length=128, verbose_name="唯一序列号") # 索引?
......
import requests
from settings import conf
from common.redis_cache import redis_handler as rh
from apps.doc.exceptions import CMSException
class CMS:
def __init__(self):
self.oauth_url = conf.CMS_OAUTH_URL
self.url = conf.CMS_URL
self.oauth_payload = {
'grant_type': 'client_credentials',
'client_id': conf.CMS_OAUTH_ID,
'client_secret': conf.CMS_OAUTH_SECRET,
'scope': conf.CMS_OAUTH_SCOPE
}
self.token_type = 'bearer'
self.token = None
self.token_key = 'access_token'
self.expires_key = 'expires_in'
self.token_type_key = 'token_type'
def update_token(self):
response = requests.post(self.oauth_url, data=self.oauth_payload, files=[])
if response.status_code != 200:
raise CMSException('CMS Oauth response with code: {0}'.format(response.status_code))
token = response.json().get(self.token_key)
if not isinstance(token, str):
raise CMSException('CMS Oauth can not get token: {0}'.format(response.json()))
self.token = token
self.token_type = response.json().get(self.token_type_key, self.token_type)
expires = response.json().get(self.expires_key, 3600)
rh.set_cms_token(self.token, expires)
def get_token(self):
if self.token is None:
self.token = rh.get_cms_token()
if self.token is None:
self.update_token()
return self.token
def send(self, payload):
token = self.get_token()
headers = {
'Authorization': '{0} {1}'.format(self.token_type.capitalize(), token),
'Content-Type': 'application/json',
}
response = requests.post(self.url, headers=headers, json=payload)
if response.status_code != 200:
raise CMSException('CMS Oauth response with code: {0}'.format(response.status_code))
return response.json()
cms = CMS()
......@@ -22,8 +22,10 @@ from .models import (
GCAPRecords,
AFCComparisonInfo,
AFCSEComparisonInfo,
AFCSECMSInfo,
HILComparisonInfo,
HILSEComparisonInfo,
HILSECMSInfo,
AFCCompareOfflineReport,
HILCompareOfflineReport,
AFCCACompareResult,
......@@ -327,7 +329,7 @@ info_args = {
'customersubType': fields.Str(required=True, validate=validate.Length(max=32)),
'selfEmployedSubType': fields.Str(required=False, validate=validate.Length(max=32)),
'name': fields.Str(required=True, validate=validate.Length(max=64)),
'legalRepName': fields.Str(required=True, validate=validate.Length(max=64)),
'legalRepName': fields.Str(required=False, validate=validate.Length(max=64)),
'dateOfBirth': CustomDate(required=False),
'nationality': fields.Str(required=False, validate=validate.Length(max=64)),
'establishmentDate': CustomDate(required=False),
......@@ -358,10 +360,10 @@ payment_schedule = {
}
associated_services = {
'associatedServices': fields.Str(required=True, validate=validate.Length(max=64)),
'price': CustomDecimal(required=True),
'financed': CustomDecimal(required=True),
'total': CustomDecimal(required=True),
'associatedServices': fields.Str(required=False, validate=validate.Length(max=64)),
'price': CustomDecimal(required=False),
'financed': CustomDecimal(required=False),
'total': CustomDecimal(required=False),
}
vehicle_info = {
......@@ -382,13 +384,13 @@ insurance_details = {
}
corporate_info = {
'hashCode': fields.Str(required=True, validate=validate.Length(max=64)),
'borrowerName': fields.Str(required=True, validate=validate.Length(max=64)),
'fiscalYear': fields.Int(required=True),
'totaAssets': CustomDecimal(required=True),
'totalLiabilitiesAndOwnersEquity': CustomDecimal(required=True),
'cashAndCashEquivalentAtEndOfPeriod': CustomDecimal(required=True),
'netProfit': CustomDecimal(required=True),
'hashCode': fields.Str(required=False, validate=validate.Length(max=64)),
'borrowerName': fields.Str(required=False, validate=validate.Length(max=64)),
'fiscalYear': fields.Int(required=False),
'totaAssets': CustomDecimal(required=False),
'totalLiabilitiesAndOwnersEquity': CustomDecimal(required=False),
'cashAndCashEquivalentAtEndOfPeriod': CustomDecimal(required=False),
'netProfit': CustomDecimal(required=False),
}
se_verification = {
......@@ -411,13 +413,13 @@ se_cms_content = {
'dealerName': fields.Str(required=True, validate=validate.Length(max=512)),
'tier': fields.Str(required=True, validate=validate.Length(max=64)),
'province': fields.Str(required=True, validate=validate.Length(max=64)),
'fapiaoIssuerDealer': fields.Str(required=True, validate=validate.Length(max=512)),
'fapiaoIssuerDealer': fields.Str(required=False, validate=validate.Length(max=512)),
'customerName': fields.Str(required=True, validate=validate.Length(max=64)),
'customerIdNo': fields.Str(required=True, validate=validate.Length(max=64)),
'vehicleStatus': fields.Str(required=True, validate=validate.Length(max=64)),
'applicationSource': fields.Str(required=True, validate=validate.Length(max=64)),
'contractSource': fields.Str(required=True, validate=validate.Length(max=64)),
'applicationRating': fields.Int(required=True),
'applicationRating': fields.Int(required=False),
'applicantInformation': fields.List(fields.Nested(info_args),
required=True, validate=validate.Length(min=1, max=4)),
......@@ -647,7 +649,7 @@ class CompareView(GenericView):
corporate_cus_info=corporate_cus_info,
)
# 触发比对
compare.apply_async((application_id, business_type, uniq_seq, None, True),
compare.apply_async((application_id, business_type, uniq_seq, None, True, False),
queue='queue_compare')
return response.ok()
......@@ -708,7 +710,7 @@ class SECompareView(GenericView):
quotationt_info=quotationt_info
)
# 触发比对
compare.apply_async((application_id, business_type, uniq_seq, None, False),
compare.apply_async((application_id, business_type, uniq_seq, None, False, False),
queue='queue_compare')
return response.ok()
......@@ -1091,7 +1093,21 @@ class SECMSView(GenericView):
# pos上传比对信息接口 SE
@use_args(se_cms_args, location='data')
def post(self, request, args):
self.running_log.info('cms in')
cms_info = args.get('content', {})
business_type = consts.AFC_PREFIX if cms_info.get('financeCompany', '').startswith('宝马') else consts.HIL_PREFIX
src_application_id = cms_info.get('settlemnetVerification', {}).get('applicationNo', '')
application_id = src_application_id[:src_application_id.rfind('-')]
content_str = json.dumps(cms_info)
comparison_class = HILSECMSInfo if business_type in consts.HIL_SET else AFCSECMSInfo
comparison_class.objects.create(
application_id=application_id,
content=content_str,
)
# 触发比对
compare.apply_async((application_id, business_type, None, None, False, True),
queue='queue_compare')
return response.ok()
post.openapi_doc = '''
......
......@@ -36,6 +36,7 @@ class RedisHandler:
self.common_queue_key = '{0}:common_queue'.format(self.prefix)
self.priority_queue_key = '{0}:priority_queue'.format(self.prefix)
self.session_id_key = '{0}:session_id'.format(self.prefix)
self.cms_token_key = '{0}:cms_token'.format(self.prefix)
def enqueue(self, tasks, is_priority=False):
# 1
......@@ -57,3 +58,9 @@ class RedisHandler:
def get_session_id(self):
return self.redis.get(self.session_id_key)
def get_cms_token(self):
return self.redis.get(self.cms_token_key)
def set_cms_token(self, token, expires=None):
return self.redis.set(self.cms_token_key, token, expires)
......
from Crypto.Cipher import DES3
from Crypto.Hash import MD5
import struct
import base64
import codecs
def mds_hash(target_str):
h = MD5.new()
h.update(target_str.encode('utf-8'))
return h.digest()
def des_pad(data):
data = data.encode('utf-8')
e = len(data)
x = (e + 4) % 8
y = 0 if x == 0 else 8 - x
size_byte = struct.pack('>I', e)
result_byte = list(range(len(size_byte) + e + y))
result_byte[0:4] = size_byte
result_byte[4:4 + e] = data
for i in range(0, y):
result_byte[e + 4 + i] = 0
result_str = bytearray(result_byte).decode('utf-8')
return result_str
# DES3加密数据
def encode_des(to_encode_str, des_key):
"""
DES3加密数据
Args:
to_encode_str(str): 要被加密的原字符串,这里的字符串需要被des_pad一下
des_key(str): 加密的key
Returns:
"""
key = mds_hash(des_key)
des3 = DES3.new(key, DES3.MODE_ECB)
data = des3.encrypt(des_pad(to_encode_str))
data = codecs.encode(data, 'hex')
return data
def un_des_pad(data):
result_byte = data[0:4]
e = struct.unpack('>I', result_byte)[0]
x = (e + 4) % 8
y = 0 if x == 0 else 8 - x
return data[4:] if y == 0 else data[4:-y]
def decode_des(to_decode_str, des_key):
"""
解密数据
Args:
to_decode_str(str): 要解密的原字符串
des_key(str): 解密的key
Returns:
"""
key = mds_hash(des_key)
des3 = DES3.new(key, DES3.MODE_ECB)
param = base64.b64decode(to_decode_str)
param = des3.decrypt(param)
param = un_des_pad(param).decode('utf-8')
return param
import pyodbc
hil_sql = """
create table afc_se_cms_info
(
id bigint identity primary key,
application_id nvarchar(64) not null,
content nvarchar(max) not null,
update_time datetime not null,
create_time datetime not null
);
create index afc_se_cms_info_application_id_index
on afc_se_cms_info (application_id);
create index afc_se_cms_info_create_time_index
on afc_se_cms_info (create_time);
"""
afc_sql = """
create table hil_se_cms_info
(
id bigint identity primary key,
application_id nvarchar(64) not null,
content nvarchar(max) not null,
update_time datetime not null,
create_time datetime not null
);
create index hil_se_cms_info_application_id_index
on hil_se_cms_info (application_id);
create index hil_se_cms_info_create_time_index
on hil_se_cms_info (create_time);
"""
hil_cnxn = pyodbc.connect('DRIVER={ODBC Driver 17 for SQL Server};', autocommit=True)
hil_cursor = hil_cnxn.cursor()
hil_cursor.execute(hil_sql)
hil_cursor.close()
hil_cnxn.close()
afc_cnxn = pyodbc.connect('DRIVER={ODBC Driver 17 for SQL Server};', autocommit=True)
afc_cursor = afc_cnxn.cursor()
afc_cursor.execute(afc_sql)
afc_cursor.close()
afc_cnxn.close()
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!