feat: 增加反馈消息闭环相关功能及文件
新增反馈目标登录白名单、账户切换守卫、待确认反馈存储、缓存生命周期管理,补充相关文档及截图,完善消息跳转逻辑
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
import { requestJson } from '@/services/api.uts'
|
||||
import { FinanceLesson, NewsArticle, contentLessonFrom, contentArticleFrom } from '@/services/content.uts'
|
||||
|
||||
/** 首页运营横幅;当前后端没有可发布横幅时返回空数组。 */
|
||||
export type HomeBanner = { id: string, title: string, subtitle: string, image: string, actionUrl: string }
|
||||
export type HomeAssessment = { assessmentId: string, type: string, status: string, statusLabel: string, stage: string, revisionId: string | null, hasReport: boolean, updatedAt: string | null }
|
||||
export type HomeAssessmentSummary = { total: number, latest: HomeAssessment | null }
|
||||
export type HomeRecommendations = { lessons: FinanceLesson[], articles: NewsArticle[] }
|
||||
export type HomeCatalog = { banners: HomeBanner[], recommendations: HomeRecommendations, assessmentSummary: HomeAssessmentSummary | null, unreadCount: number }
|
||||
|
||||
function requiredString(data: UTSJSONObject, key: string, message: string): string {
|
||||
const value = data.getString(key)
|
||||
if (value == null || value.length == 0) throw new Error(message)
|
||||
return value
|
||||
}
|
||||
|
||||
function nullableString(data: UTSJSONObject, key: string, message: string): string | null {
|
||||
const value = data[key]
|
||||
if (value == null) return null
|
||||
if (typeof value != 'string') throw new Error(message)
|
||||
return value as string
|
||||
}
|
||||
|
||||
function recordId(value: string, message: string): string {
|
||||
if (!/^[1-9][0-9]{0,9}$/.test(value)) throw new Error(message)
|
||||
if (value.length == 10 && value > '2147483647') throw new Error(message)
|
||||
return value
|
||||
}
|
||||
|
||||
function bannersFrom(value: any | null): HomeBanner[] {
|
||||
if (value == null || !Array.isArray(value)) throw new Error('首页横幅格式无效')
|
||||
return (value as UTSJSONObject[]).map((item: UTSJSONObject): HomeBanner => {
|
||||
if (item == null || typeof item != 'object' || Array.isArray(item)) throw new Error('首页横幅格式无效')
|
||||
return {
|
||||
id: recordId(requiredString(item, 'id', '首页横幅缺少编号'), '首页横幅编号无效'),
|
||||
title: requiredString(item, 'title', '首页横幅标题无效'),
|
||||
subtitle: requiredString(item, 'subtitle', '首页横幅副标题无效'),
|
||||
image: requiredString(item, 'image', '首页横幅图片无效'),
|
||||
actionUrl: requiredString(item, 'actionUrl', '首页横幅跳转地址无效')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function assessmentFrom(data: UTSJSONObject): HomeAssessment {
|
||||
if (data == null || typeof data != 'object' || Array.isArray(data)) throw new Error('首页评估摘要格式无效')
|
||||
const type = requiredString(data, 'type', '首页评估类型无效')
|
||||
const status = requiredString(data, 'status', '首页评估状态无效')
|
||||
if (!['personal', 'enterprise'].includes(type) || !['draft', 'processing', 'succeeded', 'failed'].includes(status)) throw new Error('首页评估摘要格式无效')
|
||||
const hasReport = data.getBoolean('hasReport')
|
||||
if (hasReport == null) throw new Error('首页评估报告标记无效')
|
||||
const revisionId = nullableString(data, 'revisionId', '首页评估版本编号无效')
|
||||
if (revisionId != null) recordId(revisionId, '首页评估版本编号无效')
|
||||
return {
|
||||
assessmentId: recordId(requiredString(data, 'assessmentId', '首页评估编号无效'), '首页评估编号无效'),
|
||||
type, status, statusLabel: requiredString(data, 'statusLabel', '首页评估状态文案无效'),
|
||||
stage: requiredString(data, 'stage', '首页评估阶段无效'), revisionId, hasReport,
|
||||
updatedAt: nullableString(data, 'updatedAt', '首页评估更新时间无效')
|
||||
}
|
||||
}
|
||||
|
||||
function summaryFrom(value: any | null): HomeAssessmentSummary | null {
|
||||
if (value == null) return null
|
||||
if (typeof value != 'object' || Array.isArray(value)) throw new Error('首页评估摘要格式无效')
|
||||
const data = value as UTSJSONObject
|
||||
const total = data.getNumber('total')
|
||||
if (total == null || !Number.isInteger(total) || total < 0) throw new Error('首页评估数量无效')
|
||||
const latest = data['latest']
|
||||
if (latest == null) return { total, latest: null }
|
||||
if (typeof latest != 'object' || Array.isArray(latest)) throw new Error('首页最新评估格式无效')
|
||||
return { total, latest: assessmentFrom(latest as UTSJSONObject) }
|
||||
}
|
||||
|
||||
function recommendationsFrom(value: any | null): HomeRecommendations {
|
||||
if (value == null || typeof value != 'object' || Array.isArray(value)) throw new Error('首页推荐格式无效')
|
||||
const data = value as UTSJSONObject
|
||||
const lessons = data['lessons']; const articles = data['articles']
|
||||
if (lessons == null || !Array.isArray(lessons) || articles == null || !Array.isArray(articles)) throw new Error('首页推荐格式无效')
|
||||
return {
|
||||
lessons: (lessons as UTSJSONObject[]).map((item: UTSJSONObject): FinanceLesson => contentLessonFrom(item)),
|
||||
articles: (articles as UTSJSONObject[]).map((item: UTSJSONObject): NewsArticle => contentArticleFrom(item))
|
||||
}
|
||||
}
|
||||
|
||||
function homeFrom(data: UTSJSONObject): HomeCatalog {
|
||||
const unreadCount = data.getNumber('unreadCount')
|
||||
if (unreadCount == null || !Number.isInteger(unreadCount) || unreadCount < 0) throw new Error('首页未读数量无效')
|
||||
return {
|
||||
banners: bannersFrom(data['banners']),
|
||||
recommendations: recommendationsFrom(data['recommendations']),
|
||||
assessmentSummary: summaryFrom(data['assessmentSummary']),
|
||||
unreadCount
|
||||
}
|
||||
}
|
||||
|
||||
export async function fetchHome(): Promise<HomeCatalog> { return homeFrom(await requestJson('/home', 'GET', {})) }
|
||||
Reference in New Issue
Block a user