From 76336d15531c17edff5b017936dc4bbbf65829fd Mon Sep 17 00:00:00 2001 From: landaiqing Date: Fri, 20 Dec 2024 01:23:51 +0800 Subject: [PATCH] :children_crossing: optimize --- src/api/client/index.ts | 6 +- src/api/comment/index.ts | 4 +- src/api/oauth/gitee.ts | 2 +- src/api/oauth/github.ts | 2 +- src/api/oauth/qq.ts | 2 +- src/api/oauth/wechat.ts | 2 +- src/api/user/index.ts | 11 +- src/store/modules/upscaleStore.ts | 83 ++++++++++++- src/store/modules/userStore.ts | 19 +-- src/store/modules/websocketStore.ts | 8 +- src/utils/alova/service.ts | 2 +- src/utils/errorCode/errorCodeHandler.ts | 24 ++-- src/utils/imageUtils/getImageSizeWithUnit.ts | 29 +++++ src/utils/websocket/websocket.ts | 9 +- src/views/QRLogin/QRLogin.vue | 29 +++-- src/views/Upscale/CompareImage.vue | 68 +++++++++-- src/views/Upscale/ParameterSetting.vue | 116 +++++-------------- src/views/Upscale/index.vue | 17 ++- src/workers/upscale.worker.ts | 4 - 19 files changed, 276 insertions(+), 161 deletions(-) create mode 100644 src/utils/imageUtils/getImageSizeWithUnit.ts diff --git a/src/api/client/index.ts b/src/api/client/index.ts index d9840fa..f461f0d 100644 --- a/src/api/client/index.ts +++ b/src/api/client/index.ts @@ -8,11 +8,9 @@ export const generateClientId = () => { { meta: { ignoreToken: true, + signature: true }, - cacheFor: { - mode: "restore", - expire: 1000 * 60 * 60 * 24 - } + cacheFor: null, } ); }; diff --git a/src/api/comment/index.ts b/src/api/comment/index.ts index 54d642f..d658472 100644 --- a/src/api/comment/index.ts +++ b/src/api/comment/index.ts @@ -58,7 +58,7 @@ export const commentListApi = (params: any) => { }, { cacheFor: { - expire: 60 * 60 * 24 * 7, + expire: 60 * 60 * 24, mode: "restore", }, // 7天缓存 hitSource: "comment-submit", @@ -81,7 +81,7 @@ export const replyListApi = (params: any) => { }, { cacheFor: { - expire: 60 * 60 * 24 * 7, + expire: 60 * 60 * 24, mode: "restore", }, // 7天缓存 hitSource: ["reply-submit", "reply-reply-submit"], diff --git a/src/api/oauth/gitee.ts b/src/api/oauth/gitee.ts index 225403b..4d0fa1e 100644 --- a/src/api/oauth/gitee.ts +++ b/src/api/oauth/gitee.ts @@ -11,7 +11,7 @@ export const getGiteeUrl = () => { }, cacheFor: { mode: "restore", - expire: 1000 * 60 * 60 * 24 * 7 + expire: 1000 * 60 * 60 * 24 } } ); diff --git a/src/api/oauth/github.ts b/src/api/oauth/github.ts index f9dfeee..12ae33c 100644 --- a/src/api/oauth/github.ts +++ b/src/api/oauth/github.ts @@ -14,7 +14,7 @@ export const getGithubUrl = (state: string) => { }, cacheFor: { mode: "restore", - expire: 1000 * 60 * 60 * 24 * 7 + expire: 1000 * 60 * 60 * 24 } } ); diff --git a/src/api/oauth/qq.ts b/src/api/oauth/qq.ts index 3ad86c5..7ae99df 100644 --- a/src/api/oauth/qq.ts +++ b/src/api/oauth/qq.ts @@ -11,7 +11,7 @@ export const getQQUrl = (state: string) => { }, cacheFor: { mode: "restore", - expire: 1000 * 60 * 60 * 24 * 7 + expire: 1000 * 60 * 60 * 24 } } ); diff --git a/src/api/oauth/wechat.ts b/src/api/oauth/wechat.ts index cd733b1..a85912b 100644 --- a/src/api/oauth/wechat.ts +++ b/src/api/oauth/wechat.ts @@ -10,7 +10,7 @@ export const generateQrCode = (clientId: string) => { params: { client_id: clientId }, - cacheFor: 1000 * 60 * 60 * 24 * 7, + cacheFor: null, meta: { ignoreToken: true, }, diff --git a/src/api/user/index.ts b/src/api/user/index.ts index a6145f5..aad9459 100644 --- a/src/api/user/index.ts +++ b/src/api/user/index.ts @@ -8,7 +8,7 @@ export const refreshToken = () => { return service.Post('/api/auth/token/refresh', {}, { meta: { authRole: 'refreshToken', - ignoreToken: false, + ignoreToken: true, signature: true } }); @@ -93,11 +93,14 @@ export const resetPasswordApi = (param: ResetPassword) => { /** * 获取用户设备信息 + * @param access_token */ -export const getUserDevice = () => { - return service.Get('/api/user/device', +export const getUserDevice = (access_token: string) => { + return service.Post('/api/user/device', + { + access_token: access_token, + }, { - params: {}, meta: { ignoreToken: true, signature: true diff --git a/src/store/modules/upscaleStore.ts b/src/store/modules/upscaleStore.ts index 32218d9..a7afeb5 100644 --- a/src/store/modules/upscaleStore.ts +++ b/src/store/modules/upscaleStore.ts @@ -12,6 +12,73 @@ import Module from "@/workers/imghelper.ts"; export const useUpscaleStore = defineStore( 'upscale', () => { + + // 模型参数 + const TypeData = ref(['realesrgan', 'realcugan']); + + const model_type = ref(TypeData.value[0]); + + const ModelConfig = reactive({ + realesrgan: { + model: ["anime_fast", "anime_plus", "general_fast", "general_plus"], + factor: [4], + tile_size: [32, 48, 64, 96, 128, 192, 256], + }, + realcugan: { + factor: [2, 4], + denoise: { + 2: [ + "conservative", + "no-denoise", + "denoise1x", + "denoise2x", + "denoise3x", + ], + 3: ["conservative", "denoise3x"], + 4: ["conservative", "no-denoise", "denoise3x"], + }, + tile_size: [32, 48, 64, 96, 128, 192, 256, 384, 512], + } + }); + const factor = ref(4); + const model = ref(ModelConfig[model_type.value].model[0]); + const modes = computed(() => { + if (model_type.value === "realesrgan") { + return ModelConfig[model_type.value].model; + } else { + return ModelConfig[model_type.value].denoise[factor.value]; + } + }); + + watch(model_type, val => { + if (model_type.value === "realesrgan") { + model.value = ModelConfig[val].model[0]; + } else { + model.value = ModelConfig[val].denoise[factor.value][0]; + } + }); + + + // Scale + const scales = computed(() => { + return ModelConfig[model_type.value].factor; + }); + + //tile size + const tile_size = ref(128); + const tileSize = computed(() => { + return ModelConfig[model_type.value].tile_size; + }); + + // overlap + const overlapList = ref([0, 4, 8, 12, 16, 20]); + const min_lap = ref(overlapList.value[3]); + + // run on + const backendList = ref(['webgl', 'webgpu']); + const backend = ref(backendList.value[0]); + + // ***************图片处理*************** const image: HTMLImageElement = document.createElement('img'); const imageData = ref(); const fileData = ref(); @@ -33,7 +100,7 @@ export const useUpscaleStore = defineStore( const isProcessing = ref(false); const msg = ref(""); const progressBar = ref(0); - + const status = ref('loading'); /** * 图片上传前的校验 * @param file @@ -111,6 +178,19 @@ export const useUpscaleStore = defineStore( return { + TypeData, + model_type, + ModelConfig, + model, + modes, + factor, + tile_size, + tileSize, + scales, + overlapList, + min_lap, + backend, + backendList, uploading, imageData, input, @@ -122,6 +202,7 @@ export const useUpscaleStore = defineStore( isProcessing, msg, progressBar, + status, loadImg, beforeUpload, customUploadRequest, diff --git a/src/store/modules/userStore.ts b/src/store/modules/userStore.ts index 15b7333..07272e7 100644 --- a/src/store/modules/userStore.ts +++ b/src/store/modules/userStore.ts @@ -5,7 +5,7 @@ import {getGithubUrl} from "@/api/oauth/github.ts"; import {getQQUrl} from "@/api/oauth/qq.ts"; import {getGiteeUrl} from "@/api/oauth/gitee.ts"; import {getUserDevice} from "@/api/user"; -import message from "@/components/MyUI/Message/Message.vue"; +import {message} from "ant-design-vue"; import {useI18n} from "vue-i18n"; export const useAuthStore = defineStore( @@ -70,17 +70,18 @@ export const useAuthStore = defineStore( * 处理消息 * @param e */ - const messageHandler = async (e: any) => { + const messageHandler = async (e: MessageEvent) => { if (typeof e.data === 'string') { const res: any = JSON.parse(e.data); if (res && res.code === 200) { - user.uid = res.data.uid; - user.access_token = res.data.access_token; - user.username = res.data.username; - user.avatar = res.data.avatar; - user.nickname = res.data.nickname; - user.status = res.data.status; - await getUserDevice(); + const {data} = res; + user.uid = data.uid; + user.access_token = data.access_token; + user.username = data.username; + user.avatar = data.avatar; + user.nickname = data.nickname; + user.status = data.status; + await getUserDevice(data.access_token); message.success(t('login.loginSuccess')); window.removeEventListener("message", messageHandler); setTimeout(() => { diff --git a/src/store/modules/websocketStore.ts b/src/store/modules/websocketStore.ts index 23a375b..0b450df 100644 --- a/src/store/modules/websocketStore.ts +++ b/src/store/modules/websocketStore.ts @@ -20,7 +20,13 @@ export const useWebSocketStore = defineStore('websocket', () => { }) { state.wsService = new WebSocketService(options); state.wsService?.open(); - readyState.value = WebSocket.OPEN; + + state.wsService?.on('open', () => { + readyState.value = WebSocket.OPEN; + }); + state.wsService?.on('close', () => { + readyState.value = WebSocket.CLOSED; + }); } function sendMessage(data: any) { diff --git a/src/utils/alova/service.ts b/src/utils/alova/service.ts index 0c74990..853dfc0 100644 --- a/src/utils/alova/service.ts +++ b/src/utils/alova/service.ts @@ -41,7 +41,7 @@ export const service = createAlova({ requestAdapter: axiosRequestAdapter(), l2Cache: localforageStorageAdapter, cacheLogger: import.meta.env.VITE_NODE_ENV === 'development', - cacheFor: {}, + cacheFor: null, // 设置全局的请求拦截器 beforeRequest: onAuthRequired(async (method: any) => { if (!method.meta?.ignoreToken) { diff --git a/src/utils/errorCode/errorCodeHandler.ts b/src/utils/errorCode/errorCodeHandler.ts index 4c37c6a..65ef3c8 100644 --- a/src/utils/errorCode/errorCodeHandler.ts +++ b/src/utils/errorCode/errorCodeHandler.ts @@ -6,7 +6,7 @@ export function handleErrorCode(code: number): void { message .open({ content: i18n.global.t("error.400"), - duration: 5, + duration: 3, type: "error", }) .then(); @@ -15,7 +15,7 @@ export function handleErrorCode(code: number): void { message .open({ content: i18n.global.t("error.401"), - duration: 5, + duration: 3, type: "error", }) .then(); @@ -24,7 +24,7 @@ export function handleErrorCode(code: number): void { message .open({ content: i18n.global.t("error.403"), - duration: 5, + duration: 3, type: "error", }) .then(); @@ -33,7 +33,7 @@ export function handleErrorCode(code: number): void { message .open({ content: i18n.global.t("error.404"), - duration: 5, + duration: 3, type: "error", }) .then(); @@ -42,7 +42,7 @@ export function handleErrorCode(code: number): void { message .open({ content: i18n.global.t("error.408"), - duration: 5, + duration: 3, type: "error", }) .then(); @@ -51,7 +51,7 @@ export function handleErrorCode(code: number): void { message .open({ content: i18n.global.t("error.500"), - duration: 5, + duration: 3, type: "error", }) .then(); @@ -60,7 +60,7 @@ export function handleErrorCode(code: number): void { message .open({ content: i18n.global.t("error.501"), - duration: 5, + duration: 3, type: "error", }) .then(); @@ -69,7 +69,7 @@ export function handleErrorCode(code: number): void { message .open({ content: i18n.global.t("error.502"), - duration: 5, + duration: 3, type: "error", }) .then(); @@ -78,7 +78,7 @@ export function handleErrorCode(code: number): void { message .open({ content: i18n.global.t("error.503"), - duration: 5, + duration: 3, type: "error", }) .then(); @@ -87,7 +87,7 @@ export function handleErrorCode(code: number): void { message .open({ content: i18n.global.t("error.504"), - duration: 5, + duration: 3, type: "error", }) .then(); @@ -96,7 +96,7 @@ export function handleErrorCode(code: number): void { message .open({ content: i18n.global.t("error.505"), - duration: 5, + duration: 3, type: "error", }) .then(); @@ -105,7 +105,7 @@ export function handleErrorCode(code: number): void { message .open({ content: i18n.global.t("error.other") + `(${code})`, - duration: 5, + duration: 3, type: "error", }) .then(); diff --git a/src/utils/imageUtils/getImageSizeWithUnit.ts b/src/utils/imageUtils/getImageSizeWithUnit.ts new file mode 100644 index 0000000..81e8f33 --- /dev/null +++ b/src/utils/imageUtils/getImageSizeWithUnit.ts @@ -0,0 +1,29 @@ +async function getImageSizeWithUnit(url: string): Promise { + let sizeInBytes: number; + + // 处理 base64 格式的图片 URL + if (url.startsWith('data:')) { + sizeInBytes = atob(url.split(',')[1]).length * 0.75; + } + // 处理 blob 格式的图片 URL + else if (url.startsWith('blob:')) { + const response = await fetch(url); + const blob = await response.blob(); + sizeInBytes = blob.size; + } else { + throw new Error('Unsupported URL format'); + } + + let unit = 'Bytes'; + if (sizeInBytes >= 1024 * 1024) { + sizeInBytes /= (1024 * 1024); + unit = 'MB'; + } else if (sizeInBytes >= 1024) { + sizeInBytes /= 1024; + unit = 'KB'; + } + + return `${parseFloat(sizeInBytes.toFixed(2))} ${unit}`; +} + +export default getImageSizeWithUnit; diff --git a/src/utils/websocket/websocket.ts b/src/utils/websocket/websocket.ts index 9fa6dfb..61685f1 100644 --- a/src/utils/websocket/websocket.ts +++ b/src/utils/websocket/websocket.ts @@ -53,7 +53,7 @@ export class WebSocketService { }; private handleMessage = (event: MessageEvent): void => { - const data = JSON.parse(event.data); + const {data} = event; if (this.callbacks.message) { this.callbacks.message.forEach((cb) => (cb as MessageCallback)(data)); } @@ -71,9 +71,6 @@ export class WebSocketService { console.log('WebSocket连接已关闭'); if (this.callbacks.close) { this.callbacks.close.forEach((cb) => (cb as EventCallback)()); - if (!this.options.reconnectTimeout) { - this.reconnect(); - } } }; @@ -84,8 +81,4 @@ export class WebSocketService { console.warn('尝试发送消息时WebSocket未连接'); } } - - public getReadyState(): number { - return this.ws ? this.ws.readyState : WebSocket.CLOSED; - } } diff --git a/src/views/QRLogin/QRLogin.vue b/src/views/QRLogin/QRLogin.vue index 7111053..4bb0d07 100644 --- a/src/views/QRLogin/QRLogin.vue +++ b/src/views/QRLogin/QRLogin.vue @@ -47,7 +47,6 @@ import BoxDog from "@/components/BoxDog/BoxDog.vue"; import QRLoginFooter from "@/views/QRLogin/QRLoginFooter.vue"; import {useRouter} from 'vue-router'; import {generateQrCode} from "@/api/oauth/wechat.ts"; -import {onBeforeUnmount, onMounted, ref} from "vue"; import logo from "@/assets/svgs/logo-album.svg"; import useStore from "@/store"; @@ -71,7 +70,6 @@ const userStore = useStore().user; async function getQrCode() { const res: any = await generateQrCode(userStore.clientId); if (res && res.code === 200) { - status.value = 'active'; qrcode.value = res.data; await handleListenMessage(); } else { @@ -82,6 +80,7 @@ async function getQrCode() { const wsOptions = { url: import.meta.env.VITE_QR_SOCKET_URL + "?client_id=" + userStore.clientId, + reconnectTimeout: 10000, }; @@ -93,14 +92,15 @@ async function handleListenMessage() { // 注册消息接收处理函数 websocket.on('message', async (res: any) => { if (res && res.code === 200) { - userStore.user.uid = res.data.uid; - userStore.user.access_token = res.data.access_token; - userStore.user.username = res.data.username; - userStore.user.avatar = res.data.avatar; - userStore.user.nickname = res.data.nickname; - userStore.user.status = res.data.status; status.value = 'scanned'; - await getUserDevice(); + const {data} = res; + userStore.user.uid = data.uid; + userStore.user.access_token = data.access_token; + userStore.user.username = data.username; + userStore.user.avatar = data.avatar; + userStore.user.nickname = data.nickname; + userStore.user.status = data.status; + await getUserDevice(data.access_token); message.success(t('login.loginSuccess')); setTimeout(() => { router.push('/main/photo/all'); @@ -117,6 +117,17 @@ onMounted(async () => { onBeforeUnmount(() => { websocket.close(false); }); + +watch( + () => websocket.readyState, + (newStatus) => { + if (newStatus === WebSocket.OPEN) { + status.value = 'active'; + } else { + status.value = 'expired'; + } + } +); diff --git a/src/views/Upscale/ParameterSetting.vue b/src/views/Upscale/ParameterSetting.vue index 580b684..cbbff92 100644 --- a/src/views/Upscale/ParameterSetting.vue +++ b/src/views/Upscale/ParameterSetting.vue @@ -4,15 +4,15 @@
类型: + v-model:value="upscale.model_type" + :options="upscale.TypeData.map(item => ({label: item, value: item}))">
模型: + v-model:value="upscale.model" + :options="upscale.modes.map((item: any) => ({label: item, value: item}))">
@@ -20,16 +20,16 @@
比列: + v-model:value="upscale.factor" + :options="upscale.scales.map((item: any) => ({label: item, value: item}))">
分块大小: + v-model:value="upscale.tile_size" + :options="upscale.tileSize.map((item: any) => ({label: item, value: item}))">
@@ -38,15 +38,15 @@
重复: + v-model:value="upscale.min_lap" + :options="upscale.overlapList.map((item: any) => ({label: item, value: item}))">
运行环境: + v-model:value="upscale.backend" + :options="upscale.backendList.map((item: any) => ({label: item, value: item}))">
@@ -69,70 +69,6 @@ import useStore from "@/store"; import run from '@/assets/svgs/run.svg'; const upscale = useStore().upscale; -// ***************参数设置*************** -const TypeData = ['realesrgan', 'realcugan']; - -const model_type = ref(TypeData[0]); - -const ModelConfig = reactive({ - realesrgan: { - model: ["anime_fast", "anime_plus", "general_fast", "general_plus"], - factor: [4], - tile_size: [32, 48, 64, 96, 128, 192, 256], - }, - realcugan: { - factor: [2, 4], - denoise: { - 2: [ - "conservative", - "no-denoise", - "denoise1x", - "denoise2x", - "denoise3x", - ], - 3: ["conservative", "denoise3x"], - 4: ["conservative", "no-denoise", "denoise3x"], - }, - tile_size: [32, 48, 64, 96, 128, 192, 256, 384, 512], - } -}); -const factor = ref(4); -const model = ref(ModelConfig[model_type.value].model[0]); -const modes = computed(() => { - if (model_type.value === "realesrgan") { - return ModelConfig[model_type.value].model; - } else { - return ModelConfig[model_type.value].denoise[factor.value]; - } -}); - -watch(model_type, val => { - if (model_type.value === "realesrgan") { - model.value = ModelConfig[val].model[0]; - } else { - model.value = ModelConfig[val].denoise[factor.value][0]; - } -}); - - -// Scale -const scales = computed(() => { - return ModelConfig[model_type.value].factor; -}); - -//tile size -const tile_size = ref(128); -const tileSize = computed(() => { - return ModelConfig[model_type.value].tile_size; -}); - -// overlap -const overlapList = [0, 4, 8, 12, 16, 20]; -const min_lap = ref(overlapList[3]); - -// run on -const backendList = ['webgl', 'webgpu']; -const backend = ref(backendList[0]); // ********************处理图片******************* const outputData = ref(); @@ -166,8 +102,8 @@ async function startTask() { if (!upscale.hasAlpha || (upscale.hasAlpha && upscale.inputAlpha)) { if (upscale.input) { outputData.value = new Img( - factor.value * upscale.input.width, - factor.value * upscale.input.height, + upscale.factor * upscale.input.width, + upscale.factor * upscale.input.height, new Uint8Array(output) ); } @@ -177,14 +113,14 @@ async function startTask() { worker.postMessage( { input: upscale.inputAlpha.data.buffer, - factor: factor.value, - tile_size: tile_size.value, - min_lap: min_lap.value, - model_type: model_type.value, + factor: upscale.factor, + tile_size: upscale.tile_size, + min_lap: upscale.min_lap, + model_type: upscale.model_type, width: upscale.inputAlpha.width, height: upscale.inputAlpha.height, - model: model.value, - backend: backend.value, + model: upscale.model, + backend: upscale.backend, hasAlpha: true, }, [upscale.inputAlpha.data.buffer] @@ -247,14 +183,14 @@ async function startTask() { worker.postMessage( { input: upscale.input.data.buffer, - factor: factor.value, - tile_size: tile_size.value, - min_lap: min_lap.value, - model_type: model_type.value, + factor: upscale.factor, + tile_size: upscale.tile_size, + min_lap: upscale.min_lap, + model_type: upscale.model_type, width: upscale.input.width, height: upscale.input.height, - model: model.value, - backend: backend.value, + model: upscale.model, + backend: upscale.backend, hasAlpha: false, }, [upscale.input.data.buffer] diff --git a/src/views/Upscale/index.vue b/src/views/Upscale/index.vue index b5bb369..9092d06 100644 --- a/src/views/Upscale/index.vue +++ b/src/views/Upscale/index.vue @@ -13,7 +13,7 @@
- +
@@ -35,7 +35,7 @@ const wsOptions = { onMounted(() => { websocket.initialize(wsOptions); websocket.on("message", async (res: any) => { - if (res && res && res.code === 200) { + if (res && res.code === 200) { const {data} = res; img.src = data; await upscale.loadImg(img); @@ -43,7 +43,16 @@ onMounted(() => { } }); }); - +watch( + () => websocket.readyState, + (newStatus) => { + if (newStatus === WebSocket.OPEN) { + upscale.status = 'active'; + } else { + upscale.status = 'loading'; + } + } +); onUnmounted(() => { websocket.close(false); }); @@ -87,7 +96,7 @@ onUnmounted(() => { .upscale-content-right { width: 70%; height: 100%; - + border-radius: 10px; } } } diff --git a/src/workers/upscale.worker.ts b/src/workers/upscale.worker.ts index 0ec63d2..f462b2d 100644 --- a/src/workers/upscale.worker.ts +++ b/src/workers/upscale.worker.ts @@ -236,10 +236,6 @@ self.onmessage = async function (e: MessageEvent): Promise { output.cropToOriginalSize(width_ori * factor, height_ori * factor); } await new Promise((resolve) => setTimeout(resolve, 10)); - self.postMessage({ - progress: 100, - info: `Processing image...`, - }); self.postMessage( { progress: 100,