diff --git a/Mods/CompanyRate/Utils.py b/Mods/CompanyRate/Utils.py index 64c5d10..692e58f 100644 --- a/Mods/CompanyRate/Utils.py +++ b/Mods/CompanyRate/Utils.py @@ -138,7 +138,7 @@ def load_api_data(company_name, wj_data: {} = {}) -> dict: bj['专利信息'] = "1及以上" if 企业专利信息数量 >= 1 else '0' bj['知产出质'] = '是' if 知识产权出质 else '否' bj['纳税信用等级'] = 税务评级[0]['grade'] if 税务评级 else "M" - 海关信用等级 = 进出口信用['baseInfo']['creditRating'] if 进出口信用 else "一般信用企业" + 海关信用等级 = 进出口信用['baseInfo']['creditRate'] if 进出口信用 else "一般信用企业" 海关信用等级值 = "" if "企业" in 海关信用等级: 海关信用等级值 = "一般信用企业" diff --git a/Mods/RateFlow/Crud.py b/Mods/RateFlow/Crud.py index 202c6fe..9ddd298 100644 --- a/Mods/RateFlow/Crud.py +++ b/Mods/RateFlow/Crud.py @@ -2,15 +2,15 @@ from Context.common import mg_db, common_db from sqlalchemy.orm import Session -from .Models import RatingFlow, RatingFlowParticipant, RatingFlowNode +from .Models import RateFlow, RateFlowNode from .Schemas import * from Utils.MongoUtils import MongoConnect from Utils.TimeSerialNumUtils import create_time_serial_num -def create_rating_flow(db: Session, schema: CreateRatingFlowReqBody): - item = RatingFlow(**schema.dict()) - item.id = create_time_serial_num(prefix="F") +def create_rate_flow(db: Session, company_name, company_user_id): + item = RateFlow() + item.company_name = company_name item.status = "进行" db.add(item) @@ -19,44 +19,18 @@ def create_rating_flow(db: Session, schema: CreateRatingFlowReqBody): return item -def create_rating_flow_copy(db: Session, schema: CreateRatingFlowReqBodys): - schema = schema.dict() - schema.pop('participant_list') - item = RatingFlow(**schema) - item.id = create_time_serial_num(prefix="F") - item.status = "进行" - - db.add(item) - db.commit() - db.refresh(item) - return item - - -def create_rating_flow_participant(db: Session, schema): - item = RatingFlowParticipant() - item.id = create_time_serial_num(prefix="P") - item.participant = schema.participant - item.user_id = schema.user_id - item.rating_process_id = schema.rating_process_id - - db.add(item) - db.commit() - return True - - -def create_rating_flow_node(db: Session, node_num, node_name, rating_process_id): - item = RatingFlowNode() - item.id = create_time_serial_num("N") +def create_rate_flow_node(db: Session, node_num, node_name, rate_process_id): + item = RateFlowNode() item.node_num = node_num item.node_name = node_name - item.rating_process_id = rating_process_id + item.rate_process_id = rate_process_id db.add(item) db.commit() return True -def get_rating_flow_all_nodes(_id: str, db: Session, mongodb: MongoConnect): +def get_rate_flow_all_nodes(_id: str, db: Session, mongodb: MongoConnect, with_content=False): def nodes_to_return(objs): __list = list() for obj in objs: @@ -65,12 +39,13 @@ def get_rating_flow_all_nodes(_id: str, db: Session, mongodb: MongoConnect): __dict.update({"node_num": obj.node_num}) __dict.update({"node_name": obj.node_name}) __dict.update({"status": obj.status}) - __dict.update( - {"content": mongodb.find_data_by_id(dbname="打分评级流程", sheet=obj.node_name, _id=obj.obj_id)}) + if with_content: + __dict.update( + {"content": mongodb.find_data_by_id(dbname="打分评级流程", sheet=obj.node_name, _id=obj.obj_id)}) __list.append(__dict) return __list - item = db.query(RatingFlow).filter_by(id=_id).first() + item = db.query(RateFlow).filter_by(id=_id).first() if not item: return False @@ -78,75 +53,56 @@ def get_rating_flow_all_nodes(_id: str, db: Session, mongodb: MongoConnect): return nodes_to_return(list(item.nodes)) -def save_rating_flow_node(node_id: str, data: dict, db: Session, mongodb: MongoConnect): +def save_rate_flow_node(node_id: str, data: dict, db: Session, mongodb: MongoConnect): # 查询节点信息 - node_item = db.query(RatingFlowNode).filter_by(id=node_id).first() - - if not node_item: - return False - - # 删除原节点数据 - if node_item.obj_id: - mongodb.delete_data_by_id(dbname="打分评级流程", sheet=node_item.node_name, _id=node_item.obj_id) - - # 保存新节点数据 - obj_id = mongodb.insert_data(dbname="打分评级流程", sheet=node_item.node_name, data=data) - update_data = {"obj_id": obj_id} - db.query(RatingFlowNode).filter_by(id=node_id).update(update_data) - db.commit() - - return node_item.rating_process_id + node = db.query(RateFlowNode).filter_by(id=node_id).first() + mongodb.replace_data_by_id("评级流程", node.node_name, node.obj_id, data) + return True -def get_rating_flow(db, rating_flow_id: str): - item = db.query(RatingFlow).filter_by(id=rating_flow_id).first() +def get_rate_flow(db, rate_flow_id: str): + item = db.query(RateFlow).filter_by(id=rate_flow_id).first() return item -def edit_rating_status(db, rating_flow_id, status): +def edit_rate_status(db, rate_flow_id, status): data = {"status": status} - db.query(RatingFlow).filter_by(id=rating_flow_id).update(data) + db.query(RateFlow).filter_by(id=rate_flow_id).update(data) db.commit() - return db.query(RatingFlow).filter_by(id=rating_flow_id).first() + return db.query(RateFlow).filter_by(id=rate_flow_id).first() -def change_rating_status(db, _id: str, status: bool): +def change_rate_node_status(db, _id: str, status: str): update_data = {"status": status} - db.query(RatingFlowNode).filter_by(id=_id).update(update_data) + db.query(RateFlowNode).filter_by(id=_id).update(update_data) db.commit() - return db.query(RatingFlowNode).filter_by(id=_id).first() + return db.query(RateFlowNode).filter_by(id=_id).first() -def delete_rating_flow(db, _id: str): - db.query(RatingFlow).filter_by(id=_id).delete() +def delete_rate_flow(db, _id: str): + db.query(RateFlow).filter_by(id=_id).delete() db.commit() return True -def delete_rating_participants(db, _id: str, uid: str): - db.query(RatingFlowParticipant).filter_by(rating_process_id=_id, user_id=uid).delete() +def delete_rate_flow_node(db, _id: str): + db.query(RateFlowNode).filter_by(id=_id).delete() db.commit() return True -def delete_rating_flow_node(db, _id: str): - db.query(RatingFlowNode).filter_by(id=_id).delete() - db.commit() - return True - - -def get_rating_node_data(_id: str, db: Session, mongodb: MongoConnect): - item = db.query(RatingFlowNode).filter_by(id=_id).first() +def get_rate_node_data(_id: str, db: Session, mongodb: MongoConnect): + item = db.query(RateFlowNode).filter_by(id=_id).first() content = mongodb.find_data_by_id(dbname="打分评级流程", sheet=item.node_name, _id=item.obj_id) return content -def delete_rating_node_data(_id: str, db: Session, mongodb: MongoConnect): - node_item = db.query(RatingFlowNode).filter_by(id=_id).first() +def delete_rate_node_data(_id: str, db: Session, mongodb: MongoConnect): + node_item = db.query(RateFlowNode).filter_by(id=_id).first() if not node_item: return False if node_item.obj_id: mongodb.delete_data_by_id(dbname="打分评级流程", sheet=node_item.node_name, _id=node_item.obj_id) - db.query(RatingFlowNode).filter_by(id=_id).update({"obj_id": None}) + db.query(RateFlowNode).filter_by(id=_id).update({"obj_id": None}) db.commit() return True diff --git a/Mods/RateFlow/Models.py b/Mods/RateFlow/Models.py index e3f0683..3e01e91 100644 --- a/Mods/RateFlow/Models.py +++ b/Mods/RateFlow/Models.py @@ -1,40 +1,30 @@ -from sqlalchemy import Column, String, Date, Enum, ForeignKey, Integer, Boolean +from sqlalchemy import Column, String, Date, Enum, ForeignKey, Integer,Float, Boolean, DateTime, func from sqlalchemy.orm import relationship -from .Schemas import RankLevelEnum, RatingFlowStatusEnum +from Utils.TimeSerialNumUtils import create_time_serial_num +from .Schemas import RankLevelEnum, RateFlowStatusEnum from Context.common import common_db -class RatingFlow(common_db.Base): - __tablename__ = "rating_flow" - - id = Column(String(16), primary_key=True) - report_date = Column(Date) - status = Column(String(32), comment="评级状态") - rank_level = Column(String(32), comment="评级等级") - company = Column(String(32), index=True, comment="测评企业") - company_id = Column(String(16), comment="企业ID") - nodes = relationship("RatingFlowNode", backref="rating_flow") - rating_flow_participant = relationship("RatingFlowParticipant", back_populates="rating_flow") +class RateFlow(common_db.Base): + __tablename__ = "rate_flow" + id = Column(String(16), primary_key=True, default=lambda: create_time_serial_num(prefix="R")) + rate_date = Column(DateTime, comment='创建时间') + rate_level = Column(String(32), comment="评级等级") + rate_scope = Column(Float, comment="评级分数") + company_name = Column(String(32), index=True, comment="企业名称") + nodes = relationship("RateFlowNode", backref="rate_flow") + status = Column(String(32), default="未评级", comment="评级状态") + publish = Column(Boolean, default=False, comment="是否披露") + create_time = Column(DateTime, server_default=func.now(), comment='创建时间') -class RatingFlowParticipant(common_db.Base): - __tablename__ = "rating_flow_participant" +class RateFlowNode(common_db.Base): + __tablename__ = "rate_flow_node" - id = Column(String(16), primary_key=True) - participant = Column(String(32), index=True, comment="参与人") - user_id = Column(String(16), comment="用户ID") - rating_process_id = Column(String(16), ForeignKey("rating_flow.id", ondelete="CASCADE"), comment="评级流程ID") - - rating_flow = relationship("RatingFlow", back_populates="rating_flow_participant") - - -class RatingFlowNode(common_db.Base): - __tablename__ = "rating_flow_node" - - id = Column(String(16), primary_key=True, comment="流程节点ID") + id = Column(String(16), primary_key=True, comment="流程节点ID", default=lambda: create_time_serial_num(prefix="N")) node_num = Column(Integer, comment="流程节点序号") node_name = Column(String(32), comment="流程节点名称") - status = Column(Boolean, default=0, comment="流程节点状态") + status = Column(String(32), default='未完成', comment="流程节点状态") obj_id = Column(String(24), default=None, comment="流程内容mongoID") - rating_process_id = Column(String(16), ForeignKey("rating_flow.id", ondelete="CASCADE"), comment="评级流程ID") + rate_process_id = Column(String(16), ForeignKey("rate_flow.id", ondelete="CASCADE"), comment="评级流程ID") diff --git a/Mods/RateFlow/Router.py b/Mods/RateFlow/Router.py index 03e2fdb..21ff0e5 100644 --- a/Mods/RateFlow/Router.py +++ b/Mods/RateFlow/Router.py @@ -1,31 +1,98 @@ -from fastapi import APIRouter +from fastapi import APIRouter, Depends +from sqlalchemy.orm import Session + +from Context.common import CompanyUserTokenDataModel, company_user_auth_util, common_db, mg_db, AdminUserTokenDataModel, \ + admin_user_auth_util +from . import Crud +from . import Schemas +from .Models import RateFlow, RateFlowNode +from Utils.MongoUtils import MongoConnect """ 一个流程所需的基本接口 """ -router = APIRouter() -nodes = ['公司选择', '文件上传'] +router = APIRouter(prefix="/rate_flow") -def save_node(): - pass +@router.post("/create_rate_flow_from_company_user", summary="企业用户创建评级流程") +def func(token: CompanyUserTokenDataModel = Depends(company_user_auth_util.token_data_depend), + db: Session = Depends(common_db.get_db)): + company_name = token.company_name + rate_flow = Crud.create_rate_flow(db, company_name) + nodes = ["表单填报", "三方数据录入", "后台审核校正", "评级"] + for node_num in range(len(nodes)): + node_name = nodes[node_num] + Crud.create_rate_flow_node(db, node_num=node_num, node_name=node_name, rate_process_id=rate_flow.id) + return {"message": "创建成功", "code": 200} -def node(name=""): - def warp(func): - return func - - return warp +@router.post("/get_rate_flow_by_id", summary="获取评级流程数据", response_model=Schemas.GetRateFlowByIdRes) +def func(req: Schemas.GetRateFlowByIdReq, + token: CompanyUserTokenDataModel = Depends(company_user_auth_util.token_data_depend), + db: Session = Depends(common_db.get_db), mongodb: MongoConnect = Depends(mg_db.get_db)): + rate_flow_data = db.query(RateFlow).filter(RateFlow.id == req.id).first() + nodes = Crud.get_rate_flow_all_nodes(RateFlow.id, db, mongodb, with_content=True) + rate_flow_data.nodes = nodes + return rate_flow_data -@node(name="公司选择") -@router.post('/company_select') -def company_select(): - pass +@router.post("/get_rate_flow_by_company_user", summary="获取评级列表", + response_model=Schemas.GetRateFlowByCompanyUserRes) +def func(token: CompanyUserTokenDataModel = Depends(company_user_auth_util.token_data_depend), + db: Session = Depends(common_db.get_db), mongodb: MongoConnect = Depends(mg_db.get_db)): + items = [item for item in db.query(RateFlow).filter(RateFlow.company_name == token.company_name)] + return items -@node(name="文件上传") -@router.post('/file_upload') -def file_upload(): - pass +@router.post("/rate_form_save", summary="表单填报", tags=['评级节点']) +def func(req: Schemas.RateFormSaveReq, + token: CompanyUserTokenDataModel = Depends(company_user_auth_util.token_data_depend), + db: Session = Depends(common_db.get_db), mongodb: MongoConnect = Depends(mg_db.get_db)): + node = db.query(RateFlowNode).filter( + RateFlowNode.rate_process_id == req.rate_flow_id and RateFlowNode.node_name == '表单填报').first() + Crud.save_rate_flow_node(node.id, req.data, db, mongodb) + Crud.change_rate_node_status(db, node.id, "完成") + # todo:表单解析 + return {"message": "保存成功", "code": 200} + + +# 管理端接口 +@router.post("/load_api_data", summary="三方数据录入", tags=['评级节点']) +def func(req: Schemas.LoadApiDataReq, + token: AdminUserTokenDataModel = Depends(admin_user_auth_util.token_data_depend), + db: Session = Depends(common_db.get_db), mongodb: MongoConnect = Depends(mg_db.get_db)): + node = db.query(RateFlowNode).filter( + RateFlowNode.rate_process_id == req.rate_flow_id and RateFlowNode.node_name == '三方数据录入').first() + # todo: 三方数据录入 + data = {} + Crud.save_rate_flow_node(node.id, data, db, mongodb) + Crud.change_rate_node_status(db, node.id, "完成") + return {"message": "保存成功", "code": 200} + + +# 管理端接口 +@router.post("/save_man_data", summary="后台审核校正", tags=['评级节点']) +def func(req: Schemas.SaveManDataReq, + token: AdminUserTokenDataModel = Depends(admin_user_auth_util.token_data_depend), + db: Session = Depends(common_db.get_db), mongodb: MongoConnect = Depends(mg_db.get_db)): + node = db.query(RateFlowNode).filter( + RateFlowNode.rate_process_id == req.rate_flow_id and RateFlowNode.node_name == '后台审核校正').first() + # todo: 三方数据录入 + data = {} + Crud.save_rate_flow_node(node.id, data, db, mongodb) + Crud.change_rate_node_status(db, node.id, "完成") + return {"message": "保存成功", "code": 200} + + +@router.post("/do_rate", summary="评级", tags=['评级节点']) +def func(req: Schemas.DoRateReq, + token: AdminUserTokenDataModel = Depends(admin_user_auth_util.token_data_depend), + db: Session = Depends(common_db.get_db), mongodb: MongoConnect = Depends(mg_db.get_db)): + node = db.query(RateFlowNode).filter( + RateFlowNode.rate_process_id == req.rate_flow_id and RateFlowNode.node_name == '评级').first() + # todo: 进行评级 + data = {} + Crud.save_rate_flow_node(node.id, data, db, mongodb) + Crud.change_rate_node_status(db, node.id, "完成") + return {"message": "保存成功", "code": 200} \ No newline at end of file diff --git a/Mods/RateFlow/Schemas.py b/Mods/RateFlow/Schemas.py index 07b9bc7..46a6f7d 100644 --- a/Mods/RateFlow/Schemas.py +++ b/Mods/RateFlow/Schemas.py @@ -1,12 +1,12 @@ -from datetime import date +from datetime import date, datetime from enum import Enum, unique -from typing import List +from typing import List, Optional from pydantic import BaseModel @unique -class RatingFlowStatusEnum(Enum): +class RateFlowStatusEnum(Enum): enum01 = "进行" enum02 = "完成" enum03 = "取消" @@ -36,9 +36,8 @@ class RankLevelEnum(Enum): enum20 = "-" -class CreateRatingFlowReqBody(BaseModel): +class CreateRateFlowReqBody(BaseModel): company: str = None - company_id: str = None scorecard: str = None scorecard_id: str = None report_date: date = None @@ -49,7 +48,7 @@ class Participant(BaseModel): user_id: str = None -class CreateRatingFlowReqBodys(BaseModel): +class CreateRateFlowReqBodys(BaseModel): company: str = None company_id: str = None scorecard: str = None @@ -59,22 +58,22 @@ class CreateRatingFlowReqBodys(BaseModel): class AddParticipantReqBody(BaseModel): - rating_flow_id: str = None + rate_flow_id: str = None participant_list: List[Participant] class CreateParticipantReqBody(BaseModel): participant: str = None user_id: str = None - rating_process_id: str = None + rate_process_id: str = None -class SaveRatingFlowNodeReqBody(BaseModel): +class SaveRateFlowNodeReqBody(BaseModel): node_id: str = None data: dict = {} -class GetRatingDataReqBody(BaseModel): +class GetRateDataReqBody(BaseModel): company_id: str = None scorecard_id: str = None report_date: list = None @@ -84,31 +83,81 @@ class GetIndicatorReqBody(BaseModel): scorecard_id: str = None -class ListRatingFlowsReqBody(BaseModel): - status: RatingFlowStatusEnum = None +class ListRateFlowsReqBody(BaseModel): + status: RateFlowStatusEnum = None page: int = 1 pagesize: int = 10 -class GetRatingFlowNodeContentReqBody(BaseModel): +class GetRateFlowNodeContentReqBody(BaseModel): node_id: str = None class CalculationAdjustReqBody(BaseModel): - rating_flow_id: str + rate_flow_id: str adjustment: list class ChangeStatusReqBody(BaseModel): - rating_flow_id: str + rate_flow_id: str node_name: str status: bool -class RatingFlowListReqBody(BaseModel): +class RateFlowListReqBody(BaseModel): page: int = 1 pagesize: int = 10 class SearchFlowReqBody(BaseModel): id: str = "评级流程ID" + + +class NodeInfo(BaseModel): + node_id: Optional[str] + node_num: Optional[int] + node_name: Optional[str] + status: Optional[str] + content: {} + + +class RateFlowInfo(BaseModel): + id: Optional[str] + rate_date: Optional[datetime] + rate_level: Optional[str] + rate_scope: Optional[float] + company_name: Optional[str] + status: Optional[str] + publish: Optional[bool] + create_time: Optional[datetime] + nodes: Optional[List[Optional[NodeInfo, any]]] + + +class GetRateFlowByIdReq(BaseModel): + id: Optional[str] + + +class GetRateFlowByIdRes(RateFlowInfo): + pass + + +class GetRateFlowByCompanyUserRes(BaseModel): + items: Optional[List[RateFlowInfo]] + + +class RateFormSaveReq(BaseModel): + rate_flow_id: Optional[str] + data: Optional[dict] + + +class LoadApiDataReq(BaseModel): + rate_flow_id: Optional[str] + + +class SaveManDataReq(BaseModel): + rate_flow_id: Optional[str] + data: Optional[dict] + + +class DoRateReq(BaseModel): + rate_flow_id: Optional[str] diff --git a/Mods/User/CompanyUser/Models.py b/Mods/User/CompanyUser/Models.py index 092abb6..5f02d32 100644 --- a/Mods/User/CompanyUser/Models.py +++ b/Mods/User/CompanyUser/Models.py @@ -4,6 +4,8 @@ from sqlalchemy.orm import relationship from Context.common import common_db from sqlalchemy import Column, Integer, Boolean, String, ForeignKey, Text, DateTime, func, Date, Double +from Utils.TimeSerialNumUtils import create_time_serial_num + class CompanyUser(common_db.Base): """ @@ -26,4 +28,4 @@ class CompanyUser(common_db.Base): def to_safe_dict(self): data = {c.name: getattr(self, c.name) for c in self.__table__.columns if c.name != 'passwd'} - return data \ No newline at end of file + return data diff --git a/Mods/User/CompanyUser/Router.py b/Mods/User/CompanyUser/Router.py index 0cc0a04..d3b7676 100644 --- a/Mods/User/CompanyUser/Router.py +++ b/Mods/User/CompanyUser/Router.py @@ -10,7 +10,6 @@ from . import Schemas from . import Crud from ..UploadFile import Crud as UploadFileCrud from Utils.OcrUtils import ocr_business_license - router = APIRouter(tags=["企业用户"], prefix="/company_user") diff --git a/README.md b/README.md index 4a89719..0169362 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,7 @@ On some READMEs, you may see small images that convey metadata, such as whether Depending on what you are making, it can be a good idea to include screenshots or even a video (you'll frequently see GIFs rather than actual videos). Tools like ttygif can help, but check out Asciinema for a more sophisticated method. ## Installation -Within a particular ecosystem, there may be a common way of installing things, such as using Yarn, NuGet, or Homebrew. However, consider the possibility that whoever is reading your README is a novice and would like more guidance. Listing specific steps helps remove ambiguity and gets people to using your project as quickly as possible. If it only runs in a specific context like a particular programming language version or operating system or has dependencies that have to be installed manually, also add a Requirements subsection. +Within a particular ecosystem, there may be a common way of installing things, such as using Yarn, NuGet, or Homebrew. However, consider the possibility that whoever is reading your README is a novice and would like more guidance. Listing specific steps helps remove ambiguity and gets people to using your project as quickly as possible. If it only runs in a specific context like a particular programming language version or operate system or has dependencies that have to be installed manually, also add a Requirements subsection. ## Usage Use examples liberally, and show the expected output if you can. It's helpful to have inline the smallest example of usage that you can demonstrate, while providing links to more sophisticated examples if they are too long to reasonably include in the README. diff --git a/Utils/MongoUtils.py b/Utils/MongoUtils.py index 4c0c5d5..78533fb 100644 --- a/Utils/MongoUtils.py +++ b/Utils/MongoUtils.py @@ -50,3 +50,7 @@ class MongoConnect: collection.update_one({'_id': ObjectId(_id)}, {"$set": data}) return True + def replace_data_by_id(self, dbname: str, sheet: str, _id: str, data: dict): + collection = self.client[dbname][sheet] + collection.find_one_and_replace({'_id': ObjectId(_id)}, data) + return True