Compare commits
9 Commits
46d0cac892
...
a10f6997eb
| Author | SHA1 | Date | |
|---|---|---|---|
| a10f6997eb | |||
| 2bbb30525e | |||
| 2ecda61ad4 | |||
| 3c4db6d312 | |||
| e9e83827dc | |||
| 1b8c10a8a0 | |||
| 83acb64944 | |||
| cbbd5b2abe | |||
| a75158379d |
128
package-lock.json
generated
128
package-lock.json
generated
@ -15,8 +15,6 @@
|
|||||||
"jquery": "^3.7.1",
|
"jquery": "^3.7.1",
|
||||||
"parchment": "^3.0.0",
|
"parchment": "^3.0.0",
|
||||||
"pinia": "^2.1.7",
|
"pinia": "^2.1.7",
|
||||||
"quill": "^2.0.3",
|
|
||||||
"quill-image-resize-module": "^3.0.0",
|
|
||||||
"summernote": "^0.9.1",
|
"summernote": "^0.9.1",
|
||||||
"uuid": "^11.1.0",
|
"uuid": "^11.1.0",
|
||||||
"vue": "^3.4.29",
|
"vue": "^3.4.29",
|
||||||
@ -1718,14 +1716,6 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/clone": {
|
|
||||||
"version": "2.1.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
|
|
||||||
"integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/combined-stream": {
|
"node_modules/combined-stream": {
|
||||||
"version": "1.0.8",
|
"version": "1.0.8",
|
||||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||||
@ -2006,11 +1996,6 @@
|
|||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/eventemitter3": {
|
|
||||||
"version": "5.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz",
|
|
||||||
"integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA=="
|
|
||||||
},
|
|
||||||
"node_modules/eventsource": {
|
"node_modules/eventsource": {
|
||||||
"version": "2.0.2",
|
"version": "2.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/eventsource/-/eventsource-2.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/eventsource/-/eventsource-2.0.2.tgz",
|
||||||
@ -2019,11 +2004,6 @@
|
|||||||
"node": ">=12.0.0"
|
"node": ">=12.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/extend": {
|
|
||||||
"version": "3.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
|
|
||||||
"integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
|
|
||||||
},
|
|
||||||
"node_modules/fetch-cookie": {
|
"node_modules/fetch-cookie": {
|
||||||
"version": "2.2.0",
|
"version": "2.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/fetch-cookie/-/fetch-cookie-2.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/fetch-cookie/-/fetch-cookie-2.2.0.tgz",
|
||||||
@ -2359,26 +2339,6 @@
|
|||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/lodash": {
|
|
||||||
"version": "4.17.21",
|
|
||||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
|
||||||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
|
|
||||||
},
|
|
||||||
"node_modules/lodash-es": {
|
|
||||||
"version": "4.17.21",
|
|
||||||
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz",
|
|
||||||
"integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw=="
|
|
||||||
},
|
|
||||||
"node_modules/lodash.clonedeep": {
|
|
||||||
"version": "4.5.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
|
|
||||||
"integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ=="
|
|
||||||
},
|
|
||||||
"node_modules/lodash.isequal": {
|
|
||||||
"version": "4.5.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
|
|
||||||
"integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ=="
|
|
||||||
},
|
|
||||||
"node_modules/lru-cache": {
|
"node_modules/lru-cache": {
|
||||||
"version": "5.1.1",
|
"version": "5.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
|
||||||
@ -2752,94 +2712,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
|
||||||
"integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ=="
|
"integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ=="
|
||||||
},
|
},
|
||||||
"node_modules/quill": {
|
|
||||||
"version": "2.0.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/quill/-/quill-2.0.3.tgz",
|
|
||||||
"integrity": "sha512-xEYQBqfYx/sfb33VJiKnSJp8ehloavImQ2A6564GAbqG55PGw1dAWUn1MUbQB62t0azawUS2CZZhWCjO8gRvTw==",
|
|
||||||
"dependencies": {
|
|
||||||
"eventemitter3": "^5.0.1",
|
|
||||||
"lodash-es": "^4.17.21",
|
|
||||||
"parchment": "^3.0.0",
|
|
||||||
"quill-delta": "^5.1.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"npm": ">=8.2.3"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/quill-image-resize-module": {
|
|
||||||
"version": "3.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/quill-image-resize-module/-/quill-image-resize-module-3.0.0.tgz",
|
|
||||||
"integrity": "sha512-1TZBnUxU/WIx5dPyVjQ9yN7C6mLZSp04HyWBEMqT320DIq4MW4JgzlOPDZX5ZpBM3bU6sacU4kTLUc8VgYQZYw==",
|
|
||||||
"dependencies": {
|
|
||||||
"lodash": "^4.17.4",
|
|
||||||
"quill": "^1.2.2",
|
|
||||||
"raw-loader": "^0.5.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/quill-image-resize-module/node_modules/eventemitter3": {
|
|
||||||
"version": "2.0.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-2.0.3.tgz",
|
|
||||||
"integrity": "sha512-jLN68Dx5kyFHaePoXWPsCGW5qdyZQtLYHkxkg02/Mz6g0kYpDx4FyP6XfArhQdlOC4b8Mv+EMxPo/8La7Tzghg=="
|
|
||||||
},
|
|
||||||
"node_modules/quill-image-resize-module/node_modules/fast-diff": {
|
|
||||||
"version": "1.1.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.1.2.tgz",
|
|
||||||
"integrity": "sha512-KaJUt+M9t1qaIteSvjc6P3RbMdXsNhK61GRftR6SNxqmhthcd9MGIi4T+o0jD8LUSpSnSKXE20nLtJ3fOHxQig=="
|
|
||||||
},
|
|
||||||
"node_modules/quill-image-resize-module/node_modules/parchment": {
|
|
||||||
"version": "1.1.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/parchment/-/parchment-1.1.4.tgz",
|
|
||||||
"integrity": "sha512-J5FBQt/pM2inLzg4hEWmzQx/8h8D0CiDxaG3vyp9rKrQRSDgBlhjdP5jQGgosEajXPSQouXGHOmVdgo7QmJuOg=="
|
|
||||||
},
|
|
||||||
"node_modules/quill-image-resize-module/node_modules/quill": {
|
|
||||||
"version": "1.3.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/quill/-/quill-1.3.7.tgz",
|
|
||||||
"integrity": "sha512-hG/DVzh/TiknWtE6QmWAF/pxoZKYxfe3J/d/+ShUWkDvvkZQVTPeVmUJVu1uE6DDooC4fWTiCLh84ul89oNz5g==",
|
|
||||||
"dependencies": {
|
|
||||||
"clone": "^2.1.1",
|
|
||||||
"deep-equal": "^1.0.1",
|
|
||||||
"eventemitter3": "^2.0.3",
|
|
||||||
"extend": "^3.0.2",
|
|
||||||
"parchment": "^1.1.4",
|
|
||||||
"quill-delta": "^3.6.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/quill-image-resize-module/node_modules/quill-delta": {
|
|
||||||
"version": "3.6.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/quill-delta/-/quill-delta-3.6.3.tgz",
|
|
||||||
"integrity": "sha512-wdIGBlcX13tCHOXGMVnnTVFtGRLoP0imqxM696fIPwIf5ODIYUHIvHbZcyvGlZFiFhK5XzDC2lpjbxRhnM05Tg==",
|
|
||||||
"dependencies": {
|
|
||||||
"deep-equal": "^1.0.1",
|
|
||||||
"extend": "^3.0.2",
|
|
||||||
"fast-diff": "1.1.2"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.10"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/quill/node_modules/fast-diff": {
|
|
||||||
"version": "1.3.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz",
|
|
||||||
"integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw=="
|
|
||||||
},
|
|
||||||
"node_modules/quill/node_modules/quill-delta": {
|
|
||||||
"version": "5.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/quill-delta/-/quill-delta-5.1.0.tgz",
|
|
||||||
"integrity": "sha512-X74oCeRI4/p0ucjb5Ma8adTXd9Scumz367kkMK5V/IatcX6A0vlgLgKbzXWy5nZmCGeNJm2oQX0d2Eqj+ZIlCA==",
|
|
||||||
"dependencies": {
|
|
||||||
"fast-diff": "^1.3.0",
|
|
||||||
"lodash.clonedeep": "^4.5.0",
|
|
||||||
"lodash.isequal": "^4.5.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 12.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/raw-loader": {
|
|
||||||
"version": "0.5.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/raw-loader/-/raw-loader-0.5.1.tgz",
|
|
||||||
"integrity": "sha512-sf7oGoLuaYAScB4VGr0tzetsYlS8EJH6qnTCfQ/WVEa89hALQ4RQfCKt5xCyPQKPDUbVUAIP1QsxAwfAjlDp7Q=="
|
|
||||||
},
|
|
||||||
"node_modules/read-package-json-fast": {
|
"node_modules/read-package-json-fast": {
|
||||||
"version": "3.0.2",
|
"version": "3.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/read-package-json-fast/-/read-package-json-fast-3.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/read-package-json-fast/-/read-package-json-fast-3.0.2.tgz",
|
||||||
|
|||||||
@ -392,9 +392,22 @@
|
|||||||
const searchChanging = ref<boolean>(false)
|
const searchChanging = ref<boolean>(false)
|
||||||
const filterChanging = ref<boolean>(false)
|
const filterChanging = ref<boolean>(false)
|
||||||
|
|
||||||
|
const isQueryEqual = (a: Record<string, any>, b: Record<string, any>) => {
|
||||||
|
const keys = new Set([...Object.keys(a || {}), ...Object.keys(b || {})])
|
||||||
|
for (const k of keys) {
|
||||||
|
const va = a?.[k]
|
||||||
|
const vb = b?.[k]
|
||||||
|
if (Array.isArray(va) && Array.isArray(vb)) {
|
||||||
|
if (va.length !== vb.length || va.some((v: any, i: number) => v !== vb[i]))
|
||||||
|
return false
|
||||||
|
} else if (String(va ?? '') !== String(vb ?? '')) return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
const RoutePageControl = () => {
|
const RoutePageControl = () => {
|
||||||
if (props.isUseRoute) {
|
if (props.isUseRoute) {
|
||||||
const q = { ...route.query }
|
const q = { ...route.query } as Record<string, any>
|
||||||
pageNumberChanging.value = true
|
pageNumberChanging.value = true
|
||||||
|
|
||||||
if (q.pageNumber !== undefined && q.pageNumber !== '') {
|
if (q.pageNumber !== undefined && q.pageNumber !== '') {
|
||||||
@ -404,7 +417,9 @@
|
|||||||
localPagination.value.pageNumber = localPagination.value.pageNumber || 1
|
localPagination.value.pageNumber = localPagination.value.pageNumber || 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!isQueryEqual(q, route.query as Record<string, any>)) {
|
||||||
router.push({ query: q })
|
router.push({ query: q })
|
||||||
|
}
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
pageNumberChanging.value = false
|
pageNumberChanging.value = false
|
||||||
})
|
})
|
||||||
@ -413,7 +428,7 @@
|
|||||||
|
|
||||||
const RouteSortControl = () => {
|
const RouteSortControl = () => {
|
||||||
if (props.isUseRoute) {
|
if (props.isUseRoute) {
|
||||||
const q = { ...route.query }
|
const q = { ...route.query } as Record<string, any>
|
||||||
sortChanging.value = true
|
sortChanging.value = true
|
||||||
if (q.sortOrder !== undefined && q.sortOrder !== null && q.sortOrder !== '') {
|
if (q.sortOrder !== undefined && q.sortOrder !== null && q.sortOrder !== '') {
|
||||||
localSort.value.sortColumn = q.sortColumn as string
|
localSort.value.sortColumn = q.sortColumn as string
|
||||||
@ -424,7 +439,9 @@
|
|||||||
delete localSort.value.sortColumn
|
delete localSort.value.sortColumn
|
||||||
delete localSort.value.sortOrder
|
delete localSort.value.sortOrder
|
||||||
}
|
}
|
||||||
|
if (!isQueryEqual(q, route.query as Record<string, any>)) {
|
||||||
router.push({ query: q })
|
router.push({ query: q })
|
||||||
|
}
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
sortChanging.value = false
|
sortChanging.value = false
|
||||||
})
|
})
|
||||||
@ -433,7 +450,7 @@
|
|||||||
|
|
||||||
const RouteSearchControl = () => {
|
const RouteSearchControl = () => {
|
||||||
if (props.isUseRoute) {
|
if (props.isUseRoute) {
|
||||||
const q = { ...route.query }
|
const q = { ...route.query } as Record<string, any>
|
||||||
searchChanging.value = true
|
searchChanging.value = true
|
||||||
if (
|
if (
|
||||||
q.searchString !== undefined &&
|
q.searchString !== undefined &&
|
||||||
@ -445,7 +462,9 @@
|
|||||||
localQuery.value = ''
|
localQuery.value = ''
|
||||||
delete q.searchString
|
delete q.searchString
|
||||||
}
|
}
|
||||||
|
if (!isQueryEqual(q, route.query as Record<string, any>)) {
|
||||||
router.push({ query: q })
|
router.push({ query: q })
|
||||||
|
}
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
searchChanging.value = false
|
searchChanging.value = false
|
||||||
})
|
})
|
||||||
|
|||||||
@ -59,9 +59,8 @@ axios.interceptors.response.use(
|
|||||||
const usersStore = useUsersStore()
|
const usersStore = useUsersStore()
|
||||||
const dataStore = useDataStore()
|
const dataStore = useDataStore()
|
||||||
dataStore.isLoading = false
|
dataStore.isLoading = false
|
||||||
// Yanıtta hata oluşursa burada yakalanır
|
// Yanıtta hata oluşursa burada yakalanır (401 login'e yönlendir, diğerleri dataStore catch'te toast gösterir)
|
||||||
// error.status kodu undefined geliyor
|
if (error.response?.status === 401) {
|
||||||
if (error.response.status === 401) {
|
|
||||||
const token = sessionStorage.getItem(usersStore.userStorageKeys.TOKEN)
|
const token = sessionStorage.getItem(usersStore.userStorageKeys.TOKEN)
|
||||||
if (token !== undefined) {
|
if (token !== undefined) {
|
||||||
usersStore.ResetUserData()
|
usersStore.ResetUserData()
|
||||||
|
|||||||
@ -51,11 +51,54 @@
|
|||||||
</template>
|
</template>
|
||||||
</list-table-content>
|
</list-table-content>
|
||||||
<panel-wrapper
|
<panel-wrapper
|
||||||
|
wide
|
||||||
v-if="piyangoKatilimciStore.katilimciFilePanel"
|
v-if="piyangoKatilimciStore.katilimciFilePanel"
|
||||||
v-model="piyangoKatilimciStore.katilimciFilePanel"
|
v-model="piyangoKatilimciStore.katilimciFilePanel"
|
||||||
panel-title="Katılımcı Dosyası Yükle">
|
panel-title="Katılımcı Dosyası Yükle">
|
||||||
<template #panelContent>
|
<template #panelContent>
|
||||||
|
<div class="upload-panel-content">
|
||||||
|
<div v-if="uploadProgressPanel" class="upload-progress-section">
|
||||||
|
<h4 class="upload-progress-title">Aktif Yükleme</h4>
|
||||||
|
<div class="upload-warning">
|
||||||
|
İşlem sırasında tarayıcıyı veya bu sekmeyi kapatmayınız. Sayfa yenilerseniz bu paneli tekrar açarak takip edebilirsiniz.
|
||||||
|
</div>
|
||||||
|
<div class="progress-bar">
|
||||||
|
<div
|
||||||
|
class="progress-fill"
|
||||||
|
:style="{ width: uploadProgressValue + '%' }"></div>
|
||||||
|
</div>
|
||||||
|
<div class="progress-text">
|
||||||
|
<template v-if="uploadProgressValue === 0">
|
||||||
|
Dosya içeriği okunuyor, yükleme başlatılıyor...
|
||||||
|
</template>
|
||||||
|
<template v-else>{{ uploadProgressValue }}%</template>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-if="uploadJobsLoading || uploadJobs.length > 0" class="upload-history-section">
|
||||||
|
<h4 class="upload-history-title">Yükleme Geçmişi</h4>
|
||||||
|
<div v-if="uploadJobsLoading" class="history-loading">Yükleniyor...</div>
|
||||||
|
<div v-else-if="uploadJobs.length > 0" class="history-items">
|
||||||
|
<div
|
||||||
|
v-for="job in uploadJobs"
|
||||||
|
:key="job.guid"
|
||||||
|
:class="['history-item', job.status?.toLowerCase() === 'processing' ? 'processing' : '']"
|
||||||
|
@click="OpenUploadDetail(job.guid)">
|
||||||
|
<span class="history-file">{{ job.fileName }}</span>
|
||||||
|
<span :class="['history-status', 'status-' + job.status?.toLowerCase()]">{{ statusText(job.status) }}</span>
|
||||||
|
<span class="history-progress">{{ job.progress }}%</span>
|
||||||
|
<span v-if="job.status?.toLowerCase() === 'completed'" class="history-stats">
|
||||||
|
+{{ job.insertedCount ?? 0 }}
|
||||||
|
<template v-if="(job.duplicateCount ?? 0) > 0"> / {{ job.duplicateCount }} dpl</template>
|
||||||
|
</span>
|
||||||
|
<span class="history-date">{{ formatDate(job.createdAt) }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="upload-form-section">
|
||||||
|
<h4 class="upload-form-title">Yeni Dosya Yükle</h4>
|
||||||
<panel-katilimci-document />
|
<panel-katilimci-document />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #footerButton>
|
<template #footerButton>
|
||||||
<button
|
<button
|
||||||
@ -88,26 +131,12 @@
|
|||||||
</template>
|
</template>
|
||||||
</panel-wrapper>
|
</panel-wrapper>
|
||||||
<panel-wrapper
|
<panel-wrapper
|
||||||
v-if="uploadProgressPanel"
|
wide
|
||||||
v-model="uploadProgressPanel"
|
v-if="uploadDetailPanel"
|
||||||
panel-title="Yükleme Durumu">
|
v-model="uploadDetailPanel"
|
||||||
|
panel-title="Yükleme Detayı">
|
||||||
<template #panelContent>
|
<template #panelContent>
|
||||||
<div class="progress-container">
|
<panel-excel-upload-detail :jobGuid="selectedJobGuid" />
|
||||||
<div class="upload-warning">
|
|
||||||
📌 İşlem sırasında tarayıcıyı veya bu sekmeyi kapatmayınız.
|
|
||||||
</div>
|
|
||||||
<div class="progress-bar">
|
|
||||||
<div
|
|
||||||
class="progress-fill"
|
|
||||||
:style="{ width: uploadProgressValue + '%' }"></div>
|
|
||||||
</div>
|
|
||||||
<div class="progress-text">
|
|
||||||
<template v-if="uploadProgressValue === 0">
|
|
||||||
Dosya içeriği okunuyor, yükleme başlatılıyor...
|
|
||||||
</template>
|
|
||||||
<template v-else>{{ uploadProgressValue }}%</template>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
</panel-wrapper>
|
</panel-wrapper>
|
||||||
</section>
|
</section>
|
||||||
@ -117,6 +146,8 @@
|
|||||||
import PanelWrapper from '@/components/PanelWrapper.vue'
|
import PanelWrapper from '@/components/PanelWrapper.vue'
|
||||||
import PanelKatilimciDocument from '@/module/cekilisler/components/panel/PanelKatilimciDocument.vue'
|
import PanelKatilimciDocument from '@/module/cekilisler/components/panel/PanelKatilimciDocument.vue'
|
||||||
import PanelPiyangoKatilimci from '@/module/cekilisler/components/panel/PanelPiyangoKatilimci.vue'
|
import PanelPiyangoKatilimci from '@/module/cekilisler/components/panel/PanelPiyangoKatilimci.vue'
|
||||||
|
import PanelExcelUploadDetail from '@/module/cekilisler/components/panel/PanelExcelUploadDetail.vue'
|
||||||
|
import { useDateStore } from '@/stores/dateStore'
|
||||||
|
|
||||||
import { useUsersStore } from '@/stores/usersStore'
|
import { useUsersStore } from '@/stores/usersStore'
|
||||||
const usersStore = useUsersStore()
|
const usersStore = useUsersStore()
|
||||||
@ -137,18 +168,26 @@
|
|||||||
import { useDialogStore } from '@/components/global/dialogStore'
|
import { useDialogStore } from '@/components/global/dialogStore'
|
||||||
|
|
||||||
const dialogStore = useDialogStore()
|
const dialogStore = useDialogStore()
|
||||||
|
const toastStore = useToastStore()
|
||||||
|
|
||||||
import { usePiyangoOnayStore } from '../stores/piyangoOnayStore'
|
import { usePiyangoOnayStore } from '../stores/piyangoOnayStore'
|
||||||
const piyangoOnayStore = usePiyangoOnayStore()
|
const piyangoOnayStore = usePiyangoOnayStore()
|
||||||
import { usePiyangoOnayService } from '../service/piyangoOnayService'
|
import { usePiyangoOnayService } from '../service/piyangoOnayService'
|
||||||
const piyangoOnayService = usePiyangoOnayService()
|
const piyangoOnayService = usePiyangoOnayService()
|
||||||
|
|
||||||
import { connectToHub, onProgress, onCompleted } from '../service/signalrService'
|
import { onUnmounted } from 'vue'
|
||||||
|
import { connectToHub, onProgress, onInsertProgress, onCompleted, onError, removeUploadHandlers } from '../service/signalrService'
|
||||||
|
import { useToastStore } from '@/components/global/toastStore'
|
||||||
|
|
||||||
const uploadProgressValue = ref(0)
|
const uploadProgressValue = ref(0)
|
||||||
const uploadProgressPanel = ref(false)
|
const uploadProgressPanel = ref(false)
|
||||||
|
const uploadDetailPanel = ref(false)
|
||||||
|
const uploadJobs = ref<Record<string, any>[]>([])
|
||||||
|
const uploadJobsLoading = ref(false)
|
||||||
|
const selectedJobGuid = ref('')
|
||||||
const connectionId = ref('')
|
const connectionId = ref('')
|
||||||
|
const dateStore = useDateStore()
|
||||||
|
let pollInterval: ReturnType<typeof setInterval> | null = null
|
||||||
|
|
||||||
const tableHeader = ref<Record<string, any>[]>([
|
const tableHeader = ref<Record<string, any>[]>([
|
||||||
{
|
{
|
||||||
@ -255,12 +294,57 @@
|
|||||||
})
|
})
|
||||||
|
|
||||||
const AddNewDocument = async () => {
|
const AddNewDocument = async () => {
|
||||||
|
try {
|
||||||
connectionId.value = await connectToHub()
|
connectionId.value = await connectToHub()
|
||||||
dataStore.panelData = {
|
} catch {
|
||||||
title: '',
|
connectionId.value = ''
|
||||||
file: ''
|
|
||||||
}
|
}
|
||||||
|
dataStore.panelData = { title: '', file: '' }
|
||||||
piyangoKatilimciStore.katilimciFilePanel = true
|
piyangoKatilimciStore.katilimciFilePanel = true
|
||||||
|
uploadJobsLoading.value = true
|
||||||
|
const cekilisId = piyangoStore.selectedLottery
|
||||||
|
uploadJobs.value = cekilisId !== null ? await piyangoKatilimciService.GetUploadJobs(cekilisId) : []
|
||||||
|
uploadJobsLoading.value = false
|
||||||
|
|
||||||
|
removeUploadHandlers()
|
||||||
|
// İşleniyor durumundaki job varsa SignalR ile abone ol (gerçek zamanlı progress almak için)
|
||||||
|
const processingJob = uploadJobs.value.find(
|
||||||
|
(j: Record<string, any>) => j.status?.toLowerCase() === 'processing'
|
||||||
|
)
|
||||||
|
if (processingJob?.guid && connectionId.value) {
|
||||||
|
const updateProgress = (data: any) => {
|
||||||
|
const percent = data.Percent ?? 0
|
||||||
|
uploadProgressValue.value = percent
|
||||||
|
const idx = uploadJobs.value.findIndex((j: Record<string, any>) => j.guid === processingJob.guid)
|
||||||
|
if (idx >= 0) {
|
||||||
|
uploadJobs.value[idx] = {
|
||||||
|
...uploadJobs.value[idx],
|
||||||
|
progress: percent,
|
||||||
|
processedRows: data.Current ?? data.InsertedCount,
|
||||||
|
totalRows: data.Total ?? data.TotalCount
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onProgress(updateProgress)
|
||||||
|
onInsertProgress(updateProgress)
|
||||||
|
onCompleted(() => {
|
||||||
|
stopPolling()
|
||||||
|
uploadProgressPanel.value = false
|
||||||
|
piyangoKatilimciStore.refreshPiyangoKatilimciList = true
|
||||||
|
piyangoKatilimciStore.katilimciFilePanel = true
|
||||||
|
refreshUploadJobsAndPollProcessing()
|
||||||
|
})
|
||||||
|
onError(() => {
|
||||||
|
stopPolling()
|
||||||
|
uploadProgressPanel.value = false
|
||||||
|
refreshUploadJobsAndPollProcessing()
|
||||||
|
})
|
||||||
|
uploadProgressPanel.value = true
|
||||||
|
uploadProgressValue.value = processingJob.progress ?? 0
|
||||||
|
await piyangoKatilimciService.SubscribeToJob(processingJob.guid, connectionId.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
startPollingForAnyProcessingJob()
|
||||||
}
|
}
|
||||||
|
|
||||||
const AddNewKatilimci = () => {
|
const AddNewKatilimci = () => {
|
||||||
@ -280,42 +364,59 @@
|
|||||||
piyangoKatilimciStore.katilimciUserPanel = true
|
piyangoKatilimciStore.katilimciUserPanel = true
|
||||||
}
|
}
|
||||||
const FileUpload = async () => {
|
const FileUpload = async () => {
|
||||||
// Mevcut bağlantıyı kullan (AddNewDocument'te açıldı)
|
if (!piyangoKatilimciValidationStore.FileFormCheck()) {
|
||||||
|
piyangoKatilimciValidationStore.isFileFormValid = true
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// Progress modal'ı aç
|
removeUploadHandlers()
|
||||||
uploadProgressValue.value = 0
|
uploadProgressValue.value = 0
|
||||||
uploadProgressPanel.value = true
|
uploadProgressPanel.value = true
|
||||||
|
|
||||||
onProgress((data) => {
|
onProgress((data) => {
|
||||||
uploadProgressValue.value = data.Percent
|
uploadProgressValue.value = data.Percent
|
||||||
console.log('Progress:', data.Percent)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
onCompleted((data) => {
|
onCompleted(() => {
|
||||||
console.log('Tamamlandı:', data)
|
stopPolling()
|
||||||
uploadProgressPanel.value = false
|
uploadProgressPanel.value = false
|
||||||
piyangoKatilimciStore.refreshPiyangoKatilimciList = true
|
piyangoKatilimciStore.refreshPiyangoKatilimciList = true
|
||||||
piyangoKatilimciStore.katilimciFilePanel = false
|
piyangoKatilimciStore.katilimciFilePanel = true
|
||||||
|
refreshUploadJobsAndPollProcessing()
|
||||||
|
})
|
||||||
|
|
||||||
|
onError(() => {
|
||||||
|
stopPolling()
|
||||||
|
uploadProgressPanel.value = false
|
||||||
})
|
})
|
||||||
|
|
||||||
const formData = new FormData()
|
const formData = new FormData()
|
||||||
formData.append(
|
formData.append('excelFile', piyangoKatilimciStore.piyangoKatilimciFileFormData.excelFile)
|
||||||
'excelFile',
|
|
||||||
piyangoKatilimciStore.piyangoKatilimciFileFormData.excelFile
|
const connId = connectionId.value || ''
|
||||||
)
|
|
||||||
console.log(dataStore.panelData)
|
|
||||||
const response = await dataStore.dataPost(
|
const response = await dataStore.dataPost(
|
||||||
`Katilimci/ExcelleYukle/${piyangoStore.selectedLottery}?connectionId=${connectionId.value}`,
|
`Katilimci/ExcelleYukle/${piyangoStore.selectedLottery}?connectionId=${connId}`,
|
||||||
{
|
{
|
||||||
data: formData,
|
data: formData,
|
||||||
headers: { 'Content-Type': 'multipart/form-data' }
|
headers: { 'Content-Type': 'multipart/form-data' },
|
||||||
|
skipErrorForStatuses: [409]
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
console.log('excel response', response)
|
|
||||||
if (response !== 'errorfalse') {
|
if (response?._error && response.status === 409) {
|
||||||
// Başarı işlemi zaten onCompleted içinde yapıldı
|
uploadProgressPanel.value = false
|
||||||
|
const msg = response.data?.message || 'Bu çekiliş için zaten devam eden bir Excel yükleme işlemi var.'
|
||||||
|
toastStore.AddToast(msg, 'alert', 6000)
|
||||||
|
if (response.data?.existingJobId) {
|
||||||
|
refreshUploadJobsAndPollProcessing()
|
||||||
|
OpenUploadDetail(response.data.existingJobId)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response !== 'errorfalse' && response?.jobId) {
|
||||||
|
startPolling(response.jobId)
|
||||||
} else {
|
} else {
|
||||||
// Hata olursa paneli kapat
|
|
||||||
uploadProgressPanel.value = false
|
uploadProgressPanel.value = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -352,16 +453,92 @@
|
|||||||
piyangoOnayStore.piyangoOnayForm.aciklama = ''
|
piyangoOnayStore.piyangoOnayForm.aciklama = ''
|
||||||
await piyangoOnayService.SaveOnayDurum()
|
await piyangoOnayService.SaveOnayDurum()
|
||||||
}
|
}
|
||||||
</script>
|
|
||||||
<style>
|
const statusText = (status: string) => {
|
||||||
.progress-container {
|
const map: Record<string, string> = {
|
||||||
width: 100%;
|
Pending: 'Bekliyor',
|
||||||
padding: 20px 0;
|
Processing: 'İşleniyor',
|
||||||
display: flex;
|
Completed: 'Tamamlandı',
|
||||||
flex-direction: column;
|
Failed: 'Başarısız'
|
||||||
align-items: center;
|
}
|
||||||
|
return map[status] || status
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const formatDate = (val: string | Date) => {
|
||||||
|
if (!val) return '-'
|
||||||
|
return dateStore.dateFormat({ date: new Date(val), pattern: 'dd.mm.yyyy HH:MM' })
|
||||||
|
}
|
||||||
|
|
||||||
|
const OpenUploadDetail = (guid: string) => {
|
||||||
|
selectedJobGuid.value = guid
|
||||||
|
uploadDetailPanel.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
const stopPolling = () => {
|
||||||
|
if (pollInterval) {
|
||||||
|
clearInterval(pollInterval)
|
||||||
|
pollInterval = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const startPolling = (jobId: string) => {
|
||||||
|
stopPolling()
|
||||||
|
pollInterval = setInterval(async () => {
|
||||||
|
const status = await piyangoKatilimciService.GetUploadJobStatus(jobId)
|
||||||
|
if (status && (status.status === 'Completed' || status.status === 'Failed')) {
|
||||||
|
stopPolling()
|
||||||
|
uploadProgressValue.value = status.status === 'Completed' ? 100 : status.progress || 0
|
||||||
|
uploadProgressPanel.value = false
|
||||||
|
piyangoKatilimciStore.refreshPiyangoKatilimciList = true
|
||||||
|
piyangoKatilimciStore.katilimciFilePanel = true
|
||||||
|
refreshUploadJobsAndPollProcessing()
|
||||||
|
} else if (status) {
|
||||||
|
uploadProgressValue.value = status.progress || 0
|
||||||
|
}
|
||||||
|
}, 2000)
|
||||||
|
}
|
||||||
|
|
||||||
|
const startPollingForExistingJob = (jobGuid: string) => {
|
||||||
|
stopPolling()
|
||||||
|
pollInterval = setInterval(async () => {
|
||||||
|
const status = await piyangoKatilimciService.GetUploadJobStatus(jobGuid)
|
||||||
|
if (status) {
|
||||||
|
const idx = uploadJobs.value.findIndex((j: Record<string, any>) => j.guid === jobGuid)
|
||||||
|
if (idx >= 0) {
|
||||||
|
uploadJobs.value[idx] = { ...uploadJobs.value[idx], ...status }
|
||||||
|
}
|
||||||
|
if (status.status === 'Completed' || status.status === 'Failed') {
|
||||||
|
stopPolling()
|
||||||
|
piyangoKatilimciStore.refreshPiyangoKatilimciList = true
|
||||||
|
refreshUploadJobsAndPollProcessing()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 2000)
|
||||||
|
}
|
||||||
|
|
||||||
|
const refreshUploadJobsAndPollProcessing = async () => {
|
||||||
|
const cekilisId = piyangoStore.selectedLottery
|
||||||
|
if (cekilisId !== null) {
|
||||||
|
uploadJobs.value = await piyangoKatilimciService.GetUploadJobs(cekilisId)
|
||||||
|
startPollingForAnyProcessingJob()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const startPollingForAnyProcessingJob = () => {
|
||||||
|
const processingJob = uploadJobs.value.find(
|
||||||
|
(j: Record<string, any>) => j.status?.toLowerCase() === 'processing'
|
||||||
|
)
|
||||||
|
if (processingJob?.guid) {
|
||||||
|
startPollingForExistingJob(processingJob.guid)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
stopPolling()
|
||||||
|
removeUploadHandlers()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
<style scoped>
|
||||||
.progress-bar {
|
.progress-bar {
|
||||||
width: 90%;
|
width: 90%;
|
||||||
max-width: 400px;
|
max-width: 400px;
|
||||||
@ -384,6 +561,7 @@
|
|||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
color: #333;
|
color: #333;
|
||||||
}
|
}
|
||||||
|
|
||||||
.upload-warning {
|
.upload-warning {
|
||||||
background: #fff8db;
|
background: #fff8db;
|
||||||
color: #856404;
|
color: #856404;
|
||||||
@ -394,4 +572,164 @@
|
|||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.upload-panel-content {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 32px;
|
||||||
|
padding: 24px 24px 24px 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-progress-section {
|
||||||
|
background: #f0f9ff;
|
||||||
|
border: 1px solid #b6d4fe;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 16px 20px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-progress-title {
|
||||||
|
margin: 0 0 12px;
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #1a1a2e;
|
||||||
|
align-self: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-progress-section .upload-warning {
|
||||||
|
margin-bottom: 16px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-progress-section .progress-bar {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-progress-section .progress-text {
|
||||||
|
margin-top: 12px;
|
||||||
|
color: #1a1a2e;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-history-section {
|
||||||
|
padding-bottom: 20px;
|
||||||
|
border-bottom: 1px solid #e8eaed;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-history-title,
|
||||||
|
.upload-form-title {
|
||||||
|
margin: 0 0 14px;
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #1a1a2e;
|
||||||
|
letter-spacing: 0.02em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-form-section {
|
||||||
|
padding-top: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-form-section :deep(.panel-documents-item) {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-form-section :deep(.form-item-description) {
|
||||||
|
margin-top: 8px;
|
||||||
|
font-size: 13px;
|
||||||
|
color: #5f6368;
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.history-loading {
|
||||||
|
text-align: center;
|
||||||
|
padding: 20px;
|
||||||
|
color: #5f6368;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.history-items {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.history-item {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr auto auto auto;
|
||||||
|
align-items: center;
|
||||||
|
gap: 16px;
|
||||||
|
padding: 12px 16px;
|
||||||
|
border: 1px solid #e8eaed;
|
||||||
|
border-radius: 8px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
background: #fafbfc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.history-item:hover {
|
||||||
|
background: #f1f3f5;
|
||||||
|
border-color: #d0d5dd;
|
||||||
|
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04);
|
||||||
|
}
|
||||||
|
|
||||||
|
.history-file {
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #1a1a2e;
|
||||||
|
min-width: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.history-status {
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 600;
|
||||||
|
padding: 4px 10px;
|
||||||
|
border-radius: 6px;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.history-status.status-completed {
|
||||||
|
color: #0d6832;
|
||||||
|
background: #d4edda;
|
||||||
|
}
|
||||||
|
|
||||||
|
.history-status.status-failed {
|
||||||
|
color: #721c24;
|
||||||
|
background: #f8d7da;
|
||||||
|
}
|
||||||
|
|
||||||
|
.history-status.status-processing {
|
||||||
|
color: #004085;
|
||||||
|
background: #cce5ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.history-status.status-pending {
|
||||||
|
color: #856404;
|
||||||
|
background: #fff3cd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.history-progress {
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #5f6368;
|
||||||
|
min-width: 36px;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.history-date {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #80868b;
|
||||||
|
min-width: 100px;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* İşleniyor durumunda progress bar */
|
||||||
|
.history-item.processing .history-progress {
|
||||||
|
font-weight: 600;
|
||||||
|
color: #007bff;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -80,6 +80,11 @@
|
|||||||
sort: true,
|
sort: true,
|
||||||
style: { width: '20%' }
|
style: { width: '20%' }
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'cekilisHakkiAdedi',
|
||||||
|
title: 'Çekiliş Hakkı Adedi',
|
||||||
|
style: { width: '10%' }
|
||||||
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
name: 'sifreCode',
|
name: 'sifreCode',
|
||||||
|
|||||||
@ -0,0 +1,339 @@
|
|||||||
|
<template>
|
||||||
|
<div class="panel-excel-upload-detail">
|
||||||
|
<div v-if="loading" class="detail-loading">Yükleniyor...</div>
|
||||||
|
<template v-else-if="job">
|
||||||
|
<div class="detail-summary">
|
||||||
|
<div class="detail-row detail-file-row">
|
||||||
|
<span class="detail-label">Dosya:</span>
|
||||||
|
<span class="detail-file-name">{{ job.fileName }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="detail-row">
|
||||||
|
<span class="detail-label">Durum:</span>
|
||||||
|
<span :class="['detail-status', 'status-' + job.status?.toLowerCase()]">
|
||||||
|
{{ statusText(job.status) }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="detail-row">
|
||||||
|
<span class="detail-label">İlerleme:</span>
|
||||||
|
<span>{{ job.progress }}%</span>
|
||||||
|
</div>
|
||||||
|
<div class="detail-stats">
|
||||||
|
<div class="detail-stat-item">
|
||||||
|
<span class="detail-stat-value">{{ job.totalRows }}</span>
|
||||||
|
<span class="detail-stat-label">Toplam Satır</span>
|
||||||
|
</div>
|
||||||
|
<div class="detail-stat-item detail-stat-inserted">
|
||||||
|
<span class="detail-stat-value">{{ job.insertedCount ?? 0 }}</span>
|
||||||
|
<span class="detail-stat-label">Eklenen</span>
|
||||||
|
</div>
|
||||||
|
<div class="detail-stat-item detail-stat-skipped">
|
||||||
|
<span class="detail-stat-value">{{ job.skippedRows ?? 0 }}</span>
|
||||||
|
<span class="detail-stat-label">Atlanan</span>
|
||||||
|
</div>
|
||||||
|
<div class="detail-stat-item detail-stat-duplicate">
|
||||||
|
<span class="detail-stat-value">{{ job.duplicateCount ?? 0 }}</span>
|
||||||
|
<span class="detail-stat-label">Duplicate</span>
|
||||||
|
</div>
|
||||||
|
<div class="detail-stat-item detail-stat-error">
|
||||||
|
<span class="detail-stat-value">{{ job.errorCount ?? 0 }}</span>
|
||||||
|
<span class="detail-stat-label">Hata</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-if="job.errorMessage" class="detail-error-box">
|
||||||
|
<span class="detail-error-label">Hata:</span>
|
||||||
|
<span>{{ job.errorMessage }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="detail-logs" v-if="logs && logs.length > 0">
|
||||||
|
<h4 class="detail-logs-title">İşlem Logları</h4>
|
||||||
|
<div class="logs-list">
|
||||||
|
<div
|
||||||
|
v-for="log in logs"
|
||||||
|
:key="log.id"
|
||||||
|
:class="['log-item', 'log-' + log.logLevel?.toLowerCase()]">
|
||||||
|
<span :class="['log-level', 'log-level-' + log.logLevel?.toLowerCase()]">{{ log.logLevel }}</span>
|
||||||
|
<span v-if="log.rowNumber" class="log-row">Satır {{ log.rowNumber }}</span>
|
||||||
|
<span class="log-message">{{ log.message }}</span>
|
||||||
|
<span v-if="log.details" class="log-details">{{ log.details }}</span>
|
||||||
|
<span class="log-time">{{ formatDate(log.createdAt) }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-else class="detail-no-logs">Log kaydı bulunamadı.</div>
|
||||||
|
</template>
|
||||||
|
<div v-else class="detail-not-found">Yükleme detayı bulunamadı.</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, onMounted, watch } from 'vue'
|
||||||
|
import { usePiyangoKatilimciService } from '../../service/piyangoKatilimciService'
|
||||||
|
import { useDateStore } from '@/stores/dateStore'
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
jobGuid: string
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const piyangoKatilimciService = usePiyangoKatilimciService()
|
||||||
|
const dateStore = useDateStore()
|
||||||
|
|
||||||
|
const loading = ref(true)
|
||||||
|
const job = ref<Record<string, any> | null>(null)
|
||||||
|
const logs = ref<Record<string, any>[]>([])
|
||||||
|
|
||||||
|
const statusText = (status: string) => {
|
||||||
|
const map: Record<string, string> = {
|
||||||
|
Pending: 'Bekliyor',
|
||||||
|
Processing: 'İşleniyor',
|
||||||
|
Completed: 'Tamamlandı',
|
||||||
|
Failed: 'Başarısız'
|
||||||
|
}
|
||||||
|
return map[status] || status
|
||||||
|
}
|
||||||
|
|
||||||
|
const formatDate = (val: string | Date) => {
|
||||||
|
if (!val) return '-'
|
||||||
|
return dateStore.dateFormat({ date: new Date(val), pattern: 'dd.mm.yyyy HH:MM' })
|
||||||
|
}
|
||||||
|
|
||||||
|
const loadDetail = async () => {
|
||||||
|
if (!props.jobGuid) return
|
||||||
|
loading.value = true
|
||||||
|
const data = await piyangoKatilimciService.GetUploadJobDetail(props.jobGuid)
|
||||||
|
if (data) {
|
||||||
|
job.value = data.job
|
||||||
|
logs.value = data.logs || []
|
||||||
|
} else {
|
||||||
|
job.value = null
|
||||||
|
logs.value = []
|
||||||
|
}
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => loadDetail())
|
||||||
|
watch(() => props.jobGuid, () => loadDetail())
|
||||||
|
</script>
|
||||||
|
<style scoped>
|
||||||
|
.panel-excel-upload-detail {
|
||||||
|
padding: 24px 24px 24px 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-loading {
|
||||||
|
text-align: center;
|
||||||
|
padding: 32px;
|
||||||
|
color: #5f6368;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-summary {
|
||||||
|
margin-bottom: 24px;
|
||||||
|
padding: 20px;
|
||||||
|
background: #fafbfc;
|
||||||
|
border: 1px solid #e8eaed;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-row {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 120px 1fr;
|
||||||
|
gap: 12px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-file-row {
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-file-name {
|
||||||
|
font-weight: 600;
|
||||||
|
color: #1a1a2e;
|
||||||
|
word-break: break-all;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-label {
|
||||||
|
font-weight: 600;
|
||||||
|
color: #5f6368;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-status {
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 600;
|
||||||
|
padding: 4px 10px;
|
||||||
|
border-radius: 6px;
|
||||||
|
display: inline-block;
|
||||||
|
width: fit-content;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-status.status-completed {
|
||||||
|
color: #0d6832;
|
||||||
|
background: #d4edda;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-status.status-failed {
|
||||||
|
color: #721c24;
|
||||||
|
background: #f8d7da;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-status.status-processing {
|
||||||
|
color: #004085;
|
||||||
|
background: #cce5ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-status.status-pending {
|
||||||
|
color: #856404;
|
||||||
|
background: #fff3cd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-stats {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(5, 1fr);
|
||||||
|
gap: 12px;
|
||||||
|
margin: 16px 0;
|
||||||
|
padding: 16px 0;
|
||||||
|
border-top: 1px solid #e8eaed;
|
||||||
|
border-bottom: 1px solid #e8eaed;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-stat-item {
|
||||||
|
text-align: center;
|
||||||
|
padding: 8px;
|
||||||
|
background: #f1f3f5;
|
||||||
|
border-radius: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-stat-value {
|
||||||
|
display: block;
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 700;
|
||||||
|
color: #1a1a2e;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-stat-label {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #5f6368;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-error-box {
|
||||||
|
margin-top: 16px;
|
||||||
|
padding: 12px 16px;
|
||||||
|
background: #fff5f5;
|
||||||
|
border: 1px solid #f8d7da;
|
||||||
|
border-radius: 6px;
|
||||||
|
color: #721c24;
|
||||||
|
font-size: 13px;
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-error-label {
|
||||||
|
font-weight: 600;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-not-found {
|
||||||
|
padding: 24px;
|
||||||
|
text-align: center;
|
||||||
|
color: #721c24;
|
||||||
|
background: #fff5f5;
|
||||||
|
border: 1px solid #f8d7da;
|
||||||
|
border-radius: 8px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-logs-title {
|
||||||
|
margin: 0 0 12px;
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #1a1a2e;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logs-list {
|
||||||
|
max-height: 400px;
|
||||||
|
overflow-y: auto;
|
||||||
|
border: 1px solid #e8eaed;
|
||||||
|
border-radius: 8px;
|
||||||
|
background: #fafbfc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.log-item {
|
||||||
|
padding: 10px 14px;
|
||||||
|
border-bottom: 1px solid #e8eaed;
|
||||||
|
font-size: 13px;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 10px;
|
||||||
|
align-items: baseline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.log-item:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.log-item.log-error {
|
||||||
|
background: #fff5f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.log-item.log-warning {
|
||||||
|
background: #fffbf0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.log-item.log-info {
|
||||||
|
background: #f0f9ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.log-level {
|
||||||
|
font-weight: 600;
|
||||||
|
min-width: 60px;
|
||||||
|
font-size: 11px;
|
||||||
|
padding: 2px 8px;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.log-level.log-level-error {
|
||||||
|
background: #f8d7da;
|
||||||
|
color: #721c24;
|
||||||
|
}
|
||||||
|
|
||||||
|
.log-level.log-level-warning {
|
||||||
|
background: #fff3cd;
|
||||||
|
color: #856404;
|
||||||
|
}
|
||||||
|
|
||||||
|
.log-level.log-level-info {
|
||||||
|
background: #cce5ff;
|
||||||
|
color: #004085;
|
||||||
|
}
|
||||||
|
|
||||||
|
.log-row {
|
||||||
|
color: #5f6368;
|
||||||
|
font-family: ui-monospace, monospace;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.log-message {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.log-details {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #5f6368;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.log-time {
|
||||||
|
font-size: 11px;
|
||||||
|
color: #80868b;
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-no-logs {
|
||||||
|
padding: 24px;
|
||||||
|
color: #80868b;
|
||||||
|
text-align: center;
|
||||||
|
font-style: italic;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -141,10 +141,10 @@
|
|||||||
"
|
"
|
||||||
half />
|
half />
|
||||||
<form-display
|
<form-display
|
||||||
v-model="piyangoKatilimciStore.piyangoKatilimciUserFormData.cekilisKatilimSiraNo"
|
v-model="piyangoKatilimciStore.piyangoKatilimciUserFormData.cekilisHakkiAdedi"
|
||||||
label="Katılım Sora No"
|
label="Çekiliş Hakkı Adedi"
|
||||||
:invalidText="
|
:invalidText="
|
||||||
piyangoKatilimciValidationStore.userFormInvalidTexts.cekilisKatilimSiraNo
|
piyangoKatilimciValidationStore.userFormInvalidTexts.cekilisHakkiAdedi
|
||||||
"
|
"
|
||||||
half />
|
half />
|
||||||
<form-display
|
<form-display
|
||||||
@ -287,6 +287,16 @@
|
|||||||
:invalidText="
|
:invalidText="
|
||||||
piyangoKatilimciValidationStore.userFormInvalidTexts.cekilisKatilimSiraNo
|
piyangoKatilimciValidationStore.userFormInvalidTexts.cekilisKatilimSiraNo
|
||||||
" />
|
" />
|
||||||
|
<form-input
|
||||||
|
@keyup="FormChanged"
|
||||||
|
modelKey="cekilisHakkiAdedi"
|
||||||
|
v-model="piyangoKatilimciStore.piyangoKatilimciUserFormData.cekilisHakkiAdedi"
|
||||||
|
half
|
||||||
|
label="Çekiliş Hakkı Adedi"
|
||||||
|
:invalidText="
|
||||||
|
piyangoKatilimciValidationStore.userFormInvalidTexts.cekilisHakkiAdedi
|
||||||
|
"
|
||||||
|
@keydown="validationStore.allowNumbersWithKeys" />
|
||||||
<form-input
|
<form-input
|
||||||
@keyup="FormChanged"
|
@keyup="FormChanged"
|
||||||
modelKey="magazaKartNumarasi"
|
modelKey="magazaKartNumarasi"
|
||||||
|
|||||||
@ -15,6 +15,10 @@ export const usePiyangoKatilimciService = defineStore('piyangoKatilimciService',
|
|||||||
const SaveKatilimciUser = async () => {
|
const SaveKatilimciUser = async () => {
|
||||||
if (piyangoKatilimciValidationStore.UserFormCheck()) {
|
if (piyangoKatilimciValidationStore.UserFormCheck()) {
|
||||||
let form: any
|
let form: any
|
||||||
|
piyangoKatilimciStore.piyangoKatilimciUserFormData.cekilisHakkiAdedi = Math.max(
|
||||||
|
Number(piyangoKatilimciStore.piyangoKatilimciUserFormData.cekilisHakkiAdedi) || 1,
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
if (!piyangoKatilimciStore.isPiyangoKatilimciUserUpdate) {
|
if (!piyangoKatilimciStore.isPiyangoKatilimciUserUpdate) {
|
||||||
delete piyangoKatilimciStore.piyangoKatilimciUserFormData.id
|
delete piyangoKatilimciStore.piyangoKatilimciUserFormData.id
|
||||||
@ -82,5 +86,46 @@ export const usePiyangoKatilimciService = defineStore('piyangoKatilimciService',
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return { SaveKatilimciUser, CreateOnlineDraw, KatilimciData, KatilimciFileUpload }
|
const GetUploadJobs = async (cekilisId: number): Promise<Record<string, any>[]> => {
|
||||||
|
const dt = await dataStore.dataGet(`ExcelUploadJob/my-jobs?cekilisId=${cekilisId}`)
|
||||||
|
if (dt !== 'errorfalse' && Array.isArray(dt)) {
|
||||||
|
return dt
|
||||||
|
}
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
|
const GetUploadJobDetail = async (guid: string): Promise<Record<string, any> | null> => {
|
||||||
|
const dt = await dataStore.dataGet(`ExcelUploadJob/${guid}`)
|
||||||
|
if (dt !== 'errorfalse') {
|
||||||
|
return dt
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
const GetUploadJobStatus = async (guid: string): Promise<Record<string, any> | null> => {
|
||||||
|
const dt = await dataStore.dataGet(`ExcelUploadJob/status/${guid}`)
|
||||||
|
if (dt !== 'errorfalse') {
|
||||||
|
return dt
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
const SubscribeToJob = async (guid: string, connectionId: string): Promise<boolean> => {
|
||||||
|
const result = await dataStore.dataPost(
|
||||||
|
`ExcelUploadJob/subscribe?guid=${guid}&connectionId=${encodeURIComponent(connectionId)}`,
|
||||||
|
{}
|
||||||
|
)
|
||||||
|
return result !== 'errorfalse'
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
SaveKatilimciUser,
|
||||||
|
CreateOnlineDraw,
|
||||||
|
KatilimciData,
|
||||||
|
KatilimciFileUpload,
|
||||||
|
GetUploadJobs,
|
||||||
|
GetUploadJobDetail,
|
||||||
|
GetUploadJobStatus,
|
||||||
|
SubscribeToJob
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@ -1,48 +1,68 @@
|
|||||||
import * as signalR from '@microsoft/signalr'
|
import * as signalR from '@microsoft/signalr'
|
||||||
|
|
||||||
let connection: signalR.HubConnection
|
let connection: signalR.HubConnection | null = null
|
||||||
let connectionId = ''
|
|
||||||
|
|
||||||
export const connectToHub = async () => {
|
export const connectToHub = async (): Promise<string> => {
|
||||||
console.log('Connecting to SignalR Hub...')
|
console.log('Connecting to SignalR Hub...')
|
||||||
// Mevcut bağlantı varsa kapat
|
|
||||||
if (connection && connection.state === signalR.HubConnectionState.Connected) {
|
// Mevcut bağlantı varsa her durumda kapat (Connected, Reconnecting, Disconnected)
|
||||||
|
if (connection) {
|
||||||
|
try {
|
||||||
await connection.stop()
|
await connection.stop()
|
||||||
|
} catch {
|
||||||
|
// Bağlantı zaten kapalı olabilir, yoksay
|
||||||
|
}
|
||||||
|
connection = null
|
||||||
}
|
}
|
||||||
|
|
||||||
connection = new signalR.HubConnectionBuilder()
|
connection = new signalR.HubConnectionBuilder()
|
||||||
.withUrl(import.meta.env.VITE_SOCKET_URL, {
|
.withUrl(import.meta.env.VITE_SOCKET_URL, {
|
||||||
withCredentials: false,
|
withCredentials: false,
|
||||||
skipNegotiation: true, // WebSocket kullanırken negotiation atlanabilir
|
skipNegotiation: true,
|
||||||
transport: signalR.HttpTransportType.WebSockets
|
transport: signalR.HttpTransportType.WebSockets
|
||||||
})
|
})
|
||||||
.withAutomaticReconnect()
|
.withAutomaticReconnect()
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
// Eventleri ekle
|
// Eventleri ekle (connection artık tanımlı)
|
||||||
onProgress((data) => console.log('progress', data))
|
connection.on('ReceiveProgress', (data: any) => console.log('progress', data))
|
||||||
onInsertProgress((data) => console.log('insert progress', data))
|
connection.on('ReceiveInsertProgress', (data: any) => console.log('insert progress', data))
|
||||||
onCompleted((data) => console.log('completed', data))
|
connection.on('ReceiveCompleted', (data: any) => console.log('completed', data))
|
||||||
onError((data) => console.log('error', data))
|
connection.on('ReceiveError', (data: any) => console.log('error', data))
|
||||||
|
|
||||||
|
try {
|
||||||
await connection.start()
|
await connection.start()
|
||||||
connectionId = await connection.invoke<string>('GetConnectionId')
|
const connectionId = await connection.invoke<string>('GetConnectionId')
|
||||||
console.log('Connected to SignalR Hub with Connection ID:', connectionId)
|
console.log('Connected to SignalR Hub with Connection ID:', connectionId)
|
||||||
return connectionId
|
return connectionId
|
||||||
|
} catch (err) {
|
||||||
|
connection = null
|
||||||
|
throw err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const onProgress = (callback: (data: any) => void) => {
|
export const onProgress = (callback: (data: any) => void) => {
|
||||||
connection.on('ReceiveProgress', callback)
|
if (connection) connection.on('ReceiveProgress', callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const onInsertProgress = (callback: (data: any) => void) => {
|
export const onInsertProgress = (callback: (data: any) => void) => {
|
||||||
connection.on('ReceiveInsertProgress', callback)
|
if (connection) connection.on('ReceiveInsertProgress', callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const onCompleted = (callback: (data: any) => void) => {
|
export const onCompleted = (callback: (data: any) => void) => {
|
||||||
connection.on('ReceiveCompleted', callback)
|
if (connection) connection.on('ReceiveCompleted', callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const onError = (callback: (data: any) => void) => {
|
export const onError = (callback: (data: any) => void) => {
|
||||||
connection.on('ReceiveError', callback)
|
if (connection) connection.on('ReceiveError', callback)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Upload event handler'larını kaldır (memory leak ve çoklu tetikleme önleme) */
|
||||||
|
export const removeUploadHandlers = () => {
|
||||||
|
if (connection) {
|
||||||
|
connection.off('ReceiveProgress')
|
||||||
|
connection.off('ReceiveInsertProgress')
|
||||||
|
connection.off('ReceiveCompleted')
|
||||||
|
connection.off('ReceiveError')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,6 +10,7 @@ export const usePiyangoKatilimciStore = defineStore('piyangoKatilimciStore', ()
|
|||||||
const piyangoKatilimciUserSafeFormData = reactive<Record<string, any>>({
|
const piyangoKatilimciUserSafeFormData = reactive<Record<string, any>>({
|
||||||
ikramiyeId: null,
|
ikramiyeId: null,
|
||||||
cekilisKatilimSiraNo: null,
|
cekilisKatilimSiraNo: null,
|
||||||
|
cekilisHakkiAdedi: 1,
|
||||||
sifreCode: '',
|
sifreCode: '',
|
||||||
magazaKartNumarasi: '',
|
magazaKartNumarasi: '',
|
||||||
adi: '',
|
adi: '',
|
||||||
|
|||||||
@ -96,6 +96,31 @@ export const usePiyangoKatilimciValidationStore = defineStore(
|
|||||||
'Lütfen soyadını giriniz.'
|
'Lütfen soyadını giriniz.'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
validationStore.IsFieldEmpty(
|
||||||
|
piyangoKatilimciStore.piyangoKatilimciUserFormData,
|
||||||
|
userFormInvalidTexts,
|
||||||
|
'cekilisHakkiAdedi',
|
||||||
|
'Lütfen çekiliş hakkı adedini giriniz.'
|
||||||
|
)
|
||||||
|
|
||||||
|
if (
|
||||||
|
!validationStore.checkEmpty(
|
||||||
|
piyangoKatilimciStore.piyangoKatilimciUserFormData.cekilisHakkiAdedi
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
const hakAdedi = Number(
|
||||||
|
piyangoKatilimciStore.piyangoKatilimciUserFormData.cekilisHakkiAdedi
|
||||||
|
)
|
||||||
|
|
||||||
|
if (!Number.isInteger(hakAdedi) || hakAdedi < 1) {
|
||||||
|
userFormInvalidTexts.cekilisHakkiAdedi =
|
||||||
|
'Çekiliş hakkı adedi en az 1 olmalıdır.'
|
||||||
|
isUserFormValid.value = false
|
||||||
|
} else {
|
||||||
|
delete userFormInvalidTexts.cekilisHakkiAdedi
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var today: Date | string = new Date()
|
var today: Date | string = new Date()
|
||||||
today = dateStore.dateFormat({
|
today = dateStore.dateFormat({
|
||||||
date: today,
|
date: today,
|
||||||
|
|||||||
@ -49,7 +49,7 @@ export const useDataStore = defineStore('dataStore', () => {
|
|||||||
return response.data
|
return response.data
|
||||||
}
|
}
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
CheckApiError(error.response.status, error.response.data)
|
CheckApiError(error.response?.status, error.response?.data)
|
||||||
console.error('Hata oluştu -:', error)
|
console.error('Hata oluştu -:', error)
|
||||||
return 'errorfalse'
|
return 'errorfalse'
|
||||||
}
|
}
|
||||||
@ -64,6 +64,8 @@ export const useDataStore = defineStore('dataStore', () => {
|
|||||||
options?: Record<string, any>
|
options?: Record<string, any>
|
||||||
toast?: Record<string, any>
|
toast?: Record<string, any>
|
||||||
full?: boolean
|
full?: boolean
|
||||||
|
/** Bu status kodları için CheckApiError atlanır, hata objesi döner */
|
||||||
|
skipErrorForStatuses?: number[]
|
||||||
} = {}
|
} = {}
|
||||||
): Promise<any> => {
|
): Promise<any> => {
|
||||||
try {
|
try {
|
||||||
@ -86,8 +88,11 @@ export const useDataStore = defineStore('dataStore', () => {
|
|||||||
return response.data
|
return response.data
|
||||||
}
|
}
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
CheckApiError(error.response.status, error.response.data)
|
const status = error.response?.status
|
||||||
|
if (data.skipErrorForStatuses?.includes(status)) {
|
||||||
|
return { _error: true, status, data: error.response?.data }
|
||||||
|
}
|
||||||
|
CheckApiError(status, error.response?.data)
|
||||||
console.error('Hata oluştu:', error)
|
console.error('Hata oluştu:', error)
|
||||||
return Promise.resolve('errorfalse')
|
return Promise.resolve('errorfalse')
|
||||||
}
|
}
|
||||||
@ -124,8 +129,7 @@ export const useDataStore = defineStore('dataStore', () => {
|
|||||||
return response.data
|
return response.data
|
||||||
}
|
}
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
CheckApiError(error.response.status, error.response.data)
|
CheckApiError(error.response?.status, error.response?.data)
|
||||||
|
|
||||||
console.error('Hata oluştu:', error)
|
console.error('Hata oluştu:', error)
|
||||||
return Promise.resolve('errorfalse')
|
return Promise.resolve('errorfalse')
|
||||||
}
|
}
|
||||||
@ -161,16 +165,20 @@ export const useDataStore = defineStore('dataStore', () => {
|
|||||||
return response.data
|
return response.data
|
||||||
}
|
}
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
CheckApiError(error.response.status, error.response.data)
|
CheckApiError(error.response?.status, error.response?.data)
|
||||||
console.error('Hata oluştu:', error)
|
console.error('Hata oluştu:', error)
|
||||||
return Promise.resolve('errorfalse')
|
return Promise.resolve('errorfalse')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const CheckApiError = async (status: number, data: Record<string, any>) => {
|
const CheckApiError = (status?: number, data?: Record<string, any>) => {
|
||||||
|
if (status === undefined) {
|
||||||
|
toastStore.AddToast("Bağlantı hatası. İnternet bağlantınızı kontrol edin.", "alert", 8000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (status === 401) return; // Axios interceptor login'e yönlendirir
|
||||||
if (status === 400) {
|
if (status === 400) {
|
||||||
const errorKey = typeof data === "string" ? data : data?.hata || data?.errors;
|
const errorKey = typeof data === "string" ? data : data?.hata || data?.errors;
|
||||||
|
|
||||||
if (errorKey !== undefined) {
|
if (errorKey !== undefined) {
|
||||||
if (Array.isArray(errorKey)) {
|
if (Array.isArray(errorKey)) {
|
||||||
errorKey.forEach((el: string) => {
|
errorKey.forEach((el: string) => {
|
||||||
@ -184,7 +192,19 @@ export const useDataStore = defineStore('dataStore', () => {
|
|||||||
} else {
|
} else {
|
||||||
toastStore.AddToast("Bir hata oluştu.", "alert");
|
toastStore.AddToast("Bir hata oluştu.", "alert");
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
const httpErrorMessages: Record<number, string> = {
|
||||||
|
413: "Dosya boyutu çok büyük. Lütfen daha küçük bir dosya yükleyin veya sunucu limitlerini kontrol edin.",
|
||||||
|
404: "İstenen kaynak bulunamadı.",
|
||||||
|
500: "Sunucu hatası oluştu. Lütfen daha sonra tekrar deneyin.",
|
||||||
|
502: "Sunucu geçici olarak yanıt vermiyor. Lütfen daha sonra tekrar deneyin.",
|
||||||
|
503: "Servis şu an kullanılamıyor. Lütfen daha sonra tekrar deneyin.",
|
||||||
|
504: "İstek zaman aşımına uğradı. Lütfen tekrar deneyin.",
|
||||||
|
408: "İstek zaman aşımına uğradı. Lütfen tekrar deneyin."
|
||||||
|
};
|
||||||
|
const message = httpErrorMessages[status] || `Beklenmeyen hata (${status}). Lütfen tekrar deneyin.`;
|
||||||
|
toastStore.AddToast(message, "alert", 8000);
|
||||||
};
|
};
|
||||||
|
|
||||||
const GetCustomerTipList = async () => {
|
const GetCustomerTipList = async () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user