♻️ refactor some code
This commit is contained in:
@@ -1,71 +1,217 @@
|
||||
<template>
|
||||
<div class="people-album">
|
||||
<div class="people-album-header">
|
||||
<ADropdown>
|
||||
<ADropdown trigger="click">
|
||||
<AButton type="text" size="large" class="people-album-button">
|
||||
人物
|
||||
{{ selecetedKey === '0' ? '人 物' : '已隐藏' }}
|
||||
<DownOutlined class="people-album-icon"/>
|
||||
</AButton>
|
||||
<template #overlay>
|
||||
<AMenu>
|
||||
<AMenuItem>人 物</AMenuItem>
|
||||
<AMenuItem>已隐藏</AMenuItem>
|
||||
<AMenu selectable :selectedKeys="[selecetedKey]" @select="handleSelect">
|
||||
<AMenuItem key="0">人 物</AMenuItem>
|
||||
<AMenuItem key="1">已隐藏</AMenuItem>
|
||||
</AMenu>
|
||||
</template>
|
||||
|
||||
</ADropdown>
|
||||
<span class="people-album-count">共<span style="color: #0e87cc">{{ faceList.length }}</span>位</span>
|
||||
</div>
|
||||
<div class="people-album-content">
|
||||
<div class="people-album-item" @mouseover="showButton = true" @mouseleave="showButton = false">
|
||||
<div class="people-album-item-avatar">
|
||||
<AAvatar :size="86" shape="circle" src="/test/4.png"/>
|
||||
</div>
|
||||
<div class="people-album-item-name">
|
||||
<AButton @click="showAddNameInput" class="people-album-add-name" v-show="showButton && !showInput" type="link"
|
||||
size="small">
|
||||
添加名字
|
||||
</AButton>
|
||||
<AInput v-show="showInput" @blur="hideAddNameInput" size="small" class="people-album-add-input">
|
||||
<template #suffix>
|
||||
<AButton type="link" size="small">完成</AButton>
|
||||
<transition name="fade">
|
||||
<div class="people-album-toolbar" v-show="selected.length !== 0">
|
||||
<div class="people-album-toolbar-left">
|
||||
<AButton type="text" shape="circle" size="large" class="people-album-toolbar-btn" @click="cancelSelectPeople">
|
||||
<template #icon>
|
||||
<CloseOutlined class="people-album-toolbar-icon"/>
|
||||
</template>
|
||||
</AInput>
|
||||
</AButton>
|
||||
<span style="font-size: 16px;font-weight: bold">
|
||||
已选择 {{ selected.length }} 个人物
|
||||
</span>
|
||||
<AButton type="text" shape="default" class="people-album-toolbar-btn" size="middle" @click="selectAllPeople">
|
||||
全选
|
||||
</AButton>
|
||||
</div>
|
||||
</div>
|
||||
<div class="people-album-toolbar-right">
|
||||
|
||||
<div class="people-album-item" @mouseover="showButton = true" @mouseleave="showButton = false">
|
||||
<div class="people-album-item-avatar">
|
||||
<AAvatar :size="86" shape="circle" src="/test/4.png"/>
|
||||
</div>
|
||||
<div class="people-album-item-name">
|
||||
<AButton @click="showAddNameInput" class="people-album-add-name" v-show="showButton && !showInput" type="link"
|
||||
size="small">
|
||||
添加名字
|
||||
</AButton>
|
||||
<AInput v-show="showInput" @blur="hideAddNameInput" size="small" class="people-album-add-input">
|
||||
<template #suffix>
|
||||
<AButton type="link" size="small">完成</AButton>
|
||||
<AButton type="text" shape="default" size="middle" class="people-album-toolbar-btn"
|
||||
:disabled="selected.length !== 2" v-if="selecetedKey === '0'">
|
||||
<template #icon>
|
||||
<BlockOutlined class="people-album-toolbar-icon"/>
|
||||
</template>
|
||||
</AInput>
|
||||
合并人物
|
||||
</AButton>
|
||||
|
||||
<AButton type="text" shape="default" size="middle" class="people-album-toolbar-btn" @click="hiddenFace">
|
||||
<template #icon>
|
||||
<EyeInvisibleOutlined class="people-album-toolbar-icon"/>
|
||||
</template>
|
||||
{{ selecetedKey === '0' ? '隐藏人物' : '取消隐藏' }}
|
||||
</AButton>
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
<div class="people-album-container">
|
||||
<ASpin :spinning="loading" size="large" wrapperClassName="people-album-container">
|
||||
<div class="people-album-content">
|
||||
<CheckCard
|
||||
v-for="(item, index) in faceList"
|
||||
:key="index"
|
||||
class="photo-item"
|
||||
margin="0"
|
||||
border-radius="0"
|
||||
v-model="selected"
|
||||
:showHoverCircle="true"
|
||||
:background-color="'transparent'"
|
||||
:iconSize="20"
|
||||
:showSelectedEffect="false"
|
||||
:value="item.id">
|
||||
<div class="people-album-item"
|
||||
:class="{ 'selected-item': selected.includes(item.id) }"
|
||||
@mouseover="item.showButton = true"
|
||||
@mouseleave="item.showButton = false">
|
||||
<div class="people-album-item-avatar">
|
||||
<AAvatar :size="86" shape="circle" :src="item.face_image"/>
|
||||
</div>
|
||||
<div class="people-album-item-name" v-show="!item.face_name">
|
||||
<AButton @click="showAddNameInput(index)" class="people-album-add-name"
|
||||
v-show="item.showButton && !item.showInput"
|
||||
type="link"
|
||||
size="small">
|
||||
添加名字
|
||||
</AButton>
|
||||
<AInput ref="addNameInput" v-model:value="addNameInputValue" v-show="item.showInput"
|
||||
@blur="hideAddNameInput(index)" size="small"
|
||||
:maxlength="10"
|
||||
:placeholder="item.face_name"
|
||||
class="people-album-add-input">
|
||||
<template #suffix>
|
||||
<AButton type="link" style="font-size: 12px;" size="small" @mousedown.prevent
|
||||
@click="modifyFaceName(item.id,index)">完成
|
||||
</AButton>
|
||||
</template>
|
||||
</AInput>
|
||||
</div>
|
||||
<div class="people-album-item-name" v-show="item.face_name">
|
||||
<AButton @click="showAddNameInput(index)" class="people-album-add-name" v-show="!item.showInput"
|
||||
type="link"
|
||||
size="small">
|
||||
{{ item.face_name }}
|
||||
</AButton>
|
||||
<AInput ref="addNameInput" v-model:value="addNameInputValue" autofocus v-show="item.showInput"
|
||||
@blur="hideAddNameInput(index)" size="small"
|
||||
:maxlength="10"
|
||||
:placeholder="item.face_name"
|
||||
class="people-album-add-input">
|
||||
<template #suffix>
|
||||
<AButton type="link" style="font-size: 12px;" size="small" @mousedown.prevent
|
||||
@click="modifyFaceName(item.id,index)">完成
|
||||
</AButton>
|
||||
</template>
|
||||
</AInput>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</CheckCard>
|
||||
|
||||
</div>
|
||||
</ASpin>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
const showButton = ref(false);
|
||||
const showInput = ref(false);
|
||||
import {getFaceSamplesList, modifyFaceSampleName, modifyFaceTypeBatch} from "@/api/storage";
|
||||
|
||||
function showAddNameInput() {
|
||||
showInput.value = true;
|
||||
showButton.value = false;
|
||||
const faceList = ref<any[]>([]);
|
||||
const addNameInput = ref<any>(null);
|
||||
const addNameInputValue = ref<string>('');
|
||||
const selecetedKey = ref<string>('0');
|
||||
const loading = ref<boolean>(false);
|
||||
const selected = ref<any[]>([]);
|
||||
|
||||
/**
|
||||
* 获取人脸列表
|
||||
*/
|
||||
async function getFaceList(type: number = 0) {
|
||||
loading.value = true;
|
||||
faceList.value = [];
|
||||
const res: any = await getFaceSamplesList(type);
|
||||
if (res && res.code === 200 && res.data.faces) {
|
||||
faceList.value = res.data.faces.map(face => ({
|
||||
...face,
|
||||
showButton: false,
|
||||
showInput: false,
|
||||
}));
|
||||
}
|
||||
loading.value = false;
|
||||
}
|
||||
|
||||
function hideAddNameInput() {
|
||||
showInput.value = false;
|
||||
showButton.value = false;
|
||||
function showAddNameInput(index: number) {
|
||||
if (faceList.value[index]) {
|
||||
faceList.value[index].showInput = true;
|
||||
faceList.value[index].showButton = false;
|
||||
}
|
||||
}
|
||||
|
||||
function hideAddNameInput(index: number) {
|
||||
if (faceList.value[index]) {
|
||||
faceList.value[index].showInput = false;
|
||||
faceList.value[index].showButton = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改人脸名称
|
||||
* @param id
|
||||
* @param index
|
||||
*/
|
||||
async function modifyFaceName(id: number, index: number) {
|
||||
if (!addNameInputValue.value.trim()) return;
|
||||
const res: any = await modifyFaceSampleName(id, addNameInputValue.value);
|
||||
if (res && res.code === 200) {
|
||||
faceList.value[index].face_name = res.data.face_name;
|
||||
addNameInputValue.value = '';
|
||||
hideAddNameInput(index);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 选择分类
|
||||
* @param key
|
||||
*/
|
||||
function handleSelect({key}) {
|
||||
selecetedKey.value = key;
|
||||
getFaceList(parseInt(key));
|
||||
}
|
||||
|
||||
/**
|
||||
* 全选
|
||||
*/
|
||||
function selectAllPeople() {
|
||||
selected.value = faceList.value.map((item) => item.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消选择
|
||||
*/
|
||||
function cancelSelectPeople() {
|
||||
selected.value = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* 隐藏人物
|
||||
*/
|
||||
async function hiddenFace() {
|
||||
if (selected.value.length === 0) return;
|
||||
const res: any = await modifyFaceTypeBatch(selected.value, selecetedKey.value === '0' ? 1 : 0);
|
||||
if (res && res.code === 200) {
|
||||
await getFaceList();
|
||||
selected.value = [];
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getFaceList();
|
||||
});
|
||||
|
||||
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
@@ -103,68 +249,162 @@ function hideAddNameInput() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.people-album-count {
|
||||
width: 100%;
|
||||
font-size: 13px;
|
||||
color: rgba(129, 129, 138, 0.99);
|
||||
}
|
||||
}
|
||||
|
||||
.people-album-content {
|
||||
|
||||
.people-album-toolbar {
|
||||
position: fixed;
|
||||
width: calc(100% - 220px);
|
||||
height: 70px;
|
||||
top: 70px;
|
||||
z-index: 3;
|
||||
display: flex;
|
||||
box-sizing: border-box;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
background-image: linear-gradient(45deg, #5789ff, #5c7bff 100%);
|
||||
color: #fff;
|
||||
box-shadow: 0 3px 10px 0 rgba(0, 0, 0, .06);
|
||||
padding: 0 20px;
|
||||
|
||||
.people-album-toolbar-left {
|
||||
width: 50%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.people-album-toolbar-right {
|
||||
height: 100%;
|
||||
width: 50%;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
gap: 30px;
|
||||
}
|
||||
|
||||
.people-album-toolbar-icon {
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.people-album-toolbar-btn {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
color: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
.people-album-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: flex-start;
|
||||
align-items: flex-start;
|
||||
padding-top: 20px;
|
||||
padding-left: 20px;
|
||||
gap: 20px;
|
||||
align-content: flex-start;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.people-album-item {
|
||||
width: 130px;
|
||||
height: 160px;
|
||||
.people-album-content {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 10px;
|
||||
transition: all 0.3s ease-in-out;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
flex-direction: row;
|
||||
justify-content: flex-start;
|
||||
align-content: flex-start;
|
||||
flex-wrap: wrap;
|
||||
padding-top: 20px;
|
||||
padding-left: 20px;
|
||||
padding-right: 20px;
|
||||
gap: 20px;
|
||||
|
||||
.people-album-item-avatar {
|
||||
width: 100%;
|
||||
height: 75%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.people-album-item-name {
|
||||
width: 100%;
|
||||
height: 25%;
|
||||
.people-album-item {
|
||||
width: 130px;
|
||||
height: 160px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
justify-content: center;
|
||||
border-radius: 10px;
|
||||
transition: all 0.3s ease;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
|
||||
.people-album-add-input {
|
||||
width: 80%;
|
||||
.people-album-item-avatar {
|
||||
width: 100%;
|
||||
height: 75%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.people-album-item-name {
|
||||
width: 100%;
|
||||
height: 25%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
|
||||
.people-album-add-input {
|
||||
width: 80%;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.people-album-add-name {
|
||||
color: rgba(110, 110, 113, 0.99);
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.people-album-add-name:hover {
|
||||
color: #0e87cc;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.people-album-add-name {
|
||||
color: rgba(126, 126, 135, 0.99);
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.people-album-add-name:hover {
|
||||
color: #0e87cc;
|
||||
.people-album-item:hover,
|
||||
.people-album-item.selected-item {
|
||||
background-color: rgba(248, 248, 248, 0.74);
|
||||
opacity: 1;
|
||||
transform: scale(1.05);
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
}
|
||||
|
||||
.people-album-item:hover {
|
||||
background-color: rgba(248, 248, 248, 0.74);
|
||||
opacity: 1;
|
||||
transform: scale(1.05);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.fade-enter-active, .fade-leave-active {
|
||||
transition: all 0.5s ease;
|
||||
}
|
||||
|
||||
.fade-enter-from, .fade-leave-to { /* .slide-fade-leave-active 在离开之前 */
|
||||
transform: translateY(-20px);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.fade-enter-from {
|
||||
transform: translateY(-30px);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.fade-enter-to {
|
||||
transform: translateY(0);
|
||||
opacity: 1;
|
||||
}
|
||||
</style>
|
||||
|
Reference in New Issue
Block a user