Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
陈曦
sub2api
Commits
da1d2600
"frontend/src/vscode:/vscode.git/clone" did not exist on "df57d2776b1a74e37470970f1bcf8942ad810e1d"
Commit
da1d2600
authored
Apr 22, 2026
by
IanShaw027
Browse files
Merge branch 'main' into rebuild/auth-identity-foundation
parents
e4cfcae6
78f691d2
Changes
67
Show whitespace changes
Inline
Side-by-side
frontend/src/views/admin/orders/AdminPaymentDashboardView.vue
View file @
da1d2600
...
@@ -72,7 +72,7 @@ import { ref, watch, onMounted } from 'vue'
...
@@ -72,7 +72,7 @@ import { ref, watch, onMounted } from 'vue'
import
{
useI18n
}
from
'
vue-i18n
'
import
{
useI18n
}
from
'
vue-i18n
'
import
{
useAppStore
}
from
'
@/stores/app
'
import
{
useAppStore
}
from
'
@/stores/app
'
import
{
adminPaymentAPI
}
from
'
@/api/admin/payment
'
import
{
adminPaymentAPI
}
from
'
@/api/admin/payment
'
import
{
extract
Api
ErrorMessage
}
from
'
@/utils/apiError
'
import
{
extract
I18n
ErrorMessage
}
from
'
@/utils/apiError
'
import
type
{
DashboardStats
}
from
'
@/types/payment
'
import
type
{
DashboardStats
}
from
'
@/types/payment
'
import
AppLayout
from
'
@/components/layout/AppLayout.vue
'
import
AppLayout
from
'
@/components/layout/AppLayout.vue
'
import
LoadingSpinner
from
'
@/components/common/LoadingSpinner.vue
'
import
LoadingSpinner
from
'
@/components/common/LoadingSpinner.vue
'
...
@@ -110,7 +110,7 @@ async function loadDashboard() {
...
@@ -110,7 +110,7 @@ async function loadDashboard() {
const
res
=
await
adminPaymentAPI
.
getDashboard
(
days
.
value
)
const
res
=
await
adminPaymentAPI
.
getDashboard
(
days
.
value
)
stats
.
value
=
res
.
data
stats
.
value
=
res
.
data
}
catch
(
err
:
unknown
)
{
}
catch
(
err
:
unknown
)
{
appStore
.
showError
(
extract
Api
ErrorMessage
(
err
,
t
(
'
common.error
'
)))
appStore
.
showError
(
extract
I18n
ErrorMessage
(
err
,
t
,
'
payment.errors
'
,
t
(
'
common.error
'
)))
}
finally
{
}
finally
{
loading
.
value
=
false
loading
.
value
=
false
}
}
...
...
frontend/src/views/admin/orders/AdminPaymentPlansView.vue
View file @
da1d2600
...
@@ -78,7 +78,7 @@ import { ref, computed, onMounted } from 'vue'
...
@@ -78,7 +78,7 @@ import { ref, computed, onMounted } from 'vue'
import
{
useI18n
}
from
'
vue-i18n
'
import
{
useI18n
}
from
'
vue-i18n
'
import
{
useAppStore
}
from
'
@/stores/app
'
import
{
useAppStore
}
from
'
@/stores/app
'
import
{
adminPaymentAPI
}
from
'
@/api/admin/payment
'
import
{
adminPaymentAPI
}
from
'
@/api/admin/payment
'
import
{
extract
Api
ErrorMessage
}
from
'
@/utils/apiError
'
import
{
extract
I18n
ErrorMessage
}
from
'
@/utils/apiError
'
import
adminAPI
from
'
@/api/admin
'
import
adminAPI
from
'
@/api/admin
'
import
type
{
SubscriptionPlan
}
from
'
@/types/payment
'
import
type
{
SubscriptionPlan
}
from
'
@/types/payment
'
import
type
{
AdminGroup
}
from
'
@/types
'
import
type
{
AdminGroup
}
from
'
@/types
'
...
@@ -150,7 +150,7 @@ async function loadPlans() {
...
@@ -150,7 +150,7 @@ async function loadPlans() {
:
(
p
.
features
||
[]),
:
(
p
.
features
||
[]),
}))
}))
}
}
catch
(
err
:
unknown
)
{
appStore
.
showError
(
extract
Api
ErrorMessage
(
err
,
t
(
'
common.error
'
)))
}
catch
(
err
:
unknown
)
{
appStore
.
showError
(
extract
I18n
ErrorMessage
(
err
,
t
,
'
payment.errors
'
,
t
(
'
common.error
'
)))
}
finally
{
plansLoading
.
value
=
false
}
finally
{
plansLoading
.
value
=
false
}
}
}
...
@@ -166,7 +166,7 @@ async function toggleForSale(plan: SubscriptionPlan) {
...
@@ -166,7 +166,7 @@ async function toggleForSale(plan: SubscriptionPlan) {
await
adminPaymentAPI
.
updatePlan
(
plan
.
id
,
{
for_sale
:
!
plan
.
for_sale
})
await
adminPaymentAPI
.
updatePlan
(
plan
.
id
,
{
for_sale
:
!
plan
.
for_sale
})
plan
.
for_sale
=
!
plan
.
for_sale
plan
.
for_sale
=
!
plan
.
for_sale
}
catch
(
err
:
unknown
)
{
}
catch
(
err
:
unknown
)
{
appStore
.
showError
(
extract
Api
ErrorMessage
(
err
,
t
(
'
common.error
'
)))
appStore
.
showError
(
extract
I18n
ErrorMessage
(
err
,
t
,
'
payment.errors
'
,
t
(
'
common.error
'
)))
}
}
}
}
...
@@ -174,7 +174,7 @@ function confirmDeletePlan(plan: SubscriptionPlan) { deletingPlanId.value = plan
...
@@ -174,7 +174,7 @@ function confirmDeletePlan(plan: SubscriptionPlan) { deletingPlanId.value = plan
async
function
handleDeletePlan
()
{
async
function
handleDeletePlan
()
{
if
(
!
deletingPlanId
.
value
)
return
if
(
!
deletingPlanId
.
value
)
return
try
{
await
adminPaymentAPI
.
deletePlan
(
deletingPlanId
.
value
);
appStore
.
showSuccess
(
t
(
'
common.deleted
'
));
showDeletePlanDialog
.
value
=
false
;
loadPlans
()
}
try
{
await
adminPaymentAPI
.
deletePlan
(
deletingPlanId
.
value
);
appStore
.
showSuccess
(
t
(
'
common.deleted
'
));
showDeletePlanDialog
.
value
=
false
;
loadPlans
()
}
catch
(
err
:
unknown
)
{
appStore
.
showError
(
extract
Api
ErrorMessage
(
err
,
t
(
'
common.error
'
)))
}
catch
(
err
:
unknown
)
{
appStore
.
showError
(
extract
I18n
ErrorMessage
(
err
,
t
,
'
payment.errors
'
,
t
(
'
common.error
'
)))
}
}
}
// ==================== Lifecycle ====================
// ==================== Lifecycle ====================
...
...
frontend/src/views/user/PaymentQRCodeView.vue
View file @
da1d2600
...
@@ -39,7 +39,7 @@ import { useRoute, useRouter } from 'vue-router'
...
@@ -39,7 +39,7 @@ import { useRoute, useRouter } from 'vue-router'
import
AppLayout
from
'
@/components/layout/AppLayout.vue
'
import
AppLayout
from
'
@/components/layout/AppLayout.vue
'
import
{
usePaymentStore
}
from
'
@/stores/payment
'
import
{
usePaymentStore
}
from
'
@/stores/payment
'
import
{
paymentAPI
}
from
'
@/api/payment
'
import
{
paymentAPI
}
from
'
@/api/payment
'
import
{
extract
Api
ErrorMessage
}
from
'
@/utils/apiError
'
import
{
extract
I18n
ErrorMessage
}
from
'
@/utils/apiError
'
import
{
useAppStore
}
from
'
@/stores
'
import
{
useAppStore
}
from
'
@/stores
'
import
QRCode
from
'
qrcode
'
import
QRCode
from
'
qrcode
'
import
alipayIcon
from
'
@/assets/icons/alipay.svg
'
import
alipayIcon
from
'
@/assets/icons/alipay.svg
'
...
@@ -167,7 +167,7 @@ async function handleCancel() {
...
@@ -167,7 +167,7 @@ async function handleCancel() {
cleanup
()
cleanup
()
router
.
push
(
'
/purchase
'
)
router
.
push
(
'
/purchase
'
)
}
catch
(
err
:
unknown
)
{
}
catch
(
err
:
unknown
)
{
appStore
.
showError
(
extract
Api
ErrorMessage
(
err
,
t
(
'
common.error
'
)))
appStore
.
showError
(
extract
I18n
ErrorMessage
(
err
,
t
,
'
payment.errors
'
,
t
(
'
common.error
'
)))
}
finally
{
}
finally
{
cancelling
.
value
=
false
cancelling
.
value
=
false
}
}
...
...
frontend/src/views/user/PaymentView.vue
View file @
da1d2600
...
@@ -252,13 +252,13 @@ import { usePaymentStore } from '@/stores/payment'
...
@@ -252,13 +252,13 @@ import { usePaymentStore } from '@/stores/payment'
import
{
useSubscriptionStore
}
from
'
@/stores/subscriptions
'
import
{
useSubscriptionStore
}
from
'
@/stores/subscriptions
'
import
{
useAppStore
}
from
'
@/stores
'
import
{
useAppStore
}
from
'
@/stores
'
import
{
paymentAPI
}
from
'
@/api/payment
'
import
{
paymentAPI
}
from
'
@/api/payment
'
import
{
extractApiErrorMessage
}
from
'
@/utils/apiError
'
import
{
extractApiErrorMessage
,
extractI18nErrorMessage
}
from
'
@/utils/apiError
'
import
{
isMobileDevice
}
from
'
@/utils/device
'
import
{
isMobileDevice
}
from
'
@/utils/device
'
import
type
{
SubscriptionPlan
,
CheckoutInfoResponse
,
CreateOrderResult
,
OrderType
}
from
'
@/types/payment
'
import
type
{
SubscriptionPlan
,
CheckoutInfoResponse
,
CreateOrderResult
,
OrderType
}
from
'
@/types/payment
'
import
AppLayout
from
'
@/components/layout/AppLayout.vue
'
import
AppLayout
from
'
@/components/layout/AppLayout.vue
'
import
AmountInput
from
'
@/components/payment/AmountInput.vue
'
import
AmountInput
from
'
@/components/payment/AmountInput.vue
'
import
PaymentMethodSelector
from
'
@/components/payment/PaymentMethodSelector.vue
'
import
PaymentMethodSelector
from
'
@/components/payment/PaymentMethodSelector.vue
'
import
{
METHOD_ORDER
,
POPUP_WINDOW_FEATURES
,
STRIPE_POPUP_WINDOW_FEATURES
}
from
'
@/components/payment/providerConfig
'
import
{
METHOD_ORDER
,
getPaymentPopupFeatures
}
from
'
@/components/payment/providerConfig
'
import
{
import
{
PAYMENT_RECOVERY_STORAGE_KEY
,
PAYMENT_RECOVERY_STORAGE_KEY
,
buildCreateOrderPayload
,
buildCreateOrderPayload
,
...
@@ -630,8 +630,8 @@ async function createOrder(orderAmount: number, orderType: OrderType, planId?: n
...
@@ -630,8 +630,8 @@ async function createOrder(orderAmount: number, orderType: OrderType, planId?: n
payload
.
is_mobile
=
isMobileDevice
()
payload
.
is_mobile
=
isMobileDevice
()
const
result
=
await
paymentStore
.
createOrder
(
payload
)
as
CreateOrderResult
&
{
resume_token
?:
string
}
const
result
=
await
paymentStore
.
createOrder
(
payload
)
as
CreateOrderResult
&
{
resume_token
?:
string
}
const
openWindow
=
(
url
:
string
,
features
=
POPUP_WINDOW_FEATURES
)
=>
{
const
openWindow
=
(
url
:
string
)
=>
{
const
win
=
window
.
open
(
url
,
'
paymentPopup
'
,
f
eatures
)
const
win
=
window
.
open
(
url
,
'
paymentPopup
'
,
getPaymentPopupF
eatures
()
)
if
(
!
win
||
win
.
closed
)
{
if
(
!
win
||
win
.
closed
)
{
window
.
location
.
href
=
url
window
.
location
.
href
=
url
}
}
...
@@ -672,7 +672,7 @@ async function createOrder(orderAmount: number, orderType: OrderType, planId?: n
...
@@ -672,7 +672,7 @@ async function createOrder(orderAmount: number, orderType: OrderType, planId?: n
persistRecoverySnapshot
(
decision
.
recovery
)
persistRecoverySnapshot
(
decision
.
recovery
)
if
(
decision
.
kind
===
'
stripe_popup
'
)
{
if
(
decision
.
kind
===
'
stripe_popup
'
)
{
openWindow
(
decision
.
paymentState
.
payUrl
,
STRIPE_POPUP_WINDOW_FEATURES
)
openWindow
(
decision
.
paymentState
.
payUrl
)
return
return
}
}
if
(
decision
.
kind
===
'
stripe_route
'
)
{
if
(
decision
.
kind
===
'
stripe_route
'
)
{
...
@@ -710,8 +710,8 @@ async function createOrder(orderAmount: number, orderType: OrderType, planId?: n
...
@@ -710,8 +710,8 @@ async function createOrder(orderAmount: number, orderType: OrderType, planId?: n
err
,
err
,
normalizeVisibleMethod
(
options
.
paymentType
||
selectedMethod
.
value
)
||
selectedMethod
.
value
,
normalizeVisibleMethod
(
options
.
paymentType
||
selectedMethod
.
value
)
||
selectedMethod
.
value
,
)
)
if
(
!
errorMessage
.
value
)
{
if
(
!
handled
)
{
errorMessage
.
value
=
extractApiErrorMessage
(
err
,
t
(
'
payment.result.failed
'
))
errorMessage
.
value
=
extractI18nErrorMessage
(
err
,
t
,
'
payment.errors
'
,
extractApiErrorMessage
(
err
,
t
(
'
payment.result.failed
'
))
)
errorHintMessage
.
value
=
''
errorHintMessage
.
value
=
''
}
}
if
(
handled
)
{
if
(
handled
)
{
...
@@ -825,7 +825,7 @@ onMounted(async () => {
...
@@ -825,7 +825,7 @@ onMounted(async () => {
}
}
}
}
}
}
}
catch
(
err
:
unknown
)
{
appStore
.
showError
(
extract
Api
ErrorMessage
(
err
,
t
(
'
common.error
'
)))
}
}
catch
(
err
:
unknown
)
{
appStore
.
showError
(
extract
I18n
ErrorMessage
(
err
,
t
,
'
payment.errors
'
,
t
(
'
common.error
'
)))
}
finally
{
loading
.
value
=
false
}
finally
{
loading
.
value
=
false
}
// Fetch active subscriptions (uses cache, non-blocking)
// Fetch active subscriptions (uses cache, non-blocking)
subscriptionStore
.
fetchActiveSubscriptions
().
catch
(()
=>
{
}
)
subscriptionStore
.
fetchActiveSubscriptions
().
catch
(()
=>
{
}
)
...
...
frontend/src/views/user/StripePaymentView.vue
View file @
da1d2600
...
@@ -99,7 +99,7 @@ import { useI18n } from 'vue-i18n'
...
@@ -99,7 +99,7 @@ import { useI18n } from 'vue-i18n'
import
{
useRoute
,
useRouter
}
from
'
vue-router
'
import
{
useRoute
,
useRouter
}
from
'
vue-router
'
import
{
usePaymentStore
}
from
'
@/stores/payment
'
import
{
usePaymentStore
}
from
'
@/stores/payment
'
import
{
paymentAPI
}
from
'
@/api/payment
'
import
{
paymentAPI
}
from
'
@/api/payment
'
import
{
extract
Api
ErrorMessage
}
from
'
@/utils/apiError
'
import
{
extract
I18n
ErrorMessage
}
from
'
@/utils/apiError
'
import
{
isMobileDevice
}
from
'
@/utils/device
'
import
{
isMobileDevice
}
from
'
@/utils/device
'
import
type
{
PaymentOrder
}
from
'
@/types/payment
'
import
type
{
PaymentOrder
}
from
'
@/types/payment
'
import
type
{
Stripe
,
StripeElements
}
from
'
@stripe/stripe-js
'
import
type
{
Stripe
,
StripeElements
}
from
'
@stripe/stripe-js
'
...
@@ -167,7 +167,7 @@ onMounted(async () => {
...
@@ -167,7 +167,7 @@ onMounted(async () => {
mountPaymentElement
(
stripe
,
clientSecret
)
mountPaymentElement
(
stripe
,
clientSecret
)
}
}
}
catch
(
err
:
unknown
)
{
}
catch
(
err
:
unknown
)
{
initError
.
value
=
extract
Api
ErrorMessage
(
err
,
t
(
'
payment.stripeLoadFailed
'
))
initError
.
value
=
extract
I18n
ErrorMessage
(
err
,
t
,
'
payment.errors
'
,
t
(
'
payment.stripeLoadFailed
'
))
}
finally
{
}
finally
{
loading
.
value
=
false
loading
.
value
=
false
}
}
...
@@ -248,7 +248,7 @@ async function handleGenericPay() {
...
@@ -248,7 +248,7 @@ async function handleGenericPay() {
scheduleClose
()
scheduleClose
()
}
}
}
catch
(
err
:
unknown
)
{
}
catch
(
err
:
unknown
)
{
stripeError
.
value
=
extract
Api
ErrorMessage
(
err
,
t
(
'
payment.result.failed
'
))
stripeError
.
value
=
extract
I18n
ErrorMessage
(
err
,
t
,
'
payment.errors
'
,
t
(
'
payment.result.failed
'
))
}
finally
{
}
finally
{
stripeSubmitting
.
value
=
false
stripeSubmitting
.
value
=
false
}
}
...
...
frontend/src/views/user/StripePopupView.vue
View file @
da1d2600
...
@@ -56,7 +56,7 @@
...
@@ -56,7 +56,7 @@
import
{
computed
,
ref
,
onMounted
,
onUnmounted
}
from
'
vue
'
import
{
computed
,
ref
,
onMounted
,
onUnmounted
}
from
'
vue
'
import
{
useI18n
}
from
'
vue-i18n
'
import
{
useI18n
}
from
'
vue-i18n
'
import
{
useRoute
}
from
'
vue-router
'
import
{
useRoute
}
from
'
vue-router
'
import
{
extract
Api
ErrorMessage
}
from
'
@/utils/apiError
'
import
{
extract
I18n
ErrorMessage
}
from
'
@/utils/apiError
'
import
{
isMobileDevice
}
from
'
@/utils/device
'
import
{
isMobileDevice
}
from
'
@/utils/device
'
interface
StripeWithWechatPay
{
interface
StripeWithWechatPay
{
...
@@ -143,7 +143,7 @@ async function initStripe(clientSecret: string, publishableKey: string) {
...
@@ -143,7 +143,7 @@ async function initStripe(clientSecret: string, publishableKey: string) {
}
}
}
}
}
catch
(
err
:
unknown
)
{
}
catch
(
err
:
unknown
)
{
error
.
value
=
extract
Api
ErrorMessage
(
err
,
t
(
'
payment.stripeLoadFailed
'
))
error
.
value
=
extract
I18n
ErrorMessage
(
err
,
t
,
'
payment.errors
'
,
t
(
'
payment.stripeLoadFailed
'
))
}
}
}
}
...
...
frontend/src/views/user/UserOrdersView.vue
View file @
da1d2600
...
@@ -86,7 +86,7 @@ import { useI18n } from 'vue-i18n'
...
@@ -86,7 +86,7 @@ import { useI18n } from 'vue-i18n'
import
{
useRouter
}
from
'
vue-router
'
import
{
useRouter
}
from
'
vue-router
'
import
{
useAppStore
}
from
'
@/stores
'
import
{
useAppStore
}
from
'
@/stores
'
import
{
paymentAPI
}
from
'
@/api/payment
'
import
{
paymentAPI
}
from
'
@/api/payment
'
import
{
extract
Api
ErrorMessage
}
from
'
@/utils/apiError
'
import
{
extract
I18n
ErrorMessage
}
from
'
@/utils/apiError
'
import
type
{
PaymentOrder
}
from
'
@/types/payment
'
import
type
{
PaymentOrder
}
from
'
@/types/payment
'
import
AppLayout
from
'
@/components/layout/AppLayout.vue
'
import
AppLayout
from
'
@/components/layout/AppLayout.vue
'
import
Pagination
from
'
@/components/common/Pagination.vue
'
import
Pagination
from
'
@/components/common/Pagination.vue
'
...
@@ -128,7 +128,7 @@ async function fetchOrders() {
...
@@ -128,7 +128,7 @@ async function fetchOrders() {
orders
.
value
=
res
.
data
.
items
||
[]
orders
.
value
=
res
.
data
.
items
||
[]
pagination
.
total
=
res
.
data
.
total
||
0
pagination
.
total
=
res
.
data
.
total
||
0
}
catch
(
err
:
unknown
)
{
}
catch
(
err
:
unknown
)
{
appStore
.
showError
(
extract
Api
ErrorMessage
(
err
,
t
(
'
common.error
'
)))
appStore
.
showError
(
extract
I18n
ErrorMessage
(
err
,
t
,
'
payment.errors
'
,
t
(
'
common.error
'
)))
}
finally
{
}
finally
{
loading
.
value
=
false
loading
.
value
=
false
}
}
...
@@ -148,7 +148,7 @@ async function confirmCancel() {
...
@@ -148,7 +148,7 @@ async function confirmCancel() {
cancelTargetId
.
value
=
null
cancelTargetId
.
value
=
null
await
fetchOrders
()
await
fetchOrders
()
}
catch
(
err
:
unknown
)
{
}
catch
(
err
:
unknown
)
{
appStore
.
showError
(
extract
Api
ErrorMessage
(
err
,
t
(
'
common.error
'
)))
appStore
.
showError
(
extract
I18n
ErrorMessage
(
err
,
t
,
'
payment.errors
'
,
t
(
'
common.error
'
)))
}
finally
{
}
finally
{
actionLoading
.
value
=
false
actionLoading
.
value
=
false
}
}
...
@@ -166,7 +166,7 @@ async function confirmRefund() {
...
@@ -166,7 +166,7 @@ async function confirmRefund() {
refundReason
.
value
=
''
refundReason
.
value
=
''
await
fetchOrders
()
await
fetchOrders
()
}
catch
(
err
:
unknown
)
{
}
catch
(
err
:
unknown
)
{
appStore
.
showError
(
extract
Api
ErrorMessage
(
err
,
t
(
'
common.error
'
)))
appStore
.
showError
(
extract
I18n
ErrorMessage
(
err
,
t
,
'
payment.errors
'
,
t
(
'
common.error
'
)))
}
finally
{
}
finally
{
actionLoading
.
value
=
false
actionLoading
.
value
=
false
}
}
...
...
Prev
1
2
3
4
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment