def dispatch_request(self, *args, **kwargs): if request.method not in self.allow_method: raise RequestsError(code=1014000000, message=',请求方式错误') if request.method == "GET": type_filed = request.args.get('type') request_fields = request.args.get('data') if not request_fields: request_fields = {} else: request_fields = move_space(json.loads(request_fields)) else: type_filed = request.json.get('type') data = request.json.get('data') if not data: request_fields = {} else: data = json.loads(data) request_fields = move_space(data) # 检测是否有多余参数 所有的字段加上 而额外包含的字段 if type_filed and type_filed not in self.push_strategy.keys(): raise RequestsError(code=1014010002, message=",无此推送类型") if set(request_fields) - set(self.include_fileds + list(push_convention_fileds.keys())): raise RequestsError(code=1014010003, message=",data中存在未知参数") # 检测参数数据类型 checkout_type(type_filed, request_fields) return super().dispatch_request(*args, **kwargs)
def post(self): merchant_code = request.json.get('merchant_code') if not merchant_code: raise RequestsError(code=1014010001, message=",新增数据时商户编号缺失") try: data = json.loads(request.json.get('data')) except: data = {} if not data: raise RequestsError(code=1014010001, message=",新增数据时缺少必需参数data或类型错误") data['operator_id'] = request.json.get('operator_id') data['operator'] = request.json.get('operator') data['merchant_code'] = merchant_code data = move_null(data) # 判断是否必需参数都存在 if set(get_required()) - set(data): raise RequestsError(code=1014010001, message=",新增数据时必需参数缺失") #判断新增数据是否重复 merchant_code+push_type+push_method 三者唯一 instance = self.model.query.filter( self.model.merchant_code == merchant_code, self.model.type == data.get('type'), self.model.push_method == data.get('push_method')).one_or_none() if instance: raise RequestsError(code=1014000000, message=",新增后唯一性数据重复") try: ins = self.model(**data) db.session.add(ins) db.session.commit() except: db.session.rollback() raise RequestsError(code=1014020001, message=",新增数据失败") return ins.to_pretty()
def dispatch_request(self, *args, **kwargs): if request.method not in self.allowed_method: raise RequestsError(code=1014000000, message=',请求方式错误') if request.method == 'GET': merchant_code = request.args.get("merchant_code") data = request.args.get('data') type = request.args.get('type') else: merchant_code = request.json.get("merchant_code") data = request.json.get('data') type = request.json.get('type') if merchant_code and not TbMerchant.query.filter( TbMerchant.code == merchant_code).one_or_none(): raise RequestsError(code=1014010005, message=",无此商户编号") if data: data = json.loads(data) type = data.get('type') if type and type not in push_conf.keys(): raise RequestsError(code=1014010005, message=",无此推送类型") #判断是否有此推送方式 if data.get('push_method') and data.get( 'push_method') not in self.push_methods: raise RequestsError(code=1014010005, message=",无此推送方式") #检测是否有多余的参数 if set(data) - set(get_required() + self.default_need_fields): raise RequestsError(code=1014010004, message=",有未知参数") check_type(data) return super().dispatch_request(*args, **kwargs)
def delete(self): _id = request.json.get('id') # 如果有id数值,直接删除此数据 if _id: instance = self.model.query.filter( self.model.id == _id).one_or_none() if instance: try: db.session.delete(instance) db.session.commit() except: db.session.rollback() return {} merchant_code = request.json.get('merchant_code') if not merchant_code: raise RequestsError(code=1014010001, message=",删除数据时id与商户编号至少需要一个") # 如果没有id 有merchant_code instances = self.model.query.filter( self.model.merchant_code == merchant_code).all() if instances: for instance in instances: try: db.session.delete(instance) db.session.commit() except: db.session.rollback() raise RequestsError(code=1014020001, message=",删除数据失败") return {}
def checkout_type(type_filed, request_fields): if type_filed and type( type_filed) != push_convention_fileds['type']['type']: raise RequestsError(code=1014010001, message=",type类型错误") if request_fields: for k, v in request_fields.items(): if type(v) != push_convention_fileds[k]['type']: raise RequestsError(code=1014010001, message=",data参数中类型错误")
def get(self): _id = request.args.get('id') operator = request.args.get('operator') operator_id = request.args.get('operator_id') if _id: instance = self.model.query.filter( self.model.id == _id).one_or_none() if not instance: raise RequestsError(code=1014010005, message=",查询数据时此id无对应数值") return instance.to_pretty() try: data = json.loads(request.args.get('data')) except: data = {} data['merchant_code'] = request.args.get('merchant_code') data['operator'] = operator data['operator_id'] = operator_id try: page = request.args.get('page') if page: page = int(page) else: page = 1 except: raise RequestsError(code=1014010001, message=",页数只能为整数") try: page_size = request.args.get("page_size") if page_size: page_size = int(page_size) else: page_size = self.default_page_size if page_size > self.max_page_size: page_size = self.max_page_size except: raise RequestsError(code=1014010001, message=",每页显示数只能为整数") # 每页显示数只能为整数 if data: queryset = get_pargrams(move_space(data), self.model) if not queryset: return { "total": 0, "pages": 0, "page": 0, "page_size": 0, "results": [], } else: queryset = self.model.query(self.model) if page_size == -1: page_size = queryset.count() pagination = queryset.paginate(page=page, per_page=page_size) return { "total": pagination.total, "pages": pagination.pages, "page": pagination.page, "page_size": pagination.per_page, "results": [obj.to_pretty() for obj in pagination.items], }
def get(self): _id = request.args.get('id') if _id: try: instance = self.model.objects.filter(id=_id).first() except: instance = None if not instance: raise RequestsError(code=1014010005, message="记录不存在") return instance.to_dict() try: page = request.args.get('page') if page: page = int(page) else: page = 1 except: raise RequestsError(code=1014010001, message=",页数只能为整数") try: page_size = request.args.get("page_size") if page_size: page_size = int(page_size) else: page_size = self.default_page_size if page_size > self.max_page_size: page_size = self.max_page_size except: raise RequestsError(code=1014010001, message=",每页显示数只能为整数") # 每页显示数只能为整数 datas = request.args.to_dict() datas = move_page_fields(datas, self.include_fields) if datas: datas = get_convert_type(move_null_value(move_space(datas))) try: queryset = self.model.objects.filter(**datas) except: raise RequestsError(code=1014000000, message=",参数数值类型错误") if not queryset: return { "total": 0, "pages": 0, "page": 0, "page_size": 0, "results": [], } else: queryset = self.model.objects if page_size == -1: page_size = queryset.count() pagination = queryset.paginate(page=page, per_page=page_size) return { "total": pagination.total, "pages": pagination.pages, "page": pagination.page, "page_size": pagination.per_page, "results": [obj.to_dict() for obj in pagination.items], }
def delete(self): _id = request.json.get('id') if not _id: raise RequestsError(code=1014010001, message=",必需参数id缺失") try: instance = self.model.objects.filter(id=_id).first() except: instance = None if not instance: raise RequestsError(code=1014010005, message=",id对应的数值不存在") instance.delete() return {}
def put(self): _id = request.json.get('id') if not _id: raise RequestsError(code=1014010001, message=",修改数据时需要必需参数id") instance = self.model.query.filter(self.model.id == _id).one_or_none() if not instance: raise RequestsError(code=1014010005, message=",修改数据时id对应数值不存在") operator = request.json.get('operator') operator_id = request.json.get('operator_id') if not all([operator, operator_id]): raise RequestsError(code=1014000000, message=",修改数据时无操作人信息") try: data = json.loads(request.json.get('data')) except: data = {} if not data: # 如果没有data数据 return instance.to_pretty() #如果有data数据 进行数据修改 data['operator_id'] = operator_id data['operator'] = operator data = move_null(data) type = data.get('type') push_method = data.get('push_method') status = data.get('status') if not type: type = instance.type if not push_method: push_method = instance.push_method if status is None: status = instance.status # 检测修改后的数据 是否与数据库中有重复 if instance.push_method != push_method or instance.type != type: ins = self.model.query.filter( self.model.merchant_code == instance.merchant_code, self.model.type == type, self.model.push_method == push_method).one_or_none() if ins: raise RequestsError(code=1014000000, message=",修改后唯一性数据重复") #修改数据 try: instance.update_time = utc_timestamp() instance.type = type instance.push_method = push_method instance.status = status instance.operator = operator instance.operator_id = operator_id db.session.commit() except: # 事务回滚 db.session.rollback() raise RequestsError(code=1014020001, message=",修改数据失败") return instance.to_pretty()
def parse_args(self, req=None, strict=False): """Parse all arguments from the provided request and return the results as a Namespace :param strict: if req includes args not in parser, throw 400 BadRequest exception """ if req is None: req = request namespace = self.namespace_class() # A record of arguments not yet parsed; as each is found # among self.args, it will be popped out req.unparsed_arguments = (dict(self.argument_class("").source(req)) if strict else {}) errors = {} for arg in self.args: value, found = arg.parse(req, self.bundle_errors) if isinstance(value, ValueError): errors.update(found) found = None if found or arg.store_missing: namespace[arg.dest or arg.name] = value if errors: raise RequestsError(self.code) if strict and req.unparsed_arguments: raise exceptions.BadRequest( "Unknown arguments: %s" % ", ".join(req.unparsed_arguments.keys())) return namespace
def merch_control_info(trx): """ 查询风险驾驶舱风险参数(只有授信才有) :param trx: 事务ID :return: 风险驾驶舱风险参数 dict """ try: connection = credit_center_db[ 'tb_credit_merchant'] # 风险参数所在mongo集合 raw_merch_dict = connection.find_one( { "trx": trx, "step": 1, "merch_control_info": { "$exists": True } }, { "merch_control_info": 1, "_id": 0 }) except Exception as e: raise RequestsError(code=1014020001, message=",查询风险驾驶舱风险参数失败") if not raw_merch_dict: return {} merch_control_info = raw_merch_dict.get("merch_control_info", "") return merch_control_info if merch_control_info else {}
def product_list_info(trx): """ 查询产品信息(只有授信才有) :param trx: 事务ID :param credit_db: 产品信息所在mongo数据库 :param product_col: 产品信息所在mongo集合 :return: 产品信息 list """ try: connection = credit_center_db['tb_credit_merchant'] raw_product_dict = connection.find_one( { "trx": trx, "step": 1, "product_list_info": { "$exists": True } }, { "product_list_info": 1, "_id": 0 }) except Exception as e: raise RequestsError(code=1014020001, message=",查询产品信息失败") if not raw_product_dict: return [] product_dict = raw_product_dict.get("product_list_info", "") if not product_dict: return [] product_list = product_dict.get("productlist", "") return product_list if product_list else []
def convert(self, value, op): # Don't cast None if value is None: if self.nullable: return None else: raise RequestsError(code=self.code) # and check if we're expecting a filestorage and haven't overridden `type` # (required because the below instantiation isn't valid for FileStorage) elif isinstance(value, FileStorage) and self.type == FileStorage: return value try: # 接口参数为list的情况, 例如['value1', 'value2'] if self.type.__name__ == "list": return value return self.type(value, self.name, op) except TypeError: try: if self.type is decimal.Decimal: return self.type(str(value), self.name) else: return self.type(value, self.name) except TypeError: return self.type(value)
def channel_info(trx): """ 查询渠道信息 :param trx: 事务ID :return:渠道信息 dict """ ret_dict = {} try: connection = credit_center_db[ 'tb_credit_merchant'] # 渠道信息所在mongo集合 raw_channel_dict = connection.find_one( { "trx": trx, "step": 1, "channel_info": { "$exists": True } }, { "channel_info": 1, "_id": 0 }) except Exception as e: raise RequestsError(code=1014020001, message=",查询渠道信息失败") if not raw_channel_dict: return {} ret_dict.update(raw_channel_dict.get("channel_info", "")) if raw_channel_dict else {} return ret_dict
def change_manual_info_list(trx): """ 查询人工审核数据 :param trx: 事务ID :return: 人工审核数据 """ ret_list = [] try: connection = credit_center_db[ 'tb_credit_results'] # 人工审核数据所在mongo集合 raw_manual_data = connection.find( { "trx": trx, "change_manual_info": { "$exists": True } }, { "change_manual_info": 1, "step": 1, "_id": 0 }).sort([("step", -1), ('update_time', -1)]) except Exception as e: raise RequestsError(code=1014020001, message=", 获取人工审核数据失败") for manual_data in raw_manual_data: try: manual_data_dict = manual_data.get("change_manual_info") del manual_data["change_manual_info"] except Exception as e: manual_data_dict = {} manual_data.update(manual_data_dict) ret_list.append(manual_data) return ret_list
def get(self): self.reqparse.add_argument("trx", type=str, required=True, nullable=False, code=1014010001, desc="事务ID") self.reqparse.add_argument("type", type=str, required=False, code=1014010001, desc="数据类型") rq_args = self.reqparse.parse_args(strict=True) trx = rq_args.get("trx", "") search_type = rq_args.get("type", "") search_list = self.verification_search_type(search_type) if not trx: raise RequestsError(code=1014010001, message=',事务ID不能为空') # 查询所有接口配置信息 self.interface_dict = self.get_interfaces() ret_data = dict() for tp in search_list: ret_data[tp] = eval('self.{0}'.format(tp))(trx) logger.info( "success queried credit detail information,query parameters are %s" % json.dumps(rq_args)) return ret_data
def validate_rule_conf(self, rule_conf): # rule_conf中必需字段 require_fields = check_fields(rule_detail_conf) # 请求中rule_conf字段 request_rule_conf_fields = rule_conf.keys() if set(request_rule_conf_fields) - set(require_fields): raise RequestsError(code=1014010003, message=",不允许创建额外字段") if set(require_fields) - set(request_rule_conf_fields): raise RequestsError(code=1014010001, message=',必需字段缺失') # 检测rule_conf字段的类型 if not check_fields_type(rule_conf, rule_detail_conf): raise RequestsError(code=1014010001, message=",规则参数类型错误") if not rule_conf["lend_range"]: raise RequestsError(code=1014000000, message=",放款区间不能为空") for rule_deg in rule_conf['degrees']: if rule_deg not in rule_detail_conf['degrees']['to'].keys(): raise RequestsError(code=1014010005, message=',学历对应数值不存在') ind_pos_all = IndustryPosition.objects.all() industry_position_code = dict() for ind_pos in ind_pos_all: industry_position_code.setdefault(ind_pos.industry_code, set()).add(ind_pos.position_code) for ind_code in rule_conf['selected_industries_and_professions']: if ind_code['industry_code'] not in industry_position_code.keys(): raise RequestsError(code=1014010005, message=',行业代码不存在') for prof in ind_code["professions"]: if prof["position_code"] not in industry_position_code[ ind_code["industry_code"]]: raise RequestsError(code=1014010005, message=',职位代码不存在')
def put(self): _id = request.json.get('id') if not _id: raise RequestsError(code=1014010001, message=",id参数缺失") try: instance = self.model.objects.filter(id=_id).first() except: instance = None if not instance: raise RequestsError(code=1014010005, message=",id对应数值不存在") if set(self.add_alter_have_fields) - set(request.json.keys()): raise RequestsError(code=1014010001, message=",必需字段缺失") operator = request.json.get('operator') operator_id = request.json.get('operator_id') datas = request.json.get('data') if not datas: return instance.to_pretty() datas = move_space(json.loads(datas)) if not datas: raise RequestsError(code=1014000000, message=",data参数无数据") if not datas.get('code'): raise RequestsError(code=1014000000, message=",code数值不能为空") datas['operator'] = operator datas['operator_id'] = operator_id instance["update_time"] = utc_timestamp() if set(datas.keys()) & set(self.undate_exclude_fields): raise RequestsError(code=1014010004, message=",存在不允许更新的参数") try: instance.update(**datas) instance.save() except: raise RequestsError(code=1014020001, message=",更新数据失败") instance = self.model.objects.filter(id=_id).first() return instance.to_pretty()
def dispatch_request(self, *args, **kwargs): if request.method not in self.allowed_request_methods: raise RequestsError(code=1014000000, message=',请求方式错误') if request.method == "GET": request_fields = request.args.to_dict() else: try: # 校验除get之外的请求方式是否有数据 request_fields = request.json except: raise RequestsError(code=1014010001, message=",必需参数缺失或类型错误") # 将参数字段去除空格 request_fields = move_space(request_fields) # 校验参数是否符合要求 if set(request_fields) - set( check_fields(risk_args_conf) + self.update_exclude_field + self.include_fields): raise RequestsError(code=1014010003, message=",未知参数存在") return super().dispatch_request(*args, **kwargs)
def check_fields_type(datas, risk_conf): if isinstance(datas, dict): if datas: for k, v in datas.items(): try: if type(v).__name__ != risk_conf[k]['type'].__name__: return False except: raise RequestsError(code=1014010004, message=",id参数非必需") return True
def delete(self): _id = request.json.get('id') if _id: try: # 防止传入的id值不符合mongo规范 instance = self.model.objects.filter(id=_id).first() except: instance = None if not instance: raise RequestsError(code=1014010005, message=",删除数据时id对应数值不存在") instance.delete() return {} type_field = request.json.get('type') if not type_field: raise RequestsError(code=1014010001, message=",删除数据时id与type必须存在一个") # 如果传递的参数是type则可能进行造成批量删除的情况 instances = self.model.objects.filter(push_type=type_field) for instance in instances: instance.delete() return {}
def post(self): datas = move_null_value(move_space(request.json)) if not check_fields_type(datas, risk_args_conf): raise RequestsError(code=1014010001, message=",参数类型错误") merchant_code = datas.get("merchant_code") production_code = datas.get('production_code') status = datas.get('status') if not all([merchant_code, production_code]): raise RequestsError(code=1014010001, message=',银行或产品编号缺失') if not TbMerchant.query.filter_by(code=merchant_code).first(): raise RequestsError(code=1014010005, message=',商户编号不存在') if not TbProduction.query.filter_by( code=production_code, merchant_code=merchant_code).first(): raise RequestsError(code=1014010005, message=',产品编号不存在') if status: instance = self.model.objects.filter( merchant_code=merchant_code, production_code=production_code, status=True).first() if instance: raise RequestsError(code=1014000000, message=',现有规则已存在') rule_conf = datas.get('rule_conf') self.validate_rule_conf(rule_conf) try: instance = self.model(**datas) except: raise RequestsError(code=1014020001, message=",数据保存失败") instance.rule_id = int( str(int(time.time())) + str(random.randint(0, 9))) instance.save() return instance.to_dict()
def put(self): _id = request.json.pop('id') if not _id: raise RequestsError(code=1014010001, message=',缺少必需字段id') try: instance = self.model.objects.filter(id=_id).first() except: instance = None if not instance: raise RequestsError(code=1014010005, message=",无此项记录") request_fields = request.json if set(request_fields) & set(self.update_exclude_field): raise RequestsError(code=1014010004, message=",有不允许更新字段") datas = move_null_value(move_space(request_fields)) if not check_fields_type(datas, risk_args_conf): raise RequestsError(code=1014010001, message=",参数类型错误") merchant_code = datas.get("merchant_code") production_code = datas.get('production_code') status = datas.get('status') if status: instance = self.model.objects.filter( merchant_code=merchant_code, production_code=production_code, status=True).first() if instance: raise RequestsError(code=1014000000, message=',现有规则已存在') rule_conf = datas.get('rule_conf') self.validate_rule_conf(rule_conf) try: instance.update(**datas) except: raise RequestsError(code=1014020001, message=",数据更新失败") instance.save() instance = self.model.objects.filter(id=_id).first() return instance.to_dict()
def post(self): type_con = request.json.get('type') must_have_fields = self.type_conf[type_con]["to_fields"] if set(self.add_alter_have_fields) - set(request.json.keys()): raise RequestsError(code=1014010001, message=",必需字段缺失") operator = request.json.get('operator') operator_id = request.json.get('operator_id') datas = request.json.get('data') if not datas: raise RequestsError(code=1014010001, message=",新增数据无效") request_fields = move_space(json.loads(request.json.get('data'))) if not request_fields: raise RequestsError(code=1014010001, message=",新增数据无效") request_fields['operator'] = operator request_fields['operator_id'] = operator_id if not check_need_fields(request_fields, must_have_fields): raise RequestsError(code=1014010001, message=",必需参数缺失") if not request_fields.get('code'): raise RequestsError(code=1014000000, message=",code数值不能为空") try: instance = self.model(**request_fields) instance.save() except: raise RequestsError(code=1014020001, message=",该记录已存在") return instance.to_pretty()
def get_interface_mysql(query_dict): """ 在数据库中获取数据 :param query_dict: 查询条件 :return: 查询到的数据字典组成的列表:[{}] """ try: all_data = TbMerchantCredit.query.filter_by(**query_dict) except Exception as e: raise RequestsError(code=1014020001) # 数据库操作失败 if not all_data: return [] all_data_list = [data.to_json() for data in all_data] return all_data_list
def post(self): type_field = request.json.get('type') if not type_field: raise RequestsError(code=1014010001, message=",新增数据时type数值缺失") try: data = json.loads(request.json.get('data')) except: raise RequestsError(code=1014010001, message=',必需参数data缺失或类型错误') operator = request.json.get('operator') operator_id = request.json.get('operator_id') if not data: raise RequestsError(code=1014010001, message=",新增数据data数值缺失") data['push_type'] = type_field data['operator'] = operator data['operator_id'] = operator_id # 去除空格 并 去除值为None的数据 data = move_null_val(move_space(data)) # 检测是否满足必需参数条件 if set(get_require_fileds()) - set(data): raise RequestsError(code=1014010001, message=",新增数据时必需参数缺失") sub_type = data.get('sub_type') if sub_type not in self.push_strategy[type_field].keys(): raise RequestsError(code=1014010002, message=',无此推送子类型') code = data.get('code') # 如果code为'' 并且对应的类型下的子类型下的code可以为空, if not code: if self.push_strategy[type_field][sub_type]['code']['nullable']: data['code'] = self.push_strategy[type_field][sub_type][ 'code']['default'] else: raise RequestsError(code=1014010002, message=",新增数据时此类型中的子类型 code不能为空") instance = self.model.objects.filter(push_type=type_field, sub_type=sub_type, code=data.get('code')).first() if instance: raise RequestsError(code=1014000000, message=",新增时唯一性数据重复") try: instance = self.model(**data) instance.save() except: raise RequestsError(code=1014020001, message=",新增数据失败") # 返回新增的数据 return instance.to_pretty()
def operator_log(operator_id, log_data): """ 记录用户敏感操作 :param operator_id: 用户ID :param log_data: 记录信息 :return: None """ operation = TbOperation(operator_code=operator_id, content=log_data, type="EDIT", category="MARCHANT_CREDIT") try: db.session.add(operation) db.session.commit() except Exception as e: db.session.rollback() raise RequestsError(code=1014020001) # 数据库操作失败
def handle_validation_error(self, error, bundle_errors): """Called when an error is raised while parsing. Aborts the request with a 400 status and an error message :param error: the error that was raised :param bundle_errors: do not abort when first error occurs, return a dict with the name of the argument and the error message to be bundled """ error_str = six.text_type(error) error_msg = self.help.format( error_msg=error_str) if self.help else error_str msg = {self.name: "{0}".format(error_msg)} if current_app.config.get("BUNDLE_ERRORS", False) or bundle_errors: return error, msg raise RequestsError(code=self.code)
def operator_log(operator_id, log_data, method): """ 记录用户敏感操作 :param method: 方法 :param operator_id: 用户ID :param log_data: 记录信息 :return: None """ operation = TbOperation(operator_code=operator_id, content=log_data, type=str(method), category="INTERFACE_CONF") try: db.session.add(operation) db.session.commit() except Exception as e: db.session.rollback() raise RequestsError(code=1014020001) # 数据库操作失败
def to_post_put(model, data_list): """ 在模型中插入/更新数据 :param model: 模型,对应model需要定义__init__方法,联合主键 :param data_list: 多个更新数据字典组成的列表:[{},{}] :return: True|Error """ merchant_credit_list = [] for post_data in data_list: merchant_credit = db.session.merge(model(**post_data)) merchant_credit_list.append(merchant_credit) try: db.session.add_all(merchant_credit_list) db.session.commit() return True except Exception as e: db.session.rollback() raise RequestsError(code=1014020001, message="post") # 数据库操作失败