fix: merge general improvements from release branch
Backend: - gateway_handler: pass subject.UserID instead of int64(0) for user-level routing - setting_handler: add missing BalanceLowNotifyRechargeURL to UpdateSettings response - openai_gateway_service: use applyAccountStatsCost for account stats pricing integration - embed_on: add local file override (data/public/) for embedded frontend assets Frontend: - useTableSelection: add batchUpdate method for batch operations - AccountsView: virtual scrolling params, Set-based isSelected, swipe virtualization - ProxiesView: add batchUpdate to selection and swipe-select - BulkEditAccountModal: fix submit handler to prevent event object as argument - SettingsView: move payload construction outside try block - i18n: add general translation keys (saved, deleted, view, validation, allowUserRefund) - api/client: reorder error fields for consistency - stores/payment: clarify pollOrderStatus JSDoc
This commit is contained in:
@@ -144,6 +144,7 @@
|
||||
<AccountBulkActionsBar :selected-ids="selIds" @delete="handleBulkDelete" @reset-status="handleBulkResetStatus" @refresh-token="handleBulkRefreshToken" @edit="showBulkEdit = true" @clear="clearSelection" @select-page="selectPage" @toggle-schedulable="handleBulkToggleSchedulable" />
|
||||
<div ref="accountTableRef" class="flex min-h-0 flex-1 flex-col overflow-hidden">
|
||||
<DataTable
|
||||
ref="dataTableRef"
|
||||
:columns="cols"
|
||||
:data="accounts"
|
||||
:loading="loading"
|
||||
@@ -153,6 +154,8 @@
|
||||
default-sort-key="name"
|
||||
default-sort-order="asc"
|
||||
:sort-storage-key="ACCOUNT_SORT_STORAGE_KEY"
|
||||
:estimate-row-height="72"
|
||||
:overscan="5"
|
||||
>
|
||||
<template #header-select>
|
||||
<input
|
||||
@@ -164,7 +167,7 @@
|
||||
/>
|
||||
</template>
|
||||
<template #cell-select="{ row }">
|
||||
<input type="checkbox" :checked="selIds.includes(row.id)" @change="toggleSel(row.id)" class="rounded border-gray-300 text-primary-600 focus:ring-primary-500" />
|
||||
<input type="checkbox" :checked="isSelected(row.id)" @change="toggleSel(row.id)" class="rounded border-gray-300 text-primary-600 focus:ring-primary-500" />
|
||||
</template>
|
||||
<template #cell-name="{ row, value }">
|
||||
<div class="flex flex-col">
|
||||
@@ -197,7 +200,9 @@
|
||||
<AccountCapacityCell :account="row" />
|
||||
</template>
|
||||
<template #cell-status="{ row }">
|
||||
<AccountStatusIndicator :account="row" @show-temp-unsched="handleShowTempUnsched" />
|
||||
<div class="flex items-center gap-1.5">
|
||||
<AccountStatusIndicator :account="row" @show-temp-unsched="handleShowTempUnsched" />
|
||||
</div>
|
||||
</template>
|
||||
<template #cell-schedulable="{ row }">
|
||||
<button @click="handleToggleSchedulable(row)" :disabled="togglingSchedulable === row.id" class="relative inline-flex h-5 w-9 flex-shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none focus:ring-2 focus:ring-primary-500 focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 dark:focus:ring-offset-dark-800" :class="[row.schedulable ? 'bg-primary-500 hover:bg-primary-600' : 'bg-gray-200 hover:bg-gray-300 dark:bg-dark-600 dark:hover:bg-dark-500']" :title="row.schedulable ? t('admin.accounts.schedulableEnabled') : t('admin.accounts.schedulableDisabled')">
|
||||
@@ -313,7 +318,7 @@ import { useAppStore } from '@/stores/app'
|
||||
import { useAuthStore } from '@/stores/auth'
|
||||
import { adminAPI } from '@/api/admin'
|
||||
import { useTableLoader } from '@/composables/useTableLoader'
|
||||
import { useSwipeSelect } from '@/composables/useSwipeSelect'
|
||||
import { useSwipeSelect, type SwipeSelectVirtualContext } from '@/composables/useSwipeSelect'
|
||||
import { useTableSelection } from '@/composables/useTableSelection'
|
||||
import AppLayout from '@/components/layout/AppLayout.vue'
|
||||
import TablePageLayout from '@/components/layout/TablePageLayout.vue'
|
||||
@@ -351,6 +356,7 @@ const authStore = useAuthStore()
|
||||
const proxies = ref<AccountProxy[]>([])
|
||||
const groups = ref<AdminGroup[]>([])
|
||||
const accountTableRef = ref<HTMLElement | null>(null)
|
||||
const dataTableRef = ref<InstanceType<typeof DataTable> | null>(null)
|
||||
const selPlatforms = computed<AccountPlatform[]>(() => {
|
||||
const platforms = new Set(
|
||||
accounts.value
|
||||
@@ -650,17 +656,25 @@ const {
|
||||
clear: clearSelection,
|
||||
removeMany: removeSelectedAccounts,
|
||||
toggleVisible,
|
||||
selectVisible: selectPage
|
||||
selectVisible: selectPage,
|
||||
batchUpdate
|
||||
} = useTableSelection<Account>({
|
||||
rows: accounts,
|
||||
getId: (account) => account.id
|
||||
})
|
||||
|
||||
const swipeVirtualContext: SwipeSelectVirtualContext = {
|
||||
getVirtualizer: () => dataTableRef.value?.virtualizer ?? null,
|
||||
getSortedData: () => dataTableRef.value?.sortedData ?? accounts.value,
|
||||
getRowId: (row: any) => row.id,
|
||||
}
|
||||
|
||||
useSwipeSelect(accountTableRef, {
|
||||
isSelected,
|
||||
select,
|
||||
deselect
|
||||
})
|
||||
deselect,
|
||||
batchUpdate
|
||||
}, swipeVirtualContext)
|
||||
|
||||
const resetAutoRefreshCache = () => {
|
||||
autoRefreshETag.value = null
|
||||
|
||||
@@ -985,7 +985,8 @@ const {
|
||||
deselect,
|
||||
clear: clearSelectedProxies,
|
||||
removeMany: removeSelectedProxies,
|
||||
toggleVisible
|
||||
toggleVisible,
|
||||
batchUpdate
|
||||
} = useTableSelection<Proxy>({
|
||||
rows: proxies,
|
||||
getId: (proxy) => proxy.id
|
||||
@@ -993,7 +994,8 @@ const {
|
||||
useSwipeSelect(proxyTableRef, {
|
||||
isSelected,
|
||||
select,
|
||||
deselect
|
||||
deselect,
|
||||
batchUpdate
|
||||
})
|
||||
const accountsProxy = ref<Proxy | null>(null)
|
||||
const proxyAccounts = ref<ProxyAccountSummary[]>([])
|
||||
|
||||
@@ -4116,12 +4116,13 @@ async function handleToggleField(provider: ProviderInstance, field: 'enabled' |
|
||||
if (field === 'enabled') newValue = !provider.enabled
|
||||
else if (field === 'refund_enabled') newValue = !provider.refund_enabled
|
||||
else newValue = !provider.allow_user_refund
|
||||
|
||||
const payload: Record<string, boolean> = { [field]: newValue }
|
||||
// Cascade: turning off refund_enabled also turns off allow_user_refund
|
||||
if (field === 'refund_enabled' && !newValue) {
|
||||
payload.allow_user_refund = false
|
||||
}
|
||||
try {
|
||||
const payload: Record<string, boolean> = { [field]: newValue }
|
||||
// Cascade: turning off refund_enabled also disables allow_user_refund
|
||||
if (field === 'refund_enabled' && !newValue) {
|
||||
payload.allow_user_refund = false
|
||||
}
|
||||
await adminAPI.payment.updateProvider(provider.id, payload)
|
||||
if (field === 'enabled') provider.enabled = newValue
|
||||
else if (field === 'refund_enabled') {
|
||||
|
||||
Reference in New Issue
Block a user