Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
feat: 新增MCP服务器和客户端功能,支持AI工具调用和天气查询
refactor: 重构基础模型和响应类,增加success字段

fix: 修复定时任务日志记录和异常处理问题

style: 调整中间件日志记录逻辑,优化参数处理

docs: 更新数据库配置和依赖项说明

perf: 优化文件上传服务,支持OSS存储

test: 添加定时任务日志模型和参数验证

chore: 更新依赖项,添加openai库支持
  • Loading branch information
zhangtao
zhangtao committed Aug 30, 2025
commit ecec6ceadb50fbe6f392bf9a805b0d9c7fd95a4a
4 changes: 2 additions & 2 deletions backend/app/api/v1/controllers/common/file_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from app.core.router_class import OperationLogRoute
from app.core.logger import logger
from app.api.v1.services.common.file_service import FileService
from app.common.response import SuccessResponse, CustomFileResponse
from app.common.response import SuccessResponse, UploadFileResponse

router = APIRouter(route_class=OperationLogRoute)

Expand All @@ -27,4 +27,4 @@ async def download_controller(
) -> FileResponse:
result = await FileService.download_service(file_path=file_path)
logger.info(f"下载文件成功")
return CustomFileResponse(file_path=result.file_path, file_name=result.file_name)
return UploadFileResponse(file_path=result.file_path, file_name=result.file_name)
28 changes: 26 additions & 2 deletions backend/app/api/v1/cruds/monitor/job_crud.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
from typing import Dict, List, Optional, Sequence

from app.core.base_crud import CRUDBase
from app.api.v1.models.monitor.job_model import JobModel
from app.api.v1.schemas.monitor.job_schema import JobCreateSchema,JobUpdateSchema
from app.api.v1.models.monitor.job_model import JobModel, JobLogModel
from app.api.v1.schemas.monitor.job_schema import JobCreateSchema,JobUpdateSchema,JobLogCreateSchema,JobLogUpdateSchema
from app.api.v1.schemas.system.auth_schema import AuthSchema


Expand Down Expand Up @@ -44,3 +44,27 @@ async def clear_obj_crud(self) -> None:
"""清除定时任务日志"""
return await self.clear()


class JobLogCRUD(CRUDBase[JobLogModel, JobLogCreateSchema, JobLogUpdateSchema]):
"""定时任务日志数据层"""

def __init__(self, auth: AuthSchema) -> None:
"""初始化定时任务日志CRUD"""
self.auth = auth
super().__init__(model=JobLogModel, auth=auth)

async def get_obj_log_by_id_crud(self, id: int) -> Optional[JobLogModel]:
"""获取定时任务日志详情"""
return await self.get(id=id)

async def get_obj_log_list_crud(self, search: Dict = None, order_by: List[Dict[str, str]] = None) -> Sequence[JobLogModel]:
"""获取定时任务日志列表"""
return await self.list(search=search, order_by=order_by)

async def create_obj_log_crud(self, data: JobLogCreateSchema) -> Optional[JobLogModel]:
"""创建定时任务日志"""
return await self.create(data=data)

async def delete_obj_log_crud(self, ids: List[int]) -> None:
"""删除定时任务日志"""
return await self.delete(ids=ids)
18 changes: 18 additions & 0 deletions backend/app/api/v1/models/gen_code/form_data_model.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# -*- coding:utf-8 -*-

from sqlalchemy import Boolean, Column, ForeignKey, String, Integer, Text, DateTime
from sqlalchemy.orm import relationship

from app.core.base_model import BaseMixin


class FormData(BaseMixin):
__tablename__ = "gen_form_data"

form_data = Column(Text, nullable=False, comment='表单数据')

form_id = Column(Integer, ForeignKey(SysForm.id), nullable=False, comment='表单ID')

form_name = Column(String(255), nullable=False, comment='表单名称')


22 changes: 22 additions & 0 deletions backend/app/api/v1/models/gen_code/form_model.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# -*- coding:utf-8 -*-

from sqlalchemy import Boolean, Column, ForeignKey, String, Integer, Text, DateTime

from app.core.base_model import BaseMixin


class FormModel(BaseMixin):
__tablename__ = "gen_form"

content = Column(Text, nullable=False, comment='表单代码')

form_conf = Column(Text, nullable=False, comment='表单配置')

form_data = Column(Text, nullable=False, comment='表单内容')

generate_conf = Column(Text, nullable=False, comment='生成配置')

name = Column(String(255), nullable=False, comment='表单名称')

drawing_list = Column(Text, nullable=False, comment='字段列表')

15 changes: 15 additions & 0 deletions backend/app/api/v1/models/gen_code/page_model.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# -*- coding:utf-8 -*-

from sqlalchemy import Boolean, Column, ForeignKey, String, Integer, Text, DateTime

from app.core.base_model import BaseMixin

class PageModel(BaseMixin):
__tablename__ = "gen_page"

page_name = Column(String(length=255), comment='页面名称')

keywords = Column(String(length=500), comment='页面关键词')

title = Column(String(length=500), comment='页面title标题')

44 changes: 44 additions & 0 deletions backend/app/api/v1/models/gen_code/table_model.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# -*- coding:utf-8 -*-
import datetime

from sqlalchemy import Boolean, Column, ForeignKey, String, Integer, Text, DateTime

from app.core.base_model import BaseMixin


class SysTable(BaseMixin):
__tablename__ = "gen_table"

id = Column(Integer, primary_key=True, autoincrement=True)
create_time = Column(DateTime, nullable=False, default=datetime.datetime.now, comment='创建时间')
update_time = Column(DateTime, nullable=False, default=datetime.datetime.now, onupdate=datetime.datetime.now, index=True, comment='更新时间')
del_flag = Column(String(1), nullable=False, default='0', server_default=text("'0'"), comment='删除标志(0代表存在 2代表删除)')

align = Column(String(255), nullable=False, default='left', comment='对其方式')

field_name = Column(String(255), nullable=False, comment='字段名')

fixed = Column(String(1), nullable=False, default='0', comment='固定表头')

label = Column(String(255), nullable=False, comment='字段标签')

label_tip = Column(String(255), comment='字段标签解释')

prop = Column(String(255), nullable=False, comment='驼峰属性')

show = Column(String(1), nullable=False, default='1', comment='可见')

sortable = Column(String(1), nullable=False, default='0', comment='可排序')

table_name = Column(String(255), nullable=False, comment='表名')

tooltip = Column(String(1), nullable=False, default='1', comment='超出隐藏')

update_by = Column(Integer, comment='更新者')

update_by_name = Column(String(255), comment='更新者')

width = Column(Integer, nullable=False, default=150, comment='宽度')

sequence = Column(Integer, nullable=False, default=0, comment='字段顺序')

20 changes: 20 additions & 0 deletions backend/app/api/v1/models/monitor/job_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,23 @@ class JobModel(ModelBase):
uselist=False
)


class JobLogModel(Base):
"""
定时任务调度日志表
"""

__tablename__ = 'monitor_job_log'

job_log_id = Column(Integer, primary_key=True, autoincrement=True, comment='任务日志ID')
job_name = Column(String(64), nullable=False, comment='任务名称')
job_group = Column(String(64), nullable=False, comment='任务组名')
job_executor = Column(String(64), nullable=False, comment='任务执行器')
invoke_target = Column(String(500), nullable=False, comment='调用目标字符串')
job_args = Column(String(255), nullable=True, default='', comment='位置参数')
job_kwargs = Column(String(255), nullable=True, default='', comment='关键字参数')
job_trigger = Column(String(255), nullable=True, default='', comment='任务触发器')
job_message = Column(String(500), nullable=True, default='', comment='日志信息')
status = Column(Boolean, default=False, nullable=True, comment='任务状态:正常,失败')
exception_info = Column(String(2000), nullable=True, default='', comment='异常信息')
create_time = Column(DateTime, nullable=True, default=datetime.now(), comment='创建时间')
2 changes: 1 addition & 1 deletion backend/app/api/v1/models/system/dept_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class DeptModel(ModelBase):
id = Column(Integer, primary_key=True, autoincrement=True, comment='主键ID')
name = Column(String(40), nullable=False, comment="部门名称", unique=True)
order = Column(Integer, nullable=False, default=1, comment="显示排序")

# leader_id = Column(Integer, nullable=True, default=None, comment='负责人ID') # 部门领导绑定用户,作为后面的流程审批人
# 层级关系
parent_id = Column(
Integer,
Expand Down
21 changes: 20 additions & 1 deletion backend/app/api/v1/models/system/user_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,4 +116,23 @@ class UserModel(ModelBase):
foreign_keys=[creator_id],
lazy="selectin",
uselist=False
)
)

class UserWechat(Base, BaseMixin):

"""
用户微信信息
"""

__tablename__ = 'system_users_wechat'

user_id = Column(Integer, nullable=False, comment='用户ID')
city = Column(String(100), nullable=True, comment='城市')
country = Column(String(100), nullable=True, comment='国家')
head_img_url = Column(String(255), nullable=True, comment='微信头像')
nickname = Column(String(255), nullable=True, comment='微信昵称')
openid = Column(String(255), unique=True, nullable=False, comment='openid')
union_id = Column(String(255), nullable=False, comment='union_id')
user_phone = Column(String(15), unique=True, nullable=False, comment='手机号')
province = Column(String(255), nullable=True, comment='省份')
sex = Column(Integer, nullable=True, comment='性别')
20 changes: 20 additions & 0 deletions backend/app/api/v1/params/monitor/job_param.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,23 @@ def __init__(
start_datetime = datetime.strptime(str(start_time), '%Y-%m-%d %H:%M:%S')
end_datetime = datetime.strptime(str(end_time), '%Y-%m-%d %H:%M:%S')
self.created_at = ("between", (start_datetime, end_datetime))


class JobLogQueryParams:
"""定时任务查询参数"""

def __init__(
self,
status: Optional[bool] = Query(None, description="状态: 正常,失败"),
start_time: Optional[DateTimeStr] = Query(None, description="开始时间", example="2023-01-01 00:00:00"),
end_time: Optional[DateTimeStr] = Query(None, description="结束时间", example="2023-12-31 23:59:59"),
) -> None:
super().__init__()
# 精确查询字段
self.status = status

# 时间范围查询
if start_time and end_time:
start_datetime = datetime.strptime(str(start_time), '%Y-%m-%d %H:%M:%S')
end_datetime = datetime.strptime(str(end_time), '%Y-%m-%d %H:%M:%S')
self.created_at = ("between", (start_datetime, end_datetime))
31 changes: 31 additions & 0 deletions backend/app/api/v1/schemas/gen_code/form_data_schema.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# -*- coding:utf-8 -*-
from datetime import datetime
from pydantic import BaseModel, ConfigDict, Field
from pydantic.alias_generators import to_camel
from typing import List, Literal, Optional, Union
from module_admin.annotation.pydantic_annotation import as_query


class SysFormDataModel(BaseModel):
"""
表对应pydantic模型
"""
model_config = ConfigDict(alias_generator=to_camel, from_attributes=True)
create_by: Optional[int] = Field(default=None, description='创建者')
create_time: Optional[datetime] = Field(default=None, description='创建时间')
del_flag: Optional[str] = Field(default=None, description='删除标志')
dept_id: Optional[int] = Field(default=None, description='部门id')
form_data: Optional[str] = Field(default=None, description='表单数据')
form_id: Optional[int] = Field(default=None, description='表单ID')
form_name: Optional[str] = Field(default=None, description='表单名称')
id: Optional[int] = Field(default=None, description='id')
update_time: Optional[datetime] = Field(default=None, description='更新时间')


@as_query
class SysFormDataPageModel(SysFormDataModel):
"""
分页查询模型
"""
page_num: int = Field(default=1, description='当前页码')
page_size: int = Field(default=10, description='每页记录数')
58 changes: 58 additions & 0 deletions backend/app/api/v1/schemas/gen_code/form_schema.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# -*- coding:utf-8 -*-
from datetime import datetime
from pydantic import BaseModel, ConfigDict, Field
from pydantic.alias_generators import to_camel
from typing import List, Literal, Optional, Union
from module_admin.annotation.pydantic_annotation import as_query


class SysTableModel(BaseModel):
"""
表对应pydantic模型
"""
model_config = ConfigDict(alias_generator=to_camel, from_attributes=True)
align: Optional[str] = Field(default=None, description='对其方式')
create_time: Optional[datetime] = Field(default=None, description='创建时间')
del_flag: Optional[str] = Field(default=None, description='删除标志')
field_name: Optional[str] = Field(default=None, description='字段名')
fixed: Optional[str] = Field(default=None, description='固定表头')
id: Optional[int] = Field(default=None, description='ID')
label: Optional[str] = Field(default=None, description='字段标签')
label_tip: Optional[str] = Field(default=None, description='字段标签解释')
prop: Optional[str] = Field(default=None, description='驼峰属性')
show: Optional[str] = Field(default=None, description='可见')
sortable: Optional[str] = Field(default=None, description='可排序')
table_name: Optional[str] = Field(default=None, description='表名')
tooltip: Optional[str] = Field(default=None, description='超出隐藏')
update_by: Optional[int] = Field(default=None, description='更新者')
update_by_name: Optional[str] = Field(default=None, description='更新者')
update_time: Optional[datetime] = Field(default=None, description='更新时间')
width: Optional[int] = Field(default=None, description='宽度')
sequence: Optional[int] = Field(default=None, description='字段顺序')

@as_query
class SysTablePageModel(SysTableModel):
"""
分页查询模型
"""
page_num: int = Field(default=1, description='当前页码')
page_size: int = Field(default=10, description='每页记录数')


@as_query
class DbTablePageModel(BaseModel):
"""
分页查询模型
"""
model_config = ConfigDict(alias_generator=to_camel, from_attributes=True)
table_name: Optional[str] = Field(default=None, description='表名')
table_comment: Optional[str] = Field(default=None, description='表描述')
page_num: int = Field(default=1, description='当前页码')
page_size: int = Field(default=10, description='每页记录数')

class SysTableColumnIdsModel(BaseModel):
"""
列排序
"""
model_config = ConfigDict(alias_generator=to_camel, from_attributes=True)
ids: Optional[List[int]] = Field()
15 changes: 15 additions & 0 deletions backend/app/api/v1/schemas/gen_code/page_model.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# -*- coding:utf-8 -*-

from sqlalchemy import Boolean, Column, ForeignKey, String, Integer, Text, DateTime

from app.core.base_model import BaseMixin

class PageModel(BaseMixin):
__tablename__ = "gen_page"

page_name = Column(String(length=255), comment='页面名称')

keywords = Column(String(length=500), comment='页面关键词')

title = Column(String(length=500), comment='页面title标题')

44 changes: 44 additions & 0 deletions backend/app/api/v1/schemas/gen_code/table_model.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# -*- coding:utf-8 -*-
import datetime

from sqlalchemy import Boolean, Column, ForeignKey, String, Integer, Text, DateTime

from app.core.base_model import BaseMixin


class SysTable(BaseMixin):
__tablename__ = "gen_table"

id = Column(Integer, primary_key=True, autoincrement=True)
create_time = Column(DateTime, nullable=False, default=datetime.datetime.now, comment='创建时间')
update_time = Column(DateTime, nullable=False, default=datetime.datetime.now, onupdate=datetime.datetime.now, index=True, comment='更新时间')
del_flag = Column(String(1), nullable=False, default='0', server_default=text("'0'"), comment='删除标志(0代表存在 2代表删除)')

align = Column(String(255), nullable=False, default='left', comment='对其方式')

field_name = Column(String(255), nullable=False, comment='字段名')

fixed = Column(String(1), nullable=False, default='0', comment='固定表头')

label = Column(String(255), nullable=False, comment='字段标签')

label_tip = Column(String(255), comment='字段标签解释')

prop = Column(String(255), nullable=False, comment='驼峰属性')

show = Column(String(1), nullable=False, default='1', comment='可见')

sortable = Column(String(1), nullable=False, default='0', comment='可排序')

table_name = Column(String(255), nullable=False, comment='表名')

tooltip = Column(String(1), nullable=False, default='1', comment='超出隐藏')

update_by = Column(Integer, comment='更新者')

update_by_name = Column(String(255), comment='更新者')

width = Column(Integer, nullable=False, default=150, comment='宽度')

sequence = Column(Integer, nullable=False, default=0, comment='字段顺序')

Loading