diff --git a/Crud/UserCrud.py b/Crud/UserCrud.py index 5a13373..afcdbdf 100644 --- a/Crud/UserCrud.py +++ b/Crud/UserCrud.py @@ -110,3 +110,12 @@ def get_user_by_department_type(db: Session, department_type: str): def get_department_list(db: Session): return db.query(Department).all() + + +def get_department_config(db: Session): + type_dic = {} + for d in db.query(Department).all(): + if d.sub_type not in d: + type_dic[d.sub_type] = [] + type_dic[d.sub_type].append(d.name) + return type_dic diff --git a/Models/DailyModel.py b/Models/DailyModel.py index 7b97166..8e0bcbc 100644 --- a/Models/DailyModel.py +++ b/Models/DailyModel.py @@ -2,6 +2,7 @@ from sqlalchemy import Column, String, Boolean, Enum, Text, DateTime, func, Inte from sqlalchemy.orm import relationship from Utils.SqlAlchemyUtils import Base from Schemas.DailySchemas import DailyTypeEnum +from Mods.Comment.Models import Comment class Daily(Base): @@ -18,7 +19,8 @@ class Daily(Base): file_md = Column(String(255), comment="附加文件") required_auth = Column(Text, comment="日报权限") sign_name = Column(String(128), comment="签发人") - comments = relationship("Comment", cascade='all', back_populates='daily',uselist=True) + sub_type = Column(String(255), comment="二级类别") + comments = relationship("Comment", cascade='all', back_populates='daily', uselist=True) daily_time = Column(DateTime, server_default=func.now(), comment='日报时间') create_time = Column(DateTime, server_default=func.now(), comment='创建时间') update_time = Column(DateTime, server_default=func.now(), onupdate=func.now(), comment='修改时间') diff --git a/Models/DepartmentModel.py b/Models/DepartmentModel.py index 10dc3f1..b11dc86 100644 --- a/Models/DepartmentModel.py +++ b/Models/DepartmentModel.py @@ -11,6 +11,7 @@ class Department(Base): belong = Column(Integer, comment="上级部门") auth_data = Column(Text, comment="部门权限数据") type = Column(Enum(DepartmentTypeEnum, values_callable=lambda x: [e.value for e in x]), nullable=False) + sub_type = Column(String(255), comment="二级分类") def to_dict(self): return {c.name: getattr(self, c.name) for c in self.__table__.columns} diff --git a/Mods/Comment/Router.py b/Mods/Comment/Router.py index 9a35b71..5d6ee6a 100644 --- a/Mods/Comment/Router.py +++ b/Mods/Comment/Router.py @@ -5,7 +5,7 @@ from . import Schemas from . import Crud from Utils.SqlAlchemyUtils import QueryParams, query_common from .Models import Comment -from ..Notice.Utils import DailyNotice, comment_notice_send +from ..Notice.Utils import DailyNotice, comment_notice_send, daily_notice router = APIRouter(tags=["评论"]) @@ -23,7 +23,7 @@ def comment_add(req: Schemas.CommentAddReq, db: Session = Depends(get_db)): comment_content=comment.content ) "".format() - DailyNotice.notice_comment(notice_user.email, send) + daily_notice.notice_comment(notice_user.email, send) return comment diff --git a/Mods/Notice/Utils.py b/Mods/Notice/Utils.py index f4d3544..a5306cd 100644 --- a/Mods/Notice/Utils.py +++ b/Mods/Notice/Utils.py @@ -2,14 +2,15 @@ import threading import time from concurrent.futures import ThreadPoolExecutor -from sqlalchemy import func, or_ +from sqlalchemy import func, or_, cast, DATE from sqlalchemy.orm import Session +from Models.DailyModel import Daily from Models.DepartmentModel import Department from Models.UserModel import User from Utils.EmailUtils import send_email from Utils.SqlAlchemyUtils import get_db, get_db_i -from datetime import datetime +from datetime import datetime, date comment_notice_send = """您的日报: 【{daily_type}-{daily_name}】 @@ -25,6 +26,19 @@ holiday = {'01-01': True, '01-02': True, '01-21': True, '01-22': True, '01-23': '10-04': True, '10-05': True, '10-06': True, '10-07': False, '10-08': False, '12-31': True} +def get_user_not_fill_daily(): + with get_db_i() as db: + db: Session + daily_list = db.query(Daily).filter(cast(Daily.daily_time, DATE) == datetime.now().date()) + filled_user_list = {item.fill_user for item in daily_list} + + notice_user_list = db.query(User).filter(User.email.not_in(filled_user_list)) + email_list = [user.email for user in notice_user_list] + name_list = [user.name for user in notice_user_list] + print(name_list) + return filled_user_list + + def is_workday(): """ 返回当天是否上班 @@ -46,27 +60,25 @@ def is_workday(): class DailyNotice: - @staticmethod - def notification_daily_report_filling(): - """ - 日报通知 - 每日三点通知未填写日报的部门进行日报填报 - 1.判断是否是工作日 - 2.判断哪些部门没有日报内容 - 2.通知部门的指定人员?还是所有人员? - :return: - """ + def __init__(self, email_send_func=send_email): + self.email_send_func = email_send_func + pass - @staticmethod - def notice_comment(email, content): + def send_email(self, title, email, content): + try: + return self.email_send_func(title, email, content) + except Exception as e: + print('邮件发送错误', e) + return False + + def notice_comment(self, email, content): """ 领导反馈的通知 :return: """ - send_email('日报反馈', email, content) + return self.send_email('日报反馈', email, content) - @staticmethod - def send_on_daily_pdf_upload(): + def send_on_daily_pdf_upload(self): """ 每日日报上传后的通知 :return: @@ -82,28 +94,38 @@ class DailyNotice: can_watch_departments])): emails.append(user.email) - with ThreadPoolExecutor(max_workers=8) as executor: - for i in range(2): - pass - # executor.submit(send_email, "每日运行日报已上传", 'wangsichuan@fecr.com.cn', '每日运行日报已上传') + with ThreadPoolExecutor(max_workers=5) as executor: + # for email in emails: + # executor.submit(self.send_email, "每日运行日报已上传", email, '每日运行日报已上传') + executor.submit(self.send_email, "每日运行日报已上传", 'wangsichuan@fecr.com.cn', '每日运行日报已上传') + + def start_timer_to_notice_daily_fill(self): - @staticmethod - def start_timer_to_notice_daily_fill(): - print("start_timer_to_notice_daily_fill") sended = False while True: time.sleep(60) - if is_workday() and datetime.now().hour == 17 and datetime.now().minute==18 and not sended: + if is_workday() and datetime.now().hour == 16 and not sended: sended = True try: - pass + user_list = get_user_not_fill_daily() + args_list = [['日报填报提醒', user.email, '填报提醒'] for user in user_list] + # self.email_send_thread(args_list) send_email('日报填报提醒', "fecribd@fecr.com.cn", "填报提醒") - print("邮件发送了") except Exception as e: print(e, 'start_timer_to_notice_daily_fill错误') if datetime.now().hour > 15: sended = False -threading.Thread(target=DailyNotice.start_timer_to_notice_daily_fill).start() -# DailyNotice.start_timer_to_notice_daily_fill() \ No newline at end of file + def email_send_thread(self, args_list, sem=5): + with ThreadPoolExecutor(max_workers=sem) as executor: + for args in args_list: + executor.submit(self.send_email, *args) + + def init(self): + threading.Thread(target=self.start_timer_to_notice_daily_fill).start() + + +daily_notice = DailyNotice() + + diff --git a/Router/DailyRouter.py b/Router/DailyRouter.py index 9ddd30c..be5eaf2 100644 --- a/Router/DailyRouter.py +++ b/Router/DailyRouter.py @@ -7,7 +7,7 @@ from sqlalchemy.orm import Session from starlette.responses import FileResponse from Models.DepartmentModel import Department -from Mods.Notice.Utils import DailyNotice +from Mods.Notice.Utils import DailyNotice, daily_notice from Schemas.DailySchemas import DailyTypeEnum from Schemas.UserSchemas import TokenData from Utils.AuthUtils import token_data_depend, check_auth, registered_depend @@ -55,7 +55,7 @@ def daily_add(req: DailySchemas.DailyAddReq, db: Session = Depends(get_db), # raise HTTPException(detail="没有本部门填报权限", status_code=305) new_daily = DailyCrud.daily_add(db, req.dict()) if req.type == DailyTypeEnum.运行日报: - DailyNotice.send_on_daily_pdf_upload() + daily_notice.send_on_daily_pdf_upload() return DailySchemas.DailyAddRes(**new_daily.to_dict()) diff --git a/Schemas/DailySchemas.py b/Schemas/DailySchemas.py index 5a893ed..6d0e7e2 100644 --- a/Schemas/DailySchemas.py +++ b/Schemas/DailySchemas.py @@ -16,8 +16,11 @@ class DailyTypeEnum(Enum): # 经营情况 = "经营情况" 财务营收 = "财务营收" 动态 = "动态" + + class DailyExportToPdfReq(BaseModel): - day:date + day: date + class CommentInfo(BaseModel): id: Optional[int] @@ -40,6 +43,7 @@ class DailyInfo(BaseModel): post: Optional[int] content: Optional[str] file_md: Optional[str] + sub_type: Optional[str] comments: Optional[List[CommentInfo]] daily_time: Optional[datetime] create_time: Optional[datetime] @@ -65,6 +69,7 @@ class DailyChangeReq(BaseModel): required_auth: Optional[str] post: Optional[int] content: Optional[str] + sub_type: Optional[str] daily_time: Optional[datetime] file_md: Optional[str] create_time: Optional[datetime] @@ -90,6 +95,7 @@ class DailyQuery(BaseModel): daily_time: Optional[List[Union[int, None]]] create_time: Optional[List[Union[int, None]]] update_time: Optional[List[Union[int, None]]] + sub_type: Optional[str] page_size: Optional[int] page: Optional[int] @@ -109,6 +115,7 @@ class DailyAddReq(BaseModel): content: Optional[str] post: Optional[int] daily_time: Optional[datetime] + sub_type: Optional[str] file_md: Optional[str] title: Optional[str] diff --git a/Schemas/UserSchemas.py b/Schemas/UserSchemas.py index fd638ba..2b15bb1 100644 --- a/Schemas/UserSchemas.py +++ b/Schemas/UserSchemas.py @@ -36,6 +36,7 @@ class DepartmentInfo(BaseModel): belong: Optional[int] name: str type: Optional[DepartmentTypeEnum] + sub_type:Optional[str] class PostInfo(BaseModel): diff --git a/Utils/AuthUtils.py b/Utils/AuthUtils.py index 4d02725..3054623 100644 --- a/Utils/AuthUtils.py +++ b/Utils/AuthUtils.py @@ -9,7 +9,7 @@ SECRET_KEY = "MADASDZXC255f" ALGORITHM = "HS256" -def create_token(data: dict, secret_key=SECRET_KEY, algorithm=ALGORITHM, expires_delta: timedelta = timedelta(days=3)): +def create_token(data: dict, secret_key=SECRET_KEY, algorithm=ALGORITHM, expires_delta: timedelta = timedelta(days=7)): # 设置加密数据 to_encode_body = dict() to_encode_body.update(data.copy()) @@ -32,7 +32,7 @@ class Token: ALGORITHM = ALGORITHM @classmethod - def create_token(cls, data: dict, expires_delta: timedelta = timedelta(days=3)): + def create_token(cls, data: dict, expires_delta: timedelta = timedelta(days=7)): return create_token(data, cls.SECRET_KEY, cls.ALGORITHM, expires_delta) @classmethod diff --git a/main.py b/main.py index 615e75b..a20e5a9 100644 --- a/main.py +++ b/main.py @@ -5,7 +5,8 @@ from fastapi.exceptions import RequestValidationError from fastapi.middleware.cors import CORSMiddleware from Config.log import uvicorn_log_config -from Router import UserRouter, DailyRouter, AuthRouter, FileRouter +from Mods.Notice.Utils import daily_notice +from Router import DailyRouter, UserRouter, AuthRouter, FileRouter from Utils.MiddlewareUtils import exception_handler, validation_exception_handler from Utils.SqlAlchemyUtils import init_database, get_db_i from fastapi.staticfiles import StaticFiles @@ -39,6 +40,6 @@ app.include_router(ModsRouter.router) # 中间件 # app.exception_handler(Exception)(exception_handler) # app.exception_handler(RequestValidationError)(validation_exception_handler) - +daily_notice.init() uvicorn.run(app=app, host="0.0.0.0", port=8006, log_config=uvicorn_log_config)