add image recognition classification

This commit is contained in:
2025-01-06 17:42:27 +08:00
parent 6854e41b82
commit 90a68221fe
59 changed files with 19194 additions and 111 deletions

View File

@@ -1,7 +1,7 @@
<template>
<div class="all-photo">
<div class="photo-header">
<AButton type="primary" shape="round" size="middle">
<AButton type="primary" shape="round" size="middle" @click="upload.openUploadDrawer = true">
<template #icon>
<PlusOutlined/>
</template>
@@ -83,11 +83,13 @@
:breakpoints="breakpoints">
<template #default="{ item, url, index }">
<CheckCard :key="index"
class="photo-item"
margin="0"
border-radius="0"
v-model="selected"
:showHoverCircle="true"
:iconSize="20"
:showSelectedEffect="true"
:value="url">
<AImage :src="url"
:alt="item.title"
@@ -113,6 +115,7 @@
</ATabPane>
</ATabs>
</div>
<Upload/>
</div>
</template>
@@ -121,9 +124,12 @@ import {Waterfall} from 'vue-waterfall-plugin-next';
import 'vue-waterfall-plugin-next/dist/style.css';
import loading from '@/assets/gif/loading.gif';
import error from '@/assets/svgs/no-image.svg';
import Upload from "@/views/Photograph/Upload/Upload.vue";
import useStore from "@/store";
const selected = ref<(string | number)[]>([]);
const switchValue = ref<boolean>(false);
const upload = useStore().upload;
const breakpoints = reactive({
breakpoints: {
1200: {
@@ -162,6 +168,11 @@ function loadImages() {
tag: '全部',
date: '2022-01-01',
});
images.value.push({
title: `image-${i}`,
link: '',
src: `/test/${i}.png`,
});
}
}
@@ -273,4 +284,10 @@ onBeforeMount(() => { // 组件已完成响应式状态设置但未创建DOM
transform: translateY(0);
opacity: 1;
}
.photo-item:hover {
transition: all 0.3s ease-in-out, transform 0.3s ease-in-out;
//transform: scale(0.99);
box-shadow: 0 0 10px 0 rgba(77, 167, 255, 0.89);
}
</style>

View File

@@ -15,23 +15,125 @@
</AButton>
</div>
<div class="photo-list">
<CheckCard style="margin-top: 20px;" v-for="item in items" :key="item.id" :value="item.id" v-model="selectedItems">
{{ item.name }}
</CheckCard>
<div>Selected Items: {{ selectedItems }}</div>
<div style="width:100%;height:100%;" v-if="images.length !== 0">
<span style="margin-left: 10px;font-size: 13px">2024年12月27日 星期日</span>
<AImagePreviewGroup>
<Waterfall :list="images"
:backgroundColor="`transparent`"
:width="400"
:gutter="15"
align="left"
:lazyload="true"
:animationDelay="300"
:animationDuration="1000"
:animationCancel="false"
:hasAroundGutter="true"
rowKey="id"
:imgSelector="'src'"
:loadProps="loadProps"
:breakpoints="breakpoints">
<template #default="{ item, url, index }">
<CheckCard :key="index"
margin="0"
border-radius="0"
v-model="selected"
:showHoverCircle="true"
:iconSize="20"
:value="url">
<AImage :src="url"
:alt="item.title"
:key="index"
:previewMask="false"
loading="lazy"/>
</CheckCard>
</template>
</Waterfall>
</AImagePreviewGroup>
</div>
</div>
</div>
</template>
<script setup lang="ts">
const items = ref([
{ id: 1, name: 'Item 1' },
{ id: 2, name: 'Item 2' },
{ id: 3, name: 'Item 3' },
]);
import {Waterfall} from 'vue-waterfall-plugin-next';
import 'vue-waterfall-plugin-next/dist/style.css';
import loading from '@/assets/gif/loading.gif';
import error from '@/assets/svgs/no-image.svg';
const selectedItems = ref<(string | number)[]>([]);
const selected = ref<(string | number)[]>([]);
const breakpoints = reactive({
breakpoints: {
1200: {
// 当屏幕宽度小于等于1200
rowPerView: 4,
},
800: {
// 当屏幕宽度小于等于800
rowPerView: 3,
},
500: {
// 当屏幕宽度小于等于500
rowPerView: 2,
},
},
});
const loadProps = reactive({
loading,
error,
ratioCalculator: (_width: number, _height: number) => {
// 我设置了最小宽高比
const minRatio = 3 / 4;
const maxRatio = 4 / 3;
return Math.random() > 0.5 ? minRatio : maxRatio;
},
});
const images = ref<any[]>([]);
function loadImages() {
for (let i = 1; i < 10; i++) {
images.value.push({
title: `image-${i}`,
link: '',
src: `https://cdn.jsdelivr.net/gh/themusecatcher/resources@0.0.5/${i}.jpg`,
tag: '全部',
date: '2022-01-01',
});
}
}
onBeforeMount(() => { // 组件已完成响应式状态设置但未创建DOM节点
loadImages();
});
</script>
<style scoped lang="scss" src="./index.scss">
<style scoped lang="scss">
.recent-upload {
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-start;
width: 100%;
height: 100%;
.photo-header {
width: 100%;
height: 50px;
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
gap: 10px;
border-bottom: 1px solid #e2e2e2;
}
.photo-list {
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: flex-start;
width: 100%;
height: calc(100% - 65px);
margin-top: 10px;
}
}
</style>

View File

@@ -1,19 +0,0 @@
.recent-upload {
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-start;
width: 100%;
height: 100%;
.photo-header {
width: 100%;
height: 50px;
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
gap: 10px;
border-bottom: 1px solid #e2e2e2;
}
}

View File

@@ -0,0 +1,74 @@
<template>
<ADrawer v-model:open="upload.openUploadDrawer" width="40%" placement="right" title="上传照片">
<template #extra>
<AFlex :vertical="false" justify="center" align="center" gap="large">
<ASelect size="middle" style="width: 150px">
</ASelect>
<ASelect size="middle" style="width: 150px">
</ASelect>
</AFlex>
</template>
<div>
<AUploadDragger
v-model:fileList="fileList"
accept="image/*"
name="file"
:directory="false"
:multiple="true"
@drop="handleDrop"
:beforeUpload="upload.beforeUpload"
:customRequest="upload.customUploadRequest"
:progress="progress"
>
<p class="ant-upload-drag-icon">
<inbox-outlined></inbox-outlined>
</p>
<p class="ant-upload-text">Click or drag file to this area to upload</p>
<p class="ant-upload-hint">
Support for a single or bulk upload. Strictly prohibit from uploading company data or other
band files
</p>
</AUploadDragger>
</div>
</ADrawer>
</template>
<script setup lang="ts">
import useStore from "@/store";
import {InboxOutlined} from '@ant-design/icons-vue';
import type {UploadProps} from 'ant-design-vue';
const upload = useStore().upload;
const fileList = ref([]);
// const handleChange = (info: UploadChangeParam) => {
// const status = info.file.status;
// if (status !== 'uploading') {
// console.log(info.file, info.fileList);
// }
// if (status === 'done') {
// message.success(`${info.file.name} file uploaded successfully.`);
// } else if (status === 'error') {
// message.error(`${info.file.name} file upload failed.`);
// }
// };
function handleDrop(e: DragEvent) {
console.log(e);
}
const progress: UploadProps['progress'] = {
strokeColor: {
'0%': '#108ee9',
'100%': '#87d068',
},
strokeWidth: 3,
format: (percent: any) => `${parseFloat(percent.toFixed(2))}%`,
class: 'progress-bar',
};
</script>
<style scoped lang="less">
</style>