Commit Graph

98 Commits

Author SHA1 Message Date
weli 2fb4e12ad5 fix: remove unrotated matrix landscape header
Co-authored-by: Cursor <cursoragent@cursor.com>
progress-matrix-landscape-20260502-2220
2026-05-02 22:21:24 +08:00
weli bae33085ce fix: restore matrix landscape 90° rotation with ml-* CSS and overflow fix
Restores 0910774 rotation structure (external day header + rotated
stage with ml-* layout) and adds missing ml-* CSS rules. Changes
landscape-stage overflow from hidden to visible so viewport can
handle scrolling of time slot content.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
matrix-landscape-v1
2026-05-02 21:44:45 +08:00
weli ea8aff1803 fix: matrix landscape 90° rotation with transposed layout for correct scrolling
Matrix landscape now stays in the rotated stage (same as calendar), but the
internal layout is transposed: time slots are columns (overflow-x: auto) and
days are reversed rows, so after 90° rotation the visual result has days
left-to-right across the top and time slots scrollable vertically.

Header (landscape-matrix-header) stays outside rotation for natural fixed
positioning at the top of the landscape viewport.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-02 21:20:45 +08:00
weli adbf73891a router guard: wrap in try/catch, add single-department auto-selection
- Wrap entire beforeEach guard in try/catch to prevent crashes from
  breaking navigation and leaving a blank page
- Add missing next() at end of try block so all code paths resolve
- Integrate switchDepartment() after loadMyDepartments() when exactly
  1 department is available, enabling transparent single-dept flow

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-02 18:29:54 +08:00
weli ce0ee5ee40 fix: use ml-* layout for matrix landscape (no rotation)
Revert matrix landscape to use the native ml-* template which has the
correct layout (time slots = rows, days = columns, header fixed, body
scrollable). This avoids the scroll-direction issues caused by 90° CSS
rotation. Calendar landscape retains rotation.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-02 17:16:12 +08:00
weli 55ae961b2b feat: add department context with single-department transparent support
- Add Department type to types.ts
- Add loadMyDepartments / switchDepartment to store/org.ts
- Auto-load departments after org switch in main.ts
- Single-department orgs auto-select default department
- localStorage persistence for CurrentDepartmentId
2026-05-02 16:37:32 +08:00
weli 7f44a2a401 fix: enable matrix landscape scrolling through time slots
- Override --clazz-landscape-body-height for matrix to subtract header
  height, eliminating white space when scrolling
- Set overflow: visible on landscape-stage for matrix so ml-body content
  can overflow the stage
- Add min-width: max-content on matrix container so content overflows
  in X direction → becomes vertical scroll after 90° rotation
- ml-body disabled internal scrolling when inside rotated viewport

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-02 16:35:54 +08:00
weli 0910774a2f fix: matrix landscape 90° rotation with fixed header outside rotation
Matrix landscape now uses the same landscape-stage 90° CSS rotation as
the calendar view. The weekday header (ml-header) is rendered outside
the rotated container so it stays fixed at the top. Matrix body
(ml-body) is inside the rotation and scrollable.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-02 16:17:17 +08:00
weli a9d5e0844e fix: standardize terminology — 排课 (clazz) not 课程 (course)
"排课" = scheduled class instance, "课程" = course content/curriculum.
All 21 instances of incorrect usage were in clazz/tongzhi/user-settings
contexts where the underlying data is a clazz (clazz_id, clazz_name,
is_repeat), not a course.

Affected files: clazz/index.vue (10), tongzhi/index.vue (4),
tongzhi/detail.vue (3), store/clazz.ts (3), user-settings.vue (1).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-02 11:53:34 +08:00
weli e40dfe0835 fix: show 排课 tab for SUPERVISOR role in bottom navigation
The 排课 and 打卡 tabs were hidden behind v-if="is_teacher",
excluding the SUPERVISOR role from accessing the clazz page.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-02 11:35:56 +08:00
weli eaec80f24f fix: allow SUPERVISOR role to see own courses in query filter
The query() function in clazz store only filtered for TEACHER and
STUDENT roles, causing SUPERVISOR role to always get an empty list.
Added SUPERVISOR alongside TEACHER to show supervisor's own courses.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-02 10:49:36 +08:00
weli 14f2c277c3 fix: restrict vconsole to sudoer-only (SYS_CAN_SUDO tag), remove SYS_TESTER
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-02 10:49:33 +08:00
weli 76100e4ab8 fix: also show vconsole for users with SYS_CAN_SUDO tag (root users)
Previously vConsole was only shown to users with a role carrying the
SYS_TESTER label. Extend visibility to users who have the SYS_CAN_SUDO
tag (the "root tag"), since those users also need debug access during
E2E testing and general troubleshooting.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-02 10:36:54 +08:00
weli 962fca7847 fix: use Date format (not DateTime) in clazz datesSet callback
The datesSet callback was formatting dates as "YYYY-MM-DD HH:mm:ss"
but the by_hty_id backend endpoints now use string_to_date which
only accepts "YYYY-MM-DD" format. Caused "trailing input" errors.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-02 10:34:50 +08:00
weli bb19834725 fix: supervisor role check for subsidiary data + color passthrough in matrix view
Subsidiary courses now only appear in SUPERVISOR mode, not TEACHER mode.
Matrix view shows each subsidiary teacher's courses with a distinct color.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-02 10:22:22 +08:00
weli ba05fc1b3a fix: hide admin buttons when viewing course package via 试看 preview
"试看" (preview) from the storefront should show a read-only view without
admin operations (编辑, 删除, 发布上架, 下架). Add preview=1 query param
to distinguish preview from direct management navigation. Also limit
previewable sections to first one in preview mode, consistent with
non-owner experience.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-02 09:32:33 +08:00
weli 18548cc1a4 fix: sticky day sidebar + fixed-width scrollable columns
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-02 09:29:51 +08:00
weli f54705dd5b fix: dynamic time slot columns from events + detailed event blocks
- Only show columns for time slots that have actual courses
- Event blocks show: lesson period, time range, teacher, students
- Horizontal scroll when many slot columns

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-02 09:24:25 +08:00
weli 0fa623b73c fix: rewrite matrix view as weekly timetable grid (days × slots)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-02 09:14:09 +08:00
weli 4843e3839e fix: restructure matrix view layout - X=date+time header, Y=event blocks
- Remove Y-axis time slot rows (was wrong)
- X-axis: hierarchical header (weekday + date | time slot name)
- Body: lane-packed event blocks in each date×slot column
- Show teacher name and student names in each block
- Empty slots show clickable '+' placeholder

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-02 08:58:53 +08:00
weli 8a33f35c87 fix: matrix view full-screen fill + show teacher/student names
- Add flex column layout for landscape full-screen fill
- Show teacher name and student names in matrix event blocks
- Refactor useClazzViewModel with makeEvent() helper
- Fix CSS nesting for .slot-row

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-02 08:54:11 +08:00
weli 30a845d7d3 feat: add wide-screen matrix view for clazz scheduling
Add dual-view mode to /clazz page — users can toggle between:
- Existing calendar view (portrait, FullCalendar timeGridWeek)
- New matrix view (landscape, X=date×timeSlot, Y=parallel lanes)

Includes:
- constants.ts: fixed time slot templates (08:40, 10:10, 14:00, 15:30)
- useClazzViewModel.ts: normalized event model composable
- ClazzMatrixView.vue: matrix component with lane packing algorithm
- index.vue: view toggle, matrix navigation, cell/block interactions

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-02 08:39:09 +08:00
weli d3df324b8b feat: add 创建排课 button to calendar; fix 操作记录 spacing
- Add "创建排课" custom button in FullCalendar header toolbar, defaults
  to current date/time + 45min duration, guarded by is_teacher check
- Add margin-bottom to 操作记录 cell so it doesn't crowd the footer buttons

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-01 22:17:49 +08:00
weli c96830c301 feat: add lesson statistics pages and audit log viewer
- Add student lesson records page (/student/lessons)
- Add teacher lesson statistics page (/teacher/stats)
- Add supervisor statistics page (/supervisor/stats)
- Add navigation entries in student/teacher/supervisor profiles
- Add audit log viewer in clazz detail modal
- Add getAuditLog, queryStudentLessons, queryTeacherDetailStats store methods
- Register new routes

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-01 19:46:00 +08:00
weli 53989e5731 fix: course package detail page - permission gate, status logic, preview lock 2026-05-01 10:50:56 +08:00
weli 6e4ef03e07 fix: show placeholder when cover_image_url is null
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-01 10:10:46 +08:00
weli c511cc318c feat: load all public packages without org_id for guest storefront
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-01 10:01:37 +08:00
weli ddaa862582 fix: handle empty org_id gracefully in course-package-store + index.vue
- CoursePackageStore: don't show error when no orgId and unauth,
  just show empty state
- index.vue: only render CoursePackageStore when org_id is available
  in URL, otherwise show original login prompt

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-01 08:43:13 +08:00
weli b8dca18ea4 fix: support org_id from URL query param in course-package-store
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-01 08:17:31 +08:00
weli f033e303ce feat: add course package storefront for unauth and home pages
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-01 08:08:01 +08:00
weli e65ef12cfc fix: redirect teacherless students to teacher-select page
When a student has no claimed teachers, redirect them to the
teacher-select page instead of silently landing on the home page
with no teacher. The teacher-select page falls back to showing
available valid teachers when the student's teacher list is empty.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-01 01:56:28 +08:00
weli 09653ae15b fix: remove org-unaware teacher claiming page from index.vue
- Remove the "请选择您的老师" page (v-else-if block) that showed teachers
  from all orgs
- Remove the mine.length === 0 guard in watchEffect - students with no
  teachers now redirect to home page normally
- Teacher selection moves to profile page /student/teacher-select
- Remove unused code (getAllTeachers, teachers computed, chooseTeacher)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-01 01:22:58 +08:00
weli 59f4158d24 fix: simplify student role switch and org switch to use index page auto-select
- Update chooseRole STUDENT branch: redirect to / instead of teacher-select
- Update org/select.vue: redirect to / for students (index page handles auto-select)
- Remove unused imports

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-01 01:18:21 +08:00
weli 51af5f4f1c fix: org-filtered teacher list and fix teacher selection redirect loop
- Replace getValidTeachers() with getAllTeachers() for org-scoped teacher list
- Fix chooseTeacher() to use async/await with error handling instead of reload
- After claiming teacher, refresh mine list and navigate without page reload
- Fix chooseRole STUDENT branch: clear teacher and redirect to teacher-select
- Remove auto-select on role switch (user should pick explicitly)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-01 01:14:10 +08:00
weli e7b70b2ba8 fix: restore assets_base to CDN for huiwing (CDN sync now working) 2026-05-01 00:56:41 +08:00
weli b751bf83ee fix: serve huiwing assets from nginx instead of CDN (CDN sync broken) 2026-05-01 00:52:39 +08:00
weli 8589f79e52 feat: auto-select default teacher on student login, redirect to teacher-select on org switch
- Add tryAutoSelect() to teacher store to pick first teacher when none selected
- Auto-select first teacher when student role is confirmed (both auto-login and manual role selection)
- Redirect students to /student/teacher-select after org switch, clearing previous teacher
- Covers: chooseRole(), single-role auto-login, and index page initialization

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-01 00:51:36 +08:00
weli e5e6de01d3 perf: parallelize independent requests in daka detail page
Use Promise.all for user group queries, comment loading,
and resource note group fetching.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-30 23:59:48 +08:00
weli 8589a6fc02 feat: student teacher switching in profile page
Add teacher context for students: show current teacher in profile,
allow switching via new teacher-select page. Filter daka queries
by selected teacher when available.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-30 23:50:39 +08:00
weli d117eb06f6 feat(course-package): detail page, publish/unpublish UI, edit lock
- Add detail/show page with conditional action buttons
- Route /course/course-package/detail with props query params
- List page click navigates to detail instead of edit
- Edit page redirects if package is published (published_at set)
- Store: add publish/unpublish API functions

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-30 21:06:19 +08:00
weli 8a8ce597b3 fix(pick): show my course groups tab in course-package picker
Course-package picker only showed org-visible groups, but supervisors
also need to see and use their own course groups. Add "我的课节" tab
for course-package mode.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-30 15:14:03 +08:00
weli 058e1b0a47 feat(course-package): add org_visible toggle and course-group picker
- CourseGroup: add org_visible field, teacher toggle on add/edit
- CoursePackage: add selectedGroups state, sync/list package items API
- Group picker: support COURSE_PACKAGE target, show org-visible groups

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-30 14:26:17 +08:00
weli b78f25da20 feat(course-package): add course-package CRUD pages under 教学资源库
Add list/add/edit views for course-package under the qumu section,
visible to TEACHER and SUPERVISOR roles via the 教学资源库 tab.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-30 13:51:27 +08:00
weli c3edff465b feat(org-home): render homepage markdown with signed images on teacher/student home
Made-with: Cursor
2026-04-28 10:45:11 +08:00
weli 4db9bc82c8 fix(org-homepage): sign upyun imgs in preview; strip failed upload placeholders
Made-with: Cursor
2026-04-28 09:46:48 +08:00
weli 925decd472 chore: vConsole logs for org homepage image compress upload
Made-with: Cursor
2026-04-28 08:32:17 +08:00
weli 1509bcbb99 fix(org): validate compress URL; register org_homepage in hty_resources
Made-with: Cursor
2026-04-28 08:25:09 +08:00
weli 6d74a34aa2 feat(org): homepage markdown image insert via compress pipeline
Made-with: Cursor
2026-04-28 08:07:34 +08:00
weli 1c59acc72b debug: 排课 clazz API 失败时输出 [ClazzApi]/[ClazzQuery] 到 vConsole
Made-with: Cursor
2026-04-28 00:41:28 +08:00
weli 27ce76bdfd fix(request): clazz API 使用 KC_SERVER/UC_SERVER 绝对 URL,避免相对路径落到错误 vhost 返回 HTML
Made-with: Cursor
2026-04-28 00:38:09 +08:00