From 2063a99c8300767674b390b338001fb66195c58f Mon Sep 17 00:00:00 2001 From: landaiqing Date: Thu, 20 Feb 2025 23:03:25 +0800 Subject: [PATCH] :sparkles: improve image sharing function --- components.d.ts | 10 +- package.json | 7 +- src/api/share/index.ts | 43 ++ src/api/storage/index.ts | 4 +- src/router/modules/phone_upload.ts | 2 +- .../LocationAlbum/LocationAlbumDetail.vue | 2 +- .../Album/LocationAlbum/LocationAlbumList.vue | 2 +- .../Album/PeopleAlbum/PeopleAlbumDetail.vue | 2 +- src/views/Album/Phoalbum/PhoalbumDetail.vue | 2 +- src/views/Album/Phoalbum/PhoalbumList.vue | 169 ++++- .../Album/ThingAlbum/ThingAlbumDetail.vue | 5 +- src/views/Album/ThingAlbum/ThingAlbumList.vue | 3 +- src/views/ImageShare/ImageShare.vue | 647 ++++------------- src/views/ImageShare/ShareUpload.vue | 679 ++++++++++++++++++ src/views/ImageShare/index.scss | 100 +++ .../SharePhoneUpload/SharePhoneUpload.vue | 9 + .../UpscalePhoneUpload.vue} | 0 src/views/Photograph/AllPhoto/AllPhoto.vue | 2 +- .../Photograph/ImageUpload/ImageUpload.vue | 4 +- src/views/RecyclingBin/RecyclingBin.vue | 8 + 20 files changed, 1150 insertions(+), 550 deletions(-) create mode 100644 src/api/share/index.ts create mode 100644 src/views/ImageShare/ShareUpload.vue create mode 100644 src/views/ImageShare/index.scss create mode 100644 src/views/Phone/SharePhoneUpload/SharePhoneUpload.vue rename src/views/{PhoneUpload/PhoneUpload.vue => Phone/UpscalePhoneUpload/UpscalePhoneUpload.vue} (100%) diff --git a/components.d.ts b/components.d.ts index b1fc805..94c4c87 100644 --- a/components.d.ts +++ b/components.d.ts @@ -2,6 +2,7 @@ // @ts-nocheck // Generated by unplugin-vue-components // Read more: https://github.com/vuejs/core/pull/3399 +// biome-ignore lint: disable export {} /* prettier-ignore */ @@ -39,6 +40,7 @@ declare module 'vue' { 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'] @@ -64,6 +66,7 @@ declare module 'vue' { BoxDog: typeof import('./src/components/BoxDog/BoxDog.vue')['default'] 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'] @@ -71,6 +74,7 @@ declare module 'vue' { 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'] @@ -87,6 +91,7 @@ declare module 'vue' { 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'] LoadingGraphic: typeof import('./src/components/LoadingGraphic/LoadingGraphic.vue')['default'] LocationAlbum: typeof import('./src/views/Album/LocationAlbum/LocationAlbum.vue')['default'] LocationAlbumDetail: typeof import('./src/views/Album/LocationAlbum/LocationAlbumDetail.vue')['default'] @@ -105,7 +110,7 @@ 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/PhoneUpload/PhoneUpload.vue')['default'] + PhoneUpload: typeof import('./src/views/Phone/UpscalePhoneUpload/PhoneUpload.vue')['default'] 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'] @@ -123,6 +128,8 @@ declare module 'vue' { 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'] 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'] @@ -132,6 +139,7 @@ declare module 'vue' { Tooltip: typeof import('./src/components/MyUI/Tooltip/Tooltip.vue')['default'] UploadImage: typeof import('./src/views/Upscale/UploadImage.vue')['default'] 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'] diff --git a/package.json b/package.json index 0248f97..935018e 100644 --- a/package.json +++ b/package.json @@ -52,6 +52,7 @@ "json-stringify-safe": "^5.0.1", "less": "^4.2.2", "localforage": "^1.10.0", + "moment": "^2.30.1", "nprogress": "^0.2.0", "nsfwjs": "^4.2.1", "pinia": "^3.0.1", @@ -79,15 +80,15 @@ "sass": "^1.85.0", "typescript": "^5.7.3", "typescript-eslint": "^8.24.1", - "unplugin-vue-components": "^28.2.0", - "vite": "^6.1.0", + "unplugin-vue-components": "^28.4.0", + "vite": "^6.1.1", "vite-plugin-bundle-obfuscator": "1.4.1", "vite-plugin-chunk-split": "^0.5.0", "vue-tsc": "2.2.2" }, "overrides": { "vite-plugin-chunk-split": { - "vite": "^6.1.0" + "vite": "^6.1.1" } } } diff --git a/src/api/share/index.ts b/src/api/share/index.ts new file mode 100644 index 0000000..3e34981 --- /dev/null +++ b/src/api/share/index.ts @@ -0,0 +1,43 @@ +import {service} from "@/utils/alova/service.ts"; + +/** + * 上传分享图片 + * @param formData + */ +export const shareImageUploadApi = (formData) => { + return service.Post('/api/auth/share/upload', {...formData}, { + meta: { + ignoreToken: false, + signature: false, + }, + }); +}; +/** + * 查询分享图片列表 + * @param share_code + * @param access_password + */ +export const queryShareImageApi = (share_code: string, access_password: string) => { + return service.Post('/api/auth/share/image/list', { + share_code: share_code, + access_password: access_password, + }, { + meta: { + ignoreToken: false, + signature: false, + }, + }); +}; +/** + * 查询分享记录列表 + */ +export const queryShareRecordListApi = (dataRequest: string[]) => { + return service.Post('/api/auth/share/record/list', { + date_range: dataRequest, + }, { + meta: { + ignoreToken: false, + signature: false, + }, + }); +}; diff --git a/src/api/storage/index.ts b/src/api/storage/index.ts index b10da99..ff86bdb 100644 --- a/src/api/storage/index.ts +++ b/src/api/storage/index.ts @@ -110,7 +110,7 @@ export const createAlbumApi = (name: string) => { * @param type * @param sort */ -export const albumListApi = (type: string, sort: boolean) => { +export const albumListApi = (type: number, sort: boolean) => { return service.Post('/api/auth/storage/album/list', { type: type, sort: sort, @@ -344,3 +344,5 @@ export const getStorageConfigListApi = () => { }, }); }; + + diff --git a/src/router/modules/phone_upload.ts b/src/router/modules/phone_upload.ts index fff5f48..35a5856 100644 --- a/src/router/modules/phone_upload.ts +++ b/src/router/modules/phone_upload.ts @@ -2,7 +2,7 @@ export default [ { path: '/upscale/app', name: 'upscaleApp', - component: () => import('@/views/PhoneUpload/PhoneUpload.vue'), + component: () => import('@/views/Phone/UpscalePhoneUpload/UpscalePhoneUpload.vue'), meta: { requiresAuth: false, title: '手机上传' diff --git a/src/views/Album/LocationAlbum/LocationAlbumDetail.vue b/src/views/Album/LocationAlbum/LocationAlbumDetail.vue index a334d77..25b09a8 100644 --- a/src/views/Album/LocationAlbum/LocationAlbumDetail.vue +++ b/src/views/Album/LocationAlbum/LocationAlbumDetail.vue @@ -62,7 +62,7 @@ const options = reactive({ }); async function getImageList(id: number) { - const res: any = await queryLocationDetailListApi(id, upload.storageSelected[0], upload.storageSelected[1]); + const res: any = await queryLocationDetailListApi(id, upload.storageSelected?.[0], upload.storageSelected?.[1]); console.log(res); if (res && res.code === 200) { albumList.value = res.data.records; diff --git a/src/views/Album/LocationAlbum/LocationAlbumList.vue b/src/views/Album/LocationAlbum/LocationAlbumList.vue index ff634e9..a876d97 100644 --- a/src/views/Album/LocationAlbum/LocationAlbumList.vue +++ b/src/views/Album/LocationAlbum/LocationAlbumList.vue @@ -44,7 +44,7 @@ async function getLocationAlbums(provider: string, bucket: string) { } onMounted(() => { - getLocationAlbums(upload.storageSelected[0], upload.storageSelected[1]); + getLocationAlbums(upload.storageSelected?.[0], upload.storageSelected?.[1]); }); diff --git a/src/views/ImageShare/ShareUpload.vue b/src/views/ImageShare/ShareUpload.vue new file mode 100644 index 0000000..3cd7d54 --- /dev/null +++ b/src/views/ImageShare/ShareUpload.vue @@ -0,0 +1,679 @@ + + + diff --git a/src/views/ImageShare/index.scss b/src/views/ImageShare/index.scss new file mode 100644 index 0000000..35a1b17 --- /dev/null +++ b/src/views/ImageShare/index.scss @@ -0,0 +1,100 @@ +.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/Phone/SharePhoneUpload/SharePhoneUpload.vue b/src/views/Phone/SharePhoneUpload/SharePhoneUpload.vue new file mode 100644 index 0000000..e8e39c5 --- /dev/null +++ b/src/views/Phone/SharePhoneUpload/SharePhoneUpload.vue @@ -0,0 +1,9 @@ + + + diff --git a/src/views/PhoneUpload/PhoneUpload.vue b/src/views/Phone/UpscalePhoneUpload/UpscalePhoneUpload.vue similarity index 100% rename from src/views/PhoneUpload/PhoneUpload.vue rename to src/views/Phone/UpscalePhoneUpload/UpscalePhoneUpload.vue diff --git a/src/views/Photograph/AllPhoto/AllPhoto.vue b/src/views/Photograph/AllPhoto/AllPhoto.vue index 08826aa..0a6318f 100644 --- a/src/views/Photograph/AllPhoto/AllPhoto.vue +++ b/src/views/Photograph/AllPhoto/AllPhoto.vue @@ -96,7 +96,7 @@ const images = ref([]); * 获取所有图片 */ async function getAllImages() { - const res: any = await queryAllImagesApi("image", false, upload.storageSelected[0], upload.storageSelected[1]); + const res: any = await queryAllImagesApi("image", false, upload.storageSelected?.[0], upload.storageSelected?.[1]); if (res && res.code === 200) { images.value = res.data.records; } diff --git a/src/views/Photograph/ImageUpload/ImageUpload.vue b/src/views/Photograph/ImageUpload/ImageUpload.vue index b896894..8b4c4ab 100644 --- a/src/views/Photograph/ImageUpload/ImageUpload.vue +++ b/src/views/Photograph/ImageUpload/ImageUpload.vue @@ -224,8 +224,8 @@ async function customUploadRequest(file: any) { formData.append("thumbnail", binaryData); } formData.append("data", JSON.stringify({ - provider: upload.storageSelected[0], - bucket: upload.storageSelected[1], + provider: upload.storageSelected?.[0], + bucket: upload.storageSelected?.[1], fileType: file.file.type, ...upload.predictResult, })); diff --git a/src/views/RecyclingBin/RecyclingBin.vue b/src/views/RecyclingBin/RecyclingBin.vue index e6985aa..90b31c2 100644 --- a/src/views/RecyclingBin/RecyclingBin.vue +++ b/src/views/RecyclingBin/RecyclingBin.vue @@ -38,6 +38,7 @@