@@ -49,7 +57,7 @@
新增
查看
- 删除
+ 禁用
导出
重置
@@ -57,36 +65,31 @@
-
+
-
-
{{s.row.username}}
-
{{s.row.tell}}
+
{{s.row.username}} / {{s.row.nickname}}
+
{{s.row.student_id}} / {{s.row.phone}}
-
-
-
- 共{{s.row.photo_list.length}}张, 点击预览
-
-
+
+
-
-
- 正常
- 禁用
+
+ 正常
+ 禁用
详情
- 删除
+ 禁用
@@ -117,33 +120,42 @@
data: {
p: { // 查询参数
username: '',
+ nickname: '',
+ real_name: '',
create_type: 0,
sortType: 1,
- start_time: new Date().getFullYear() + '-' + (new Date().getMonth() + 1) + '-1', // 本月一号
- end_time: new Date().getFullYear() + '-' + (new Date().getMonth() + 1) + '-' + new Date().getDate(), // 本月当日
+ start_time: new Date().getFullYear() + '-' + (new Date().getMonth() + 1) + '-1', // 本月一号
+ end_time: new Date().getFullYear() + '-' + (new Date().getMonth() + 1) + '-' + new Date().getDate(), // 本月当日
pageNo: 1,
pageSize: 10,
},
- dataCount: 1422,
+ dataCount: 0,
dataList: []
},
methods: {
// 数据刷新
f5: function() {
- sa.ajax2('/user/getList', this.p, function(res){
- this.dataList = res.data; // 数据
- this.dataCount = res.dataCount; // 分页
+ sa.ajax('/user/admin/list', this.p, function(res){
+ this.dataList = res.data.data; // 数据
+ for (let i = 0; i < this.dataList.length; i++) {
+ this.dataList[i].status = this.dataList[i].is_active ? 1 : 0;
+ }
+ this.dataCount = res.data.count; // 分页
sa.f5TableHeight(); // 刷新表格高度
- }.bind(this), {res: mockData});
+ }.bind(this), {});
},
// 查看
get: function(data) {
var str = '
';
str += '
编号:' + data.id + '
';
- str += '
昵称:' + data.username + '
';
+ str += '
用户名:' + data.username + '
';
+ str += '
昵称:' + data.nickname + '
';
+ str += '
真实姓名:' + data.real_name + '
';
+ str += '
学号:' + data.student_id + '
';
+ str += '
电话:' + data.phone + '
';
+ str += '
邮箱:' + data.email + '
';
str += '
性别:' + data.sex + '
';
str += '
当前状态:' + (data.status == 1 ? '正常' : '禁用') + '
';
- str += '
注册方式:' + data.create_type + '
';
str += '
注册时间:' + data.create_time + '
';
str += '
';
sa.alert(str);
diff --git a/src/route/users_admin.py b/src/route/users_admin.py
new file mode 100644
index 0000000..7e9b10c
--- /dev/null
+++ b/src/route/users_admin.py
@@ -0,0 +1,46 @@
+from fastapi import HTTPException
+from fastapi_amis_admin.crud import BaseApiOut
+from starlette import status
+
+from src.plugin import handler
+from src.plugin.plugin import Plugin
+from src.services.users.schemas import UserList
+from src.services.users.services import UserServices
+
+
+class UserRoutes(Plugin):
+ _prefix = "/user/admin"
+
+ def __init__(
+ self,
+ user_services: UserServices,
+ ):
+ self.user_services = user_services
+
+ @handler.post("/list", student=True)
+ async def get_user_list(self, data: UserList):
+ username, nickname, real_name = data.username, data.nickname, data.real_name
+ start_time, end_time = data.start, data.end
+ page_no, page_size = data.pageNo, data.pageSize
+ if page_no < 1:
+ page_no = 1
+ if page_size < 0 or page_size > 100:
+ page_size = 10
+ try:
+ data, count = await self.user_services.get_user_list(
+ username,
+ nickname,
+ real_name,
+ start_time,
+ end_time,
+ page_no,
+ page_size,
+ )
+ return BaseApiOut(
+ code=0, msg="请求成功", data={"data": data, "count": count}
+ )
+ except Exception as e:
+ raise HTTPException(
+ status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
+ detail=f"Error Execute SQL:{e}",
+ ) from e
diff --git a/src/services/users/repositories.py b/src/services/users/repositories.py
index 8f1c99a..4cad8db 100644
--- a/src/services/users/repositories.py
+++ b/src/services/users/repositories.py
@@ -1,11 +1,13 @@
-from typing import Optional, Sequence
+from datetime import datetime
+from typing import Optional, Sequence, Tuple
from fastapi_user_auth.auth import Auth
from fastapi_user_auth.auth.backends.redis import RedisTokenStore
from fastapi_user_auth.auth.models import CasbinRule, LoginHistory
from persica.factory.component import AsyncInitializingComponent
from pydantic import SecretStr
-from sqlmodel import select
+from sqlalchemy import func
+from sqlmodel import select, col
from sqlmodel.ext.asyncio.session import AsyncSession
from src.core.database import Database
@@ -133,3 +135,49 @@ class UserRepo(AsyncInitializingComponent):
await session.commit()
await session.refresh(user)
return user
+
+ @staticmethod
+ async def get_count(session, q) -> int:
+ count_q = (
+ q.with_only_columns(func.count())
+ .order_by(None)
+ .select_from(q.get_final_froms()[0])
+ )
+ iterator = await session.exec(count_q)
+ for count in iterator:
+ return count
+ return 0
+
+ async def get_user_list(
+ self,
+ username: str,
+ nickname: str,
+ real_name: str,
+ start_time: datetime,
+ end_time: datetime,
+ page_no: int,
+ page_size: int,
+ ) -> Tuple[Sequence[UserModel], int]:
+ async with AsyncSession(self.engine) as session:
+ statement = select(self.user_model)
+ if username:
+ statement = statement.where(
+ col(self.user_model.username).like(f"%{username}%")
+ )
+ if nickname:
+ statement = statement.where(
+ col(self.user_model.nickname).like(f"%{nickname}%")
+ )
+ if real_name:
+ statement = statement.where(
+ col(self.user_model.real_name).like(f"%{real_name}%")
+ )
+ if start_time:
+ statement = statement.where(self.user_model.create_time >= start_time)
+ if end_time:
+ statement = statement.where(self.user_model.create_time <= end_time)
+ all_count = await self.get_count(session, statement)
+ offset = (page_no - 1) * page_size
+ statement = statement.offset(offset).limit(page_size)
+ r = await session.exec(statement)
+ return r.all(), all_count
diff --git a/src/services/users/schemas.py b/src/services/users/schemas.py
index c7d08bb..4af67b7 100644
--- a/src/services/users/schemas.py
+++ b/src/services/users/schemas.py
@@ -1,3 +1,4 @@
+from datetime import date, datetime
from enum import Enum
from typing import Optional
@@ -107,3 +108,27 @@ class UserRoleEnum(str, Enum):
ADMIN = "admin" # 管理员
STUDENT = "student" # 教职工
OUT = "out" # 校外人员
+
+
+class UserList(BaseModel):
+ username: str = ""
+ nickname: str = ""
+ real_name: str = ""
+
+ sortType: int = 1
+ start_time: str
+ end_time: str
+ pageNo: int = 1
+ pageSize: int = 10
+
+ @property
+ def start(self):
+ y, m, d = self.start_time.split("-")
+ start_time = date(int(y), int(m), int(d))
+ return datetime.combine(start_time, datetime.min.time())
+
+ @property
+ def end(self):
+ y, m, d = self.end_time.split("-")
+ end_time = date(int(y), int(m), int(d))
+ return datetime.combine(end_time, datetime.max.time())
diff --git a/src/services/users/services.py b/src/services/users/services.py
index 4ab0199..3a9ed53 100644
--- a/src/services/users/services.py
+++ b/src/services/users/services.py
@@ -1,4 +1,5 @@
-from typing import Optional, List, Union, Sequence
+from datetime import datetime
+from typing import Optional, List, Union, Sequence, Tuple
from fastapi_user_auth.auth.models import CasbinRule, LoginHistory
from fastapi_user_auth.utils.casbin import update_subject_roles
@@ -96,6 +97,20 @@ class UserServices(AsyncInitializingComponent):
user.avatar = avatar
return await self.repo.update_user(user)
+ async def get_user_list(
+ self,
+ username: str,
+ nickname: str,
+ real_name: str,
+ start_time: datetime,
+ end_time: datetime,
+ page_no: int,
+ page_size: int,
+ ) -> Tuple[Sequence[UserModel], int]:
+ return await self.repo.get_user_list(
+ username, nickname, real_name, start_time, end_time, page_no, page_size
+ )
+
class UserRoleServices(AsyncInitializingComponent):
__order__ = 1