update 报告相关接口
This commit is contained in:
parent
a5fc76d081
commit
d61793650e
|
@ -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):
|
||||
"""
|
||||
读取一个文件
|
||||
|
|
|
@ -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()
|
||||
|
||||
|
|
|
@ -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万以上", "合计"],
|
||||
|
|
|
@ -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": "更新时间"
|
||||
}
|
||||
|
|
|
@ -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]
|
||||
)
|
||||
|
||||
|
|
|
@ -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()
|
|
@ -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
|
|
@ -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):
|
||||
""""""
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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):
|
||||
|
||||
|
|
|
@ -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
|
|
@ -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.
Binary file not shown.
After Width: | Height: | Size: 64 KiB |
|
@ -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
|
|
@ -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):
|
||||
"""评级搜索"""
|
2
app.py
2
app.py
|
@ -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')
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue