数据源修改
This commit is contained in:
parent
b10b1c44db
commit
ec15f40323
@ -37,6 +37,11 @@ export type Strategy = Prisma.StrategyModel
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
export type Indicator = Prisma.IndicatorModel
|
export type Indicator = Prisma.IndicatorModel
|
||||||
|
/**
|
||||||
|
* Model IndicatorPoint
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export type IndicatorPoint = Prisma.IndicatorPointModel
|
||||||
/**
|
/**
|
||||||
* Model Econ_SowInventory
|
* Model Econ_SowInventory
|
||||||
*
|
*
|
||||||
|
|||||||
@ -61,6 +61,11 @@ export type Strategy = Prisma.StrategyModel
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
export type Indicator = Prisma.IndicatorModel
|
export type Indicator = Prisma.IndicatorModel
|
||||||
|
/**
|
||||||
|
* Model IndicatorPoint
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export type IndicatorPoint = Prisma.IndicatorPointModel
|
||||||
/**
|
/**
|
||||||
* Model Econ_SowInventory
|
* Model Econ_SowInventory
|
||||||
*
|
*
|
||||||
|
|||||||
@ -150,6 +150,46 @@ export type JsonWithAggregatesFilterBase<$PrismaModel = never> = {
|
|||||||
_max?: Prisma.NestedJsonFilter<$PrismaModel>
|
_max?: Prisma.NestedJsonFilter<$PrismaModel>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type BoolFilter<$PrismaModel = never> = {
|
||||||
|
equals?: boolean | Prisma.BooleanFieldRefInput<$PrismaModel>
|
||||||
|
not?: Prisma.NestedBoolFilter<$PrismaModel> | boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export type BoolWithAggregatesFilter<$PrismaModel = never> = {
|
||||||
|
equals?: boolean | Prisma.BooleanFieldRefInput<$PrismaModel>
|
||||||
|
not?: Prisma.NestedBoolWithAggregatesFilter<$PrismaModel> | boolean
|
||||||
|
_count?: Prisma.NestedIntFilter<$PrismaModel>
|
||||||
|
_min?: Prisma.NestedBoolFilter<$PrismaModel>
|
||||||
|
_max?: Prisma.NestedBoolFilter<$PrismaModel>
|
||||||
|
}
|
||||||
|
|
||||||
|
export type FloatFilter<$PrismaModel = never> = {
|
||||||
|
equals?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||||
|
in?: number[]
|
||||||
|
notIn?: number[]
|
||||||
|
lt?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||||
|
lte?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||||
|
gt?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||||
|
gte?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||||
|
not?: Prisma.NestedFloatFilter<$PrismaModel> | number
|
||||||
|
}
|
||||||
|
|
||||||
|
export type FloatWithAggregatesFilter<$PrismaModel = never> = {
|
||||||
|
equals?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||||
|
in?: number[]
|
||||||
|
notIn?: number[]
|
||||||
|
lt?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||||
|
lte?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||||
|
gt?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||||
|
gte?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||||
|
not?: Prisma.NestedFloatWithAggregatesFilter<$PrismaModel> | number
|
||||||
|
_count?: Prisma.NestedIntFilter<$PrismaModel>
|
||||||
|
_avg?: Prisma.NestedFloatFilter<$PrismaModel>
|
||||||
|
_sum?: Prisma.NestedFloatFilter<$PrismaModel>
|
||||||
|
_min?: Prisma.NestedFloatFilter<$PrismaModel>
|
||||||
|
_max?: Prisma.NestedFloatFilter<$PrismaModel>
|
||||||
|
}
|
||||||
|
|
||||||
export type StringNullableFilter<$PrismaModel = never> = {
|
export type StringNullableFilter<$PrismaModel = never> = {
|
||||||
equals?: string | Prisma.StringFieldRefInput<$PrismaModel> | null
|
equals?: string | Prisma.StringFieldRefInput<$PrismaModel> | null
|
||||||
in?: string[] | null
|
in?: string[] | null
|
||||||
@ -359,6 +399,35 @@ export type NestedJsonFilterBase<$PrismaModel = never> = {
|
|||||||
not?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | Prisma.JsonNullValueFilter
|
not?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | Prisma.JsonNullValueFilter
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type NestedBoolFilter<$PrismaModel = never> = {
|
||||||
|
equals?: boolean | Prisma.BooleanFieldRefInput<$PrismaModel>
|
||||||
|
not?: Prisma.NestedBoolFilter<$PrismaModel> | boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export type NestedBoolWithAggregatesFilter<$PrismaModel = never> = {
|
||||||
|
equals?: boolean | Prisma.BooleanFieldRefInput<$PrismaModel>
|
||||||
|
not?: Prisma.NestedBoolWithAggregatesFilter<$PrismaModel> | boolean
|
||||||
|
_count?: Prisma.NestedIntFilter<$PrismaModel>
|
||||||
|
_min?: Prisma.NestedBoolFilter<$PrismaModel>
|
||||||
|
_max?: Prisma.NestedBoolFilter<$PrismaModel>
|
||||||
|
}
|
||||||
|
|
||||||
|
export type NestedFloatWithAggregatesFilter<$PrismaModel = never> = {
|
||||||
|
equals?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||||
|
in?: number[]
|
||||||
|
notIn?: number[]
|
||||||
|
lt?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||||
|
lte?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||||
|
gt?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||||
|
gte?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||||
|
not?: Prisma.NestedFloatWithAggregatesFilter<$PrismaModel> | number
|
||||||
|
_count?: Prisma.NestedIntFilter<$PrismaModel>
|
||||||
|
_avg?: Prisma.NestedFloatFilter<$PrismaModel>
|
||||||
|
_sum?: Prisma.NestedFloatFilter<$PrismaModel>
|
||||||
|
_min?: Prisma.NestedFloatFilter<$PrismaModel>
|
||||||
|
_max?: Prisma.NestedFloatFilter<$PrismaModel>
|
||||||
|
}
|
||||||
|
|
||||||
export type NestedStringNullableFilter<$PrismaModel = never> = {
|
export type NestedStringNullableFilter<$PrismaModel = never> = {
|
||||||
equals?: string | Prisma.StringFieldRefInput<$PrismaModel> | null
|
equals?: string | Prisma.StringFieldRefInput<$PrismaModel> | null
|
||||||
in?: string[] | null
|
in?: string[] | null
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@ -388,6 +388,7 @@ export const ModelName = {
|
|||||||
Article: 'Article',
|
Article: 'Article',
|
||||||
Strategy: 'Strategy',
|
Strategy: 'Strategy',
|
||||||
Indicator: 'Indicator',
|
Indicator: 'Indicator',
|
||||||
|
IndicatorPoint: 'IndicatorPoint',
|
||||||
Econ_SowInventory: 'Econ_SowInventory',
|
Econ_SowInventory: 'Econ_SowInventory',
|
||||||
ScraperCache: 'ScraperCache'
|
ScraperCache: 'ScraperCache'
|
||||||
} as const
|
} as const
|
||||||
@ -405,7 +406,7 @@ export type TypeMap<ExtArgs extends runtime.Types.Extensions.InternalArgs = runt
|
|||||||
omit: GlobalOmitOptions
|
omit: GlobalOmitOptions
|
||||||
}
|
}
|
||||||
meta: {
|
meta: {
|
||||||
modelProps: "user" | "article" | "strategy" | "indicator" | "econ_SowInventory" | "scraperCache"
|
modelProps: "user" | "article" | "strategy" | "indicator" | "indicatorPoint" | "econ_SowInventory" | "scraperCache"
|
||||||
txIsolationLevel: TransactionIsolationLevel
|
txIsolationLevel: TransactionIsolationLevel
|
||||||
}
|
}
|
||||||
model: {
|
model: {
|
||||||
@ -673,6 +674,72 @@ export type TypeMap<ExtArgs extends runtime.Types.Extensions.InternalArgs = runt
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
IndicatorPoint: {
|
||||||
|
payload: Prisma.$IndicatorPointPayload<ExtArgs>
|
||||||
|
fields: Prisma.IndicatorPointFieldRefs
|
||||||
|
operations: {
|
||||||
|
findUnique: {
|
||||||
|
args: Prisma.IndicatorPointFindUniqueArgs<ExtArgs>
|
||||||
|
result: runtime.Types.Utils.PayloadToResult<Prisma.$IndicatorPointPayload> | null
|
||||||
|
}
|
||||||
|
findUniqueOrThrow: {
|
||||||
|
args: Prisma.IndicatorPointFindUniqueOrThrowArgs<ExtArgs>
|
||||||
|
result: runtime.Types.Utils.PayloadToResult<Prisma.$IndicatorPointPayload>
|
||||||
|
}
|
||||||
|
findFirst: {
|
||||||
|
args: Prisma.IndicatorPointFindFirstArgs<ExtArgs>
|
||||||
|
result: runtime.Types.Utils.PayloadToResult<Prisma.$IndicatorPointPayload> | null
|
||||||
|
}
|
||||||
|
findFirstOrThrow: {
|
||||||
|
args: Prisma.IndicatorPointFindFirstOrThrowArgs<ExtArgs>
|
||||||
|
result: runtime.Types.Utils.PayloadToResult<Prisma.$IndicatorPointPayload>
|
||||||
|
}
|
||||||
|
findMany: {
|
||||||
|
args: Prisma.IndicatorPointFindManyArgs<ExtArgs>
|
||||||
|
result: runtime.Types.Utils.PayloadToResult<Prisma.$IndicatorPointPayload>[]
|
||||||
|
}
|
||||||
|
create: {
|
||||||
|
args: Prisma.IndicatorPointCreateArgs<ExtArgs>
|
||||||
|
result: runtime.Types.Utils.PayloadToResult<Prisma.$IndicatorPointPayload>
|
||||||
|
}
|
||||||
|
createMany: {
|
||||||
|
args: Prisma.IndicatorPointCreateManyArgs<ExtArgs>
|
||||||
|
result: BatchPayload
|
||||||
|
}
|
||||||
|
delete: {
|
||||||
|
args: Prisma.IndicatorPointDeleteArgs<ExtArgs>
|
||||||
|
result: runtime.Types.Utils.PayloadToResult<Prisma.$IndicatorPointPayload>
|
||||||
|
}
|
||||||
|
update: {
|
||||||
|
args: Prisma.IndicatorPointUpdateArgs<ExtArgs>
|
||||||
|
result: runtime.Types.Utils.PayloadToResult<Prisma.$IndicatorPointPayload>
|
||||||
|
}
|
||||||
|
deleteMany: {
|
||||||
|
args: Prisma.IndicatorPointDeleteManyArgs<ExtArgs>
|
||||||
|
result: BatchPayload
|
||||||
|
}
|
||||||
|
updateMany: {
|
||||||
|
args: Prisma.IndicatorPointUpdateManyArgs<ExtArgs>
|
||||||
|
result: BatchPayload
|
||||||
|
}
|
||||||
|
upsert: {
|
||||||
|
args: Prisma.IndicatorPointUpsertArgs<ExtArgs>
|
||||||
|
result: runtime.Types.Utils.PayloadToResult<Prisma.$IndicatorPointPayload>
|
||||||
|
}
|
||||||
|
aggregate: {
|
||||||
|
args: Prisma.IndicatorPointAggregateArgs<ExtArgs>
|
||||||
|
result: runtime.Types.Utils.Optional<Prisma.AggregateIndicatorPoint>
|
||||||
|
}
|
||||||
|
groupBy: {
|
||||||
|
args: Prisma.IndicatorPointGroupByArgs<ExtArgs>
|
||||||
|
result: runtime.Types.Utils.Optional<Prisma.IndicatorPointGroupByOutputType>[]
|
||||||
|
}
|
||||||
|
count: {
|
||||||
|
args: Prisma.IndicatorPointCountArgs<ExtArgs>
|
||||||
|
result: runtime.Types.Utils.Optional<Prisma.IndicatorPointCountAggregateOutputType> | number
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Econ_SowInventory: {
|
Econ_SowInventory: {
|
||||||
payload: Prisma.$Econ_SowInventoryPayload<ExtArgs>
|
payload: Prisma.$Econ_SowInventoryPayload<ExtArgs>
|
||||||
fields: Prisma.Econ_SowInventoryFieldRefs
|
fields: Prisma.Econ_SowInventoryFieldRefs
|
||||||
@ -885,7 +952,11 @@ export const IndicatorScalarFieldEnum = {
|
|||||||
id: 'id',
|
id: 'id',
|
||||||
name: 'name',
|
name: 'name',
|
||||||
groupName: 'groupName',
|
groupName: 'groupName',
|
||||||
data: 'data',
|
title: 'title',
|
||||||
|
unit: 'unit',
|
||||||
|
source: 'source',
|
||||||
|
frequency: 'frequency',
|
||||||
|
hidden: 'hidden',
|
||||||
createdAt: 'createdAt',
|
createdAt: 'createdAt',
|
||||||
updatedAt: 'updatedAt'
|
updatedAt: 'updatedAt'
|
||||||
} as const
|
} as const
|
||||||
@ -893,6 +964,18 @@ export const IndicatorScalarFieldEnum = {
|
|||||||
export type IndicatorScalarFieldEnum = (typeof IndicatorScalarFieldEnum)[keyof typeof IndicatorScalarFieldEnum]
|
export type IndicatorScalarFieldEnum = (typeof IndicatorScalarFieldEnum)[keyof typeof IndicatorScalarFieldEnum]
|
||||||
|
|
||||||
|
|
||||||
|
export const IndicatorPointScalarFieldEnum = {
|
||||||
|
id: 'id',
|
||||||
|
indicatorId: 'indicatorId',
|
||||||
|
period: 'period',
|
||||||
|
value: 'value',
|
||||||
|
createdAt: 'createdAt',
|
||||||
|
updatedAt: 'updatedAt'
|
||||||
|
} as const
|
||||||
|
|
||||||
|
export type IndicatorPointScalarFieldEnum = (typeof IndicatorPointScalarFieldEnum)[keyof typeof IndicatorPointScalarFieldEnum]
|
||||||
|
|
||||||
|
|
||||||
export const Econ_SowInventoryScalarFieldEnum = {
|
export const Econ_SowInventoryScalarFieldEnum = {
|
||||||
id: 'id',
|
id: 'id',
|
||||||
month: 'month',
|
month: 'month',
|
||||||
@ -986,12 +1069,23 @@ export type StrategyOrderByRelevanceFieldEnum = (typeof StrategyOrderByRelevance
|
|||||||
|
|
||||||
export const IndicatorOrderByRelevanceFieldEnum = {
|
export const IndicatorOrderByRelevanceFieldEnum = {
|
||||||
name: 'name',
|
name: 'name',
|
||||||
groupName: 'groupName'
|
groupName: 'groupName',
|
||||||
|
title: 'title',
|
||||||
|
unit: 'unit',
|
||||||
|
source: 'source',
|
||||||
|
frequency: 'frequency'
|
||||||
} as const
|
} as const
|
||||||
|
|
||||||
export type IndicatorOrderByRelevanceFieldEnum = (typeof IndicatorOrderByRelevanceFieldEnum)[keyof typeof IndicatorOrderByRelevanceFieldEnum]
|
export type IndicatorOrderByRelevanceFieldEnum = (typeof IndicatorOrderByRelevanceFieldEnum)[keyof typeof IndicatorOrderByRelevanceFieldEnum]
|
||||||
|
|
||||||
|
|
||||||
|
export const IndicatorPointOrderByRelevanceFieldEnum = {
|
||||||
|
period: 'period'
|
||||||
|
} as const
|
||||||
|
|
||||||
|
export type IndicatorPointOrderByRelevanceFieldEnum = (typeof IndicatorPointOrderByRelevanceFieldEnum)[keyof typeof IndicatorPointOrderByRelevanceFieldEnum]
|
||||||
|
|
||||||
|
|
||||||
export const Econ_SowInventoryOrderByRelevanceFieldEnum = {
|
export const Econ_SowInventoryOrderByRelevanceFieldEnum = {
|
||||||
month: 'month'
|
month: 'month'
|
||||||
} as const
|
} as const
|
||||||
@ -1056,6 +1150,13 @@ export type EnumQueryModeFieldRefInput<$PrismaModel> = FieldRefInputType<$Prisma
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reference to a field of type 'Boolean'
|
||||||
|
*/
|
||||||
|
export type BooleanFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'Boolean'>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reference to a field of type 'Float'
|
* Reference to a field of type 'Float'
|
||||||
*/
|
*/
|
||||||
@ -1161,6 +1262,7 @@ export type GlobalOmitConfig = {
|
|||||||
article?: Prisma.ArticleOmit
|
article?: Prisma.ArticleOmit
|
||||||
strategy?: Prisma.StrategyOmit
|
strategy?: Prisma.StrategyOmit
|
||||||
indicator?: Prisma.IndicatorOmit
|
indicator?: Prisma.IndicatorOmit
|
||||||
|
indicatorPoint?: Prisma.IndicatorPointOmit
|
||||||
econ_SowInventory?: Prisma.Econ_SowInventoryOmit
|
econ_SowInventory?: Prisma.Econ_SowInventoryOmit
|
||||||
scraperCache?: Prisma.ScraperCacheOmit
|
scraperCache?: Prisma.ScraperCacheOmit
|
||||||
}
|
}
|
||||||
|
|||||||
@ -55,6 +55,7 @@ export const ModelName = {
|
|||||||
Article: 'Article',
|
Article: 'Article',
|
||||||
Strategy: 'Strategy',
|
Strategy: 'Strategy',
|
||||||
Indicator: 'Indicator',
|
Indicator: 'Indicator',
|
||||||
|
IndicatorPoint: 'IndicatorPoint',
|
||||||
Econ_SowInventory: 'Econ_SowInventory',
|
Econ_SowInventory: 'Econ_SowInventory',
|
||||||
ScraperCache: 'ScraperCache'
|
ScraperCache: 'ScraperCache'
|
||||||
} as const
|
} as const
|
||||||
@ -116,7 +117,11 @@ export const IndicatorScalarFieldEnum = {
|
|||||||
id: 'id',
|
id: 'id',
|
||||||
name: 'name',
|
name: 'name',
|
||||||
groupName: 'groupName',
|
groupName: 'groupName',
|
||||||
data: 'data',
|
title: 'title',
|
||||||
|
unit: 'unit',
|
||||||
|
source: 'source',
|
||||||
|
frequency: 'frequency',
|
||||||
|
hidden: 'hidden',
|
||||||
createdAt: 'createdAt',
|
createdAt: 'createdAt',
|
||||||
updatedAt: 'updatedAt'
|
updatedAt: 'updatedAt'
|
||||||
} as const
|
} as const
|
||||||
@ -124,6 +129,18 @@ export const IndicatorScalarFieldEnum = {
|
|||||||
export type IndicatorScalarFieldEnum = (typeof IndicatorScalarFieldEnum)[keyof typeof IndicatorScalarFieldEnum]
|
export type IndicatorScalarFieldEnum = (typeof IndicatorScalarFieldEnum)[keyof typeof IndicatorScalarFieldEnum]
|
||||||
|
|
||||||
|
|
||||||
|
export const IndicatorPointScalarFieldEnum = {
|
||||||
|
id: 'id',
|
||||||
|
indicatorId: 'indicatorId',
|
||||||
|
period: 'period',
|
||||||
|
value: 'value',
|
||||||
|
createdAt: 'createdAt',
|
||||||
|
updatedAt: 'updatedAt'
|
||||||
|
} as const
|
||||||
|
|
||||||
|
export type IndicatorPointScalarFieldEnum = (typeof IndicatorPointScalarFieldEnum)[keyof typeof IndicatorPointScalarFieldEnum]
|
||||||
|
|
||||||
|
|
||||||
export const Econ_SowInventoryScalarFieldEnum = {
|
export const Econ_SowInventoryScalarFieldEnum = {
|
||||||
id: 'id',
|
id: 'id',
|
||||||
month: 'month',
|
month: 'month',
|
||||||
@ -217,12 +234,23 @@ export type StrategyOrderByRelevanceFieldEnum = (typeof StrategyOrderByRelevance
|
|||||||
|
|
||||||
export const IndicatorOrderByRelevanceFieldEnum = {
|
export const IndicatorOrderByRelevanceFieldEnum = {
|
||||||
name: 'name',
|
name: 'name',
|
||||||
groupName: 'groupName'
|
groupName: 'groupName',
|
||||||
|
title: 'title',
|
||||||
|
unit: 'unit',
|
||||||
|
source: 'source',
|
||||||
|
frequency: 'frequency'
|
||||||
} as const
|
} as const
|
||||||
|
|
||||||
export type IndicatorOrderByRelevanceFieldEnum = (typeof IndicatorOrderByRelevanceFieldEnum)[keyof typeof IndicatorOrderByRelevanceFieldEnum]
|
export type IndicatorOrderByRelevanceFieldEnum = (typeof IndicatorOrderByRelevanceFieldEnum)[keyof typeof IndicatorOrderByRelevanceFieldEnum]
|
||||||
|
|
||||||
|
|
||||||
|
export const IndicatorPointOrderByRelevanceFieldEnum = {
|
||||||
|
period: 'period'
|
||||||
|
} as const
|
||||||
|
|
||||||
|
export type IndicatorPointOrderByRelevanceFieldEnum = (typeof IndicatorPointOrderByRelevanceFieldEnum)[keyof typeof IndicatorPointOrderByRelevanceFieldEnum]
|
||||||
|
|
||||||
|
|
||||||
export const Econ_SowInventoryOrderByRelevanceFieldEnum = {
|
export const Econ_SowInventoryOrderByRelevanceFieldEnum = {
|
||||||
month: 'month'
|
month: 'month'
|
||||||
} as const
|
} as const
|
||||||
|
|||||||
@ -12,6 +12,7 @@ export type * from './models/User.ts'
|
|||||||
export type * from './models/Article.ts'
|
export type * from './models/Article.ts'
|
||||||
export type * from './models/Strategy.ts'
|
export type * from './models/Strategy.ts'
|
||||||
export type * from './models/Indicator.ts'
|
export type * from './models/Indicator.ts'
|
||||||
|
export type * from './models/IndicatorPoint.ts'
|
||||||
export type * from './models/Econ_SowInventory.ts'
|
export type * from './models/Econ_SowInventory.ts'
|
||||||
export type * from './models/ScraperCache.ts'
|
export type * from './models/ScraperCache.ts'
|
||||||
export type * from './commonInputTypes.ts'
|
export type * from './commonInputTypes.ts'
|
||||||
@ -38,6 +38,11 @@ export type IndicatorMinAggregateOutputType = {
|
|||||||
id: number | null
|
id: number | null
|
||||||
name: string | null
|
name: string | null
|
||||||
groupName: string | null
|
groupName: string | null
|
||||||
|
title: string | null
|
||||||
|
unit: string | null
|
||||||
|
source: string | null
|
||||||
|
frequency: string | null
|
||||||
|
hidden: boolean | null
|
||||||
createdAt: Date | null
|
createdAt: Date | null
|
||||||
updatedAt: Date | null
|
updatedAt: Date | null
|
||||||
}
|
}
|
||||||
@ -46,6 +51,11 @@ export type IndicatorMaxAggregateOutputType = {
|
|||||||
id: number | null
|
id: number | null
|
||||||
name: string | null
|
name: string | null
|
||||||
groupName: string | null
|
groupName: string | null
|
||||||
|
title: string | null
|
||||||
|
unit: string | null
|
||||||
|
source: string | null
|
||||||
|
frequency: string | null
|
||||||
|
hidden: boolean | null
|
||||||
createdAt: Date | null
|
createdAt: Date | null
|
||||||
updatedAt: Date | null
|
updatedAt: Date | null
|
||||||
}
|
}
|
||||||
@ -54,7 +64,11 @@ export type IndicatorCountAggregateOutputType = {
|
|||||||
id: number
|
id: number
|
||||||
name: number
|
name: number
|
||||||
groupName: number
|
groupName: number
|
||||||
data: number
|
title: number
|
||||||
|
unit: number
|
||||||
|
source: number
|
||||||
|
frequency: number
|
||||||
|
hidden: number
|
||||||
createdAt: number
|
createdAt: number
|
||||||
updatedAt: number
|
updatedAt: number
|
||||||
_all: number
|
_all: number
|
||||||
@ -73,6 +87,11 @@ export type IndicatorMinAggregateInputType = {
|
|||||||
id?: true
|
id?: true
|
||||||
name?: true
|
name?: true
|
||||||
groupName?: true
|
groupName?: true
|
||||||
|
title?: true
|
||||||
|
unit?: true
|
||||||
|
source?: true
|
||||||
|
frequency?: true
|
||||||
|
hidden?: true
|
||||||
createdAt?: true
|
createdAt?: true
|
||||||
updatedAt?: true
|
updatedAt?: true
|
||||||
}
|
}
|
||||||
@ -81,6 +100,11 @@ export type IndicatorMaxAggregateInputType = {
|
|||||||
id?: true
|
id?: true
|
||||||
name?: true
|
name?: true
|
||||||
groupName?: true
|
groupName?: true
|
||||||
|
title?: true
|
||||||
|
unit?: true
|
||||||
|
source?: true
|
||||||
|
frequency?: true
|
||||||
|
hidden?: true
|
||||||
createdAt?: true
|
createdAt?: true
|
||||||
updatedAt?: true
|
updatedAt?: true
|
||||||
}
|
}
|
||||||
@ -89,7 +113,11 @@ export type IndicatorCountAggregateInputType = {
|
|||||||
id?: true
|
id?: true
|
||||||
name?: true
|
name?: true
|
||||||
groupName?: true
|
groupName?: true
|
||||||
data?: true
|
title?: true
|
||||||
|
unit?: true
|
||||||
|
source?: true
|
||||||
|
frequency?: true
|
||||||
|
hidden?: true
|
||||||
createdAt?: true
|
createdAt?: true
|
||||||
updatedAt?: true
|
updatedAt?: true
|
||||||
_all?: true
|
_all?: true
|
||||||
@ -185,7 +213,11 @@ export type IndicatorGroupByOutputType = {
|
|||||||
id: number
|
id: number
|
||||||
name: string
|
name: string
|
||||||
groupName: string
|
groupName: string
|
||||||
data: runtime.JsonValue
|
title: string
|
||||||
|
unit: string
|
||||||
|
source: string
|
||||||
|
frequency: string
|
||||||
|
hidden: boolean
|
||||||
createdAt: Date
|
createdAt: Date
|
||||||
updatedAt: Date
|
updatedAt: Date
|
||||||
_count: IndicatorCountAggregateOutputType | null
|
_count: IndicatorCountAggregateOutputType | null
|
||||||
@ -217,18 +249,28 @@ export type IndicatorWhereInput = {
|
|||||||
id?: Prisma.IntFilter<"Indicator"> | number
|
id?: Prisma.IntFilter<"Indicator"> | number
|
||||||
name?: Prisma.StringFilter<"Indicator"> | string
|
name?: Prisma.StringFilter<"Indicator"> | string
|
||||||
groupName?: Prisma.StringFilter<"Indicator"> | string
|
groupName?: Prisma.StringFilter<"Indicator"> | string
|
||||||
data?: Prisma.JsonFilter<"Indicator">
|
title?: Prisma.StringFilter<"Indicator"> | string
|
||||||
|
unit?: Prisma.StringFilter<"Indicator"> | string
|
||||||
|
source?: Prisma.StringFilter<"Indicator"> | string
|
||||||
|
frequency?: Prisma.StringFilter<"Indicator"> | string
|
||||||
|
hidden?: Prisma.BoolFilter<"Indicator"> | boolean
|
||||||
createdAt?: Prisma.DateTimeFilter<"Indicator"> | Date | string
|
createdAt?: Prisma.DateTimeFilter<"Indicator"> | Date | string
|
||||||
updatedAt?: Prisma.DateTimeFilter<"Indicator"> | Date | string
|
updatedAt?: Prisma.DateTimeFilter<"Indicator"> | Date | string
|
||||||
|
points?: Prisma.IndicatorPointListRelationFilter
|
||||||
}
|
}
|
||||||
|
|
||||||
export type IndicatorOrderByWithRelationInput = {
|
export type IndicatorOrderByWithRelationInput = {
|
||||||
id?: Prisma.SortOrder
|
id?: Prisma.SortOrder
|
||||||
name?: Prisma.SortOrder
|
name?: Prisma.SortOrder
|
||||||
groupName?: Prisma.SortOrder
|
groupName?: Prisma.SortOrder
|
||||||
data?: Prisma.SortOrder
|
title?: Prisma.SortOrder
|
||||||
|
unit?: Prisma.SortOrder
|
||||||
|
source?: Prisma.SortOrder
|
||||||
|
frequency?: Prisma.SortOrder
|
||||||
|
hidden?: Prisma.SortOrder
|
||||||
createdAt?: Prisma.SortOrder
|
createdAt?: Prisma.SortOrder
|
||||||
updatedAt?: Prisma.SortOrder
|
updatedAt?: Prisma.SortOrder
|
||||||
|
points?: Prisma.IndicatorPointOrderByRelationAggregateInput
|
||||||
_relevance?: Prisma.IndicatorOrderByRelevanceInput
|
_relevance?: Prisma.IndicatorOrderByRelevanceInput
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -239,16 +281,25 @@ export type IndicatorWhereUniqueInput = Prisma.AtLeast<{
|
|||||||
OR?: Prisma.IndicatorWhereInput[]
|
OR?: Prisma.IndicatorWhereInput[]
|
||||||
NOT?: Prisma.IndicatorWhereInput | Prisma.IndicatorWhereInput[]
|
NOT?: Prisma.IndicatorWhereInput | Prisma.IndicatorWhereInput[]
|
||||||
groupName?: Prisma.StringFilter<"Indicator"> | string
|
groupName?: Prisma.StringFilter<"Indicator"> | string
|
||||||
data?: Prisma.JsonFilter<"Indicator">
|
title?: Prisma.StringFilter<"Indicator"> | string
|
||||||
|
unit?: Prisma.StringFilter<"Indicator"> | string
|
||||||
|
source?: Prisma.StringFilter<"Indicator"> | string
|
||||||
|
frequency?: Prisma.StringFilter<"Indicator"> | string
|
||||||
|
hidden?: Prisma.BoolFilter<"Indicator"> | boolean
|
||||||
createdAt?: Prisma.DateTimeFilter<"Indicator"> | Date | string
|
createdAt?: Prisma.DateTimeFilter<"Indicator"> | Date | string
|
||||||
updatedAt?: Prisma.DateTimeFilter<"Indicator"> | Date | string
|
updatedAt?: Prisma.DateTimeFilter<"Indicator"> | Date | string
|
||||||
|
points?: Prisma.IndicatorPointListRelationFilter
|
||||||
}, "id" | "name">
|
}, "id" | "name">
|
||||||
|
|
||||||
export type IndicatorOrderByWithAggregationInput = {
|
export type IndicatorOrderByWithAggregationInput = {
|
||||||
id?: Prisma.SortOrder
|
id?: Prisma.SortOrder
|
||||||
name?: Prisma.SortOrder
|
name?: Prisma.SortOrder
|
||||||
groupName?: Prisma.SortOrder
|
groupName?: Prisma.SortOrder
|
||||||
data?: Prisma.SortOrder
|
title?: Prisma.SortOrder
|
||||||
|
unit?: Prisma.SortOrder
|
||||||
|
source?: Prisma.SortOrder
|
||||||
|
frequency?: Prisma.SortOrder
|
||||||
|
hidden?: Prisma.SortOrder
|
||||||
createdAt?: Prisma.SortOrder
|
createdAt?: Prisma.SortOrder
|
||||||
updatedAt?: Prisma.SortOrder
|
updatedAt?: Prisma.SortOrder
|
||||||
_count?: Prisma.IndicatorCountOrderByAggregateInput
|
_count?: Prisma.IndicatorCountOrderByAggregateInput
|
||||||
@ -265,7 +316,11 @@ export type IndicatorScalarWhereWithAggregatesInput = {
|
|||||||
id?: Prisma.IntWithAggregatesFilter<"Indicator"> | number
|
id?: Prisma.IntWithAggregatesFilter<"Indicator"> | number
|
||||||
name?: Prisma.StringWithAggregatesFilter<"Indicator"> | string
|
name?: Prisma.StringWithAggregatesFilter<"Indicator"> | string
|
||||||
groupName?: Prisma.StringWithAggregatesFilter<"Indicator"> | string
|
groupName?: Prisma.StringWithAggregatesFilter<"Indicator"> | string
|
||||||
data?: Prisma.JsonWithAggregatesFilter<"Indicator">
|
title?: Prisma.StringWithAggregatesFilter<"Indicator"> | string
|
||||||
|
unit?: Prisma.StringWithAggregatesFilter<"Indicator"> | string
|
||||||
|
source?: Prisma.StringWithAggregatesFilter<"Indicator"> | string
|
||||||
|
frequency?: Prisma.StringWithAggregatesFilter<"Indicator"> | string
|
||||||
|
hidden?: Prisma.BoolWithAggregatesFilter<"Indicator"> | boolean
|
||||||
createdAt?: Prisma.DateTimeWithAggregatesFilter<"Indicator"> | Date | string
|
createdAt?: Prisma.DateTimeWithAggregatesFilter<"Indicator"> | Date | string
|
||||||
updatedAt?: Prisma.DateTimeWithAggregatesFilter<"Indicator"> | Date | string
|
updatedAt?: Prisma.DateTimeWithAggregatesFilter<"Indicator"> | Date | string
|
||||||
}
|
}
|
||||||
@ -273,42 +328,66 @@ export type IndicatorScalarWhereWithAggregatesInput = {
|
|||||||
export type IndicatorCreateInput = {
|
export type IndicatorCreateInput = {
|
||||||
name: string
|
name: string
|
||||||
groupName: string
|
groupName: string
|
||||||
data: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
title?: string
|
||||||
|
unit?: string
|
||||||
|
source?: string
|
||||||
|
frequency?: string
|
||||||
|
hidden?: boolean
|
||||||
createdAt?: Date | string
|
createdAt?: Date | string
|
||||||
updatedAt?: Date | string
|
updatedAt?: Date | string
|
||||||
|
points?: Prisma.IndicatorPointCreateNestedManyWithoutIndicatorInput
|
||||||
}
|
}
|
||||||
|
|
||||||
export type IndicatorUncheckedCreateInput = {
|
export type IndicatorUncheckedCreateInput = {
|
||||||
id?: number
|
id?: number
|
||||||
name: string
|
name: string
|
||||||
groupName: string
|
groupName: string
|
||||||
data: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
title?: string
|
||||||
|
unit?: string
|
||||||
|
source?: string
|
||||||
|
frequency?: string
|
||||||
|
hidden?: boolean
|
||||||
createdAt?: Date | string
|
createdAt?: Date | string
|
||||||
updatedAt?: Date | string
|
updatedAt?: Date | string
|
||||||
|
points?: Prisma.IndicatorPointUncheckedCreateNestedManyWithoutIndicatorInput
|
||||||
}
|
}
|
||||||
|
|
||||||
export type IndicatorUpdateInput = {
|
export type IndicatorUpdateInput = {
|
||||||
name?: Prisma.StringFieldUpdateOperationsInput | string
|
name?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
groupName?: Prisma.StringFieldUpdateOperationsInput | string
|
groupName?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
data?: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
title?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
|
unit?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
|
source?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
|
frequency?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
|
hidden?: Prisma.BoolFieldUpdateOperationsInput | boolean
|
||||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
|
points?: Prisma.IndicatorPointUpdateManyWithoutIndicatorNestedInput
|
||||||
}
|
}
|
||||||
|
|
||||||
export type IndicatorUncheckedUpdateInput = {
|
export type IndicatorUncheckedUpdateInput = {
|
||||||
id?: Prisma.IntFieldUpdateOperationsInput | number
|
id?: Prisma.IntFieldUpdateOperationsInput | number
|
||||||
name?: Prisma.StringFieldUpdateOperationsInput | string
|
name?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
groupName?: Prisma.StringFieldUpdateOperationsInput | string
|
groupName?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
data?: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
title?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
|
unit?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
|
source?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
|
frequency?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
|
hidden?: Prisma.BoolFieldUpdateOperationsInput | boolean
|
||||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
|
points?: Prisma.IndicatorPointUncheckedUpdateManyWithoutIndicatorNestedInput
|
||||||
}
|
}
|
||||||
|
|
||||||
export type IndicatorCreateManyInput = {
|
export type IndicatorCreateManyInput = {
|
||||||
id?: number
|
id?: number
|
||||||
name: string
|
name: string
|
||||||
groupName: string
|
groupName: string
|
||||||
data: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
title?: string
|
||||||
|
unit?: string
|
||||||
|
source?: string
|
||||||
|
frequency?: string
|
||||||
|
hidden?: boolean
|
||||||
createdAt?: Date | string
|
createdAt?: Date | string
|
||||||
updatedAt?: Date | string
|
updatedAt?: Date | string
|
||||||
}
|
}
|
||||||
@ -316,7 +395,11 @@ export type IndicatorCreateManyInput = {
|
|||||||
export type IndicatorUpdateManyMutationInput = {
|
export type IndicatorUpdateManyMutationInput = {
|
||||||
name?: Prisma.StringFieldUpdateOperationsInput | string
|
name?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
groupName?: Prisma.StringFieldUpdateOperationsInput | string
|
groupName?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
data?: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
title?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
|
unit?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
|
source?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
|
frequency?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
|
hidden?: Prisma.BoolFieldUpdateOperationsInput | boolean
|
||||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
}
|
}
|
||||||
@ -325,7 +408,11 @@ export type IndicatorUncheckedUpdateManyInput = {
|
|||||||
id?: Prisma.IntFieldUpdateOperationsInput | number
|
id?: Prisma.IntFieldUpdateOperationsInput | number
|
||||||
name?: Prisma.StringFieldUpdateOperationsInput | string
|
name?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
groupName?: Prisma.StringFieldUpdateOperationsInput | string
|
groupName?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
data?: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
title?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
|
unit?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
|
source?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
|
frequency?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
|
hidden?: Prisma.BoolFieldUpdateOperationsInput | boolean
|
||||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
}
|
}
|
||||||
@ -340,7 +427,11 @@ export type IndicatorCountOrderByAggregateInput = {
|
|||||||
id?: Prisma.SortOrder
|
id?: Prisma.SortOrder
|
||||||
name?: Prisma.SortOrder
|
name?: Prisma.SortOrder
|
||||||
groupName?: Prisma.SortOrder
|
groupName?: Prisma.SortOrder
|
||||||
data?: Prisma.SortOrder
|
title?: Prisma.SortOrder
|
||||||
|
unit?: Prisma.SortOrder
|
||||||
|
source?: Prisma.SortOrder
|
||||||
|
frequency?: Prisma.SortOrder
|
||||||
|
hidden?: Prisma.SortOrder
|
||||||
createdAt?: Prisma.SortOrder
|
createdAt?: Prisma.SortOrder
|
||||||
updatedAt?: Prisma.SortOrder
|
updatedAt?: Prisma.SortOrder
|
||||||
}
|
}
|
||||||
@ -353,6 +444,11 @@ export type IndicatorMaxOrderByAggregateInput = {
|
|||||||
id?: Prisma.SortOrder
|
id?: Prisma.SortOrder
|
||||||
name?: Prisma.SortOrder
|
name?: Prisma.SortOrder
|
||||||
groupName?: Prisma.SortOrder
|
groupName?: Prisma.SortOrder
|
||||||
|
title?: Prisma.SortOrder
|
||||||
|
unit?: Prisma.SortOrder
|
||||||
|
source?: Prisma.SortOrder
|
||||||
|
frequency?: Prisma.SortOrder
|
||||||
|
hidden?: Prisma.SortOrder
|
||||||
createdAt?: Prisma.SortOrder
|
createdAt?: Prisma.SortOrder
|
||||||
updatedAt?: Prisma.SortOrder
|
updatedAt?: Prisma.SortOrder
|
||||||
}
|
}
|
||||||
@ -361,6 +457,11 @@ export type IndicatorMinOrderByAggregateInput = {
|
|||||||
id?: Prisma.SortOrder
|
id?: Prisma.SortOrder
|
||||||
name?: Prisma.SortOrder
|
name?: Prisma.SortOrder
|
||||||
groupName?: Prisma.SortOrder
|
groupName?: Prisma.SortOrder
|
||||||
|
title?: Prisma.SortOrder
|
||||||
|
unit?: Prisma.SortOrder
|
||||||
|
source?: Prisma.SortOrder
|
||||||
|
frequency?: Prisma.SortOrder
|
||||||
|
hidden?: Prisma.SortOrder
|
||||||
createdAt?: Prisma.SortOrder
|
createdAt?: Prisma.SortOrder
|
||||||
updatedAt?: Prisma.SortOrder
|
updatedAt?: Prisma.SortOrder
|
||||||
}
|
}
|
||||||
@ -369,15 +470,139 @@ export type IndicatorSumOrderByAggregateInput = {
|
|||||||
id?: Prisma.SortOrder
|
id?: Prisma.SortOrder
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type IndicatorScalarRelationFilter = {
|
||||||
|
is?: Prisma.IndicatorWhereInput
|
||||||
|
isNot?: Prisma.IndicatorWhereInput
|
||||||
|
}
|
||||||
|
|
||||||
|
export type BoolFieldUpdateOperationsInput = {
|
||||||
|
set?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export type IndicatorCreateNestedOneWithoutPointsInput = {
|
||||||
|
create?: Prisma.XOR<Prisma.IndicatorCreateWithoutPointsInput, Prisma.IndicatorUncheckedCreateWithoutPointsInput>
|
||||||
|
connectOrCreate?: Prisma.IndicatorCreateOrConnectWithoutPointsInput
|
||||||
|
connect?: Prisma.IndicatorWhereUniqueInput
|
||||||
|
}
|
||||||
|
|
||||||
|
export type IndicatorUpdateOneRequiredWithoutPointsNestedInput = {
|
||||||
|
create?: Prisma.XOR<Prisma.IndicatorCreateWithoutPointsInput, Prisma.IndicatorUncheckedCreateWithoutPointsInput>
|
||||||
|
connectOrCreate?: Prisma.IndicatorCreateOrConnectWithoutPointsInput
|
||||||
|
upsert?: Prisma.IndicatorUpsertWithoutPointsInput
|
||||||
|
connect?: Prisma.IndicatorWhereUniqueInput
|
||||||
|
update?: Prisma.XOR<Prisma.XOR<Prisma.IndicatorUpdateToOneWithWhereWithoutPointsInput, Prisma.IndicatorUpdateWithoutPointsInput>, Prisma.IndicatorUncheckedUpdateWithoutPointsInput>
|
||||||
|
}
|
||||||
|
|
||||||
|
export type IndicatorCreateWithoutPointsInput = {
|
||||||
|
name: string
|
||||||
|
groupName: string
|
||||||
|
title?: string
|
||||||
|
unit?: string
|
||||||
|
source?: string
|
||||||
|
frequency?: string
|
||||||
|
hidden?: boolean
|
||||||
|
createdAt?: Date | string
|
||||||
|
updatedAt?: Date | string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type IndicatorUncheckedCreateWithoutPointsInput = {
|
||||||
|
id?: number
|
||||||
|
name: string
|
||||||
|
groupName: string
|
||||||
|
title?: string
|
||||||
|
unit?: string
|
||||||
|
source?: string
|
||||||
|
frequency?: string
|
||||||
|
hidden?: boolean
|
||||||
|
createdAt?: Date | string
|
||||||
|
updatedAt?: Date | string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type IndicatorCreateOrConnectWithoutPointsInput = {
|
||||||
|
where: Prisma.IndicatorWhereUniqueInput
|
||||||
|
create: Prisma.XOR<Prisma.IndicatorCreateWithoutPointsInput, Prisma.IndicatorUncheckedCreateWithoutPointsInput>
|
||||||
|
}
|
||||||
|
|
||||||
|
export type IndicatorUpsertWithoutPointsInput = {
|
||||||
|
update: Prisma.XOR<Prisma.IndicatorUpdateWithoutPointsInput, Prisma.IndicatorUncheckedUpdateWithoutPointsInput>
|
||||||
|
create: Prisma.XOR<Prisma.IndicatorCreateWithoutPointsInput, Prisma.IndicatorUncheckedCreateWithoutPointsInput>
|
||||||
|
where?: Prisma.IndicatorWhereInput
|
||||||
|
}
|
||||||
|
|
||||||
|
export type IndicatorUpdateToOneWithWhereWithoutPointsInput = {
|
||||||
|
where?: Prisma.IndicatorWhereInput
|
||||||
|
data: Prisma.XOR<Prisma.IndicatorUpdateWithoutPointsInput, Prisma.IndicatorUncheckedUpdateWithoutPointsInput>
|
||||||
|
}
|
||||||
|
|
||||||
|
export type IndicatorUpdateWithoutPointsInput = {
|
||||||
|
name?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
|
groupName?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
|
title?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
|
unit?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
|
source?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
|
frequency?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
|
hidden?: Prisma.BoolFieldUpdateOperationsInput | boolean
|
||||||
|
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
|
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type IndicatorUncheckedUpdateWithoutPointsInput = {
|
||||||
|
id?: Prisma.IntFieldUpdateOperationsInput | number
|
||||||
|
name?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
|
groupName?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
|
title?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
|
unit?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
|
source?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
|
frequency?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
|
hidden?: Prisma.BoolFieldUpdateOperationsInput | boolean
|
||||||
|
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
|
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Count Type IndicatorCountOutputType
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type IndicatorCountOutputType = {
|
||||||
|
points: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export type IndicatorCountOutputTypeSelect<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||||
|
points?: boolean | IndicatorCountOutputTypeCountPointsArgs
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IndicatorCountOutputType without action
|
||||||
|
*/
|
||||||
|
export type IndicatorCountOutputTypeDefaultArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||||
|
/**
|
||||||
|
* Select specific fields to fetch from the IndicatorCountOutputType
|
||||||
|
*/
|
||||||
|
select?: Prisma.IndicatorCountOutputTypeSelect<ExtArgs> | null
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IndicatorCountOutputType without action
|
||||||
|
*/
|
||||||
|
export type IndicatorCountOutputTypeCountPointsArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||||
|
where?: Prisma.IndicatorPointWhereInput
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
export type IndicatorSelect<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{
|
export type IndicatorSelect<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{
|
||||||
id?: boolean
|
id?: boolean
|
||||||
name?: boolean
|
name?: boolean
|
||||||
groupName?: boolean
|
groupName?: boolean
|
||||||
data?: boolean
|
title?: boolean
|
||||||
|
unit?: boolean
|
||||||
|
source?: boolean
|
||||||
|
frequency?: boolean
|
||||||
|
hidden?: boolean
|
||||||
createdAt?: boolean
|
createdAt?: boolean
|
||||||
updatedAt?: boolean
|
updatedAt?: boolean
|
||||||
|
points?: boolean | Prisma.Indicator$pointsArgs<ExtArgs>
|
||||||
|
_count?: boolean | Prisma.IndicatorCountOutputTypeDefaultArgs<ExtArgs>
|
||||||
}, ExtArgs["result"]["indicator"]>
|
}, ExtArgs["result"]["indicator"]>
|
||||||
|
|
||||||
|
|
||||||
@ -386,21 +611,35 @@ export type IndicatorSelectScalar = {
|
|||||||
id?: boolean
|
id?: boolean
|
||||||
name?: boolean
|
name?: boolean
|
||||||
groupName?: boolean
|
groupName?: boolean
|
||||||
data?: boolean
|
title?: boolean
|
||||||
|
unit?: boolean
|
||||||
|
source?: boolean
|
||||||
|
frequency?: boolean
|
||||||
|
hidden?: boolean
|
||||||
createdAt?: boolean
|
createdAt?: boolean
|
||||||
updatedAt?: boolean
|
updatedAt?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export type IndicatorOmit<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetOmit<"id" | "name" | "groupName" | "data" | "createdAt" | "updatedAt", ExtArgs["result"]["indicator"]>
|
export type IndicatorOmit<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetOmit<"id" | "name" | "groupName" | "title" | "unit" | "source" | "frequency" | "hidden" | "createdAt" | "updatedAt", ExtArgs["result"]["indicator"]>
|
||||||
|
export type IndicatorInclude<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||||
|
points?: boolean | Prisma.Indicator$pointsArgs<ExtArgs>
|
||||||
|
_count?: boolean | Prisma.IndicatorCountOutputTypeDefaultArgs<ExtArgs>
|
||||||
|
}
|
||||||
|
|
||||||
export type $IndicatorPayload<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
export type $IndicatorPayload<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||||
name: "Indicator"
|
name: "Indicator"
|
||||||
objects: {}
|
objects: {
|
||||||
|
points: Prisma.$IndicatorPointPayload<ExtArgs>[]
|
||||||
|
}
|
||||||
scalars: runtime.Types.Extensions.GetPayloadResult<{
|
scalars: runtime.Types.Extensions.GetPayloadResult<{
|
||||||
id: number
|
id: number
|
||||||
name: string
|
name: string
|
||||||
groupName: string
|
groupName: string
|
||||||
data: runtime.JsonValue
|
title: string
|
||||||
|
unit: string
|
||||||
|
source: string
|
||||||
|
frequency: string
|
||||||
|
hidden: boolean
|
||||||
createdAt: Date
|
createdAt: Date
|
||||||
updatedAt: Date
|
updatedAt: Date
|
||||||
}, ExtArgs["result"]["indicator"]>
|
}, ExtArgs["result"]["indicator"]>
|
||||||
@ -743,6 +982,7 @@ readonly fields: IndicatorFieldRefs;
|
|||||||
*/
|
*/
|
||||||
export interface Prisma__IndicatorClient<T, Null = never, ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs, GlobalOmitOptions = {}> extends Prisma.PrismaPromise<T> {
|
export interface Prisma__IndicatorClient<T, Null = never, ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs, GlobalOmitOptions = {}> extends Prisma.PrismaPromise<T> {
|
||||||
readonly [Symbol.toStringTag]: "PrismaPromise"
|
readonly [Symbol.toStringTag]: "PrismaPromise"
|
||||||
|
points<T extends Prisma.Indicator$pointsArgs<ExtArgs> = {}>(args?: Prisma.Subset<T, Prisma.Indicator$pointsArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$IndicatorPointPayload<ExtArgs>, T, "findMany", GlobalOmitOptions> | Null>
|
||||||
/**
|
/**
|
||||||
* Attaches callbacks for the resolution and/or rejection of the Promise.
|
* Attaches callbacks for the resolution and/or rejection of the Promise.
|
||||||
* @param onfulfilled The callback to execute when the Promise is resolved.
|
* @param onfulfilled The callback to execute when the Promise is resolved.
|
||||||
@ -775,7 +1015,11 @@ export interface IndicatorFieldRefs {
|
|||||||
readonly id: Prisma.FieldRef<"Indicator", 'Int'>
|
readonly id: Prisma.FieldRef<"Indicator", 'Int'>
|
||||||
readonly name: Prisma.FieldRef<"Indicator", 'String'>
|
readonly name: Prisma.FieldRef<"Indicator", 'String'>
|
||||||
readonly groupName: Prisma.FieldRef<"Indicator", 'String'>
|
readonly groupName: Prisma.FieldRef<"Indicator", 'String'>
|
||||||
readonly data: Prisma.FieldRef<"Indicator", 'Json'>
|
readonly title: Prisma.FieldRef<"Indicator", 'String'>
|
||||||
|
readonly unit: Prisma.FieldRef<"Indicator", 'String'>
|
||||||
|
readonly source: Prisma.FieldRef<"Indicator", 'String'>
|
||||||
|
readonly frequency: Prisma.FieldRef<"Indicator", 'String'>
|
||||||
|
readonly hidden: Prisma.FieldRef<"Indicator", 'Boolean'>
|
||||||
readonly createdAt: Prisma.FieldRef<"Indicator", 'DateTime'>
|
readonly createdAt: Prisma.FieldRef<"Indicator", 'DateTime'>
|
||||||
readonly updatedAt: Prisma.FieldRef<"Indicator", 'DateTime'>
|
readonly updatedAt: Prisma.FieldRef<"Indicator", 'DateTime'>
|
||||||
}
|
}
|
||||||
@ -794,6 +1038,10 @@ export type IndicatorFindUniqueArgs<ExtArgs extends runtime.Types.Extensions.Int
|
|||||||
* Omit specific fields from the Indicator
|
* Omit specific fields from the Indicator
|
||||||
*/
|
*/
|
||||||
omit?: Prisma.IndicatorOmit<ExtArgs> | null
|
omit?: Prisma.IndicatorOmit<ExtArgs> | null
|
||||||
|
/**
|
||||||
|
* Choose, which related nodes to fetch as well
|
||||||
|
*/
|
||||||
|
include?: Prisma.IndicatorInclude<ExtArgs> | null
|
||||||
/**
|
/**
|
||||||
* Filter, which Indicator to fetch.
|
* Filter, which Indicator to fetch.
|
||||||
*/
|
*/
|
||||||
@ -812,6 +1060,10 @@ export type IndicatorFindUniqueOrThrowArgs<ExtArgs extends runtime.Types.Extensi
|
|||||||
* Omit specific fields from the Indicator
|
* Omit specific fields from the Indicator
|
||||||
*/
|
*/
|
||||||
omit?: Prisma.IndicatorOmit<ExtArgs> | null
|
omit?: Prisma.IndicatorOmit<ExtArgs> | null
|
||||||
|
/**
|
||||||
|
* Choose, which related nodes to fetch as well
|
||||||
|
*/
|
||||||
|
include?: Prisma.IndicatorInclude<ExtArgs> | null
|
||||||
/**
|
/**
|
||||||
* Filter, which Indicator to fetch.
|
* Filter, which Indicator to fetch.
|
||||||
*/
|
*/
|
||||||
@ -830,6 +1082,10 @@ export type IndicatorFindFirstArgs<ExtArgs extends runtime.Types.Extensions.Inte
|
|||||||
* Omit specific fields from the Indicator
|
* Omit specific fields from the Indicator
|
||||||
*/
|
*/
|
||||||
omit?: Prisma.IndicatorOmit<ExtArgs> | null
|
omit?: Prisma.IndicatorOmit<ExtArgs> | null
|
||||||
|
/**
|
||||||
|
* Choose, which related nodes to fetch as well
|
||||||
|
*/
|
||||||
|
include?: Prisma.IndicatorInclude<ExtArgs> | null
|
||||||
/**
|
/**
|
||||||
* Filter, which Indicator to fetch.
|
* Filter, which Indicator to fetch.
|
||||||
*/
|
*/
|
||||||
@ -878,6 +1134,10 @@ export type IndicatorFindFirstOrThrowArgs<ExtArgs extends runtime.Types.Extensio
|
|||||||
* Omit specific fields from the Indicator
|
* Omit specific fields from the Indicator
|
||||||
*/
|
*/
|
||||||
omit?: Prisma.IndicatorOmit<ExtArgs> | null
|
omit?: Prisma.IndicatorOmit<ExtArgs> | null
|
||||||
|
/**
|
||||||
|
* Choose, which related nodes to fetch as well
|
||||||
|
*/
|
||||||
|
include?: Prisma.IndicatorInclude<ExtArgs> | null
|
||||||
/**
|
/**
|
||||||
* Filter, which Indicator to fetch.
|
* Filter, which Indicator to fetch.
|
||||||
*/
|
*/
|
||||||
@ -926,6 +1186,10 @@ export type IndicatorFindManyArgs<ExtArgs extends runtime.Types.Extensions.Inter
|
|||||||
* Omit specific fields from the Indicator
|
* Omit specific fields from the Indicator
|
||||||
*/
|
*/
|
||||||
omit?: Prisma.IndicatorOmit<ExtArgs> | null
|
omit?: Prisma.IndicatorOmit<ExtArgs> | null
|
||||||
|
/**
|
||||||
|
* Choose, which related nodes to fetch as well
|
||||||
|
*/
|
||||||
|
include?: Prisma.IndicatorInclude<ExtArgs> | null
|
||||||
/**
|
/**
|
||||||
* Filter, which Indicators to fetch.
|
* Filter, which Indicators to fetch.
|
||||||
*/
|
*/
|
||||||
@ -974,6 +1238,10 @@ export type IndicatorCreateArgs<ExtArgs extends runtime.Types.Extensions.Interna
|
|||||||
* Omit specific fields from the Indicator
|
* Omit specific fields from the Indicator
|
||||||
*/
|
*/
|
||||||
omit?: Prisma.IndicatorOmit<ExtArgs> | null
|
omit?: Prisma.IndicatorOmit<ExtArgs> | null
|
||||||
|
/**
|
||||||
|
* Choose, which related nodes to fetch as well
|
||||||
|
*/
|
||||||
|
include?: Prisma.IndicatorInclude<ExtArgs> | null
|
||||||
/**
|
/**
|
||||||
* The data needed to create a Indicator.
|
* The data needed to create a Indicator.
|
||||||
*/
|
*/
|
||||||
@ -1003,6 +1271,10 @@ export type IndicatorUpdateArgs<ExtArgs extends runtime.Types.Extensions.Interna
|
|||||||
* Omit specific fields from the Indicator
|
* Omit specific fields from the Indicator
|
||||||
*/
|
*/
|
||||||
omit?: Prisma.IndicatorOmit<ExtArgs> | null
|
omit?: Prisma.IndicatorOmit<ExtArgs> | null
|
||||||
|
/**
|
||||||
|
* Choose, which related nodes to fetch as well
|
||||||
|
*/
|
||||||
|
include?: Prisma.IndicatorInclude<ExtArgs> | null
|
||||||
/**
|
/**
|
||||||
* The data needed to update a Indicator.
|
* The data needed to update a Indicator.
|
||||||
*/
|
*/
|
||||||
@ -1043,6 +1315,10 @@ export type IndicatorUpsertArgs<ExtArgs extends runtime.Types.Extensions.Interna
|
|||||||
* Omit specific fields from the Indicator
|
* Omit specific fields from the Indicator
|
||||||
*/
|
*/
|
||||||
omit?: Prisma.IndicatorOmit<ExtArgs> | null
|
omit?: Prisma.IndicatorOmit<ExtArgs> | null
|
||||||
|
/**
|
||||||
|
* Choose, which related nodes to fetch as well
|
||||||
|
*/
|
||||||
|
include?: Prisma.IndicatorInclude<ExtArgs> | null
|
||||||
/**
|
/**
|
||||||
* The filter to search for the Indicator to update in case it exists.
|
* The filter to search for the Indicator to update in case it exists.
|
||||||
*/
|
*/
|
||||||
@ -1069,6 +1345,10 @@ export type IndicatorDeleteArgs<ExtArgs extends runtime.Types.Extensions.Interna
|
|||||||
* Omit specific fields from the Indicator
|
* Omit specific fields from the Indicator
|
||||||
*/
|
*/
|
||||||
omit?: Prisma.IndicatorOmit<ExtArgs> | null
|
omit?: Prisma.IndicatorOmit<ExtArgs> | null
|
||||||
|
/**
|
||||||
|
* Choose, which related nodes to fetch as well
|
||||||
|
*/
|
||||||
|
include?: Prisma.IndicatorInclude<ExtArgs> | null
|
||||||
/**
|
/**
|
||||||
* Filter which Indicator to delete.
|
* Filter which Indicator to delete.
|
||||||
*/
|
*/
|
||||||
@ -1089,6 +1369,30 @@ export type IndicatorDeleteManyArgs<ExtArgs extends runtime.Types.Extensions.Int
|
|||||||
limit?: number
|
limit?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicator.points
|
||||||
|
*/
|
||||||
|
export type Indicator$pointsArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||||
|
/**
|
||||||
|
* Select specific fields to fetch from the IndicatorPoint
|
||||||
|
*/
|
||||||
|
select?: Prisma.IndicatorPointSelect<ExtArgs> | null
|
||||||
|
/**
|
||||||
|
* Omit specific fields from the IndicatorPoint
|
||||||
|
*/
|
||||||
|
omit?: Prisma.IndicatorPointOmit<ExtArgs> | null
|
||||||
|
/**
|
||||||
|
* Choose, which related nodes to fetch as well
|
||||||
|
*/
|
||||||
|
include?: Prisma.IndicatorPointInclude<ExtArgs> | null
|
||||||
|
where?: Prisma.IndicatorPointWhereInput
|
||||||
|
orderBy?: Prisma.IndicatorPointOrderByWithRelationInput | Prisma.IndicatorPointOrderByWithRelationInput[]
|
||||||
|
cursor?: Prisma.IndicatorPointWhereUniqueInput
|
||||||
|
take?: number
|
||||||
|
skip?: number
|
||||||
|
distinct?: Prisma.IndicatorPointScalarFieldEnum | Prisma.IndicatorPointScalarFieldEnum[]
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicator without action
|
* Indicator without action
|
||||||
*/
|
*/
|
||||||
@ -1101,4 +1405,8 @@ export type IndicatorDefaultArgs<ExtArgs extends runtime.Types.Extensions.Intern
|
|||||||
* Omit specific fields from the Indicator
|
* Omit specific fields from the Indicator
|
||||||
*/
|
*/
|
||||||
omit?: Prisma.IndicatorOmit<ExtArgs> | null
|
omit?: Prisma.IndicatorOmit<ExtArgs> | null
|
||||||
|
/**
|
||||||
|
* Choose, which related nodes to fetch as well
|
||||||
|
*/
|
||||||
|
include?: Prisma.IndicatorInclude<ExtArgs> | null
|
||||||
}
|
}
|
||||||
|
|||||||
1321
generated/prisma/models/IndicatorPoint.ts
Normal file
1321
generated/prisma/models/IndicatorPoint.ts
Normal file
File diff suppressed because it is too large
Load Diff
@ -234,15 +234,15 @@ export type StrategyOrderByWithRelationInput = {
|
|||||||
|
|
||||||
export type StrategyWhereUniqueInput = Prisma.AtLeast<{
|
export type StrategyWhereUniqueInput = Prisma.AtLeast<{
|
||||||
id?: number
|
id?: number
|
||||||
name?: string
|
|
||||||
AND?: Prisma.StrategyWhereInput | Prisma.StrategyWhereInput[]
|
AND?: Prisma.StrategyWhereInput | Prisma.StrategyWhereInput[]
|
||||||
OR?: Prisma.StrategyWhereInput[]
|
OR?: Prisma.StrategyWhereInput[]
|
||||||
NOT?: Prisma.StrategyWhereInput | Prisma.StrategyWhereInput[]
|
NOT?: Prisma.StrategyWhereInput | Prisma.StrategyWhereInput[]
|
||||||
|
name?: Prisma.StringFilter<"Strategy"> | string
|
||||||
description?: Prisma.StringFilter<"Strategy"> | string
|
description?: Prisma.StringFilter<"Strategy"> | string
|
||||||
data?: Prisma.JsonFilter<"Strategy">
|
data?: Prisma.JsonFilter<"Strategy">
|
||||||
createdAt?: Prisma.DateTimeFilter<"Strategy"> | Date | string
|
createdAt?: Prisma.DateTimeFilter<"Strategy"> | Date | string
|
||||||
updatedAt?: Prisma.DateTimeFilter<"Strategy"> | Date | string
|
updatedAt?: Prisma.DateTimeFilter<"Strategy"> | Date | string
|
||||||
}, "id" | "name">
|
}, "id">
|
||||||
|
|
||||||
export type StrategyOrderByWithAggregationInput = {
|
export type StrategyOrderByWithAggregationInput = {
|
||||||
id?: Prisma.SortOrder
|
id?: Prisma.SortOrder
|
||||||
|
|||||||
@ -0,0 +1,24 @@
|
|||||||
|
-- 经济指标: 明细数据拆到独立表, 兼容年/季/月/日频率
|
||||||
|
-- 第一步: 建 IndicatorPoint 表 + Indicator 加元数据列 (data 列暂保留, 由迁移脚本搬运后删除)
|
||||||
|
|
||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE `IndicatorPoint` (
|
||||||
|
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||||
|
`indicatorId` INTEGER NOT NULL,
|
||||||
|
`period` VARCHAR(191) NOT NULL,
|
||||||
|
`value` DOUBLE NOT NULL,
|
||||||
|
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||||
|
`updatedAt` DATETIME(3) NOT NULL,
|
||||||
|
|
||||||
|
UNIQUE INDEX `IndicatorPoint_indicatorId_period_key`(`indicatorId`, `period`),
|
||||||
|
PRIMARY KEY (`id`)
|
||||||
|
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||||
|
|
||||||
|
-- AlterTable: 元数据列 (data JSON 拆出)
|
||||||
|
ALTER TABLE `Indicator` ADD COLUMN `title` VARCHAR(191) NOT NULL DEFAULT '',
|
||||||
|
ADD COLUMN `unit` VARCHAR(191) NOT NULL DEFAULT '',
|
||||||
|
ADD COLUMN `source` VARCHAR(191) NOT NULL DEFAULT '',
|
||||||
|
ADD COLUMN `frequency` VARCHAR(191) NOT NULL DEFAULT 'month';
|
||||||
|
|
||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE `IndicatorPoint` ADD CONSTRAINT `IndicatorPoint_indicatorId_fkey` FOREIGN KEY (`indicatorId`) REFERENCES `Indicator`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
-- 第二步: 明细数据已迁移到 IndicatorPoint, 删除 Indicator.data JSON 列
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE `Indicator` DROP COLUMN `data`;
|
||||||
@ -0,0 +1,2 @@
|
|||||||
|
-- 指标隐藏标记: 数据与获取脚本保留, 前端展示过滤 hidden=true
|
||||||
|
ALTER TABLE `Indicator` ADD COLUMN `hidden` BOOLEAN NOT NULL DEFAULT false;
|
||||||
@ -41,12 +41,29 @@ model Strategy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
model Indicator {
|
model Indicator {
|
||||||
id Int @id @default(autoincrement())
|
id Int @id @default(autoincrement())
|
||||||
name String
|
name String @unique
|
||||||
groupName String
|
groupName String
|
||||||
data Json
|
title String @default("")
|
||||||
createdAt DateTime @default(now())
|
unit String @default("")
|
||||||
updatedAt DateTime @updatedAt
|
source String @default("")
|
||||||
|
frequency String @default("month") // year | quarter | month | day
|
||||||
|
hidden Boolean @default(false) // true = 数据/脚本保留, 但不在前端展示
|
||||||
|
points IndicatorPoint[]
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
updatedAt DateTime @updatedAt
|
||||||
|
}
|
||||||
|
|
||||||
|
model IndicatorPoint {
|
||||||
|
id Int @id @default(autoincrement())
|
||||||
|
indicatorId Int
|
||||||
|
indicator Indicator @relation(fields: [indicatorId], references: [id], onDelete: Cascade)
|
||||||
|
period String // "2024" | "2024-Q1" | "2024-01" | "2024-01-15"
|
||||||
|
value Float
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
updatedAt DateTime @updatedAt
|
||||||
|
|
||||||
|
@@unique([indicatorId, period])
|
||||||
}
|
}
|
||||||
|
|
||||||
model Econ_SowInventory {
|
model Econ_SowInventory {
|
||||||
@ -66,3 +83,5 @@ model ScraperCache {
|
|||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @updatedAt
|
updatedAt DateTime @updatedAt
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
20
readme
20
readme
@ -6,18 +6,18 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## 新闻模块
|
|
||||||
增加一个新闻模块,数据来源是每日夜间 3点,通过妙想 MCP 获取国内外最新经济政治新闻,按影响大小排序10条。
|
|
||||||
存入数据库。
|
|
||||||
|
|
||||||
|
|
||||||
## 报警模块
|
|
||||||
World Bank 中的数据只用来对比妙想 MCP 拉取的数据正确性。当同一时间的同一项数据不同时,记录一个报警。
|
|
||||||
|
|
||||||
|
|
||||||
## 首页
|
## 首页
|
||||||
首页显示新闻模块和报警模块的数据,按照时间最新优先,无限滚动,直到数据库中没有数据为止。
|
首页显示新闻模块和报警模块的数据,按照时间最新优先,无限滚动,直到数据库中没有数据为止。
|
||||||
|
|
||||||
|
|
||||||
|
### 新闻模块
|
||||||
|
增加一个新闻模块,数据来源是每日夜间 3点,通过妙想 MCP 获取国内外最新经济政治新闻,按影响大小排序10条。
|
||||||
|
存入数据库。
|
||||||
|
|
||||||
|
|
||||||
|
### 报警模块
|
||||||
|
World Bank 中的数据只用来对比妙想 MCP 拉取的数据正确性。当同一时间的同一项数据不同时,记录一个报警。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -50,6 +50,59 @@ const INDICATORS = [
|
|||||||
sheets.find((s) => s.items?.[0]?.[0]?.includes('GDP') && s.items[0][0].includes('同比'))
|
sheets.find((s) => s.items?.[0]?.[0]?.includes('GDP') && s.items[0][0].includes('同比'))
|
||||||
|| sheets[0],
|
|| sheets[0],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
// 国债收益率: MCP 返回日频, 用月末降采样成月频点
|
||||||
|
name: 'china-bond-10y',
|
||||||
|
groupName: 'china-macro',
|
||||||
|
title: '中国国债 10 年期收益率',
|
||||||
|
unit: '%',
|
||||||
|
frequency: 'month',
|
||||||
|
tool: 'mx_macro_data',
|
||||||
|
query: '查询中国10年期国债到期收益率 2024年至今 每日数据',
|
||||||
|
pickSheet: (sheets) =>
|
||||||
|
sheets.find((s) => s.items?.some?.((row) => String(row[0] || '').includes('国债到期收益率:10年')))
|
||||||
|
|| sheets[0],
|
||||||
|
parseSheet: (sheet) => monthEndSample(sheet, '国债到期收益率:10年'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'china-bond-1y',
|
||||||
|
groupName: 'china-macro',
|
||||||
|
title: '中国国债 1 年期收益率',
|
||||||
|
unit: '%',
|
||||||
|
frequency: 'month',
|
||||||
|
tool: 'mx_macro_data',
|
||||||
|
query: '查询中国1年期国债到期收益率 2024年至今 每日数据',
|
||||||
|
pickSheet: (sheets) =>
|
||||||
|
sheets.find((s) => s.items?.some?.((row) => String(row[0] || '').includes('国债到期收益率:1年')))
|
||||||
|
|| sheets[0],
|
||||||
|
parseSheet: (sheet) => monthEndSample(sheet, '国债到期收益率:1年'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'china-lpr-1y',
|
||||||
|
groupName: 'china-macro',
|
||||||
|
title: '中国 LPR 1 年期',
|
||||||
|
unit: '%',
|
||||||
|
frequency: 'month',
|
||||||
|
tool: 'mx_macro_data',
|
||||||
|
query: '查询中国LPR 1年期贷款市场报价利率 2024年至今 月度数据,每一个月的数值',
|
||||||
|
pickSheet: (sheets) =>
|
||||||
|
sheets.find((s) => s.sheetName?.includes('宏观数据(月)'))
|
||||||
|
|| sheets[0],
|
||||||
|
parseSheet: (sheet) => pickRowByKeyword(sheet, '(LPR):1年'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'china-lpr-5y',
|
||||||
|
groupName: 'china-macro',
|
||||||
|
title: '中国 LPR 5 年期',
|
||||||
|
unit: '%',
|
||||||
|
frequency: 'month',
|
||||||
|
tool: 'mx_macro_data',
|
||||||
|
query: '查询中国LPR 5年期以上贷款市场报价利率 2024年至今 月度数据,每一个月的数值',
|
||||||
|
pickSheet: (sheets) =>
|
||||||
|
sheets.find((s) => s.sheetName?.includes('宏观数据(月)'))
|
||||||
|
|| sheets[0],
|
||||||
|
parseSheet: (sheet) => pickRowByKeyword(sheet, '(LPR):5年'),
|
||||||
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
export const META = {
|
export const META = {
|
||||||
@ -139,6 +192,44 @@ function defaultParseSheet(sheet) {
|
|||||||
return out.reverse() // 从老到新
|
return out.reverse() // 从老到新
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 宽表 → 长表, 指定 item 行 (按指标全名前缀匹配), 日频列降采样为月末值
|
||||||
|
// 例: columns=["指标","来源","2026-08-05","2026-08-04",...] → [{period:"2024-01",value},...]
|
||||||
|
function monthEndSample(sheet, keyword) {
|
||||||
|
if (!sheet || !sheet.columns || !sheet.items) return []
|
||||||
|
const row = sheet.items.find((r) => String(r[0] || '').includes(keyword))
|
||||||
|
if (!row) return []
|
||||||
|
const cols = sheet.columns
|
||||||
|
const dates = cols.slice(2) // 新 → 老
|
||||||
|
const values = row.slice(2)
|
||||||
|
const out = []
|
||||||
|
const seen = new Set()
|
||||||
|
for (let i = 0; i < dates.length; i++) {
|
||||||
|
const v = parseFloat(values[i])
|
||||||
|
const m = String(dates[i] || '').slice(0, 7) // "2024-01-02" → "2024-01"
|
||||||
|
if (!/^\d{4}-\d{2}$/.test(m) || Number.isNaN(v)) continue
|
||||||
|
if (seen.has(m)) continue // 列是降序, 第一次遇到的即当月最后一个交易日
|
||||||
|
seen.add(m)
|
||||||
|
out.push({ period: m, value: v })
|
||||||
|
}
|
||||||
|
return out.reverse() // 从老到新
|
||||||
|
}
|
||||||
|
|
||||||
|
// 宽表 → 长表, 指定 item 行 (按指标全名前缀匹配), 保留原频率 (月/季/年)
|
||||||
|
function pickRowByKeyword(sheet, keyword) {
|
||||||
|
if (!sheet || !sheet.columns || !sheet.items) return []
|
||||||
|
const row = sheet.items.find((r) => String(r[0] || '').includes(keyword))
|
||||||
|
if (!row) return []
|
||||||
|
const cols = sheet.columns
|
||||||
|
const dates = cols.slice(2)
|
||||||
|
const values = row.slice(2)
|
||||||
|
const out = []
|
||||||
|
for (let i = 0; i < dates.length; i++) {
|
||||||
|
const v = parseFloat(values[i])
|
||||||
|
if (!Number.isNaN(v)) out.push({ period: String(dates[i]), value: v })
|
||||||
|
}
|
||||||
|
return out.reverse() // 从老到新
|
||||||
|
}
|
||||||
|
|
||||||
// ====== fetcher 入口 ======
|
// ====== fetcher 入口 ======
|
||||||
|
|
||||||
export async function listAvailableTools() {
|
export async function listAvailableTools() {
|
||||||
@ -156,6 +247,7 @@ export async function fetchAll(opts = {}) {
|
|||||||
throw new Error('eastmoney-mcp: INDICATORS 数组为空, 加新指标见文件顶部注释')
|
throw new Error('eastmoney-mcp: INDICATORS 数组为空, 加新指标见文件顶部注释')
|
||||||
}
|
}
|
||||||
const skip = opts.skipNames || new Set()
|
const skip = opts.skipNames || new Set()
|
||||||
|
const force = opts.forceNames || new Set()
|
||||||
const only = opts.onlyNames || null
|
const only = opts.onlyNames || null
|
||||||
|
|
||||||
const key = process.env.EM_API_KEY
|
const key = process.env.EM_API_KEY
|
||||||
@ -165,7 +257,7 @@ export async function fetchAll(opts = {}) {
|
|||||||
|
|
||||||
const results = []
|
const results = []
|
||||||
for (const cfg of INDICATORS) {
|
for (const cfg of INDICATORS) {
|
||||||
if (skip.has(cfg.name)) {
|
if (skip.has(cfg.name) && !force.has(cfg.name)) {
|
||||||
console.log(`[MCP] ${cfg.name} 跳过 (DB 已存在)`)
|
console.log(`[MCP] ${cfg.name} 跳过 (DB 已存在)`)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -199,7 +291,7 @@ export async function fetchAll(opts = {}) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 全部被 DB 优先跳过时, 返回显式标记而不是空数组 (避免被误判为失败)
|
// 全部被 DB 优先跳过时, 返回显式标记而不是空数组 (避免被误判为失败)
|
||||||
if (results.length === 0 && INDICATORS.every((cfg) => skip.has(cfg.name))) {
|
if (results.length === 0 && INDICATORS.every((cfg) => skip.has(cfg.name) && !force.has(cfg.name))) {
|
||||||
return { skipped: true, reason: 'DB 已存在全部指标' }
|
return { skipped: true, reason: 'DB 已存在全部指标' }
|
||||||
}
|
}
|
||||||
return results
|
return results
|
||||||
@ -208,3 +300,4 @@ export async function fetchAll(opts = {}) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -36,7 +36,8 @@ export function checkEnv(required) {
|
|||||||
|
|
||||||
// 加载并运行所有启用的 fetcher, 返回 [{ name, ok, items, error, skipped }]
|
// 加载并运行所有启用的 fetcher, 返回 [{ name, ok, items, error, skipped }]
|
||||||
// 错误隔离: 一个 fetcher 挂了不影响其他
|
// 错误隔离: 一个 fetcher 挂了不影响其他
|
||||||
// opts.skipNames: Set<string> — DB 优先, 已存在的指标名, 透传给 fetcher
|
// opts.skipNames: Set<string> — DB 优先, 已存在的指标名, 透传给 fetcher
|
||||||
|
// opts.forceNames: Set<string> — 强制刷新名单, 即使 skipNames 里有也照拉
|
||||||
export async function runFetchers(opts = {}) {
|
export async function runFetchers(opts = {}) {
|
||||||
const results = []
|
const results = []
|
||||||
for (const meta of FETCHERS) {
|
for (const meta of FETCHERS) {
|
||||||
@ -57,7 +58,7 @@ export async function runFetchers(opts = {}) {
|
|||||||
throw new Error('fetcher 必须导出 META 和 fetchAll')
|
throw new Error('fetcher 必须导出 META 和 fetchAll')
|
||||||
}
|
}
|
||||||
console.log(`[Fetcher] ${meta.name} 开始...`)
|
console.log(`[Fetcher] ${meta.name} 开始...`)
|
||||||
const out = await mod.fetchAll({ skipNames: opts.skipNames, onlyNames: opts.onlyNames })
|
const out = await mod.fetchAll({ skipNames: opts.skipNames, onlyNames: opts.onlyNames, forceNames: opts.forceNames })
|
||||||
// fetcher 可返回 { skipped: true, reason } 表示"全部被 DB 优先跳过", 不算失败
|
// fetcher 可返回 { skipped: true, reason } 表示"全部被 DB 优先跳过", 不算失败
|
||||||
if (out && out.skipped) {
|
if (out && out.skipped) {
|
||||||
results.push({ name: meta.name, skipped: true, reason: out.reason })
|
results.push({ name: meta.name, skipped: true, reason: out.reason })
|
||||||
|
|||||||
84
scripts/migrate-indicator-points.cjs
Normal file
84
scripts/migrate-indicator-points.cjs
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
/**
|
||||||
|
* 一次性数据迁移: 把 Indicator.data (JSON) 拆分到 IndicatorPoint 明细表
|
||||||
|
* 用法: 在迁移 A (建表+加列) 之后、迁移 B (删 data 列) 之前运行
|
||||||
|
* 幂等: 同 (indicatorId, period) 重复插入会更新 value, 可安全重跑
|
||||||
|
*/
|
||||||
|
require('dotenv').config()
|
||||||
|
const mysql = require('mysql2/promise')
|
||||||
|
|
||||||
|
function parseUrl(url) {
|
||||||
|
const u = new URL(url)
|
||||||
|
return {
|
||||||
|
host: u.hostname,
|
||||||
|
port: Number(u.port) || 3306,
|
||||||
|
user: decodeURIComponent(u.username),
|
||||||
|
password: decodeURIComponent(u.password),
|
||||||
|
database: u.pathname.replace(/^\//, ''),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据 row 的时间字段推断频率: year | quarter | month | day
|
||||||
|
function inferFrequency(row) {
|
||||||
|
if (row && row.month !== undefined) return 'month'
|
||||||
|
if (row && row.year !== undefined) return 'year'
|
||||||
|
const p = String((row && row.period) || '')
|
||||||
|
if (/^\d{4}$/.test(p)) return 'year'
|
||||||
|
if (/^\d{4}-Q[1-4]$/.test(p)) return 'quarter'
|
||||||
|
if (/^\d{4}-\d{2}$/.test(p)) return 'month'
|
||||||
|
if (/^\d{4}-\d{2}-\d{2}$/.test(p)) return 'day'
|
||||||
|
return 'month'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 统一 row 的时间字段为 period
|
||||||
|
function periodOf(row) {
|
||||||
|
if (!row) return ''
|
||||||
|
return String(row.period !== undefined ? row.period : (row.month !== undefined ? row.month : row.year))
|
||||||
|
}
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
const conn = await mysql.createConnection(parseUrl(process.env.DATABASE_URL))
|
||||||
|
try {
|
||||||
|
const [rows] = await conn.execute('SELECT id, name, groupName, data FROM Indicator')
|
||||||
|
console.log('[Migrate] 读取', rows.length, '个 Indicator')
|
||||||
|
|
||||||
|
let points = 0, updated = 0
|
||||||
|
for (const ind of rows) {
|
||||||
|
// mysql2 对 JSON 列已自动解析为对象, 兼容字符串兜底
|
||||||
|
let data = ind.data
|
||||||
|
if (typeof data === 'string') {
|
||||||
|
try { data = JSON.parse(data) } catch { data = null }
|
||||||
|
}
|
||||||
|
const title = (data && data.title) || ind.name
|
||||||
|
const unit = (data && data.unit) || ''
|
||||||
|
const source = (data && data.source) || ''
|
||||||
|
const rowsArr = (data && Array.isArray(data.rows)) ? data.rows : []
|
||||||
|
const freq = rowsArr.length ? inferFrequency(rowsArr[0]) : 'month'
|
||||||
|
|
||||||
|
// 更新 Indicator 元数据列
|
||||||
|
await conn.execute(
|
||||||
|
'UPDATE Indicator SET title=?, unit=?, source=?, frequency=?, updatedAt=NOW(3) WHERE id=?',
|
||||||
|
[title, unit, source, freq, ind.id],
|
||||||
|
)
|
||||||
|
updated++
|
||||||
|
|
||||||
|
// 写入明细
|
||||||
|
for (const r of rowsArr) {
|
||||||
|
const period = periodOf(r)
|
||||||
|
const value = Number(r.value)
|
||||||
|
if (!period || Number.isNaN(value)) continue
|
||||||
|
const [res] = await conn.execute(
|
||||||
|
'INSERT INTO IndicatorPoint (indicatorId, period, value, createdAt, updatedAt) VALUES (?, ?, ?, NOW(3), NOW(3)) ' +
|
||||||
|
'ON DUPLICATE KEY UPDATE value=VALUES(value), updatedAt=NOW(3)',
|
||||||
|
[ind.id, period, value],
|
||||||
|
)
|
||||||
|
points += (res.affectedRows > 0 ? 1 : 0)
|
||||||
|
}
|
||||||
|
console.log('[Migrate]', ind.name, '->', rowsArr.length, '个点, 频率', freq)
|
||||||
|
}
|
||||||
|
console.log('[Migrate] 完成: 更新', updated, '个 Indicator, 写入/更新', points, '个明细点')
|
||||||
|
} finally {
|
||||||
|
await conn.end()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
main().catch((e) => { console.error('[Migrate] 失败:', e); process.exit(1) })
|
||||||
@ -1,7 +1,12 @@
|
|||||||
/**
|
/**
|
||||||
* 拉所有启用的数据源, upsert 到 Indicator 表
|
* 拉所有启用的数据源, upsert 到 Indicator + IndicatorPoint 明细表
|
||||||
* 用法: npm run data:refresh
|
* 用法:
|
||||||
* 幂等: 同 name 覆盖 data, 跨源独立, 错误隔离
|
* npm run data:refresh # 只拉 DB 里没有的指标
|
||||||
|
* npm run data:refresh -- --force a,b,c # 强制刷新指定指标 (忽略 DB 已有)
|
||||||
|
*
|
||||||
|
* 数据结构 (2026-08 重构):
|
||||||
|
* Indicator 元数据: name/groupName/title/unit/source/frequency/hidden
|
||||||
|
* IndicatorPoint 明细: (indicatorId, period, value), period 兼容年/季/月/日
|
||||||
*
|
*
|
||||||
* DB 优先策略:
|
* DB 优先策略:
|
||||||
* 1. 先从 DB 查已存在的 name 集合
|
* 1. 先从 DB 查已存在的 name 集合
|
||||||
@ -14,6 +19,15 @@
|
|||||||
require('dotenv').config()
|
require('dotenv').config()
|
||||||
const mysql = require('mysql2/promise')
|
const mysql = require('mysql2/promise')
|
||||||
|
|
||||||
|
// 隐藏指标: 数据与获取脚本保留, 但不参与前端展示 (API 过滤)
|
||||||
|
const HIDDEN_INDICATORS = new Set([
|
||||||
|
'china-gdp-usd', // 中国 GDP (现价美元)
|
||||||
|
'china-gdp-growth', // 中国 GDP 同比 (World Bank)
|
||||||
|
'china-gdp-yoy', // 中国 GDP 同比 (妙想季度)
|
||||||
|
'china-unemploy', // 中国失业率
|
||||||
|
'usa-gdp-usd', // 美国 GDP
|
||||||
|
])
|
||||||
|
|
||||||
function parseUrl(url) {
|
function parseUrl(url) {
|
||||||
const u = new URL(url)
|
const u = new URL(url)
|
||||||
return {
|
return {
|
||||||
@ -25,13 +39,63 @@ function parseUrl(url) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function upsertIndicator(conn, payload) {
|
function parseForceArg(argv) {
|
||||||
const sql =
|
const i = argv.indexOf('--force')
|
||||||
'INSERT INTO `Indicator` (`name`, `groupName`, `data`, `createdAt`, `updatedAt`) ' +
|
if (i === -1) return new Set()
|
||||||
'VALUES (?, ?, ?, NOW(3), NOW(3)) ' +
|
return new Set(String(argv[i + 1] || '').split(',').map((s) => s.trim()).filter(Boolean))
|
||||||
'ON DUPLICATE KEY UPDATE `groupName` = VALUES(`groupName`), `data` = VALUES(`data`), `updatedAt` = NOW(3)'
|
}
|
||||||
const [r] = await conn.execute(sql, [payload.name, payload.groupName, JSON.stringify(payload.data)])
|
|
||||||
return r.affectedRows
|
// 推断频率: year | quarter | month | day (优先用 fetcher 显式声明)
|
||||||
|
function inferFrequency(data) {
|
||||||
|
if (data && data.frequency) return data.frequency
|
||||||
|
const p = String(((data && data.rows) || [])[0]?.period || '')
|
||||||
|
if (/^\d{4}$/.test(p)) return 'year'
|
||||||
|
if (/^\d{4}-Q[1-4]$/.test(p)) return 'quarter'
|
||||||
|
if (/^\d{4}-\d{2}$/.test(p)) return 'month'
|
||||||
|
if (/^\d{4}-\d{2}-\d{2}$/.test(p)) return 'day'
|
||||||
|
return 'month'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 写 Indicator 元数据 + 全量替换明细点 (每指标一个事务)
|
||||||
|
async function upsertIndicatorWithPoints(conn, payload) {
|
||||||
|
const { name, groupName, data, hidden } = payload
|
||||||
|
const title = data.title || name
|
||||||
|
const unit = data.unit || ''
|
||||||
|
const source = data.source || ''
|
||||||
|
const frequency = inferFrequency(data)
|
||||||
|
const rows = Array.isArray(data.rows) ? data.rows : []
|
||||||
|
|
||||||
|
await conn.beginTransaction()
|
||||||
|
try {
|
||||||
|
const [res] = await conn.execute(
|
||||||
|
'INSERT INTO `Indicator` (`name`, `groupName`, `title`, `unit`, `source`, `frequency`, `hidden`, `createdAt`, `updatedAt`) ' +
|
||||||
|
'VALUES (?, ?, ?, ?, ?, ?, ?, NOW(3), NOW(3)) ' +
|
||||||
|
'ON DUPLICATE KEY UPDATE `groupName` = VALUES(`groupName`), `title` = VALUES(`title`), ' +
|
||||||
|
'`unit` = VALUES(`unit`), `source` = VALUES(`source`), `frequency` = VALUES(`frequency`), ' +
|
||||||
|
'`hidden` = VALUES(`hidden`), `updatedAt` = NOW(3)',
|
||||||
|
[name, groupName, title, unit, source, frequency, hidden ? 1 : 0],
|
||||||
|
)
|
||||||
|
const indicatorId = res.insertId
|
||||||
|
|
||||||
|
// 明细: 先删旧点再插入新点 (全量替换, 保证与数据源一致)
|
||||||
|
await conn.execute('DELETE FROM `IndicatorPoint` WHERE `indicatorId` = ?', [indicatorId])
|
||||||
|
let points = 0
|
||||||
|
for (const r of rows) {
|
||||||
|
const period = String(r.period !== undefined ? r.period : (r.month !== undefined ? r.month : r.year))
|
||||||
|
const value = Number(r.value)
|
||||||
|
if (!period || Number.isNaN(value)) continue
|
||||||
|
await conn.execute(
|
||||||
|
'INSERT INTO `IndicatorPoint` (`indicatorId`, `period`, `value`, `createdAt`, `updatedAt`) VALUES (?, ?, ?, NOW(3), NOW(3))',
|
||||||
|
[indicatorId, period, value],
|
||||||
|
)
|
||||||
|
points++
|
||||||
|
}
|
||||||
|
await conn.commit()
|
||||||
|
return { indicatorId, points }
|
||||||
|
} catch (e) {
|
||||||
|
await conn.rollback()
|
||||||
|
throw e
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function fetchExistingNames(conn) {
|
async function fetchExistingNames(conn) {
|
||||||
@ -44,48 +108,63 @@ async function main() {
|
|||||||
console.error('缺少 DATABASE_URL 环境变量')
|
console.error('缺少 DATABASE_URL 环境变量')
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
}
|
}
|
||||||
|
const force = parseForceArg(process.argv.slice(2))
|
||||||
|
if (force.size) console.log('[Refresh] 强制刷新: ' + [...force].join(', '))
|
||||||
|
|
||||||
const conn = await mysql.createConnection(parseUrl(process.env.DATABASE_URL))
|
const conn = await mysql.createConnection(parseUrl(process.env.DATABASE_URL))
|
||||||
try {
|
try {
|
||||||
// 1) 查 DB 已存在的指标名
|
// 1) 查 DB 已存在的指标名
|
||||||
const existing = await fetchExistingNames(conn)
|
const existing = await fetchExistingNames(conn)
|
||||||
console.log(`[Refresh] DB 已有 ${existing.size} 个指标: ${[...existing].join(', ') || '(空)'}`)
|
console.log('[Refresh] DB 已有 ' + existing.size + ' 个指标: ' + ([...existing].join(', ') || '(空)'))
|
||||||
|
|
||||||
// 2) 跑所有 fetcher, 传入 existing (DB 优先)
|
// 2) 跑所有 fetcher, 传入 existing + force (DB 优先, force 覆盖)
|
||||||
const { runFetchers } = await import('./fetchers/index.js')
|
const { runFetchers } = await import('./fetchers/index.js')
|
||||||
const fetcherResults = await runFetchers({ skipNames: existing })
|
const fetcherResults = await runFetchers({ skipNames: existing, forceNames: force })
|
||||||
|
|
||||||
// 3) 汇总
|
// 3) 汇总: force 名单里的指标即使 DB 已有也写入
|
||||||
const allItems = []
|
const allItems = []
|
||||||
let skipped = 0, failed = 0
|
let skipped = 0, failed = 0
|
||||||
for (const r of fetcherResults) {
|
for (const r of fetcherResults) {
|
||||||
if (r.skipped) { skipped++; continue }
|
if (r.skipped) { skipped++; continue }
|
||||||
if (!r.ok) { failed++; continue }
|
if (!r.ok) { failed++; continue }
|
||||||
// fetcher 内部已经按 skipNames 过滤过, 这里再做一次防御性去重
|
|
||||||
for (const it of r.items) {
|
for (const it of r.items) {
|
||||||
if (existing.has(it.name)) continue
|
if (existing.has(it.name) && !force.has(it.name)) continue
|
||||||
allItems.push(it)
|
allItems.push(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
console.log(`\n[Refresh] 汇总: ${allItems.length} 个新指标 (跳过 ${skipped} 个数据源, 失败 ${failed} 个, DB 已存在 ${existing.size} 个)`)
|
console.log('\n[Refresh] 汇总: ' + allItems.length + ' 个指标待写 (跳过 ' + skipped + ' 个数据源, 失败 ' + failed + ' 个, DB 已存在 ' + existing.size + ' 个)')
|
||||||
|
|
||||||
if (failed > 0) {
|
if (failed > 0) {
|
||||||
console.error('[Refresh] 警告: 有数据源失败, 仅写入成功的指标')
|
console.error('[Refresh] 警告: 有数据源失败, 仅写入成功的指标')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 5) 同步隐藏标记: 即使指标被 DB 优先跳过, 名单内的也确保 hidden=true
|
||||||
|
if (HIDDEN_INDICATORS.size > 0) {
|
||||||
|
const names = [...HIDDEN_INDICATORS]
|
||||||
|
const ph = names.map(() => '?').join(',')
|
||||||
|
const sql = "UPDATE `Indicator` SET `hidden` = 1, `updatedAt` = NOW(3) WHERE `name` IN (" + ph + ")"
|
||||||
|
await conn.execute(sql, names)
|
||||||
|
console.log('[Refresh] 同步隐藏标记: ' + names.length + ' 个指标 hidden=true (数据保留, 不展示)')
|
||||||
|
}
|
||||||
|
|
||||||
if (allItems.length === 0) {
|
if (allItems.length === 0) {
|
||||||
console.log('[Refresh] 无新指标, 不写库 (DB 优先策略生效)')
|
console.log('[Refresh] 无指标待写, 不写库 (DB 优先策略生效)')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4) 写库
|
// 4) 写库
|
||||||
console.log('[Refresh] 写入数据库...')
|
console.log('[Refresh] 写入数据库...')
|
||||||
let ins = 0, upd = 0
|
let ins = 0, upd = 0, totalPoints = 0
|
||||||
for (const it of allItems) {
|
for (const it of allItems) {
|
||||||
const n = await upsertIndicator(conn, { name: it.name, groupName: it.groupName, data: it.data })
|
const hidden = HIDDEN_INDICATORS.has(it.name)
|
||||||
if (n === 1) ins++
|
const { points } = await upsertIndicatorWithPoints(conn, { name: it.name, groupName: it.groupName, data: it.data, hidden })
|
||||||
else if (n === 2) upd++
|
if (points > 0) ins++
|
||||||
|
else upd++
|
||||||
|
totalPoints += points
|
||||||
|
console.log('[Refresh] ' + it.name + (hidden ? ' (hidden)' : '') + ': ' + points + ' 个明细点')
|
||||||
}
|
}
|
||||||
console.log(`[Refresh] 写入完成: ${ins} 新增, ${upd} 更新\n`)
|
console.log('[Refresh] 写入完成: ' + ins + ' 个指标有数据, ' + upd + ' 个无数据, 共 ' + totalPoints + ' 个明细点\n')
|
||||||
|
|
||||||
} finally {
|
} finally {
|
||||||
await conn.end()
|
await conn.end()
|
||||||
}
|
}
|
||||||
@ -95,3 +174,4 @@ main().catch((e) => {
|
|||||||
console.error('[Refresh] 异常:', e)
|
console.error('[Refresh] 异常:', e)
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@ -92,16 +92,8 @@ async function main() {
|
|||||||
}
|
}
|
||||||
console.log('[Strategy] upsert 策略: ' + n2 + ' 行 (1=新增, 2=更新)');
|
console.log('[Strategy] upsert 策略: ' + n2 + ' 行 (1=新增, 2=更新)');
|
||||||
|
|
||||||
// Indicator 表: 改由 scripts/refresh-indicators.cjs 从 World Bank API 拉取最新数据
|
// Indicator 表: 改由 scripts/refresh-indicators.cjs 管理 (2026-08 重构后数据存 IndicatorPoint 明细表)
|
||||||
// 旧 4 个金融指标 (国债/LPR) 无稳定 JSON 数据源, 暂不维护
|
// 本脚本不再写入 Indicator, 如需初始化指标请运行 npm run data:refresh
|
||||||
const indicators = [];
|
|
||||||
let n3 = 0;
|
|
||||||
for (const i of indicators) {
|
|
||||||
n3 += await upsertByName(conn, 'Indicator',
|
|
||||||
{ name: i.name, groupName: i.groupName, data: JSON.stringify(i.data), updatedAt: new Date() },
|
|
||||||
'name');
|
|
||||||
}
|
|
||||||
console.log('[Indicator] upsert 指标: ' + n3 + ' 行 (1=新增, 2=更新)');
|
|
||||||
|
|
||||||
const article = {
|
const article = {
|
||||||
title: '欢迎使用 iBoard',
|
title: '欢迎使用 iBoard',
|
||||||
|
|||||||
@ -6,10 +6,26 @@ const router = Router()
|
|||||||
|
|
||||||
router.use(authRequired)
|
router.use(authRequired)
|
||||||
|
|
||||||
|
// 指标列表: 元数据 + 明细点, 过滤 hidden (数据与脚本保留, 仅不展示)
|
||||||
router.get('/indicators', async (_req, res, next) => {
|
router.get('/indicators', async (_req, res, next) => {
|
||||||
try {
|
try {
|
||||||
const rows = await prisma.indicator.findMany({ orderBy: [{ groupName: 'asc' }, { name: 'asc' }] })
|
const rows = await prisma.indicator.findMany({
|
||||||
res.json({ indicators: rows })
|
where: { hidden: false },
|
||||||
|
include: { points: { orderBy: { period: 'asc' } } },
|
||||||
|
orderBy: [{ groupName: 'asc' }, { name: 'asc' }],
|
||||||
|
})
|
||||||
|
// 组装前端友好结构: points 保持从老到新
|
||||||
|
const indicators = rows.map((r) => ({
|
||||||
|
id: r.id,
|
||||||
|
name: r.name,
|
||||||
|
groupName: r.groupName,
|
||||||
|
title: r.title,
|
||||||
|
unit: r.unit,
|
||||||
|
source: r.source,
|
||||||
|
frequency: r.frequency,
|
||||||
|
points: r.points.map((p) => ({ period: p.period, value: p.value })),
|
||||||
|
}))
|
||||||
|
res.json({ indicators })
|
||||||
} catch (e) { next(e) }
|
} catch (e) { next(e) }
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@ -45,10 +45,13 @@ export default function MacroPage() {
|
|||||||
if (next) navigate(next.path)
|
if (next) navigate(next.path)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 详情页 /macro/articles/:slug 单独走 React Router 渲染, 不参与滑屏
|
// 详情页 /macro/articles/:slug 和 /macro/data/:name 单独走 React Router 渲染, 不参与滑屏
|
||||||
if (location.pathname.match(/^\/macro\/articles\/[^/]+$/)) {
|
// 这样浏览器/手机物理返回键也能正常回到列表
|
||||||
|
if (location.pathname.match(/^\/macro\/(articles|data|strategy)\/[^/]+$/)) {
|
||||||
return (
|
return (
|
||||||
<Routes>
|
<Routes>
|
||||||
|
<Route path="data/:name" element={<DataView />} />
|
||||||
|
<Route path="strategy/:name" element={<StrategyView />} />
|
||||||
<Route path="articles/:slug" element={<ArticleDetail />} />
|
<Route path="articles/:slug" element={<ArticleDetail />} />
|
||||||
</Routes>
|
</Routes>
|
||||||
)
|
)
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
|
import { useParams, useNavigate } from 'react-router-dom'
|
||||||
import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer } from 'recharts'
|
import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer } from 'recharts'
|
||||||
import { Card, List, NavBar } from 'antd-mobile'
|
import { Card, List, NavBar } from 'antd-mobile'
|
||||||
import { api } from '../../api/client.js'
|
import { api } from '../../api/client.js'
|
||||||
@ -7,6 +8,9 @@ import TrendBadge, { calcTrend, lastPoint } from '../../components/TrendBadge.js
|
|||||||
// 经济数据
|
// 经济数据
|
||||||
// 列表态 (默认): 列出所有指标, 每行显示最新值 + 趋势徽标, 点击进入详情
|
// 列表态 (默认): 列出所有指标, 每行显示最新值 + 趋势徽标, 点击进入详情
|
||||||
// 详情态: 顶部 NavBar (返回) + 折线图 + 数据表
|
// 详情态: 顶部 NavBar (返回) + 折线图 + 数据表
|
||||||
|
// 频率中文标签 (对应 Indicator.frequency)
|
||||||
|
const FREQ_LABEL = { year: '年', quarter: '季', month: '月', day: '日' }
|
||||||
|
|
||||||
// 统一数据行的时间字段: 兼容 {month}/{year}/{period} 三种存储形状
|
// 统一数据行的时间字段: 兼容 {month}/{year}/{period} 三种存储形状
|
||||||
function periodOf(r) {
|
function periodOf(r) {
|
||||||
return (r && (r.period || r.month || r.year)) || ''
|
return (r && (r.period || r.month || r.year)) || ''
|
||||||
@ -16,7 +20,9 @@ export default function DataView() {
|
|||||||
const [indicators, setIndicators] = useState([])
|
const [indicators, setIndicators] = useState([])
|
||||||
const [err, setErr] = useState('')
|
const [err, setErr] = useState('')
|
||||||
const [loading, setLoading] = useState(true)
|
const [loading, setLoading] = useState(true)
|
||||||
const [selected, setSelected] = useState(null) // null = 列表态, 名称 = 详情态
|
// 路由驱动: /macro/data 列表, /macro/data/:name 详情, 浏览器/手机返回键天然可用
|
||||||
|
const { name } = useParams()
|
||||||
|
const navigate = useNavigate()
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let cancelled = false
|
let cancelled = false
|
||||||
@ -35,41 +41,33 @@ export default function DataView() {
|
|||||||
if (err) return <div className="error-banner">{err}</div>
|
if (err) return <div className="error-banner">{err}</div>
|
||||||
if (!indicators.length) return <div className="empty">暂无指标数据, 请先执行 npm run db:seed</div>
|
if (!indicators.length) return <div className="empty">暂无指标数据, 请先执行 npm run db:seed</div>
|
||||||
|
|
||||||
// 详情态
|
// 详情态 (路径 /macro/data/:name)
|
||||||
if (selected) {
|
if (name) {
|
||||||
const cur = indicators.find((i) => i.name === selected)
|
const cur = indicators.find((i) => i.name === name)
|
||||||
if (cur) return <DataDetail indicator={cur} onBack={() => setSelected(null)} />
|
if (cur) return <DataDetail indicator={cur} onBack={() => navigate('/macro/data')} />
|
||||||
}
|
}
|
||||||
|
|
||||||
// 列表态
|
// 列表态
|
||||||
const labelOf = (i) => (i.data && i.data.title) || i.name
|
const labelOf = (i) => i.title || i.name
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="list-page">
|
<div className="list-page">
|
||||||
<div className="page-title">经济数据</div>
|
<div className="page-title">经济数据</div>
|
||||||
<List>
|
<List>
|
||||||
{indicators.map((i) => {
|
{indicators.map((i) => {
|
||||||
const lp = lastPoint(i.data)
|
const lp = lastPoint({ rows: i.points || [] })
|
||||||
const { trend, change } = calcTrend(i.data && i.data.rows)
|
const { trend, change } = calcTrend(i.points || [])
|
||||||
const unit = (i.data && i.data.unit) || ''
|
const unit = i.unit || ''
|
||||||
return (
|
return (
|
||||||
<List.Item
|
<List.Item
|
||||||
key={i.name}
|
key={i.name}
|
||||||
title={labelOf(i)}
|
title={labelOf(i)}
|
||||||
description={lp ? <><b>{lp.value}{unit}</b> · {periodOf(lp)}</> : '暂无数据'}
|
description={lp ? <><b>{lp.value}{unit}</b> · {periodOf(lp)}</> : '暂无数据'}
|
||||||
extra={
|
extra={<TrendBadge trend={trend} />}
|
||||||
<div className="row-meta">
|
|
||||||
{lp && Math.abs(change) >= 1 && (
|
|
||||||
<span className="row-change">
|
|
||||||
{change > 0 ? '+' : ''}{change.toFixed(1)}%
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
<TrendBadge trend={trend} />
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
arrowIcon
|
arrowIcon
|
||||||
clickable
|
clickable
|
||||||
onClick={() => setSelected(i.name)}
|
onClick={() => navigate('/macro/data/' + i.name)}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
@ -81,19 +79,19 @@ export default function DataView() {
|
|||||||
// 详情: 折线图 + 数据表
|
// 详情: 折线图 + 数据表
|
||||||
function DataDetail({ indicator, onBack }) {
|
function DataDetail({ indicator, onBack }) {
|
||||||
const i = indicator
|
const i = indicator
|
||||||
const rows = (i.data && i.data.rows) || []
|
const rows = (i.points || [])
|
||||||
// 图表 X 轴统一用 period 字段
|
// 图表 X 轴统一用 period 字段
|
||||||
const chartRows = rows.map((r) => ({ ...r, period: periodOf(r) }))
|
const chartRows = rows.map((r) => ({ ...r, period: periodOf(r) }))
|
||||||
const lp = lastPoint(i.data)
|
const lp = lastPoint({ rows })
|
||||||
const { trend } = calcTrend(rows)
|
const { trend } = calcTrend(rows)
|
||||||
const title = (i.data && i.data.title) || i.name
|
const title = i.title || i.name
|
||||||
return (
|
return (
|
||||||
<div className="detail-page">
|
<div className="detail-page">
|
||||||
<NavBar onBack={onBack}>{title}</NavBar>
|
<NavBar onBack={onBack}>{title}</NavBar>
|
||||||
<Card className="detail-card">
|
<Card className="detail-card">
|
||||||
<div className="detail-meta">
|
<div className="detail-meta">
|
||||||
单位 {i.data.unit || '-'} · 来源 {i.data.source || 'seed'} ·
|
单位 {i.unit || '-'} · 频率 {FREQ_LABEL[i.frequency] || i.frequency || '-'} · 来源 {i.source || 'seed'} ·
|
||||||
{lp && <> 最新 <b style={{ color: 'var(--color-text)' }}>{lp.value}{i.data.unit || ''}</b> ({periodOf(lp)}) </>}
|
{lp && <> 最新 <b style={{ color: 'var(--color-text)' }}>{lp.value}{i.unit || ''}</b> ({periodOf(lp)}) </>}
|
||||||
<TrendBadge trend={trend} />
|
<TrendBadge trend={trend} />
|
||||||
</div>
|
</div>
|
||||||
<div className="chart-wrap">
|
<div className="chart-wrap">
|
||||||
@ -104,7 +102,7 @@ function DataDetail({ indicator, onBack }) {
|
|||||||
<YAxis tick={{ fontSize: 11 }} />
|
<YAxis tick={{ fontSize: 11 }} />
|
||||||
<Tooltip />
|
<Tooltip />
|
||||||
<Legend />
|
<Legend />
|
||||||
<Line type="monotone" dataKey="value" name={i.data.unit || '值'} stroke="#1677ff" strokeWidth={2} dot={{ r: 3 }} />
|
<Line type="monotone" dataKey="value" name={i.unit || '值'} stroke="#1677ff" strokeWidth={2} dot={{ r: 3 }} />
|
||||||
</LineChart>
|
</LineChart>
|
||||||
</ResponsiveContainer>
|
</ResponsiveContainer>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
|
import { useParams, useNavigate } from 'react-router-dom'
|
||||||
import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer } from 'recharts'
|
import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer } from 'recharts'
|
||||||
import { Card, List, NavBar } from 'antd-mobile'
|
import { Card, List, NavBar } from 'antd-mobile'
|
||||||
import { api } from '../../api/client.js'
|
import { api } from '../../api/client.js'
|
||||||
@ -26,7 +27,9 @@ export default function StrategyView() {
|
|||||||
const [strategies, setStrategies] = useState([])
|
const [strategies, setStrategies] = useState([])
|
||||||
const [err, setErr] = useState('')
|
const [err, setErr] = useState('')
|
||||||
const [loading, setLoading] = useState(true)
|
const [loading, setLoading] = useState(true)
|
||||||
const [selected, setSelected] = useState(null)
|
// 路由驱动: /macro/strategy 列表, /macro/strategy/:name 详情, 浏览器/手机返回键天然可用
|
||||||
|
const { name } = useParams()
|
||||||
|
const navigate = useNavigate()
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let cancelled = false
|
let cancelled = false
|
||||||
@ -42,10 +45,10 @@ export default function StrategyView() {
|
|||||||
if (err) return <div className="error-banner">{err}</div>
|
if (err) return <div className="error-banner">{err}</div>
|
||||||
if (!strategies.length) return <div className="empty">暂无策略数据</div>
|
if (!strategies.length) return <div className="empty">暂无策略数据</div>
|
||||||
|
|
||||||
// 详情态
|
// 详情态 (路径 /macro/strategy/:name)
|
||||||
if (selected) {
|
if (name) {
|
||||||
const cur = strategies.find((s) => s.name === selected)
|
const cur = strategies.find((s) => s.name === name)
|
||||||
if (cur) return <StrategyDetail strategy={cur} onBack={() => setSelected(null)} />
|
if (cur) return <StrategyDetail strategy={cur} onBack={() => navigate('/macro/strategy')} />
|
||||||
}
|
}
|
||||||
|
|
||||||
// 列表态: 主指标 = 债务/GDP, 趋势基于其最近变化
|
// 列表态: 主指标 = 债务/GDP, 趋势基于其最近变化
|
||||||
@ -64,19 +67,10 @@ export default function StrategyView() {
|
|||||||
description={last
|
description={last
|
||||||
? <><b>{last.debtToGdp}%</b> · 债务利息/GDP {last.interestToGdp}% · {last.year}</>
|
? <><b>{last.debtToGdp}%</b> · 债务利息/GDP {last.interestToGdp}% · {last.year}</>
|
||||||
: '暂无数据'}
|
: '暂无数据'}
|
||||||
extra={
|
extra={<TrendBadge trend={trend} />}
|
||||||
<div className="row-meta">
|
|
||||||
{last && Math.abs(change) >= 1 && (
|
|
||||||
<span className="row-change">
|
|
||||||
{change > 0 ? '+' : ''}{change.toFixed(1)}%
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
<TrendBadge trend={trend} />
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
arrowIcon
|
arrowIcon
|
||||||
clickable
|
clickable
|
||||||
onClick={() => setSelected(s.name)}
|
onClick={() => navigate('/macro/strategy/' + s.name)}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user