mirror of
https://github.com/langgenius/dify.git
synced 2026-02-19 01:14:44 +08:00
refactor(contract): restructure console contracts with nested billing module (#30999)
This commit is contained in:
parent
328897f81c
commit
3bee2ee067
@ -27,7 +27,9 @@ vi.mock('@/service/billing', () => ({
|
|||||||
|
|
||||||
vi.mock('@/service/client', () => ({
|
vi.mock('@/service/client', () => ({
|
||||||
consoleClient: {
|
consoleClient: {
|
||||||
billingUrl: vi.fn(),
|
billing: {
|
||||||
|
invoices: vi.fn(),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}))
|
}))
|
||||||
|
|
||||||
@ -43,7 +45,7 @@ vi.mock('../../assets', () => ({
|
|||||||
|
|
||||||
const mockUseAppContext = useAppContext as Mock
|
const mockUseAppContext = useAppContext as Mock
|
||||||
const mockUseAsyncWindowOpen = useAsyncWindowOpen as Mock
|
const mockUseAsyncWindowOpen = useAsyncWindowOpen as Mock
|
||||||
const mockBillingUrl = consoleClient.billingUrl as Mock
|
const mockBillingInvoices = consoleClient.billing.invoices as Mock
|
||||||
const mockFetchSubscriptionUrls = fetchSubscriptionUrls as Mock
|
const mockFetchSubscriptionUrls = fetchSubscriptionUrls as Mock
|
||||||
const mockToastNotify = Toast.notify as Mock
|
const mockToastNotify = Toast.notify as Mock
|
||||||
|
|
||||||
@ -75,7 +77,7 @@ beforeEach(() => {
|
|||||||
vi.clearAllMocks()
|
vi.clearAllMocks()
|
||||||
mockUseAppContext.mockReturnValue({ isCurrentWorkspaceManager: true })
|
mockUseAppContext.mockReturnValue({ isCurrentWorkspaceManager: true })
|
||||||
mockUseAsyncWindowOpen.mockReturnValue(vi.fn(async open => await open()))
|
mockUseAsyncWindowOpen.mockReturnValue(vi.fn(async open => await open()))
|
||||||
mockBillingUrl.mockResolvedValue({ url: 'https://billing.example' })
|
mockBillingInvoices.mockResolvedValue({ url: 'https://billing.example' })
|
||||||
mockFetchSubscriptionUrls.mockResolvedValue({ url: 'https://subscription.example' })
|
mockFetchSubscriptionUrls.mockResolvedValue({ url: 'https://subscription.example' })
|
||||||
assignedHref = ''
|
assignedHref = ''
|
||||||
})
|
})
|
||||||
@ -149,7 +151,7 @@ describe('CloudPlanItem', () => {
|
|||||||
type: 'error',
|
type: 'error',
|
||||||
message: 'billing.buyPermissionDeniedTip',
|
message: 'billing.buyPermissionDeniedTip',
|
||||||
}))
|
}))
|
||||||
expect(mockBillingUrl).not.toHaveBeenCalled()
|
expect(mockBillingInvoices).not.toHaveBeenCalled()
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should open billing portal when upgrading current paid plan', async () => {
|
it('should open billing portal when upgrading current paid plan', async () => {
|
||||||
@ -168,7 +170,7 @@ describe('CloudPlanItem', () => {
|
|||||||
fireEvent.click(screen.getByRole('button', { name: 'billing.plansCommon.currentPlan' }))
|
fireEvent.click(screen.getByRole('button', { name: 'billing.plansCommon.currentPlan' }))
|
||||||
|
|
||||||
await waitFor(() => {
|
await waitFor(() => {
|
||||||
expect(mockBillingUrl).toHaveBeenCalledTimes(1)
|
expect(mockBillingInvoices).toHaveBeenCalledTimes(1)
|
||||||
})
|
})
|
||||||
expect(openWindow).toHaveBeenCalledTimes(1)
|
expect(openWindow).toHaveBeenCalledTimes(1)
|
||||||
})
|
})
|
||||||
|
|||||||
@ -77,7 +77,7 @@ const CloudPlanItem: FC<CloudPlanItemProps> = ({
|
|||||||
try {
|
try {
|
||||||
if (isCurrentPaidPlan) {
|
if (isCurrentPaidPlan) {
|
||||||
await openAsyncWindow(async () => {
|
await openAsyncWindow(async () => {
|
||||||
const res = await consoleClient.billingUrl()
|
const res = await consoleClient.billing.invoices()
|
||||||
if (res.url)
|
if (res.url)
|
||||||
return res.url
|
return res.url
|
||||||
throw new Error('Failed to open billing page')
|
throw new Error('Failed to open billing page')
|
||||||
|
|||||||
@ -1,16 +1,7 @@
|
|||||||
import type { SystemFeatures } from '@/types/feature'
|
|
||||||
import { type } from '@orpc/contract'
|
import { type } from '@orpc/contract'
|
||||||
import { base } from './base'
|
import { base } from '../base'
|
||||||
|
|
||||||
export const systemFeaturesContract = base
|
export const invoicesContract = base
|
||||||
.route({
|
|
||||||
path: '/system-features',
|
|
||||||
method: 'GET',
|
|
||||||
})
|
|
||||||
.input(type<unknown>())
|
|
||||||
.output(type<SystemFeatures>())
|
|
||||||
|
|
||||||
export const billingUrlContract = base
|
|
||||||
.route({
|
.route({
|
||||||
path: '/billing/invoices',
|
path: '/billing/invoices',
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
11
web/contract/console/system.ts
Normal file
11
web/contract/console/system.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import type { SystemFeatures } from '@/types/feature'
|
||||||
|
import { type } from '@orpc/contract'
|
||||||
|
import { base } from '../base'
|
||||||
|
|
||||||
|
export const systemFeaturesContract = base
|
||||||
|
.route({
|
||||||
|
path: '/system-features',
|
||||||
|
method: 'GET',
|
||||||
|
})
|
||||||
|
.input(type<unknown>())
|
||||||
|
.output(type<SystemFeatures>())
|
||||||
@ -1,5 +1,6 @@
|
|||||||
import type { InferContractRouterInputs } from '@orpc/contract'
|
import type { InferContractRouterInputs } from '@orpc/contract'
|
||||||
import { billingUrlContract, bindPartnerStackContract, systemFeaturesContract } from './console'
|
import { bindPartnerStackContract, invoicesContract } from './console/billing'
|
||||||
|
import { systemFeaturesContract } from './console/system'
|
||||||
import { collectionPluginsContract, collectionsContract, searchAdvancedContract } from './marketplace'
|
import { collectionPluginsContract, collectionsContract, searchAdvancedContract } from './marketplace'
|
||||||
|
|
||||||
export const marketplaceRouterContract = {
|
export const marketplaceRouterContract = {
|
||||||
@ -12,8 +13,10 @@ export type MarketPlaceInputs = InferContractRouterInputs<typeof marketplaceRout
|
|||||||
|
|
||||||
export const consoleRouterContract = {
|
export const consoleRouterContract = {
|
||||||
systemFeatures: systemFeaturesContract,
|
systemFeatures: systemFeaturesContract,
|
||||||
billingUrl: billingUrlContract,
|
billing: {
|
||||||
bindPartnerStack: bindPartnerStackContract,
|
invoices: invoicesContract,
|
||||||
|
bindPartnerStack: bindPartnerStackContract,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ConsoleInputs = InferContractRouterInputs<typeof consoleRouterContract>
|
export type ConsoleInputs = InferContractRouterInputs<typeof consoleRouterContract>
|
||||||
|
|||||||
@ -3,8 +3,8 @@ import { consoleClient, consoleQuery } from '@/service/client'
|
|||||||
|
|
||||||
export const useBindPartnerStackInfo = () => {
|
export const useBindPartnerStackInfo = () => {
|
||||||
return useMutation({
|
return useMutation({
|
||||||
mutationKey: consoleQuery.bindPartnerStack.mutationKey(),
|
mutationKey: consoleQuery.billing.bindPartnerStack.mutationKey(),
|
||||||
mutationFn: (data: { partnerKey: string, clickId: string }) => consoleClient.bindPartnerStack({
|
mutationFn: (data: { partnerKey: string, clickId: string }) => consoleClient.billing.bindPartnerStack({
|
||||||
params: { partnerKey: data.partnerKey },
|
params: { partnerKey: data.partnerKey },
|
||||||
body: { click_id: data.clickId },
|
body: { click_id: data.clickId },
|
||||||
}),
|
}),
|
||||||
@ -13,10 +13,10 @@ export const useBindPartnerStackInfo = () => {
|
|||||||
|
|
||||||
export const useBillingUrl = (enabled: boolean) => {
|
export const useBillingUrl = (enabled: boolean) => {
|
||||||
return useQuery({
|
return useQuery({
|
||||||
queryKey: consoleQuery.billingUrl.queryKey(),
|
queryKey: consoleQuery.billing.invoices.queryKey(),
|
||||||
enabled,
|
enabled,
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await consoleClient.billingUrl()
|
const res = await consoleClient.billing.invoices()
|
||||||
return res.url
|
return res.url
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user