扩展导入功能
导入功能原理
主要的业务逻辑是在前端,前端对 JSON 数据进行解析,将整理后的数据发送至后端。不管从哪个平台导入,后端接收的数据结构是一样的。
后端将请求获取数据中的图片,处理后与数据中的其他内容一同保存在数据库。
导入的数据结构
前端对 JSON 数据进行解析,解析为这个结构
// tweet-blog-vue3: src\types\data\import.d.ts
import type { PlatformKeyEnumValues } from '@/config' // src\config\platform.ts
export type ImportPostItem = {
// 帖子内容
content: string
// 帖子时间
createdAt: string
// 帖子所属平台
platform: PlatformKeyEnumValues
// 帖子在所属平台的id
platformId: string
// 帖子在所属平台的链接
platformLink: string
// 帖子在所属平台的父帖id
platformParentId: string | null
// 帖子的图片
importImages: {
// 图片链接,后端将请求此url来获取图片
link: string
// 图片描述
alt: string
// 图片所属平台
platform: PlatformKeyEnumValues
// 图片在所属平台的id
platformId: string
}[]
}
export type ImportPostList = ImportPostItem[]
关键代码
tweet-blog-vue3\src\views\control\views\tweet-import
| TweetImport.vue
+---components
| dependencies.ts
| ImportProcess.vue
| ImportSubmit.vue
| ……
\---services
| index.ts
| process.ts
\---data-process
| index.ts
\---x-twitter
index.ts
schemas.ts
services.ts
types.d.ts
utils.ts
components/ImportProcess.vue
中存在一个文本域,其会调用 services/process.ts
导出的 processJsonToImportPostsByPlatform
函数来解析 json 数据
processJsonToImportPostsByPlatform 会根据传入的 platform(平台代表字段) 来调用对应各平台的解析函数,并接收其类型为 ImportPostList
的返回值
// services/process.ts
import { platformKeyMap, type PlatformKeyEnumValues } from '@/config'
import { dataProcessXtwitterService } from './data-process'
import type { ImportPostList } from '@/types'
export const processJsonToImportPostsByPlatform = (data: {
jsonData: string
platform: PlatformKeyEnumValues
}) => {
const { jsonData, platform } = data
let importPosts: ImportPostList | null = null
if (platform === platformKeyMap.X.key) {
importPosts = dataProcessXtwitterService(jsonData)
}
return importPosts
}
如 dataProcessXtwitterService
函数 就是 X 的解析函数,由 data-process/x-twitter
导出
如果要扩展的话,比如添加从 Telegram 解析数据,可以创建 data-process/telegram
目录来编写对应的函数,并在 services/process.ts
调用
导入功能扩展流程
现在以扩展从 Telegram 导入推文为例,来梳理扩展流程
修改前后端的 platform.ts
// 前端:src\config\platform.ts
// 后端:src\configs\platform.ts
// 添加
// 虽然对于导入功能来说,用不到Schema之类的,但是还是需要模仿着创建一个
const forwardSettingDataSchemaTelegram = z.object({
tokenTelegram: z.string()
})
const forwardSettingDataDefaultTelegram: z.infer<typeof forwardSettingDataSchemaTelegram> = {
tokenTelegram: ''
}
// 修改
// 全部平台的 forwardSettingDataDefault
export const forwardSettingDataDefaultAll = {
...forwardSettingDataDefaultX,
...forwardSettingDataDefaultT,
...forwardSettingDataDefaultTelegram
}
// 关于导入与导出所需的平台数据
export const platformKeyMap = {
X: {
key: 'X',
name: 'X / Twitter',
// https://fontawesome.com/v6/search?o=v&ic=brands
fontawesomeClass: 'fa-brands fa-x-twitter',
// 是否支持导入或导出,这个会控制对应 radio 单选框
couldImport: true,
couldForward: true,
// 转发配置中,data 的 schema 与 默认值
forwardSettingDataSchema: forwardSettingDataSchemaX,
forwardSettingDataDefault: forwardSettingDataDefaultX
},
T: {
key: 'T',
name: 'Test',
fontawesomeClass: 'fa-brands fa-font-awesome',
couldImport: false,
couldForward: false,
forwardSettingDataSchema: forwardSettingDataSchemaT,
forwardSettingDataDefault: forwardSettingDataDefaultT
},
// 添加
Telegram: {
key: 'Telegram',
name: 'Telegram',
fontawesomeClass: 'fa-brands fa-telegram',
couldImport: true,
couldForward: false,
forwardSettingDataSchema: forwardSettingDataSchemaTelegram,
forwardSettingDataDefault: forwardSettingDataDefaultTelegram
}
} as const
// 这个手动写出来的原因是,zod枚举需要字面量类型数组
export const platformKeyEnum = [
'X',
'T',
'Telegram' // 添加
] as const
关于 platform.ts
详细的说明请看 platform.ts 说明
编写解析函数
tweet-blog-vue3: src\views\control\views\tweet-import
| TweetImport.vue
+---components
| ……
\---services
| index.ts
| process.ts
\---data-process
| index.ts
+---telegram
| services.ts
| index.ts
\---x-twitter
index.ts
schemas.ts
services.ts
types.d.ts
utils.ts
创建 data-process/telegram
目录,在其中创建 services.ts
index.ts
、
index.ts
中导出 services.ts
的所有导出 export * from './services'
services.ts
导出 dataProcessTelegramService
函数。
dataProcessTelegramService
函数类型为
type DataProcessTelegramService = (jsonData: string) => ImportPostList | null
可以参考 x-twitter 文件夹中的内容来完善
schemas.ts 用来编写和导出 zod 校验对象
types.d.ts 用来管理类型
utils.ts 用来写比较零碎的字符串处理之类的函数
完成后,需要在 data-process/index.ts
中导出 telegram 文件夹
export * from './x-twitter'
export * from './telegram'
最后要在 services/process.ts
中调用 dataProcessTelegramService
import {
dataProcessXtwitterService,
dataProcessTelegramService
} from './data-process'
export const processJsonToImportPostsByPlatform = (data: {
jsonData: string
platform: PlatformKeyEnumValues
}) => {
const { jsonData, platform } = data
let importPosts: ImportPostList | null = null
if (platform === platformKeyMap.X.key) {
importPosts = dataProcessXtwitterService(jsonData)
}
// 添加
if (platform === platformKeyMap.Telegram.key) {
importPosts = dataProcessTelegramService(jsonData)
}
return importPosts
}