feat: feat: face admin get list
This commit is contained in:
parent
2cda4a2ecd
commit
eeccb88ebe
@ -84,7 +84,9 @@
|
||||
location.href = "register.html";
|
||||
}else{
|
||||
sa.closeCurrIframe();
|
||||
parent.sa.$page.openReg("register.html", false);
|
||||
var shadeClose = parseInt(sa.p('canClose', 0)) === 1;
|
||||
var shadeCloseInt = shadeClose ? 1 : 0;
|
||||
parent.sa.$page.openReg("register.html?canClose=" + shadeCloseInt, shadeClose);
|
||||
}
|
||||
}
|
||||
// 点击登录按钮
|
||||
|
@ -122,7 +122,9 @@
|
||||
location.href = "login.html";
|
||||
}else{
|
||||
sa.closeCurrIframe();
|
||||
parent.sa.$page.openLogin("login.html", false);
|
||||
var shadeClose = parseInt(sa.p('canClose', 0)) === 1;
|
||||
var shadeCloseInt = shadeClose ? 1 : 0;
|
||||
parent.sa.$page.openLogin("login.html?canClose=" + shadeCloseInt, shadeClose);
|
||||
}
|
||||
}
|
||||
// 选择注册类型
|
||||
|
@ -175,4 +175,13 @@ var adminMenuList = [
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
id: '6',
|
||||
name: '人脸信息管理',
|
||||
icon: 'el-icon-search',
|
||||
info: '人脸信息管理',
|
||||
childList: [
|
||||
{id: '6-1', name: '人脸信息列表', icon: 'el-icon-document-remove', url: 'sa-view/face/face-list.html'},
|
||||
]
|
||||
},
|
||||
]
|
||||
|
@ -63,7 +63,7 @@ sa_admin.dropList = [ // 头像点击处可操作的选项
|
||||
{
|
||||
name: '切换账号',
|
||||
click: function() {
|
||||
sa.$page.openLogin('login.html', true);
|
||||
sa.$page.openLogin('login.html?canClose=1', true);
|
||||
// layer.open({
|
||||
// type: 2,
|
||||
// title: false,
|
||||
|
237
src/frontend/sa-view/face/face-list.html
Normal file
237
src/frontend/sa-view/face/face-list.html
Normal file
@ -0,0 +1,237 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>人脸信息列表</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
|
||||
<!-- 所有的 css & js 资源 -->
|
||||
<link rel="stylesheet" href="https://unpkg.com/element-ui@2.13.0/lib/theme-chalk/index.css">
|
||||
<link rel="stylesheet" href="../../static/sa.css">
|
||||
<script src="https://unpkg.com/vue@2.6.10/dist/vue.js"></script>
|
||||
<script src="https://unpkg.com/element-ui@2.13.0/lib/index.js"></script>
|
||||
<script src="https://unpkg.com/http-vue-loader@1.4.2/src/httpVueLoader.js"></script>
|
||||
<script src="https://unpkg.com/jquery@3.4.1/dist/jquery.min.js"></script>
|
||||
<script src="../../static/kj/layer/layer.js"></script>
|
||||
<script src="../../static/sa.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="vue-box" style="display: none;" :style="'display: block;'">
|
||||
<div class="c-panel">
|
||||
<!-- ------------- 检索参数 ------------- -->
|
||||
<div class="c-title">人脸列表</div>
|
||||
<el-form>
|
||||
<div class="c-item">
|
||||
<label class="c-label">用户 ID:</label>
|
||||
<el-input v-model="p.user_id" placeholder=""></el-input>
|
||||
</div>
|
||||
<div class="c-item">
|
||||
<label class="c-label">删除状态:</label>
|
||||
<el-select v-model="p.deleted">
|
||||
<el-option label="所有" :value="0"></el-option>
|
||||
<el-option label="已被删除" :value="1"></el-option>
|
||||
<el-option label="未被删除" :value="2"></el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="c-item">
|
||||
<label class="c-label">批准状态:</label>
|
||||
<el-select v-model="p.approved">
|
||||
<el-option label="所有" :value="0"></el-option>
|
||||
<el-option label="已被批准" :value="1"></el-option>
|
||||
<el-option label="未被批准" :value="2"></el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
<br />
|
||||
<div class="c-item">
|
||||
<label class="c-label">创建日期:</label>
|
||||
<el-date-picker v-model="p.start_time" type="date" value-format="yyyy-MM-dd" placeholder="开始日期"></el-date-picker> -
|
||||
<el-date-picker v-model="p.end_time" type="date" value-format="yyyy-MM-dd" placeholder="结束日期"></el-date-picker>
|
||||
</div>
|
||||
<div class="c-item" style="min-width: 0px;">
|
||||
<el-button type="primary" icon="el-icon-search" @click="p.pageNo = 1; f5()">查询</el-button>
|
||||
</div>
|
||||
<br />
|
||||
<div class="c-item s-radio-text">
|
||||
<label class="c-label">综合排序:</label>
|
||||
<el-radio-group v-model="p.sortType">
|
||||
<el-radio :label="1">创建时间</el-radio>
|
||||
<el-radio :label="2">用户 ID</el-radio>
|
||||
<el-radio :label="3">是否批准</el-radio>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
</el-form>
|
||||
<!-- <div class="c-title">数据列表</div> -->
|
||||
<!-- ------------- 快捷按钮 ------------- -->
|
||||
<div class="fast-btn">
|
||||
<!-- <el-button type="primary" icon="el-icon-plus" @click="add()">新增</el-button>-->
|
||||
<el-button type="success" icon="el-icon-view" @click="getBySelect()">查看</el-button>
|
||||
<el-button type="success" icon="el-icon-check" @click="deleteByIds()">批准</el-button>
|
||||
<el-button type="danger" icon="el-icon-delete" @click="deleteByIds()">禁用</el-button>
|
||||
<el-button type="warning" icon="el-icon-download" @click="sa.exportExcel()">导出</el-button>
|
||||
<el-button type="info" icon="el-icon-refresh" @click="sa.f5()">重置</el-button>
|
||||
</div>
|
||||
<!-- ------------- 数据列表 ------------- -->
|
||||
<el-table class="data-table" ref="data-table" :data="dataList" size="small">
|
||||
<el-table-column type="selection" width="45px"></el-table-column>
|
||||
<el-table-column label="编号" prop="id" width="80px" > </el-table-column>
|
||||
<el-table-column label="人脸" prop="username" width="220px">
|
||||
<template slot-scope="s">
|
||||
<img :src="sa.cfg.api_url + s.row.image" @click="sa.showImage(sa.cfg.api_url + s.row.image, '400px', '400px')"
|
||||
style="width: 3em; height: 3em; float: left; margin-right: 1em; border-radius: 50%; cursor: pointer;" >
|
||||
<div style="float: left; width: 130px; line-height: 40px;">
|
||||
<b>UID: {{s.row.user_id}}</b>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="创建于" prop="create_time"></el-table-column>
|
||||
<el-table-column label="删除状态">
|
||||
<template slot-scope="s">
|
||||
<el-switch v-model="s.row.status_delete" :active-value="1" :inactive-value="0" inactive-color="#ff4949"></el-switch>
|
||||
<b style="color: green;" v-if="s.row.status_delete === 1">已被删除</b>
|
||||
<b style="color: red;" v-if="s.row.status_delete === 0">未被删除</b>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="状态">
|
||||
<template slot-scope="s">
|
||||
<el-switch v-model="s.row.status" :active-value="1" :inactive-value="0" inactive-color="#ff4949"></el-switch>
|
||||
<b style="color: green;" v-if="s.row.status === 1">已批准</b>
|
||||
<b style="color: red;" v-if="s.row.status === 0">未批准</b>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="address" label="操作">
|
||||
<template slot-scope="s">
|
||||
<el-button class="c-btn" type="success" icon="el-icon-view" @click="get(s.row)">详情</el-button>
|
||||
<el-button v-if="s.row.status === 1" class="c-btn" type="danger" icon="el-icon-delete" @click="del(s.row)">禁用</el-button>
|
||||
<el-button v-if="s.row.status === 0" class="c-btn" type="success" icon="el-icon-check" @click="del(s.row)">批准</el-button>
|
||||
<el-button v-if="s.row.status_delete === 0" class="c-btn" type="danger" icon="el-icon-delete" @click="del(s.row)">删除</el-button>
|
||||
<el-button v-if="s.row.status_delete === 1" class="c-btn" type="success" icon="el-icon-check" @click="del(s.row)">撤销</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- ------------- 分页 ------------- -->
|
||||
<div class="page-box">
|
||||
<el-pagination background
|
||||
layout="total, prev, pager, next, sizes, jumper"
|
||||
:current-page.sync="p.pageNo"
|
||||
:page-size.sync="p.pageSize"
|
||||
:total="dataCount"
|
||||
:page-sizes="[1, 10, 20, 30, 40, 50, 100]"
|
||||
@current-change="f5(true)"
|
||||
@size-change="f5(true)">
|
||||
</el-pagination>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 给layer打一波广告 -->
|
||||
<!-- <div class="c-panel" style="background-color: rgba(0,0,0,0);">
|
||||
layer:<el-link type="primary" href="http://layer.layui.com/" target="_blank">
|
||||
一个可以让你想到即可做到的JavaScript弹窗(层)解决方案
|
||||
</el-link>
|
||||
</div> -->
|
||||
</div>
|
||||
<script src="data-list.js"></script>
|
||||
<script type="text/javascript">
|
||||
sa.checkAuth('admin');
|
||||
var app = new Vue({
|
||||
el: '.vue-box',
|
||||
data: {
|
||||
p: { // 查询参数
|
||||
user_id: sa.p("user_id", '0'),
|
||||
deleted: 0,
|
||||
approved: 0,
|
||||
sortType: 1,
|
||||
start_time: '',
|
||||
end_time: '',
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
},
|
||||
dataCount: 0,
|
||||
dataList: []
|
||||
},
|
||||
methods: {
|
||||
// 数据刷新
|
||||
f5: function() {
|
||||
sa.ajax('/face/admin/image/list', this.p, function(res){
|
||||
this.dataList = res.data.data; // 数据
|
||||
for (let i = 0; i < this.dataList.length; i++) {
|
||||
this.dataList[i].image = '/face/view/' + this.dataList[i].image;
|
||||
this.dataList[i].status_delete = this.dataList[i].delete_time !== null ? 1 : 0;
|
||||
this.dataList[i].status = this.dataList[i].is_approved ? 1 : 0;
|
||||
}
|
||||
this.dataCount = res.data.count; // 分页
|
||||
sa.f5TableHeight(); // 刷新表格高度
|
||||
}.bind(this), {});
|
||||
},
|
||||
// 查看
|
||||
get: function(data) {
|
||||
var str = '<div>';
|
||||
str += '<p>编号:' + data.id + '</p>';
|
||||
str += '<p>用户 ID:' + data.user_id + '</p>';
|
||||
str += '<p>当前状态:<b>' + (data.status == 1 ? '已批准' : '未批准') + '</b></p>';
|
||||
str += '<p>创建时间:' + data.create_time + '</p>';
|
||||
str += '<p>更新时间:' + data.update_time + '</p>';
|
||||
str += '<p>删除时间:' + data.delete_time + '</p>';
|
||||
str += '</div>';
|
||||
sa.alert(str);
|
||||
},
|
||||
// 查看 - 根据选中的
|
||||
getBySelect: function(data) {
|
||||
var selection = this.$refs['data-table'].selection;
|
||||
if(selection.length == 0) {
|
||||
return sa.msg('请选择一条数据')
|
||||
}
|
||||
this.get(selection[0]);
|
||||
},
|
||||
// 删除
|
||||
del: function(data) {
|
||||
sa.confirm('是否修改,此操作可撤销', function() {
|
||||
sa.ajax('/user/admin/change_status', {user_id: data.id, is_active: !data.is_active}, function(res) {
|
||||
// sa.arrayDelete(this.dataList, data);
|
||||
if (data.is_active) {
|
||||
sa.ok('禁用成功');
|
||||
} else {
|
||||
sa.ok('启用成功');
|
||||
}
|
||||
this.f5();
|
||||
}.bind(this), {})
|
||||
}.bind(this));
|
||||
},
|
||||
// 重置密码
|
||||
reset_pwd: function (data) {
|
||||
sa.confirm('是否重置密码,此操作不可撤销', function() {
|
||||
sa.ajax('/user/admin/reset_password', {user_id: data.id}, function(res) {
|
||||
sa.ok('重置密码成功');
|
||||
}.bind(this), {})
|
||||
}.bind(this));
|
||||
},
|
||||
// 批量删除
|
||||
deleteByIds: function() {
|
||||
// 获取选中元素的id列表
|
||||
let selection = this.$refs['data-table'].selection;
|
||||
let ids = sa.getArrayField(selection, 'id');
|
||||
if(selection.length == 0) {
|
||||
return sa.msg('请至少选择一条数据')
|
||||
}
|
||||
// 提交删除
|
||||
sa.confirm('是否批量禁用选中用户?此操作可撤销', function() {
|
||||
sa.ajax2('/user/admin/change_status', {ids: ids}, function(res) {
|
||||
sa.arrayDelete(this.dataList, selection);
|
||||
sa.ok('删除成功');
|
||||
sa.f5TableHeight(); // 刷新表格高度
|
||||
}.bind(this))
|
||||
}.bind(this));
|
||||
},
|
||||
},
|
||||
created: function(){
|
||||
this.f5()
|
||||
sa.onInputEnter(); // 监听输入框的回车事件,执行查询
|
||||
}
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
@ -113,8 +113,10 @@
|
||||
<el-table-column prop="address" label="操作">
|
||||
<template slot-scope="s">
|
||||
<el-button class="c-btn" type="success" icon="el-icon-view" @click="get(s.row)">详情</el-button>
|
||||
<el-button class="c-btn" type="success" icon="el-icon-view" @click="getFace(s.row)">人脸信息</el-button>
|
||||
<el-button class="c-btn" type="danger" icon="el-icon-delete" @click="reset_pwd(s.row)">重置密码</el-button>
|
||||
<el-button class="c-btn" type="danger" icon="el-icon-delete" @click="del(s.row)">禁/启用</el-button>
|
||||
<el-button v-if="s.row.status === 1" class="c-btn" type="danger" icon="el-icon-delete" @click="del(s.row)">禁用</el-button>
|
||||
<el-button v-if="s.row.status === 0" class="c-btn" type="success" icon="el-icon-check" @click="del(s.row)">启用</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@ -190,6 +192,10 @@
|
||||
str += '</div>';
|
||||
sa.alert(str);
|
||||
},
|
||||
// 查看人脸信息
|
||||
getFace: function(data) {
|
||||
sa.showIframe('人脸信息', '../face/face-list.html?user_id=' + data.id, '900px', '600px');
|
||||
},
|
||||
// 查看 - 根据选中的
|
||||
getBySelect: function(data) {
|
||||
var selection = this.$refs['data-table'].selection;
|
||||
|
@ -1,10 +1,10 @@
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from fastapi import UploadFile, File
|
||||
from fastapi_amis_admin.crud import BaseApiOut
|
||||
from starlette import status
|
||||
from starlette.exceptions import HTTPException
|
||||
from starlette.requests import Request
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from starlette.responses import FileResponse
|
||||
|
||||
from src.plugin import handler
|
||||
|
52
src/route/face_image_admin.py
Normal file
52
src/route/face_image_admin.py
Normal file
@ -0,0 +1,52 @@
|
||||
from fastapi_amis_admin.crud import BaseApiOut
|
||||
from starlette import status
|
||||
from starlette.exceptions import HTTPException
|
||||
|
||||
from src.plugin import handler
|
||||
from src.plugin.plugin import Plugin
|
||||
from src.services.face_image.schemas import FaceList
|
||||
from src.services.face_image.services import FaceImageServices
|
||||
from src.services.users.services import UserRoleServices
|
||||
|
||||
|
||||
class FaceImageAdminRoutes(Plugin):
|
||||
_prefix = "/face/admin"
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
face_image_services: FaceImageServices,
|
||||
user_role_services: UserRoleServices,
|
||||
):
|
||||
self.face_image_services = face_image_services
|
||||
self.user_role_services = user_role_services
|
||||
self.avatar_path = "/face/view/"
|
||||
|
||||
@handler.post("/image/list", student=True)
|
||||
async def get_me_face_images(self, data: FaceList):
|
||||
user_id = data.user_id
|
||||
deleted, approved, sort_type = data.deleted, data.approved, data.sortType
|
||||
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.face_image_services.get_image_list(
|
||||
user_id,
|
||||
deleted,
|
||||
approved,
|
||||
sort_type,
|
||||
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
|
@ -1,9 +1,8 @@
|
||||
import datetime
|
||||
from typing import TYPE_CHECKING, Union
|
||||
|
||||
from fastapi_amis_admin.crud import BaseApiOut
|
||||
|
||||
from fastapi import HTTPException
|
||||
from fastapi_amis_admin.crud import BaseApiOut
|
||||
from starlette import status
|
||||
from starlette.requests import Request
|
||||
from starlette.responses import Response
|
||||
|
@ -9,7 +9,6 @@ from src.services.users.schemas import (
|
||||
UserList,
|
||||
DisableOrEnableUser,
|
||||
UserAdminAdd,
|
||||
UserRoleEnum,
|
||||
CreateTypeEnum,
|
||||
)
|
||||
from src.services.users.services import UserServices
|
||||
|
@ -2,7 +2,6 @@ from fastapi import File, UploadFile
|
||||
from fastapi_amis_admin.crud import BaseApiOut
|
||||
from starlette import status
|
||||
from starlette.exceptions import HTTPException
|
||||
|
||||
from starlette.requests import Request
|
||||
from starlette.responses import FileResponse
|
||||
|
||||
|
@ -1,11 +1,14 @@
|
||||
from typing import Optional, Sequence
|
||||
from datetime import datetime
|
||||
from typing import Optional, Sequence, Tuple
|
||||
|
||||
from persica.factory.component import AsyncInitializingComponent
|
||||
from sqlalchemy import func
|
||||
from sqlmodel.ext.asyncio.session import AsyncSession
|
||||
from sqlmodel import select, col
|
||||
|
||||
from src.core.database import Database
|
||||
from src.services.face_image.models import FaceImageModel
|
||||
from src.services.face_image.schemas import TypeEnum, SortTypeEnum
|
||||
|
||||
|
||||
class FaceImageRepo(AsyncInitializingComponent):
|
||||
@ -52,3 +55,61 @@ class FaceImageRepo(AsyncInitializingComponent):
|
||||
await session.commit()
|
||||
await session.refresh(image)
|
||||
return image
|
||||
|
||||
@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_image_list(
|
||||
self,
|
||||
user_id: Optional[int],
|
||||
deleted: Optional[TypeEnum],
|
||||
approved: Optional[TypeEnum],
|
||||
sort_type: Optional[SortTypeEnum],
|
||||
start_time: Optional[datetime],
|
||||
end_time: Optional[datetime],
|
||||
page_no: int,
|
||||
page_size: int,
|
||||
) -> Tuple[Sequence[FaceImageModel], int]:
|
||||
async with AsyncSession(self.engine) as session:
|
||||
statement = select(FaceImageModel)
|
||||
if user_id:
|
||||
statement = statement.where(FaceImageModel.user_id == user_id)
|
||||
if deleted:
|
||||
if deleted is TypeEnum.DO:
|
||||
statement = statement.where(
|
||||
col(FaceImageModel.delete_time).isnot(None)
|
||||
)
|
||||
elif deleted is TypeEnum.UNDO:
|
||||
statement = statement.where(
|
||||
col(FaceImageModel.delete_time).is_(None)
|
||||
)
|
||||
if approved:
|
||||
if approved is TypeEnum.DO:
|
||||
statement = statement.where(FaceImageModel.is_approved == True)
|
||||
elif approved is TypeEnum.UNDO:
|
||||
statement = statement.where(FaceImageModel.is_approved == False)
|
||||
if start_time:
|
||||
statement = statement.where(FaceImageModel.create_time >= start_time)
|
||||
if end_time:
|
||||
statement = statement.where(FaceImageModel.create_time <= end_time)
|
||||
all_count = await self.get_count(session, statement)
|
||||
if sort_type:
|
||||
if sort_type.CREATE_TIME:
|
||||
statement = statement.order_by(FaceImageModel.create_time)
|
||||
elif sort_type.USER_ID:
|
||||
statement = statement.order_by(FaceImageModel.user_id)
|
||||
elif sort_type.APPROVED:
|
||||
statement = statement.order_by(FaceImageModel.is_approved)
|
||||
offset = (page_no - 1) * page_size
|
||||
statement = statement.offset(offset).limit(page_size)
|
||||
r = await session.exec(statement)
|
||||
return r.all(), all_count
|
||||
|
@ -1,4 +1,6 @@
|
||||
from typing import List
|
||||
from enum import Enum
|
||||
from datetime import date, datetime
|
||||
from typing import List, Optional
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
@ -17,3 +19,43 @@ class FaceImageDeleteIds(BaseModel):
|
||||
|
||||
class FaceImageUpdate(FaceImageCreate, FaceImageDelete):
|
||||
pass
|
||||
|
||||
|
||||
class TypeEnum(int, Enum):
|
||||
ALL = 0
|
||||
DO = 1
|
||||
UNDO = 2
|
||||
|
||||
|
||||
class SortTypeEnum(int, Enum):
|
||||
CREATE_TIME = 1
|
||||
USER_ID = 2
|
||||
APPROVED = 3
|
||||
|
||||
|
||||
class FaceList(BaseModel):
|
||||
user_id: Optional[int] = None
|
||||
|
||||
deleted: TypeEnum = TypeEnum.ALL
|
||||
approved: TypeEnum = TypeEnum.ALL
|
||||
sortType: SortTypeEnum = SortTypeEnum.CREATE_TIME
|
||||
start_time: Optional[str] = ""
|
||||
end_time: Optional[str] = ""
|
||||
pageNo: int = 1
|
||||
pageSize: int = 10
|
||||
|
||||
@property
|
||||
def start(self):
|
||||
if not self.start_time:
|
||||
return None
|
||||
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):
|
||||
if not self.end_time:
|
||||
return None
|
||||
y, m, d = self.end_time.split("-")
|
||||
end_time = date(int(y), int(m), int(d))
|
||||
return datetime.combine(end_time, datetime.max.time())
|
||||
|
@ -5,6 +5,7 @@ from typing_extensions import Optional
|
||||
|
||||
from .models import FaceImageModel
|
||||
from .repositories import FaceImageRepo
|
||||
from .schemas import SortTypeEnum, TypeEnum
|
||||
|
||||
|
||||
class FaceImageServices(AsyncInitializingComponent):
|
||||
@ -53,3 +54,25 @@ class FaceImageServices(AsyncInitializingComponent):
|
||||
image = await self.repo.get_by(rid)
|
||||
image.is_approved = True
|
||||
return await self.repo.add_face_image(image)
|
||||
|
||||
async def get_image_list(
|
||||
self,
|
||||
user_id: Optional[int],
|
||||
deleted: Optional[TypeEnum],
|
||||
approved: Optional[TypeEnum],
|
||||
sort_type: Optional[SortTypeEnum],
|
||||
start_time: Optional[datetime],
|
||||
end_time: Optional[datetime],
|
||||
page_no: int,
|
||||
page_size: int,
|
||||
):
|
||||
return await self.repo.get_image_list(
|
||||
user_id=user_id,
|
||||
deleted=deleted,
|
||||
approved=approved,
|
||||
sort_type=sort_type,
|
||||
start_time=start_time,
|
||||
end_time=end_time,
|
||||
page_no=page_no,
|
||||
page_size=page_size,
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user