Commit Graph

175 Commits

Author SHA1 Message Date
4887093c3a feat: 头像上传选区限制 3840×3840 + 客户端裁剪压缩
- 后端:3840×2160 限制改为 3840×3840(方形限制适应方形裁剪),并移到裁剪结果上检查而非原图
- 前端:原图短边超过 3840 时自动抬高最小缩放,确保选区永不超过 3840×3840
- 前端:裁剪确认后用 Canvas 预裁剪 + JPEG 压缩再上传,大幅节省带宽
- 前端:裁剪框标题栏新增实时像素尺寸提示
- 新增 .crop-info 样式
2026-05-31 02:42:27 +08:00
09a9394c30 fix: 修复静态资源哈希 key 与模板 URL 路径不匹配导致版本号全为 0
- 重构 walkStaticDir 统一处理三个 static 目录
- URL key 基于文件相对于 static 目录的路径,不含主题目录名
2026-05-31 02:18:20 +08:00
eabceecaae refactor: 静态资源哈希算法从 SHA-1 改为 CRC32
- CRC32 更快且语义更匹配缓存破坏场景
- 输出自然为 8 位 hex,无需截取
2026-05-31 02:06:41 +08:00
d3e5cbe18b refactor: 静态资源缓存破坏改为文件级哈希,重启不刷新未修改文件的缓存
- 启动时计算每个 JS/CSS 的 SHA-1 前 8 位作为版本号
- 文件不变则哈希不变,浏览器继续用缓存,重启零压力
- 替换全局 AssetVersion 为 assetV 模板函数,按文件路径查询哈希
- 移除 BuildPageData 中的全局版本号注入
2026-05-31 01:53:17 +08:00
b8658712bb fix: 静态资源加缓存破坏版本号,解决浏览器缓存旧 JS 导致功能不生效
- 启动时生成 AssetVersion(base36 时间戳),注入模板 {{.V}}
- 所有 JS/CSS 引用加 ?v={{.V}},重启即刷新缓存
- 涉及前端、管理后台共 12 个模板文件
2026-05-31 01:46:47 +08:00
0bcaadceb4 fix: 注销恢复流程文案统一为'撤销注销',消除歧义
- '恢复'易误解为故障恢复,改为'撤销注销'明确表达取消注销操作
- 涉及后端错误提示、API 响应、前端弹窗及按钮文案共 9 处
2026-05-31 01:26:04 +08:00
a62039e6bb fix: 登录/注册支持 redirect 参数,未登录跳转自动携带来源页
- login.js/register.js 登录成功后优先跳转 redirect 参数指定页面
- 新增 common.RedirectToLogin 辅助函数,自动携带当前路径
- 替换所有 9 处硬编码 /auth/login 重定向
2026-05-31 01:23:09 +08:00
9d84d6bf25 feat: 临时会话超时从 24 小时缩短为 2 小时
- idle_timeout: 1440 → 120 分钟
- 前端已有 10 分钟心跳续期机制,写文章等长时间操作不会丢失会话
2026-05-31 00:51:44 +08:00
213b2a571e feat: 登录管理设备列表显示会话类型和剩余有效期
- 临时会话显示橙色'临时会话'徽章
- 非当前设备显示剩余有效时间(临时/长期均显示)
- 当前设备不显示剩余时间(持续续期,显示无意义)
- 新增 formatTTL 模板函数,分钟数转人类可读格式
- sessionConfig 接口增加 GetRememberTimeout 方法
2026-05-31 00:36:25 +08:00
e244bccb5c fix: 移除服务端登录会话去重逻辑
- 去重会合并标准模式/无痕模式的独立会话,不符合预期
- 防重复提交由前端按钮禁用保证即可,服务端无需干预
2026-05-31 00:29:47 +08:00
d5d33c3ace fix: 修复登录重复创建会话 + 备注输入框不可交互
- login.js 增加防重复提交锁,请求期间禁用按钮
- Manager.Create 增加幂等检查,同用户同IP同UA 10秒内复用已有会话
- 移除当前设备备注输入框的 readonly 限制,改为 data-current 标记
- 修复 readonly 状态下输入框完全透明无法点击的问题
2026-05-31 00:28:00 +08:00
47ef3f2a99 fix: 重写设置页模板,修复 sessions tab 重复和结构损坏
- 移除 sessions tab 重复3次的冗余内容
- 修复 profile 内容碎片混入 sessions 区块的问题
- 恢复正确的三tab结构(profile / sessions / account)
2026-05-31 00:18:47 +08:00
b63dc9075f fix: 修复 MemoryStore.Set 重复追加 byUID 索引导致会话列表重复 2026-05-31 00:08:08 +08:00
2180c27b16 fix: 修复设置页模板中文引号与 HTML 属性冲突导致渲染报错 2026-05-31 00:06:24 +08:00
d203447eb3 feat: 设置页新增登录管理 TAB
- Session 结构体新增 IP、UserAgent、Remark 字段,登录/注册时记录设备信息
- Store 接口新增 ListByUID、DeleteByUIDExclude 方法,MemoryStore 完整实现
- SessionManager 新增 ListByUID、DestroyOtherByUID、UpdateRemark 方法
- 新增 UA 轻量解析器(session/ua.go),提取浏览器/OS/设备类型
- 新增 settings_api_sessions.go,提供列表/踢出/一键踢出/备注 4 个 API
- 控制器层声明 sessionManager 最小接口(ISP),SettingsController 注入依赖
- Auth 中间件注入 sid 到 gin context,支持识别当前会话
- 设置页左侧导航增加登录管理入口,tab 白名单新增 sessions
- 前端实现设备列表展示(浏览器/OS/设备图标/IP/时间)、当前设备标识、备注输入、踢出按钮、一键踢出
- settings.css 新增会话管理全套样式及响应式适配
2026-05-30 23:58:37 +08:00
e3853071d6 chore: 清理 JWT 向后兼容残留,移除全部死代码
- 删除 5 个空壳占位文件:auth_token.go/auth_parser.go/repository.go(middleware)/token_service.go/provider.go
- 移除 Config.JWT 字段、JWTConfig 结构体、JWT_SECRET 环境变量绑定
- 移除 config.yaml 中的 jwt 配置段
- 移除 model.User.TokenVersion 字段(session DestroyByUID 替代)
- 移除 service/repository.go 中已废弃的 userTokenStore 接口
2026-05-30 23:42:27 +08:00
d9ba1cdf28 refactor: 移除 Session 架构下已无用的 TokenVersion 即时吊销机制
- 删除 UserRepo.IncrementTokenVersion/FindTokenVersion 方法
- 从 userAuthStore/userAdminStore 接口移除 IncrementTokenVersion
- 删除 middleware.tokenVersionStore 接口(中间件不再查询 token_version)
- auth_service: DeleteAccount/InvalidateSessions 仅调用 DestroyByUID
- admin_service: UpdateUserStatus/ResetUserToken 仅调用 DestroyByUID
- FindByIDForAuth/FindByIDUnscoped Select 移除 token_version 列
- 新架构下登出/改密/封禁统一走 sessionManager.DestroyByUID,无需 token_version
2026-05-30 23:38:42 +08:00
daf87f895b refactor: JWT 无状态认证替换为服务端 Session,修复记住我掉线问题
- 新增 internal/session 包:Session 结构体、Store 接口、MemoryStore(内存+后台清理)、RedisStore 预留
- Cookie 从 3 个精简为 1 个 mlb_sid(HttpOnly),移除 JWT access/refresh cookie
- 会话过期采用滑动窗口:每次请求自动续期,记住我 30 天无操作过期
- AuthMiddleware/AuthAdmin/Maintenance 中间件改用 SessionManager.Validate()
- AuthService Login/Register/ConfirmRestore 去除 token 生成,返回 *model.User
- Controller 层在登录/注册后调用 SessionManager.Create 创建会话
- AdminService UpdateUserStatus/ResetUserToken 同步销毁 session 实现即时退登
- 改密/注销时通过 DestroyByUID 删除所有 session(替换 TokenVersion 检查)
- config.yaml 新增 session 配置段(idle_timeout/remember_timeout/cleanup_interval)
- TokenService/auth_parser/auth_token 标记废弃,移除 JWT 到期字段依赖
2026-05-30 23:36:52 +08:00
53f84bfcc4 fix: 修复编辑模式下 Vditor 不加载稿件内容
- 创作中心编辑文章时,after 回调中显式调用 vditor.setValue(initialMD)
- 修复 Vditor 3.x wysiwyg 模式下 value 选项可能不渲染内容的问题
2026-05-30 21:29:29 +08:00
67444434b9 feat: 对接稿件审核通知系统 + 消息页面系统消息区域
- 新增通知类型 post_approved / post_rejected
- PostService.Approve/Reject 完成后通知作者(通知失败不影响主流程)
- NotificationService 新增 NotifyPostApproved/NotifyPostRejected 方法
- 消息页面顶部增加系统消息标识和分隔线,之下为全部消息列表
- 稿件审核通过通知卡片点击跳转到 /posts/{id} 页面
- 稿件审核拒绝通知卡片点击跳转到 /studio/posts 创作中心
- 新增 postNotifier 接口遵循 ISP 原则
2026-05-30 21:24:30 +08:00
fb94ce60ae fix: 维护期间登录一律返回统一提示,不泄露账号状态
- 维护检查提前到 FindByEmail 之后、所有状态检查之前
- 非站长账号(不存在/已封禁/已锁定等)统一走模拟 bcrypt 防时序 → 返回维护提示
- 站长角色正常通过,走完整登录流程
- 旧实现:维护检查在 banned/locked/deleted 之后,会泄露账号状态
2026-05-30 21:10:41 +08:00
c1357cf4af fix: 维护条对站长显示“正处于维护状态”提醒 + BuildPageData 注入 IsOwner
- BuildPageData 新增 IsOwner 变量,所有前端页面可获取站长角色
- Nav 维护条:站长显示“社区正处于维护状态”(防止忘记关闭),非站长显示“仅站长可访问”
- 维护中间件 API 拦截验证:所有非 /api/auth/ 的 API 对非 Owner 返回 403,正确
2026-05-30 21:06:32 +08:00
fe683900bb fix: 维护状态下登录页隐藏“立即注册”链接 2026-05-30 21:01:54 +08:00
1b4a74c23d fix: 维护开关初始状态显示与实际不符
- maintenance.enabled 默认 false,但 JS 用 registration 同逻辑导致首次显示为 ON
- 分离 maintenance 判断:仅当保存过 true 时才显示 ON
- registration 保持原逻辑(默认 true,仅当 !== false 时 ON)
2026-05-30 20:58:05 +08:00
6229c81f6e feat: 新增维护模式 + 修复注册关闭页面标题显示问题
- 修复注册关闭时标题“创建账号”和副标题仍显示的问题,三态互斥(维护中 > 关闭注册 > 正常)
- 新增 maintenance.enabled 站点设置,默认关闭,仅 Owner 可见可调节
- 维护中间件:全局拦截,维护期间仅站长可访问,白名单放行登录相关路径
- 登录服务:维护期间仅 Owner 角色可登录,Register 优先检查维护状态
- Nav 模板新增维护通知条(黄色横幅)
- 管理后台站点设置新增“启用维护模式”开关
- BuildPageData 自动注入 IsMaintenance 到所有页面模板
2026-05-30 20:54:23 +08:00
fb2eff5f23 feat: 注册关闭时页面隐藏表单并显示友好提示,保留登录入口
- RegisterPage 传入 RegistrationEnabled 标志到模板
- 注册关闭时隐藏输入框和按钮,显示“当前暂不开放注册”提示
- 保留“已有账号?立即登录”链接
- API 层已有拦截(AuthService.Register 返回 403),无需修改
- authUseCase 接口新增 IsRegistrationEnabled 方法(ISP)
2026-05-30 20:38:55 +08:00
90d17ed4b1 feat: 管理后台待审稿件置顶优先显示
- FindAdminPageable 新增 pageResultsAdmin,使用 CASE WHEN 排序
- pending 和有 PendingBody 的 approved 帖子排在最前
- 其余帖子按创建时间倒序排在后面
2026-05-30 20:33:14 +08:00
8bb87cd685 fix: 去掉独立修订表格,消除帖子重复显示
- 移除管理后台独立的"修订待审核"表格区域
- 修订标识和按钮已在主列表中内联展示,无需额外表格
- PostsPage 不再额外查询 Revisions 列表
2026-05-30 20:31:19 +08:00
95311704fe fix: 修订状态标识仅对作者可见,不公开显示 2026-05-30 20:28:59 +08:00
eabc1e7d3d feat: 已发布帖子编辑后进修订审核,通过前保持展示旧内容
- Post 模型新增 PendingTitle/PendingBody 字段,分离已发布内容与待审修订
- Update: approved 帖子编辑写入 Pending 字段,不覆盖正文,不改变发布状态
- Approve: 有 PendingBody 时复制到正式字段后清空,无 PendingBody 走首次审核
- Reject: 有 PendingBody 时仅清空待审修订(保持已发布),无 PendingBody 走普通退回
- 新增 ListPendingRevisions 查询,管理后台独立展示"修订待审核"区域
- 详情页展示"修订审核中"标识,编辑页加载待审内容
- 通过修订后直接覆盖,不保留历史版本
2026-05-30 20:24:43 +08:00
89fa50a013 fix: 锁定机制不再改变帖子状态,锁定与退回独立
- Post 模型新增 IsLocked 字段,与 Status 解耦
- Lock 仅设 IsLocked=true(不改 Status),已通过帖子锁定后仍公开可见
- Unlock 仅设 IsLocked=false(不改 Status)
- Update/EditPage 编辑检查改用 IsLocked 而非 Status==locked
- Reject 与 Lock 独立,可单独退回或锁定+退回组合使用
- 新增 ErrPostCannotLock 错误哨兵
- 前端模板编辑按钮/锁定标识基于 IsLocked 渲染
2026-05-30 20:08:41 +08:00
7659aee468 feat: 新增创作中心(/studio),支持数据概览、内容管理、草稿箱、写文章
- 新增 StudioController,依赖 studioUseCase 接口,遵循 ISP 接口隔离
- PostRepo 新增 FindByUserIDAndStatus 方法,按用户+状态分页查询
- PostService 新增 ListByUser、GetOverview 及 StudioOverview 统计
- /studio 页面路由(概览/管理/草稿箱/写文章/数据分析)+ /api/studio API
- 复用 Vditor 编辑器,studio-editor.js 对接 /api/studio/posts 端点
- 新增 studio.css(B站风格三栏布局+统计卡片+状态筛选tabs)
- 模板引擎注册 add/subtract 函数,分页模板中直接使用
2026-05-30 19:55:29 +08:00
bacfd4945d feat: 编辑器与帖子展示布局优化 + 新增个人空间
- 编辑器投稿页布局优化:标题与编辑器高度动态适配,工具栏与内容区视觉对齐
- 稿件展示页布局优化:MD 渲染区与评论区视觉分离,代码块主题微调
- CSRF 中间件:图像上传端点豁免,解决 Vditor 拖拽/粘贴上传 403
- Post 状态映射、GetGinUser、SaveUploadedFile 提取至 common 包,遵循审计建议
- 新增个人空间功能:/space(需登录)重定向到 /space/:uid,/space/:uid 公开访问
- 空间页模板:参考 B 站布局,展示头像、用户名、个性签名、UID、加入时间及稿件列表
- 导航栏:用户名链接指向 /space,新增「设置」入口
- 分层实现:SpaceController → SpaceService → PostRepo.FindByUserID,严格 ISP 接口隔离
2026-05-30 19:06:10 +08:00
40f0529cbf docs: 更新 README,移除暂停开发通知,补充 Vditor 编辑器与帖子功能
- 移除状态 badge(status-hiatus)和暂停说明
- 技术栈新增 Vditor 3.11 编辑器
- 当前功能新增:帖子 CRUD、代码高亮、Shortcode 卡片、草稿、审核工作流
- 计划中去掉已完成的帖子系统,新增评论系统
2026-05-30 15:59:06 +08:00
6ec12010f3 feat: Tiptap替换为Vditor + MD存储重构 + Shortcode卡片扩展
- 编辑器:Tiptap 替换为 Vditor 3.11.2(wysiwyg 模式,本地托管 5.8MB,去 CDN)
- 存储:Body 字段从 HTML 改为 Markdown,去除 BodyHTML,新增 Excerpt 列表摘要
- 安全:去除 bluemonday 依赖(MD 纯文本无 XSS 风险),go.mod 已清理
- Shortcode:新增 [zone:type:params] 扩展语法,支持活动/游戏/投票/资源卡片
- 图片上传:POST /api/posts/upload-image 直接返回 Vditor 原生响应格式
- 草稿:localStorage 键名改为 draft_post_body_md,与旧 HTML 草稿隔离
- 详情页:Vditor.method.min.js 客户端 MD → HTML 渲染,去 highlight.js CDN
- 样式:去 Tiptap 样式 ~190 行,精简工具栏 CSS,新增卡片样式
- 文档:vditor-migration-plan.md 完整记录迁移决策、架构、用法
2026-05-30 15:56:22 +08:00
c9808ab9b2 docs: 标注项目暂停开发及原因
- 状态徽标从 dev 改为 hiatus

- 说明编辑器集成问题未解决

- 说明将先采用 Flarum 上线社区
2026-05-28 15:28:22 +08:00
fe81c879b0 fix: 修复代码块语法高亮丢失 + 语言标签注入 + 安全性增强
- 新增 cdnjs.cloudflare.com CSP 白名单,允许加载 highlight.js
- 消毒策略放行 span 元素,保留 highlight.js 高亮 class
- 详情页和新帖子页引入 highlight.js 库和 GitHub 主题
- 代码块语言选择器默认 text,支持 prev/next 循环切换语言
- 代码块语言标签注入兼容 data-language 和 code class 双来源
- 修复 utils.js defer 导致 common.js 执行时 getCSRFToken 未定义
2026-05-28 15:21:44 +08:00
91f2cbebc1 fix: 修复帖子提交审核权限缺失 + 防重复提交 + 分页逻辑复用
- 修复 Submit API 缺少 uid 权限检查,任意登录用户可提交他人帖子审核
- 前端 handleSubmit 添加 submitting 锁和按钮禁用/恢复,防止重复提交
- 分页计算 TotalPages/PrevPage/NextPage 提取为 Pagination 方法,消除三处重复代码
2026-05-28 14:47:14 +08:00
e45d66fb77 fix: 修复帖子相关逻辑的严重安全与错误处理问题
- 修复 Service 层所有 FindByID 错误均返回 ErrUserNotFound 的严重 bug,新增 findPost/findPostWithAuthor 正确区分 gorm.ErrRecordNotFound 和数据库错误
- 新增帖子相关错误哨兵:ErrPostNotFound/ErrPostCannotEdit/ErrPostCannotSubmit/ErrPostCannotApprove/ErrPostCannotReject/ErrPostCannotUnlock
- 修复 ShowAPI 缺少权限控制,非 approved 帖子可被任意用户通过 API 获取
- 修复 EditPage 缺少权限检查,非作者可访问编辑页面
- 修复 Update/Delete API 中 uid 断言未做 ok 检查
- Controller 层区分业务错误和内部错误,避免透传 Service 层错误信息给客户端
- 将 postStore 接口从 post_service.go 移至 repository.go,与其他仓储接口保持一致
- 移除 new.html 中孤立的 </template> 标签
2026-05-28 14:44:22 +08:00
36b18c0ffe feat: 代码块语法高亮 + 语言选择 + 样式统一
- 引入 @tiptap/extension-code-block-lowlight + lowlight 实现代码语法高亮
- 工具栏新增语言下拉选择器,光标在代码块内时显示,支持 27 种常用语言
- 默认语言 text,高亮主题适配 MetaLab 深蓝背景 (#1a2332)
- 代码块语言标签用 JS 动态注入 DOM 元素(避免 ::before 在 overflow 容器中失效)
- 详情页同步代码块高亮和语言标签显示
- 编辑器与详情页样式统一:代码块暗色背景、引用蓝色边框、链接 accent 蓝
- sanitizePolicy 放行 data-language 属性和 hljs-* class
- 修复 import map 避免 keyed plugin 重复实例
- 修复详情页代码块开头空白行(移除多余的 padding-top)
- 修复语法错误(多余的闭合括号)
2026-05-28 14:34:58 +08:00
69ba2fb01b refactor: ByteMD 迁移至 Tiptap WYSIWYG 编辑器 + Token 刷新优化
- 移除 ByteMD CDN 资源和 goldmark 依赖,替换为 Tiptap ESM 模块
- 编辑器从源码编辑模式改为 WYSIWYG 所见即所得
- 移除 /api/posts/preview 预览接口(Tiptap 直接输出 HTML 无需后端渲染)
- 保留 UploadImage 图片上传接口和 bluemonday HTML 消毒
- 工具栏支持加粗、斜体、删除线、代码、标题、列表、引用、代码块、分割线、撤销/重做
- 支持图片粘贴/拖拽上传,Ctrl+S 快捷提交,F11 全屏,字数统计
- 优化 common.js:自动 401 拦截 Token 刷新,修复刷新死循环
- 草稿 localStorage 键名更新为 draft_post_body_html
2026-05-28 11:21:53 +08:00
22a302315a feat: wangEditor 替换为 ByteMD Markdown 编辑器
- 移除 wangEditor 5 库文件(1.27MB JS + 14KB CSS,含手动 hack)
- 集成 ByteMD 1.22.0(基于 CodeMirror 5,不依赖 contentEditable)
- 编辑器输出 Markdown 原文,后端 goldmark + bluemonday 双重防护渲染 HTML
- 删除 editor.js 中 scrollIntoView hack、code-lang-label DOM 注入、PreviewAPI 调用
- 清理 posts.css 中 ~200 行 wangEditor 样式覆盖(w-e-* 类名)
- 清理 show.html 中 code-lang-label JS 注入(goldmark 自带 language-xxx class)
- 更新 CSP 安全策略:移除 CodeMirror 注释,保留 esm.sh CDN
- go.mod:bluemonday 和 goldmark 均保留为直接依赖(纵深防御)
2026-05-28 02:16:50 +08:00
804fd50edf fix: 修复编辑器代码块换行滚动跳动 + 移除视频和网络图片功能
- 修复 wangeditor 选区同步 scrollIntoView 导致代码块换行大幅跳动的问题
  - 移除 getBoundingClientRect 替换 hack,改用元素自身真实位置计算滚动
  - 将 block 参数从 end 改为 nearest,behavior 从 smooth 改为 instant
- 修复 #editor-container 与 .w-e-scroll 双重滚动容器冲突
  - #editor-container 和 .w-e-text-container 设为 overflow:hidden
  - .w-e-scroll 作为唯一滚动容器设 overflow-y:auto
- updateCodeLabels 改为节流执行并保存/恢复滚动位置
- 新增 ensureCursorVisible 替代内置滚动保证光标可见
- 滚动同步函数统一引用 .w-e-scroll 容器
- 工具栏排除视频相关按钮和网络图片功能
- .gitignore 添加 .codebuddy
2026-05-28 01:44:46 +08:00
2917562bf0 fix: 修复编辑器代码块样式不一致 + 提交 HTML 保留格式 + 详情页布局优化
- 编辑器 pre code 移除 wangEditor 内置 border,与预览区样式统一
- 代码块语言标签 padding 加大并用 !important 对抗 wangEditor 全局重置
- 编辑器 ::before 伪元素仅作降级方案,避免与 JS 注入的 .code-lang-label 冲突
- 编辑器 pre padding-top 统一为 36px,font-size/line-height 对齐预览区
- 提交改用 editor.getHtml(),后端 sanitizeHTML 替代 renderMarkdown,保留富文本格式
- 详情页 post-detail-header 覆盖 common.css sticky,固定在文章卡片内
- 详情页增加白色卡片背景、圆角、阴影和内边距
- 详情页添加代码块语言标签 JS 注入
- 详情页用户名移除括号 UID 显示,移除管理按钮
2026-05-28 00:53:02 +08:00
ec8fa3eb56 fix: 修复 wangEditor 布局、预览、图片上传和链接样式
- 修复编辑区高度未撑满问题
- 预览改用 getHtml() 直接展示
- 图片上传改用 fetch + credentials:same-origin(修复 CSRF 403)
- 添加帖子正文链接蓝色+下划线样式
- 草稿改用 getHtml() 保存,恢复时正确还原格式
- 草稿改为每 300 字 + 停笔 10 秒双重触发
- 空编辑区不保存草稿
- 代码块语言标签通过 DOMParser 注入(编辑器 + 预览)
2026-05-27 23:01:59 +08:00
9d17185e11 feat: 用 wangEditor 5 替换 CodeMirror 6 2026-05-27 20:24:56 +08:00
c326cbc104 fix: 改用 importmap + esm.sh 解决 CodeMirror 多实例冲突
- 将 import 改回 bare specifier,通过 importmap 指向 esm.sh
- esm.sh 在同一构建上下文中能识别共享依赖,确保 @codemirror/state 单例
- 消除 "Unrecognized extension value" instanceof 检查错误
2026-05-27 19:48:01 +08:00
799ac3c95c fix: 放宽 CSP 允许 esm.sh CDN 加载 CodeMirror 6 ESM 模块
- script-src 添加 https://esm.sh,允许 CodeMirror 6 的 ESM import 加载
- connect-src 显式设为 self,确保 Markdown 预览 fetch 请求正常
- img-src 添加 blob:,支持粘贴图片场景
2026-05-27 19:44:59 +08:00
cc527aaf19 fix: 移除 new.html 末尾多余的 {{end}} 导致模板编译 panic 2026-05-27 19:41:20 +08:00
9801edc313 refactor: 用 CodeMirror 6 重构 MD 编辑器,废弃自研 WYSIWYG
- 引入 CodeMirror 6 (MIT) 替代 contenteditable WYSIWYG 编辑器,消除 execCommand 废弃 API 风险
- 全新全宽三栏布局:标题栏、工具栏、编辑区+可切换预览、状态栏
- 工具栏新增删除线/H1/H4/任务列表/表格/预览切换/全屏按钮
- 支持粘贴图片自动上传 (Ctrl+V)、拖拽上传、上传进度反馈
- 代码块语言下拉选择器替代 prompt() 弹窗,支持搜索和键盘导航
- 自动保存草稿 (30s 防抖,localStorage + 后端静默保存)
- 分屏实时预览 (Ctrl+Shift+P),编辑器与预览区双向滚动同步
- 字数/行数/阅读时间统计、全屏编辑 (F11)
- 快捷键:Ctrl+B/I/K/`/Shift+I/S/Shift+P + Tab/Shift+Tab
- 删除旧的 htmlToMarkdown、syncMarkdownToWysiwyg、mode-tab 等废弃代码
- 后端 API 零改动,仅移除控制器中不再需要的 ExtraJS 字段
2026-05-27 19:38:42 +08:00