Commit Graph

3 Commits

Author SHA1 Message Date
govin 4d749b3592 frontend: add the paper list, document view, and paragraph editor
The 论文 menu now carries the papers themselves, read from a pinia store, so a
paper opens straight from the rail; every page that changes the list reloads
that store, and a filter box appears once there are more than six.

PapersView is the library — search, create, edit, open, single and batch
delete. PaperDetailView is the writing surface: it renders the server's
document verbatim, with an edit button beside every paragraph (written or not,
because content only ever enters a paper through the editor), citation markers
numbered in reading order to match the 参考文献 list, and a 切换模板 dialog that
previews the impact before re-shaping the document.

The paragraph editor shows one paragraph as the paper will read it — every
sentence on its own line, in sort order, each editable, each able to carry
citations — and writes the paragraph back whole. Whitespace-only lines are
dropped on save; a citation with an empty 引用内容 is refused; and 所属段落
moves the paragraph to another position, appended after what is already there.
2026-09-18 17:29:16 +08:00
govin 098bfd1bfb frontend: add the template configuration UI
The shell: the app mark at both ends of the header, the two top-level
entries between them, and the second-level menu on the right. That menu is
driven entirely by `route.meta.section`, so a route declares which menu it
belongs to and a deep link renders the right one on first paint; routes with
no section (the welcome page) show none.

Screens:
  /                    welcome, with live template and field counts so the
                       page doubles as a connectivity check
  /papers              论文, content still to be decided
  /templates/list      the template table: search, create, edit, preview,
                       delete, batch delete, pagination
  /templates/fields    the field library: the same CRUD, plus level filter

The template form is the centre of it. Fields are chosen from the flat
library by clicking — any subset, any order, the same field more than once —
and the selection is always rendered sorted by `sort`, so editing a number
reorders the outline immediately. Repeats and duplicate sorts are surfaced as
warnings rather than blocked, because a repeat is often deliberate and a tie
is legal; a "自动排序" button renumbers the selection 1..N. The panel on the
right of the picker opens 字段管理 in a second tab, so a half-filled form is
never lost to a navigation.

The preview drawer renders the outline exactly as it will read, at each
field's own size and colour, with the sort value shown alongside — the
quickest way to confirm the ordering before writing against a template.

Also in this change:

  - ApiError now extends Error. It was a plain object, so the common
    `error instanceof Error ? error.message : ...` idiom fell through to a
    generic message and threw away what the server actually said — such as
    which template name is already taken. Server messages now reach the user.
  - font colours are normalised client-side on blur, matching the backend,
    so a hand-typed rgb(255, 0, 0) is tidied up rather than rejected later.
  - api/health.ts is removed: the rewritten welcome page was its only
    consumer, and the counts already prove connectivity.
2026-09-18 16:00:02 +08:00
govin 5128e1551c feat: scaffold FastAPI backend and Vue 3 frontend
Backend (backend/):
- FastAPI app with layered app/{api,core,crud,db,models,schemas} structure
- TiDB connection via SQLAlchemy. The URL is built with URL.create rather
  than string formatting: the password contains '@', which would otherwise be
  parsed as the user/host separator and silently truncate the credential.
- Alembic environment wired to Base.metadata and the app settings, so
  backend/.env stays the single source of truth for credentials
- /api/health endpoint reporting database reachability
- models/ and crud/ are intentionally empty: no model classes are defined and
  no tables are created, at import time or otherwise

Frontend (frontend/):
- Vue 3 + Vite + TypeScript scaffold (create-vue, --bare)
- axios instance with a normalized error shape
- vue-router with a home route and a catch-all 404
- pinia + pinia-plugin-persistedstate; the app store persists selected keys
- Element Plus with its icons registered globally
- dev proxy forwards /api to the FastAPI service on port 8000

The database paper_doc was created in TiDB out of band; no table exists yet.
2026-09-17 12:51:37 +08:00