diff --git a/components.d.ts b/components.d.ts
index 94c4c87..620fadb 100644
--- a/components.d.ts
+++ b/components.d.ts
@@ -31,33 +31,25 @@ declare module 'vue' {
AInputGroup: typeof import('ant-design-vue/es')['InputGroup']
AInputNumber: typeof import('ant-design-vue/es')['InputNumber']
AInputPassword: typeof import('ant-design-vue/es')['InputPassword']
- AList: typeof import('ant-design-vue/es')['List']
- AListItem: typeof import('ant-design-vue/es')['ListItem']
AllPhoto: typeof import('./src/views/Photograph/AllPhoto/AllPhoto.vue')['default']
AMenu: typeof import('ant-design-vue/es')['Menu']
AMenuItem: typeof import('ant-design-vue/es')['MenuItem']
AMenuItemGroup: typeof import('ant-design-vue/es')['MenuItemGroup']
AModal: typeof import('ant-design-vue/es')['Modal']
AnimatedNature: typeof import('./src/components/AnimatedNature/AnimatedNature.vue')['default']
- APagination: typeof import('ant-design-vue/es')['Pagination']
APopconfirm: typeof import('ant-design-vue/es')['Popconfirm']
APopover: typeof import('ant-design-vue/es')['Popover']
AProgress: typeof import('ant-design-vue/es')['Progress']
AQrcode: typeof import('ant-design-vue/es')['QRCode']
- ARadio: typeof import('ant-design-vue/es')['Radio']
- ARadioGroup: typeof import('ant-design-vue/es')['RadioGroup']
ARangePicker: typeof import('ant-design-vue/es')['RangePicker']
ASelect: typeof import('ant-design-vue/es')['Select']
ASelectOption: typeof import('ant-design-vue/es')['SelectOption']
- ASkeleton: typeof import('ant-design-vue/es')['Skeleton']
- ASpace: typeof import('ant-design-vue/es')['Space']
ASpin: typeof import('ant-design-vue/es')['Spin']
ASwitch: typeof import('ant-design-vue/es')['Switch']
ATable: typeof import('ant-design-vue/es')['Table']
ATabPane: typeof import('ant-design-vue/es')['TabPane']
ATabs: typeof import('ant-design-vue/es')['Tabs']
ATag: typeof import('ant-design-vue/es')['Tag']
- ATextarea: typeof import('ant-design-vue/es')['Textarea']
ATooltip: typeof import('ant-design-vue/es')['Tooltip']
AUpload: typeof import('ant-design-vue/es')['Upload']
AUploadDragger: typeof import('ant-design-vue/es')['UploadDragger']
@@ -67,28 +59,25 @@ declare module 'vue' {
Card3D: typeof import('./src/components/Card3D/Card3D.vue')['default']
CheckCard: typeof import('./src/components/CheckCard/CheckCard.vue')['default']
CheckCircleOutlined: typeof import('@ant-design/icons-vue')['CheckCircleOutlined']
- CloseCircleOutlined: typeof import('@ant-design/icons-vue')['CloseCircleOutlined']
CloseOutlined: typeof import('@ant-design/icons-vue')['CloseOutlined']
Clouds: typeof import('./src/components/Clouds/Clouds.vue')['default']
+ CloudUploadOutlined: typeof import('@ant-design/icons-vue')['CloudUploadOutlined']
CommentInput: typeof import('./src/components/CommentReply/src/CommentInput/CommentInput.vue')['default']
CommentList: typeof import('./src/components/CommentReply/src/CommentList/CommentList.vue')['default']
CommentReply: typeof import('./src/components/CommentReply/index.vue')['default']
CompareImage: typeof import('./src/views/Upscale/CompareImage.vue')['default']
- CopyOutlined: typeof import('@ant-design/icons-vue')['CopyOutlined']
DeleteOutlined: typeof import('@ant-design/icons-vue')['DeleteOutlined']
DownloadOutlined: typeof import('@ant-design/icons-vue')['DownloadOutlined']
DownOutlined: typeof import('@ant-design/icons-vue')['DownOutlined']
DynamicTitle: typeof import('./src/components/DynamicTitle/DynamicTitle.vue')['default']
EyeInvisibleOutlined: typeof import('@ant-design/icons-vue')['EyeInvisibleOutlined']
- EyeOutlined: typeof import('@ant-design/icons-vue')['EyeOutlined']
FileImageOutlined: typeof import('@ant-design/icons-vue')['FileImageOutlined']
Folder: typeof import('./src/components/Folder/Folder.vue')['default']
ForgetPage: typeof import('./src/views/Forget/ForgetPage.vue')['default']
GradientText: typeof import('./src/components/MyUI/GradientText/GradientText.vue')['default']
- ImageShare: typeof import('./src/views/ImageShare/ImageShare.vue')['default']
+ ImageShare: typeof import('./src/views/Share/ImageShare/ImageShare.vue')['default']
ImageToolbar: typeof import('./src/views/Photograph/ImageToolbar/ImageToolbar.vue')['default']
ImageUpload: typeof import('./src/views/Photograph/ImageUpload/ImageUpload.vue')['default']
- InboxOutlined: typeof import('@ant-design/icons-vue')['InboxOutlined']
LandingPage: typeof import('./src/views/Landing/LandingPage.vue')['default']
LeftOutlined: typeof import('@ant-design/icons-vue')['LeftOutlined']
LinkOutlined: typeof import('@ant-design/icons-vue')['LinkOutlined']
@@ -110,12 +99,14 @@ declare module 'vue' {
Phoalbum: typeof import('./src/views/Album/Phoalbum/Phoalbum.vue')['default']
PhoalbumDetail: typeof import('./src/views/Album/Phoalbum/PhoalbumDetail.vue')['default']
PhoalbumList: typeof import('./src/views/Album/Phoalbum/PhoalbumList.vue')['default']
- PhoneUpload: typeof import('./src/views/Phone/UpscalePhoneUpload/PhoneUpload.vue')['default']
+ PhoneOutlined: typeof import('@ant-design/icons-vue')['PhoneOutlined']
PhotoStack: typeof import('./src/components/PhotoStack/PhotoStack.vue')['default']
PlusOutlined: typeof import('@ant-design/icons-vue')['PlusOutlined']
PlusSquareOutlined: typeof import('@ant-design/icons-vue')['PlusSquareOutlined']
+ QrcodeOutlined: typeof import('@ant-design/icons-vue')['QrcodeOutlined']
QRLogin: typeof import('./src/views/QRLogin/QRLogin.vue')['default']
QRLoginFooter: typeof import('./src/views/QRLogin/QRLoginFooter.vue')['default']
+ QuestionCircleOutlined: typeof import('@ant-design/icons-vue')['QuestionCircleOutlined']
Rate: typeof import('./src/components/MyUI/Rate/Rate.vue')['default']
RecentUpload: typeof import('./src/views/Photograph/RecentUpload/RecentUpload.vue')['default']
RecyclingBin: typeof import('./src/views/RecyclingBin/RecyclingBin.vue')['default']
@@ -126,10 +117,11 @@ declare module 'vue' {
RouterView: typeof import('vue-router')['RouterView']
SafetyOutlined: typeof import('@ant-design/icons-vue')['SafetyOutlined']
SearchOutlined: typeof import('@ant-design/icons-vue')['SearchOutlined']
- SendOutlined: typeof import('@ant-design/icons-vue')['SendOutlined']
ShareAltOutlined: typeof import('@ant-design/icons-vue')['ShareAltOutlined']
SharePhoneUpload: typeof import('./src/views/Phone/SharePhoneUpload/SharePhoneUpload.vue')['default']
- ShareUpload: typeof import('./src/views/ImageShare/ShareUpload.vue')['default']
+ ShareSidebar: typeof import('./src/views/Share/ShareViewList/ShareSidebar.vue')['default']
+ ShareUpload: typeof import('./src/views/Share/ImageShare/ShareUpload.vue')['default']
+ ShareViewList: typeof import('./src/views/Share/ShareViewList/index.vue')['default']
Spin: typeof import('./src/components/MyUI/Spin/Spin.vue')['default']
StarButton: typeof import('./src/components/StarButton/StarButton.vue')['default']
TabletOutlined: typeof import('@ant-design/icons-vue')['TabletOutlined']
@@ -138,11 +130,11 @@ declare module 'vue' {
ThingAlbumList: typeof import('./src/views/Album/ThingAlbum/ThingAlbumList.vue')['default']
Tooltip: typeof import('./src/components/MyUI/Tooltip/Tooltip.vue')['default']
UploadImage: typeof import('./src/views/Upscale/UploadImage.vue')['default']
+ UploadOutlined: typeof import('@ant-design/icons-vue')['UploadOutlined']
Upscale: typeof import('./src/views/Upscale/index.vue')['default']
UpscalePhoneUpload: typeof import('./src/views/Phone/UpscalePhoneUpload/UpscalePhoneUpload.vue')['default']
UserInfoCard: typeof import('./src/components/CommentReply/src/UserInfoCard/UserInfoCard.vue')['default']
UserOutlined: typeof import('@ant-design/icons-vue')['UserOutlined']
VueCompareImage: typeof import('./src/components/VueCompareImage/VueCompareImage.vue')['default']
- WarningOutlined: typeof import('@ant-design/icons-vue')['WarningOutlined']
}
}
diff --git a/package.json b/package.json
index 935018e..e35d5ce 100644
--- a/package.json
+++ b/package.json
@@ -10,7 +10,7 @@
"docker-build": "docker build -t schisandra/schisandra-cloud-album-front ."
},
"dependencies": {
- "@alova/adapter-axios": "^2.0.12",
+ "@alova/adapter-axios": "^2.0.13",
"@ant-design/icons-vue": "^7.0.1",
"@intlify/eslint-plugin-vue-i18n": "^3.2.0",
"@mediapipe/face_detection": "^0.4.1646425229",
@@ -27,10 +27,10 @@
"@tensorflow/tfjs-backend-webgpu": "^4.22.0",
"@tensorflow/tfjs-converter": "^4.22.0",
"@tensorflow/tfjs-core": "^4.22.0",
- "@types/animejs": "^3.1.12",
+ "@types/animejs": "^3.1.13",
"@types/crypto-js": "^4.2.2",
"@types/json-stringify-safe": "^5.0.3",
- "@types/node": "^22.13.4",
+ "@types/node": "^22.13.5",
"@types/nprogress": "^0.2.3",
"@vladmandic/face-api": "^1.7.15",
"@vuepic/vue-datepicker": "^11.0.1",
@@ -44,7 +44,7 @@
"buffer": "^6.0.3",
"crypto-js": "^4.2.0",
"echarts": "^5.6.0",
- "eslint": "9.20.1",
+ "eslint": "9.21.0",
"exifr": "^7.1.3",
"go-captcha-vue": "^2.0.6",
"gsap": "^3.12.7",
@@ -70,13 +70,13 @@
"vue-i18n": "^11.1.1",
"vue-router": "^4.5.0",
"vue3-justified-layout": "^0.0.6",
- "ws": "^8.18.0"
+ "ws": "^8.18.1"
},
"devDependencies": {
- "@eslint/js": "^9.20.0",
+ "@eslint/js": "^9.21.0",
"@vitejs/plugin-vue": "^5.2.1",
"eslint-plugin-vue": "^9.32.0",
- "globals": "^15.15.0",
+ "globals": "^16.0.0",
"sass": "^1.85.0",
"typescript": "^5.7.3",
"typescript-eslint": "^8.24.1",
diff --git a/src/api/share/index.ts b/src/api/share/index.ts
index 3e34981..22f5f89 100644
--- a/src/api/share/index.ts
+++ b/src/api/share/index.ts
@@ -14,12 +14,12 @@ export const shareImageUploadApi = (formData) => {
};
/**
* 查询分享图片列表
- * @param share_code
+ * @param invite_code
* @param access_password
*/
-export const queryShareImageApi = (share_code: string, access_password: string) => {
+export const queryShareImageApi = (invite_code: string, access_password: string) => {
return service.Post('/api/auth/share/image/list', {
- share_code: share_code,
+ invite_code: invite_code,
access_password: access_password,
}, {
meta: {
@@ -41,3 +41,36 @@ export const queryShareRecordListApi = (dataRequest: string[]) => {
},
});
};
+/**
+ * 查询分享信息
+ * @param invite_code
+ */
+export const queryShareInfoApi = (invite_code: string) => {
+ return service.Post('/api/auth/share/info', {
+ invite_code: invite_code,
+ }, {
+ cacheFor: {
+ expire: 60, //60 * 60 * 24 * 7
+ mode: "restore",
+ },
+ meta: {
+ ignoreToken: false,
+ signature: false,
+ },
+ });
+};
+/**
+ * 查询分享概览
+ */
+export const queryShareOverviewApi = () => {
+ return service.Post('/api/auth/share/overview', {}, {
+ cacheFor: {
+ expire: 60, //60 * 60 * 24 * 7
+ mode: "restore",
+ },
+ meta: {
+ ignoreToken: false,
+ signature: false,
+ },
+ });
+};
diff --git a/src/api/storage/index.ts b/src/api/storage/index.ts
index ff86bdb..26956da 100644
--- a/src/api/storage/index.ts
+++ b/src/api/storage/index.ts
@@ -30,7 +30,7 @@ export const getFaceSamplesList = (type: number) => {
ignoreToken: false,
signature: false,
},
- hitSource: ["modify-face-sample-name", "modify-face-sample-type"],
+ hitSource: ["modify-face-sample-name", "modify-face-sample-type", "delete-images"],
});
};
/**
@@ -146,6 +146,8 @@ export const queryAlbumDetailListApi = (id: number, provider: string, bucket: st
ignoreToken: false,
signature: false,
},
+ name: "album-detail-list",
+ hitSource: ["upload-file", "delete-images"],
});
};
@@ -203,7 +205,7 @@ export const queryAllImagesApi = (type: string, sort: boolean, provider: string,
ignoreToken: false,
signature: false,
},
- hitSource: ["upload-file"],
+ hitSource: ["upload-file", "delete-images"],
});
};
@@ -221,7 +223,7 @@ export const queryRecentImagesApi = () => {
ignoreToken: false,
signature: false,
},
- hitSource: ["upload-file"],
+ hitSource: ["upload-file", "delete-images"],
});
};
/**
@@ -240,7 +242,7 @@ export const queryLocationAlbumApi = (provider: string, bucket: string) => {
ignoreToken: false,
signature: false,
},
- hitSource: ["upload-file"],
+ hitSource: ["upload-file", "delete-images"],
});
};
/**
@@ -263,7 +265,7 @@ export const queryLocationDetailListApi = (id: number, provider: string, bucket:
ignoreToken: false,
signature: false,
},
- hitSource: ["upload-file"],
+ hitSource: ["upload-file", "delete-images"],
});
};
@@ -283,7 +285,7 @@ export const queryThingAlbumApi = (provider: string, bucket: string) => {
ignoreToken: false,
signature: false,
},
- hitSource: ["upload-file"],
+ hitSource: ["upload-file", "delete-images"],
});
};
@@ -307,7 +309,7 @@ export const queryThingDetailListApi = (tag_name: string, provider: string, buck
ignoreToken: false,
signature: false,
},
- hitSource: ["upload-file"],
+ hitSource: ["upload-file", "delete-images"],
});
};
@@ -327,6 +329,7 @@ export const getSingleImageApi = (id: number) => {
ignoreToken: false,
signature: false,
},
+ name: "single-image-url",
});
};
/**
@@ -342,7 +345,68 @@ export const getStorageConfigListApi = () => {
ignoreToken: false,
signature: false,
},
+ name: "storage-config-list",
+ });
+};
+/**
+ * 查询删除记录
+ * @param provider
+ * @param bucket
+ */
+export const getDeletedRecordApi = (provider: string, bucket: string) => {
+ return service.Post('/api/auth/storage/delete/record', {
+ provider: provider,
+ bucket: bucket,
+ }, {
+ cacheFor: {
+ expire: 60 * 60 * 24 * 7,
+ mode: "restore",
+ },
+ meta: {
+ ignoreToken: false,
+ signature: false,
+ },
+ name: "deleted-record",
+ hitSource: ["upload-file", "delete-images"],
+ });
+};
+/**
+ * 删除照片
+ * @param ids
+ * @param provider
+ * @param bucket
+ */
+export const deletedImagesApi = (ids: number[], provider: string, bucket: string) => {
+ return service.Post('/api/auth/storage/image/delete', {
+ ids: ids,
+ provider: provider,
+ bucket: bucket,
+ }, {
+ meta: {
+ ignoreToken: false,
+ signature: false,
+ },
+ name: "delete-images",
+ });
+};
+/**
+ * 获取存储桶容量
+ * @param provider
+ * @param bucket
+ */
+export const getBucketCapacityApi = (provider: string, bucket: string) => {
+ return service.Post('/api/auth/storage/bucket/capacity', {
+ provider: provider,
+ bucket: bucket,
+ }, {
+ cacheFor: {
+ expire: 60 * 60 * 24,
+ mode: "restore",
+ },
+ meta: {
+ ignoreToken: false,
+ signature: false,
+ },
+ name: "delete-images",
});
};
-
-
diff --git a/src/assets/images/original.png b/src/assets/images/original.png
new file mode 100644
index 0000000..36a8fd8
Binary files /dev/null and b/src/assets/images/original.png differ
diff --git a/src/assets/svgs/empty.svg b/src/assets/svgs/empty.svg
index f8b7977..1f5d753 100644
--- a/src/assets/svgs/empty.svg
+++ b/src/assets/svgs/empty.svg
@@ -1 +1 @@
-
+
diff --git a/src/layout/default/Sidebar/Sidebar.vue b/src/layout/default/Sidebar/Sidebar.vue
index 8c21b50..50af92e 100644
--- a/src/layout/default/Sidebar/Sidebar.vue
+++ b/src/layout/default/Sidebar/Sidebar.vue
@@ -74,11 +74,15 @@
@@ -97,11 +101,13 @@ import Folder from "@/components/Folder/Folder.vue";
import ai from '@/assets/svgs/ai.svg';
import share from '@/assets/svgs/share.svg';
import useStore from "@/store";
+import {getBucketCapacityApi} from "@/api/storage";
const {t} = useI18n();
const router = useRouter();
const route = useRoute();
const menu = useStore().menu;
+const upload = useStore().upload;
/**
* handle click event of menu item
@@ -117,6 +123,14 @@ const menuCSSStyle: any = reactive({
alignItems: 'center',
});
+const bucketCapacityInfo = ref();
+
+async function getBucketCapacity() {
+ const res: any = await getBucketCapacityApi(upload.storageSelected?.[0], upload.storageSelected?.[1]);
+ if (res && res.code === 200) {
+ bucketCapacityInfo.value = res.data;
+ }
+}
watch(
() => route.path,
@@ -135,9 +149,10 @@ function scrollToSelectedMenuItem() {
});
}
-onMounted(() => {
+onMounted(async () => {
menu.currentMenu = route.path.replace('/main', '').split('/').slice(0, 3).join('/').substring(1);
scrollToSelectedMenuItem();
+ await getBucketCapacity();
});
router.afterEach((_to) => {
menu.currentMenu = route.path.replace('/main', '').split('/').slice(0, 3).join('/').substring(1);
diff --git a/src/router/modules/main_router.ts b/src/router/modules/main_router.ts
index 720687b..22fac11 100644
--- a/src/router/modules/main_router.ts
+++ b/src/router/modules/main_router.ts
@@ -1,12 +1,14 @@
import photo from "@/router/modules/photos.ts";
import albums from "@/router/modules/albums.ts";
import recycling_bin from "@/router/modules/recycling_bin.ts";
+import share from "@/router/modules/share.ts";
+import upscale from "@/router/modules/upscale.ts";
export default [
{
path: '/main',
name: 'main',
- redirect: '/main/photos',
+ redirect: '/main/photo/all',
component: () => import('@/views/Main/MainPage.vue'),
meta: {
requiresAuth: true,
@@ -16,25 +18,18 @@ export default [
...photo,
...albums,
...recycling_bin,
- {
- path: '/main/photo/upscale',
- name: 'upscale',
- component: () => import('@/views/Upscale/index.vue'),
- meta: {
- requiresAuth: true,
- title: '图像修复'
- },
- },
- {
- path: '/main/photo/share',
- name: 'share',
- component: () => import('@/views/ImageShare/ImageShare.vue'),
- meta: {
- requiresAuth: true,
- title: '快传'
- }
- }
+ ...share,
+ ...upscale,
]
+ }, {
+ path: '/main/share/list/:id',
+ name: 'share-list',
+ component: () => import('@/views/Share/ShareViewList/index.vue'),
+ meta: {
+ requiresAuth: true,
+ title: '分享列表'
+ },
}
+
];
diff --git a/src/router/modules/share.ts b/src/router/modules/share.ts
new file mode 100644
index 0000000..a1d6a3e
--- /dev/null
+++ b/src/router/modules/share.ts
@@ -0,0 +1,11 @@
+export default [
+ {
+ path: '/main/photo/share',
+ name: 'share',
+ component: () => import('@/views/Share/ImageShare/ImageShare.vue'),
+ meta: {
+ requiresAuth: true,
+ title: '快传'
+ }
+ }
+];
diff --git a/src/router/modules/upscale.ts b/src/router/modules/upscale.ts
new file mode 100644
index 0000000..19776ea
--- /dev/null
+++ b/src/router/modules/upscale.ts
@@ -0,0 +1,11 @@
+export default [
+ {
+ path: '/main/photo/upscale',
+ name: 'upscale',
+ component: () => import('@/views/Upscale/index.vue'),
+ meta: {
+ requiresAuth: true,
+ title: '图像修复'
+ },
+ },
+];
diff --git a/src/store/index.ts b/src/store/index.ts
index 5e02e80..54db36b 100644
--- a/src/store/index.ts
+++ b/src/store/index.ts
@@ -6,6 +6,7 @@ import {useWebSocketStore} from "@/store/modules/websocketStore.ts";
import {useUpscaleStore} from "@/store/modules/upscaleStore.ts";
import {useMenuStore} from "@/store/modules/menuStore.ts";
import {useUploadStore} from "@/store/modules/uploadStore.ts";
+import {useImageStore} from "@/store/modules/imageStore.ts";
export default function useStore() {
return {
@@ -17,5 +18,6 @@ export default function useStore() {
upscale: useUpscaleStore(),
menu: useMenuStore(),
upload: useUploadStore(),
+ image: useImageStore(),
};
}
diff --git a/src/store/modules/imageStore.ts b/src/store/modules/imageStore.ts
new file mode 100644
index 0000000..be08ce4
--- /dev/null
+++ b/src/store/modules/imageStore.ts
@@ -0,0 +1,52 @@
+import {ImageList} from "@/types/image";
+
+export const useImageStore = defineStore(
+ 'image',
+ () => {
+ const selected = ref([]);
+ const tabActiveKey = ref("-1");
+ const tabMap = reactive({
+ "-1": "全部相册",
+ "0": "我的相册",
+ "1": "我的分享",
+ "2": "我的收藏",
+ });
+ const homeTabActiveKey = ref("all");
+ const homeTabMap = reactive({
+ "all": "全部",
+ "video": "视频",
+ "gif": "动图",
+ "screenshot": "截图",
+ });
+
+ /**
+ * 统计图片总数
+ * @param imageList 图片列表数据
+ * @returns 图片总数
+ */
+ function countTotalImages(imageList: ImageList): number {
+ if (!imageList) {
+ return 0;
+ }
+ return imageList.reduce((total, record) => total + record.list.length, 0);
+ }
+
+ return {
+ selected,
+ tabActiveKey,
+ tabMap,
+ homeTabMap,
+ homeTabActiveKey,
+ countTotalImages
+ };
+ },
+ {
+ // 开启数据持久化
+ persistedState: {
+ persist: true,
+ storage: localStorage,
+ key: 'image',
+ includePaths: ["tabActiveKey", "tabMap", "homeTabActiveKey", "homeTabMap"],
+ }
+ }
+);
diff --git a/src/store/modules/userStore.ts b/src/store/modules/userStore.ts
index b661bf4..1795fe6 100644
--- a/src/store/modules/userStore.ts
+++ b/src/store/modules/userStore.ts
@@ -84,7 +84,13 @@ export const useAuthStore = defineStore(
message.success(t('login.loginSuccess'));
window.removeEventListener("message", messageHandler);
setTimeout(() => {
- router.push('/main/photo/all');
+ const currentUrl = new URL(window.location.href);
+ const redirect = currentUrl.searchParams.get('redirect');
+ if (redirect) {
+ router.push(redirect);
+ } else {
+ router.push('/main/photo/all');
+ }
}, 1000);
} else {
message.error(t('login.loginError'));
diff --git a/src/types/image.d.ts b/src/types/image.d.ts
new file mode 100644
index 0000000..d2d1141
--- /dev/null
+++ b/src/types/image.d.ts
@@ -0,0 +1,16 @@
+export interface Image {
+ id: number;
+ file_name: string;
+ url: string;
+ width: number;
+ height: number;
+ created_at: string;
+ thumbnail: string;
+}
+
+export interface ImageRecord {
+ date: string;
+ list: Image[];
+}
+
+export type ImageList = ImageRecord[];
diff --git a/src/views/Album/LocationAlbum/LocationAlbumDetail.vue b/src/views/Album/LocationAlbum/LocationAlbumDetail.vue
index 25b09a8..a944c51 100644
--- a/src/views/Album/LocationAlbum/LocationAlbumDetail.vue
+++ b/src/views/Album/LocationAlbum/LocationAlbumDetail.vue
@@ -4,14 +4,15 @@
地点
>
-
乌鲁木齐
+
{{ route.query.name }}
+
- 共12张照片
+ 共{{ imageStore.countTotalImages(albumList) }}张照片
-
+
{{ itemList.date }}
@@ -21,7 +22,7 @@
class="photo-item"
margin="0"
border-radius="0"
- v-model="selected"
+ v-model="imageStore.selected"
:showHoverCircle="true"
:iconSize="20"
:showSelectedEffect="true"
@@ -41,6 +42,15 @@
+
+
+
+
+ 暂无照片,快去上传吧
+
+
+
+
@@ -50,8 +60,10 @@ import Vue3JustifiedLayout from "vue3-justified-layout";
import 'vue3-justified-layout/dist/style.css';
import {queryLocationDetailListApi} from "@/api/storage";
import useStore from "@/store";
+import ImageToolbar from "@/views/Photograph/ImageToolbar/ImageToolbar.vue";
+import empty from "@/assets/svgs/empty.svg";
-const selected = ref<(string | number)[]>([]);
+const imageStore = useStore().image;
const albumList = ref([]);
const route = useRoute();
diff --git a/src/views/Album/LocationAlbum/LocationAlbumList.vue b/src/views/Album/LocationAlbum/LocationAlbumList.vue
index a876d97..3487d93 100644
--- a/src/views/Album/LocationAlbum/LocationAlbumList.vue
+++ b/src/views/Album/LocationAlbum/LocationAlbumList.vue
@@ -8,7 +8,7 @@
{{ item.location }}
-
@@ -30,8 +30,8 @@ const route = useRoute();
const router = useRouter();
const upload = useStore().upload;
-function handleClick(id: number) {
- router.push({path: route.path + `/${id}`});
+function handleClick(id: number,name: string) {
+ router.push({path: route.path + `/${id}`, query: {name: name}});
}
const locationAlbums = ref
([]);
diff --git a/src/views/Album/PeopleAlbum/PeopleAlbumDetail.vue b/src/views/Album/PeopleAlbum/PeopleAlbumDetail.vue
index 16d7552..cf57444 100644
--- a/src/views/Album/PeopleAlbum/PeopleAlbumDetail.vue
+++ b/src/views/Album/PeopleAlbum/PeopleAlbumDetail.vue
@@ -11,16 +11,16 @@
-
+
- 共12张照片
+ 共{{ imageStore.countTotalImages(images) }}张照片
-
-
+
+
{{ itemList.date }}
@@ -29,7 +29,7 @@
class="photo-item"
margin="0"
border-radius="0"
- v-model="selected"
+ v-model="imageStore.selected"
:showHoverCircle="true"
:iconSize="20"
:showSelectedEffect="true"
@@ -49,6 +49,15 @@
+
+
+
+
+ 暂无照片,快去上传吧
+
+
+
+
@@ -58,10 +67,11 @@ import 'vue3-justified-layout/dist/style.css';
import {getFaceSamplesDetailList} from "@/api/storage";
import ImageToolbar from "@/views/Photograph/ImageToolbar/ImageToolbar.vue";
import useStore from "@/store";
+import empty from "@/assets/svgs/empty.svg";
-const selected = ref<(string | number)[]>([]);
-const albumList = ref
([]);
+const imageStore = useStore().image;
+const images = ref([]);
const route = useRoute();
const router = useRouter();
@@ -74,7 +84,7 @@ const options = reactive({
async function getAlbumList(id: number) {
const res: any = await getFaceSamplesDetailList(id, upload.storageSelected?.[0], upload.storageSelected?.[1]);
if (res && res.code === 200) {
- albumList.value = res.data.records;
+ images.value = res.data.records;
}
}
diff --git a/src/views/Album/PeopleAlbum/PeopleAlbumList.vue b/src/views/Album/PeopleAlbum/PeopleAlbumList.vue
index bc1bfcf..8d27d35 100644
--- a/src/views/Album/PeopleAlbum/PeopleAlbumList.vue
+++ b/src/views/Album/PeopleAlbum/PeopleAlbumList.vue
@@ -3,11 +3,11 @@
@@ -55,7 +55,7 @@
([]);
const addNameInputValue = ref('');
-const selecetedKey = ref('0');
+const selectedKey = ref('0');
const loading = ref(false);
const selected = ref([]);
@@ -180,7 +180,7 @@ async function modifyFaceName(id: number, index: number) {
* @param key
*/
function handleSelect({key}) {
- selecetedKey.value = key;
+ selectedKey.value = key;
getFaceList(parseInt(key));
}
@@ -203,7 +203,7 @@ function cancelSelectPeople() {
*/
async function hiddenFace() {
if (selected.value.length === 0) return;
- const res: any = await modifyFaceTypeBatch(selected.value, selecetedKey.value === '0' ? 1 : 0);
+ const res: any = await modifyFaceTypeBatch(selected.value, selectedKey.value === '0' ? 1 : 0);
if (res && res.code === 200) {
await getFaceList();
selected.value = [];
@@ -216,9 +216,10 @@ const router = useRouter();
/**
* 点击人物跳转到详情页
* @param id
+ * @param name
*/
-function handleClick(id: number) {
- router.push({path: route.path + `/${id}`});
+function handleClick(id: number, name: string | null) {
+ router.push({path: route.path + `/${id}`, query: {name: name}});
}
onMounted(() => {
diff --git a/src/views/Album/Phoalbum/PhoalbumDetail.vue b/src/views/Album/Phoalbum/PhoalbumDetail.vue
index 69ae192..3e8370a 100644
--- a/src/views/Album/Phoalbum/PhoalbumDetail.vue
+++ b/src/views/Album/Phoalbum/PhoalbumDetail.vue
@@ -26,17 +26,18 @@
下载相册
-
+
-
全部相册
+
+ {{ imageStore.tabMap[imageStore.tabActiveKey] }}
>
- 网盘导入
+ {{ route.query.name }}
- 共15张照片,1个视频,创建于2025年1月1日
+ 共 {{ imageStore.countTotalImages(albumList) }} 张照片
@@ -44,7 +45,7 @@
相册描述
-
+
{{ itemList.date }}
@@ -54,7 +55,7 @@
class="photo-item"
margin="0"
border-radius="0"
- v-model="selected"
+ v-model="imageStore.selected"
:showHoverCircle="true"
:iconSize="20"
:showSelectedEffect="true"
@@ -74,6 +75,15 @@
+
+
+
+
+ 暂无照片,快去上传吧
+
+
+
+
@@ -84,9 +94,10 @@ import 'vue3-justified-layout/dist/style.css';
import {queryAlbumDetailListApi} from "@/api/storage";
import ImageToolbar from "@/views/Photograph/ImageToolbar/ImageToolbar.vue";
import useStore from "@/store";
+import empty from "@/assets/svgs/empty.svg";
-const selected = ref<(string | number)[]>([]);
+const imageStore = useStore().image;
const albumList = ref
([]);
const route = useRoute();
diff --git a/src/views/Album/Phoalbum/PhoalbumList.vue b/src/views/Album/Phoalbum/PhoalbumList.vue
index 15c8b10..b059657 100644
--- a/src/views/Album/Phoalbum/PhoalbumList.vue
+++ b/src/views/Album/Phoalbum/PhoalbumList.vue
@@ -31,7 +31,7 @@
排序
-
+
按时间排序
按名称排序
@@ -49,18 +49,20 @@
+ style="width: 100%;"
+ v-model:activeKey="imageStore.tabActiveKey"
+ @change="handleTabChange">
已全部加载,共 {{ albumList ? albumList.length : 0 }} 个相册
-
+
-
+
-
+
-
+
(null);
const albumNameValue = ref("未命名相册");
const albumRenameValue = ref("");
-const selecetedKey = ref(true);
+const selectedKey = ref(true);
const albumList = ref([]);
const loading = ref(false);
+const imageStore = useStore().image;
+
/**
* 创建相册
*/
@@ -286,7 +291,7 @@ async function createAlbumSubmit() {
const res: any = await createAlbumApi(albumNameValue.value);
if (res && res.code === 200) {
albumNameValue.value = "未命名相册";
- await getAlbumList(0, selecetedKey.value);
+ await getAlbumList(parseInt(imageStore.tabActiveKey), selectedKey.value);
} else {
message.error("创建相册失败");
}
@@ -297,8 +302,8 @@ async function createAlbumSubmit() {
* @param key
*/
async function handleSelect({key}) {
- selecetedKey.value = key;
- await getAlbumList(0, key);
+ selectedKey.value = key;
+ await getAlbumList(parseInt(imageStore.tabActiveKey), key);
}
/**
@@ -306,7 +311,8 @@ async function handleSelect({key}) {
* @param activeKey
*/
async function handleTabChange(activeKey: string) {
- await getAlbumList(parseInt(activeKey), selecetedKey.value);
+ imageStore.tabActiveKey = activeKey;
+ await getAlbumList(parseInt(activeKey), selectedKey.value);
}
/**
@@ -337,7 +343,7 @@ async function renameAlbum(id: number, name: string) {
const res: any = await renameAlbumApi(id, name);
if (res && res.code === 200) {
albumRenameValue.value = "";
- await getAlbumList(0, selecetedKey.value);
+ await getAlbumList(parseInt(imageStore.tabActiveKey), selectedKey.value);
}
}
@@ -348,7 +354,7 @@ async function renameAlbum(id: number, name: string) {
async function deleteAlbum(id: number) {
const res: any = await deleteAlbumApi(id);
if (res && res.code === 200) {
- await getAlbumList(0, selecetedKey.value);
+ await getAlbumList(parseInt(imageStore.tabActiveKey), selectedKey.value);
} else {
message.error("删除相册失败");
}
@@ -360,13 +366,16 @@ const router = useRouter();
/**
* 点击相册跳转到详情页
* @param id
+ * @param albumName
*/
-function handleClick(id: number) {
- router.push({path: route.path + `/${id}`});
+function handleClick(id: number, albumName: string) {
+ router.push({
+ path: route.path + `/${id}`, query: {name: albumName}
+ });
}
onMounted(() => {
- getAlbumList(0, selecetedKey.value);
+ getAlbumList(parseInt(imageStore.tabActiveKey), selectedKey.value);
});
diff --git a/src/views/Album/ThingAlbum/ThingAlbumDetail.vue b/src/views/Album/ThingAlbum/ThingAlbumDetail.vue
index 3ec122c..b7e6ddf 100644
--- a/src/views/Album/ThingAlbum/ThingAlbumDetail.vue
+++ b/src/views/Album/ThingAlbum/ThingAlbumDetail.vue
@@ -2,14 +2,16 @@
-
+
- 共12张照片
+ 共{{ imageStore.countTotalImages(albumList) }}张照片
@@ -22,7 +24,7 @@
class="photo-item"
margin="0"
border-radius="0"
- v-model="selected"
+ v-model="imageStore.selected"
:showHoverCircle="true"
:iconSize="20"
:showSelectedEffect="true"
@@ -53,9 +55,10 @@ import 'vue3-justified-layout/dist/style.css';
import {queryThingDetailListApi} from "@/api/storage";
import ImageToolbar from "@/views/Photograph/ImageToolbar/ImageToolbar.vue";
import useStore from "@/store";
+import {getZhCategoryNameByEnName, getZhLabelNameByEnName} from "@/constant/coco_ssd_label_category.ts";
-const selected = ref<(string | number)[]>([]);
+const imageStore = useStore().image;
const albumList = ref
([]);
const upload = useStore().upload;
const route = useRoute();
@@ -113,7 +116,7 @@ function goBack(): void {
justify-content: flex-start;
width: 1000%;
height: 100%;
- gap: 10px;
+ gap: 5px;
.thing-detail-content-nav-title {
font-size: 20px;
@@ -121,6 +124,7 @@ function goBack(): void {
display: flex;
align-items: center;
justify-content: center;
+ padding: 7px;
}
.thing-detail-content-nav-separator {
@@ -141,13 +145,13 @@ function goBack(): void {
flex-direction: row;
align-items: center;
justify-content: flex-start;
- margin-left: 30px;
+ margin-left: 15px;
width: 100%;
height: 22px;
}
.thing-album-detail-list {
- width: 99%;
+ width: 100%;
height: 100%;
//margin-left: 5px;
}
diff --git a/src/views/Album/ThingAlbum/ThingAlbumList.vue b/src/views/Album/ThingAlbum/ThingAlbumList.vue
index bbe835c..2f9fcbd 100644
--- a/src/views/Album/ThingAlbum/ThingAlbumList.vue
+++ b/src/views/Album/ThingAlbum/ThingAlbumList.vue
@@ -10,7 +10,7 @@
{{ getZhCategoryNameByEnName(item.category) }}
+ @click="handleClick(tags.tag_name,item.category,tags.tag_name)">
{{ getZhLabelNameByEnName(tags.tag_name) }}
@@ -46,9 +46,11 @@ const upload = useStore().upload;
/**
* 点击事件
* @param id
+ * @param tag
+ * @param category
*/
-function handleClick(id: string) {
- router.push({path: route.path + `/${id}`});
+function handleClick(id: string, category: string, tag: string) {
+ router.push({path: route.path + `/${id}`, query: {category: category, tag: tag}});
}
onMounted(() => {
diff --git a/src/views/ImageShare/index.scss b/src/views/ImageShare/index.scss
deleted file mode 100644
index 35a1b17..0000000
--- a/src/views/ImageShare/index.scss
+++ /dev/null
@@ -1,100 +0,0 @@
-.image-share {
- display: flex;
- flex-direction: row;
- align-items: flex-start;
- justify-content: flex-start;
- width: 100%;
- height: 100%;
- gap: 20px;
-
- .image-share-left {
- height: 100%;
- width: 65%;
- display: flex;
- flex-direction: column;
- align-items: flex-start;
- justify-content: flex-start;
-
- .image-share-left-top {
- width: 100%;
- height: 30%;
- display: flex;
- flex-direction: column;
- gap: 10px;
-
- .image-share-left-title {
- width: 100%;
- height: 20%;
- display: flex;
- flex-direction: row;
- align-items: center;
- justify-content: space-between;
- }
-
- .image-share-left-content {
- width: 100%;
- height: 80%;
- display: flex;
- flex-direction: row;
- align-items: center;
- justify-content: space-between;
-
- .image-share-left-content-item {
- height: 100%;
- width: 30%;
- color: #fff;
- overflow: auto;
-
- .image-share-left-item-content {
- width: 100%;
- height: 100%;
- display: flex;
- flex-direction: column;
- justify-content: space-between;
- align-items: flex-start;
- overflow: hidden;
- }
- }
- }
-
- }
-
- .image-share-left-bottom {
- width: 100%;
- height: 70%;
- display: flex;
- flex-direction: column;
-
- .image-share-left-bottom-title {
- width: 100%;
- height: 20%;
- display: flex;
- flex-direction: row;
- align-items: center;
- justify-content: space-between;
- }
-
- .image-share-left-bottom-content {
- width: 100%;
- height: 80%;
- display: flex;
- flex-direction: column;
- align-items: flex-start;
- justify-content: flex-start;
-
- .ant-card {
- height: 100%;
-
- .ant-table {
- flex: 1; // 让 ATable 填满剩余空间
- height: 100%;
- }
- }
- }
- }
- }
-
-}
-
-
-
diff --git a/src/views/Login/LoginPage.vue b/src/views/Login/LoginPage.vue
index 163d2de..67f1c54 100644
--- a/src/views/Login/LoginPage.vue
+++ b/src/views/Login/LoginPage.vue
@@ -383,7 +383,13 @@ async function phoneLoginSubmit() {
message.success(t('login.loginSuccess'));
loginLoading.value = false;
setTimeout(() => {
- router.push('/main/photo/all');
+ const currentUrl = new URL(window.location.href);
+ const redirect = currentUrl.searchParams.get('redirect');
+ if (redirect) {
+ router.push(redirect);
+ } else {
+ router.push('/main/photo/all');
+ }
}, 1000);
} else {
loginLoading.value = false;
@@ -472,7 +478,13 @@ async function checkAccountLoginCaptcha(angle: number) {
loginLoading.value = false;
showAccountRotateCaptcha.value = false;
setTimeout(() => {
- router.push('/main/photo/all');
+ const currentUrl = new URL(window.location.href);
+ const redirect = currentUrl.searchParams.get('redirect');
+ if (redirect) {
+ router.push(redirect);
+ } else {
+ router.push('/main/photo/all');
+ }
}, 1000);
} else {
showAccountRotateCaptcha.value = false;
diff --git a/src/views/Photograph/AllPhoto/AllPhoto.vue b/src/views/Photograph/AllPhoto/AllPhoto.vue
index 0a6318f..4ee5710 100644
--- a/src/views/Photograph/AllPhoto/AllPhoto.vue
+++ b/src/views/Photograph/AllPhoto/AllPhoto.vue
@@ -14,57 +14,216 @@
创建相册
-
+
-
-
-
-
{{ itemList.date }}
-
-
-
-
-
+
+
+
+
{{ itemList.date }}
+
+
+
+
+
-
-
-
-
-
-
-
+ loading="lazy">
+
+
+
+
+
+
+
+
-
+
+
+
+
+ 还没检测到任何图片,快去上传吧!
+
+
+
+
+
-
-
-
-
+
+
+
+
+
{{ itemList.date }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 还没检测到任何视频,快去上传吧!
+
+
+
+
+
-
-
+
+
+
+
+
{{ itemList.date }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 还没检测到任何动图,快去上传吧!
+
+
+
+
+
-
-
+
+
+
+
+
{{ itemList.date }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 还没检测到任何屏幕截图,快去上传吧!
+
+
+
+
+
@@ -80,9 +239,10 @@ import ImageUpload from "@/views/Photograph/ImageUpload/ImageUpload.vue";
import useStore from "@/store";
import {queryAllImagesApi} from "@/api/storage";
import ImageToolbar from "@/views/Photograph/ImageToolbar/ImageToolbar.vue";
+import empty from "@/assets/svgs/empty.svg";
+const imageStore = useStore().image;
-const selected = ref<(string | number)[]>([]);
const switchValue = ref(false);
const upload = useStore().upload;
@@ -91,20 +251,29 @@ const options = reactive({
});
const images = ref([]);
+const loading = ref(false);
/**
* 获取所有图片
*/
-async function getAllImages() {
- const res: any = await queryAllImagesApi("image", false, upload.storageSelected?.[0], upload.storageSelected?.[1]);
+async function getAllImages(type: string) {
+ images.value = [];
+ loading.value = true;
+ const res: any = await queryAllImagesApi(type, false, upload.storageSelected?.[0], upload.storageSelected?.[1]);
if (res && res.code === 200) {
images.value = res.data.records;
}
+ loading.value = false;
+}
+
+async function handleTabChange(activeKey: string) {
+ imageStore.homeTabActiveKey = activeKey;
+ await getAllImages(activeKey);
}
onMounted(() => {
- getAllImages();
+ getAllImages(imageStore.homeTabActiveKey);
});
diff --git a/src/views/Photograph/ImageToolbar/ImageToolbar.vue b/src/views/Photograph/ImageToolbar/ImageToolbar.vue
index ec4dd1f..f4f10f5 100644
--- a/src/views/Photograph/ImageToolbar/ImageToolbar.vue
+++ b/src/views/Photograph/ImageToolbar/ImageToolbar.vue
@@ -1,18 +1,8 @@
-
-
+
diff --git a/src/views/ImageShare/ShareUpload.vue b/src/views/Share/ImageShare/ShareUpload.vue
similarity index 94%
rename from src/views/ImageShare/ShareUpload.vue
rename to src/views/Share/ImageShare/ShareUpload.vue
index 3cd7d54..0b85588 100644
--- a/src/views/ImageShare/ShareUpload.vue
+++ b/src/views/Share/ImageShare/ShareUpload.vue
@@ -23,18 +23,30 @@
单击或拖动文件到此区域以上传
- 上 传 照 片
+
+
+
+
+ 上 传 照 片
+
+
+
+
+
+
+
+
+
+ 手 机 上 传
+
+
-
@@ -143,7 +155,7 @@
-
.image-share-right {
@@ -674,6 +689,6 @@ onMounted(() => {
display: flex;
flex-direction: column;
align-items: center;
- gap: 2vh;
+ gap: 5vh;
}
diff --git a/src/views/Share/ShareViewList/ShareSidebar.vue b/src/views/Share/ShareViewList/ShareSidebar.vue
new file mode 100644
index 0000000..b44f63e
--- /dev/null
+++ b/src/views/Share/ShareViewList/ShareSidebar.vue
@@ -0,0 +1,154 @@
+
+
+
+
+
diff --git a/src/views/Share/ShareViewList/index.vue b/src/views/Share/ShareViewList/index.vue
new file mode 100644
index 0000000..ba9ea20
--- /dev/null
+++ b/src/views/Share/ShareViewList/index.vue
@@ -0,0 +1,142 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+