Compare commits

..

5 commits

Author SHA1 Message Date
nquidox
0c576c0787 update
Some checks failed
/ Make image (push) Failing after 27s
2025-10-26 21:33:13 +03:00
nquidox
339abe4c84 get image update 2025-10-26 21:33:06 +03:00
nquidox
51436141a4 jwt parse for user uuid 2025-10-26 21:32:51 +03:00
nquidox
a1ed5429a4 upload response + get url refactor 2025-10-26 21:32:35 +03:00
nquidox
9ba00dc29c image storage url added 2025-10-26 21:32:05 +03:00
6 changed files with 632 additions and 656 deletions

1176
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,10 @@
import { apiClient } from '@/services/apiClient.js' import { apiClient } from '@/services/apiClient.js'
import { useAuthStore } from '@/stores/authStore.js'
import { IMAGE_STORAGE_URL } from '@/main.js'
export const useMerchImagesApi = () => { export const useMerchImagesApi = () => {
const authStore = useAuthStore()
const uploadImage = async (uuid, file) => { const uploadImage = async (uuid, file) => {
const formData = new FormData() const formData = new FormData()
formData.append('file', file) formData.append('file', file)
@ -13,28 +17,30 @@ export const useMerchImagesApi = () => {
throw new Error(`Upload failed: ${response.status}`) throw new Error(`Upload failed: ${response.status}`)
} }
return response.data const { fullImage, thumbnail } = response.data
return {
fullImage,
thumbnail,
}
} catch (error) { } catch (error) {
console.error('Upload failed:', error) console.error('Upload failed:', error)
throw error throw error
} }
} }
const getImageUrl = async (uuid, type) => { const getImageUrl = (merchUuid, type = 'full') => {
try { const userUuid = authStore.userUuid;
const response = await apiClient.get(`/merch/images/${uuid}`, { type }) if (!userUuid) throw new Error('userUuid not found in store');
console.log(response.data.link)
if (response.status !== 200) { const allowedTypes = ['full', 'thumbnail'];
throw new Error(`Get image failed: ${response.status}`) if (!allowedTypes.includes(type)) {
throw new Error(`Invalid type: ${type}. Allowed values: ${allowedTypes.join(', ')}`);
} }
return response.data.link return `${IMAGE_STORAGE_URL}/merchImages/${userUuid}/${merchUuid}?type=${type}`;
} catch (error) { };
console.error('Get image failed:', error)
throw error
}
}
const deleteImage = async (uuid) => { const deleteImage = async (uuid) => {
try { try {

View file

@ -11,6 +11,8 @@ export const BASE_URL = 'https://api.nqws.ru/api/v2'
// export const BASE_URL = 'http://localhost:9090/api/v2' // export const BASE_URL = 'http://localhost:9090/api/v2'
export const BASE_MANDARAKE_LINK = 'https://order.mandarake.co.jp/order/listPage/list?soldOut=1&keyword=' export const BASE_MANDARAKE_LINK = 'https://order.mandarake.co.jp/order/listPage/list?soldOut=1&keyword='
// export const IMAGE_STORAGE_URL = 'http://localhost:9280'
export const IMAGE_STORAGE_URL = 'https://images.nqws.ru'
app.use(createPinia()) app.use(createPinia())
app.use(router) app.use(router)

View file

@ -3,11 +3,28 @@ import { computed, ref } from 'vue'
import { apiClient } from '@/services/apiClient' import { apiClient } from '@/services/apiClient'
import router from '@/router/index.js' import router from '@/router/index.js'
function parseJwt(token) {
try {
const base64Url = token.split('.')[1]
const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/')
const jsonPayload = decodeURIComponent(
atob(base64)
.split('')
.map(c => '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2))
.join('')
)
return JSON.parse(jsonPayload)
} catch (e) {
console.error('Invalid JWT:', e)
return null
}
}
export const useAuthStore = defineStore('auth', () => { export const useAuthStore = defineStore('auth', () => {
// state // state
const accessToken = ref(localStorage.getItem('accessToken')) const accessToken = ref(localStorage.getItem('accessToken'))
const userUuid = ref(localStorage.getItem('userUuid') || null)
const user = ref(null) const user = ref(null)
const activeTab = ref('signin') const activeTab = ref('signin')
// getters // getters
@ -16,10 +33,20 @@ export const useAuthStore = defineStore('auth', () => {
// actions // actions
const setToken = (token) => { const setToken = (token) => {
accessToken.value = token accessToken.value = token
if (token) { if (token) {
localStorage.setItem('accessToken', token) localStorage.setItem('accessToken', token)
const decoded = parseJwt(token)
const uuid = decoded?.sub
if (uuid) {
userUuid.value = uuid
localStorage.setItem('userUuid', uuid)
}
} else { } else {
localStorage.removeItem('accessToken') localStorage.removeItem('accessToken')
localStorage.removeItem('userUuid')
userUuid.value = null
} }
} }
@ -68,7 +95,7 @@ export const useAuthStore = defineStore('auth', () => {
const response = await apiClient.get('/user/') const response = await apiClient.get('/user/')
return response.data return response.data
} catch (error) { } catch (error) {
console.error('Register error:', error) console.error('User info error:', error)
} }
} }
@ -77,12 +104,13 @@ export const useAuthStore = defineStore('auth', () => {
const response = await apiClient.get('/user/auth/current-session') const response = await apiClient.get('/user/auth/current-session')
return response.data return response.data
} catch (error) { } catch (error) {
console.error('Register error:', error) console.error('Current session error:', error)
} }
} }
return { return {
accessToken, accessToken,
userUuid,
user, user,
isAuthenticated, isAuthenticated,
activeTab, activeTab,

View file

@ -15,22 +15,29 @@ const fileList = ref([])
onMounted(async () => { onMounted(async () => {
try { try {
const imgUrl = await getImageUrl(props.merch.merch_uuid, 'thumbnail') const imgUrl = getImageUrl(props.merch.merch_uuid, 'thumbnail')
await new Promise((resolve, reject) => {
const img = new Image()
img.src = imgUrl
img.onload = () => resolve(imgUrl)
img.onerror = () => reject(new Error('Image not found'))
})
fileList.value = [ fileList.value = [
{ {
name: 'full.jpg', name: 'thumbnail.jpg',
url: imgUrl, url: imgUrl,
status: 'finished', status: 'finished',
}, },
] ]
} catch (error) { } catch (error) {
fileList.value = [] fileList.value = []
if (!error.message?.includes('404')) { if (!error.message.includes('404')) {
console.error('Error getting image: ', error) console.error('Error getting thumbnail: ', error)
} }
} }
}) })
</script> </script>
<template> <template>

View file

@ -77,21 +77,29 @@ async function handleUpload({ fileList: newFileList }) {
onMounted(async () => { onMounted(async () => {
try { try {
const imgUrl = await getImageUrl(props.merchUuid, 'full') const imgUrl = getImageUrl(props.merchUuid, 'full');
await new Promise((resolve, reject) => {
const img = new Image();
img.src = imgUrl;
img.onload = () => resolve(imgUrl);
img.onerror = () => reject(new Error('Image not found'));
});
fileList.value = [ fileList.value = [
{ {
name: 'full.jpg', name: 'full.jpg',
url: imgUrl, url: imgUrl,
status: 'finished', status: 'finished',
}, },
] ];
} catch (error) { } catch (error) {
fileList.value = [] fileList.value = [];
if (!error.message?.includes('404')) { if (!error.message.includes('404')) {
console.error('Error getting image: ', error) console.error('Error getting image: ', error);
} }
} }
}) });
const showConfirmDelete = ref(false) const showConfirmDelete = ref(false)
@ -207,7 +215,8 @@ const cancelDelete = () => {
.preview-container { .preview-container {
display: block; display: block;
width: 100%; width: 50%;
min-width: 250px;
max-width: 400px; max-width: 400px;
margin: 0 auto; margin: 0 auto;
} }