diff --git a/kinit-api/apps/vadmin/auth/crud.py b/kinit-api/apps/vadmin/auth/crud.py index e8539d5..28e4133 100644 --- a/kinit-api/apps/vadmin/auth/crud.py +++ b/kinit-api/apps/vadmin/auth/crud.py @@ -13,7 +13,7 @@ from sqlalchemy.orm import joinedload from sqlalchemy.orm.strategy_options import _AbstractLoad from core.exception import CustomException from fastapi.encoders import jsonable_encoder -from sqlalchemy import select +from sqlalchemy import select, false from core.crud import DalBase from sqlalchemy.ext.asyncio import AsyncSession from core.validator import vali_telephone @@ -45,7 +45,10 @@ class UserDal(DalBase): ] def __init__(self, db: AsyncSession): - super(UserDal, self).__init__(db, models.VadminUser, schemas.UserSimpleOut) + super(UserDal, self).__init__() + self.db = db + self.model = models.VadminUser + self.schema = schemas.UserSimpleOut async def update_login_info(self, user: models.VadminUser, last_ip: str) -> None: """ @@ -67,6 +70,11 @@ class UserDal(DalBase): ) -> Any: """ 创建用户 + :param data: + :param v_options: + :param v_return_obj: + :param v_schema: + :return: """ unique = await self.get_data(telephone=data.telephone, v_return_none=True) if unique: @@ -92,6 +100,12 @@ class UserDal(DalBase): ) -> Any: """ 更新用户信息 + :param data_id: + :param data: + :param v_options: + :param v_return_obj: + :param v_schema: + :return: """ obj = await self.get_data(data_id, v_options=[joinedload(self.model.roles)]) data_dict = jsonable_encoder(data) @@ -111,6 +125,9 @@ class UserDal(DalBase): async def reset_current_password(self, user: models.VadminUser, data: schemas.ResetPwd) -> None: """ 重置密码 + :param user: + :param data: + :return: """ if data.password != data.password_two: raise CustomException(msg="两次密码不一致", code=400) @@ -124,6 +141,9 @@ class UserDal(DalBase): async def update_current_info(self, user: models.VadminUser, data: schemas.UserUpdateBaseInfo) -> Any: """ 更新当前用户基本信息 + :param user: + :param data: + :return: """ if data.telephone != user.telephone: unique = await self.get_data(telephone=data.telephone, v_return_none=True) @@ -139,7 +159,10 @@ class UserDal(DalBase): async def export_query_list(self, header: list, params: UserParams) -> dict: """ - 导出用户查询列表为excel + 导出用户查询列表为 excel + :param header: + :param params: + :return: """ datas = await self.get_datas(**params.dict(), v_return_objs=True) # 获取表头 @@ -171,6 +194,7 @@ class UserDal(DalBase): async def get_import_headers_options(self) -> None: """ 补全表头数据选项 + :return: """ # 角色选择项 roles = await RoleDal(self.db).get_datas(limit=0, v_return_objs=True, disabled=False, is_admin=False) @@ -188,16 +212,20 @@ class UserDal(DalBase): async def download_import_template(self) -> dict: """ 下载用户最新版导入模板 + :return: """ await self.get_import_headers_options() - em = WriteXlsx(sheet_name="用户导入模板") + em = WriteXlsx() + em.create_excel(sheet_name="用户导入模板", save_static=True) em.generate_template(copy.deepcopy(self.import_headers)) em.close() - return {"url": em.file_url, "filename": "用户导入模板.xlsx"} + return {"url": em.get_file_url(), "filename": "用户导入模板.xlsx"} async def import_users(self, file: UploadFile) -> dict: """ 批量导入用户数据 + :param file: + :return: """ await self.get_import_headers_options() im = ImportManage(file, copy.deepcopy(self.import_headers)) @@ -224,6 +252,8 @@ class UserDal(DalBase): """ 初始化所选用户密码 将用户密码改为系统默认密码,并将初始化密码状态改为false + :param ids: + :return: """ users = await self.get_datas(limit=0, id=("in", ids), v_return_objs=True) result = [] @@ -244,6 +274,9 @@ class UserDal(DalBase): """ 初始化所选用户密码并发送通知短信 将用户密码改为系统默认密码,并将初始化密码状态改为false + :param ids: + :param rd: + :return: """ result = await self.init_password(ids) for user in result: @@ -266,6 +299,9 @@ class UserDal(DalBase): """ 初始化所选用户密码并发送通知邮件 将用户密码改为系统默认密码,并将初始化密码状态改为false + :param ids: + :param rd: + :return: """ result = await self.init_password(ids) for user in result: @@ -294,6 +330,9 @@ class UserDal(DalBase): async def update_current_avatar(self, user: models.VadminUser, file: UploadFile) -> str: """ 更新当前用户头像 + :param user: + :param file: + :return: """ result = await AliyunOSS(BucketConf(**settings.ALIYUN_OSS)).upload_image("avatar", file) user.avatar = result @@ -303,6 +342,10 @@ class UserDal(DalBase): async def update_wx_server_openid(self, code: str, user: models.VadminUser, redis: Redis) -> bool: """ 更新用户服务端微信平台openid + :param code: + :param user: + :param redis: + :return: """ wx = WXOAuth(redis, 0) openid = await wx.parsing_openid(code) @@ -332,7 +375,10 @@ class UserDal(DalBase): class RoleDal(DalBase): def __init__(self, db: AsyncSession): - super(RoleDal, self).__init__(db, models.VadminRole, schemas.RoleSimpleOut) + super(RoleDal, self).__init__() + self.db = db + self.model = models.VadminRole + self.schema = schemas.RoleSimpleOut async def create_data( self, @@ -341,7 +387,14 @@ class RoleDal(DalBase): v_return_obj: bool = False, v_schema: Any = None ) -> Any: - """创建数据""" + """ + 创建数据 + :param data: + :param v_options: + :param v_return_obj: + :param v_schema: + :return: + """ obj = self.model(**data.model_dump(exclude={'menu_ids'})) if data.menu_ids: menus = await MenuDal(db=self.db).get_datas(limit=0, id=("in", data.menu_ids), v_return_objs=True) @@ -358,7 +411,15 @@ class RoleDal(DalBase): v_return_obj: bool = False, v_schema: Any = None ) -> Any: - """更新单个数据""" + """ + 更新单个数据 + :param data_id: + :param data: + :param v_options: + :param v_return_obj: + :param v_schema: + :return: + """ obj = await self.get_data(data_id, v_options=[joinedload(self.model.menus)]) obj_dict = jsonable_encoder(data) for key, value in obj_dict.items(): @@ -379,7 +440,10 @@ class RoleDal(DalBase): return [i.id for i in role.menus] async def get_select_datas(self) -> list: - """获取选择数据,全部数据""" + """ + 获取选择数据,全部数据 + :return: + """ sql = select(self.model) queryset = await self.db.scalars(sql) return [schemas.RoleOptionsOut.model_validate(i).model_dump() for i in queryset.all()] @@ -401,18 +465,23 @@ class RoleDal(DalBase): class MenuDal(DalBase): def __init__(self, db: AsyncSession): - super(MenuDal, self).__init__(db, models.VadminMenu, schemas.MenuSimpleOut) + super(MenuDal, self).__init__() + self.db = db + self.model = models.VadminMenu + self.schema = schemas.MenuSimpleOut async def get_tree_list(self, mode: int) -> list: """ 1:获取菜单树列表 2:获取菜单树选择项,添加/修改菜单时使用 3:获取菜单树列表,角色添加菜单权限时使用 + :param mode: + :return: """ if mode == 3: - sql = select(self.model).where(self.model.disabled == 0, self.model.is_delete == False) + sql = select(self.model).where(self.model.disabled == 0, self.model.is_delete == false()) else: - sql = select(self.model).where(self.model.is_delete == False) + sql = select(self.model).where(self.model.is_delete == false()) queryset = await self.db.scalars(sql) datas = list(queryset.all()) roots = filter(lambda i: not i.parent_id, datas) @@ -435,10 +504,12 @@ class MenuDal(DalBase): redirect: string children?: AppCustomRouteRecordRaw[] } + :param user: + :return: """ if any([i.is_admin for i in user.roles]): sql = select(self.model) \ - .where(self.model.disabled == 0, self.model.menu_type != "2", self.model.is_delete == False) + .where(self.model.disabled == 0, self.model.menu_type != "2", self.model.is_delete == false()) queryset = await self.db.scalars(sql) datas = list(queryset.all()) else: @@ -457,10 +528,10 @@ class MenuDal(DalBase): def generate_router_tree(self, menus: list[models.VadminMenu], nodes: filter, name: str = "") -> list: """ 生成路由树 - - menus: 总菜单列表 - nodes:节点菜单列表 - name:name拼接,切记Name不能重复 + :param menus: 总菜单列表 + :param nodes: 节点菜单列表 + :param name: name拼接,切记Name不能重复 + :return: """ data = [] for root in nodes: @@ -482,9 +553,9 @@ class MenuDal(DalBase): def generate_tree_list(self, menus: list[models.VadminMenu], nodes: filter) -> list: """ 生成菜单树列表 - - menus: 总菜单列表 - nodes:每层节点菜单列表 + :param menus: 总菜单列表 + :param nodes: 每层节点菜单列表 + :return: """ data = [] for root in nodes: @@ -498,9 +569,9 @@ class MenuDal(DalBase): def generate_tree_options(self, menus: list[models.VadminMenu], nodes: filter) -> list: """ 生成菜单树选择项 - - menus: 总菜单列表 - nodes:每层节点菜单列表 + :param menus:总菜单列表 + :param nodes:每层节点菜单列表 + :return: """ data = [] for root in nodes: @@ -515,6 +586,10 @@ class MenuDal(DalBase): def menus_order(cls, datas: list, order: str = "order", children: str = "children") -> list: """ 菜单排序 + :param datas: + :param order: + :param children: + :return: """ result = sorted(datas, key=lambda menu: menu[order]) for item in result: @@ -529,32 +604,10 @@ class MenuDal(DalBase): :param ids: 数据集 :param v_soft: 是否执行软删除 :param kwargs: 其他更新字段 + :return: """ count = await RoleDal(self.db).get_count(v_join=[["menus"]], v_where=[self.model.id.in_(ids)]) if count > 0: raise CustomException("无法删除存在角色关联的菜单", code=400) await super(MenuDal, self).delete_datas(ids, v_soft, **kwargs) - -class TestDal(DalBase): - - def __init__(self, db: AsyncSession): - super(TestDal, self).__init__(db, models.VadminUser, schemas.UserSimpleOut) - - async def test(self): - # print("-----------------------开始------------------------") - options = [joinedload(self.model.roles)] - v_join = [[self.model.roles]] - v_where = [self.model.id == 1, models.VadminRole.id == 1] - v_start_sql = select(self.model) - result, count = await self.get_datas( - v_start_sql=v_start_sql, - v_join=v_join, - v_options=options, - v_where=v_where, - v_return_count=True - ) - if result: - print(result) - print(count) - # print("-----------------------结束------------------------") diff --git a/kinit-api/apps/vadmin/auth/params/role.py b/kinit-api/apps/vadmin/auth/params/role.py index 6dc2a43..8f4d029 100644 --- a/kinit-api/apps/vadmin/auth/params/role.py +++ b/kinit-api/apps/vadmin/auth/params/role.py @@ -9,7 +9,7 @@ """ 类依赖项-官方文档:https://fastapi.tiangolo.com/zh/tutorial/dependencies/classes-as-dependencies/ """ -from fastapi import Depends +from fastapi import Depends, Query from core.dependencies import Paging, QueryParams @@ -20,9 +20,9 @@ class RoleParams(QueryParams): def __init__( self, - name: str | None = None, - role_key: str | None = None, - disabled: bool | None = None, + name: str | None = Query(None, title="角色名称"), + role_key: str | None = Query(None, title="权限字符"), + disabled: bool | None = Query(None, title="是否禁用"), params: Paging = Depends() ): super().__init__(params) diff --git a/kinit-api/apps/vadmin/auth/params/user.py b/kinit-api/apps/vadmin/auth/params/user.py index 0bb9a3b..f056da7 100644 --- a/kinit-api/apps/vadmin/auth/params/user.py +++ b/kinit-api/apps/vadmin/auth/params/user.py @@ -9,7 +9,7 @@ """ 类依赖项-官方文档:https://fastapi.tiangolo.com/zh/tutorial/dependencies/classes-as-dependencies/ """ -from fastapi import Depends +from fastapi import Depends, Query from core.dependencies import Paging, QueryParams @@ -20,11 +20,11 @@ class UserParams(QueryParams): def __init__( self, - name: str | None = None, - telephone: str | None = None, - email: str | None = None, - is_active: bool | None = None, - is_staff: bool | None = None, + name: str | None = Query(None, title="用户名称"), + telephone: str | None = Query(None, title="手机号"), + email: str | None = Query(None, title="邮箱"), + is_active: bool | None = Query(None, title="是否可用"), + is_staff: bool | None = Query(None, title="是否为工作人员"), params: Paging = Depends() ): super().__init__(params) diff --git a/kinit-api/apps/vadmin/auth/views.py b/kinit-api/apps/vadmin/auth/views.py index d85aaa2..1f285a2 100644 --- a/kinit-api/apps/vadmin/auth/views.py +++ b/kinit-api/apps/vadmin/auth/views.py @@ -13,22 +13,13 @@ from core.database import redis_getter from utils.response import SuccessResponse, ErrorResponse from . import schemas, crud, models from core.dependencies import IdList -from apps.vadmin.auth.utils.current import AllUserAuth, FullAdminAuth, OpenAuth +from apps.vadmin.auth.utils.current import AllUserAuth, FullAdminAuth from apps.vadmin.auth.utils.validation.auth import Auth from .params import UserParams, RoleParams app = APIRouter() -########################################################### -# 接口测试 -########################################################### -@app.get("/test", summary="接口测试") -async def test(auth: Auth = Depends(OpenAuth())): - await crud.TestDal(auth.db).test() - return SuccessResponse() - - ########################################################### # 用户管理 ########################################################### @@ -260,6 +251,6 @@ async def get_role_menu_tree( role_id: int, auth: Auth = Depends(FullAdminAuth(permissions=["auth.role.create", "auth.role.update"])) ): - treeselect = await crud.MenuDal(auth.db).get_tree_list(mode=3) + tree_data = await crud.MenuDal(auth.db).get_tree_list(mode=3) role_menu_tree = await crud.RoleDal(auth.db).get_role_menu_tree(role_id) - return SuccessResponse({"role_menu_tree": role_menu_tree, "menus": treeselect}) + return SuccessResponse({"role_menu_tree": role_menu_tree, "menus": tree_data}) diff --git a/kinit-api/apps/vadmin/help/crud.py b/kinit-api/apps/vadmin/help/crud.py index 1e0b371..cdf1e35 100644 --- a/kinit-api/apps/vadmin/help/crud.py +++ b/kinit-api/apps/vadmin/help/crud.py @@ -14,7 +14,10 @@ from . import models, schemas class IssueDal(DalBase): def __init__(self, db: AsyncSession): - super(IssueDal, self).__init__(db, models.VadminIssue, schemas.IssueSimpleOut) + super(IssueDal, self).__init__() + self.db = db + self.model = models.VadminIssue + self.schema = schemas.IssueSimpleOut async def add_view_number(self, data_id: int) -> None: """ @@ -28,4 +31,7 @@ class IssueDal(DalBase): class IssueCategoryDal(DalBase): def __init__(self, db: AsyncSession): - super(IssueCategoryDal, self).__init__(db, models.VadminIssueCategory, schemas.IssueCategorySimpleOut) + super(IssueCategoryDal, self).__init__() + self.db = db + self.model = models.VadminIssueCategory + self.schema = schemas.IssueCategorySimpleOut diff --git a/kinit-api/apps/vadmin/record/crud.py b/kinit-api/apps/vadmin/record/crud.py index f9b9f55..9174a2b 100644 --- a/kinit-api/apps/vadmin/record/crud.py +++ b/kinit-api/apps/vadmin/record/crud.py @@ -17,7 +17,10 @@ from core.mongo_manage import MongoManage class LoginRecordDal(DalBase): def __init__(self, db: AsyncSession): - super(LoginRecordDal, self).__init__(db, models.VadminLoginRecord, schemas.LoginRecordSimpleOut) + super(LoginRecordDal, self).__init__() + self.db = db + self.model = models.VadminLoginRecord + self.schema = schemas.LoginRecordSimpleOut async def get_user_distribute(self) -> list[dict]: """ @@ -69,10 +72,17 @@ class LoginRecordDal(DalBase): class SMSSendRecordDal(DalBase): def __init__(self, db: AsyncSession): - super(SMSSendRecordDal, self).__init__(db, models.VadminSMSSendRecord, schemas.SMSSendRecordSimpleOut) + super(SMSSendRecordDal, self).__init__() + self.db = db + self.model = models.VadminSMSSendRecord + self.schema = schemas.SMSSendRecordSimpleOut class OperationRecordDal(MongoManage): def __init__(self, db: AsyncIOMotorDatabase): - super(OperationRecordDal, self).__init__(db, "operation_record", schemas.OperationRecordSimpleOut) + super(OperationRecordDal, self).__init__() + self.db = db + self.collection = db["operation_record"] + self.schema = schemas.OperationRecordSimpleOut + self.is_object_id = True diff --git a/kinit-api/apps/vadmin/resource/crud.py b/kinit-api/apps/vadmin/resource/crud.py index 6f723e0..b90463f 100644 --- a/kinit-api/apps/vadmin/resource/crud.py +++ b/kinit-api/apps/vadmin/resource/crud.py @@ -14,4 +14,7 @@ from . import models, schemas class ImagesDal(DalBase): def __init__(self, db: AsyncSession): - super(ImagesDal, self).__init__(db, models.VadminImages, schemas.ImagesSimpleOut) + super(ImagesDal, self).__init__() + self.db = db + self.model = models.VadminImages + self.schema = schemas.ImagesSimpleOut diff --git a/kinit-api/apps/vadmin/system/crud.py b/kinit-api/apps/vadmin/system/crud.py index 5751783..f8a2f6e 100644 --- a/kinit-api/apps/vadmin/system/crud.py +++ b/kinit-api/apps/vadmin/system/crud.py @@ -30,7 +30,10 @@ from fastapi import Request class DictTypeDal(DalBase): def __init__(self, db: AsyncSession): - super(DictTypeDal, self).__init__(db, models.VadminDictType, schemas.DictTypeSimpleOut) + super(DictTypeDal, self).__init__() + self.db = db + self.model = models.VadminDictType + self.schema = schemas.DictTypeSimpleOut async def get_dicts_details(self, dict_types: list[str]) -> dict: """ @@ -62,13 +65,19 @@ class DictTypeDal(DalBase): class DictDetailsDal(DalBase): def __init__(self, db: AsyncSession): - super(DictDetailsDal, self).__init__(db, models.VadminDictDetails, schemas.DictDetailsSimpleOut) + super(DictDetailsDal, self).__init__() + self.db = db + self.model = models.VadminDictDetails + self.schema = schemas.DictDetailsSimpleOut class SettingsDal(DalBase): def __init__(self, db: AsyncSession): - super(SettingsDal, self).__init__(db, models.VadminSystemSettings, schemas.SettingsSimpleOut) + super(SettingsDal, self).__init__() + self.db = db + self.model = models.VadminSystemSettings + self.schema = schemas.SettingsSimpleOut async def get_tab_values(self, tab_id: int) -> dict: """ @@ -108,6 +117,9 @@ class SettingsDal(DalBase): if "wx_server_app_id" in datas and REDIS_DB_ENABLE: rd = redis_getter(request) await rd.client().set("wx_server", json.dumps(datas)) + elif "sms_access_key" in datas and REDIS_DB_ENABLE: + rd = redis_getter(request) + await rd.client().set('aliyun_sms', json.dumps(datas)) async def get_base_config(self) -> dict: """ @@ -371,8 +383,8 @@ class TaskDal(MongoManage): 使用消息无保留策略:无保留是指当发送者向某个频道发送消息时,如果没有订阅该频道的调用方,就直接将该消息丢弃。 - :params rd: redis 对象 - :params data: 行数据字典 + :param rd: redis 对象 + :param data: 行数据字典 :return: 接收到消息的订阅者数量。 """ exec_strategy = data.get("exec_strategy")