diff --git a/.gitignore b/.gitignore index eb98c7b..94ad668 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ /jurigged/ /venv/ -/static_data/ \ No newline at end of file +/static_data/ +/run.ps1 +/.idea/* diff --git a/Config/word_day.json b/Config/word_day.json new file mode 100644 index 0000000..99ed928 --- /dev/null +++ b/Config/word_day.json @@ -0,0 +1,257 @@ +{ + "code": 0, + "holiday": { + "01-01": { + "holiday": true, + "name": "元旦", + "wage": 3, + "date": "2023-01-01", + "rest": 1 + }, + "01-02": { + "holiday": true, + "name": "元旦", + "wage": 2, + "date": "2023-01-02", + "rest": 1 + }, + "01-21": { + "holiday": true, + "name": "除夕", + "wage": 3, + "date": "2023-01-21", + "rest": 1 + }, + "01-22": { + "holiday": true, + "name": "初一", + "wage": 3, + "date": "2023-01-22", + "rest": 1 + }, + "01-23": { + "holiday": true, + "name": "初二", + "wage": 3, + "date": "2023-01-23", + "rest": 1 + }, + "01-24": { + "holiday": true, + "name": "初三", + "wage": 3, + "date": "2023-01-24", + "rest": 1 + }, + "01-25": { + "holiday": true, + "name": "初四", + "wage": 2, + "date": "2023-01-25", + "rest": 1 + }, + "01-26": { + "holiday": true, + "name": "初五", + "wage": 2, + "date": "2023-01-26", + "rest": 1 + }, + "01-27": { + "holiday": true, + "name": "初六", + "wage": 2, + "date": "2023-01-27", + "rest": 1 + }, + "01-28": { + "holiday": false, + "name": "春节后补班", + "wage": 1, + "after": true, + "target": "春节", + "date": "2023-01-28", + "rest": 1 + }, + "01-29": { + "holiday": false, + "name": "春节后补班", + "wage": 1, + "after": true, + "target": "春节", + "date": "2023-01-29", + "rest": 1 + }, + "04-05": { + "holiday": true, + "name": "清明节", + "wage": 3, + "date": "2023-04-05", + "rest": 16 + }, + "04-23": { + "holiday": false, + "name": "劳动节前补班", + "wage": 1, + "target": "劳动节", + "after": false, + "date": "2023-04-23", + "rest": 3 + }, + "04-29": { + "holiday": true, + "name": "劳动节", + "wage": 2, + "date": "2023-04-29", + "rest": 9 + }, + "04-30": { + "holiday": true, + "name": "劳动节", + "wage": 2, + "date": "2023-04-30", + "rest": 1 + }, + "05-01": { + "holiday": true, + "name": "劳动节", + "wage": 3, + "date": "2023-05-01", + "rest": 1 + }, + "05-02": { + "holiday": true, + "name": "劳动节", + "wage": 3, + "date": "2023-05-02", + "rest": 1 + }, + "05-03": { + "holiday": true, + "name": "劳动节", + "wage": 3, + "date": "2023-05-03", + "rest": 1 + }, + "05-06": { + "holiday": false, + "name": "劳动节后补班", + "after": true, + "wage": 1, + "target": "劳动节", + "date": "2023-05-06", + "rest": 2 + }, + "06-22": { + "holiday": true, + "name": "端午节", + "wage": 3, + "date": "2023-06-22", + "rest": 34 + }, + "06-23": { + "holiday": true, + "name": "端午节", + "wage": 3, + "date": "2023-06-23", + "rest": 1 + }, + "06-24": { + "holiday": true, + "name": "端午节", + "wage": 2, + "date": "2023-06-24", + "rest": 1 + }, + "06-25": { + "holiday": false, + "name": "端午节后补班", + "wage": 1, + "target": "端午节", + "after": true, + "date": "2023-06-25", + "rest": 1 + }, + "09-29": { + "holiday": true, + "name": "中秋节", + "wage": 3, + "date": "2023-09-29", + "rest": 94 + }, + "09-30": { + "holiday": true, + "name": "中秋节", + "wage": 3, + "date": "2023-09-30", + "rest": 1 + }, + "10-01": { + "holiday": true, + "name": "国庆节", + "wage": 3, + "date": "2023-10-01", + "rest": 1 + }, + "10-02": { + "holiday": true, + "name": "国庆节", + "wage": 3, + "date": "2023-10-02", + "rest": 1 + }, + "10-03": { + "holiday": true, + "name": "国庆节", + "wage": 2, + "date": "2023-10-03", + "rest": 1 + }, + "10-04": { + "holiday": true, + "name": "国庆节", + "wage": 2, + "date": "2023-10-04", + "rest": 1 + }, + "10-05": { + "holiday": true, + "name": "国庆节", + "wage": 2, + "date": "2023-10-05", + "rest": 1 + }, + "10-06": { + "holiday": true, + "name": "国庆节", + "wage": 2, + "date": "2023-10-06", + "rest": 1 + }, + "10-07": { + "holiday": false, + "after": true, + "wage": 1, + "name": "国庆节后补班", + "target": "国庆节", + "date": "2023-10-07", + "rest": 1 + }, + "10-08": { + "holiday": false, + "after": true, + "wage": 1, + "name": "国庆节后补班", + "target": "国庆节", + "date": "2023-10-08", + "rest": 1 + }, + "12-31": { + "holiday": true, + "name": "元旦", + "wage": 2, + "date": "2023-12-31", + "rest": 85 + } + } +} \ No newline at end of file diff --git a/Config/节假日接口.txt b/Config/节假日接口.txt new file mode 100644 index 0000000..cd1410c --- /dev/null +++ b/Config/节假日接口.txt @@ -0,0 +1 @@ +http://timor.tech/api/holiday/year/2023/ \ No newline at end of file diff --git a/Models/DailyModel.py b/Models/DailyModel.py index f4a7976..7b97166 100644 --- a/Models/DailyModel.py +++ b/Models/DailyModel.py @@ -18,6 +18,7 @@ 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) 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/Mods/Comment/Crud.py b/Mods/Comment/Crud.py new file mode 100644 index 0000000..de40dd6 --- /dev/null +++ b/Mods/Comment/Crud.py @@ -0,0 +1,57 @@ +from sqlalchemy.orm import Session +from . import Schemas +from .Models import Comment + + +def comment_add(db: Session, data: Schemas.CommentAddInfo): + item = Comment(**data.dict()) + db.add(item) + db.commit() + db.refresh(item) + return item + + +def comment_delete(db: Session, item_id: int): + db.query(Comment).filter_by(id=item_id).delete() + db.commit() + + +def comment_update(db: Session, data: Schemas.CommentUpdateInfo): + db.query(Comment).filter_by(id=data.id).update({key: v for key, v in data.dict().items() if v is not None}) + db.commit() + item = db.query(Comment).filter_by(id=data.id).first() + return item + + +def comment_get(db: Session, item_id: int): + item = db.query(Comment).filter_by(id=item_id).first() + return item + + +def comment_query(db: Session, params: Schemas.CommentQuery): + params_dict = params.dict() + query = db.query(Comment) + db_model = Comment + for key, value in params_dict.items(): + if key not in ['page', 'page_size'] and value is not None: + if type(value) == str: + query = query.filter(getattr(db_model, key).like(f'%{value}%')) + elif type(value) in [int, float, bool]: + query = query.filter_by(**{key: value}) + else: + query = query.filter(getattr(db_model, key) == value) + count = query.count() + page = None + page_size = None + if 'page' in params_dict: + page = params_dict['page'] + if 'page_size' in params_dict: + page_size = params_dict['page_size'] + # 页数不超过100 + if page is not None and page_size is not None: + page_size = min(page_size, 100) + query = query.offset((page - 1) * page_size).limit(page_size).all() + return count, query + + +################ \ No newline at end of file diff --git a/Mods/Comment/Models.py b/Mods/Comment/Models.py new file mode 100644 index 0000000..afd1da9 --- /dev/null +++ b/Mods/Comment/Models.py @@ -0,0 +1,38 @@ +from sqlalchemy.orm import relationship + +from sqlalchemy import Column, Integer, String, ForeignKey, Text, DateTime, func, Date, Double +from Utils.SqlAlchemyUtils import get_db, Base + + +class Comment(Base): + """ + 评论表 + """ + __tablename__ = "comment" + + id = Column(Integer, primary_key=True) + content = Column(Text) + daily_id = Column(Integer, ForeignKey('daily.id', ondelete='CASCADE')) + daily = relationship('Daily', back_populates='comments') + user_email = Column(String(255), ForeignKey('user.email', ondelete='CASCADE')) + user = relationship('User', backref='comments') + create_time = Column(DateTime, server_default=func.now(), comment='创建时间') + + def to_dict(self, full=False): + data = {} + for c in self.__table__.columns: + data[c.name] = getattr(self, c.name) + if full: + if self.user: + data['user'] = self.user.to_dict() + if self.user: + data['daily'] = self.daily.to_dict() + return data + + def to_with_user_dict(self): + data = {} + for c in self.__table__.columns: + data[c.name] = getattr(self, c.name) + if self.user: + data['user'] = self.user.to_dict() + return data diff --git a/Mods/Comment/Router.py b/Mods/Comment/Router.py new file mode 100644 index 0000000..00f71dc --- /dev/null +++ b/Mods/Comment/Router.py @@ -0,0 +1,52 @@ +from fastapi import APIRouter, Depends, HTTPException +from sqlalchemy.orm import Session +from Utils.SqlAlchemyUtils import get_db, Base +from . import Schemas +from . import Crud +from Utils.SqlAlchemyUtils import QueryParams, query_common +from .Models import Comment + +router = APIRouter(tags=["评论"]) + + +@router.post("/comment/add", summary="添加评论", response_model=Schemas.CommentAddRes) +def comment_add(req: Schemas.CommentAddReq, db: Session = Depends(get_db)): + item = Crud.comment_add(db, req) + return Schemas.CommentAddRes(**item.to_dict()) + + +@router.post("/comment/delete", summary="删除评论") +def comment_delete(req: Schemas.CommentDeleteReq, db: Session = Depends(get_db)): + Crud.comment_delete(db, req.id) + return "删除成功" + + +@router.post("/comment/update", summary="更新评论", response_model=Schemas.CommentUpdateRes) +def comment_update(req: Schemas.CommentUpdateReq, db: Session = Depends(get_db)): + item = Crud.comment_update(db, req) + return Schemas.CommentUpdateRes(**item.to_dict()) + + +@router.post("/comment/get", summary="获取评论", response_model=Schemas.CommentGetRes) +def comment_get(req: Schemas.CommentGetReq, db: Session = Depends(get_db)): + item = Crud.comment_get(db, req.id) + if not item: + raise HTTPException(detail="未查询到信息", status_code=404) + return Schemas.CommentGetRes(**item.to_dict(full=True)) + + +@router.post("/comment/query", summary="查询评论", response_model=Schemas.CommentQueryRes) +def comment_query(req: Schemas.CommentQueryReq, db: Session = Depends(get_db)): + count, query = Crud.comment_query(db, req) + items = [Schemas.CommentInfo(**item.to_dict()) for item in query] + return Schemas.CommentQueryRes(count=count, items=items) + + +@router.post("/comment/query_common", summary="通用查询评论", + response_model=Schemas.CommentQueryRes) +def comment_query_common(req: QueryParams, db: Session = Depends(get_db)): + count, query = query_common(db, Comment, req) + items = [Schemas.CommentInfo(**item.to_dict()) for item in query] + return Schemas.CommentQueryRes(count=count, items=items) + +######### diff --git a/Mods/Comment/Schemas.py b/Mods/Comment/Schemas.py new file mode 100644 index 0000000..f07c285 --- /dev/null +++ b/Mods/Comment/Schemas.py @@ -0,0 +1,70 @@ +from datetime import datetime, date +from pydantic import BaseModel +from typing import Optional, List +from Schemas.DailySchemas import DailyInfo +from Schemas.UserSchemas import UserInfo + + +class CommentInfo(BaseModel): + id: Optional[int] + daily_id: Optional[int] + user_email: Optional[str] + daily: Optional[DailyInfo] + content: Optional[str] + user: Optional[UserInfo] + create_time: Optional[datetime] + + +class CommentAddInfo(BaseModel): + daily_id: Optional[int] + user_email: Optional[str] + content: Optional[str] + + +class CommentAddReq(CommentAddInfo): + pass + + +class CommentAddRes(CommentInfo): + pass + + +class CommentUpdateInfo(CommentInfo): + pass + + +class CommentUpdateReq(CommentUpdateInfo): + pass + + +class CommentUpdateRes(CommentInfo): + pass + + +class CommentQuery(CommentInfo): + page: Optional[int] + page_size: Optional[int] + pass + + +class CommentQueryReq(CommentQuery): + pass + + +class CommentGetReq(BaseModel): + id: int + + +class CommentGetRes(CommentInfo): + pass + + +class CommentQueryRes(BaseModel): + count: int + items: List[CommentInfo] + + +class CommentDeleteReq(BaseModel): + id: int + +####################### diff --git a/Mods/Router.py b/Mods/Router.py index 241405c..d476fbc 100644 --- a/Mods/Router.py +++ b/Mods/Router.py @@ -1,7 +1,9 @@ from fastapi import APIRouter, Depends, HTTPException from .Finance import Router as FinanceRouter from .RevenueType import Router as RevenueTypeRouter +from .Comment import Router as CommentRouter router = APIRouter(prefix="/api/daily/daily") router.include_router(FinanceRouter.router) router.include_router(RevenueTypeRouter.router) +router.include_router(CommentRouter.router) diff --git a/Router/DailyRouter.py b/Router/DailyRouter.py index 533f969..03d56d3 100644 --- a/Router/DailyRouter.py +++ b/Router/DailyRouter.py @@ -20,7 +20,9 @@ import pandas as pd router = APIRouter( tags=["日报"], prefix="/api/daily/daily", - dependencies=[Depends(registered_depend)] + dependencies=[ + Depends(registered_depend) + ] ) @@ -31,11 +33,13 @@ router = APIRouter( @router.post("/daily_get", response_model=DailySchemas.DailyGetRes, summary="获取日报") def daily_get(req: DailySchemas.DailyGetReq, db: Session = Depends(get_db), - token_data: TokenData = Depends(registered_depend)): + # token_data: TokenData = Depends(registered_depend) + ): item = DailyCrud.daily_get(db, req.id) + comments = [DailySchemas.CommentInfo(**comment.to_with_user_dict()) for comment in item.comments] if not item: raise HTTPException(detail="未取到信息") - return DailySchemas.DailyGetRes(**item.to_dict()) + return DailySchemas.DailyGetRes(**item.to_dict(), comments=comments) @router.post("/daily_add", response_model=DailySchemas.DailyAddRes, summary="添加日报") diff --git a/Schemas/DailySchemas.py b/Schemas/DailySchemas.py index 1f4d95f..b986b9e 100644 --- a/Schemas/DailySchemas.py +++ b/Schemas/DailySchemas.py @@ -18,6 +18,15 @@ class DailyTypeEnum(Enum): 动态 = "动态" +class CommentInfo(BaseModel): + id: Optional[int] + daily_id: Optional[int] + user_email: Optional[str] + content: Optional[str] + user: Optional[UserInfo] + create_time: Optional[datetime] + + class DailyInfo(BaseModel): id: Optional[int] type: Optional[DailyTypeEnum] @@ -30,6 +39,7 @@ class DailyInfo(BaseModel): post: Optional[int] content: Optional[str] file_md: Optional[str] + comments: Optional[List[CommentInfo]] daily_time: Optional[datetime] create_time: Optional[datetime] update_time: Optional[datetime] diff --git a/Utils/TimeUtils.py b/Utils/TimeUtils.py new file mode 100644 index 0000000..81e8b4c --- /dev/null +++ b/Utils/TimeUtils.py @@ -0,0 +1,14 @@ +from datetime import datetime + +import requests +import json + + +def is_workday(): + today = datetime.now().strftime("%Y-%m-%d") + response = requests.get(f'https://timor.tech/api/holiday/info/{today}') + data = response.json() + print(data) + + +is_workday() \ No newline at end of file