diff --git a/kinit-admin/src/views/vadmin/resource/images/components/Write.vue b/kinit-admin/src/views/vadmin/resource/images/components/Write.vue new file mode 100644 index 0000000..7f0f874 --- /dev/null +++ b/kinit-admin/src/views/vadmin/resource/images/components/Write.vue @@ -0,0 +1,185 @@ + + + + + diff --git a/kinit-admin/src/views/vadmin/resource/images/components/images.data.ts b/kinit-admin/src/views/vadmin/resource/images/components/images.data.ts new file mode 100644 index 0000000..5df8272 --- /dev/null +++ b/kinit-admin/src/views/vadmin/resource/images/components/images.data.ts @@ -0,0 +1,103 @@ +import { FormSchema } from '@/types/form' +import { TableColumn } from '@/types/table' +import { reactive } from 'vue' + +export const columns = reactive([ + { + field: 'id', + label: '编号', + show: true, + disabled: false, + width: '120px', + span: 24 + }, + { + field: 'image_url', + label: '图片', + show: true, + disabled: true, + minWidth: '90px', + span: 24 + }, + { + field: 'remark', + label: '备注', + show: false, + disabled: false, + span: 24 + }, + { + field: 'update_datetime', + label: '更新时间', + show: false, + width: '180px', + span: 24 + }, + { + field: 'create_datetime', + label: '创建时间', + width: '180px', + show: true, + span: 24 + }, + { + field: 'create_user.name', + label: '创建人', + show: false, + span: 24 + }, + { + field: 'action', + label: '操作', + show: true, + disabled: false, + width: '260px', + fixed: 'right', + span: 24 + } +]) + +export const searchSchema = reactive([ + { + field: 'filename', + label: '文件名称', + component: 'Input', + componentProps: { + clearable: true, + style: { + width: '214px' + } + } + } +]) + +export const schema = reactive([ + { + field: 'upload_method', + label: '上传方式', + colProps: { + span: 24 + }, + component: 'Radio', + componentProps: { + options: [ + { + label: '同时上传', + value: '1' + }, + { + label: '按顺序上传', + value: '2' + } + ] + }, + value: '1' + }, + { + field: 'images', + label: '', + colProps: { + span: 24 + } + } +]) diff --git a/kinit-admin/src/views/vadmin/resource/images/index.vue b/kinit-admin/src/views/vadmin/resource/images/index.vue new file mode 100644 index 0000000..4841a75 --- /dev/null +++ b/kinit-admin/src/views/vadmin/resource/images/index.vue @@ -0,0 +1,218 @@ + + + + + + + diff --git a/kinit-api/README.md b/kinit-api/README.md index 9be3162..0c0ebcd 100644 --- a/kinit-api/README.md +++ b/kinit-api/README.md @@ -253,7 +253,7 @@ def __dict_filter(self, **kwargs) -> list[BinaryExpression]: 查询所有用户id为1或2或 4或6,并且email不为空,并且名称包括李: ```python -users = UserDal(db).get_datas(limit=0, id=("in", [1,2,4,6]), email=("not None"), name=("like", "李")) +users = UserDal(db).get_datas(limit=0, id=("in", [1,2,4,6]), email=("not None", ), name=("like", "李")) # limit=0:表示返回所有结果数据 # 这里的 get_datas 默认返回的是 pydantic 模型数据 @@ -261,7 +261,7 @@ users = UserDal(db).get_datas(limit=0, id=("in", [1,2,4,6]), email=("not None"), users = UserDal(db).get_datas( limit=0, id=("in", [1,2,4,6]), - email=("not None"), + email=("not None", ), name=("like", "李"), v_return_objs=True ) diff --git a/kinit-api/application/settings.py b/kinit-api/application/settings.py index a97eab8..6cceee9 100644 --- a/kinit-api/application/settings.py +++ b/kinit-api/application/settings.py @@ -11,10 +11,10 @@ from fastapi.security import OAuth2PasswordBearer """ 系统版本 """ -VERSION = "2.0.0" +VERSION = "2.1.0" """安全警告: 不要在生产中打开调试运行!""" -DEBUG = True +DEBUG = False """是否开启演示功能:取消所有POST,DELETE,PUT操作权限""" DEMO = not DEBUG @@ -24,6 +24,7 @@ DEMO_WHITE_LIST_PATH = [ "/auth/token/refresh", "/auth/wx/login", "/vadmin/system/dict/types/details", + "/vadmin/resource/images", "/vadmin/auth/user/export/query/list/to/excel" ] diff --git a/kinit-api/application/urls.py b/kinit-api/application/urls.py index 9b251f9..8fadfae 100644 --- a/kinit-api/application/urls.py +++ b/kinit-api/application/urls.py @@ -12,6 +12,7 @@ from apps.vadmin.record.views import app as vadmin_record_app from apps.vadmin.workplace.views import app as vadmin_workplace_app from apps.vadmin.analysis.views import app as vadmin_analysis_app from apps.vadmin.help.views import app as vadmin_help_app +from apps.vadmin.resource.views import app as vadmin_resource_app # 引入应用中的路由 @@ -23,4 +24,5 @@ urlpatterns = [ {"ApiRouter": vadmin_workplace_app, "prefix": "/vadmin/workplace", "tags": ["工作区管理"]}, {"ApiRouter": vadmin_analysis_app, "prefix": "/vadmin/analysis", "tags": ["数据分析管理"]}, {"ApiRouter": vadmin_help_app, "prefix": "/vadmin/help", "tags": ["帮助中心管理"]}, + {"ApiRouter": vadmin_resource_app, "prefix": "/vadmin/resource", "tags": ["资源管理"]}, ] diff --git a/kinit-api/apps/vadmin/help/models/issue.py b/kinit-api/apps/vadmin/help/models/issue.py index f0e906b..6f33fd3 100644 --- a/kinit-api/apps/vadmin/help/models/issue.py +++ b/kinit-api/apps/vadmin/help/models/issue.py @@ -9,7 +9,7 @@ from sqlalchemy.orm import relationship, Mapped, mapped_column from apps.vadmin.auth.models import VadminUser from db.db_base import BaseModel -from sqlalchemy import String, Boolean, Integer, ForeignKey +from sqlalchemy import String, Boolean, Integer, ForeignKey, Text class VadminIssueCategory(BaseModel): @@ -42,7 +42,7 @@ class VadminIssue(BaseModel): category: Mapped[list["VadminIssueCategory"]] = relationship(foreign_keys=category_id, back_populates='issues') title: Mapped[str] = mapped_column(String(255), index=True, nullable=False, comment="标题") - content: Mapped[str] = mapped_column(String(5000), comment="内容") + content: Mapped[str] = mapped_column(Text, comment="内容") view_number: Mapped[int] = mapped_column(Integer, default=0, comment="查看次数") is_active: Mapped[bool] = mapped_column(Boolean, default=True, comment="是否可见") diff --git a/kinit-api/apps/vadmin/record/models/login.py b/kinit-api/apps/vadmin/record/models/login.py index b4631ff..20527da 100644 --- a/kinit-api/apps/vadmin/record/models/login.py +++ b/kinit-api/apps/vadmin/record/models/login.py @@ -14,7 +14,7 @@ from apps.vadmin.auth.utils.validation import LoginForm, WXLoginForm from utils.ip_manage import IPManage from sqlalchemy.ext.asyncio import AsyncSession from db.db_base import BaseModel -from sqlalchemy import String, Boolean +from sqlalchemy import String, Boolean, Text from fastapi import Request from starlette.requests import Request as StarletteRequest from user_agents import parse @@ -39,8 +39,8 @@ class VadminLoginRecord(BaseModel): area_code: Mapped[str | None] = mapped_column(String(255), comment="地区区号") browser: Mapped[str | None] = mapped_column(String(50), comment="浏览器") system: Mapped[str | None] = mapped_column(String(50), comment="操作系统") - response: Mapped[str | None] = mapped_column(String(5000), comment="响应信息") - request: Mapped[str | None] = mapped_column(String(5000), comment="请求信息") + response: Mapped[str | None] = mapped_column(Text, comment="响应信息") + request: Mapped[str | None] = mapped_column(Text, comment="请求信息") @classmethod async def create_login_record( diff --git a/kinit-api/apps/vadmin/resource/__init__.py b/kinit-api/apps/vadmin/resource/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/kinit-api/apps/vadmin/resource/crud.py b/kinit-api/apps/vadmin/resource/crud.py new file mode 100644 index 0000000..6f723e0 --- /dev/null +++ b/kinit-api/apps/vadmin/resource/crud.py @@ -0,0 +1,17 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# @version : 1.0 +# @Create Time : 2023/8/25 13:15 +# @File : crud.py +# @IDE : PyCharm +# @desc : 简要说明 + +from sqlalchemy.ext.asyncio import AsyncSession +from core.crud import DalBase +from . import models, schemas + + +class ImagesDal(DalBase): + + def __init__(self, db: AsyncSession): + super(ImagesDal, self).__init__(db, models.VadminImages, schemas.ImagesSimpleOut) diff --git a/kinit-api/apps/vadmin/resource/models/__init__.py b/kinit-api/apps/vadmin/resource/models/__init__.py new file mode 100644 index 0000000..ca31757 --- /dev/null +++ b/kinit-api/apps/vadmin/resource/models/__init__.py @@ -0,0 +1 @@ +from .images import VadminImages diff --git a/kinit-api/apps/vadmin/resource/models/images.py b/kinit-api/apps/vadmin/resource/models/images.py new file mode 100644 index 0000000..525f2a7 --- /dev/null +++ b/kinit-api/apps/vadmin/resource/models/images.py @@ -0,0 +1,27 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# @version : 1.0 +# @Create Time : 2023/8/25 13:41 +# @File : images.py +# @IDE : PyCharm +# @desc : 图片素材表 + +from sqlalchemy.orm import relationship, Mapped, mapped_column +from apps.vadmin.auth.models import VadminUser +from db.db_base import BaseModel +from sqlalchemy import String, ForeignKey, Integer + + +class VadminImages(BaseModel): + __tablename__ = "vadmin_resource_images" + __table_args__ = ({'comment': '图片素材表'}) + + filename: Mapped[str] = mapped_column(String(255), nullable=False, comment="原图片名称") + image_url: Mapped[str] = mapped_column(String(500), nullable=False, comment="图片链接") + + create_user_id: Mapped[int] = mapped_column( + Integer, + ForeignKey("vadmin_auth_user.id", ondelete='RESTRICT'), + comment="创建人" + ) + create_user: Mapped[VadminUser] = relationship(foreign_keys=create_user_id) diff --git a/kinit-api/apps/vadmin/resource/params/__init__.py b/kinit-api/apps/vadmin/resource/params/__init__.py new file mode 100644 index 0000000..d18efa1 --- /dev/null +++ b/kinit-api/apps/vadmin/resource/params/__init__.py @@ -0,0 +1 @@ +from .images import ImagesParams diff --git a/kinit-api/apps/vadmin/resource/params/images.py b/kinit-api/apps/vadmin/resource/params/images.py new file mode 100644 index 0000000..3050386 --- /dev/null +++ b/kinit-api/apps/vadmin/resource/params/images.py @@ -0,0 +1,27 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# @version : 1.0 +# @Create Time : 2023/8/25 14:59 +# @File : images.py +# @IDE : PyCharm +# @desc : 简要说明 + + +from fastapi import Depends +from core.dependencies import Paging, QueryParams + + +class ImagesParams(QueryParams): + """ + 列表分页 + """ + + def __init__( + self, + filename: str = None, + params: Paging = Depends() + ): + super().__init__(params) + self.filename = ('like', filename) + self.v_order = "desc" + self.v_order_field = "create_datetime" diff --git a/kinit-api/apps/vadmin/resource/schemas/__init__.py b/kinit-api/apps/vadmin/resource/schemas/__init__.py new file mode 100644 index 0000000..7e8d000 --- /dev/null +++ b/kinit-api/apps/vadmin/resource/schemas/__init__.py @@ -0,0 +1 @@ +from .images import Images, ImagesOut, ImagesSimpleOut diff --git a/kinit-api/apps/vadmin/resource/schemas/images.py b/kinit-api/apps/vadmin/resource/schemas/images.py new file mode 100644 index 0000000..451e7c1 --- /dev/null +++ b/kinit-api/apps/vadmin/resource/schemas/images.py @@ -0,0 +1,33 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# @version : 1.0 +# @Create Time : 2023/8/25 14:49 +# @File : images.py +# @IDE : PyCharm +# @desc : 简要说明 + + +from pydantic import BaseModel, ConfigDict +from core.data_types import DatetimeStr +from apps.vadmin.auth.schemas import UserSimpleOut + + +class Images(BaseModel): + filename: str + image_url: str + + create_user_id: int + + +class ImagesSimpleOut(Images): + model_config = ConfigDict(from_attributes=True) + + id: int + create_datetime: DatetimeStr + update_datetime: DatetimeStr + + +class ImagesOut(ImagesSimpleOut): + model_config = ConfigDict(from_attributes=True) + + create_user: UserSimpleOut diff --git a/kinit-api/apps/vadmin/resource/views.py b/kinit-api/apps/vadmin/resource/views.py new file mode 100644 index 0000000..bf79970 --- /dev/null +++ b/kinit-api/apps/vadmin/resource/views.py @@ -0,0 +1,60 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# @version : 1.0 +# @Create Time : 2023/8/25 9:29 +# @File : views.py +# @IDE : PyCharm +# @desc : 简要说明 + +from fastapi import APIRouter, Depends, UploadFile +from sqlalchemy.orm import joinedload +from core.dependencies import IdList +from utils.file.aliyun_oss import AliyunOSS, BucketConf +from utils.response import SuccessResponse +from . import schemas, crud, params, models +from apps.vadmin.auth.utils.current import FullAdminAuth +from apps.vadmin.auth.utils.validation.auth import Auth +from application.settings import ALIYUN_OSS + +app = APIRouter() + + +########################################################### +# 图片资源管理 +########################################################### +@app.get("/images", summary="获取图片列表") +async def get_images_list(p: params.ImagesParams = Depends(), auth: Auth = Depends(FullAdminAuth())): + model = models.VadminImages + v_options = [joinedload(model.create_user)] + v_schema = schemas.ImagesOut + datas, count = await crud.ImagesDal(auth.db).get_datas( + **p.dict(), + v_options=v_options, + v_schema=v_schema, + v_return_count=True + ) + return SuccessResponse(datas, count=count) + + +@app.post("/images", summary="创建图片") +async def create_images(file: UploadFile, auth: Auth = Depends(FullAdminAuth())): + filepath = f"/resource/images/" + result = await AliyunOSS(BucketConf(**ALIYUN_OSS)).upload_image(filepath, file) + data = schemas.Images( + filename=file.filename, + image_url=result, + create_user_id=auth.user.id + ) + + return SuccessResponse(await crud.ImagesDal(auth.db).create_data(data=data)) + + +@app.delete("/images", summary="删除图片", description="硬删除") +async def delete_images(ids: IdList = Depends(), auth: Auth = Depends(FullAdminAuth())): + await crud.ImagesDal(auth.db).delete_datas(ids.ids, v_soft=False) + return SuccessResponse("删除成功") + + +@app.get("/images/{data_id}", summary="获取图片信息") +async def get_images(data_id: int, auth: Auth = Depends(FullAdminAuth())): + return SuccessResponse(await crud.ImagesDal(auth.db).get_data(data_id, v_schema=schemas.ImagesSimpleOut)) diff --git a/kinit-api/scripts/initialize/data/init.xlsx b/kinit-api/scripts/initialize/data/init.xlsx index 9a138b8..0e57114 100644 Binary files a/kinit-api/scripts/initialize/data/init.xlsx and b/kinit-api/scripts/initialize/data/init.xlsx differ