重构项目结构,将数据层集中在 lib 包中;resource 类型更新,支持多个子套餐类型分别表示;新增长效套餐的购买流程,以及已购查询功能
This commit is contained in:
@@ -21,7 +21,8 @@ type PageRecord<T = unknown> = {
|
||||
list: T[]
|
||||
}
|
||||
|
||||
type ExtractData<T extends (...args: never) => unknown> = Awaited<ReturnType<T>> extends ApiResponse<infer D> ? D : never
|
||||
type ExtraReq<T extends (...args: never) => unknown> = T extends (...args: infer P) => unknown ? P[0] : never
|
||||
type ExtraResp<T extends (...args: never) => unknown> = Awaited<ReturnType<T>> extends ApiResponse<infer D> ? D : never
|
||||
|
||||
// 预定义错误
|
||||
const UnauthorizedError = new Error('未授权访问')
|
||||
@@ -32,6 +33,7 @@ export {
|
||||
CLIENT_SECRET,
|
||||
type ApiResponse,
|
||||
type PageRecord,
|
||||
type ExtractData,
|
||||
type ExtraReq,
|
||||
type ExtraResp,
|
||||
UnauthorizedError,
|
||||
}
|
||||
|
||||
2
src/lib/models/index.ts
Normal file
2
src/lib/models/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export * from './models'
|
||||
export * from './resource'
|
||||
@@ -1,3 +1,5 @@
|
||||
import {Resource} from '@/lib/models'
|
||||
|
||||
export type User = {
|
||||
id: number
|
||||
admin_id: number
|
||||
@@ -20,45 +22,6 @@ export type User = {
|
||||
updated_at: Date
|
||||
}
|
||||
|
||||
export type Resource = {
|
||||
id: number
|
||||
user_id: number
|
||||
resource_no: string
|
||||
active: boolean
|
||||
type: number
|
||||
created_at: Date
|
||||
updated_at: Date
|
||||
short: ResourceShort
|
||||
}
|
||||
|
||||
export function name(obj: Resource) {
|
||||
switch (obj.type) {
|
||||
case 1:
|
||||
switch (obj.short.type) {
|
||||
case 1:
|
||||
return `包时 ${obj.short.live / 60}分钟`
|
||||
case 2:
|
||||
return `包量 ${obj.short.live / 60}分钟`
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
export type ResourceShort = {
|
||||
id: number
|
||||
resource_id: number
|
||||
type: number
|
||||
live: number
|
||||
expire: Date
|
||||
quota: number
|
||||
used: number
|
||||
daily_limit: number
|
||||
daily_used: number
|
||||
daily_last: Date
|
||||
created_at: Date
|
||||
updated_at: Date
|
||||
}
|
||||
|
||||
export type Bill = {
|
||||
id: number
|
||||
user_id: number
|
||||
47
src/lib/models/resource.ts
Normal file
47
src/lib/models/resource.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
type ResourceShort = {
|
||||
id: number
|
||||
resource_id: number
|
||||
type: number
|
||||
live: number
|
||||
expire: Date
|
||||
quota: number
|
||||
used: number
|
||||
daily_limit: number
|
||||
daily_used: number
|
||||
daily_last: Date
|
||||
created_at: Date
|
||||
updated_at: Date
|
||||
}
|
||||
|
||||
type ResourceLong = {
|
||||
id: number
|
||||
resource_id: number
|
||||
type: number
|
||||
live: number
|
||||
expire: Date
|
||||
quota: number
|
||||
used: number
|
||||
daily_limit: number
|
||||
daily_used: number
|
||||
daily_last: Date
|
||||
created_at: Date
|
||||
updated_at: Date
|
||||
}
|
||||
|
||||
export type Resource<T extends 1 | 2 = 1 | 2> = {
|
||||
id: number
|
||||
user_id: number
|
||||
resource_no: string
|
||||
active: boolean
|
||||
created_at: Date
|
||||
updated_at: Date
|
||||
} & (
|
||||
T extends 1 ? {
|
||||
type: 1
|
||||
short: ResourceShort
|
||||
} :
|
||||
T extends 2 ? {
|
||||
type: 2
|
||||
long: ResourceLong
|
||||
} : {}
|
||||
)
|
||||
24
src/lib/stores/layout.ts
Normal file
24
src/lib/stores/layout.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import {createStore} from 'zustand/vanilla'
|
||||
|
||||
export type LayoutStore = LayoutState & LayoutActions
|
||||
|
||||
export type LayoutState = {
|
||||
navbar: boolean
|
||||
}
|
||||
|
||||
export type LayoutActions = {
|
||||
toggleNavbar: () => void
|
||||
setNavbar: (navbar: boolean) => void
|
||||
}
|
||||
|
||||
export const createLayoutStore = () => {
|
||||
return createStore<LayoutStore>()(setState => ({
|
||||
navbar: true,
|
||||
toggleNavbar: () => setState(state => {
|
||||
return {navbar: !state.navbar}
|
||||
}),
|
||||
setNavbar: (navbar) => setState(_ => {
|
||||
return {navbar}
|
||||
}),
|
||||
}))
|
||||
}
|
||||
26
src/lib/stores/profile.ts
Normal file
26
src/lib/stores/profile.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import {User} from '@/lib/models'
|
||||
import {createStore} from 'zustand/vanilla'
|
||||
import {getProfile} from '@/actions/auth'
|
||||
|
||||
|
||||
export type ProfileStore = ProfileState & ProfileActions
|
||||
|
||||
export type ProfileState = {
|
||||
profile: User | null
|
||||
}
|
||||
|
||||
export type ProfileActions = {
|
||||
refreshProfile: () => Promise<void>
|
||||
}
|
||||
|
||||
export const createProfileStore = (init: User|null) => {
|
||||
return createStore<ProfileStore>()(setState => ({
|
||||
profile: init,
|
||||
refreshProfile: async () => {
|
||||
const profile = await getProfile()
|
||||
if (!profile.success) return
|
||||
setState({profile: profile.data})
|
||||
},
|
||||
}))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user