From 65e1d6c84e8f2b4d114455ccff408e26eb6e11cd Mon Sep 17 00:00:00 2001 From: wcq <744800102@qq.com> Date: Thu, 7 Dec 2023 14:48:06 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=B8=BB=E9=A2=98=E5=88=97?= =?UTF-8?q?=E8=A1=A8=E5=A2=9E=E5=88=A0=E6=94=B9=E6=9F=A5=EF=BC=8C=E4=B8=BB?= =?UTF-8?q?=E9=A2=98=E6=96=87=E4=BB=B6=E6=A8=A1=E6=9D=BF=E5=A2=9E=E5=88=A0?= =?UTF-8?q?=E6=94=B9=E6=9F=A5=EF=BC=8C=E4=B8=BB=E9=A2=98=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E4=BF=AE=E6=94=B9=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- context/common.py | 2 + mods/receive/models.py | 6 +- mods/receive/mods/receive_subject/schemas.py | 17 +- .../receive/mods/receive_subject_file/crud.py | 1 + .../mods/receive_subject_file/router.py | 44 ++- .../mods/receive_subject_file/schemas.py | 2 +- mods/receive/routes.json | 351 +++++++++++++++++- mods/receive/schemas.py | 28 +- mods/receive/utils.py | 43 +++ 9 files changed, 459 insertions(+), 35 deletions(-) create mode 100644 mods/receive/utils.py diff --git a/context/common.py b/context/common.py index 054ed7e..8b86c92 100644 --- a/context/common.py +++ b/context/common.py @@ -102,3 +102,5 @@ email_tool = EmailTool(**dict(conf['email_tool'])) # 邮箱验证码工具类 email_verify_code = EmailVerifyCode(redis_pool, email_tool) + +static_path = Path('static') diff --git a/mods/receive/models.py b/mods/receive/models.py index a07488d..ee36ea5 100644 --- a/mods/receive/models.py +++ b/mods/receive/models.py @@ -5,7 +5,7 @@ from random import random from typing import Set from sqlalchemy import String, DateTime, func, Boolean, JSON, ForeignKey, Enum, TEXT, Double, Integer, create_engine from sqlalchemy.orm import mapped_column, Mapped, declarative_base, relationship -from mods.rate.schemas import ReceiveSubjectState, ReceiveOrderState, NoticeType +from .schemas import ReceiveSubjectState, ReceiveOrderState, NoticeType from utils.random_utils import get_random_letter_and_num_code, get_random_num_code, time_now_to_code from utils.sqlalchemy_common_utils import SalBase from .common import Base @@ -23,8 +23,7 @@ class ReceiveSubjectFile(Base, SalBase): """ __tablename__ = "receive_subject_file" id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True, comment='id') - subject_id: Mapped[int] = mapped_column(ForeignKey("receive_subject.id", ondelete="CASCADE", onupdate="CASCADE"), - comment="主题ID", nullable=False) + subject_id: Mapped[int] = mapped_column(ForeignKey("receive_subject.id", ondelete="CASCADE", onupdate="CASCADE"),comment="主题ID", nullable=False) name: Mapped[str] = mapped_column(String(255), nullable=False, comment='名称') type: Mapped[str] = mapped_column(String(255), nullable=False, comment='类型') des: Mapped[str] = mapped_column(TEXT, nullable=True, comment='说明') @@ -39,6 +38,7 @@ class ReceiveSubject(Base, SalBase): __tablename__ = "receive_subject" id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True, comment='主题ID') name: Mapped[str] = mapped_column(String(255), nullable=False, unique=True, comment='主题名称') + receiver: Mapped[str] = mapped_column(String(255), nullable=False, comment='接收人') start_time: Mapped[datetime] = mapped_column(DateTime, server_default=func.now(), nullable=True, comment='开始时间') finish_time: Mapped[datetime] = mapped_column(DateTime, nullable=True, diff --git a/mods/receive/mods/receive_subject/schemas.py b/mods/receive/mods/receive_subject/schemas.py index 1e191f4..b94ce72 100644 --- a/mods/receive/mods/receive_subject/schemas.py +++ b/mods/receive/mods/receive_subject/schemas.py @@ -10,14 +10,15 @@ class ReceiveSubjectId(BaseModel): class ReceiveSubjectAdd(BaseModel): - name: str - start_time: Optional[datetime]= None - finish_time: Optional[datetime]= None - state: Any - folder_name: Optional[str]= None - create_time: Optional[datetime]= None - des: Any - files: Optional[List[Any]]= None + name: str + start_time: Optional[datetime] = None + finish_time: Optional[datetime] = None + receiver: str + state: Any + folder_name: Optional[str] = None + create_time: Optional[datetime] = None + des: Any + files: Optional[List[Any]] = None class ReceiveSubjectAddOptional(ReceiveSubjectAdd, metaclass=AllOptional): diff --git a/mods/receive/mods/receive_subject_file/crud.py b/mods/receive/mods/receive_subject_file/crud.py index 8ea7ab3..22f2825 100644 --- a/mods/receive/mods/receive_subject_file/crud.py +++ b/mods/receive/mods/receive_subject_file/crud.py @@ -34,3 +34,4 @@ def receive_subject_file_get(db: Session, data: schemas.ReceiveSubjectFileId) -> def receive_subject_file_all(db: Session): return db.query(ReceiveSubjectFile).all() + diff --git a/mods/receive/mods/receive_subject_file/router.py b/mods/receive/mods/receive_subject_file/router.py index 6ab75ff..2d01629 100644 --- a/mods/receive/mods/receive_subject_file/router.py +++ b/mods/receive/mods/receive_subject_file/router.py @@ -1,9 +1,14 @@ -from fastapi import APIRouter, Depends, HTTPException +import json + +from fastapi import APIRouter, Depends, HTTPException, UploadFile, File, Form from sqlalchemy.orm import Session +from context.common import static_path from ...common import get_db from . import crud from . import schemas +from ...models import ReceiveSubject +from ...utils import get_upload_file_type, file_upload router = APIRouter(tags=["主题文件模板"], prefix='/receive_subject_file') @@ -43,11 +48,34 @@ def receive_subject_file_query(req: schemas.ReceiveSubjectFileQueryReq, db: Sess return schemas.ReceiveSubjectFileQueryRes(count=count, items=items) -@router.post("/all", summary="获取所有主题文件模板", response_model=schemas.ReceiveSubjectFileAllRes) -def receive_subject_file_all(req: schemas.ReceiveSubjectFileAllReq, db: Session = Depends(get_db)): - query = crud.receive_subject_file_all(db) - items = [schemas.ReceiveSubjectFileInfo(**item.to_full_dict(include=req.include, - ex_include=req.ex_include, - relation_use_id=req.relation_use_id)) for item in query] - return schemas.ReceiveSubjectFileAllRes(items=items) +@router.post("/add_with_file", summary="添加主题文件模板附带文件") +def receive_subject_file_add_with_file(file: UploadFile = File(...), data: str = Form(...), + db: Session = Depends(get_db)): + file_type = get_upload_file_type(file) + data = json.loads(data) + data['template_path'] = '' + data['type'] = file_type + req = schemas.ReceiveSubjectFileAddReq(**data) + subject: ReceiveSubject = db.query(ReceiveSubject).filter(ReceiveSubject.id == req.D).first() + folder_name = subject.folder_name + file_path = file_upload(file, static_path / folder_name, db) + req.template_path = file_path + item = crud.receive_subject_file_add(db, req) + return schemas.ReceiveSubjectFileAddRes(**item.to_dict()) + + +@router.post("/update_file", summary="修改主题文件模板附带文件") +def receive_subject_file_update_file(file: UploadFile = File(...), data: str = Form(...), + db: Session = Depends(get_db)): + data = json.loads(data) + file_type = get_upload_file_type(file) + req = schemas.ReceiveSubjectFileUpdate( + **{'id': data['id'], 'template_path': '', 'type': file_type, 'subject_id': data['subject_id']}) + subject: ReceiveSubject = db.query(ReceiveSubject).filter(ReceiveSubject.id == req.subject_id).first() + folder_name = subject.folder_name + file_path = file_upload(file, static_path / folder_name, db) + req.template_path = file_path + item = crud.receive_subject_file_update(db, req) + return schemas.ReceiveSubjectFileUpdateRes(**item.to_dict()) + ######### diff --git a/mods/receive/mods/receive_subject_file/schemas.py b/mods/receive/mods/receive_subject_file/schemas.py index 36744e0..5970dc2 100644 --- a/mods/receive/mods/receive_subject_file/schemas.py +++ b/mods/receive/mods/receive_subject_file/schemas.py @@ -12,7 +12,7 @@ class ReceiveSubjectFileId(BaseModel): class ReceiveSubjectFileAdd(BaseModel): name: str subject_id: int - type: str + type: Optional[str] = None des: Any template_path: Optional[str] = None file_size_limit: Optional[float] = None diff --git a/mods/receive/routes.json b/mods/receive/routes.json index 4de54e0..17d84d5 100644 --- a/mods/receive/routes.json +++ b/mods/receive/routes.json @@ -1 +1,350 @@ -[{"path": "/receive", "name": "receive", "component": "Layout", "redirect": "/receive/receive_subject", "meta": {"icon": "calendar", "title": "城投管理"}, "children": [{"path": "/receive/receive_subject", "name": "接收主题", "component": "tablePlus/index", "meta": {"keepAlive": true, "title": "接收主题", "tableModel": {"tableName": "receive_subject", "name": "接收主题", "idKey": "id", "columns": [{"key": "name", "name": "主题名称", "addNeed": true, "updateNeed": true, "type": "string"}, {"key": "id", "name": "主题ID", "addNeed": false, "type": "int"}, {"key": "start_time", "name": "开始时间", "addNeed": false, "type": "datetime"}, {"key": "finish_time", "name": "结束时间", "type": "datetime"}, {"key": "state", "name": "主题状态", "addNeed": false, "type": "enum"}, {"key": "folder_name", "name": "文件接收目录名称", "addNeed": false, "type": "string"}, {"key": "create_time", "name": "创建时间", "addNeed": false, "type": "datetime"}, {"key": "des", "name": "说明"}, {"key": "files", "name": "files", "hidden": true, "type": "set"}], "baseUrl": "/fastapi_crud_template/receive/receive_subject"}}}, {"path": "/receive/receive_order_notice_log", "name": "通知日志", "component": "tablePlus/index", "meta": {"keepAlive": true, "title": "通知日志", "tableModel": {"tableName": "receive_order_notice_log", "name": "通知日志", "idKey": "id", "columns": [{"key": "id", "name": "id", "addNeed": false, "type": "int"}, {"key": "subject_id", "name": "主题ID", "addNeed": true, "updateNeed": true, "type": "string"}, {"key": "account", "name": "通知账户", "addNeed": true, "updateNeed": true, "type": "string"}, {"key": "notice_type", "name": "通知类型", "addNeed": true, "updateNeed": true, "type": "enum"}, {"key": "notice_time", "name": "通知时间", "addNeed": false, "type": "datetime"}], "baseUrl": "/fastapi_crud_template/receive/receive_order_notice_log"}}}, {"path": "/receive/receive_order", "name": "接收单", "component": "tablePlus/index", "meta": {"keepAlive": true, "title": "接收单", "tableModel": {"tableName": "receive_order", "name": "接收单", "idKey": "id", "columns": [{"key": "id", "name": "id", "addNeed": false, "type": "string"}, {"key": "subject", "name": "subject", "hidden": true, "type": "json"}, {"key": "subject_id", "name": "主题ID", "addNeed": true, "updateNeed": true, "type": "int"}, {"key": "sender_company", "name": "接收公司", "addNeed": true, "updateNeed": true, "type": "string"}, {"key": "sender_phone", "name": "接收人手机", "type": "string"}, {"key": "sender_email", "name": "接收人邮箱", "type": "string"}, {"key": "sender_name", "name": "接收人", "type": "string"}, {"key": "sender_wx", "name": "接收人微信", "type": "string"}, {"key": "contact_user_id", "name": "对接人", "type": "string"}, {"key": "url_code", "name": "接收链接后缀", "addNeed": false, "type": "string"}, {"key": "code", "name": "接收链接后缀", "addNeed": false, "type": "string"}, {"key": "state", "name": "接收单状态", "addNeed": false, "type": "enum"}, {"key": "files", "name": "files", "hidden": true, "type": "set"}, {"key": "create_time", "name": "创建时间", "addNeed": false, "type": "datetime"}, {"key": "finish_time", "name": "完成时间", "type": "datetime"}, {"key": "notice_logs", "name": "notice_logs", "hidden": true, "type": "set"}], "baseUrl": "/fastapi_crud_template/receive/receive_order"}}}, {"path": "/receive/receive_subject_file", "name": "主题文件模板", "component": "tablePlus/index", "meta": {"keepAlive": true, "title": "主题文件模板", "tableModel": {"tableName": "receive_subject_file", "name": "主题文件模板", "idKey": "id", "columns": [{"key": "name", "name": "名称", "addNeed": true, "updateNeed": true, "type": "string"}, {"key": "id", "name": "id", "addNeed": false, "type": "int"}, {"key": "subject_id", "name": "主题ID", "addNeed": true, "updateNeed": true, "type": "int"}, {"key": "type", "name": "类型", "addNeed": true, "updateNeed": true, "type": "string"}, {"key": "des", "name": "说明"}, {"key": "template_path", "name": "模板文件链接", "type": "string"}, {"key": "file_size_limit", "name": "文件大小限制mb", "addNeed": false, "type": "float"}], "baseUrl": "/fastapi_crud_template/receive/receive_subject_file"}}}, {"path": "/receive/receive_file", "name": "接收文件", "component": "tablePlus/index", "meta": {"keepAlive": true, "title": "接收文件", "tableModel": {"tableName": "receive_file", "name": "接收文件", "idKey": "id", "columns": [{"key": "name", "name": "文件名称", "addNeed": true, "updateNeed": true, "type": "string"}, {"key": "id", "name": "id", "addNeed": false, "type": "int"}, {"key": "receive_order_id", "name": "接收单id", "addNeed": true, "updateNeed": true, "type": "string"}, {"key": "receive_subject_file_id", "name": "模板ID", "addNeed": true, "updateNeed": true, "type": "int"}, {"key": "file_path", "name": "文件链接", "type": "string"}], "baseUrl": "/fastapi_crud_template/receive/receive_file"}}}]}] \ No newline at end of file +[ + { + "path": "/receive", + "name": "receive", + "component": "Layout", + "redirect": "/receive/receive_subject", + "meta": { + "icon": "calendar", + "title": "城投管理" + }, + "children": [ + { + "path": "/receive/receive_subject", + "name": "接收主题", + "component": "tablePlus/index", + "meta": { + "keepAlive": true, + "title": "接收主题", + "tableModel": { + "tableName": "receive_subject", + "name": "接收主题", + "idKey": "id", + "columns": [ + { + "key": "name", + "name": "主题名称", + "addNeed": true, + "updateNeed": true, + "type": "string" + }, + { + "key": "id", + "name": "主题ID", + "addNeed": false, + "type": "int" + }, + { + "key": "start_time", + "name": "开始时间", + "addNeed": false, + "type": "datetime" + }, + { + "key": "finish_time", + "name": "结束时间", + "type": "datetime" + }, + { + "key": "state", + "name": "主题状态", + "addNeed": false, + "type": "enum" + }, + { + "key": "folder_name", + "name": "文件接收目录名称", + "addNeed": false, + "type": "string" + }, + { + "key": "create_time", + "name": "创建时间", + "addNeed": false, + "type": "datetime" + }, + { + "key": "des", + "name": "说明" + }, + { + "key": "files", + "name": "files", + "hidden": true, + "type": "set" + } + ], + "baseUrl": "/fastapi_crud_template/receive/receive_subject" + } + } + }, + { + "path": "/receive/receive_order_notice_log", + "name": "通知日志", + "component": "tablePlus/index", + "meta": { + "keepAlive": true, + "title": "通知日志", + "tableModel": { + "tableName": "receive_order_notice_log", + "name": "通知日志", + "idKey": "id", + "columns": [ + { + "key": "id", + "name": "id", + "addNeed": false, + "type": "int" + }, + { + "key": "subject_id", + "name": "主题ID", + "addNeed": true, + "updateNeed": true, + "type": "string" + }, + { + "key": "account", + "name": "通知账户", + "addNeed": true, + "updateNeed": true, + "type": "string" + }, + { + "key": "notice_type", + "name": "通知类型", + "addNeed": true, + "updateNeed": true, + "type": "enum" + }, + { + "key": "notice_time", + "name": "通知时间", + "addNeed": false, + "type": "datetime" + } + ], + "baseUrl": "/fastapi_crud_template/receive/receive_order_notice_log" + } + } + }, + { + "path": "/receive/receive_order", + "name": "接收单", + "component": "tablePlus/index", + "meta": { + "keepAlive": true, + "title": "接收单", + "tableModel": { + "tableName": "receive_order", + "name": "接收单", + "idKey": "id", + "columns": [ + { + "key": "id", + "name": "id", + "addNeed": false, + "type": "string" + }, + { + "key": "subject", + "name": "subject", + "hidden": true, + "type": "json" + }, + { + "key": "subject_id", + "name": "主题ID", + "addNeed": true, + "updateNeed": true, + "type": "int" + }, + { + "key": "sender_company", + "name": "接收公司", + "addNeed": true, + "updateNeed": true, + "type": "string" + }, + { + "key": "sender_phone", + "name": "接收人手机", + "type": "string" + }, + { + "key": "sender_email", + "name": "接收人邮箱", + "type": "string" + }, + { + "key": "sender_name", + "name": "接收人", + "type": "string" + }, + { + "key": "sender_wx", + "name": "接收人微信", + "type": "string" + }, + { + "key": "contact_user_id", + "name": "对接人", + "type": "string" + }, + { + "key": "url_code", + "name": "接收链接后缀", + "addNeed": false, + "type": "string" + }, + { + "key": "code", + "name": "接收链接后缀", + "addNeed": false, + "type": "string" + }, + { + "key": "state", + "name": "接收单状态", + "addNeed": false, + "type": "enum" + }, + { + "key": "files", + "name": "files", + "hidden": true, + "type": "set" + }, + { + "key": "create_time", + "name": "创建时间", + "addNeed": false, + "type": "datetime" + }, + { + "key": "finish_time", + "name": "完成时间", + "type": "datetime" + }, + { + "key": "notice_logs", + "name": "notice_logs", + "hidden": true, + "type": "set" + } + ], + "baseUrl": "/fastapi_crud_template/receive/receive_order" + } + } + }, + { + "path": "/receive/receive_subject_file", + "name": "主题文件模板", + "component": "tablePlus/index", + "meta": { + "keepAlive": true, + "title": "主题文件模板", + "tableModel": { + "tableName": "receive_subject_file", + "name": "主题文件模板", + "idKey": "id", + "columns": [ + { + "key": "name", + "name": "名称", + "addNeed": true, + "updateNeed": true, + "type": "string" + }, + { + "key": "id", + "name": "id", + "addNeed": false, + "type": "int" + }, + { + "key": "subject_id", + "name": "主题ID", + "addNeed": true, + "updateNeed": true, + "type": "int" + }, + { + "key": "type", + "name": "类型", + "addNeed": true, + "updateNeed": true, + "type": "string" + }, + { + "key": "des", + "name": "说明" + }, + { + "key": "template_path", + "name": "模板文件链接", + "type": "string" + }, + { + "key": "file_size_limit", + "name": "文件大小限制mb", + "addNeed": false, + "type": "float" + } + ], + "baseUrl": "/fastapi_crud_template/receive/receive_subject_file" + } + } + }, + { + "path": "/receive/receive_file", + "name": "接收文件", + "component": "tablePlus/index", + "meta": { + "keepAlive": true, + "title": "接收文件", + "tableModel": { + "tableName": "receive_file", + "name": "接收文件", + "idKey": "id", + "columns": [ + { + "key": "name", + "name": "文件名称", + "addNeed": true, + "updateNeed": true, + "type": "string" + }, + { + "key": "id", + "name": "id", + "addNeed": false, + "type": "int" + }, + { + "key": "receive_order_id", + "name": "接收单id", + "addNeed": true, + "updateNeed": true, + "type": "string" + }, + { + "key": "receive_subject_file_id", + "name": "模板ID", + "addNeed": true, + "updateNeed": true, + "type": "int" + }, + { + "key": "file_path", + "name": "文件链接", + "type": "string" + } + ], + "baseUrl": "/fastapi_crud_template/receive/receive_file" + } + } + } + ] + } +] \ No newline at end of file diff --git a/mods/receive/schemas.py b/mods/receive/schemas.py index da296e7..f6f64f9 100644 --- a/mods/receive/schemas.py +++ b/mods/receive/schemas.py @@ -1,28 +1,28 @@ from enum import Enum -class RateServeState(Enum): +class ReceiveSubjectState(Enum): """ - 评级服务状态类型 + 接收主题状态 """ - examining = 'examining' # 审核中 - rating = 'rating' # 评级中 - cancel = 'cancel' # 取消 + receiving = 'receiving' # 接收种 + examining = 'examining' # 处理种 finish = 'finish' # 完成 -class NodeState(Enum): +class ReceiveOrderState(Enum): """ - 节点状态 + 接收主题状态 """ - incomplete = "incomplete" # 未完成 - finish = "finish" # 完成 + receiving = 'receiving' # 接收种 + examining = 'examining' # 处理种 + finish = 'finish' # 完成 -class FileSubType: +class NoticeType(Enum): """ - 文件分类,不使用Enum,因为类型不限制 + 通知类型 """ - report = 'report' # 报告 - cert = 'cert' # 证书 - fill_sheet = 'fill_sheet' # 企业填报文件 + phone = 'phone' + email = 'email' + diff --git a/mods/receive/utils.py b/mods/receive/utils.py new file mode 100644 index 0000000..c167475 --- /dev/null +++ b/mods/receive/utils.py @@ -0,0 +1,43 @@ +import os +from pathlib import Path + +from fastapi import UploadFile +from sqlalchemy.orm import Session +from mimetypes import types_map + +from utils.common_utils import file_md5 + +types_map['.xlsx'] = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' +types_map['.docx'] = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' +types_dic = {key[1:]: item for key, item in types_map.items()} +types_dic_rev = {item: key[1:] for key, item in types_map.items()} + + +def get_upload_file_type(file: UploadFile, ): + file_type = types_dic_rev.get(file.content_type) + return file_type + + +def file_upload(file: UploadFile, save_path: str, db: Session, user_id=None, sub_type=''): + content = b"" + while True: + byte = file.file.read(10240) + if byte: + content += byte + else: + break + content_type = file.content_type + file_type = get_upload_file_type(file) + common_type, _ = content_type.split('/') + content_start = content[0:10240] + file_md = file_md5(content_start) + file_save_name = file_md + f".{file_type}" + save_path = Path(save_path) + file_save_path = save_path / file_save_name + file_url = file_save_path.__str__() + if not os.path.exists(save_path): + os.makedirs(save_path) + if not os.path.exists(file_save_path): + with open(file_save_path, 'wb') as f: + f.write(content) + return file_url