From 2ba27381070a82985ad9e08700ceeacd70987c38 Mon Sep 17 00:00:00 2001 From: ktianc Date: Thu, 30 Mar 2023 15:56:47 +0800 Subject: [PATCH] =?UTF-8?q?=E7=89=88=E6=9C=AC=E6=9B=B4=E6=96=B0=EF=BC=9A?= =?UTF-8?q?=201.=20=E6=96=B0=E5=A2=9E=EF=BC=88kinit-api=EF=BC=8Ckinit-admi?= =?UTF-8?q?n=EF=BC=89=EF=BC=9A=E6=94=AF=E6=8C=81=E5=8F=91=E9=80=81?= =?UTF-8?q?=E9=82=AE=E7=AE=B1=E9=80=9A=E7=9F=A5=202.=20=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=88kinit-api=EF=BC=89=EF=BC=9Acore/crud.py=20=E4=BC=98?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kinit-admin/src/api/vadmin/auth/user.ts | 4 + kinit-admin/src/hooks/web/useValidator.ts | 12 +- .../vadmin/auth/user/components/Write.vue | 5 +- .../vadmin/auth/user/components/user.data.ts | 23 ++- .../src/views/vadmin/auth/user/index.vue | 45 ++++- .../views/vadmin/system/settings/index.vue | 2 + kinit-api/application/settings.py | 2 +- kinit-api/apps/vadmin/auth/crud.py | 44 ++++- kinit-api/apps/vadmin/auth/models/user.py | 1 + kinit-api/apps/vadmin/auth/params/user.py | 2 + kinit-api/apps/vadmin/auth/schemas/user.py | 5 +- kinit-api/apps/vadmin/auth/views.py | 9 + kinit-api/core/crud.py | 172 ++++++++++++------ kinit-api/core/data_types.py | 11 ++ kinit-api/core/exception.py | 5 +- kinit-api/core/logger.py | 5 +- kinit-api/core/validator.py | 21 ++- kinit-api/scripts/initialize/data/init.xlsx | Bin 43249 -> 43869 bytes kinit-api/utils/cache.py | 6 +- kinit-api/utils/wx/oauth.py | 1 - 20 files changed, 290 insertions(+), 85 deletions(-) diff --git a/kinit-admin/src/api/vadmin/auth/user.ts b/kinit-admin/src/api/vadmin/auth/user.ts index ea67af9..3972a2d 100644 --- a/kinit-admin/src/api/vadmin/auth/user.ts +++ b/kinit-admin/src/api/vadmin/auth/user.ts @@ -51,3 +51,7 @@ export const postImportUserApi = (data: any): Promise => { export const postUsersInitPasswordSendSMSApi = (data: any): Promise => { return request.post({ url: `/vadmin/auth/users/init/password/send/sms/`, data }) } + +export const postUsersInitPasswordSendEmailApi = (data: any): Promise => { + return request.post({ url: `/vadmin/auth/users/init/password/send/email/`, data }) +} diff --git a/kinit-admin/src/hooks/web/useValidator.ts b/kinit-admin/src/hooks/web/useValidator.ts index a0d36c3..cda9b21 100644 --- a/kinit-admin/src/hooks/web/useValidator.ts +++ b/kinit-admin/src/hooks/web/useValidator.ts @@ -54,11 +54,21 @@ export const useValidator = () => { } } + const isEmail = (rule: any, val: any, callback: Callback) => { + // 判断是否为邮箱地址 + if (/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(val)) { + callback() + } else { + callback(new Error('请填写正确的邮箱地址')) + } + } + return { required, lengthRange, notSpace, notSpecialCharacters, - isEqual + isEqual, + isEmail } } diff --git a/kinit-admin/src/views/vadmin/auth/user/components/Write.vue b/kinit-admin/src/views/vadmin/auth/user/components/Write.vue index 6d8695b..07f6b92 100644 --- a/kinit-admin/src/views/vadmin/auth/user/components/Write.vue +++ b/kinit-admin/src/views/vadmin/auth/user/components/Write.vue @@ -6,7 +6,7 @@ import { useValidator } from '@/hooks/web/useValidator' import { schema } from './user.data' import { getRoleOptionsApi } from '@/api/vadmin/auth/role' -const { required } = useValidator() +const { required, isEmail } = useValidator() const props = defineProps({ currentRow: { @@ -20,7 +20,8 @@ const rules = reactive({ is_active: [required()], is_staff: [required()], role_ids: [required()], - telephone: [required()] + telephone: [required()], + email: [required(), { validator: isEmail, trigger: 'blur' }] }) const { register, methods, elFormRef } = useForm({ diff --git a/kinit-admin/src/views/vadmin/auth/user/components/user.data.ts b/kinit-admin/src/views/vadmin/auth/user/components/user.data.ts index 7d29caf..ed9e508 100644 --- a/kinit-admin/src/views/vadmin/auth/user/components/user.data.ts +++ b/kinit-admin/src/views/vadmin/auth/user/components/user.data.ts @@ -27,6 +27,12 @@ export const columns = reactive([ show: true, disabled: true }, + { + field: 'email', + label: '邮箱', + show: true, + disabled: true + }, { field: 'gender', label: '性别', @@ -76,6 +82,19 @@ export const schema = reactive([ } } }, + { + field: 'nickname', + label: '用户昵称', + colProps: { + span: 12 + }, + component: 'Input', + componentProps: { + style: { + width: '100%' + } + } + }, { field: 'telephone', label: '手机号码', @@ -90,8 +109,8 @@ export const schema = reactive([ } }, { - field: 'nickname', - label: '用户昵称', + field: 'email', + label: '邮箱', colProps: { span: 12 }, diff --git a/kinit-admin/src/views/vadmin/auth/user/index.vue b/kinit-admin/src/views/vadmin/auth/user/index.vue index 60195a9..f6db192 100644 --- a/kinit-admin/src/views/vadmin/auth/user/index.vue +++ b/kinit-admin/src/views/vadmin/auth/user/index.vue @@ -20,7 +20,8 @@ import { columns, searchSchema } from './components/user.data' import { ref, unref, watch, nextTick } from 'vue' import Write from './components/Write.vue' import Import from './components/Import.vue' -import Password from './components/Password.vue' +import PasswordSendSMS from './components/PasswordSendSMS.vue' +import PasswordSendEmail from './components/PasswordSendEmail.vue' import { Dialog } from '@/components/Dialog' import { ElButton, @@ -180,7 +181,8 @@ const importList = () => { } const passwordDialogVisible = ref(false) -const passwordDialogTitle = ref('重置密码并发送短信') +let passwordDialogType = 'sms' +let passwordDialogTitle = ref('重置密码并发送短信') const selections = ref([] as any[]) // 批量发送密码至短信 @@ -189,6 +191,21 @@ const sendPasswordToSMS = async () => { selections.value = await getSelections() if (selections.value.length > 0) { passwordDialogVisible.value = true + passwordDialogType = 'sms' + passwordDialogTitle.value = '重置密码并发送短信' + } else { + return ElMessage.warning('请先选择数据') + } +} + +// 批量发送密码至邮件 +const sendPasswordToEmail = async () => { + const { getSelections } = methods + selections.value = await getSelections() + if (selections.value.length > 0) { + passwordDialogVisible.value = true + passwordDialogType = 'email' + passwordDialogTitle.value = '重置密码并发送邮件' } else { return ElMessage.warning('请先选择数据') } @@ -205,6 +222,8 @@ const handleCommand = (command: string) => { } else if (command === 'c') { sendPasswordToSMS() } else if (command === 'd') { + sendPasswordToEmail() + } else if (command === 'e') { delDatas(null, true) } } @@ -233,6 +252,9 @@ const handleCommand = (command: string) => { 重置密码通知短信 + + 重置密码通知邮件 + 批量删除 @@ -255,7 +277,10 @@ const handleCommand = (command: string) => { 重置密码通知短信 - 重置密码通知邮件 + 批量删除 @@ -343,10 +368,20 @@ const handleCommand = (command: string) => { - + + + diff --git a/kinit-admin/src/views/vadmin/system/settings/index.vue b/kinit-admin/src/views/vadmin/system/settings/index.vue index d90ae3b..12ace49 100644 --- a/kinit-admin/src/views/vadmin/system/settings/index.vue +++ b/kinit-admin/src/views/vadmin/system/settings/index.vue @@ -12,6 +12,7 @@ import Baidu from './baidu.vue' import Privacy from './privacy.vue' import Agreement from './agreement.vue' import WXClient from './wxServer.vue' +import Email from './email.vue' import { ContentWrap } from '@/components/ContentWrap' import { getSystemSettingsTabsApi } from '@/api/vadmin/system/settings' @@ -37,6 +38,7 @@ getList() + diff --git a/kinit-api/application/settings.py b/kinit-api/application/settings.py index 973cac4..f05ce3d 100644 --- a/kinit-api/application/settings.py +++ b/kinit-api/application/settings.py @@ -11,7 +11,7 @@ from fastapi.security import OAuth2PasswordBearer """ 系统版本 """ -VERSION = "1.7.1" +VERSION = "1.7.2" """安全警告: 不要在生产中打开调试运行!""" DEBUG = True diff --git a/kinit-api/apps/vadmin/auth/crud.py b/kinit-api/apps/vadmin/auth/crud.py index e4b68ab..801296c 100644 --- a/kinit-api/apps/vadmin/auth/crud.py +++ b/kinit-api/apps/vadmin/auth/crud.py @@ -21,6 +21,7 @@ from utils.file.aliyun_oss import AliyunOSS, BucketConf from utils.aliyun_sms import AliyunSMS from utils.excel.import_manage import ImportManage, FieldType from utils.excel.write_xlsx import WriteXlsx +from utils.send_email import EmailSender from .params import UserParams from utils.tools import test_password from . import models, schemas @@ -205,16 +206,16 @@ class UserDal(DalBase): "error_url": im.generate_error_url() } - async def init_password_send_sms(self, ids: List[int], rd: Redis): + async def init_password(self, ids: List[int]): """ - 初始化所选用户密码并发送通知短信 + 初始化所选用户密码 将用户密码改为系统默认密码,并将初始化密码状态改为false """ users = await self.get_datas(limit=0, id=("in", ids), v_return_objs=True) result = [] for user in users: # 重置密码 - data = {"id": user.id, "telephone": user.telephone, "name": user.name} + data = {"id": user.id, "telephone": user.telephone, "name": user.name, "email": user.email} password = user.telephone[5:12] if settings.DEFAULT_PASSWORD == "0" else settings.DEFAULT_PASSWORD user.password = self.model.get_password_hash(password) user.is_reset_password = False @@ -223,6 +224,14 @@ class UserDal(DalBase): data["password"] = password result.append(data) await self.db.flush() + return result + + async def init_password_send_sms(self, ids: List[int], rd: Redis): + """ + 初始化所选用户密码并发送通知短信 + 将用户密码改为系统默认密码,并将初始化密码状态改为false + """ + result = await self.init_password(ids) for user in result: if not user["reset_password_status"]: user["send_sms_status"] = False @@ -239,6 +248,35 @@ class UserDal(DalBase): user["send_sms_msg"] = e.msg return result + async def init_password_send_email(self, ids: List[int], rd: Redis): + """ + 初始化所选用户密码并发送通知邮件 + 将用户密码改为系统默认密码,并将初始化密码状态改为false + """ + result = await self.init_password(ids) + for user in result: + if not user["reset_password_status"]: + user["send_sms_status"] = False + user["send_sms_msg"] = "重置密码失败" + continue + password: str = user.pop("password") + email: str = user.get("email", None) + if email: + subject = "密码已重置" + body = f"您好,您的密码已经重置为{password},请及时登录并修改密码。" + es = EmailSender(rd) + try: + send_result = await es.send_email([email], subject, body) + user["send_sms_status"] = send_result + user["send_sms_msg"] = "" if send_result else "发送失败,请联系管理员" + except CustomException as e: + user["send_sms_status"] = False + user["send_sms_msg"] = e.msg + else: + user["send_sms_status"] = False + user["send_sms_msg"] = "未获取到邮箱地址" + return result + async def update_current_avatar(self, user: models.VadminUser, file: UploadFile): """ 更新当前用户头像 diff --git a/kinit-api/apps/vadmin/auth/models/user.py b/kinit-api/apps/vadmin/auth/models/user.py index 28034c4..9eebdd4 100644 --- a/kinit-api/apps/vadmin/auth/models/user.py +++ b/kinit-api/apps/vadmin/auth/models/user.py @@ -23,6 +23,7 @@ class VadminUser(BaseModel): avatar = Column(String(500), nullable=True, comment='头像') telephone = Column(String(11), nullable=False, index=True, comment="手机号", unique=False) + email = Column(String(50), nullable=True, comment="邮箱地址") name = Column(String(50), index=True, nullable=False, comment="姓名") nickname = Column(String(50), nullable=True, comment="昵称") password = Column(String(255), nullable=True, comment="密码") diff --git a/kinit-api/apps/vadmin/auth/params/user.py b/kinit-api/apps/vadmin/auth/params/user.py index 7481aa6..b622978 100644 --- a/kinit-api/apps/vadmin/auth/params/user.py +++ b/kinit-api/apps/vadmin/auth/params/user.py @@ -22,6 +22,7 @@ class UserParams(QueryParams): self, name: str = None, telephone: str = None, + email: str = None, is_active: bool | str = None, is_staff: bool | str = None, params: Paging = Depends() @@ -29,6 +30,7 @@ class UserParams(QueryParams): super().__init__(params) self.name = ("like", name) self.telephone = ("like", telephone) + self.email = ("like", email) self.is_active = is_active self.is_staff = is_staff diff --git a/kinit-api/apps/vadmin/auth/schemas/user.py b/kinit-api/apps/vadmin/auth/schemas/user.py index 07cc9c8..dd61d43 100644 --- a/kinit-api/apps/vadmin/auth/schemas/user.py +++ b/kinit-api/apps/vadmin/auth/schemas/user.py @@ -11,13 +11,14 @@ from typing import List, Optional from pydantic import BaseModel, root_validator -from core.data_types import Telephone, DatetimeStr +from core.data_types import Telephone, DatetimeStr, Email from .role import RoleSimpleOut class User(BaseModel): name: Optional[str] = None telephone: Telephone + email: Optional[Email] = None nickname: Optional[str] = None avatar: Optional[str] = None is_active: Optional[bool] = True @@ -40,6 +41,7 @@ class UserUpdateBaseInfo(BaseModel): """ name: str telephone: Telephone + email: Optional[Email] = None nickname: Optional[str] = None gender: Optional[str] = "0" @@ -50,6 +52,7 @@ class UserUpdate(User): """ name: Optional[str] = None telephone: Telephone + email: Optional[Email] = None nickname: Optional[str] = None avatar: Optional[str] = None is_active: Optional[bool] = True diff --git a/kinit-api/apps/vadmin/auth/views.py b/kinit-api/apps/vadmin/auth/views.py index ee4065f..f8dc020 100644 --- a/kinit-api/apps/vadmin/auth/views.py +++ b/kinit-api/apps/vadmin/auth/views.py @@ -119,6 +119,15 @@ async def post_users_init_password( return SuccessResponse(await crud.UserDal(auth.db).init_password_send_sms(ids.ids, request.app.state.redis)) +@app.post("/users/init/password/send/email/", summary="初始化所选用户密码并发送通知邮件") +async def post_users_init_password_send_email( + request: Request, + ids: IdList = Depends(), + auth: Auth = Depends(FullAdminAuth(permissions=["auth.user.reset"])) +): + return SuccessResponse(await crud.UserDal(auth.db).init_password_send_email(ids.ids, request.app.state.redis)) + + @app.put("/users/wx/server/openid/", summary="更新当前用户服务端微信平台openid") async def put_user_wx_server_openid(request: Request, code: str, auth: Auth = Depends(AllUserAuth())): result = await crud.UserDal(auth.db).update_wx_server_openid(code, auth.user, request.app.state.redis) diff --git a/kinit-api/core/crud.py b/kinit-api/core/crud.py index 77017c1..eb3ca76 100644 --- a/kinit-api/core/crud.py +++ b/kinit-api/core/crud.py @@ -19,14 +19,14 @@ # https://www.osgeo.cn/sqlalchemy/orm/loading_relationships.html?highlight=selectinload#sqlalchemy.orm.joinedload import datetime -from typing import List +from typing import List, Set from fastapi import HTTPException from fastapi.encoders import jsonable_encoder from sqlalchemy import func, delete, update, or_ from sqlalchemy.future import select from sqlalchemy.ext.asyncio import AsyncSession from starlette import status -from core.logger import logger +from core.exception import CustomException from sqlalchemy.sql.selectable import Select from typing import Any @@ -47,6 +47,7 @@ class DalBase: data_id: int = None, v_options: list = None, v_join_query: dict = None, + v_or: List[tuple] = None, v_order: str = None, v_return_none: bool = False, v_schema: Any = None, @@ -58,6 +59,7 @@ class DalBase: :param data_id: 数据 ID :param v_options: 指示应使用select在预加载中加载给定的属性。 :param v_join_query: 外键字段查询,内连接 + :param v_or: 或逻辑查询 :param v_order: 排序,默认正序,为 desc 是倒叙 :param v_return_none: 是否返回空 None,否认 抛出异常,默认抛出异常 :param v_schema: 指定使用的序列化对象 @@ -66,7 +68,7 @@ class DalBase: sql = select(self.model).where(self.model.is_delete == False) if data_id: sql = sql.where(self.model.id == data_id) - sql = self.add_filter_condition(sql, v_join_query, v_options, **kwargs) + sql = self.add_filter_condition(sql, v_options, v_join_query, v_or, **kwargs) if v_order and (v_order in self.ORDER_FIELD): sql = sql.order_by(self.model.create_datetime.desc()) queryset = await self.db.execute(sql) @@ -83,8 +85,9 @@ class DalBase: self, page: int = 1, limit: int = 10, - v_join_query: dict = None, v_options: list = None, + v_join_query: dict = None, + v_or: List[tuple] = None, v_order: str = None, v_order_field: str = None, v_return_objs: bool = False, @@ -96,18 +99,19 @@ class DalBase: 获取数据列表 :param page: 页码 :param limit: 当前页数据量 - :param v_join_query: 外键字段查询 :param v_options: 指示应使用select在预加载中加载给定的属性。 - :param v_schema: 指定使用的序列化对象 + :param v_join_query: 外键字段查询 + :param v_or: 或逻辑查询 :param v_order: 排序,默认正序,为 desc 是倒叙 :param v_order_field: 排序字段 :param v_return_objs: 是否返回对象 :param v_start_sql: 初始 sql + :param v_schema: 指定使用的序列化对象 :param kwargs: 查询参数 """ if not isinstance(v_start_sql, Select): v_start_sql = select(self.model).where(self.model.is_delete == False) - sql = self.add_filter_condition(v_start_sql, v_join_query, v_options, **kwargs) + sql = self.add_filter_condition(v_start_sql, v_options, v_join_query, v_or, **kwargs) if v_order_field and (v_order in self.ORDER_FIELD): sql = sql.order_by(getattr(self.model, v_order_field).desc(), self.model.id.desc()) elif v_order_field: @@ -121,15 +125,17 @@ class DalBase: return queryset.scalars().unique().all() return [await self.out_dict(i, v_schema=v_schema) for i in queryset.scalars().unique().all()] - async def get_count(self, v_join_query: dict = None, v_options: list = None, **kwargs): + async def get_count(self, v_options: list = None, v_join_query: dict = None, v_or: List[tuple] = None, **kwargs): """ 获取数据总数 - :param v_join_query: 外键字段查询 + :param v_options: 指示应使用select在预加载中加载给定的属性。 + :param v_join_query: 外键字段查询 + :param v_or: 或逻辑查询 :param kwargs: 查询参数 """ sql = select(func.count(self.model.id).label('total')).where(self.model.is_delete == False) - sql = self.add_filter_condition(sql, v_join_query, v_options, **kwargs) + sql = self.add_filter_condition(sql, v_options, v_join_query, v_or, **kwargs) queryset = await self.db.execute(sql) return queryset.one()['total'] @@ -189,72 +195,118 @@ class DalBase: else: await self.db.execute(delete(self.model).where(self.model.id.in_(ids))) - def add_filter_condition(self, sql: select, v_join_query: dict = None, v_options: list = None, **kwargs) -> select: + def add_filter_condition( + self, + sql: select, + v_options: list = None, + v_join_query: dict = None, + v_or: List[tuple] = None, + **kwargs + ) -> select: """ 添加过滤条件,以及内连接过滤条件 :param sql: - :param v_join_query: 外键字段查询,内连接 :param v_options: 指示应使用select在预加载中加载给定的属性。 + :param v_join_query: 外键字段查询,内连接 + :param v_or: 或逻辑 :param kwargs: 关键词参数 """ - if v_join_query and self.key_models: + v_join: Set[str] = set() + v_join_left: Set[str] = set() + if v_join_query: for key, value in v_join_query.items(): foreign_key = self.key_models.get(key) - if foreign_key and foreign_key.get("model"): - # 当外键模型在查询模型中存在多个外键时,则需要添加onclause属性 - sql = sql.join(foreign_key.get("model"), onclause=foreign_key.get("onclause", None)) - for v_key, v_value in value.items(): - if v_value is not None and v_value != "": - v_attr = getattr(foreign_key.get("model"), v_key, None) - sql = self.filter_condition(sql, v_attr, v_value) - else: - logger.error(f"外键查询报错:{key}模型不存在,无法进行下一步查询。") - elif v_join_query and not self.key_models: - logger.error(f"外键查询报错:key_models 外键模型无配置项,无法进行下一步查询。") - for field in kwargs: - value = kwargs.get(field) - if value is not None and value != "": - attr = getattr(self.model, field, None) - sql = self.filter_condition(sql, attr, value) + conditions = [] + self.__dict_filter(conditions, foreign_key.get("model"), **value) + if conditions: + sql = sql.where(*conditions) + v_join.add(key) + if v_or: + sql = self.__or_filter(sql, v_or, v_join_left, v_join) + for item in v_join: + foreign_key = self.key_models.get(item) + # 当外键模型在查询模型中存在多个外键时,则需要添加onclause属性 + sql = sql.join(foreign_key.get("model"), onclause=foreign_key.get("onclause")) + for item in v_join_left: + foreign_key = self.key_models.get(item) + # 当外键模型在查询模型中存在多个外键时,则需要添加onclause属性 + sql = sql.outerjoin(foreign_key.get("model"), onclause=foreign_key.get("onclause")) + conditions = [] + self.__dict_filter(conditions, self.model, **kwargs) + if conditions: + sql = sql.where(*conditions) if v_options: sql = sql.options(*[load for load in v_options]) return sql - @classmethod - def filter_condition(cls, sql: Any, attr: Any, value: Any): + def __or_filter(self, sql: select, v_or: List[tuple], v_join_left: Set[str], v_join: Set[str]): """ - 过滤条件 + 或逻辑操作 + :param sql: + :param v_or: 或逻辑 + :param v_join_left: 左连接 + :param v_join: 内连接 """ - if not attr: - return sql - if isinstance(value, tuple): - if len(value) == 1: - if value[0] == "None": - sql = sql.where(attr.is_(None)) - elif value[0] == "not None": - sql = sql.where(attr.isnot(None)) - elif len(value) == 2 and value[1] is not None: - if value[0] == "date": - # 根据日期查询, 关键函数是:func.time_format和func.date_format - sql = sql.where(func.date_format(attr, "%Y-%m-%d") == value[1]) - elif value[0] == "like": - sql = sql.where(attr.like(f"%{value[1]}%")) - elif value[0] == "or": - sql = sql.where(or_(i for i in value[1])) - elif value[0] == "in": - sql = sql.where(attr.in_(value[1])) - elif value[0] == "between" and len(value[1]) == 2: - sql = sql.where(attr.between(value[1][0], value[1][1])) - elif value[0] == "month": - sql = sql.where(func.date_format(attr, "%Y-%m") == value[1]) - elif value[0] == "!=": - sql = sql.where(attr != value[1]) - elif value[0] == ">": - sql = sql.where(attr > value[1]) - else: - sql = sql.where(attr == value) + or_list = [] + for item in v_or: + if len(item) == 2: + model = self.model + condition = {item[0]: item[1]} + self.__dict_filter(or_list, model, **condition) + elif len(item) == 4 and item[0] == "fk": + model = self.key_models.get(item[1]).get("model") + condition = {item[2]: item[3]} + conditions = [] + self.__dict_filter(conditions, model, **condition) + if conditions: + or_list = or_list + conditions + v_join_left.add(item[1]) + if item[1] in v_join: + v_join.remove(item[1]) + else: + raise CustomException(msg="v_or 获取查询属性失败,语法错误!") + if or_list: + sql = sql.where(or_(i for i in or_list)) return sql + def __dict_filter(self, conditions: list, model, **kwargs): + """ + 字典过滤 + :param model: + :param kwargs: + """ + for field, value in kwargs.items(): + if value is not None and value != "": + attr = getattr(model, field) + if isinstance(value, tuple): + if len(value) == 1: + if value[0] == "None": + conditions.append(attr.is_(None)) + elif value[0] == "not None": + conditions.append(attr.isnot(None)) + else: + raise CustomException("SQL查询语法错误") + elif len(value) == 2 and value[1] not in [None, [], ""]: + if value[0] == "date": + # 根据日期查询, 关键函数是:func.time_format和func.date_format + conditions.append(func.date_format(attr, "%Y-%m-%d") == value[1]) + elif value[0] == "like": + conditions.append(attr.like(f"%{value[1]}%")) + elif value[0] == "in": + conditions.append(attr.in_(value[1])) + elif value[0] == "between" and len(value[1]) == 2: + conditions.append(attr.between(value[1][0], value[1][1])) + elif value[0] == "month": + conditions.append(func.date_format(attr, "%Y-%m") == value[1]) + elif value[0] == "!=": + conditions.append(attr != value[1]) + elif value[0] == ">": + conditions.append(attr > value[1]) + else: + raise CustomException("SQL查询语法错误") + else: + conditions.append(attr == value) + async def flush(self, obj: Any = None): """ 刷新到数据库 diff --git a/kinit-api/core/data_types.py b/kinit-api/core/data_types.py index e67a0df..edd12e1 100644 --- a/kinit-api/core/data_types.py +++ b/kinit-api/core/data_types.py @@ -37,6 +37,17 @@ class Telephone(str): return vali_telephone(v) +class Email(str): + + @classmethod + def __get_validators__(cls): + yield cls.validate + + @classmethod + def validate(cls, v): + return vali_email(v) + + class DateStr(str): @classmethod diff --git a/kinit-api/core/exception.py b/kinit-api/core/exception.py index 72bfa05..773a6cf 100644 --- a/kinit-api/core/exception.py +++ b/kinit-api/core/exception.py @@ -16,7 +16,8 @@ from core.logger import logger class CustomException(Exception): - def __init__(self, msg: str, code: int, status_code: int = status.HTTP_200_OK): + + def __init__(self, msg: str, code: int = status.HTTP_400_BAD_REQUEST, status_code: int = status.HTTP_200_OK): self.msg = msg self.code = code self.status_code = status_code @@ -33,7 +34,7 @@ def register_exception(app: FastAPI): 自定义异常 """ return JSONResponse( - status_code=200, + status_code=exc.status_code, content={"message": exc.msg, "code": exc.code}, ) diff --git a/kinit-api/core/logger.py b/kinit-api/core/logger.py index bf0645c..4e0d9df 100644 --- a/kinit-api/core/logger.py +++ b/kinit-api/core/logger.py @@ -24,5 +24,6 @@ error = logger.add(log_path_error, rotation="00:00", retention="3 days", enqueue if __name__ == '__main__': print(BASE_DIR) - logger.info("hell") - logger.error("hell") + # logger.info("1") + retry: int = 1 + logger.error("未从Redis中获取到配置信息,正在重新更新配置信息,重试次数:{}。".format(retry)) diff --git a/kinit-api/core/validator.py b/kinit-api/core/validator.py index d04e35e..59c1f49 100644 --- a/kinit-api/core/validator.py +++ b/kinit-api/core/validator.py @@ -22,13 +22,30 @@ def vali_telephone(value: str) -> str: if not value or len(value) != 11 or not value.isdigit(): raise ValueError("请输入正确手机号") - REGEX_TELEPHONE = r'^1(3\d|4[4-9]|5[0-35-9]|6[67]|7[013-8]|8[0-9]|9[0-9])\d{8}$' + regex = r'^1(3\d|4[4-9]|5[0-35-9]|6[67]|7[013-8]|8[0-9]|9[0-9])\d{8}$' - if not re.match(REGEX_TELEPHONE, value): + if not re.match(regex, value): raise ValueError("请输入正确手机号") return value +def vali_email(value: str) -> str: + """ + 邮箱地址验证器 + :param value: 邮箱 + :return: 邮箱 + """ + if not value: + raise ValueError("请输入邮箱地址") + + regex = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$' + + if not re.match(regex, value): + raise ValueError("请输入正确邮箱地址") + + return value + + diff --git a/kinit-api/scripts/initialize/data/init.xlsx b/kinit-api/scripts/initialize/data/init.xlsx index 0a95a968fcdccad650125f4e4facb70f46c4062d..db9cbcaa1708b51ab0172e1514d67579066a654a 100644 GIT binary patch literal 43869 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%0A1W2rv~$NzS&pQbVJ8B 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 literal 43249 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 diff --git a/kinit-api/utils/cache.py b/kinit-api/utils/cache.py index 5b4fec7..01a443f 100644 --- a/kinit-api/utils/cache.py +++ b/kinit-api/utils/cache.py @@ -42,13 +42,13 @@ class Cache: """ 获取系统配置 :params tab_name: 配置表标签名称 - :params retry: 重试次数 + :params retry_num: 重试次数 """ result = await self.rd.get(tab_name) if not result and retry > 0: - logger.error(f"未从Redis中获取到{tab_name}配置信息,正在重新更新配置信息,重试次数:{retry}") + logger.error(f"未从Redis中获取到{tab_name}配置信息,正在重新更新配置信息,重试次数:{retry}。") await self.cache_tab_names([tab_name]) - await self.get_tab_name(tab_name, retry - 1) + return await self.get_tab_name(tab_name, retry - 1) elif not result and retry == 0: raise CustomException(f"获取{tab_name}配置信息失败,请联系管理员!", code=status.HTTP_ERROR) else: diff --git a/kinit-api/utils/wx/oauth.py b/kinit-api/utils/wx/oauth.py index 19e309e..7f503c1 100644 --- a/kinit-api/utils/wx/oauth.py +++ b/kinit-api/utils/wx/oauth.py @@ -6,7 +6,6 @@ # @IDE : PyCharm # @desc : 简要说明 -import json import requests from core.logger import logger from utils.cache import Cache