添加部门二级分类
This commit is contained in:
parent
4c23c2c6f2
commit
600aebf8cf
|
@ -110,3 +110,12 @@ def get_user_by_department_type(db: Session, department_type: str):
|
||||||
|
|
||||||
def get_department_list(db: Session):
|
def get_department_list(db: Session):
|
||||||
return db.query(Department).all()
|
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
|
||||||
|
|
|
@ -2,6 +2,7 @@ from sqlalchemy import Column, String, Boolean, Enum, Text, DateTime, func, Inte
|
||||||
from sqlalchemy.orm import relationship
|
from sqlalchemy.orm import relationship
|
||||||
from Utils.SqlAlchemyUtils import Base
|
from Utils.SqlAlchemyUtils import Base
|
||||||
from Schemas.DailySchemas import DailyTypeEnum
|
from Schemas.DailySchemas import DailyTypeEnum
|
||||||
|
from Mods.Comment.Models import Comment
|
||||||
|
|
||||||
|
|
||||||
class Daily(Base):
|
class Daily(Base):
|
||||||
|
@ -18,7 +19,8 @@ class Daily(Base):
|
||||||
file_md = Column(String(255), comment="附加文件")
|
file_md = Column(String(255), comment="附加文件")
|
||||||
required_auth = Column(Text, comment="日报权限")
|
required_auth = Column(Text, comment="日报权限")
|
||||||
sign_name = Column(String(128), 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='日报时间')
|
daily_time = Column(DateTime, server_default=func.now(), comment='日报时间')
|
||||||
create_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='修改时间')
|
update_time = Column(DateTime, server_default=func.now(), onupdate=func.now(), comment='修改时间')
|
||||||
|
|
|
@ -11,6 +11,7 @@ class Department(Base):
|
||||||
belong = Column(Integer, comment="上级部门")
|
belong = Column(Integer, comment="上级部门")
|
||||||
auth_data = Column(Text, comment="部门权限数据")
|
auth_data = Column(Text, comment="部门权限数据")
|
||||||
type = Column(Enum(DepartmentTypeEnum, values_callable=lambda x: [e.value for e in x]), nullable=False)
|
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):
|
def to_dict(self):
|
||||||
return {c.name: getattr(self, c.name) for c in self.__table__.columns}
|
return {c.name: getattr(self, c.name) for c in self.__table__.columns}
|
||||||
|
|
|
@ -5,7 +5,7 @@ from . import Schemas
|
||||||
from . import Crud
|
from . import Crud
|
||||||
from Utils.SqlAlchemyUtils import QueryParams, query_common
|
from Utils.SqlAlchemyUtils import QueryParams, query_common
|
||||||
from .Models import Comment
|
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=["评论"])
|
router = APIRouter(tags=["评论"])
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ def comment_add(req: Schemas.CommentAddReq, db: Session = Depends(get_db)):
|
||||||
comment_content=comment.content
|
comment_content=comment.content
|
||||||
)
|
)
|
||||||
"".format()
|
"".format()
|
||||||
DailyNotice.notice_comment(notice_user.email, send)
|
daily_notice.notice_comment(notice_user.email, send)
|
||||||
return comment
|
return comment
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,14 +2,15 @@ import threading
|
||||||
import time
|
import time
|
||||||
from concurrent.futures import ThreadPoolExecutor
|
from concurrent.futures import ThreadPoolExecutor
|
||||||
|
|
||||||
from sqlalchemy import func, or_
|
from sqlalchemy import func, or_, cast, DATE
|
||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
|
|
||||||
|
from Models.DailyModel import Daily
|
||||||
from Models.DepartmentModel import Department
|
from Models.DepartmentModel import Department
|
||||||
from Models.UserModel import User
|
from Models.UserModel import User
|
||||||
from Utils.EmailUtils import send_email
|
from Utils.EmailUtils import send_email
|
||||||
from Utils.SqlAlchemyUtils import get_db, get_db_i
|
from Utils.SqlAlchemyUtils import get_db, get_db_i
|
||||||
from datetime import datetime
|
from datetime import datetime, date
|
||||||
|
|
||||||
comment_notice_send = """您的日报:
|
comment_notice_send = """您的日报:
|
||||||
【{daily_type}-{daily_name}】
|
【{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}
|
'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():
|
def is_workday():
|
||||||
"""
|
"""
|
||||||
返回当天是否上班
|
返回当天是否上班
|
||||||
|
@ -46,27 +60,25 @@ def is_workday():
|
||||||
|
|
||||||
|
|
||||||
class DailyNotice:
|
class DailyNotice:
|
||||||
@staticmethod
|
def __init__(self, email_send_func=send_email):
|
||||||
def notification_daily_report_filling():
|
self.email_send_func = email_send_func
|
||||||
"""
|
pass
|
||||||
日报通知
|
|
||||||
每日三点通知未填写日报的部门进行日报填报
|
|
||||||
1.判断是否是工作日
|
|
||||||
2.判断哪些部门没有日报内容
|
|
||||||
2.通知部门的指定人员?还是所有人员?
|
|
||||||
:return:
|
|
||||||
"""
|
|
||||||
|
|
||||||
@staticmethod
|
def send_email(self, title, email, content):
|
||||||
def notice_comment(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:
|
:return:
|
||||||
"""
|
"""
|
||||||
send_email('日报反馈', email, content)
|
return self.send_email('日报反馈', email, content)
|
||||||
|
|
||||||
@staticmethod
|
def send_on_daily_pdf_upload(self):
|
||||||
def send_on_daily_pdf_upload():
|
|
||||||
"""
|
"""
|
||||||
每日日报上传后的通知
|
每日日报上传后的通知
|
||||||
:return:
|
:return:
|
||||||
|
@ -82,28 +94,38 @@ class DailyNotice:
|
||||||
can_watch_departments])):
|
can_watch_departments])):
|
||||||
emails.append(user.email)
|
emails.append(user.email)
|
||||||
|
|
||||||
with ThreadPoolExecutor(max_workers=8) as executor:
|
with ThreadPoolExecutor(max_workers=5) as executor:
|
||||||
for i in range(2):
|
# for email in emails:
|
||||||
pass
|
# executor.submit(self.send_email, "每日运行日报已上传", email, '每日运行日报已上传')
|
||||||
# executor.submit(send_email, "每日运行日报已上传", 'wangsichuan@fecr.com.cn', '每日运行日报已上传')
|
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
|
sended = False
|
||||||
while True:
|
while True:
|
||||||
time.sleep(60)
|
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
|
sended = True
|
||||||
try:
|
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", "填报提醒")
|
send_email('日报填报提醒', "fecribd@fecr.com.cn", "填报提醒")
|
||||||
print("邮件发送了")
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(e, 'start_timer_to_notice_daily_fill错误')
|
print(e, 'start_timer_to_notice_daily_fill错误')
|
||||||
|
|
||||||
if datetime.now().hour > 15:
|
if datetime.now().hour > 15:
|
||||||
sended = False
|
sended = False
|
||||||
|
|
||||||
threading.Thread(target=DailyNotice.start_timer_to_notice_daily_fill).start()
|
def email_send_thread(self, args_list, sem=5):
|
||||||
# DailyNotice.start_timer_to_notice_daily_fill()
|
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()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ from sqlalchemy.orm import Session
|
||||||
from starlette.responses import FileResponse
|
from starlette.responses import FileResponse
|
||||||
|
|
||||||
from Models.DepartmentModel import Department
|
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.DailySchemas import DailyTypeEnum
|
||||||
from Schemas.UserSchemas import TokenData
|
from Schemas.UserSchemas import TokenData
|
||||||
from Utils.AuthUtils import token_data_depend, check_auth, registered_depend
|
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)
|
# raise HTTPException(detail="没有本部门填报权限", status_code=305)
|
||||||
new_daily = DailyCrud.daily_add(db, req.dict())
|
new_daily = DailyCrud.daily_add(db, req.dict())
|
||||||
if req.type == DailyTypeEnum.运行日报:
|
if req.type == DailyTypeEnum.运行日报:
|
||||||
DailyNotice.send_on_daily_pdf_upload()
|
daily_notice.send_on_daily_pdf_upload()
|
||||||
return DailySchemas.DailyAddRes(**new_daily.to_dict())
|
return DailySchemas.DailyAddRes(**new_daily.to_dict())
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -16,8 +16,11 @@ class DailyTypeEnum(Enum):
|
||||||
# 经营情况 = "经营情况"
|
# 经营情况 = "经营情况"
|
||||||
财务营收 = "财务营收"
|
财务营收 = "财务营收"
|
||||||
动态 = "动态"
|
动态 = "动态"
|
||||||
|
|
||||||
|
|
||||||
class DailyExportToPdfReq(BaseModel):
|
class DailyExportToPdfReq(BaseModel):
|
||||||
day:date
|
day: date
|
||||||
|
|
||||||
|
|
||||||
class CommentInfo(BaseModel):
|
class CommentInfo(BaseModel):
|
||||||
id: Optional[int]
|
id: Optional[int]
|
||||||
|
@ -40,6 +43,7 @@ class DailyInfo(BaseModel):
|
||||||
post: Optional[int]
|
post: Optional[int]
|
||||||
content: Optional[str]
|
content: Optional[str]
|
||||||
file_md: Optional[str]
|
file_md: Optional[str]
|
||||||
|
sub_type: Optional[str]
|
||||||
comments: Optional[List[CommentInfo]]
|
comments: Optional[List[CommentInfo]]
|
||||||
daily_time: Optional[datetime]
|
daily_time: Optional[datetime]
|
||||||
create_time: Optional[datetime]
|
create_time: Optional[datetime]
|
||||||
|
@ -65,6 +69,7 @@ class DailyChangeReq(BaseModel):
|
||||||
required_auth: Optional[str]
|
required_auth: Optional[str]
|
||||||
post: Optional[int]
|
post: Optional[int]
|
||||||
content: Optional[str]
|
content: Optional[str]
|
||||||
|
sub_type: Optional[str]
|
||||||
daily_time: Optional[datetime]
|
daily_time: Optional[datetime]
|
||||||
file_md: Optional[str]
|
file_md: Optional[str]
|
||||||
create_time: Optional[datetime]
|
create_time: Optional[datetime]
|
||||||
|
@ -90,6 +95,7 @@ class DailyQuery(BaseModel):
|
||||||
daily_time: Optional[List[Union[int, None]]]
|
daily_time: Optional[List[Union[int, None]]]
|
||||||
create_time: Optional[List[Union[int, None]]]
|
create_time: Optional[List[Union[int, None]]]
|
||||||
update_time: Optional[List[Union[int, None]]]
|
update_time: Optional[List[Union[int, None]]]
|
||||||
|
sub_type: Optional[str]
|
||||||
page_size: Optional[int]
|
page_size: Optional[int]
|
||||||
page: Optional[int]
|
page: Optional[int]
|
||||||
|
|
||||||
|
@ -109,6 +115,7 @@ class DailyAddReq(BaseModel):
|
||||||
content: Optional[str]
|
content: Optional[str]
|
||||||
post: Optional[int]
|
post: Optional[int]
|
||||||
daily_time: Optional[datetime]
|
daily_time: Optional[datetime]
|
||||||
|
sub_type: Optional[str]
|
||||||
file_md: Optional[str]
|
file_md: Optional[str]
|
||||||
title: Optional[str]
|
title: Optional[str]
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,7 @@ class DepartmentInfo(BaseModel):
|
||||||
belong: Optional[int]
|
belong: Optional[int]
|
||||||
name: str
|
name: str
|
||||||
type: Optional[DepartmentTypeEnum]
|
type: Optional[DepartmentTypeEnum]
|
||||||
|
sub_type:Optional[str]
|
||||||
|
|
||||||
|
|
||||||
class PostInfo(BaseModel):
|
class PostInfo(BaseModel):
|
||||||
|
|
|
@ -9,7 +9,7 @@ SECRET_KEY = "MADASDZXC255f"
|
||||||
ALGORITHM = "HS256"
|
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 = dict()
|
||||||
to_encode_body.update(data.copy())
|
to_encode_body.update(data.copy())
|
||||||
|
@ -32,7 +32,7 @@ class Token:
|
||||||
ALGORITHM = ALGORITHM
|
ALGORITHM = ALGORITHM
|
||||||
|
|
||||||
@classmethod
|
@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)
|
return create_token(data, cls.SECRET_KEY, cls.ALGORITHM, expires_delta)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|
5
main.py
5
main.py
|
@ -5,7 +5,8 @@ from fastapi.exceptions import RequestValidationError
|
||||||
from fastapi.middleware.cors import CORSMiddleware
|
from fastapi.middleware.cors import CORSMiddleware
|
||||||
|
|
||||||
from Config.log import uvicorn_log_config
|
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.MiddlewareUtils import exception_handler, validation_exception_handler
|
||||||
from Utils.SqlAlchemyUtils import init_database, get_db_i
|
from Utils.SqlAlchemyUtils import init_database, get_db_i
|
||||||
from fastapi.staticfiles import StaticFiles
|
from fastapi.staticfiles import StaticFiles
|
||||||
|
@ -39,6 +40,6 @@ app.include_router(ModsRouter.router)
|
||||||
# 中间件
|
# 中间件
|
||||||
# app.exception_handler(Exception)(exception_handler)
|
# app.exception_handler(Exception)(exception_handler)
|
||||||
# app.exception_handler(RequestValidationError)(validation_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)
|
uvicorn.run(app=app, host="0.0.0.0", port=8006, log_config=uvicorn_log_config)
|
||||||
|
|
Loading…
Reference in New Issue