修复环境变量问题
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
# 开发环境配置
|
# 开发环境配置
|
||||||
NEXT_PUBLIC_API_BASE_URL=http://192.168.3.42:8080
|
API_BASE_URL=http://192.168.3.42:8080
|
||||||
CLIENT_ID=web
|
CLIENT_ID=web
|
||||||
CLIENT_SECRET=web
|
CLIENT_SECRET=web
|
||||||
|
|||||||
2
.github/copilot-instructions.md
vendored
2
.github/copilot-instructions.md
vendored
@@ -122,7 +122,7 @@ type UserProfile = ExtraResp<typeof getProfile>
|
|||||||
## 环境变量
|
## 环境变量
|
||||||
|
|
||||||
需要配置:
|
需要配置:
|
||||||
- `NEXT_PUBLIC_API_BASE_URL` - 后端 API 地址
|
- `API_BASE_URL` - 后端 API 地址
|
||||||
- `CLIENT_ID`, `CLIENT_SECRET` - OAuth2 设备认证凭据
|
- `CLIENT_ID`, `CLIENT_SECRET` - OAuth2 设备认证凭据
|
||||||
|
|
||||||
## 部署
|
## 部署
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ RUN adduser --system --uid 1001 nextjs
|
|||||||
COPY --from=builder /app/public ./public
|
COPY --from=builder /app/public ./public
|
||||||
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
|
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
|
||||||
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
|
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
|
||||||
|
RUN rm .env
|
||||||
|
|
||||||
USER nextjs
|
USER nextjs
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,13 @@ export type TokenResp = {
|
|||||||
scope?: string
|
scope?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function getApiUrl() {
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
data: API_BASE_URL,
|
||||||
|
} satisfies ApiResponse<string>
|
||||||
|
}
|
||||||
|
|
||||||
// ======================
|
// ======================
|
||||||
// public
|
// public
|
||||||
// ======================
|
// ======================
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ import {LayoutStoreProvider} from '@/components/stores/layout'
|
|||||||
import {ClientStoreProvider} from '@/components/stores/client'
|
import {ClientStoreProvider} from '@/components/stores/client'
|
||||||
import {getProfile} from '@/actions/auth'
|
import {getProfile} from '@/actions/auth'
|
||||||
import Script from 'next/script'
|
import Script from 'next/script'
|
||||||
|
import {AppStoreProvider} from '@/components/stores/app'
|
||||||
|
import {getApiUrl} from '@/actions/base'
|
||||||
|
|
||||||
export async function generateMetadata(): Promise<Metadata> {
|
export async function generateMetadata(): Promise<Metadata> {
|
||||||
return {
|
return {
|
||||||
@@ -30,12 +32,14 @@ export default async function RootLayout(props: Readonly<{
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function StoreProviders(props: {children: ReactNode}) {
|
async function StoreProviders(props: {children: ReactNode}) {
|
||||||
return (
|
return (
|
||||||
<ProfileStoreProvider profile={getProfile().then(resp => resp.success ? resp.data : null)}>
|
<ProfileStoreProvider profile={getProfile().then(resp => resp.success ? resp.data : null)}>
|
||||||
<LayoutStoreProvider>
|
<LayoutStoreProvider>
|
||||||
<ClientStoreProvider>
|
<ClientStoreProvider>
|
||||||
{props.children}
|
<AppStoreProvider url={await getApiUrl().then(r => r.data)}>
|
||||||
|
{props.children}
|
||||||
|
</AppStoreProvider>
|
||||||
</ClientStoreProvider>
|
</ClientStoreProvider>
|
||||||
</LayoutStoreProvider>
|
</LayoutStoreProvider>
|
||||||
</ProfileStoreProvider>
|
</ProfileStoreProvider>
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import {PaymentProps} from './type'
|
|||||||
import {payClose} from '@/actions/resource'
|
import {payClose} from '@/actions/resource'
|
||||||
import {useEffect} from 'react'
|
import {useEffect} from 'react'
|
||||||
import {UniversalDesktopPayment} from './universal-desktop-payment'
|
import {UniversalDesktopPayment} from './universal-desktop-payment'
|
||||||
|
import {useAppStore} from '@/components/stores/app'
|
||||||
|
|
||||||
export type PaymentModalProps = {
|
export type PaymentModalProps = {
|
||||||
onConfirm: (showFail: boolean) => Promise<void>
|
onConfirm: (showFail: boolean) => Promise<void>
|
||||||
@@ -34,9 +35,10 @@ export function PaymentModal(props: PaymentModalProps) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SSE处理方式检查支付状态
|
// SSE处理方式检查支付状态
|
||||||
|
const apiUrl = useAppStore('apiUrl')
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const eventSource = new EventSource(
|
const eventSource = new EventSource(
|
||||||
`${process.env.NEXT_PUBLIC_API_BASE_URL}/api/trade/check?trade_no=${props.inner_no}&method=${props.method}`,
|
`${apiUrl}/api/trade/check?trade_no=${props.inner_no}&method=${props.method}`,
|
||||||
)
|
)
|
||||||
eventSource.onmessage = async (event) => {
|
eventSource.onmessage = async (event) => {
|
||||||
switch (event.data) {
|
switch (event.data) {
|
||||||
@@ -53,7 +55,7 @@ export function PaymentModal(props: PaymentModalProps) {
|
|||||||
return () => {
|
return () => {
|
||||||
eventSource.close()
|
eventSource.close()
|
||||||
}
|
}
|
||||||
}, [props])
|
}, [apiUrl, props])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog
|
<Dialog
|
||||||
|
|||||||
38
src/components/stores/app.tsx
Normal file
38
src/components/stores/app.tsx
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
'use client'
|
||||||
|
import {createStore, StoreApi} from 'zustand/vanilla'
|
||||||
|
import {createContext, ReactNode, useContext, useState} from 'react'
|
||||||
|
import {useStore} from 'zustand/react'
|
||||||
|
|
||||||
|
// store
|
||||||
|
type AppStoreState = {
|
||||||
|
apiUrl: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createAppStore(url: string) {
|
||||||
|
return createStore<AppStoreState>()(() => ({
|
||||||
|
apiUrl: url,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
// provider
|
||||||
|
const AppStoreContext = createContext<StoreApi<AppStoreState> | null>(null)
|
||||||
|
|
||||||
|
export function AppStoreProvider(props: {
|
||||||
|
url: string
|
||||||
|
children: ReactNode
|
||||||
|
}) {
|
||||||
|
const [store] = useState(() => createAppStore(props.url))
|
||||||
|
return (
|
||||||
|
<AppStoreContext.Provider value={store}>
|
||||||
|
{props.children}
|
||||||
|
</AppStoreContext.Provider>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useAppStore(name: keyof AppStoreState) {
|
||||||
|
const context = useContext(AppStoreContext)
|
||||||
|
if (!context) {
|
||||||
|
throw new Error('AppStoreContext 没有正确初始化')
|
||||||
|
}
|
||||||
|
return useStore(context, c => c[name])
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
// 定义后端服务URL和OAuth2配置
|
// 定义后端服务URL和OAuth2配置
|
||||||
const _api_base_url = process.env.NEXT_PUBLIC_API_BASE_URL
|
const _api_base_url = process.env.API_BASE_URL
|
||||||
if (!_api_base_url) throw new Error('NEXT_PUBLIC_API_BASE_URL is not set')
|
if (!_api_base_url) throw new Error('API_BASE_URL is not set')
|
||||||
const API_BASE_URL = _api_base_url
|
const API_BASE_URL = _api_base_url
|
||||||
|
|
||||||
const _client_id = process.env.CLIENT_ID
|
const _client_id = process.env.CLIENT_ID
|
||||||
|
|||||||
Reference in New Issue
Block a user