interface BuildVditorOptionsInput { value: string isMobile: boolean onInput: (value: string) => void onUploadError: () => void onEditorReady?: () => void } const DESKTOP_TOOLBAR: ReadonlyArray = [ 'emoji', 'headings', 'bold', 'italic', 'strike', '|', 'line', 'list', 'ordered-list', 'check', 'quote', '|', 'code', 'inline-code', 'insert-before', 'insert-after', '|', 'upload', 'link', 'table', '|', 'undo', 'redo', '|', 'fullscreen', 'edit-mode', ] const MOBILE_TOOLBAR: ReadonlyArray = [ 'bold', 'italic', 'headings', '|', 'list', 'ordered-list', '|', 'link', 'upload', 'code', '|', 'preview', ] export function buildPostBodyMarkdownEditorVditorOptions(input: BuildVditorOptionsInput): Record { return { value: input.value, lang: 'zh_CN', cdn: '/vditor', cache: { enable: false }, mode: 'ir', preview: { mode: 'editor', actions: [] as string[], }, toolbar: input.isMobile ? MOBILE_TOOLBAR : DESKTOP_TOOLBAR, upload: { url: '/api/file/upload', fieldName: 'file', multiple: true, accept: 'image/*', format(files: File[], responseText: string) { try { const parsed = JSON.parse(responseText) as { files?: Array<{ url?: string }> data?: { files?: Array<{ url?: string }> } } const nestedFiles = parsed?.data?.files const rootFiles = parsed?.files const uploaded = Array.isArray(nestedFiles) ? nestedFiles : (Array.isArray(rootFiles) ? rootFiles : []) const succMap: Record = {} uploaded.forEach((item, index) => { const url = item?.url?.trim() if (!url) { return } const fallbackName = `upload-${index + 1}` const sourceName = files[index]?.name?.trim() || fallbackName succMap[sourceName] = url }) return JSON.stringify({ msg: '', code: 0, data: { errFiles: [] as string[], succMap, }, }) } catch { return JSON.stringify({ msg: 'upload response parse failed', code: 1, data: { errFiles: [] as string[], succMap: {} as Record, }, }) } }, error() { input.onUploadError() }, }, input(value: string) { input.onInput(value) }, after() { input.onEditorReady?.() }, } } export const postBodyMarkdownEditorToolbarPresets = { desktop: DESKTOP_TOOLBAR, mobile: MOBILE_TOOLBAR, }