From cab33828dd70604383e2344dca3a05e0ca2270e3 Mon Sep 17 00:00:00 2001 From: ktianc Date: Sun, 25 Feb 2024 16:40:19 +0800 Subject: [PATCH] =?UTF-8?q?1.=20=E5=8F=96=E6=B6=88TEMP=E9=9D=99=E6=80=81?= =?UTF-8?q?=E7=9B=AE=E5=BD=95=E6=8C=82=E8=BD=BD=202.=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E6=95=B0=E6=8D=AE=E5=AF=BC=E5=87=BA=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=203.=20=E7=94=9F=E6=88=90=20static=20=E9=9D=99?= =?UTF-8?q?=E6=80=81=E7=9B=AE=E5=BD=95=E5=B0=86=E6=97=B6=E9=97=B4=E6=88=B3?= =?UTF-8?q?=E6=94=B9=E4=B8=BA=E6=97=A5=E6=9C=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kinit-api/application/settings.py | 6 +--- kinit-api/apps/vadmin/auth/crud.py | 52 +++++++++++++++++++-------- kinit-api/main.py | 2 -- kinit-api/utils/excel/excel_manage.py | 38 ++++++++------------ kinit-api/utils/file/file_base.py | 5 +-- kinit-api/utils/file/file_manage.py | 6 ---- 6 files changed, 55 insertions(+), 54 deletions(-) diff --git a/kinit-api/application/settings.py b/kinit-api/application/settings.py index 07b99c3..4453f0e 100644 --- a/kinit-api/application/settings.py +++ b/kinit-api/application/settings.py @@ -11,7 +11,7 @@ """ 系统版本 """ -VERSION = "3.6.5" +VERSION = "3.7.0" """安全警告: 不要在生产中打开调试运行!""" DEBUG = False @@ -67,13 +67,9 @@ """ 挂载临时文件目录,并添加路由访问,此路由不会在接口文档中显示 -TEMP_ENABLE:是否启用临时文件目录访问 -TEMP_URL:路由访问 TEMP_DIR:临时文件目录绝对路径 官方文档:https://fastapi.tiangolo.com/tutorial/static-files/ """ -TEMP_ENABLE = True -TEMP_URL = "/temp" TEMP_DIR = os.path.join(BASE_DIR, "temp") """ diff --git a/kinit-api/apps/vadmin/auth/crud.py b/kinit-api/apps/vadmin/auth/crud.py index 97d66c0..5f64fe2 100644 --- a/kinit-api/apps/vadmin/auth/crud.py +++ b/kinit-api/apps/vadmin/auth/crud.py @@ -37,7 +37,6 @@ class UserDal(DalBase): - import_headers = [ {"label": "姓名", "field": "name", "required": True}, {"label": "昵称", "field": "nickname", "required": False}, @@ -205,11 +204,15 @@ async def export_query_list(self, header: list, params: UserParams) -> dict: :param params: :return: """ - datas = await self.get_datas(**params.dict(), v_return_objs=True) + datas = await self.get_datas( + **params.dict(), + v_return_objs=True, + v_options=[joinedload(self.model.depts), joinedload(self.model.roles)] + ) # 获取表头 row = list(map(lambda i: i.get("label"), header)) rows = [] - options = await vadmin_system_crud.DictTypeDal(self.db).get_dicts_details(["sys_vadmin_gender"]) + options = await self.get_export_headers_options() for user in datas: data = [] for item in header: @@ -221,16 +224,35 @@ async def export_query_list(self, header: list, params: UserParams) -> dict: elif field == "is_staff": value = "是" if value else "否" elif field == "gender": - result = list(filter(lambda i: i["value"] == value, options["sys_vadmin_gender"])) + result = list(filter(lambda i: i["value"] == value, options["gender_options"])) value = result[0]["label"] if result else "" + elif field == "roles": + value = ",".join([i.name for i in value]) + elif field == "depts": + value = ",".join([i.name for i in value]) data.append(value) rows.append(data) em = ExcelManage() em.create_excel("用户列表") em.write_list(rows, row) - file_url = em.save_excel() + remote_file_url = em.save_excel().get("remote_path") em.close() - return {"url": file_url, "filename": "用户列表.xlsx"} + return {"url": remote_file_url, "filename": "用户列表.xlsx"} + + async def get_export_headers_options(self, include: list[str] = None) -> dict[str, list]: + """ + 获取导出所需选择项 + :param include: 包括的选择项 + :return: + """ + options = {} + # 性别选择项 + if include is None or 'gender' in include: + gender_objs = await vadmin_system_crud.DictTypeDal(self.db).get_dicts_details(["sys_vadmin_gender"]) + sys_vadmin_gender = gender_objs.get("sys_vadmin_gender", []) + gender_options = [{"label": i["label"], "value": i["value"]} for i in sys_vadmin_gender] + options["gender_options"] = gender_options + return options async def get_import_headers_options(self) -> None: """ @@ -238,17 +260,17 @@ 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) - role_options = self.import_headers[4] - assert isinstance(role_options, dict) - role_options["options"] = [{"label": role.name, "value": role.id} for role in roles] + role_options = await RoleDal(self.db).get_datas(limit=0, v_return_objs=True, disabled=False, is_admin=False) + role_item = self.import_headers[4] + assert isinstance(role_item, dict) + role_item["options"] = [{"label": role.name, "value": role.id} for role in role_options] # 性别选择项 - dict_types = await vadmin_system_crud.DictTypeDal(self.db).get_dicts_details(["sys_vadmin_gender"]) - gender_options = self.import_headers[3] - assert isinstance(gender_options, dict) - sys_vadmin_gender = dict_types.get("sys_vadmin_gender") - gender_options["options"] = [{"label": item["label"], "value": item["value"]} for item in sys_vadmin_gender] + gender_options = await vadmin_system_crud.DictTypeDal(self.db).get_dicts_details(["sys_vadmin_gender"]) + gender_item = self.import_headers[3] + assert isinstance(gender_item, dict) + sys_vadmin_gender = gender_options.get("sys_vadmin_gender") + gender_item["options"] = [{"label": item["label"], "value": item["value"]} for item in sys_vadmin_gender] async def download_import_template(self) -> dict: """ diff --git a/kinit-api/main.py b/kinit-api/main.py index 81c414f..5f17057 100644 --- a/kinit-api/main.py +++ b/kinit-api/main.py @@ -60,8 +60,6 @@ def create_app(): # 挂在静态目录 if settings.STATIC_ENABLE: app.mount(settings.STATIC_URL, app=StaticFiles(directory=settings.STATIC_ROOT)) - if settings.TEMP_ENABLE: - app.mount(settings.TEMP_URL, app=StaticFiles(directory=settings.TEMP_DIR)) # 引入应用中的路由 for url in urls.urlpatterns: app.include_router(url["ApiRouter"], prefix=url["prefix"], tags=url["tags"]) diff --git a/kinit-api/utils/excel/excel_manage.py b/kinit-api/utils/excel/excel_manage.py index 7f30e67..c58cad1 100644 --- a/kinit-api/utils/excel/excel_manage.py +++ b/kinit-api/utils/excel/excel_manage.py @@ -9,12 +9,13 @@ import datetime import os import re +from pathlib import Path + from openpyxl.utils import get_column_letter from openpyxl import load_workbook, Workbook -from application.settings import TEMP_DIR, TEMP_URL -import hashlib -import random +from application.settings import STATIC_ROOT, STATIC_URL from openpyxl.styles import Alignment, Font, PatternFill, Border, Side +from utils.file.file_base import FileBase from .excel_schema import AlignmentModel, FontModel, PatternFillModel @@ -150,26 +151,19 @@ def write_list(self, rows: list, header: list = None) -> None: self.__auto_width() self.__set_row_border() - def save_excel(self, filename: str = None): + def save_excel(self, path: str = "excel_manage"): """ - 保存 excel 文件到本地 - 默认保存到临时目录中 - :param filename: 保存的文件名称 + 保存 excel 文件到本地 static 目录 + :param path: static 指定目录类别 :return: """ - date = datetime.datetime.strftime(datetime.datetime.now(), "%Y%m%d") - file_dir = os.path.join(TEMP_DIR, date) - if not os.path.exists(file_dir): - os.mkdir(file_dir) - if not filename: - name = hashlib.md5(str(random.random()).encode()).hexdigest() + ".xlsx" - filename = os.path.join(file_dir, name) - else: - name = filename - filename = os.path.join(file_dir, filename) - self.wb.save(filename) - # 返回访问路由 - return f"{TEMP_URL}/{date}/{name}" + file_path = FileBase.generate_static_file_path(path=path, suffix="xlsx") + Path(file_path).parent.mkdir(parents=True, exist_ok=True) + self.wb.save(file_path) + return { + "local_path": file_path, + "remote_path": file_path.replace(STATIC_ROOT, STATIC_URL) + } def __set_row_style( self, @@ -249,7 +243,3 @@ def close(self): :return: """ self.wb.close() - - -if __name__ == '__main__': - print([chr(a) for a in range(ord('A'), ord('Z') + 1)]) diff --git a/kinit-api/utils/file/file_base.py b/kinit-api/utils/file/file_base.py index e909014..f229d38 100644 --- a/kinit-api/utils/file/file_base.py +++ b/kinit-api/utils/file/file_base.py @@ -50,7 +50,7 @@ def generate_static_file_path(cls, path: str, filename: str = None, suffix: str 1. filename 参数或者 suffix 参数必须填写一个 2. filename 参数和 suffix 参数都存在则优先取 suffix 参数为后缀 :param path: static 指定目录类别 - :param filename: 文件名称 + :param filename: 文件名称,只用户获取后缀,不做真实文件名称,避免文件重复问题 :param suffix: 文件后缀 :return: """ @@ -63,7 +63,8 @@ def generate_static_file_path(cls, path: str, filename: str = None, suffix: str path = path[1:] if path[-1] == "/": path = path[:-1] - return f"{STATIC_ROOT}/{path}/{cls.get_today_timestamp()}/{cls.get_random_filename(suffix)}" + today = datetime.datetime.strftime(datetime.datetime.now(), "%Y%m%d") + return f"{STATIC_ROOT}/{path}/{today}/{cls.get_random_filename(suffix)}" @classmethod def generate_temp_file_path(cls, filename: str = None, suffix: str = None) -> str: diff --git a/kinit-api/utils/file/file_manage.py b/kinit-api/utils/file/file_manage.py index 9d537b8..83043de 100644 --- a/kinit-api/utils/file/file_manage.py +++ b/kinit-api/utils/file/file_manage.py @@ -137,9 +137,3 @@ async def async_copy_dir(src: str, dst: str, dirs_exist_ok: bool = True) -> None if not os.path.exists(dst): raise CustomException("目标目录不存在!") await aioshutil.copytree(src, dst, dirs_exist_ok=dirs_exist_ok) - - -if __name__ == '__main__': - _src = r"E:\ktianc\linfeng\project\leadership\temp\20231212\3nCx1702349951\template" - _dst = r"E:\ktianc\linfeng\project\leadership\static\template" - asyncio.run(FileManage.async_copy_dir(_src, _dst))