update 报告相关接口

This commit is contained in:
P3ngSaM 2022-06-16 16:19:10 +08:00
parent a5fc76d081
commit d61793650e
28 changed files with 718 additions and 26 deletions

View File

@ -9,6 +9,8 @@ from urllib import parse
from bson import ObjectId
from gridfs import GridFS
from Modules.Reports.ReportPathImpl import get_gen_report_path
class MongoHelper:
@ -212,6 +214,26 @@ class MongoHelper:
collection.delete_one(param3)
return True
def upsert_file(self, param1, param2, param3):
"""
根据名称保存该企业报告
param1: str 数据库
param2: str 数据集
param3: str 文件名称
Returns:
pdf_id: str 文件id
"""
try:
path = get_gen_report_path(name=param3)
database = param1
collection = param2
fs = GridFS(self.client[database], collection)
content = open(path, 'rb').read()
pdf_id = fs.put(content, content_type='application/pdf', filename=param3)
return str(pdf_id)
except Exception:
return False
def find_file(self, param1, param2, param3):
"""
读取一个文件

View File

@ -8,7 +8,8 @@ import requests
import xlrd
import cpca
from DBHelper.MongoHelperInstance import DB_GUA, DB_TYC
from Modules.Company.CompanyObject import BasicBusinessInfo, FinancialData, GuaranteeInfo, BankCredit
from Modules.Company.CompanyObject import BasicBusinessInfo, FinancialData, GuaranteeInfo, BankCredit, \
CompanyOverviewInfo
from Modules.Company.CompanyUtils import CompanyUtils, ExcelSheetParser, ExcelParserUtil
from Modules.Company.static.province_map import p_map
from Modules.ETL.GuaranteeDataJob import RiskInfoDataJob, BusinessInfoDataJob
@ -26,6 +27,7 @@ class BasicBusinessInfoImpl(object):
work_book = xlrd.open_workbook(file_contents=file.read())
basic_business_info = BasicBusinessInfo()
company_overview = CompanyOverviewInfo()
financial_data_list = list()
guarantee_info_list = list()
bank_credit_info_list = list()
@ -185,12 +187,13 @@ class BasicBusinessInfoImpl(object):
basic_business_info.shareholder_information = list()
basic_business_info.executive_information = list()
# 工商信息
company_info['企业简称'] = basic_info['基本信息']['alias']
company_info['企业类型'] = basic_info['基本信息']['companyOrgType']
company_info['统一社会信用代码'] = basic_info['基本信息']['creditCode']
company_info['组织代码'] = basic_info['基本信息']['orgNumber']
tuptime_newest = time.localtime(basic_info['基本信息']['estiblishTime'] / 1000)
company_info['成立日期'] = time.strftime("%Y-%m-%d", tuptime_newest)
company_info['成立日期'] = time.strftime("%Y%m月%d", tuptime_newest)
company_info['经营范围'] = basic_info['基本信息']['businessScope']
company_info['所在省份'] = [v for k, v in p_map.items() if k == basic_info['基本信息']['base']][0]
company_info['所在城市'] = basic_info['基本信息']['city']
@ -201,6 +204,7 @@ class BasicBusinessInfoImpl(object):
company_info['从业人员总数'] = sum(employee_education.values())
company_info['参保人数'] = int(company_info['参保人数'])
# 企业股东
for item in tyc_shareholders:
shareholder = SpecObject.set_specify_instance(
instance=BasicBusinessInfo.ShareholderInformation,
@ -208,6 +212,7 @@ class BasicBusinessInfoImpl(object):
)
basic_business_info.shareholder_information.append(shareholder)
# 主要人员
for item in tyc_staff:
executive = SpecObject.set_specify_instance(
instance=BasicBusinessInfo.ExecutiveInformation,
@ -215,6 +220,17 @@ class BasicBusinessInfoImpl(object):
)
basic_business_info.executive_information.append(executive)
# 企业概览
tags = basic_info['基本信息']['tags']
company_overview.company_name = company_info['企业名称']
company_overview.cid = new_cid
company_overview.credit_level = None
company_overview.rating_date = None
company_overview.province = company_info['所在省份']
company_overview.city = company_info['所在城市']
company_overview.label = list(tags.split(';'))
company_overview.update_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())
basic_business_info.employee_education = SpecObject.set_specify_instance(
instance=BasicBusinessInfo.EmployeeEducation,
data=employee_education
@ -565,6 +581,12 @@ class BasicBusinessInfoImpl(object):
basic_business_info.fields_toggle()
)
DB_GUA.insert_single_data(
"企业数据",
"公司概览",
company_overview.fields_toggle()
)
if financial_data_list:
DB_GUA.insert_many_data(
"企业数据",
@ -594,3 +616,4 @@ class BasicBusinessInfoImpl(object):
business_job.create()
guarantee_business_info()

View File

@ -224,13 +224,13 @@ class CompanyManageImpl(object):
page_size = kwargs["page_size"]
total = DB_GUA.find_all_data_with_count(
"企业数据",
"担保-客户信息",
"担保数据-客户信息",
{"企业ID": cid}
)
records = DB_GUA.find_data_by_page_with_sort(
"企业数据",
"担保-客户信息",
"担保数据-客户信息",
{"企业ID": cid},
["企业ID", "客户名称", "担保类型", "在保余额", "融资担保责任余额", "担保起始日", "担保截止日"],
{"担保起始日": -1},
@ -253,13 +253,13 @@ class CompanyManageImpl(object):
page_size = kwargs["page_size"]
total = DB_GUA.find_all_data_with_count(
"企业数据",
"担保-区域分布",
"担保数据-区域分布",
{"企业ID": cid}
)
records = DB_GUA.find_data_by_page_with_sort(
"企业数据",
"担保-区域分布",
"担保数据-区域分布",
{"企业ID": cid},
["企业ID", "地区", "报告期", "年末在保余额", "年末在保责任余额", "当年新增在保余额", "当年新增在保责任余额"],
{"报告期": -1},
@ -282,13 +282,13 @@ class CompanyManageImpl(object):
page_size = kwargs["page_size"]
total = DB_GUA.find_all_data_with_count(
"企业数据",
"担保-行业分布",
"担保数据-行业分布",
{"企业ID": cid}
)
records = DB_GUA.find_data_by_page_with_sort(
"企业数据",
"担保-行业分布",
"担保数据-行业分布",
{"企业ID": cid},
["企业ID", "报告期", "所属行业", "年末在保余额", "年末在保责任余额", "当年新增在保余额", "当年新增在保责任余额"],
{"报告期": -1},
@ -311,13 +311,13 @@ class CompanyManageImpl(object):
page_size = kwargs["page_size"]
total = DB_GUA.find_all_data_with_count(
"企业数据",
"担保-担保金额分布",
"担保数据-担保金额分布",
{"企业ID": cid}
)
records = DB_GUA.find_data_by_page_with_sort(
"企业数据",
"担保-担保金额分布",
"担保数据-担保金额分布",
{"企业ID": cid},
["企业ID", "报告期", "100万以下含100万", "500万以下含500万", "500-1000万含1000万", "1000-3000万含3000万", "3000-5000万含5000万"
"3000-5000万含5000万", "5000-8000万含8000万", "8000-10000万含10000万", "10000万以上", "合计"],

View File

@ -115,18 +115,20 @@ class CompanyOverviewInfo(SpecObject):
cid = ValidateAttr(field="cid", type=str)
company_name = ValidateAttr(field="company_name", type=str)
credit_level = ValidateAttr(field="credit_level", type=str)
rating_date = ValidateAttr(field="rating_date", func=Validate.date_format)
province_city = ValidateAttr(field="province_city", type=str)
label = ValidateAttr(field="label", type=str)
credit_level = ValidateAttr(field="credit_level", type=str, default=None)
rating_date = ValidateAttr(field="rating_date", default=None)
province = ValidateAttr(field="province", type=str)
city = ValidateAttr(field="city", type=str)
label = ValidateAttr(field="label", type=list)
update_time = ValidateAttr(field="update_time", func=Validate.date_format)
fields_map = {
"cid": "企业ID",
"company_name": "企业名称",
"credit_level": "信用",
"credit_level": "信用",
"rating_date": "评级日期",
"province_city": "所属省市",
"province": "所在省份",
"city": "所在城市",
"label": "公司标签",
"update_time": "更新时间"
}

View File

@ -445,25 +445,25 @@ class ProcessBusinessInfo(DataProcess):
DB_GUA.insert_many_data(
'企业数据',
'担保-客户信息',
'担保数据-客户信息',
[item for item in customer_data]
)
DB_GUA.insert_many_data(
'企业数据',
'担保-区域分布',
'担保数据-区域分布',
[item for item in regional_data]
)
DB_GUA.insert_many_data(
'企业数据',
'担保-行业分布',
'担保数据-行业分布',
[item for item in industry_data]
)
DB_GUA.insert_many_data(
'企业数据',
'担保-担保金额分布',
'担保数据-担保金额分布',
[item for item in amount_data]
)

View File

@ -0,0 +1,33 @@
from flask import Blueprint, request
from Modules.AdminUser.UserAuthUtils import verify_token
from Modules.File.FileImpl import FileImpl
from Utils.ErrorUtil import AttrCheckError, APIReturnError
from Utils.RouteUtil import RouteParamsCheck
file_route = Blueprint('file', __name__)
@file_route.route('/credit_report', methods=['GET'])
@verify_token
def get_rating_report_route(**kwargs):
"""获取综信报告"""
try:
RouteParamsCheck(req=request.args, params=['file_id']).required()
file_id = request.args.get('file_id')
impl = FileImpl()
impl.file_bucket = '报告PDF'
impl.file_id = file_id
impl.get_pdf()
return impl.dict_to_return()
except APIReturnError as e:
return {"info": e.__str__()}, e.status_code
@file_route.route('/create_company', methods=['GET'])
@verify_token
def get_template_route(**kwargs):
"""获取综信报告"""
impl = FileImpl()
impl.get_company_excel()
return impl.dict_to_return()

55
Modules/File/FileImpl.py Normal file
View File

@ -0,0 +1,55 @@
from flask import Response
from DBHelper.MongoHelperInstance import DB_GUA
from Utils.ObjUtil import SpecObject
from Utils.ValidateUtil import ValidateAttr
class TFSEFile(SpecObject):
"""文件类"""
file_id = ValidateAttr(field='file_id', type=str)
file_bucket = ValidateAttr(field='file_bucket', in_list=["报告PDF"])
file_body = ValidateAttr(field='file_body', type=Response, default=None)
fields_map = {
"file_id": "文件ID",
"file_bucket": "文件桶",
"file_body": "文件体"
}
class FileImpl(TFSEFile):
"""文件类实现"""
def dict_to_return(self, **kwargs):
return self.file_body
def get_image(self):
""""""
def get_pdf(self):
file_stream = DB_GUA.find_file(
"评级数据",
self.file_bucket,
self.file_id
)
if file_stream:
self.file_body = Response(file_stream, content_type='application/pdf')
else:
self.file_body = None
def get_company_excel(self):
file_stream = DB_GUA.find_file(
"企业数据",
'填报模板',
'62aae021a35c00006e0031a2'
)
if file_stream:
self.file_body = Response(file_stream, content_type='application/pdf')
else:
self.file_body = None

0
Modules/File/__init__.py Normal file
View File

View File

@ -1,9 +1,14 @@
import os
import time
from DBHelper.MongoHelperInstance import DB_GUA
from Modules.Models.FinancialIndicatorsModel import FinancialIndicatorsModel
from Modules.Models.ScoreAndRankModel import CreditIndexScore, ScoreAndRankModel, refs
from Modules.Rating.RatingObjects import RatingRecord
from Modules.Rating.RatingUtils import RatingUtils
from Modules.Reports.ReportDataModel import ReportDataModel
from Modules.Reports.ReportPathImpl import get_gen_report_path
from Modules.Reports.ReportPdfImpl import ReportGenerator
from Utils.CommonUtil import sub_dict
from Utils.ErrorUtil import APIReturnError
from Utils.ScoreUtils import ScoreUtils
@ -422,6 +427,55 @@ class RatingImpl(object):
return result
@staticmethod
def edit_rank_report(**kwargs):
rid = kwargs['rid']
content = kwargs['content']
DB_GUA.update_single_data(
'评级数据',
'报告数据',
{'评级ID': rid},
{'报告内容': content, '生成日期': time.strftime('%Y-%m-%d', time.localtime())}
)
@staticmethod
def report_file(**kwargs):
rid = kwargs["rid"]
record_item = DB_GUA.find_single_data(
"评级数据",
"报告数据",
{"评级ID": rid},
["企业名称", "报告内容", "报告标题"]
)
if not record_item:
raise APIReturnError("该rid不存在", 202)
record_item['生成日期'] = time.strftime('%Y-%m-%d', time.localtime())
report_file_name = '{}.pdf'.format(record_item['报告标题'])
pdf_report = ReportGenerator(name=report_file_name, text_model=record_item)
pdf_report.gen_report()
file_id = DB_GUA.upsert_file(
'评级数据',
'报告PDF',
report_file_name
)
DB_GUA.upsert_single_data(
"评级数据",
"评级记录",
{"评级ID": rid},
{"评级报告": file_id}
)
report_path = get_gen_report_path(name=report_file_name)
os.remove(report_path)
# 保存PDF报告成功返回FileID;保存PDF报告文件失败返回False
return file_id if file_id else False
@staticmethod
def submit(**kwargs):
""""""

View File

@ -92,14 +92,27 @@ def score_and_rank_route(**kwargs):
return {"info": e.__str__()}, e.status_code
@rating_route.route('/report_data', methods=['GET'])
@rating_route.route('/report_data', methods=['GET', 'POST'])
@verify_token
def report_data_route(**kwargs):
"""报告数据"""
rid = request.args['rid']
impl = RatingImpl()
result = impl.rank_report(rid=rid)
return {"info": "报告数据", "result": result}
try:
if request.method == 'GET':
rid = request.args['rid']
impl = RatingImpl()
result = impl.rank_report(rid=rid)
return {"info": "报告数据", "result": result}
if request.method == 'POST':
rid = request.json['rid']
content = request.json['content']
impl = RatingImpl()
impl.edit_rank_report(rid=rid, content=content)
return {"info": "编辑成功"}, 200
except APIReturnError as e:
return {"info": e.__str__()}, e.status_code
@rating_route.route('/rank_report', methods=['GET'])
@ -107,6 +120,16 @@ def report_data_route(**kwargs):
def rank_report_route(**kwargs):
"""评级报告"""
try:
rid = request.args['rid']
impl = RatingImpl()
result = impl.report_file(rid=rid)
info = '生成报告成功' if result else '生成报告失败'
res = {"FileID": result} if result else {"FileID": None}
return {"info": info, "result": res}
except APIReturnError as e:
return {"info": e.__str__()}, e.status_code
@rating_route.route('/submit', methods=['GET'])
@verify_token

View File

@ -0,0 +1,202 @@
from reportlab.lib.colors import HexColor
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_RIGHT
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.lib.styles import ParagraphStyle as PS, ParagraphStyle
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.platypus import TableStyle, Paragraph
from reportlab.lib import colors
import pandas as pd
import numpy as np
# rgb
from Modules.Reports.ReportPathImpl import get_font_path
darkGolden = '#C8A063'
lightGrey = '#F4F2EF'
darkGrey = '#A1A8AB'
Seashell4 = '#8B8682'
# font
pdfmetrics.registerFont(TTFont('pingbold', get_font_path(font='PingBold.ttf')))
pdfmetrics.registerFont(TTFont('SimHei', get_font_path(font='simhei.ttf')))
pdfmetrics.registerFont(TTFont('SIMSUN', get_font_path(font='SIMSUN.ttf')))
pdfmetrics.registerFont(TTFont('SourceHanSerifCN-Bold', get_font_path(font='SourceHanSerifCN-Bold.ttf')))
# toc
toc_style_1 = PS(name='TOCHeading1', fontName='pingbold', fontSize=16, leftIndent=20, firstLineIndent=-20,
spaceBefore=10, leading=16)
toc_style_2 = PS(name='TOCHeading2', fontName='pingbold', fontSize=12, leftIndent=40, firstLineIndent=-20,
spaceBefore=5, leading=12)
# table of content
table_content_style = PS(name="table_content_style", fontName="pingbold", fontSize=18, leading=40, alignment=TA_CENTER)
# cover
cover_space = PS(name='cover_space', fontSize=0, leading=75, alignment=TA_CENTER)
cover_company_style = PS(name="cover_company_style", fontName="pingbold", fontSize=30, leading=60, alignment=TA_CENTER)
cover_report_style = PS(name="cover_report_style", fontName="pingbold", fontSize=18, leading=400, alignment=TA_CENTER)
cover_fecr_style = PS(name="cover_fecr_style", fontName="pingbold", fontSize=18, leading=20, alignment=TA_CENTER)
cover_time_style = PS(name="cover_time_style", fontName="pingbold", fontSize=16, leading=40, alignment=TA_CENTER,
spaceBefore=20)
# chapter & section
chapter_style = PS(name="chapter_style", fontName="pingbold", fontSize=18, leading=40, alignment=TA_LEFT, spaceBefore=6)
section_style = PS(name="section_style", fontName="pingbold", fontSize=12, leading=30, alignment=TA_LEFT, spaceBefore=6,
textColor=HexColor(darkGolden))
# table
table_name = PS(name="table_name", fontName="pingbold", fontSize=8, leading=16, alignment=TA_CENTER, spaceBefore=2,
textColor=HexColor(darkGrey))
table_unit = PS(name="table_unit", fontName="SimHei", fontSize=6, leading=8, alignment=TA_RIGHT, spaceBefore=2)
table_mark = PS(name="table_mark", fontName="SimHei", fontSize=6, leading=16, alignment=TA_LEFT, spaceBefore=2)
table_style = getSampleStyleSheet()
table_style.add(
ParagraphStyle(fontName='SimHei', name='Song', leading=12, fontSize=8, spaceBefore=2, alignment=TA_CENTER))
table_style.add(
ParagraphStyle(fontName='SimHei', name='Long', leading=12, fontSize=8, spaceBefore=2, alignment=TA_LEFT))
table_style.add(
ParagraphStyle(fontName='SimHei', name='Longs', leading=9, fontSize=6, spaceBefore=2, alignment=TA_LEFT))
table_style.add(
ParagraphStyle(fontName='SimHei', name='Songs', leading=9, fontSize=6, spaceBefore=2, alignment=TA_CENTER))
table_style.add(
ParagraphStyle(fontName='SimHei', name='Song_small', leading=7, fontSize=5, spaceBefore=2, alignment=TA_CENTER))
# para
para_style_single = PS(name="para_style_single", fontName="SimHei", fontSize=8, leading=18, alignment=TA_LEFT,
spaceBefore=6)
para_style_special = PS(name="para_style_single", fontName="SimHei", fontSize=8, leading=18, alignment=TA_LEFT,
spaceBefore=6, textColor='red')
para_style_normal = PS(name="para_style_normal", fontName="SimHei", fontSize=8, leading=18, alignment=TA_LEFT,
spaceBefore=6, firstLineIndent=16)
para_style_esg = PS(name="para_style_esg", fontName="SimHei", fontSize=10, leading=18, alignment=TA_LEFT,
spaceBefore=6)
para_style_bold = PS(name="para_style_bold", fontName="pingbold", fontSize=10, leading=18, alignment=TA_LEFT,
spaceBefore=6)
para_bold_style = PS(name="para_style", fontName="pingbold", fontSize=9, leading=18, alignment=TA_LEFT, spaceBefore=6)
# table
def adjust_table_widths(list_):
"""
计算表格每列宽度
Parameters:
list_: list 表格数据
Returns:
result: list 表格宽度列表
"""
# 表格默认宽度
total_width = 410
df = pd.DataFrame()
for list__ in list_:
df = df.append(dict(zip(range(len(list__)), list__)), ignore_index=True)
# 将列表中的数据替换成数据的长度并将0置为NaN
df = df.apply(lambda x: x.str.len())
df = df.replace(0, np.NaN)
# 计算每列数据长度平均值占总数的多少,并转为列表
width_rate = (df.mean() / df.mean().sum()).values.tolist()
# 列数
cols_num = len(width_rate)
# 判断首列是否小于默认宽度
if width_rate[0] < 0.33:
# 小于默认宽度,用当前数据重新计算各列宽度
widths = [width_rate[0] * total_width] + [((1 - width_rate[0]) / (cols_num - 1)) * total_width] * (cols_num - 1)
else:
# 大于默认宽度,则继续使用默认宽度继续各列宽度
widths = [0.33 * total_width] + [(0.67 / (cols_num - 1)) * total_width] * (cols_num - 1)
return widths
def adjust_table_data(list_):
"""
调整表格数据样式
Parameters:
list_: list 表格数据
Returns:
result: list 处理好的表格数据
"""
for item_ in list_:
if len(item_) > 6:
for index in range(len(item_)):
if item_[index] != '报告期' and index == 0:
item_[index] = Paragraph(item_[index], table_style['Longs'])
else:
if index == 5 and len(item_[index]) > 10:
item_[index] = Paragraph(item_[index], table_style['Song_small'])
else:
item_[index] = Paragraph(item_[index], table_style['Songs'])
else:
for index in range(len(item_)):
if item_[index] != '报告期' and index == 0:
item_[index] = Paragraph(item_[index], table_style['Long'])
else:
item_[index] = Paragraph(item_[index], table_style['Song'])
return list_
def adjust_table_style(list_):
return TableStyle([
# 边框
('INNERGRID', (0, 0), (-1, -1), 0.25, colors.grey),
('BOX', (0, 0), (-1, -1), 1, colors.black),
# 文字
('FONTNAME', (0, 0), (-1, -1), 'SimHei'),
('FONTSIZE', (0, 0), (-1, -1), 8),
('TEXTCOLOR', (0, 0), (-1, 0), colors.white),
# 排版
('ALIGN', (1, 0), (-1, -1), 'CENTER'),
# 背景
# ('BACKGROUND', (0, 0), (0, -1), HexColor(lightGrey)),
('BACKGROUND', (0, 0), (-1, 0), HexColor(darkGolden)),
])
def adjust_line_width(str_, font_size):
mark_length = 400
trans_length = mark_length / font_size - 1
if len(str_) < trans_length:
return str_
n = 0
s1 = ''
s2 = ''
for i in range(len(str_)):
if n == 0 and str_[i] in ['', '', '', '']:
continue
if u'\u4e00' <= str_[i] <= u'\u9fa5':
s2 += str_[i]
n = n + 1
elif str_[i] in ['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '-', '', '', '',
'', '', '', '', '', '', '', '', '_', '', '', '', '', '', '', '', '', '', '',
'', '', '', '', '', '', '', '', '', '', '', '', '']:
s2 += str_[i]
n = n + 1
else:
s2 += str_[i]
n = n + 0.5
if (n > trans_length) and (i != len(str_) - 1):
if str_[i + 1] in ['', '', '', '']:
s2 += str_[i + 1]
s2 += '<br/>'
n = 0
s1 += s2
s2 = ''
else:
s2 += '<br/>'
n = 0
s1 += s2
s2 = ''
elif i == len(str_) - 1:
s1 += s2
return s1

View File

@ -20,7 +20,7 @@ class ReportDataModel(object):
srds = {}
# 报告模板
tempo = get_yaml(file_rel_path='/Reports/static/report_template.yaml')
tempo = get_yaml(file_rel_path='/Reports/static/template/report_template.yaml')
def mock_report_data(self, **kwargs):

View File

@ -0,0 +1,38 @@
import os
APP_NAME = 'guarantee-admin-api-v0.2'
def get_project_abs_path():
file_abs_path = os.path.abspath(os.path.dirname(__file__))
project_abs_path = file_abs_path[:file_abs_path.find(APP_NAME)+len(APP_NAME)]
return project_abs_path
def get_font_path(**kwargs):
font = kwargs['font']
project_abs_path = get_project_abs_path()
font_path = os.path.abspath(project_abs_path + '/Modules/Reports/static/font/' + font)
return font_path
def gen_pdf_path(**kwargs):
name = kwargs['name']
project_abs_path = get_project_abs_path()
pdf_relative_path = '/Modules/Reports/static/file/{}'.format(name)
pdf_abs_path = os.path.abspath(project_abs_path + pdf_relative_path)
return pdf_abs_path
def get_pic_path(**kwargs):
pic_name = kwargs['pic_name']
project_abs_path = get_project_abs_path()
pic_abs_path = os.path.abspath(project_abs_path + '/Modules/Reports/static/img/' + pic_name)
return pic_abs_path
def get_gen_report_path(**kwargs):
name = kwargs['name']
project_abs_path = get_project_abs_path()
file_name = '/Modules/Reports/static/file/' + '{}'.format(name)
pdf_path = os.path.abspath(project_abs_path + file_name)
return pdf_path

View File

@ -0,0 +1,150 @@
from hashlib import sha1
from reportlab.lib.units import cm, inch
from reportlab.platypus import Paragraph, Image, PageBreak, Frame, Table
from reportlab.platypus.doctemplate import PageTemplate, BaseDocTemplate
from reportlab.platypus.tableofcontents import TableOfContents
from reportlab.pdfgen import canvas
from Modules.Reports.ReportPathImpl import gen_pdf_path, get_pic_path
from Modules.Reports.PdfStyleIpml import *
class HeaderAndFooterCanvas(canvas.Canvas):
def __init__(self, *args, **kwargs):
self.offeset = 3
canvas.Canvas.__init__(self, *args, **kwargs)
self._saved_page_states = []
def showPage(self):
self._saved_page_states.append(dict(self.__dict__))
self._startPage()
def draw_header_and_footer(self, page_count):
self.setFont("Helvetica", 7)
if self._pageNumber > self.offeset:
self.setFont('pingbold', 8)
self.setFillColor(HexColor(Seashell4))
self.drawString(74, 805, "远东资信评估有限公司")
self.drawString(74, 40, "%d / %d" % (self._pageNumber - self.offeset, page_count - self.offeset))
self.setStrokeColor(darkGolden)
self.setLineWidth(2.5)
self.line(74, 820, 6.8 * inch, 820)
self.setLineWidth(1)
self.line(74, 50, 6.8 * inch, 50)
def save(self):
num_pages = len(self._saved_page_states)
for state in self._saved_page_states:
self.__dict__.update(state)
self.draw_header_and_footer(num_pages)
canvas.Canvas.showPage(self)
canvas.Canvas.save(self)
class MyDocTemplate(BaseDocTemplate):
def __init__(self, filename, **kw):
self.allowSplitting = 1
BaseDocTemplate.__init__(self, filename, **kw)
template = PageTemplate('normal', [Frame(2.5 * cm, 2.5 * cm, 15 * cm, 25 * cm, id='F1')])
self.addPageTemplates(template)
self.offeset = kw['offeset']
def afterFlowable(self, flowable):
if flowable.__class__.__name__ == 'Paragraph':
text = flowable.getPlainText()
style = flowable.style.name
if style == 'chapter_style':
level = 1
elif style == 'section_style':
level = 2
else:
return
e = (level, text, self.page - self.offeset)
self.notify('TOCEntry', e)
class ReportGenerator:
def __init__(self, **kwargs):
# 文本数据
self.text_model = kwargs['text_model']
self.doc = MyDocTemplate(gen_pdf_path(name=kwargs['name']), offeset=3)
# 内容框
self.story = list()
# 生成报告
def gen_report(self):
self.gen_cover()
self.gen_menu()
self.gen_main_part()
self.doc.multiBuild(self.story, canvasmaker=HeaderAndFooterCanvas)
# 设置章节、小节标题
def set_head(self, text, sty):
bn = sha1("Vintage".encode('utf-8')).hexdigest()
h = Paragraph(text + '<a name="%s"/>' % bn, sty)
h._bookmarkName = bn
self.story.append(h)
# 目录
def gen_menu(self):
toc = TableOfContents()
toc.levelStyles = [toc_style_1, toc_style_2]
self.story.append(Paragraph('目录', table_content_style))
self.story.append(toc)
self.story.append(PageBreak())
# 封面
def gen_cover(self):
data = self.text_model
self.story.append(Paragraph('.', cover_space))
self.story.append(Paragraph(data['企业名称'], cover_company_style))
self.story.append(Paragraph('综合信用等级评价报告', cover_report_style))
self.story.append(Image(get_pic_path(pic_name='ydzx.png'), width=202, height=37))
self.story.append(Paragraph(data['生成日期'], cover_time_style))
self.story.append(PageBreak())
# 正文
def gen_main_part(self):
data = self.text_model['报告内容']
for chapter in data:
self.set_head(chapter['章节'], chapter_style)
for section in chapter['章节内容']:
self.set_head(section['小节'], section_style)
for part in section['小节内容']:
# 段落
if list(part.keys())[0] == '段落':
self.story.append(Paragraph(adjust_line_width(part['段落'], 8), para_style_single))
# 节点
elif list(part.keys())[0] == '节点':
self.story.append(Paragraph(part['节点'], para_style_bold))
# 表名
elif list(part.keys())[0] == '表名':
self.story.append(Paragraph(part['表名'], table_name))
# 单位
elif list(part.keys())[0] == '单位':
self.story.append(Paragraph(part['单位'], table_unit))
# 注释
elif list(part.keys())[0] == '注释':
self.story.append(Paragraph(part['注释'], table_mark))
# 表格
elif list(part.keys())[0] == '表格' and part[list(part.keys())[0]]:
style = adjust_table_style(part['表格'])
td = adjust_table_data(part['表格'])
self.story.append(Table(td, style=style))

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

View File

@ -0,0 +1,39 @@
from DBHelper.MongoHelperInstance import DB_GUA
class RatingResultImpl(object):
@staticmethod
def search(**kwargs):
total = DB_GUA.find_all_data_with_count(
"评级数据",
"得分级别",
{"信用级别": kwargs["level"]}
)
items = DB_GUA.find_data_by_page_with_sort(
"评级数据",
"得分级别",
{"企业名称": kwargs["level"]},
["企业ID", "企业名称", "所在省份", "所在城市", "信用评级", "评级日期", "公司标签"],
{"更新时间": -1},
kwargs["page_size"],
kwargs["page_no"]
)
trans_items = list()
for item in items:
trans_item = trans_fields_name(
item,
["企业ID", "所在省份", "所在城市", "信用评级", "评级日期", "公司标签"],
["cid", "省份", "地级市", "级别", "日期", "标签"]
)
trans_items.append(trans_item)
result = {
"total": total,
"records": trans_items
}
return result

View File

@ -0,0 +1,49 @@
from flask import Blueprint, request
from Modules.AdminUser.UserAuthUtils import verify_token
from Utils.ErrorUtil import AttrCheckError, APIReturnError
from Utils.RouteUtil import RouteParamsCheck
result_route = Blueprint('result', __name__)
@result_route.route('/search', methods=['GET'])
@verify_token
def search_routes(**kwargs):
"""评级搜索"""
try:
RouteParamsCheck(request.args, ["level", "page_size", "page_no"]).required()
level = request.args["level"]
page_size = request.args["page_size"]
page_no = request.args["page_no"]
impl = RatingResultImpl()
result = impl.search(
company_name=company_name,
page_size=page_size,
page_no=page_no
)
return {"info": "评级搜索", "result": result}, 200
except APIReturnError as e:
return {"info": e.__str__()}, e.status_code
@result_route.route('/info', methods=['GET'])
@verify_token
def info_routes(**kwargs):
"""评级信息"""
@result_route.route('/rank', methods=['GET'])
@verify_token
def rank_routes(**kwargs):
"""得分级别"""
@result_route.route('/report', methods=['GET'])
@verify_token
def search_routes(**kwargs):
"""评级搜索"""

View File

2
app.py
View File

@ -4,6 +4,7 @@ from flask_cors import *
from Modules.AdminUser.UserRoutes import user_route
from Modules.Company.CompanyRoutes import company_route
from Modules.DashBoard.DashBoardRoutes import board_route
from Modules.File.FielRoutes import file_route
from Modules.Rating.RatingRoutes import rating_route
app = Flask(__name__)
@ -14,6 +15,7 @@ app.config['JSON_SORT_KEYS'] = False
app.register_blueprint(user_route, url_prefix='/admin/user')
app.register_blueprint(company_route, url_prefix='/admin/company')
app.register_blueprint(rating_route, url_prefix='/admin/rating')
app.register_blueprint(file_route, url_prefix='/admin/file')
# app.register_blueprint(board_route, url_prefix='/admin/board')