diff --git a/.gitignore b/.gitignore index cf62af3..d1cc67e 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ dist/ .env.local .env.*.local coverage/ +.generated/ *.tsbuildinfo *.log .DS_Store diff --git a/docs/legacy-feature-gap.md b/docs/legacy-feature-gap.md new file mode 100644 index 0000000..180da18 --- /dev/null +++ b/docs/legacy-feature-gap.md @@ -0,0 +1,63 @@ +# 旧版页面与 .NET 接口覆盖矩阵 + +更新日期:2026-08-04。接口事实来源为 `tiku-backend.net` 当前 `/openapi/v1.json`;旧版页面只用于确认业务内容和信息层级,不复用 PocketBase、`MockBackend` 或浏览器伪造结果。 + +状态说明: + +- `ready`:第一批已接入可用的 .NET 契约。 +- `partial`:存在可复用基础契约,但缺少完整业务流程或公开发起配置。 +- `missing`:当前 OpenAPI 没有满足该学生功能的契约;仅保留前端类型位置,生产入口隐藏。 +- `deferred`:后端已有契约,但不在第一批核心学习闭环范围内。 + +## 第一批闭环 + +| 旧版能力 | SaaS 路由/位置 | 状态 | 当前 .NET 契约 | 前端模块 | +| --- | --- | --- | --- | --- | +| 密码/短信登录 | `/login` | ready | `/api/tenant/auth/browser/login/password`、`sms/send`、`login/sms` | `studentAuthApi` | +| 找回密码 | `/reset-password` | ready | `/api/tenant/auth/browser/password/reset/*` | `studentAuthApi` | +| 地区选择 | `/select-region` | ready | `/api/public/catalog/regions`、`PATCH /api/student/profile/me` | `catalogApi`、`profileApi` | +| 学习首页 | `/` | ready | Profile、learning stats/trend、exam countdowns、banners、announcements | `DashboardPage` | +| 科目/章节 | `/subjects`、`/subject/:subjectId` | ready | subjects、categories、practice-blueprints | `catalogApi` | +| 刷题与恢复 | `/quiz` | ready | practice-sessions create/detail、answers、submit | `learningApi` | +| 报告 | `/quiz/report/:sessionId` | ready | practice-sessions/report,含 `PendingReview` | `PracticeReportPage` | +| 错题/收藏 | `/collections` | ready | wrong-questions、favorites/questions | `CollectionsPage` | +| 公开品牌首页 | `/`(未登录) | ready | `/api/public/runtime/bootstrap`、学生资产 preview | `PublicLandingPage`、`RuntimeProvider` | +| 主题建站/发布 | `/manage/site` | ready | frontend-config draft/publish、`configVersion` | `site-builder/*` | +| OSS 主题资产 | 建站资产库 | ready | uploads/sign → OSS PUT → uploads/confirm → student asset preview | `assetApi`、`useThemeAssets` | +| 词汇单元与词表 | `/vocabulary/*` | ready | public vocabulary units/words | `VocabularyPage`、`VocabularyUnitPage` | +| 知识手册阅读 | `/handbook/*` | ready | public handbook subjects/chapters/entries | `student/pages/Handbook*` | +| 院校分数线 | `/scoreline` | ready | public scoreline records/years | `ScorelinePage` | +| 个人中心基础能力 | `/profile` | ready | student profile | `ProfilePage` | + +## 缺失与部分支持 + +| 旧版能力 | 目标路由 | 状态 | 缺少的后端契约 | 前端预留 | +| --- | --- | --- | --- | --- | +| 择校报告/志愿规划 | `/school-planning` | missing | 报告输入校验、生成、版本、查询和导出契约;公共 schools 目录不足以生成报告 | `SchoolPlanningClient`、feature `school-planning` | +| QQ OAuth | `/login` | missing | 浏览器授权发起、state/回调和租户公开 AppId 配置 | `QqOAuthClient`;不渲染按钮 | +| 学生自助激活码核销 | `/activation-code` | missing | 当前 activation/commerce 契约不能证明等价于旧版学生自助权益核销流程 | `StudentActivationCodeClient`、feature `activation-code` | +| 旧版 C/C++ 代码运行器 | `/code-runner` 或题目内 | missing | 沙箱执行、资源限制、语言版本、结果和审计契约 | `CodeRunnerClient`、feature `code-runner` | +| 微信网页登录 | `/login` | partial | 已有回调处理 `/api/tenant/auth/browser/oauth/wechat`,但 Runtime 缺少公开授权发起参数/URL | 仅记录 `loginMethods`,暂不显示不可完成入口 | +| 独立模拟考试/作业 | 待定 | partial | practice session 可承载答题和判分,但缺考试日程、限时、作业下发、班级分配、交卷策略和成绩册流程 | 后续在 learning 领域扩展,不伪装成普通练习 | +| 主题资产专用权限 | 建站资产库 | partial | 当前资产控制器复用 `tenant:question-bank:manage`,没有更细的 `tenant:theme-assets:manage` | 权限不足时只读保留资产,不回退 Data URL | + +## 已有接口但延期接入 + +| 能力 | 旧版路由/入口 | 状态 | 已确认 .NET 契约族 | 计划前端领域 | +| --- | --- | --- | --- | --- | +| 词汇学习进度/收藏/复习 | `/vocabulary/*` | deferred | student vocabulary progress/review/favorites | `student/vocabulary` | +| 视频精讲 | 题目解析/视频中心 | deferred | student videos search/play/progress、question videos | `student/videos` | +| 分数线动态图表与字段筛选 | `/scoreline` | deferred | public scoreline fields/trend | `student/scoreline` | +| 个人中心完整能力 | `/profile` | deferred | score-events、membership、设置等 | `student/profile` | +| 排行榜 | 首页/个人中心 | deferred | `/api/student/learning/leaderboard` | `student/leaderboard` | +| 积分/兑换 | 个人中心/商城 | deferred | `/api/student/points/*` | `student/points` | +| 商城、订单与支付 | `/store` | deferred | student commerce orders/coupons;支付能力需按实际支付渠道复核 | `student/commerce` | +| 优惠券 | 商城 | deferred | student commerce coupons claim/list/check | `student/commerce` | +| 推荐增长 | 邀请入口 | deferred | `/api/student/referral/*` | `student/referral` | + +## 前端约束 + +- 正式路由和导航必须同时满足:前端注册项为 `ready`、Runtime `enabledFeatures` 已启用、租户发布配置允许显示。 +- `missing`、`deferred` 能力可进入固定的建设中页面,但不得调用猜测接口或返回 Mock 成功;租户仍可在发布配置中隐藏入口。 +- 不允许配置 JSON 注入任意 React 组件、路由或远程脚本。 +- 缺失功能不调用猜测路径、不持久化 Mock 成功结果。后端补齐后,应先更新 OpenAPI 快照,再实现对应 Client。 diff --git a/docs/tenant-admin-coverage-matrix.md b/docs/tenant-admin-coverage-matrix.md new file mode 100644 index 0000000..af01388 --- /dev/null +++ b/docs/tenant-admin-coverage-matrix.md @@ -0,0 +1,40 @@ +# 租户后台旧版能力与 .NET 覆盖矩阵 + +更新日期:2026-08-04。旧版 `tiki-web` 和线上参考后台只用于确认功能名称、信息层级和交互密度;接口状态以当前 `tiku-backend.net` OpenAPI、`ui-bootstrap` 菜单、权限和 Runtime Feature 为准。 + +状态:`live` 已有真实页面;`frontend_pending` 后端能力存在但前端待接入;`backend_missing` 缺少等价后端契约;`tenant_disabled` 由运行时根据租户 Feature 动态判定。 + +| 一级大类 | 二级功能 | 前端路由 | 状态 | .NET 菜单/权限/Feature 或缺口 | +| --- | --- | --- | --- | --- | +| 总览 | 数据看板 | `/manage` | live | `tenant.dashboard` / `tenant:dashboard:view`;当前真实展示 Runtime 与 onboarding,统一经营聚合接口缺失 | +| 总览 | 收益账本 | `/manage/revenue` | backend_missing | 缺租户级收入趋势、渠道汇总和账本聚合契约 | +| 教学内容 | 题库管理 | `/manage/question-bank` | frontend_pending | `tenant.question-bank` / `tenant:question-bank:manage` / `question_bank.private` | +| 教学内容 | 词汇管理 | `/manage/vocabulary` | frontend_pending | `tenant.vocabulary` / `tenant:vocabulary:manage` / `content.vocabulary` | +| 教学内容 | 知识手册 | `/manage/handbook` | frontend_pending | `tenant.handbook` / `tenant:handbook:manage` / `content.handbook` | +| 教学内容 | 视频精讲 | `/manage/video` | frontend_pending | `tenant.video` / `tenant:video:manage` / `content.video` | +| 教学内容 | 分数线配置 | `/manage/scoreline` | frontend_pending | `tenant.scoreline` / `tenant:scoreline:manage` / `content.scoreline` | +| 教学内容 | 模拟考试 | `/manage/teaching/mock-exams` | backend_missing | 缺独立考试日程、试卷发布、监考策略和成绩册契约 | +| 教学内容 | 智能组卷、PDF 拆章、每日一练、题目导出 | `/manage/teaching/*` | backend_missing | 缺租户端任务、排期、生成物和导出契约 | +| 学员运营 | 学员与班级 | `/manage/students` | frontend_pending | `tenant.students` / `tenant:student:manage` / `student.management` | +| 学员运营 | 学习记录 | `/manage/students/learning-history` | backend_missing | 学生侧记录已有,缺租户管理端跨学员聚合查询 | +| 学员运营 | 反馈管理 | `/manage/students/feedback` | frontend_pending | Tenant Admin Direct feedback 契约 / `tenant:student:manage` | +| 学员运营 | CRM 跟进 | `/manage/students/crm` | frontend_pending | `tenant:crm:manage` / `crm.followup`;当前 `ui-bootstrap` 尚无独立租户 CRM 菜单 | +| 营销交易 | 商品套餐、订单、优惠券 | `/manage/commerce/*` | frontend_pending | `tenant.commerce` / `tenant:commerce:operate` / `commerce.student_store` | +| 营销交易 | 激活码 | `/manage/commerce/activation-codes` | backend_missing | 缺学生自助核销与租户端完整激活码管理契约 | +| 营销交易 | 代理推广 | `/manage/commerce/referrals` | frontend_pending | `tenant:commission:manage` / `growth.referral_commission`;当前 `ui-bootstrap` 尚无独立佣金菜单 | +| 营销交易 | 销售追踪 | `/manage/commerce/sales` | backend_missing | 缺渠道归因、销售漏斗和人员业绩聚合契约 | +| 站点装修 | 站点与主题 | `/manage/site/:tab` | live | frontend-config draft/publish、资产 sign/confirm/preview;上传暂复用 `tenant:question-bank:manage` | +| 站点装修 | 运营内容 | `/manage/site-content` | frontend_pending | `tenant.site-content` / `tenant:site-content:manage` / `marketing.site_content` | +| 系统设置 | 地区管理 | `/manage/settings/regions` | backend_missing | 公共地区目录可读,缺租户自主管理地区范围契约 | +| 系统设置 | 员工与权限 | `/manage/staff` | frontend_pending | `tenant.staff` / `tenant:staff:manage` | +| 系统设置 | 基础设置 | `/manage/settings/base` | frontend_pending | `tenant:settings:manage` 与 Tenant Admin Direct 品牌/域名等契约 | +| 系统设置 | 登录方式、外部服务、短信 | `/manage/settings/*`、`/manage/providers` | frontend_pending | `tenant.providers` / `tenant:provider:manage` | +| 系统设置 | SaaS 账务 | `/manage/billing` | frontend_pending | `tenant.billing` / `tenant:billing:manage` | +| 系统设置 | 审计日志 | `/manage/settings/audit` | frontend_pending | Tenant Admin Direct audit 契约;前端按 `tenant:settings:manage` 暂时归组 | + +## 前端行为约束 + +- `ui-bootstrap` 返回的已知菜单只映射到固定注册路由;未知菜单代码忽略并在开发环境告警。 +- 具备权限但套餐 Feature 未启用时显示 `tenant_disabled`,不发送业务请求。 +- `frontend_pending` 和 `backend_missing` 路由只显示统一占位页,不返回 Mock 成功结果。 +- Mock 模式模拟 Owner 完整权限、标准菜单和天津演示数据;API 模式不会因为接口为空或失败回退 Mock。 diff --git a/package-lock.json b/package-lock.json index 48df62f..e276844 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,22 +12,32 @@ "@dnd-kit/core": "6.3.1", "@dnd-kit/sortable": "10.0.0", "@dnd-kit/utilities": "3.2.2", + "@tanstack/react-query": "^5.101.4", "antd": "6.5.3", + "katex": "^0.18.1", "lucide-react": "0.468.0", + "openapi-fetch": "^0.17.0", "react": "19.2.8", "react-dom": "19.2.8", - "react-router": "8.3.0" + "react-markdown": "^10.1.0", + "react-router": "8.3.0", + "rehype-katex": "^7.0.1", + "rehype-sanitize": "^6.0.0", + "remark-gfm": "^4.0.1", + "remark-math": "^6.0.0" }, "devDependencies": { "@tailwindcss/vite": "4.3.3", "@testing-library/jest-dom": "6.9.1", "@testing-library/react": "16.3.2", + "@types/katex": "^0.16.8", "@types/node": "24.10.0", "@types/react": "19.2.2", "@types/react-dom": "19.2.2", "@vitejs/plugin-react": "6.0.5", "jsdom": "28.1.0", "msw": "2.15.0", + "openapi-typescript": "^7.13.0", "tailwindcss": "4.3.3", "typescript": "5.9.3", "vite": "8.2.0", @@ -195,7 +205,6 @@ "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-validator-identifier": "^7.29.7", "js-tokens": "^4.0.0", @@ -211,7 +220,6 @@ "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=6.9.0" } @@ -1417,6 +1425,52 @@ "integrity": "sha512-sL6cvO2IfkSu/iU+zs2S/w01B7A8V7suXSIKEN4hPFFdZoiPGxrj5pAG0lCaqLWiEIrjKzdznIWuaLcxPR53qw==", "license": "MIT" }, + "node_modules/@redocly/ajv": { + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/@redocly/ajv/-/ajv-8.11.2.tgz", + "integrity": "sha512-io1JpnwtIcvojV7QKDUSIuMN/ikdOUd1ReEnUnMKGfDVridQZ31J0MmIuqwuRjWDZfmvr+Q0MqCcfHM2gTivOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js-replace": "^1.0.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@redocly/config": { + "version": "0.22.0", + "resolved": "https://registry.npmjs.org/@redocly/config/-/config-0.22.0.tgz", + "integrity": "sha512-gAy93Ddo01Z3bHuVdPWfCwzgfaYgMdaZPcfL7JZ7hWJoK9V0lXDbigTWkhiPFAaLWzbOJ+kbUQG1+XwIm0KRGQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@redocly/openapi-core": { + "version": "1.34.18", + "resolved": "https://registry.npmjs.org/@redocly/openapi-core/-/openapi-core-1.34.18.tgz", + "integrity": "sha512-UyKIm0wTPw5BcY7Z2PkbK1Ma260um96LSBWXHrdSMe+ZV0EPMyDfAcUcjjm3qEiGST9OK/1TriekdPCZkn4Q3A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@redocly/ajv": "8.11.2", + "@redocly/config": "0.22.0", + "colorette": "1.4.0", + "https-proxy-agent": "7.0.6", + "js-levenshtein": "1.1.6", + "js-yaml": "4.3.0", + "minimatch": "5.1.9", + "pluralize": "8.0.0", + "yaml-ast-parser": "0.0.43" + }, + "engines": { + "node": ">=18.17.0", + "npm": ">=9.5.0" + } + }, "node_modules/@rolldown/binding-android-arm64": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.1.tgz", @@ -1987,6 +2041,32 @@ "vite": "^5.2.0 || ^6 || ^7 || ^8" } }, + "node_modules/@tanstack/query-core": { + "version": "5.101.4", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.101.4.tgz", + "integrity": "sha512-gNwcvOJcRbLWPOLG/2OBm+zM+Yv+MKsXKEOWC57USuZDEsI71hEErQsiEGx5wX9rzWWkfwM0fVSPoiIFSsxfiw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/react-query": { + "version": "5.101.4", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.101.4.tgz", + "integrity": "sha512-yRg2pfOCxIs4ZJW3XYYHU/WgtD04FHSnfHlpRT7h7pR77hwkdRG4wxbKe4aq6P0RvXUTBSQpQeadS1SUYUe+KA==", + "license": "MIT", + "dependencies": { + "@tanstack/query-core": "5.101.4" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^18 || ^19" + } + }, "node_modules/@testing-library/dom": { "version": "10.4.1", "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.1.tgz", @@ -2093,6 +2173,15 @@ "assertion-error": "^2.0.1" } }, + "node_modules/@types/debug": { + "version": "4.1.13", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.13.tgz", + "integrity": "sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==", + "license": "MIT", + "dependencies": { + "@types/ms": "*" + } + }, "node_modules/@types/deep-eql": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", @@ -2104,7 +2193,45 @@ "version": "1.0.9", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", - "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree-jsx": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.5.tgz", + "integrity": "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==", + "license": "MIT", + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/@types/hast": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.5.tgz", + "integrity": "sha512-rp/ezSWaD1m44dPKICGhiskI13nVr7qTloFwDa/IYkhhf5nzwP+zIQcIJh3WIFSBOy/H1PzB40jPjMDksN4F+g==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/katex": { + "version": "0.16.8", + "resolved": "https://registry.npmjs.org/@types/katex/-/katex-0.16.8.tgz", + "integrity": "sha512-trgaNyfU+Xh2Tc+ABIb44a5AYUpicB3uwirOioeOkNPPbmgRNtcWyDeeFRzjPZENO9Vq8gvVqfhaaXWLlevVwg==", + "license": "MIT" + }, + "node_modules/@types/mdast": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", + "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", + "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", "license": "MIT" }, "node_modules/@types/node": { @@ -2121,7 +2248,6 @@ "version": "19.2.2", "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.2.tgz", "integrity": "sha512-6mDvHUFSjyT2B2yeNx2nUgMxh9LtOWvkhIU3uePn2I2oyNymUAX1NIsdgviM4CH+JSrp2D2hsMvJOkxY+0wNRA==", - "dev": true, "license": "MIT", "dependencies": { "csstype": "^3.0.2" @@ -2154,6 +2280,18 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "license": "MIT" + }, + "node_modules/@ungap/structured-clone": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.3.tgz", + "integrity": "sha512-60YRaenCQcVjYEKOcG824+DRGGIQ3VKErcBoAEDJZz5bKIs2ZG+X/H9Nk+Q6EVkwJk5QNApxbrc5QtBSwtrXAg==", + "license": "ISC" + }, "node_modules/@vitejs/plugin-react": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-6.0.5.tgz", @@ -2303,6 +2441,16 @@ "node": ">= 14" } }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", @@ -2409,6 +2557,13 @@ "react-dom": ">=16.0.0" } }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, "node_modules/aria-query": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", @@ -2429,6 +2584,23 @@ "node": ">=12" } }, + "node_modules/bail": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", + "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, "node_modules/bidi-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/bidi-js/-/bidi-js-1.0.3.tgz", @@ -2439,6 +2611,26 @@ "require-from-string": "^2.0.2" } }, + "node_modules/brace-expansion": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.4.tgz", + "integrity": "sha512-hGfVzPxthbf3+2yjg/RBs60cB0FhqBS/zvdV/4wn4/BmN0bNMMHPc4V/BbFieqf1TKAGGAHnY4eSjajCl0f2Xg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/ccount": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", + "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/chai": { "version": "6.2.2", "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz", @@ -2449,6 +2641,53 @@ "node": ">=18" } }, + "node_modules/change-case": { + "version": "5.4.4", + "resolved": "https://registry.npmjs.org/change-case/-/change-case-5.4.4.tgz", + "integrity": "sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/character-entities": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-html4": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", + "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-legacy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", + "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-reference-invalid": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz", + "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/cli-width": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", @@ -2503,6 +2742,32 @@ "dev": true, "license": "MIT" }, + "node_modules/colorette": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.4.0.tgz", + "integrity": "sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==", + "dev": true, + "license": "MIT" + }, + "node_modules/comma-separated-tokens": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", + "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, "node_modules/compute-scroll-into-view": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-3.1.1.tgz", @@ -2603,7 +2868,6 @@ "version": "4.4.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "dev": true, "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -2624,11 +2888,23 @@ "dev": true, "license": "MIT" }, + "node_modules/decode-named-character-reference": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.3.0.tgz", + "integrity": "sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==", + "license": "MIT", + "dependencies": { + "character-entities": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/dequal": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", - "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -2644,6 +2920,19 @@ "node": ">=8" } }, + "node_modules/devlop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", + "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "license": "MIT", + "dependencies": { + "dequal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/dom-accessibility-api": { "version": "0.5.16", "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", @@ -2703,6 +2992,28 @@ "node": ">=6" } }, + "node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/estree-util-is-identifier-name": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-3.0.0.tgz", + "integrity": "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/estree-walker": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", @@ -2723,6 +3034,19 @@ "node": ">=12.0.0" } }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "license": "MIT" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, "node_modules/fast-string-truncated-width": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/fast-string-truncated-width/-/fast-string-truncated-width-3.0.3.tgz", @@ -2810,6 +3134,213 @@ "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0" } }, + "node_modules/hast-util-from-dom": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/hast-util-from-dom/-/hast-util-from-dom-5.0.1.tgz", + "integrity": "sha512-N+LqofjR2zuzTjCPzyDUdSshy4Ma6li7p/c3pA78uTwzFgENbgbUrm2ugwsOdcjI1muO+o6Dgzp9p8WHtn/39Q==", + "license": "ISC", + "dependencies": { + "@types/hast": "^3.0.0", + "hastscript": "^9.0.0", + "web-namespaces": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-from-html": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/hast-util-from-html/-/hast-util-from-html-2.0.3.tgz", + "integrity": "sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "devlop": "^1.1.0", + "hast-util-from-parse5": "^8.0.0", + "parse5": "^7.0.0", + "vfile": "^6.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-from-html-isomorphic": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hast-util-from-html-isomorphic/-/hast-util-from-html-isomorphic-2.0.0.tgz", + "integrity": "sha512-zJfpXq44yff2hmE0XmwEOzdWin5xwH+QIhMLOScpX91e/NSGPsAzNCvLQDIEPyO2TXi+lBmU6hjLIhV8MwP2kw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-from-dom": "^5.0.0", + "hast-util-from-html": "^2.0.0", + "unist-util-remove-position": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-from-html/node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/hast-util-from-html/node_modules/parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "license": "MIT", + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/hast-util-from-parse5": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-8.0.3.tgz", + "integrity": "sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "hastscript": "^9.0.0", + "property-information": "^7.0.0", + "vfile": "^6.0.0", + "vfile-location": "^5.0.0", + "web-namespaces": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-is-element": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-3.0.0.tgz", + "integrity": "sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-parse-selector": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz", + "integrity": "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-sanitize": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/hast-util-sanitize/-/hast-util-sanitize-5.0.2.tgz", + "integrity": "sha512-3yTWghByc50aGS7JlGhk61SPenfE/p1oaFeNwkOOyrscaOkMGrcW9+Cy/QAIOBpZxP1yqDIzFMR0+Np0i0+usg==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@ungap/structured-clone": "^1.0.0", + "unist-util-position": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-jsx-runtime": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.6.tgz", + "integrity": "sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "hast-util-whitespace": "^3.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "style-to-js": "^1.0.0", + "unist-util-position": "^5.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-text": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/hast-util-to-text/-/hast-util-to-text-4.0.2.tgz", + "integrity": "sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "hast-util-is-element": "^3.0.0", + "unist-util-find-after": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-whitespace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", + "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hastscript": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-9.0.1.tgz", + "integrity": "sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-parse-selector": "^4.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/headers-polyfill": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/headers-polyfill/-/headers-polyfill-5.0.1.tgz", @@ -2834,6 +3365,16 @@ "node": "^20.19.0 || ^22.12.0 || >=24.0.0" } }, + "node_modules/html-url-attributes": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/html-url-attributes/-/html-url-attributes-3.0.1.tgz", + "integrity": "sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/http-proxy-agent": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", @@ -2872,6 +3413,59 @@ "node": ">=8" } }, + "node_modules/index-to-position": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/index-to-position/-/index-to-position-1.2.0.tgz", + "integrity": "sha512-Yg7+ztRkqslMAS2iFaU+Oa4KTSidr63OsFGlOrJoW981kIYO3CGCS3wA95P1mUi/IVSJkn0D479KTJpVpvFNuw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/inline-style-parser": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.7.tgz", + "integrity": "sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==", + "license": "MIT" + }, + "node_modules/is-alphabetical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", + "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-alphanumerical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", + "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", + "license": "MIT", + "dependencies": { + "is-alphabetical": "^2.0.0", + "is-decimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-decimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", + "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -2882,6 +3476,16 @@ "node": ">=8" } }, + "node_modules/is-hexadecimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", + "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/is-mobile": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/is-mobile/-/is-mobile-5.0.0.tgz", @@ -2895,6 +3499,18 @@ "dev": true, "license": "MIT" }, + "node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-potential-custom-element-name": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", @@ -2912,13 +3528,45 @@ "jiti": "lib/jiti-cli.mjs" } }, + "node_modules/js-levenshtein": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/js-levenshtein/-/js-levenshtein-1.1.6.tgz", + "integrity": "sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "dev": true, + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.0.tgz", + "integrity": "sha512-1td788aAnnZ5qs7V2QIRl1owjtYpbKt749Y3xauqQgwIIGF/xXWz1wMTEBx5O3LK3lXLVuqXPdPxj2BoFHaW9Q==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/puzrin" + }, + { + "type": "github", + "url": "https://github.com/sponsors/nodeca" + } + ], "license": "MIT", - "peer": true + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } }, "node_modules/jsdom": { "version": "28.1.0", @@ -2961,6 +3609,13 @@ } } }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, "node_modules/json2mq": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/json2mq/-/json2mq-0.2.0.tgz", @@ -2970,6 +3625,22 @@ "string-convert": "^0.2.0" } }, + "node_modules/katex": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/katex/-/katex-0.18.1.tgz", + "integrity": "sha512-Td8GCYSxDAoMhHOlKmCFMJ/hz5qlAAb71n66Dryw9nfCVfumLo7nhuotbvKom/XPADmrYC3O5QR71EPq4DarJQ==", + "funding": [ + "https://opencollective.com/katex", + "https://github.com/sponsors/katex" + ], + "license": "MIT", + "dependencies": { + "commander": "^8.3.0" + }, + "bin": { + "katex": "cli.js" + } + }, "node_modules/lightningcss": { "version": "1.32.0", "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz", @@ -3243,6 +3914,16 @@ "url": "https://opencollective.com/parcel" } }, + "node_modules/longest-streak": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", + "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/lru-cache": { "version": "11.5.2", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.2.tgz", @@ -3283,6 +3964,305 @@ "@jridgewell/sourcemap-codec": "^1.5.5" } }, + "node_modules/markdown-table": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz", + "integrity": "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/mdast-util-find-and-replace": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.2.tgz", + "integrity": "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "escape-string-regexp": "^5.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-from-markdown": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.3.tgz", + "integrity": "sha512-W4mAWTvSlKvf8L6J+VN9yLSqQ9AOAAvHuoDAmPkz4dHf553m5gVj2ejadHJhoJmcmxEnOv6Pa8XJhpxE93kb8Q==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark": "^4.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.1.0.tgz", + "integrity": "sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==", + "license": "MIT", + "dependencies": { + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-gfm-autolink-literal": "^2.0.0", + "mdast-util-gfm-footnote": "^2.0.0", + "mdast-util-gfm-strikethrough": "^2.0.0", + "mdast-util-gfm-table": "^2.0.0", + "mdast-util-gfm-task-list-item": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-autolink-literal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.1.tgz", + "integrity": "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "ccount": "^2.0.0", + "devlop": "^1.0.0", + "mdast-util-find-and-replace": "^3.0.0", + "micromark-util-character": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-strikethrough": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", + "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-table": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", + "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "markdown-table": "^3.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-task-list-item": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", + "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-math": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-math/-/mdast-util-math-3.0.0.tgz", + "integrity": "sha512-Tl9GBNeG/AhJnQM221bJR2HPvLOSnLE/T9cJI9tlc6zwQk2nPk/4f0cHkOdEixQPC/j8UtKDdITswvLAy1OZ1w==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "longest-streak": "^3.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.1.0", + "unist-util-remove-position": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-expression": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.1.tgz", + "integrity": "sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-jsx": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.2.0.tgz", + "integrity": "sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "parse-entities": "^4.0.0", + "stringify-entities": "^4.0.0", + "unist-util-stringify-position": "^4.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdxjs-esm": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz", + "integrity": "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-phrasing": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", + "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-hast": { + "version": "13.2.1", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.1.tgz", + "integrity": "sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@ungap/structured-clone": "^1.0.0", + "devlop": "^1.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "trim-lines": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-markdown": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz", + "integrity": "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "longest-streak": "^3.0.0", + "mdast-util-phrasing": "^4.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "unist-util-visit": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", + "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/mdn-data": { "version": "2.27.1", "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.27.1.tgz", @@ -3290,6 +4270,604 @@ "dev": true, "license": "CC0-1.0" }, + "node_modules/micromark": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", + "integrity": "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz", + "integrity": "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-destination": "^2.0.0", + "micromark-factory-label": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-title": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-html-tag-name": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", + "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==", + "license": "MIT", + "dependencies": { + "micromark-extension-gfm-autolink-literal": "^2.0.0", + "micromark-extension-gfm-footnote": "^2.0.0", + "micromark-extension-gfm-strikethrough": "^2.0.0", + "micromark-extension-gfm-table": "^2.0.0", + "micromark-extension-gfm-tagfilter": "^2.0.0", + "micromark-extension-gfm-task-list-item": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz", + "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==", + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-strikethrough": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.1.0.tgz", + "integrity": "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-table": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.1.tgz", + "integrity": "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-tagfilter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz", + "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==", + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-task-list-item": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz", + "integrity": "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-math": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-math/-/micromark-extension-math-3.1.0.tgz", + "integrity": "sha512-lvEqd+fHjATVs+2v/8kg9i5Q0AP2k85H0WUOwpIVvUML8BapsMvh1XAogmQjOCsLpoKRCVQqEkQBB3NhVBcsOg==", + "license": "MIT", + "dependencies": { + "@types/katex": "^0.16.0", + "devlop": "^1.0.0", + "katex": "^0.16.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-math/node_modules/katex": { + "version": "0.16.47", + "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.47.tgz", + "integrity": "sha512-Eeo8Ys1doU1z+x8AZsPpQu+p/QcZBI5PeOo7QGQdy2x2m0MU/hYagBbGOmXwr5KVbEfVuWv9LpnQWeehogurjg==", + "funding": [ + "https://opencollective.com/katex", + "https://github.com/sponsors/katex" + ], + "license": "MIT", + "dependencies": { + "commander": "^8.3.0" + }, + "bin": { + "katex": "cli.js" + } + }, + "node_modules/micromark-factory-destination": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", + "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-label": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz", + "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-title": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz", + "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-whitespace": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz", + "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-chunked": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz", + "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-classify-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz", + "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-combine-extensions": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz", + "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-chunked": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-numeric-character-reference": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz", + "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-string": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz", + "integrity": "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-encode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", + "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-html-tag-name": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz", + "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-normalize-identifier": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz", + "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-resolve-all": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz", + "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", + "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-subtokenize": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz", + "integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-types": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz", + "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, "node_modules/min-indent": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", @@ -3300,11 +4878,23 @@ "node": ">=4" } }, + "node_modules/minimatch": { + "version": "5.1.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.9.tgz", + "integrity": "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, "license": "MIT" }, "node_modules/msw": { @@ -3395,6 +4985,42 @@ "node": ">=12.20.0" } }, + "node_modules/openapi-fetch": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/openapi-fetch/-/openapi-fetch-0.17.0.tgz", + "integrity": "sha512-PsbZR1wAPcG91eEthKhN+Zn92FMHxv+/faECIwjXdxfTODGSGegYv0sc1Olz+HYPvKOuoXfp+0pA2XVt2cI0Ig==", + "license": "MIT", + "dependencies": { + "openapi-typescript-helpers": "^0.1.0" + } + }, + "node_modules/openapi-typescript": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/openapi-typescript/-/openapi-typescript-7.13.0.tgz", + "integrity": "sha512-EFP392gcqXS7ntPvbhBzbF8TyBA+baIYEm791Hy5YkjDYKTnk/Tn5OQeKm5BIZvJihpp8Zzr4hzx0Irde1LNGQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@redocly/openapi-core": "^1.34.6", + "ansi-colors": "^4.1.3", + "change-case": "^5.4.4", + "parse-json": "^8.3.0", + "supports-color": "^10.2.2", + "yargs-parser": "^21.1.1" + }, + "bin": { + "openapi-typescript": "bin/cli.js" + }, + "peerDependencies": { + "typescript": "^5.x" + } + }, + "node_modules/openapi-typescript-helpers": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/openapi-typescript-helpers/-/openapi-typescript-helpers-0.1.0.tgz", + "integrity": "sha512-OKTGPthhivLw/fHz6c3OPtg72vi86qaMlqbJuVJ23qOvQ+53uw1n7HdmkJFibloF7QEjDrDkzJiOJuockM/ljw==", + "license": "MIT" + }, "node_modules/outvariant": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/outvariant/-/outvariant-1.4.3.tgz", @@ -3402,6 +5028,62 @@ "dev": true, "license": "MIT" }, + "node_modules/parse-entities": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.2.tgz", + "integrity": "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "character-entities-legacy": "^3.0.0", + "character-reference-invalid": "^2.0.0", + "decode-named-character-reference": "^1.0.0", + "is-alphanumerical": "^2.0.0", + "is-decimal": "^2.0.0", + "is-hexadecimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/parse-entities/node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", + "license": "MIT" + }, + "node_modules/parse-json": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-8.3.0.tgz", + "integrity": "sha512-ybiGyvspI+fAoRQbIPRddCcSTV9/LsJbf0e/S85VLowVGzRmokfneg2kwVW/KU5rOXrPSbF1qAKPMgNTqqROQQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.26.2", + "index-to-position": "^1.1.0", + "type-fest": "^4.39.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse-json/node_modules/type-fest": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/parse5": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/parse5/-/parse5-8.0.1.tgz", @@ -3449,6 +5131,16 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/pluralize": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", + "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/postcss": { "version": "8.5.25", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.25.tgz", @@ -3502,6 +5194,16 @@ "license": "MIT", "peer": true }, + "node_modules/property-information": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.2.0.tgz", + "integrity": "sha512-IAtzIB6sUiWaJYrX9smp3V46pBGbBeLFRGdh25kg1334VcBlD8HzhPeNIWQH9zhGmo2itIe25EHt9dQP7G5hmg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -3539,6 +5241,33 @@ "integrity": "sha512-s5un28nYxKJw5gvUHyW5PCC28CvBqLu9r3cWgzHT4Vo/5fqqkFcdRYsGcKf50WMPpjjFZS5d76fn3YCo2njKwQ==", "license": "MIT" }, + "node_modules/react-markdown": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/react-markdown/-/react-markdown-10.1.0.tgz", + "integrity": "sha512-qKxVopLT/TyA6BX3Ue5NwabOsAzm0Q7kAPwq6L+wWDwisYs7R8vZ0nRXqq6rkueboxpkjvLGU9fWifiX/ZZFxQ==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "hast-util-to-jsx-runtime": "^2.0.0", + "html-url-attributes": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "remark-parse": "^11.0.0", + "remark-rehype": "^11.0.0", + "unified": "^11.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + }, + "peerDependencies": { + "@types/react": ">=18", + "react": ">=18" + } + }, "node_modules/react-router": { "version": "8.3.0", "resolved": "https://registry.npmjs.org/react-router/-/react-router-8.3.0.tgz", @@ -3574,6 +5303,137 @@ "node": ">=8" } }, + "node_modules/rehype-katex": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/rehype-katex/-/rehype-katex-7.0.1.tgz", + "integrity": "sha512-OiM2wrZ/wuhKkigASodFoo8wimG3H12LWQaH8qSPVJn9apWKFSH3YOCtbKpBorTVw/eI7cuT21XBbvwEswbIOA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/katex": "^0.16.0", + "hast-util-from-html-isomorphic": "^2.0.0", + "hast-util-to-text": "^4.0.0", + "katex": "^0.16.0", + "unist-util-visit-parents": "^6.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-katex/node_modules/katex": { + "version": "0.16.47", + "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.47.tgz", + "integrity": "sha512-Eeo8Ys1doU1z+x8AZsPpQu+p/QcZBI5PeOo7QGQdy2x2m0MU/hYagBbGOmXwr5KVbEfVuWv9LpnQWeehogurjg==", + "funding": [ + "https://opencollective.com/katex", + "https://github.com/sponsors/katex" + ], + "license": "MIT", + "dependencies": { + "commander": "^8.3.0" + }, + "bin": { + "katex": "cli.js" + } + }, + "node_modules/rehype-sanitize": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/rehype-sanitize/-/rehype-sanitize-6.0.0.tgz", + "integrity": "sha512-CsnhKNsyI8Tub6L4sm5ZFsme4puGfc6pYylvXo1AeqaGbjOYyzNv3qZPwvs0oMJ39eryyeOdmxwUIo94IpEhqg==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-sanitize": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-gfm": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.1.tgz", + "integrity": "sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-gfm": "^3.0.0", + "micromark-extension-gfm": "^3.0.0", + "remark-parse": "^11.0.0", + "remark-stringify": "^11.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-math": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/remark-math/-/remark-math-6.0.0.tgz", + "integrity": "sha512-MMqgnP74Igy+S3WwnhQ7kqGlEerTETXMvJhrUzDikVZ2/uogJCb+WHUg97hK9/jcfc0dkD73s3LN8zU49cTEtA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-math": "^3.0.0", + "micromark-extension-math": "^3.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-parse": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", + "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-rehype": { + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.1.2.tgz", + "integrity": "sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "mdast-util-to-hast": "^13.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-stringify": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz", + "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-to-markdown": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -3700,6 +5560,16 @@ "node": ">=0.10.0" } }, + "node_modules/space-separated-tokens": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", + "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/stackback": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", @@ -3752,6 +5622,20 @@ "node": ">=8" } }, + "node_modules/stringify-entities": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", + "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", + "license": "MIT", + "dependencies": { + "character-entities-html4": "^2.0.0", + "character-entities-legacy": "^3.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -3778,12 +5662,43 @@ "node": ">=8" } }, + "node_modules/style-to-js": { + "version": "1.1.21", + "resolved": "https://registry.npmjs.org/style-to-js/-/style-to-js-1.1.21.tgz", + "integrity": "sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ==", + "license": "MIT", + "dependencies": { + "style-to-object": "1.0.14" + } + }, + "node_modules/style-to-object": { + "version": "1.0.14", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.14.tgz", + "integrity": "sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw==", + "license": "MIT", + "dependencies": { + "inline-style-parser": "0.2.7" + } + }, "node_modules/stylis": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.4.0.tgz", "integrity": "sha512-5Z9ZpRzfuH6l/UAvCPAPUo3665Nk2wLaZU3x+TLHKVzIz33+sbJqbtrYoC3KD4/uVOr2Zp+L0LySezP9OHV9yA==", "license": "MIT" }, + "node_modules/supports-color": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-10.2.2.tgz", + "integrity": "sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, "node_modules/symbol-tree": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", @@ -3924,6 +5839,26 @@ "node": ">=20" } }, + "node_modules/trim-lines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", + "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/trough": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", + "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", @@ -3977,6 +5912,121 @@ "dev": true, "license": "MIT" }, + "node_modules/unified": { + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", + "integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "bail": "^2.0.0", + "devlop": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-find-after": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-find-after/-/unist-util-find-after-5.0.0.tgz", + "integrity": "sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-is": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.1.tgz", + "integrity": "sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-position": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", + "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-remove-position": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-5.0.0.tgz", + "integrity": "sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-visit": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.1.0.tgz", + "integrity": "sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-parents": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.2.tgz", + "integrity": "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/until-async": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/until-async/-/until-async-3.0.2.tgz", @@ -3987,6 +6037,55 @@ "url": "https://github.com/sponsors/kettanaito" } }, + "node_modules/uri-js-replace": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/uri-js-replace/-/uri-js-replace-1.0.1.tgz", + "integrity": "sha512-W+C9NWNLFOoBI2QWDp4UT9pv65r2w5Cx+3sTYFvtMdDBxkKt1syCqsUdSFAChbEe1uK5TfS04wt/nGwmaeIQ0g==", + "dev": true, + "license": "MIT" + }, + "node_modules/vfile": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", + "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-location": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-5.0.3.tgz", + "integrity": "sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-message": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.3.tgz", + "integrity": "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/vite": { "version": "8.2.0", "resolved": "https://registry.npmjs.org/vite/-/vite-8.2.0.tgz", @@ -4441,6 +6540,16 @@ "node": ">=18" } }, + "node_modules/web-namespaces": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz", + "integrity": "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/webidl-conversions": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-8.0.1.tgz", @@ -4554,6 +6663,13 @@ "node": ">=10" } }, + "node_modules/yaml-ast-parser": { + "version": "0.0.43", + "resolved": "https://registry.npmjs.org/yaml-ast-parser/-/yaml-ast-parser-0.0.43.tgz", + "integrity": "sha512-2PTINUwsRqSd+s8XxKaJWQlUuEMHJQyEuh2edBbW8KNJz0SJPwUSD2zRWqezFEdN7IzAgeuYHFUCF7o8zRdZ0A==", + "dev": true, + "license": "Apache-2.0" + }, "node_modules/yargs": { "version": "17.7.3", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.3.tgz", @@ -4582,6 +6698,16 @@ "engines": { "node": ">=12" } + }, + "node_modules/zwitch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", + "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } } } } diff --git a/package.json b/package.json index 4c68c7b..38add14 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ "scripts": { "dev": "vite", "build": "tsc -b && vite build", + "generate:api": "node scripts/generate-api.mjs", "preview": "vite preview", "test": "vitest run", "test:watch": "vitest", @@ -17,22 +18,32 @@ "@dnd-kit/core": "6.3.1", "@dnd-kit/sortable": "10.0.0", "@dnd-kit/utilities": "3.2.2", + "@tanstack/react-query": "^5.101.4", "antd": "6.5.3", + "katex": "^0.18.1", "lucide-react": "0.468.0", + "openapi-fetch": "^0.17.0", "react": "19.2.8", "react-dom": "19.2.8", - "react-router": "8.3.0" + "react-markdown": "^10.1.0", + "react-router": "8.3.0", + "rehype-katex": "^7.0.1", + "rehype-sanitize": "^6.0.0", + "remark-gfm": "^4.0.1", + "remark-math": "^6.0.0" }, "devDependencies": { "@tailwindcss/vite": "4.3.3", "@testing-library/jest-dom": "6.9.1", "@testing-library/react": "16.3.2", + "@types/katex": "^0.16.8", "@types/node": "24.10.0", "@types/react": "19.2.2", "@types/react-dom": "19.2.2", "@vitejs/plugin-react": "6.0.5", "jsdom": "28.1.0", "msw": "2.15.0", + "openapi-typescript": "^7.13.0", "tailwindcss": "4.3.3", "typescript": "5.9.3", "vite": "8.2.0", diff --git a/scripts/generate-api.mjs b/scripts/generate-api.mjs new file mode 100644 index 0000000..9ccaf37 --- /dev/null +++ b/scripts/generate-api.mjs @@ -0,0 +1,32 @@ +import { execFileSync } from "node:child_process"; +import { mkdirSync, writeFileSync } from "node:fs"; +import { fileURLToPath } from "node:url"; +import path from "node:path"; + +const projectRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), ".."); +const openApiUrl = process.env.OPENAPI_URL || "http://localhost:5090/openapi/v1.json"; +const response = await fetch(openApiUrl); +if (!response.ok) { + throw new Error(`OpenAPI 下载失败:${response.status} ${response.statusText}`); +} + +const document = await response.json(); +const generatedDir = path.join(projectRoot, ".generated"); +const apiDir = path.join(projectRoot, "src", "api"); +mkdirSync(generatedDir, { recursive: true }); +mkdirSync(apiDir, { recursive: true }); + +const snapshotPath = path.join(generatedDir, "openapi.json"); +writeFileSync(snapshotPath, `${JSON.stringify(document)}\n`); + +const cli = path.join( + projectRoot, + "node_modules", + ".bin", + process.platform === "win32" ? "openapi-typescript.cmd" : "openapi-typescript", +); +execFileSync(cli, [snapshotPath, "-o", path.join(apiDir, "schema.generated.d.ts")], { + stdio: "inherit", +}); + +console.log(`已生成前端 OpenAPI 类型,来源:${openApiUrl}`); diff --git a/src/api/assetApi.ts b/src/api/assetApi.ts new file mode 100644 index 0000000..cef2b8c --- /dev/null +++ b/src/api/assetApi.ts @@ -0,0 +1,59 @@ +import { apiClient, unwrap } from "./client"; + +const allowedTypes = new Set(["image/png", "image/jpeg", "image/webp", "image/svg+xml"]); +const maxImageBytes = 8 * 1024 * 1024; + +export interface ThemeAssetUpload { + assetId: string; + fileName: string; +} + +export const assetApi = { + preview: (assetId: string) => unwrap(apiClient.GET("/api/student/assets/{assetId}/preview", { + params: { path: { assetId }, query: { ExpiresInSeconds: 1800 } }, + })), + uploadThemeImage: async ( + file: File, + title: string, + onProgress?: (percent: number) => void, + ): Promise => { + if (!allowedTypes.has(file.type)) throw new Error("仅支持 PNG、JPEG、WebP 或 SVG 图片。"); + if (file.size > maxImageBytes) throw new Error("图片不能超过 8 MB。"); + + const signed = await unwrap(apiClient.POST("/api/tenant/content/assets/uploads/sign", { + body: { + fileName: file.name, + mimeType: file.type, + fileSizeBytes: file.size, + title, + category: "theme", + assetType: "Image", + visibility: "Public", + isPublic: true, + expiresInSeconds: 900, + metadata: { purpose: "tenant-theme" }, + }, + })); + + await new Promise((resolve, reject) => { + const request = new XMLHttpRequest(); + request.open(signed.upload.method, signed.upload.url); + Object.entries(signed.upload.headers).forEach(([key, value]) => request.setRequestHeader(key, value)); + request.upload.onprogress = (event) => { + if (event.lengthComputable) onProgress?.(Math.round((event.loaded / event.total) * 100)); + }; + request.onerror = () => reject(new Error("上传连接中断,请重试。")); + request.onload = () => { + if (request.status >= 200 && request.status < 300) resolve(); + else reject(new Error(`对象存储上传失败(${request.status})。`)); + }; + request.send(file); + }); + + await unwrap(apiClient.POST("/api/tenant/content/assets/uploads/confirm", { + body: { assetId: signed.item.id, mimeType: file.type, fileSizeBytes: file.size }, + })); + onProgress?.(100); + return { assetId: signed.item.id, fileName: file.name }; + }, +}; diff --git a/src/api/backofficeApi.ts b/src/api/backofficeApi.ts index 1c4e56f..69a56cc 100644 --- a/src/api/backofficeApi.ts +++ b/src/api/backofficeApi.ts @@ -12,11 +12,27 @@ interface BackofficeUiBootstrapResponse { enabledFeatures: string[]; } -const supportedMenuRoutes: Record = { - 'tenant.dashboard': { path: '/manage' }, - 'tenant.site-content': { path: '/manage/site', requiresSiteSettings: true }, +const supportedMenuRoutes: Record = { + 'tenant.dashboard': '/manage', + 'tenant.staff': '/manage/staff', + 'tenant.students': '/manage/students', + 'tenant.question-bank': '/manage/question-bank', + 'tenant.vocabulary': '/manage/vocabulary', + 'tenant.handbook': '/manage/handbook', + 'tenant.video': '/manage/video', + 'tenant.scoreline': '/manage/scoreline', + 'tenant.site-content': '/manage/site/brand', + 'tenant.providers': '/manage/providers', + 'tenant.commerce': '/manage/commerce', + 'tenant.billing': '/manage/billing', }; +export function normalizeTenantBackofficePath(code: string, _path: string | null): string | null { + const registered = supportedMenuRoutes[code]; + if (registered) return registered; + return null; +} + export const backofficeApi = { bootstrap: async (): Promise => { const response = await apiRequest('/api/tenant/access/ui-bootstrap'); @@ -25,14 +41,16 @@ export const backofficeApi = { enabledFeatures: response.enabledFeatures, menus: response.menus .flatMap((item) => { - const route = supportedMenuRoutes[item.code]; - if (!route) return []; - if (route.requiresSiteSettings && !response.permissionCodes.includes('tenant:settings:manage')) return []; + const path = normalizeTenantBackofficePath(item.code, item.path); + if (!path || !Object.hasOwn(supportedMenuRoutes, item.code)) { + if (import.meta.env.DEV) console.warn(`[backoffice] ignored unknown menu code: ${item.code}`); + return []; + } return [{ code: item.code, name: item.title, - path: route.path, - requiredPermission: route.requiresSiteSettings ? 'tenant:settings:manage' : item.permissionCode, + path, + requiredPermission: item.permissionCode, }]; }), }; diff --git a/src/api/client.ts b/src/api/client.ts new file mode 100644 index 0000000..1f7a294 --- /dev/null +++ b/src/api/client.ts @@ -0,0 +1,49 @@ +import createClient, { type Middleware } from "openapi-fetch"; +import type { paths } from "./schema.generated"; +import { ApiError } from "./http"; + +function readCookie(name: string): string | null { + const prefix = `${encodeURIComponent(name)}=`; + const entry = document.cookie + .split(";") + .map((value) => value.trim()) + .find((value) => value.startsWith(prefix)); + return entry ? decodeURIComponent(entry.slice(prefix.length)) : null; +} + +const middleware: Middleware = { + async onRequest({ request }) { + const headers = new Headers(request.headers); + if (import.meta.env.DEV && import.meta.env.VITE_DATA_MODE !== "api") { + headers.set( + "X-Demo-Host", + window.localStorage.getItem("tiku-saas-demo-host") || window.location.hostname, + ); + } + if (!["GET", "HEAD", "OPTIONS"].includes(request.method.toUpperCase())) { + const csrf = readCookie("__Host-tiku-csrf"); + if (csrf) headers.set("X-CSRF-Token", csrf); + } + return new Request(request, { credentials: "include", headers }); + }, +}; + +export const apiClient = createClient({ baseUrl: window.location.origin }); +apiClient.use(middleware); + +type TypedResponse = { data?: T; error?: unknown; response: Response }; + +export async function unwrap(request: Promise>): Promise { + const result = await request; + if (result.data !== undefined) return result.data; + const problem = (result.error ?? {}) as { + code?: string; + title?: string; + detail?: string; + }; + throw new ApiError( + result.response.status, + problem.code ?? `http_${result.response.status}`, + problem.detail ?? problem.title ?? "请求失败,请稍后重试。", + ); +} diff --git a/src/api/futureFeatureClients.ts b/src/api/futureFeatureClients.ts new file mode 100644 index 0000000..41ceced --- /dev/null +++ b/src/api/futureFeatureClients.ts @@ -0,0 +1,30 @@ +/** + * Intentionally contract-only placeholders for legacy capabilities that do not + * have a usable .NET student API. No implementation is exported, so production + * code cannot accidentally report a mock success. + */ +export interface SchoolPlanningClient { + createReport(input: unknown): Promise; + getReport(reportId: string): Promise; +} + +export interface QqOAuthClient { + begin(returnUrl: string): Promise<{ authorizationUrl: string }>; + complete(code: string, state: string): Promise; +} + +export interface StudentActivationCodeClient { + inspect(code: string): Promise; + redeem(code: string): Promise; +} + +export interface CodeRunnerClient { + execute(input: { language: string; source: string; stdin?: string }): Promise; +} + +export interface FutureFeatureClients { + schoolPlanning: SchoolPlanningClient; + qqOAuth: QqOAuthClient; + studentActivationCode: StudentActivationCodeClient; + codeRunner: CodeRunnerClient; +} diff --git a/src/api/index.ts b/src/api/index.ts index ff61b36..8b6b5e8 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -4,3 +4,7 @@ export * from './http'; export * from './onboardingApi'; export * from './runtimeApi'; export * from './siteConfigApi'; +export * from './studentApi'; +export * from './assetApi'; +export type * from './futureFeatureClients'; +export * from './queryClient'; diff --git a/src/api/queryClient.ts b/src/api/queryClient.ts new file mode 100644 index 0000000..b3862a7 --- /dev/null +++ b/src/api/queryClient.ts @@ -0,0 +1,34 @@ +import { QueryClient } from "@tanstack/react-query"; +import { ApiError } from "./http"; + +export const queryKeys = { + profile: ["student", "profile"] as const, + regions: ["catalog", "regions"] as const, + subjects: (regionId?: string | null) => ["catalog", "subjects", regionId ?? "all"] as const, + categories: (subjectId: string) => ["catalog", "categories", subjectId] as const, + blueprints: (regionId?: string | null) => ["catalog", "practice-blueprints", regionId ?? "all"] as const, + dashboard: ["student", "dashboard"] as const, + practice: (sessionId: string) => ["student", "practice", sessionId] as const, + practiceReport: (sessionId: string) => ["student", "practice-report", sessionId] as const, + favorites: ["student", "favorites", "questions"] as const, + wrongQuestions: ["student", "wrong-questions"] as const, + vocabularyUnits: (regionId?: string | null) => ["catalog", "vocabulary-units", regionId ?? "all"] as const, + vocabularyWords: (unitId: string) => ["catalog", "vocabulary-words", unitId] as const, + handbookSubjects: (regionId?: string | null) => ["catalog", "handbook-subjects", regionId ?? "all"] as const, + handbookChapters: (subjectId: string) => ["catalog", "handbook-chapters", subjectId] as const, + handbookEntries: (chapterId: string) => ["catalog", "handbook-entries", chapterId] as const, + scoreline: (regionId?: string | null, keyword = "", year?: number) => ["catalog", "scoreline", regionId ?? "all", keyword, year ?? "all"] as const, + asset: (assetId: string) => ["assets", "preview", assetId] as const, +}; + +export const queryClient = new QueryClient({ + defaultOptions: { + queries: { + staleTime: 30_000, + retry: (failureCount, error) => + !(error instanceof ApiError && error.status < 500) && failureCount < 2, + refetchOnWindowFocus: false, + }, + mutations: { retry: false }, + }, +}); diff --git a/src/api/schema.generated.d.ts b/src/api/schema.generated.d.ts new file mode 100644 index 0000000..dc8401d --- /dev/null +++ b/src/api/schema.generated.d.ts @@ -0,0 +1,30780 @@ +/** + * This file was auto-generated by openapi-typescript. + * Do not make direct changes to the file. + */ + +export interface paths { + "/api/tenant/commerce/code-batches": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 创建兑换码批次 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["CreateCodeBatchDto"]; + "text/json": components["schemas"]["CreateCodeBatchDto"]; + "application/*+json": components["schemas"]["CreateCodeBatchDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CodeBatchItem"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/commerce/activation-codes": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询兑换码 */ + get: { + parameters: { + query?: { + /** @description 服务提供方。 */ + Provider?: string; + /** @description 状态。 */ + Status?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + /** @description 用户 ID。 */ + UserId?: string; + /** @description 地区 ID。 */ + RegionId?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ActivationCodeList"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/commerce/activation-codes/redeem": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 后台核销兑换码 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["RedeemActivationCodeDto"]; + "text/json": components["schemas"]["RedeemActivationCodeDto"]; + "application/*+json": components["schemas"]["RedeemActivationCodeDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ActivationCodeItem"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/student/learning/answers": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 提交题目答案 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["SubmitAnswerDto"]; + "text/json": components["schemas"]["SubmitAnswerDto"]; + "application/*+json": components["schemas"]["SubmitAnswerDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["AnswerRecordItem"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + /** @description Forbidden */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/student/assets/{assetId}/download": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 获取资源下载地址 */ + get: { + parameters: { + query?: { + /** @description 租户编码。 */ + TenantCode?: string; + /** @description 有效期秒数。 */ + ExpiresInSeconds?: number | string; + }; + header?: never; + path: { + assetId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["AssetAccessResponseDto"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + /** @description Forbidden */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + /** @description Conflict */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + /** @description Service Unavailable */ + 503: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/student/assets/{assetId}/preview": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 获取资源预览地址 */ + get: { + parameters: { + query?: { + /** @description 租户编码。 */ + TenantCode?: string; + /** @description 有效期秒数。 */ + ExpiresInSeconds?: number | string; + }; + header?: never; + path: { + assetId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["AssetAccessResponseDto"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + /** @description Forbidden */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + /** @description Conflict */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + /** @description Service Unavailable */ + 503: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/auth/activation/complete": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * 完成租户负责人一次性激活 + * @description 使用平台开通时签发的一次性令牌设置初始密码;令牌仅可消费一次。 + */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["CompleteOwnerActivationDto"]; + "text/json": components["schemas"]["CompleteOwnerActivationDto"]; + "application/*+json": components["schemas"]["CompleteOwnerActivationDto"]; + }; + }; + responses: { + /** @description No Content */ + 204: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": unknown; + }; + }; + /** @description Bad Request */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + /** @description Conflict */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/auth/activation/complete": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * 完成租户负责人一次性激活 + * @description 使用平台开通时签发的一次性令牌设置初始密码;令牌仅可消费一次。 + */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["CompleteOwnerActivationDto"]; + "text/json": components["schemas"]["CompleteOwnerActivationDto"]; + "application/*+json": components["schemas"]["CompleteOwnerActivationDto"]; + }; + }; + responses: { + /** @description No Content */ + 204: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": unknown; + }; + }; + /** @description Bad Request */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + /** @description Conflict */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/student/auth/activation/complete": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * 完成租户负责人一次性激活 + * @description 使用平台开通时签发的一次性令牌设置初始密码;令牌仅可消费一次。 + */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["CompleteOwnerActivationDto"]; + "text/json": components["schemas"]["CompleteOwnerActivationDto"]; + "application/*+json": components["schemas"]["CompleteOwnerActivationDto"]; + }; + }; + responses: { + /** @description No Content */ + 204: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": unknown; + }; + }; + /** @description Bad Request */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + /** @description Conflict */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/auth/sms/send": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * 发送短信验证码 + * @description 发送登录用途短信验证码,并应用租户级短信限流。 + */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["SendSmsCodeDto"]; + "text/json": components["schemas"]["SendSmsCodeDto"]; + "application/*+json": components["schemas"]["SendSmsCodeDto"]; + }; + }; + responses: { + /** @description Accepted */ + 202: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["SmsSendResult"]; + }; + }; + /** @description Bad Request */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + /** @description Too Many Requests */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/auth/sms/send": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * 发送短信验证码 + * @description 发送登录用途短信验证码,并应用租户级短信限流。 + */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["SendSmsCodeDto"]; + "text/json": components["schemas"]["SendSmsCodeDto"]; + "application/*+json": components["schemas"]["SendSmsCodeDto"]; + }; + }; + responses: { + /** @description Accepted */ + 202: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["SmsSendResult"]; + }; + }; + /** @description Bad Request */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + /** @description Too Many Requests */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/student/auth/sms/send": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * 发送短信验证码 + * @description 发送登录用途短信验证码,并应用租户级短信限流。 + */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["SendSmsCodeDto"]; + "text/json": components["schemas"]["SendSmsCodeDto"]; + "application/*+json": components["schemas"]["SendSmsCodeDto"]; + }; + }; + responses: { + /** @description Accepted */ + 202: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["SmsSendResult"]; + }; + }; + /** @description Bad Request */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + /** @description Too Many Requests */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/auth/login/password": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * 手机号密码登录 + * @description 使用本地手机号和密码登录,签发 JWT access token 与数据库 refresh/session。 + */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["PasswordLoginDto"]; + "text/json": components["schemas"]["PasswordLoginDto"]; + "application/*+json": components["schemas"]["PasswordLoginDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["AuthenticationResultDto"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/auth/login/password": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * 手机号密码登录 + * @description 使用本地手机号和密码登录,签发 JWT access token 与数据库 refresh/session。 + */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["PasswordLoginDto"]; + "text/json": components["schemas"]["PasswordLoginDto"]; + "application/*+json": components["schemas"]["PasswordLoginDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["AuthenticationResultDto"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/student/auth/login/password": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * 手机号密码登录 + * @description 使用本地手机号和密码登录,签发 JWT access token 与数据库 refresh/session。 + */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["PasswordLoginDto"]; + "text/json": components["schemas"]["PasswordLoginDto"]; + "application/*+json": components["schemas"]["PasswordLoginDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["AuthenticationResultDto"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/auth/login/sms": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * 短信验证码登录 + * @description 校验已发送的登录用途短信验证码,成功后签发 JWT access token 与数据库 refresh/session。 + */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["SmsLoginDto"]; + "text/json": components["schemas"]["SmsLoginDto"]; + "application/*+json": components["schemas"]["SmsLoginDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["AuthenticationResultDto"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/auth/login/sms": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * 短信验证码登录 + * @description 校验已发送的登录用途短信验证码,成功后签发 JWT access token 与数据库 refresh/session。 + */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["SmsLoginDto"]; + "text/json": components["schemas"]["SmsLoginDto"]; + "application/*+json": components["schemas"]["SmsLoginDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["AuthenticationResultDto"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/student/auth/login/sms": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * 短信验证码登录 + * @description 校验已发送的登录用途短信验证码,成功后签发 JWT access token 与数据库 refresh/session。 + */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["SmsLoginDto"]; + "text/json": components["schemas"]["SmsLoginDto"]; + "application/*+json": components["schemas"]["SmsLoginDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["AuthenticationResultDto"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/auth/oauth/wechat": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * 微信网页 OAuth 登录 + * @description 使用微信网页授权 code 换取 openid/unionid,upsert 用户身份并创建应用会话。 + */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["OAuthCodeDto"]; + "text/json": components["schemas"]["OAuthCodeDto"]; + "application/*+json": components["schemas"]["OAuthCodeDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["AuthenticationResultDto"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + /** @description Service Unavailable */ + 503: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/auth/oauth/wechat": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * 微信网页 OAuth 登录 + * @description 使用微信网页授权 code 换取 openid/unionid,upsert 用户身份并创建应用会话。 + */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["OAuthCodeDto"]; + "text/json": components["schemas"]["OAuthCodeDto"]; + "application/*+json": components["schemas"]["OAuthCodeDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["AuthenticationResultDto"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + /** @description Service Unavailable */ + 503: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/student/auth/oauth/wechat": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * 微信网页 OAuth 登录 + * @description 使用微信网页授权 code 换取 openid/unionid,upsert 用户身份并创建应用会话。 + */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["OAuthCodeDto"]; + "text/json": components["schemas"]["OAuthCodeDto"]; + "application/*+json": components["schemas"]["OAuthCodeDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["AuthenticationResultDto"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + /** @description Service Unavailable */ + 503: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/auth/oauth/wechat-miniapp": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * 微信小程序登录 + * @description 使用小程序 wx.login 返回的 code 换取 openid/session_key,upsert 用户身份并创建应用会话。 + */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["OAuthCodeDto"]; + "text/json": components["schemas"]["OAuthCodeDto"]; + "application/*+json": components["schemas"]["OAuthCodeDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["AuthenticationResultDto"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + /** @description Service Unavailable */ + 503: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/auth/oauth/wechat-miniapp": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * 微信小程序登录 + * @description 使用小程序 wx.login 返回的 code 换取 openid/session_key,upsert 用户身份并创建应用会话。 + */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["OAuthCodeDto"]; + "text/json": components["schemas"]["OAuthCodeDto"]; + "application/*+json": components["schemas"]["OAuthCodeDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["AuthenticationResultDto"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + /** @description Service Unavailable */ + 503: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/student/auth/oauth/wechat-miniapp": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * 微信小程序登录 + * @description 使用小程序 wx.login 返回的 code 换取 openid/session_key,upsert 用户身份并创建应用会话。 + */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["OAuthCodeDto"]; + "text/json": components["schemas"]["OAuthCodeDto"]; + "application/*+json": components["schemas"]["OAuthCodeDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["AuthenticationResultDto"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + /** @description Service Unavailable */ + 503: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/auth/refresh": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * 刷新登录会话 + * @description 使用 refresh token 轮换数据库 session,并签发新的 access/refresh token。 + */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["RefreshSessionDto"]; + "text/json": components["schemas"]["RefreshSessionDto"]; + "application/*+json": components["schemas"]["RefreshSessionDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["AuthTokenPair"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/auth/refresh": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * 刷新登录会话 + * @description 使用 refresh token 轮换数据库 session,并签发新的 access/refresh token。 + */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["RefreshSessionDto"]; + "text/json": components["schemas"]["RefreshSessionDto"]; + "application/*+json": components["schemas"]["RefreshSessionDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["AuthTokenPair"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/student/auth/refresh": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * 刷新登录会话 + * @description 使用 refresh token 轮换数据库 session,并签发新的 access/refresh token。 + */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["RefreshSessionDto"]; + "text/json": components["schemas"]["RefreshSessionDto"]; + "application/*+json": components["schemas"]["RefreshSessionDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["AuthTokenPair"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/auth/logout": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * 退出登录 + * @description 撤销 refresh token 对应的数据库 session;session 校验开启时,旧 access token 也会被拒绝。 + */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["RefreshSessionDto"]; + "text/json": components["schemas"]["RefreshSessionDto"]; + "application/*+json": components["schemas"]["RefreshSessionDto"]; + }; + }; + responses: { + /** @description No Content */ + 204: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": unknown; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/auth/logout": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * 退出登录 + * @description 撤销 refresh token 对应的数据库 session;session 校验开启时,旧 access token 也会被拒绝。 + */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["RefreshSessionDto"]; + "text/json": components["schemas"]["RefreshSessionDto"]; + "application/*+json": components["schemas"]["RefreshSessionDto"]; + }; + }; + responses: { + /** @description No Content */ + 204: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": unknown; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/student/auth/logout": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * 退出登录 + * @description 撤销 refresh token 对应的数据库 session;session 校验开启时,旧 access token 也会被拒绝。 + */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["RefreshSessionDto"]; + "text/json": components["schemas"]["RefreshSessionDto"]; + "application/*+json": components["schemas"]["RefreshSessionDto"]; + }; + }; + responses: { + /** @description No Content */ + 204: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": unknown; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/auth/logout-all": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * 退出全部登录会话 + * @description 撤销当前用户全部 refresh/session,会话校验开启时旧 access token 也会被拒绝。 + */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description No Content */ + 204: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": unknown; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/auth/logout-all": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * 退出全部登录会话 + * @description 撤销当前用户全部 refresh/session,会话校验开启时旧 access token 也会被拒绝。 + */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description No Content */ + 204: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": unknown; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/student/auth/logout-all": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * 退出全部登录会话 + * @description 撤销当前用户全部 refresh/session,会话校验开启时旧 access token 也会被拒绝。 + */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description No Content */ + 204: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": unknown; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/auth/password/change-required": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * 修改首次登录必改密码 + * @description 校验密码变更挑战令牌并设置新密码,成功后签发新的登录会话。 + */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["RequiredPasswordChangeDto"]; + "text/json": components["schemas"]["RequiredPasswordChangeDto"]; + "application/*+json": components["schemas"]["RequiredPasswordChangeDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["AuthenticationResultDto"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/auth/password/change-required": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * 修改首次登录必改密码 + * @description 校验密码变更挑战令牌并设置新密码,成功后签发新的登录会话。 + */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["RequiredPasswordChangeDto"]; + "text/json": components["schemas"]["RequiredPasswordChangeDto"]; + "application/*+json": components["schemas"]["RequiredPasswordChangeDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["AuthenticationResultDto"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/student/auth/password/change-required": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * 修改首次登录必改密码 + * @description 校验密码变更挑战令牌并设置新密码,成功后签发新的登录会话。 + */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["RequiredPasswordChangeDto"]; + "text/json": components["schemas"]["RequiredPasswordChangeDto"]; + "application/*+json": components["schemas"]["RequiredPasswordChangeDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["AuthenticationResultDto"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/auth/password/reset/sms/send": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * 发送密码重置短信验证码 + * @description 仅适用于租户授权域;无论手机号是否存在均返回相同接受响应。 + */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["PasswordResetSmsSendDto"]; + "text/json": components["schemas"]["PasswordResetSmsSendDto"]; + "application/*+json": components["schemas"]["PasswordResetSmsSendDto"]; + }; + }; + responses: { + /** @description Accepted */ + 202: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["SmsSendResult"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/auth/password/reset/sms/send": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * 发送密码重置短信验证码 + * @description 仅适用于租户授权域;无论手机号是否存在均返回相同接受响应。 + */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["PasswordResetSmsSendDto"]; + "text/json": components["schemas"]["PasswordResetSmsSendDto"]; + "application/*+json": components["schemas"]["PasswordResetSmsSendDto"]; + }; + }; + responses: { + /** @description Accepted */ + 202: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["SmsSendResult"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/student/auth/password/reset/sms/send": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * 发送密码重置短信验证码 + * @description 仅适用于租户授权域;无论手机号是否存在均返回相同接受响应。 + */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["PasswordResetSmsSendDto"]; + "text/json": components["schemas"]["PasswordResetSmsSendDto"]; + "application/*+json": components["schemas"]["PasswordResetSmsSendDto"]; + }; + }; + responses: { + /** @description Accepted */ + 202: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["SmsSendResult"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/auth/password/reset": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 使用短信验证码重置密码 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["PasswordResetDto"]; + "text/json": components["schemas"]["PasswordResetDto"]; + "application/*+json": components["schemas"]["PasswordResetDto"]; + }; + }; + responses: { + /** @description No Content */ + 204: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": unknown; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/auth/password/reset": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 使用短信验证码重置密码 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["PasswordResetDto"]; + "text/json": components["schemas"]["PasswordResetDto"]; + "application/*+json": components["schemas"]["PasswordResetDto"]; + }; + }; + responses: { + /** @description No Content */ + 204: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": unknown; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/student/auth/password/reset": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 使用短信验证码重置密码 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["PasswordResetDto"]; + "text/json": components["schemas"]["PasswordResetDto"]; + "application/*+json": components["schemas"]["PasswordResetDto"]; + }; + }; + responses: { + /** @description No Content */ + 204: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": unknown; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/auth/password/change": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * 已登录用户修改密码 + * @description 修改成功后撤销旧会话并返回新的令牌对。 + */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["AuthenticatedPasswordChangeDto"]; + "text/json": components["schemas"]["AuthenticatedPasswordChangeDto"]; + "application/*+json": components["schemas"]["AuthenticatedPasswordChangeDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["AuthenticationResultDto"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/auth/password/change": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * 已登录用户修改密码 + * @description 修改成功后撤销旧会话并返回新的令牌对。 + */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["AuthenticatedPasswordChangeDto"]; + "text/json": components["schemas"]["AuthenticatedPasswordChangeDto"]; + "application/*+json": components["schemas"]["AuthenticatedPasswordChangeDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["AuthenticationResultDto"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/student/auth/password/change": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * 已登录用户修改密码 + * @description 修改成功后撤销旧会话并返回新的令牌对。 + */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["AuthenticatedPasswordChangeDto"]; + "text/json": components["schemas"]["AuthenticatedPasswordChangeDto"]; + "application/*+json": components["schemas"]["AuthenticatedPasswordChangeDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["AuthenticationResultDto"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/access/jobs": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询租户后台任务 */ + get: { + parameters: { + query?: { + jobType?: string; + limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["BackgroundJobItem"][]; + "application/json": components["schemas"]["BackgroundJobItem"][]; + "text/json": components["schemas"]["BackgroundJobItem"][]; + }; + }; + }; + }; + put?: never; + /** 创建租户后台任务 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["CreateBackgroundJobDto"]; + "text/json": components["schemas"]["CreateBackgroundJobDto"]; + "application/*+json": components["schemas"]["CreateBackgroundJobDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["BackgroundJobItem"]; + "application/json": components["schemas"]["BackgroundJobItem"]; + "text/json": components["schemas"]["BackgroundJobItem"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/access/jobs/{jobId}": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询租户后台任务详情 */ + get: { + parameters: { + query?: never; + header?: never; + path: { + jobId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["BackgroundJobItem"]; + "application/json": components["schemas"]["BackgroundJobItem"]; + "text/json": components["schemas"]["BackgroundJobItem"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/access/jobs/{jobId}/cancel": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 取消租户后台任务 */ + post: { + parameters: { + query?: never; + header?: never; + path: { + jobId: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["CancelBackgroundJobDto"]; + "text/json": components["schemas"]["CancelBackgroundJobDto"]; + "application/*+json": components["schemas"]["CancelBackgroundJobDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["BackgroundJobItem"]; + "application/json": components["schemas"]["BackgroundJobItem"]; + "text/json": components["schemas"]["BackgroundJobItem"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/access/jobs/{jobId}/retry": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 重试失败或已取消的租户后台任务 */ + post: { + parameters: { + query?: never; + header?: never; + path: { + jobId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["BackgroundJobItem"]; + "application/json": components["schemas"]["BackgroundJobItem"]; + "text/json": components["schemas"]["BackgroundJobItem"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/auth/browser/activation/complete": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 完成租户 Owner 激活并建立浏览器会话 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["CompleteOwnerActivationDto"]; + "text/json": components["schemas"]["CompleteOwnerActivationDto"]; + "application/*+json": components["schemas"]["CompleteOwnerActivationDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": unknown; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/auth/browser/sms/send": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 发送浏览器短信验证码 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["SendSmsCodeDto"]; + "text/json": components["schemas"]["SendSmsCodeDto"]; + "application/*+json": components["schemas"]["SendSmsCodeDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["SmsSendResult"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/auth/browser/login/password": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 浏览器手机号密码登录 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["PasswordLoginDto"]; + "text/json": components["schemas"]["PasswordLoginDto"]; + "application/*+json": components["schemas"]["PasswordLoginDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": unknown; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/auth/browser/login/sms": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 浏览器短信验证码登录 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["SmsLoginDto"]; + "text/json": components["schemas"]["SmsLoginDto"]; + "application/*+json": components["schemas"]["SmsLoginDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": unknown; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/auth/browser/oauth/wechat": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 浏览器微信网页 OAuth 登录 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["OAuthCodeDto"]; + "text/json": components["schemas"]["OAuthCodeDto"]; + "application/*+json": components["schemas"]["OAuthCodeDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": unknown; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/auth/browser/oauth/wechat-miniapp": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 浏览器微信小程序登录 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["OAuthCodeDto"]; + "text/json": components["schemas"]["OAuthCodeDto"]; + "application/*+json": components["schemas"]["OAuthCodeDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": unknown; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/auth/browser/refresh": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * 刷新浏览器登录会话 + * @description 读取浏览器 refresh cookie,轮换会话并重新写入认证 cookie。 + */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": unknown; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/auth/browser/logout": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * 退出浏览器登录 + * @description 撤销浏览器 refresh cookie 对应会话,并清理 access、refresh 与 CSRF cookie。 + */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": unknown; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/auth/browser/logout-all": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 退出全部浏览器登录会话 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": unknown; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/auth/browser/password/reset/sms/send": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 发送浏览器密码重置短信验证码 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["PasswordResetSmsSendDto"]; + "text/json": components["schemas"]["PasswordResetSmsSendDto"]; + "application/*+json": components["schemas"]["PasswordResetSmsSendDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["SmsSendResult"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/auth/browser/password/reset": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 使用短信验证码重置浏览器账号密码 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["PasswordResetDto"]; + "text/json": components["schemas"]["PasswordResetDto"]; + "application/*+json": components["schemas"]["PasswordResetDto"]; + }; + }; + responses: { + /** @description No Content */ + 204: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": unknown; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/auth/browser/password/change": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 浏览器已登录用户修改密码 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["AuthenticatedPasswordChangeDto"]; + "text/json": components["schemas"]["AuthenticatedPasswordChangeDto"]; + "application/*+json": components["schemas"]["AuthenticatedPasswordChangeDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": unknown; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/public/catalog/regions": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询可用地区 */ + get: { + parameters: { + query?: { + /** @description 租户编码。 */ + TenantCode?: string; + /** @description 地区 ID。 */ + RegionId?: string; + /** @description ModuleId。 */ + ModuleId?: string; + /** @description 父节点 ID;传 root 表示根节点。 */ + ParentId?: string; + /** @description 院校 ID。 */ + SchoolId?: string; + /** @description 专业 ID。 */ + MajorId?: string; + /** @description 科目 ID。 */ + SubjectId?: string; + /** @description 节点 ID。 */ + NodeId?: string; + /** @description 关键字。 */ + Keyword?: string; + /** @description 类型。 */ + Type?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfRegionCatalogItem"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/public/catalog/region-modules": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询地区功能模块 */ + get: { + parameters: { + query?: { + /** @description 租户编码。 */ + TenantCode?: string; + /** @description 地区 ID。 */ + RegionId?: string; + /** @description ModuleId。 */ + ModuleId?: string; + /** @description 父节点 ID;传 root 表示根节点。 */ + ParentId?: string; + /** @description 院校 ID。 */ + SchoolId?: string; + /** @description 专业 ID。 */ + MajorId?: string; + /** @description 科目 ID。 */ + SubjectId?: string; + /** @description 节点 ID。 */ + NodeId?: string; + /** @description 关键字。 */ + Keyword?: string; + /** @description 类型。 */ + Type?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfRegionModuleCatalogItem"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/public/catalog/module-nodes": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询模块导航节点 */ + get: { + parameters: { + query?: { + /** @description 租户编码。 */ + TenantCode?: string; + /** @description 地区 ID。 */ + RegionId?: string; + /** @description ModuleId。 */ + ModuleId?: string; + /** @description 父节点 ID;传 root 表示根节点。 */ + ParentId?: string; + /** @description 院校 ID。 */ + SchoolId?: string; + /** @description 专业 ID。 */ + MajorId?: string; + /** @description 科目 ID。 */ + SubjectId?: string; + /** @description 节点 ID。 */ + NodeId?: string; + /** @description 关键字。 */ + Keyword?: string; + /** @description 类型。 */ + Type?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfModuleNodeCatalogItem"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/public/catalog/schools": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询院校目录 */ + get: { + parameters: { + query?: { + /** @description 租户编码。 */ + TenantCode?: string; + /** @description 地区 ID。 */ + RegionId?: string; + /** @description ModuleId。 */ + ModuleId?: string; + /** @description 父节点 ID;传 root 表示根节点。 */ + ParentId?: string; + /** @description 院校 ID。 */ + SchoolId?: string; + /** @description 专业 ID。 */ + MajorId?: string; + /** @description 科目 ID。 */ + SubjectId?: string; + /** @description 节点 ID。 */ + NodeId?: string; + /** @description 关键字。 */ + Keyword?: string; + /** @description 类型。 */ + Type?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfSchoolCatalogItem"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/public/catalog/majors": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询专业目录 */ + get: { + parameters: { + query?: { + /** @description 租户编码。 */ + TenantCode?: string; + /** @description 地区 ID。 */ + RegionId?: string; + /** @description ModuleId。 */ + ModuleId?: string; + /** @description 父节点 ID;传 root 表示根节点。 */ + ParentId?: string; + /** @description 院校 ID。 */ + SchoolId?: string; + /** @description 专业 ID。 */ + MajorId?: string; + /** @description 科目 ID。 */ + SubjectId?: string; + /** @description 节点 ID。 */ + NodeId?: string; + /** @description 关键字。 */ + Keyword?: string; + /** @description 类型。 */ + Type?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfMajorCatalogItem"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/public/catalog/subjects": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询科目目录 */ + get: { + parameters: { + query?: { + /** @description 租户编码。 */ + TenantCode?: string; + /** @description 地区 ID。 */ + RegionId?: string; + /** @description ModuleId。 */ + ModuleId?: string; + /** @description 父节点 ID;传 root 表示根节点。 */ + ParentId?: string; + /** @description 院校 ID。 */ + SchoolId?: string; + /** @description 专业 ID。 */ + MajorId?: string; + /** @description 科目 ID。 */ + SubjectId?: string; + /** @description 节点 ID。 */ + NodeId?: string; + /** @description 关键字。 */ + Keyword?: string; + /** @description 类型。 */ + Type?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfSubjectCatalogItem"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/public/catalog/categories": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询题目分类 */ + get: { + parameters: { + query?: { + /** @description 租户编码。 */ + TenantCode?: string; + /** @description 地区 ID。 */ + RegionId?: string; + /** @description ModuleId。 */ + ModuleId?: string; + /** @description 父节点 ID;传 root 表示根节点。 */ + ParentId?: string; + /** @description 院校 ID。 */ + SchoolId?: string; + /** @description 专业 ID。 */ + MajorId?: string; + /** @description 科目 ID。 */ + SubjectId?: string; + /** @description 节点 ID。 */ + NodeId?: string; + /** @description 关键字。 */ + Keyword?: string; + /** @description 类型。 */ + Type?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfCategoryCatalogItem"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/public/catalog/question-categories": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询题目分类 */ + get: { + parameters: { + query?: { + /** @description 租户编码。 */ + TenantCode?: string; + /** @description 地区 ID。 */ + RegionId?: string; + /** @description ModuleId。 */ + ModuleId?: string; + /** @description 父节点 ID;传 root 表示根节点。 */ + ParentId?: string; + /** @description 院校 ID。 */ + SchoolId?: string; + /** @description 专业 ID。 */ + MajorId?: string; + /** @description 科目 ID。 */ + SubjectId?: string; + /** @description 节点 ID。 */ + NodeId?: string; + /** @description 关键字。 */ + Keyword?: string; + /** @description 类型。 */ + Type?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfCategoryCatalogItem"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/public/catalog/content-entries": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询内容入口 */ + get: { + parameters: { + query?: { + /** @description 租户编码。 */ + TenantCode?: string; + /** @description 地区 ID。 */ + RegionId?: string; + /** @description 内容入口 ID。 */ + EntryId?: string; + /** @description 节点 ID。 */ + NodeId?: string; + /** @description 题集 ID。 */ + CollectionId?: string; + /** @description 父节点 ID;传 root 表示根节点。 */ + ParentId?: string; + /** @description 入口类型。 */ + EntryType?: string; + /** @description 题集类型。 */ + CollectionType?: string; + /** @description 模式。 */ + Mode?: string; + /** @description 标记类型。 */ + MarkerType?: string; + /** @description 关键字。 */ + Keyword?: string; + /** @description 是否包含隐藏数据。 */ + IncludeHidden?: boolean; + /** @description 是否包含停用数据。 */ + IncludeInactive?: boolean; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfContentEntryCatalogItem"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/public/catalog/content-nodes": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询内容导航节点 */ + get: { + parameters: { + query?: { + /** @description 租户编码。 */ + TenantCode?: string; + /** @description 地区 ID。 */ + RegionId?: string; + /** @description 内容入口 ID。 */ + EntryId?: string; + /** @description 节点 ID。 */ + NodeId?: string; + /** @description 题集 ID。 */ + CollectionId?: string; + /** @description 父节点 ID;传 root 表示根节点。 */ + ParentId?: string; + /** @description 入口类型。 */ + EntryType?: string; + /** @description 题集类型。 */ + CollectionType?: string; + /** @description 模式。 */ + Mode?: string; + /** @description 标记类型。 */ + MarkerType?: string; + /** @description 关键字。 */ + Keyword?: string; + /** @description 是否包含隐藏数据。 */ + IncludeHidden?: boolean; + /** @description 是否包含停用数据。 */ + IncludeInactive?: boolean; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfContentNodeCatalogItem"]; + }; + }; + /** @description Bad Request */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/public/catalog/question-collections": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询可用题集 */ + get: { + parameters: { + query?: { + /** @description 租户编码。 */ + TenantCode?: string; + /** @description 地区 ID。 */ + RegionId?: string; + /** @description 内容入口 ID。 */ + EntryId?: string; + /** @description 节点 ID。 */ + NodeId?: string; + /** @description 题集 ID。 */ + CollectionId?: string; + /** @description 父节点 ID;传 root 表示根节点。 */ + ParentId?: string; + /** @description 入口类型。 */ + EntryType?: string; + /** @description 题集类型。 */ + CollectionType?: string; + /** @description 模式。 */ + Mode?: string; + /** @description 标记类型。 */ + MarkerType?: string; + /** @description 关键字。 */ + Keyword?: string; + /** @description 是否包含隐藏数据。 */ + IncludeHidden?: boolean; + /** @description 是否包含停用数据。 */ + IncludeInactive?: boolean; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfQuestionCollectionCatalogItem"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/public/catalog/question-collections/questions": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询题集内题目 */ + get: { + parameters: { + query?: { + /** @description 租户编码。 */ + TenantCode?: string; + /** @description 地区 ID。 */ + RegionId?: string; + /** @description 内容入口 ID。 */ + EntryId?: string; + /** @description 节点 ID。 */ + NodeId?: string; + /** @description 题集 ID。 */ + CollectionId?: string; + /** @description 父节点 ID;传 root 表示根节点。 */ + ParentId?: string; + /** @description 入口类型。 */ + EntryType?: string; + /** @description 题集类型。 */ + CollectionType?: string; + /** @description 模式。 */ + Mode?: string; + /** @description 标记类型。 */ + MarkerType?: string; + /** @description 关键字。 */ + Keyword?: string; + /** @description 是否包含隐藏数据。 */ + IncludeHidden?: boolean; + /** @description 是否包含停用数据。 */ + IncludeInactive?: boolean; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfCollectionQuestionCatalogItem"]; + }; + }; + /** @description Bad Request */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/public/catalog/practice-blueprints": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询练习蓝图 */ + get: { + parameters: { + query?: { + /** @description 租户编码。 */ + TenantCode?: string; + /** @description 地区 ID。 */ + RegionId?: string; + /** @description 内容入口 ID。 */ + EntryId?: string; + /** @description 节点 ID。 */ + NodeId?: string; + /** @description 题集 ID。 */ + CollectionId?: string; + /** @description 父节点 ID;传 root 表示根节点。 */ + ParentId?: string; + /** @description 入口类型。 */ + EntryType?: string; + /** @description 题集类型。 */ + CollectionType?: string; + /** @description 模式。 */ + Mode?: string; + /** @description 标记类型。 */ + MarkerType?: string; + /** @description 关键字。 */ + Keyword?: string; + /** @description 是否包含隐藏数据。 */ + IncludeHidden?: boolean; + /** @description 是否包含停用数据。 */ + IncludeInactive?: boolean; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfPracticeBlueprintCatalogItem"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/public/catalog/question-banks": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询题库列表 */ + get: { + parameters: { + query?: { + /** @description 租户编码。 */ + TenantCode?: string; + /** @description 地区 ID。 */ + RegionId?: string; + /** @description 题库 ID。 */ + QuestionBankId?: string; + /** @description 科目 ID。 */ + SubjectId?: string; + /** @description 分类 ID。 */ + CategoryId?: string; + /** @description 节点 ID。 */ + NodeId?: string; + /** @description 内容入口 ID。 */ + EntryId?: string; + /** @description 内容节点 ID。 */ + ContentNodeId?: string; + /** @description 题集 ID。 */ + CollectionId?: string; + /** @description 来源。 */ + Source?: components["schemas"]["QuestionSource"]; + /** @description 类型。 */ + Type?: string; + /** @description 关键字。 */ + Keyword?: string; + /** @description 题目 ID 列表。 */ + QuestionIds?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfQuestionBankCatalogItem"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/public/catalog/questions": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * 查询已发布题目 + * @description 支持按题库、科目、分类、模块节点、内容入口、内容节点、题集或题目 ID 列表筛选。 + */ + get: { + parameters: { + query?: { + /** @description 租户编码。 */ + TenantCode?: string; + /** @description 地区 ID。 */ + RegionId?: string; + /** @description 题库 ID。 */ + QuestionBankId?: string; + /** @description 科目 ID。 */ + SubjectId?: string; + /** @description 分类 ID。 */ + CategoryId?: string; + /** @description 节点 ID。 */ + NodeId?: string; + /** @description 内容入口 ID。 */ + EntryId?: string; + /** @description 内容节点 ID。 */ + ContentNodeId?: string; + /** @description 题集 ID。 */ + CollectionId?: string; + /** @description 来源。 */ + Source?: components["schemas"]["QuestionSource"]; + /** @description 类型。 */ + Type?: string; + /** @description 关键字。 */ + Keyword?: string; + /** @description 题目 ID 列表。 */ + QuestionIds?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfQuestionCatalogItem"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/public/catalog/questions/{questionId}": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询题目详情 */ + get: { + parameters: { + query?: { + /** @description 租户编码。 */ + TenantCode?: string; + /** @description 地区 ID。 */ + RegionId?: string; + /** @description 题库 ID。 */ + QuestionBankId?: string; + /** @description 科目 ID。 */ + SubjectId?: string; + /** @description 分类 ID。 */ + CategoryId?: string; + /** @description 节点 ID。 */ + NodeId?: string; + /** @description 内容入口 ID。 */ + EntryId?: string; + /** @description 内容节点 ID。 */ + ContentNodeId?: string; + /** @description 题集 ID。 */ + CollectionId?: string; + /** @description 来源。 */ + Source?: components["schemas"]["QuestionSource"]; + /** @description 类型。 */ + Type?: string; + /** @description 关键字。 */ + Keyword?: string; + /** @description 题目 ID 列表。 */ + QuestionIds?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path: { + questionId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["QuestionCatalogItem"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/public/catalog/questions/{questionId}/versions": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询题目版本 */ + get: { + parameters: { + query?: { + /** @description 租户编码。 */ + TenantCode?: string; + /** @description 地区 ID。 */ + RegionId?: string; + /** @description 题库 ID。 */ + QuestionBankId?: string; + /** @description 科目 ID。 */ + SubjectId?: string; + /** @description 分类 ID。 */ + CategoryId?: string; + /** @description 节点 ID。 */ + NodeId?: string; + /** @description 内容入口 ID。 */ + EntryId?: string; + /** @description 内容节点 ID。 */ + ContentNodeId?: string; + /** @description 题集 ID。 */ + CollectionId?: string; + /** @description 来源。 */ + Source?: components["schemas"]["QuestionSource"]; + /** @description 类型。 */ + Type?: string; + /** @description 关键字。 */ + Keyword?: string; + /** @description 题目 ID 列表。 */ + QuestionIds?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path: { + questionId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfQuestionVersionCatalogItem"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/public/catalog/vocabulary-units": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询词汇单元 */ + get: { + parameters: { + query?: { + /** @description 租户编码。 */ + TenantCode?: string; + /** @description 地区 ID。 */ + RegionId?: string; + /** @description 单元 ID。 */ + UnitId?: string; + /** @description 科目 ID。 */ + SubjectId?: string; + /** @description 章节 ID。 */ + ChapterId?: string; + /** @description 内容入口 ID。 */ + EntryId?: string; + /** @description 内容节点 ID。 */ + ContentNodeId?: string; + /** @description 关键字。 */ + Keyword?: string; + /** @description 是否包含正文内容。 */ + IncludeContent?: boolean; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfVocabularyUnitCatalogItem"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/public/catalog/vocabulary-words": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询词汇单词 */ + get: { + parameters: { + query?: { + /** @description 租户编码。 */ + TenantCode?: string; + /** @description 地区 ID。 */ + RegionId?: string; + /** @description 单元 ID。 */ + UnitId?: string; + /** @description 科目 ID。 */ + SubjectId?: string; + /** @description 章节 ID。 */ + ChapterId?: string; + /** @description 内容入口 ID。 */ + EntryId?: string; + /** @description 内容节点 ID。 */ + ContentNodeId?: string; + /** @description 关键字。 */ + Keyword?: string; + /** @description 是否包含正文内容。 */ + IncludeContent?: boolean; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfVocabularyWordCatalogItem"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/public/catalog/handbook-subjects": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询知识手册科目 */ + get: { + parameters: { + query?: { + /** @description 租户编码。 */ + TenantCode?: string; + /** @description 地区 ID。 */ + RegionId?: string; + /** @description 单元 ID。 */ + UnitId?: string; + /** @description 科目 ID。 */ + SubjectId?: string; + /** @description 章节 ID。 */ + ChapterId?: string; + /** @description 内容入口 ID。 */ + EntryId?: string; + /** @description 内容节点 ID。 */ + ContentNodeId?: string; + /** @description 关键字。 */ + Keyword?: string; + /** @description 是否包含正文内容。 */ + IncludeContent?: boolean; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfHandbookSubjectCatalogItem"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/public/catalog/handbook-chapters": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询知识手册章节 */ + get: { + parameters: { + query?: { + /** @description 租户编码。 */ + TenantCode?: string; + /** @description 地区 ID。 */ + RegionId?: string; + /** @description 单元 ID。 */ + UnitId?: string; + /** @description 科目 ID。 */ + SubjectId?: string; + /** @description 章节 ID。 */ + ChapterId?: string; + /** @description 内容入口 ID。 */ + EntryId?: string; + /** @description 内容节点 ID。 */ + ContentNodeId?: string; + /** @description 关键字。 */ + Keyword?: string; + /** @description 是否包含正文内容。 */ + IncludeContent?: boolean; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfHandbookChapterCatalogItem"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/public/catalog/handbook-entries": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询知识手册条目 */ + get: { + parameters: { + query?: { + /** @description 租户编码。 */ + TenantCode?: string; + /** @description 地区 ID。 */ + RegionId?: string; + /** @description 单元 ID。 */ + UnitId?: string; + /** @description 科目 ID。 */ + SubjectId?: string; + /** @description 章节 ID。 */ + ChapterId?: string; + /** @description 内容入口 ID。 */ + EntryId?: string; + /** @description 内容节点 ID。 */ + ContentNodeId?: string; + /** @description 关键字。 */ + Keyword?: string; + /** @description 是否包含正文内容。 */ + IncludeContent?: boolean; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfHandbookEntryCatalogItem"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/public/catalog/content-assets": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询内容资源 */ + get: { + parameters: { + query?: { + /** @description 租户编码。 */ + TenantCode?: string; + /** @description 地区 ID。 */ + RegionId?: string; + /** @description 科目 ID。 */ + SubjectId?: string; + /** @description 分类 ID。 */ + CategoryId?: string; + /** @description 内容节点 ID。 */ + ContentNodeId?: string; + /** @description 题目 ID。 */ + QuestionId?: string; + /** @description 资产 ID。 */ + AssetId?: string; + /** @description 资产类型。 */ + AssetType?: string; + /** @description 分类。 */ + Category?: string; + /** @description 资产键。 */ + AssetKey?: string; + /** @description 关键字。 */ + Keyword?: string; + /** @description 是否包含锁定资源。 */ + IncludeLocked?: boolean; + /** @description 是否包含停用数据。 */ + IncludeInactive?: boolean; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfContentAssetCatalogItem"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/public/catalog/images": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询图片资源 */ + get: { + parameters: { + query?: { + /** @description 租户编码。 */ + TenantCode?: string; + /** @description 地区 ID。 */ + RegionId?: string; + /** @description 科目 ID。 */ + SubjectId?: string; + /** @description 分类 ID。 */ + CategoryId?: string; + /** @description 内容节点 ID。 */ + ContentNodeId?: string; + /** @description 题目 ID。 */ + QuestionId?: string; + /** @description 资产 ID。 */ + AssetId?: string; + /** @description 资产类型。 */ + AssetType?: string; + /** @description 分类。 */ + Category?: string; + /** @description 资产键。 */ + AssetKey?: string; + /** @description 关键字。 */ + Keyword?: string; + /** @description 是否包含锁定资源。 */ + IncludeLocked?: boolean; + /** @description 是否包含停用数据。 */ + IncludeInactive?: boolean; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfImageAssetCatalogItem"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/public/catalog/app-assets": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询应用资源 */ + get: { + parameters: { + query?: { + /** @description 租户编码。 */ + TenantCode?: string; + /** @description 地区 ID。 */ + RegionId?: string; + /** @description 科目 ID。 */ + SubjectId?: string; + /** @description 分类 ID。 */ + CategoryId?: string; + /** @description 内容节点 ID。 */ + ContentNodeId?: string; + /** @description 题目 ID。 */ + QuestionId?: string; + /** @description 资产 ID。 */ + AssetId?: string; + /** @description 资产类型。 */ + AssetType?: string; + /** @description 分类。 */ + Category?: string; + /** @description 资产键。 */ + AssetKey?: string; + /** @description 关键字。 */ + Keyword?: string; + /** @description 是否包含锁定资源。 */ + IncludeLocked?: boolean; + /** @description 是否包含停用数据。 */ + IncludeInactive?: boolean; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfAppAssetCatalogItem"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/public/catalog/video-explanations": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询视频讲解 */ + get: { + parameters: { + query?: { + /** @description 租户编码。 */ + TenantCode?: string; + /** @description 地区 ID。 */ + RegionId?: string; + /** @description 科目 ID。 */ + SubjectId?: string; + /** @description 分类 ID。 */ + CategoryId?: string; + /** @description 内容节点 ID。 */ + ContentNodeId?: string; + /** @description 题目 ID。 */ + QuestionId?: string; + /** @description 资产 ID。 */ + AssetId?: string; + /** @description 资产类型。 */ + AssetType?: string; + /** @description 分类。 */ + Category?: string; + /** @description 资产键。 */ + AssetKey?: string; + /** @description 关键字。 */ + Keyword?: string; + /** @description 是否包含锁定资源。 */ + IncludeLocked?: boolean; + /** @description 是否包含停用数据。 */ + IncludeInactive?: boolean; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfVideoExplanationCatalogItem"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/public/catalog/question-videos": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询题目关联视频 */ + get: { + parameters: { + query?: { + /** @description 租户编码。 */ + TenantCode?: string; + /** @description 地区 ID。 */ + RegionId?: string; + /** @description 科目 ID。 */ + SubjectId?: string; + /** @description 分类 ID。 */ + CategoryId?: string; + /** @description 内容节点 ID。 */ + ContentNodeId?: string; + /** @description 题目 ID。 */ + QuestionId?: string; + /** @description 资产 ID。 */ + AssetId?: string; + /** @description 资产类型。 */ + AssetType?: string; + /** @description 分类。 */ + Category?: string; + /** @description 资产键。 */ + AssetKey?: string; + /** @description 关键字。 */ + Keyword?: string; + /** @description 是否包含锁定资源。 */ + IncludeLocked?: boolean; + /** @description 是否包含停用数据。 */ + IncludeInactive?: boolean; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfQuestionVideoCatalogItem"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/public/catalog/banners": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询首页横幅 */ + get: { + parameters: { + query?: { + /** @description 租户编码。 */ + TenantCode?: string; + /** @description 地区 ID。 */ + RegionId?: string; + /** @description ModuleId。 */ + ModuleId?: string; + /** @description 父节点 ID;传 root 表示根节点。 */ + ParentId?: string; + /** @description 院校 ID。 */ + SchoolId?: string; + /** @description 专业 ID。 */ + MajorId?: string; + /** @description 科目 ID。 */ + SubjectId?: string; + /** @description 节点 ID。 */ + NodeId?: string; + /** @description 关键字。 */ + Keyword?: string; + /** @description 类型。 */ + Type?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfBannerCatalogItem"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/public/catalog/faqs": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询常见问题 */ + get: { + parameters: { + query?: { + /** @description 租户编码。 */ + TenantCode?: string; + /** @description 地区 ID。 */ + RegionId?: string; + /** @description ModuleId。 */ + ModuleId?: string; + /** @description 父节点 ID;传 root 表示根节点。 */ + ParentId?: string; + /** @description 院校 ID。 */ + SchoolId?: string; + /** @description 专业 ID。 */ + MajorId?: string; + /** @description 科目 ID。 */ + SubjectId?: string; + /** @description 节点 ID。 */ + NodeId?: string; + /** @description 关键字。 */ + Keyword?: string; + /** @description 类型。 */ + Type?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfFaqCatalogItem"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/public/catalog/announcements": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询公告 */ + get: { + parameters: { + query?: { + /** @description 租户编码。 */ + TenantCode?: string; + /** @description 地区 ID。 */ + RegionId?: string; + /** @description ModuleId。 */ + ModuleId?: string; + /** @description 父节点 ID;传 root 表示根节点。 */ + ParentId?: string; + /** @description 院校 ID。 */ + SchoolId?: string; + /** @description 专业 ID。 */ + MajorId?: string; + /** @description 科目 ID。 */ + SubjectId?: string; + /** @description 节点 ID。 */ + NodeId?: string; + /** @description 关键字。 */ + Keyword?: string; + /** @description 类型。 */ + Type?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfAnnouncementCatalogItem"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/public/catalog/exam-dates": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询考试日期 */ + get: { + parameters: { + query?: { + /** @description 租户编码。 */ + TenantCode?: string; + /** @description 地区 ID。 */ + RegionId?: string; + /** @description ModuleId。 */ + ModuleId?: string; + /** @description 父节点 ID;传 root 表示根节点。 */ + ParentId?: string; + /** @description 院校 ID。 */ + SchoolId?: string; + /** @description 专业 ID。 */ + MajorId?: string; + /** @description 科目 ID。 */ + SubjectId?: string; + /** @description 节点 ID。 */ + NodeId?: string; + /** @description 关键字。 */ + Keyword?: string; + /** @description 类型。 */ + Type?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfExamDateCatalogItem"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/public/catalog/products": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询可购买产品 */ + get: { + parameters: { + query?: { + /** @description 租户编码。 */ + TenantCode?: string; + /** @description 地区 ID。 */ + RegionId?: string; + /** @description ModuleId。 */ + ModuleId?: string; + /** @description 父节点 ID;传 root 表示根节点。 */ + ParentId?: string; + /** @description 院校 ID。 */ + SchoolId?: string; + /** @description 专业 ID。 */ + MajorId?: string; + /** @description 科目 ID。 */ + SubjectId?: string; + /** @description 节点 ID。 */ + NodeId?: string; + /** @description 关键字。 */ + Keyword?: string; + /** @description 类型。 */ + Type?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfProductCatalogItem"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/public/catalog/svip-plans": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询 SVIP 套餐 */ + get: { + parameters: { + query?: { + /** @description 租户编码。 */ + TenantCode?: string; + /** @description 地区 ID。 */ + RegionId?: string; + /** @description ModuleId。 */ + ModuleId?: string; + /** @description 父节点 ID;传 root 表示根节点。 */ + ParentId?: string; + /** @description 院校 ID。 */ + SchoolId?: string; + /** @description 专业 ID。 */ + MajorId?: string; + /** @description 科目 ID。 */ + SubjectId?: string; + /** @description 节点 ID。 */ + NodeId?: string; + /** @description 关键字。 */ + Keyword?: string; + /** @description 类型。 */ + Type?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfSvipPlanCatalogItem"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/commerce/adjustment-vouchers": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询调账凭证 */ + get: { + parameters: { + query?: { + /** @description 服务提供方。 */ + Provider?: string; + /** @description 状态。 */ + Status?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + /** @description 用户 ID。 */ + UserId?: string; + /** @description 地区 ID。 */ + RegionId?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["TenantAdjustmentVoucherList"]; + }; + }; + }; + }; + put?: never; + /** 创建调账凭证 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["CreateAdjustmentVoucherDto"]; + "text/json": components["schemas"]["CreateAdjustmentVoucherDto"]; + "application/*+json": components["schemas"]["CreateAdjustmentVoucherDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CommerceAdjustmentVoucher"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/commerce/adjustment-vouchers/detail": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询调账凭证详情 */ + get: { + parameters: { + query?: { + voucherId?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CommerceAdjustmentVoucher"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/commerce/adjustment-vouchers/status": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 审核或关闭调账凭证 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["UpdateAdjustmentVoucherStatusDto"]; + "text/json": components["schemas"]["UpdateAdjustmentVoucherStatusDto"]; + "application/*+json": components["schemas"]["UpdateAdjustmentVoucherStatusDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CommerceAdjustmentVoucher"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/commerce/adjustment-vouchers/events": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询调账凭证事件 */ + get: { + parameters: { + query?: { + voucherId?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["TenantAdjustmentVoucherEventList"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/commerce/adjustment-vouchers/report": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询调账统计报告 */ + get: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["TenantAdjustmentReport"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/commerce/reconciliation/anomalies": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询对账异常汇总 */ + get: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["TenantCommerceAnomalySummary"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/student/commerce/orders": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询当前用户订单 */ + get: { + parameters: { + query?: { + /** @description 返回数量上限。 */ + Limit?: number | string; + /** @description 状态。 */ + Status?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CommerceOrderList"]; + }; + }; + }; + }; + put?: never; + /** 创建学生端订单 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["CreateCommerceOrderDto"]; + "text/json": components["schemas"]["CreateCommerceOrderDto"]; + "application/*+json": components["schemas"]["CreateCommerceOrderDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CommerceOrderItem"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/student/commerce/orders/{orderNo}": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询当前用户订单详情 */ + get: { + parameters: { + query?: never; + header?: never; + path: { + orderNo: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CommerceOrderItem"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/student/commerce/payments": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 创建订单支付 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["CreateCommercePaymentDto"]; + "text/json": components["schemas"]["CreateCommercePaymentDto"]; + "application/*+json": components["schemas"]["CreateCommercePaymentDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CommercePaymentItem"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/student/commerce/entitlements/current": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询当前用户权益 */ + get: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CurrentEntitlementItem"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/student/commerce/coupons/claim": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 领取优惠券 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["ClaimCommerceCouponDto"]; + "text/json": components["schemas"]["ClaimCommerceCouponDto"]; + "application/*+json": components["schemas"]["ClaimCommerceCouponDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CommerceCouponItem"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/student/commerce/coupons": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询当前用户优惠券 */ + get: { + parameters: { + query?: { + /** @description 返回数量上限。 */ + Limit?: number | string; + /** @description 状态。 */ + Status?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CommerceCouponList"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/student/commerce/coupons/check": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 校验优惠券并预览订单金额 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["CheckCommerceCouponDto"]; + "text/json": components["schemas"]["CheckCommerceCouponDto"]; + "application/*+json": components["schemas"]["CheckCommerceCouponDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CommerceCouponCheckResult"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/student/commerce/payments/notify/wechat-pay": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 微信支付回调 */ + post: { + parameters: { + query?: { + tenantCode?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PaymentNotificationProcessResult"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/student/commerce/payments/notify/alipay": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 支付宝支付回调 */ + post: { + parameters: { + query?: { + tenantCode?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PaymentNotificationProcessResult"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/student/commerce/refunds/notify/wechat_pay": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 微信退款结果回调 */ + post: { + parameters: { + query?: { + tenantCode?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["RefundNotificationDto"]; + "text/json": components["schemas"]["RefundNotificationDto"]; + "application/*+json": components["schemas"]["RefundNotificationDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CommerceRefundRequest"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/student/commerce/refunds/notify/alipay": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 支付宝退款结果回调 */ + post: { + parameters: { + query?: { + tenantCode?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["RefundNotificationDto"]; + "text/json": components["schemas"]["RefundNotificationDto"]; + "application/*+json": components["schemas"]["RefundNotificationDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CommerceRefundRequest"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/commerce/orders": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询租户订单 */ + get: { + parameters: { + query?: { + /** @description 服务提供方。 */ + Provider?: string; + /** @description 状态。 */ + Status?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + /** @description 用户 ID。 */ + UserId?: string; + /** @description 地区 ID。 */ + RegionId?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["AdminOrderList"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/commerce/payments": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询租户支付记录 */ + get: { + parameters: { + query?: { + /** @description 服务提供方。 */ + Provider?: string; + /** @description 状态。 */ + Status?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + /** @description 用户 ID。 */ + UserId?: string; + /** @description 地区 ID。 */ + RegionId?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["AdminPaymentList"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/commission/settings": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询佣金配置 */ + get: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CommissionSettingsItem"]; + }; + }; + }; + }; + /** 保存佣金配置 */ + put: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["UpdateCommissionSettingsDto"]; + "text/json": components["schemas"]["UpdateCommissionSettingsDto"]; + "application/*+json": components["schemas"]["UpdateCommissionSettingsDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CommissionSettingsItem"]; + }; + }; + }; + }; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/commission/member-rate": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + /** 调整成员佣金比例 */ + put: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["UpdateMemberCommissionRateDto"]; + "text/json": components["schemas"]["UpdateMemberCommissionRateDto"]; + "application/*+json": components["schemas"]["UpdateMemberCommissionRateDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": unknown; + }; + }; + }; + }; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/commission/summary": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询佣金统计摘要 */ + get: { + parameters: { + query?: { + /** @description 开始日期,格式为 yyyy-MM-dd。 */ + StartDate?: string; + /** @description 结束日期,格式为 yyyy-MM-dd。 */ + EndDate?: string; + /** @description 推荐人用户 ID。 */ + ReferrerUserId?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CommissionSummaryItem"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/commission/orders": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询佣金来源订单 */ + get: { + parameters: { + query?: { + /** @description 开始日期,格式为 yyyy-MM-dd。 */ + StartDate?: string; + /** @description 结束日期,格式为 yyyy-MM-dd。 */ + EndDate?: string; + /** @description 推荐人用户 ID。 */ + ReferrerUserId?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CommissionListOfCommissionSourceItem"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/commission/settlements": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询佣金结算单 */ + get: { + parameters: { + query?: { + /** @description 状态。 */ + Status?: string; + /** @description 推荐人用户 ID。 */ + ReferrerUserId?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CommissionListOfCommissionSettlementItemDto"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/commission/settlements/export": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 导出佣金结算单 */ + get: { + parameters: { + query?: { + /** @description 结算单 ID。 */ + SettlementId?: string; + /** @description 导出格式。 */ + Format?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CommissionExportItem"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/commission/settlements/generate": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 生成佣金结算单 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["GenerateCommissionSettlementDto"]; + "text/json": components["schemas"]["GenerateCommissionSettlementDto"]; + "application/*+json": components["schemas"]["GenerateCommissionSettlementDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CommissionSettlementItemDto"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/commission/settlements/status": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 更新佣金结算单状态 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["UpdateCommissionSettlementStatusDto"]; + "text/json": components["schemas"]["UpdateCommissionSettlementStatusDto"]; + "application/*+json": components["schemas"]["UpdateCommissionSettlementStatusDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CommissionSettlementItemDto"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/commission/settlements/proofs": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询佣金结算凭证 */ + get: { + parameters: { + query?: { + /** @description 结算单 ID。 */ + SettlementId?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CommissionListOfCommissionProofItem"]; + }; + }; + }; + }; + put?: never; + /** 创建佣金结算凭证 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["CreateCommissionProofDto"]; + "text/json": components["schemas"]["CreateCommissionProofDto"]; + "application/*+json": components["schemas"]["CreateCommissionProofDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CommissionProofItem"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/commission/settlements/proofs/status": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 更新佣金结算凭证状态 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["UpdateCommissionProofStatusDto"]; + "text/json": components["schemas"]["UpdateCommissionProofStatusDto"]; + "application/*+json": components["schemas"]["UpdateCommissionProofStatusDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CommissionProofItem"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/content/imports/preview/{importType}": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 预览内容导入数据 */ + post: { + parameters: { + query?: never; + header?: never; + path: { + importType: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["DirectImportDto"]; + "text/json": components["schemas"]["DirectImportDto"]; + "application/*+json": components["schemas"]["DirectImportDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["SimpleImportResult"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/content/imports/{importType}": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 执行或排队内容导入 */ + post: { + parameters: { + query?: never; + header?: never; + path: { + importType: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["DirectImportDto"]; + "text/json": components["schemas"]["DirectImportDto"]; + "application/*+json": components["schemas"]["DirectImportDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["SimpleImportResult"]; + }; + }; + /** @description Accepted */ + 202: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BackgroundJobItem"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/content/imports/detail": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询内容导入任务详情 */ + get: { + parameters: { + query?: { + /** @description 任务 ID。 */ + JobId?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ContentImportJobDetail"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/content/imports/issues": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询内容导入问题明细 */ + get: { + parameters: { + query?: { + /** @description 任务 ID。 */ + JobId?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfContentImportIssueModel"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/content/imports/post-check": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询内容导入后检查状态 */ + get: { + parameters: { + query?: { + /** @description 任务 ID。 */ + JobId?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ImportPostCheckResult"]; + }; + }; + }; + }; + put?: never; + /** 执行内容导入后完整性检查 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["DirectImportJobDto"]; + "text/json": components["schemas"]["DirectImportJobDto"]; + "application/*+json": components["schemas"]["DirectImportJobDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ImportPostCheckResult"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/commerce/coupons": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询租户优惠券 */ + get: { + parameters: { + query?: { + /** @description 服务提供方。 */ + Provider?: string; + /** @description 状态。 */ + Status?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + /** @description 用户 ID。 */ + UserId?: string; + /** @description 地区 ID。 */ + RegionId?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["TenantCouponList"]; + }; + }; + }; + }; + /** 新增或更新租户优惠券 */ + put: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["UpsertTenantCouponDto"]; + "text/json": components["schemas"]["UpsertTenantCouponDto"]; + "application/*+json": components["schemas"]["UpsertTenantCouponDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": unknown; + }; + }; + }; + }; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/commerce/coupons/redemptions": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询优惠券领取和核销记录 */ + get: { + parameters: { + query?: { + /** @description 服务提供方。 */ + Provider?: string; + /** @description 状态。 */ + Status?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + /** @description 用户 ID。 */ + UserId?: string; + /** @description 地区 ID。 */ + RegionId?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["TenantCouponRedemptionList"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/commerce/coupons/report": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询优惠券基础报表 */ + get: { + parameters: { + query?: { + /** @description 服务提供方。 */ + Provider?: string; + /** @description 状态。 */ + Status?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + /** @description 用户 ID。 */ + UserId?: string; + /** @description 地区 ID。 */ + RegionId?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["TenantCouponReport"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/crm/config": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询 CRM 推送配置 */ + get: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CrmConfigItem"]; + }; + }; + }; + }; + /** 保存 CRM 推送配置 */ + put: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["UpsertCrmConfigDto"]; + "text/json": components["schemas"]["UpsertCrmConfigDto"]; + "application/*+json": components["schemas"]["UpsertCrmConfigDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CrmConfigItem"]; + }; + }; + }; + }; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/crm/queue": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询 CRM webhook 队列 */ + get: { + parameters: { + query?: { + /** @description 状态。 */ + Status?: string; + /** @description 队列任务 ID。 */ + QueueId?: string; + /** @description 来源。 */ + Source?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CrmListOfCrmQueueItem"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/crm/dead-letters": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询 CRM 死信任务与汇总 */ + get: { + parameters: { + query?: { + /** @description 状态。 */ + Status?: string; + /** @description 队列任务 ID。 */ + QueueId?: string; + /** @description 来源。 */ + Source?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CrmDeadLetterResult"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/crm/queue/logs": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询 CRM 队列执行日志 */ + get: { + parameters: { + query?: { + /** @description 队列任务 ID。 */ + QueueId?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CrmListOfCrmQueueLogItem"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/crm/queue/action": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 重试或忽略 CRM 死信任务 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["CrmQueueActionDto"]; + "text/json": components["schemas"]["CrmQueueActionDto"]; + "application/*+json": components["schemas"]["CrmQueueActionDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CrmQueueItem"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/content/scoreline/schools": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询管理侧分数线院校 */ + get: { + parameters: { + query?: { + /** @description 地区 ID。 */ + RegionId?: string; + /** @description 内容入口 ID。 */ + EntryId?: string; + /** @description 内容节点 ID。 */ + ContentNodeId?: string; + /** @description 父节点 ID。 */ + ParentId?: string; + /** @description 科目 ID。 */ + SubjectId?: string; + /** @description 章节 ID。 */ + ChapterId?: string; + /** @description 单元 ID。 */ + UnitId?: string; + /** @description 院校 ID。 */ + SchoolId?: string; + /** @description 专业 ID。 */ + MajorId?: string; + /** @description 题目 ID。 */ + QuestionId?: string; + /** @description 状态。 */ + Status?: string; + /** @description 关键字。 */ + Keyword?: string; + /** @description 年份。 */ + Year?: number | string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfSchool"]; + }; + }; + }; + }; + /** 新增或更新分数线院校 */ + put: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["DirectSchoolDto"]; + "text/json": components["schemas"]["DirectSchoolDto"]; + "application/*+json": components["schemas"]["DirectSchoolDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ContentManagementResultOfSchool"]; + }; + }; + }; + }; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/content/scoreline/majors": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询管理侧分数线专业 */ + get: { + parameters: { + query?: { + /** @description 地区 ID。 */ + RegionId?: string; + /** @description 内容入口 ID。 */ + EntryId?: string; + /** @description 内容节点 ID。 */ + ContentNodeId?: string; + /** @description 父节点 ID。 */ + ParentId?: string; + /** @description 科目 ID。 */ + SubjectId?: string; + /** @description 章节 ID。 */ + ChapterId?: string; + /** @description 单元 ID。 */ + UnitId?: string; + /** @description 院校 ID。 */ + SchoolId?: string; + /** @description 专业 ID。 */ + MajorId?: string; + /** @description 题目 ID。 */ + QuestionId?: string; + /** @description 状态。 */ + Status?: string; + /** @description 关键字。 */ + Keyword?: string; + /** @description 年份。 */ + Year?: number | string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfMajor"]; + }; + }; + }; + }; + /** 新增或更新分数线专业 */ + put: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["DirectMajorDto"]; + "text/json": components["schemas"]["DirectMajorDto"]; + "application/*+json": components["schemas"]["DirectMajorDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ContentManagementResultOfMajor"]; + }; + }; + }; + }; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/content/handbook-subjects": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询管理侧知识手册科目 */ + get: { + parameters: { + query?: { + /** @description 地区 ID。 */ + RegionId?: string; + /** @description 内容入口 ID。 */ + EntryId?: string; + /** @description 内容节点 ID。 */ + ContentNodeId?: string; + /** @description 父节点 ID。 */ + ParentId?: string; + /** @description 科目 ID。 */ + SubjectId?: string; + /** @description 章节 ID。 */ + ChapterId?: string; + /** @description 单元 ID。 */ + UnitId?: string; + /** @description 院校 ID。 */ + SchoolId?: string; + /** @description 专业 ID。 */ + MajorId?: string; + /** @description 题目 ID。 */ + QuestionId?: string; + /** @description 状态。 */ + Status?: string; + /** @description 关键字。 */ + Keyword?: string; + /** @description 年份。 */ + Year?: number | string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfHandbookSubject"]; + }; + }; + }; + }; + /** 新增或更新知识手册科目 */ + put: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["DirectHandbookSubjectDto"]; + "text/json": components["schemas"]["DirectHandbookSubjectDto"]; + "application/*+json": components["schemas"]["DirectHandbookSubjectDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ContentManagementResultOfHandbookSubject"]; + }; + }; + }; + }; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/content/handbook-chapters": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询管理侧知识手册章节 */ + get: { + parameters: { + query?: { + /** @description 地区 ID。 */ + RegionId?: string; + /** @description 内容入口 ID。 */ + EntryId?: string; + /** @description 内容节点 ID。 */ + ContentNodeId?: string; + /** @description 父节点 ID。 */ + ParentId?: string; + /** @description 科目 ID。 */ + SubjectId?: string; + /** @description 章节 ID。 */ + ChapterId?: string; + /** @description 单元 ID。 */ + UnitId?: string; + /** @description 院校 ID。 */ + SchoolId?: string; + /** @description 专业 ID。 */ + MajorId?: string; + /** @description 题目 ID。 */ + QuestionId?: string; + /** @description 状态。 */ + Status?: string; + /** @description 关键字。 */ + Keyword?: string; + /** @description 年份。 */ + Year?: number | string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfHandbookChapter"]; + }; + }; + }; + }; + /** 新增或更新知识手册章节 */ + put: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["DirectHandbookChapterDto"]; + "text/json": components["schemas"]["DirectHandbookChapterDto"]; + "application/*+json": components["schemas"]["DirectHandbookChapterDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ContentManagementResultOfHandbookChapter"]; + }; + }; + }; + }; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/content/handbook-entries": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询管理侧知识手册条目 */ + get: { + parameters: { + query?: { + /** @description 地区 ID。 */ + RegionId?: string; + /** @description 内容入口 ID。 */ + EntryId?: string; + /** @description 内容节点 ID。 */ + ContentNodeId?: string; + /** @description 父节点 ID。 */ + ParentId?: string; + /** @description 科目 ID。 */ + SubjectId?: string; + /** @description 章节 ID。 */ + ChapterId?: string; + /** @description 单元 ID。 */ + UnitId?: string; + /** @description 院校 ID。 */ + SchoolId?: string; + /** @description 专业 ID。 */ + MajorId?: string; + /** @description 题目 ID。 */ + QuestionId?: string; + /** @description 状态。 */ + Status?: string; + /** @description 关键字。 */ + Keyword?: string; + /** @description 年份。 */ + Year?: number | string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfHandbookEntry"]; + }; + }; + }; + }; + /** 新增或更新知识手册条目 */ + put: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["DirectHandbookEntryDto"]; + "text/json": components["schemas"]["DirectHandbookEntryDto"]; + "application/*+json": components["schemas"]["DirectHandbookEntryDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ContentManagementResultOfHandbookEntry"]; + }; + }; + }; + }; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/system/health": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * 健康检查 + * @description 用于本地、CI 和部署环境 smoke test 的轻量健康检查。 + */ + get: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["HealthResponseDto"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/system/health/ready": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 依赖就绪检查 */ + get: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": unknown; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/student/learning/stats": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询学习统计 */ + get: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["LearningStatsItem"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/student/learning/trend": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询学习趋势 */ + get: { + parameters: { + query?: { + /** @description 返回数量上限。 */ + Limit?: number | string; + /** @description 状态。 */ + Status?: string; + /** @description 单元 ID。 */ + UnitId?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["LearningListOfLearningTrendItem"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/student/learning/leaderboard": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询学习排行榜 */ + get: { + parameters: { + query?: { + /** @description 返回数量上限。 */ + Limit?: number | string; + /** @description 状态。 */ + Status?: string; + /** @description 单元 ID。 */ + UnitId?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["LearningLeaderboardResult"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/me": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * 获取当前登录用户 + * @description 根据 Bearer Token 返回当前用户基础信息和活跃租户成员摘要。 + */ + get: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["MeResponse"]; + "application/json": components["schemas"]["MeResponse"]; + "text/json": components["schemas"]["MeResponse"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/me/sessions": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询当前授权域的登录设备 */ + get: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["AuthSessionSummary"][]; + "application/json": components["schemas"]["AuthSessionSummary"][]; + "text/json": components["schemas"]["AuthSessionSummary"][]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/me/sessions/{sessionFamilyId}": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + post?: never; + /** 撤销其他设备的登录会话 */ + delete: { + parameters: { + query?: never; + header?: never; + path: { + sessionFamilyId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description No Content */ + 204: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + }; + }; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/content/operations/{kind}": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询运营内容 */ + get: { + parameters: { + query?: { + /** @description 地区 ID。 */ + RegionId?: string; + /** @description 内容入口 ID。 */ + EntryId?: string; + /** @description 内容节点 ID。 */ + ContentNodeId?: string; + /** @description 父节点 ID。 */ + ParentId?: string; + /** @description 科目 ID。 */ + SubjectId?: string; + /** @description 章节 ID。 */ + ChapterId?: string; + /** @description 单元 ID。 */ + UnitId?: string; + /** @description 院校 ID。 */ + SchoolId?: string; + /** @description 专业 ID。 */ + MajorId?: string; + /** @description 题目 ID。 */ + QuestionId?: string; + /** @description 状态。 */ + Status?: string; + /** @description 关键字。 */ + Keyword?: string; + /** @description 年份。 */ + Year?: number | string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path: { + kind: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfOperationContentItem"]; + }; + }; + }; + }; + /** 新增或更新运营内容 */ + put: { + parameters: { + query?: never; + header?: never; + path: { + kind: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["DirectOperationContentDto"]; + "text/json": components["schemas"]["DirectOperationContentDto"]; + "application/*+json": components["schemas"]["DirectOperationContentDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ContentManagementResultOfOperationContentItem"]; + }; + }; + }; + }; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/commerce/payment-accounts": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询租户支付账号 */ + get: { + parameters: { + query?: { + /** @description 服务提供方。 */ + Provider?: string; + /** @description 状态。 */ + Status?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + /** @description 用户 ID。 */ + UserId?: string; + /** @description 地区 ID。 */ + RegionId?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["TenantPaymentProviderItem"][]; + }; + }; + }; + }; + /** 新增或更新租户支付账号 */ + put: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["UpsertPaymentAccountDto"]; + "text/json": components["schemas"]["UpsertPaymentAccountDto"]; + "application/*+json": components["schemas"]["UpsertPaymentAccountDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["TenantPaymentProviderItem"]; + }; + }; + }; + }; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/commerce/secrets": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + /** 写入或轮换租户密钥 */ + put: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["UpsertTenantSecretDto"]; + "text/json": components["schemas"]["UpsertTenantSecretDto"]; + "application/*+json": components["schemas"]["UpsertTenantSecretDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["TenantSecretItem"]; + }; + }; + }; + }; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/approvals": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询平台审批任务 */ + get: { + parameters: { + query?: { + status?: components["schemas"]["PlatformApprovalRequestStatus"]; + limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["PlatformApprovalRequestItem"][]; + "application/json": components["schemas"]["PlatformApprovalRequestItem"][]; + "text/json": components["schemas"]["PlatformApprovalRequestItem"][]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/approvals/{requestId}": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询平台审批详情 */ + get: { + parameters: { + query?: never; + header?: never; + path: { + requestId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["PlatformApprovalRequestItem"]; + "application/json": components["schemas"]["PlatformApprovalRequestItem"]; + "text/json": components["schemas"]["PlatformApprovalRequestItem"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/approvals/policies": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询平台审批策略 */ + get: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["PlatformApprovalPolicyItem"][]; + "application/json": components["schemas"]["PlatformApprovalPolicyItem"][]; + "text/json": components["schemas"]["PlatformApprovalPolicyItem"][]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/approvals/policies/{code}": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + /** 更新平台审批策略 */ + put: { + parameters: { + query?: never; + header?: never; + path: { + code: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["UpdatePlatformApprovalPolicyDto"]; + "text/json": components["schemas"]["UpdatePlatformApprovalPolicyDto"]; + "application/*+json": components["schemas"]["UpdatePlatformApprovalPolicyDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["PlatformApprovalPolicyItem"]; + "application/json": components["schemas"]["PlatformApprovalPolicyItem"]; + "text/json": components["schemas"]["PlatformApprovalPolicyItem"]; + }; + }; + }; + }; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/approvals/{requestId}/approve": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 批准并执行平台审批任务 */ + post: { + parameters: { + query?: never; + header?: never; + path: { + requestId: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["PlatformApprovalDecisionDto"]; + "text/json": components["schemas"]["PlatformApprovalDecisionDto"]; + "application/*+json": components["schemas"]["PlatformApprovalDecisionDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["PlatformApprovalRequestItem"]; + "application/json": components["schemas"]["PlatformApprovalRequestItem"]; + "text/json": components["schemas"]["PlatformApprovalRequestItem"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/approvals/{requestId}/reject": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 拒绝平台审批任务 */ + post: { + parameters: { + query?: never; + header?: never; + path: { + requestId: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["PlatformApprovalDecisionDto"]; + "text/json": components["schemas"]["PlatformApprovalDecisionDto"]; + "application/*+json": components["schemas"]["PlatformApprovalDecisionDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["PlatformApprovalRequestItem"]; + "application/json": components["schemas"]["PlatformApprovalRequestItem"]; + "text/json": components["schemas"]["PlatformApprovalRequestItem"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/approvals/{requestId}/cancel": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 撤销本人提交的平台审批任务 */ + post: { + parameters: { + query?: never; + header?: never; + path: { + requestId: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["PlatformApprovalDecisionDto"]; + "text/json": components["schemas"]["PlatformApprovalDecisionDto"]; + "application/*+json": components["schemas"]["PlatformApprovalDecisionDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["PlatformApprovalRequestItem"]; + "application/json": components["schemas"]["PlatformApprovalRequestItem"]; + "text/json": components["schemas"]["PlatformApprovalRequestItem"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/audit-logs": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询平台审计日志 */ + get: { + parameters: { + query?: { + /** @description 状态。 */ + Status?: string; + /** @description 搜索关键字。 */ + Search?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PlatformAuditLogList"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/audit-alerts": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询平台审计告警 */ + get: { + parameters: { + query?: { + /** @description 状态。 */ + Status?: string; + /** @description 搜索关键字。 */ + Search?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PlatformAuditAlertList"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/audit-alerts/status": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 更新平台审计告警状态 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["UpdatePlatformAuditAlertStatusDto"]; + "text/json": components["schemas"]["UpdatePlatformAuditAlertStatusDto"]; + "application/*+json": components["schemas"]["UpdatePlatformAuditAlertStatusDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PlatformAuditAlert"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/access/ui-bootstrap": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * 查询平台后台菜单与权限 + * @description 返回当前平台管理员可见的后台菜单、权限和模块启用状态。 + */ + get: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["BackofficeUiBootstrap"]; + "application/json": components["schemas"]["BackofficeUiBootstrap"]; + "text/json": components["schemas"]["BackofficeUiBootstrap"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/access/bootstrap": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询平台角色管理初始化数据 */ + get: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["BackofficeBootstrap"]; + "application/json": components["schemas"]["BackofficeBootstrap"]; + "text/json": components["schemas"]["BackofficeBootstrap"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/access/roles": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 创建或更新平台后台角色 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["UpsertBackofficeRoleDto"]; + "text/json": components["schemas"]["UpsertBackofficeRoleDto"]; + "application/*+json": components["schemas"]["UpsertBackofficeRoleDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["BackofficeRoleItem"]; + "application/json": components["schemas"]["BackofficeRoleItem"]; + "text/json": components["schemas"]["BackofficeRoleItem"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/access/roles/{roleId}/bindings": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + /** 替换平台后台角色权限绑定 */ + put: { + parameters: { + query?: never; + header: { + "Idempotency-Key": string; + }; + path: { + roleId: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["ReplaceRoleBindingsDto"]; + "text/json": components["schemas"]["ReplaceRoleBindingsDto"]; + "application/*+json": components["schemas"]["ReplaceRoleBindingsDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["PlatformCommandSubmission"]; + "application/json": components["schemas"]["PlatformCommandSubmission"]; + "text/json": components["schemas"]["PlatformCommandSubmission"]; + }; + }; + /** @description Accepted */ + 202: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["PlatformCommandSubmission"]; + "application/json": components["schemas"]["PlatformCommandSubmission"]; + "text/json": components["schemas"]["PlatformCommandSubmission"]; + }; + }; + }; + }; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/access/users/{userId}/roles": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + /** 替换平台用户后台角色 */ + put: { + parameters: { + query?: never; + header?: never; + path: { + userId: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["ReplaceUserRolesDto"]; + "text/json": components["schemas"]["ReplaceUserRolesDto"]; + "application/*+json": components["schemas"]["ReplaceUserRolesDto"]; + }; + }; + responses: { + /** @description No Content */ + 204: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + }; + }; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/integrations/platform-billing/callbacks/{provider}": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * 处理平台账务支付回调 + * @description 接收平台账务支付渠道回调,按 provider 归一化后写入通知处理流程。 + */ + post: { + parameters: { + query?: never; + header?: never; + path: { + provider: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/overview": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询平台经营概览 */ + get: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PlatformOverview"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/saas/dunning/channels": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询平台催缴通知渠道 */ + get: { + parameters: { + query?: { + /** @description 状态。 */ + Status?: string; + /** @description 搜索关键字。 */ + Search?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PlatformBillingDunningChannelList"]; + }; + }; + }; + }; + /** 创建或更新平台催缴通知渠道 */ + put: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["UpsertPlatformBillingDunningChannelDto"]; + "text/json": components["schemas"]["UpsertPlatformBillingDunningChannelDto"]; + "application/*+json": components["schemas"]["UpsertPlatformBillingDunningChannelDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PlatformBillingDunningChannelItem"]; + }; + }; + }; + }; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/saas/dunning/channels/disable": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 禁用平台催缴通知渠道 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["DisablePlatformBillingDunningChannelDto"]; + "text/json": components["schemas"]["DisablePlatformBillingDunningChannelDto"]; + "application/*+json": components["schemas"]["DisablePlatformBillingDunningChannelDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PlatformBillingDunningChannelItem"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/saas/dunning/events": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询平台催缴通知事件 */ + get: { + parameters: { + query?: { + /** @description 状态。 */ + Status?: string; + /** @description 搜索关键字。 */ + Search?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PlatformBillingDunningEventList"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/saas/dunning/events/detail": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询平台催缴通知事件详情 */ + get: { + parameters: { + query?: { + eventId?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PlatformBillingDunningEventItem"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/saas/dunning/events/retry": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 重新标记平台催缴通知事件待发送 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["RetryPlatformBillingDunningEventDto"]; + "text/json": components["schemas"]["RetryPlatformBillingDunningEventDto"]; + "application/*+json": components["schemas"]["RetryPlatformBillingDunningEventDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PlatformBillingDunningEventItem"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/saas/dunning/events/acknowledge": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 人工确认平台催缴通知事件 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["ResolvePlatformBillingDunningEventDto"]; + "text/json": components["schemas"]["ResolvePlatformBillingDunningEventDto"]; + "application/*+json": components["schemas"]["ResolvePlatformBillingDunningEventDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PlatformBillingDunningEventItem"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/saas/dunning/events/ignore": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 人工忽略平台催缴通知事件 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["ResolvePlatformBillingDunningEventDto"]; + "text/json": components["schemas"]["ResolvePlatformBillingDunningEventDto"]; + "application/*+json": components["schemas"]["ResolvePlatformBillingDunningEventDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PlatformBillingDunningEventItem"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/governance/configuration/definitions": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询类型化平台配置定义 */ + get: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["PlatformConfigurationDefinitionItem"][]; + "application/json": components["schemas"]["PlatformConfigurationDefinitionItem"][]; + "text/json": components["schemas"]["PlatformConfigurationDefinitionItem"][]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/governance/configuration/versions": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询平台配置版本 */ + get: { + parameters: { + query?: { + definitionCode?: string; + environment?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["PlatformConfigurationVersionItem"][]; + "application/json": components["schemas"]["PlatformConfigurationVersionItem"][]; + "text/json": components["schemas"]["PlatformConfigurationVersionItem"][]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/governance/configuration/drafts": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 保存平台配置草稿 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["SavePlatformConfigurationDraftDto"]; + "text/json": components["schemas"]["SavePlatformConfigurationDraftDto"]; + "application/*+json": components["schemas"]["SavePlatformConfigurationDraftDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["PlatformConfigurationVersionItem"]; + "application/json": components["schemas"]["PlatformConfigurationVersionItem"]; + "text/json": components["schemas"]["PlatformConfigurationVersionItem"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/governance/configuration/versions/{versionId}/publish": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 发布平台配置版本 */ + post: { + parameters: { + query?: never; + header?: never; + path: { + versionId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["PlatformConfigurationVersionItem"]; + "application/json": components["schemas"]["PlatformConfigurationVersionItem"]; + "text/json": components["schemas"]["PlatformConfigurationVersionItem"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/governance/configuration/versions/{versionId}/rollback": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 回滚平台配置版本 */ + post: { + parameters: { + query?: never; + header?: never; + path: { + versionId: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["PlatformRollbackDto"]; + "text/json": components["schemas"]["PlatformRollbackDto"]; + "application/*+json": components["schemas"]["PlatformRollbackDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["PlatformConfigurationVersionItem"]; + "application/json": components["schemas"]["PlatformConfigurationVersionItem"]; + "text/json": components["schemas"]["PlatformConfigurationVersionItem"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/governance/notifications/templates": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询平台通知模板 */ + get: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["PlatformNotificationTemplateItem"][]; + "application/json": components["schemas"]["PlatformNotificationTemplateItem"][]; + "text/json": components["schemas"]["PlatformNotificationTemplateItem"][]; + }; + }; + }; + }; + /** 新增或更新平台通知模板 */ + put: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["UpsertPlatformNotificationTemplateDto"]; + "text/json": components["schemas"]["UpsertPlatformNotificationTemplateDto"]; + "application/*+json": components["schemas"]["UpsertPlatformNotificationTemplateDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["PlatformNotificationTemplateItem"]; + "application/json": components["schemas"]["PlatformNotificationTemplateItem"]; + "text/json": components["schemas"]["PlatformNotificationTemplateItem"]; + }; + }; + }; + }; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/governance/notifications/send": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 按平台岗位发送通知 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["SendPlatformNotificationDto"]; + "text/json": components["schemas"]["SendPlatformNotificationDto"]; + "application/*+json": components["schemas"]["SendPlatformNotificationDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["PlatformNotificationDeliveryItem"][]; + "application/json": components["schemas"]["PlatformNotificationDeliveryItem"][]; + "text/json": components["schemas"]["PlatformNotificationDeliveryItem"][]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/governance/notifications/deliveries": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 分页查询平台通知投递 */ + get: { + parameters: { + query?: { + page?: number | string; + pageSize?: number | string; + search?: string; + status?: components["schemas"]["PlatformNotificationDeliveryStatus"]; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["PagedResultOfPlatformNotificationDeliveryItem"]; + "application/json": components["schemas"]["PagedResultOfPlatformNotificationDeliveryItem"]; + "text/json": components["schemas"]["PagedResultOfPlatformNotificationDeliveryItem"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/governance/notifications/deliveries/{deliveryId}/retry": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 重试平台通知投递 */ + post: { + parameters: { + query?: never; + header?: never; + path: { + deliveryId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["PlatformNotificationDeliveryItem"]; + "application/json": components["schemas"]["PlatformNotificationDeliveryItem"]; + "text/json": components["schemas"]["PlatformNotificationDeliveryItem"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/operations/health": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询受保护的依赖深度健康状态 */ + get: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/operations/workers": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询 Worker 与周期循环状态 */ + get: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/operations/job-metrics": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询后台任务队列指标 */ + get: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/operations/governance-metrics": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询审批、配置与通知治理指标 */ + get: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/operations/jobs": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询全平台后台任务 */ + get: { + parameters: { + query?: { + tenantId?: string; + jobType?: string; + status?: components["schemas"]["BackgroundJobStatus"]; + limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["BackgroundJobItem"][]; + "application/json": components["schemas"]["BackgroundJobItem"][]; + "text/json": components["schemas"]["BackgroundJobItem"][]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/operations/jobs/{jobId}": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询平台后台任务详情 */ + get: { + parameters: { + query?: never; + header?: never; + path: { + jobId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["BackgroundJobItem"]; + "application/json": components["schemas"]["BackgroundJobItem"]; + "text/json": components["schemas"]["BackgroundJobItem"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/operations/jobs/{jobId}/cancel": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 取消平台后台任务 */ + post: { + parameters: { + query?: never; + header?: never; + path: { + jobId: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["CancelBackgroundJobDto"]; + "text/json": components["schemas"]["CancelBackgroundJobDto"]; + "application/*+json": components["schemas"]["CancelBackgroundJobDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["BackgroundJobItem"]; + "application/json": components["schemas"]["BackgroundJobItem"]; + "text/json": components["schemas"]["BackgroundJobItem"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/operations/jobs/{jobId}/retry": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 重试平台后台任务 */ + post: { + parameters: { + query?: never; + header?: never; + path: { + jobId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["BackgroundJobItem"]; + "application/json": components["schemas"]["BackgroundJobItem"]; + "text/json": components["schemas"]["BackgroundJobItem"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/payment-settings/apps": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询平台支付应用 */ + get: { + parameters: { + query?: { + status?: string; + limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PlatformPaymentApp"][]; + }; + }; + }; + }; + /** 新增或更新平台支付应用 */ + put: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["UpsertPlatformPaymentAppDto"]; + "text/json": components["schemas"]["UpsertPlatformPaymentAppDto"]; + "application/*+json": components["schemas"]["UpsertPlatformPaymentAppDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PlatformPaymentApp"]; + }; + }; + }; + }; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/payment-settings/channels": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询平台支付渠道 */ + get: { + parameters: { + query?: { + appId?: string; + status?: string; + limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PlatformPaymentChannel"][]; + }; + }; + }; + }; + /** 新增或更新平台支付渠道 */ + put: { + parameters: { + query?: never; + header: { + "Idempotency-Key": string; + }; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["UpsertPlatformPaymentChannelDto"]; + "text/json": components["schemas"]["UpsertPlatformPaymentChannelDto"]; + "application/*+json": components["schemas"]["UpsertPlatformPaymentChannelDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PlatformCommandSubmission"]; + }; + }; + /** @description Accepted */ + 202: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PlatformCommandSubmission"]; + }; + }; + }; + }; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/payment-settings/channels/{id}/disable": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 禁用平台支付渠道 */ + post: { + parameters: { + query?: never; + header?: never; + path: { + id: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PlatformPaymentChannel"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/payment-settings/events": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询平台支付事件 */ + get: { + parameters: { + query?: { + status?: string; + limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PlatformBillingPaymentEvent"][]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/payment-settings/rebates/summary": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询平台返佣汇总 */ + get: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PlatformRebateSummary"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/question-banks": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询平台公共题库 */ + get: { + parameters: { + query?: { + keyword?: string; + status?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PlatformQuestionBankItem"][]; + }; + }; + }; + }; + /** 新增或更新平台公共题库 */ + put: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["UpsertPlatformQuestionBankCommand"]; + "text/json": components["schemas"]["UpsertPlatformQuestionBankCommand"]; + "application/*+json": components["schemas"]["UpsertPlatformQuestionBankCommand"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PlatformQuestionBankItem"]; + }; + }; + }; + }; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/question-banks/{bankId}/archive": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 归档平台公共题库 */ + post: { + parameters: { + query?: never; + header?: never; + path: { + bankId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PlatformQuestionBankItem"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/question-banks/{bankId}/nodes": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询公共题库内容结构 */ + get: { + parameters: { + query?: never; + header?: never; + path: { + bankId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PlatformQuestionBankNodeItem"][]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/question-banks/nodes": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + /** 新增或更新公共题库内容节点 */ + put: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["UpsertPlatformQuestionBankNodeCommand"]; + "text/json": components["schemas"]["UpsertPlatformQuestionBankNodeCommand"]; + "application/*+json": components["schemas"]["UpsertPlatformQuestionBankNodeCommand"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PlatformQuestionBankNodeItem"]; + }; + }; + }; + }; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/question-banks/nodes/batch": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 批量创建公共题库章节或试卷 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["BatchCreatePlatformQuestionBankNodesCommand"]; + "text/json": components["schemas"]["BatchCreatePlatformQuestionBankNodesCommand"]; + "application/*+json": components["schemas"]["BatchCreatePlatformQuestionBankNodesCommand"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PlatformQuestionBankNodeItem"][]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/question-banks/nodes/{nodeId}/archive": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 归档公共题库内容节点 */ + post: { + parameters: { + query?: never; + header?: never; + path: { + nodeId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PlatformQuestionBankNodeItem"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/question-banks/questions": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 分页查询公共题库题目 */ + get: { + parameters: { + query?: { + questionBankId?: string; + contentNodeId?: string; + keyword?: string; + type?: string; + difficulty?: number | string; + status?: string; + page?: number | string; + pageSize?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PlatformQuestionPage"]; + }; + }; + }; + }; + /** 新增或更新公共题库题目并保留版本 */ + put: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["UpsertPlatformQuestionCommand"]; + "text/json": components["schemas"]["UpsertPlatformQuestionCommand"]; + "application/*+json": components["schemas"]["UpsertPlatformQuestionCommand"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PlatformQuestionItem"]; + }; + }; + }; + }; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/question-banks/questions/archive": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 批量归档公共题库题目 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["ArchivePlatformQuestionsCommand"]; + "text/json": components["schemas"]["ArchivePlatformQuestionsCommand"]; + "application/*+json": components["schemas"]["ArchivePlatformQuestionsCommand"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": number | string; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/question-banks/imports/preview": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 预检公共题库 JSON 导入 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["PlatformQuestionImportCommand"]; + "text/json": components["schemas"]["PlatformQuestionImportCommand"]; + "application/*+json": components["schemas"]["PlatformQuestionImportCommand"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PlatformQuestionImportResult"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/question-banks/imports": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 执行公共题库 JSON 导入 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["PlatformQuestionImportCommand"]; + "text/json": components["schemas"]["PlatformQuestionImportCommand"]; + "application/*+json": components["schemas"]["PlatformQuestionImportCommand"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PlatformQuestionImportResult"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/question-banks/imports/{jobId}": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询公共题库导入结果 */ + get: { + parameters: { + query?: never; + header?: never; + path: { + jobId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ContentImportJobDetail"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/question-banks/assets/upload-sign": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 签发公共题库图片上传地址 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["AssetUploadSignDto"]; + "text/json": components["schemas"]["AssetUploadSignDto"]; + "application/*+json": components["schemas"]["AssetUploadSignDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["AssetUploadSignResult"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/question-banks/assets/upload-confirm": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 确认公共题库图片上传结果 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["AssetUploadConfirmDto"]; + "text/json": components["schemas"]["AssetUploadConfirmDto"]; + "application/*+json": components["schemas"]["AssetUploadConfirmDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["AssetUploadConfirmResult"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/saas/catalog": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询平台 SaaS 商品目录 */ + get: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["SaasCatalogSnapshot"]; + "application/json": components["schemas"]["SaasCatalogSnapshot"]; + "text/json": components["schemas"]["SaasCatalogSnapshot"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/saas/features": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + /** 新增或更新 SaaS 功能 */ + put: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["UpsertSaasFeatureDto"]; + "text/json": components["schemas"]["UpsertSaasFeatureDto"]; + "application/*+json": components["schemas"]["UpsertSaasFeatureDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["SaasFeature"]; + "application/json": components["schemas"]["SaasFeature"]; + "text/json": components["schemas"]["SaasFeature"]; + }; + }; + }; + }; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/saas/feature-limits": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + /** 新增或更新 SaaS 功能限额 */ + put: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["UpsertSaasFeatureLimitDto"]; + "text/json": components["schemas"]["UpsertSaasFeatureLimitDto"]; + "application/*+json": components["schemas"]["UpsertSaasFeatureLimitDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["SaasFeatureLimitDefinition"]; + "application/json": components["schemas"]["SaasFeatureLimitDefinition"]; + "text/json": components["schemas"]["SaasFeatureLimitDefinition"]; + }; + }; + }; + }; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/saas/offerings": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + /** 新增或更新 SaaS 套餐 */ + put: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["UpsertSaasOfferingDto"]; + "text/json": components["schemas"]["UpsertSaasOfferingDto"]; + "application/*+json": components["schemas"]["UpsertSaasOfferingDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["SaasOffering"]; + "application/json": components["schemas"]["SaasOffering"]; + "text/json": components["schemas"]["SaasOffering"]; + }; + }; + }; + }; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/saas/offering-versions": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + /** 新增或更新 SaaS 套餐版本草稿 */ + put: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["UpsertSaasOfferingVersionDto"]; + "text/json": components["schemas"]["UpsertSaasOfferingVersionDto"]; + "application/*+json": components["schemas"]["UpsertSaasOfferingVersionDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["SaasOfferingVersionItem"]; + "application/json": components["schemas"]["SaasOfferingVersionItem"]; + "text/json": components["schemas"]["SaasOfferingVersionItem"]; + }; + }; + }; + }; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/saas/offering-versions/{versionId}/publish": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 发布 SaaS 套餐版本 */ + post: { + parameters: { + query?: never; + header?: never; + path: { + versionId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["SaasOfferingVersionItem"]; + "application/json": components["schemas"]["SaasOfferingVersionItem"]; + "text/json": components["schemas"]["SaasOfferingVersionItem"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/saas/offering-versions/{versionId}/clone": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 克隆 SaaS 套餐版本 */ + post: { + parameters: { + query?: never; + header?: never; + path: { + versionId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["SaasOfferingVersionItem"]; + "application/json": components["schemas"]["SaasOfferingVersionItem"]; + "text/json": components["schemas"]["SaasOfferingVersionItem"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/saas/offering-versions/{versionId}/retire": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 下架 SaaS 套餐版本 */ + post: { + parameters: { + query?: never; + header?: never; + path: { + versionId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["SaasOfferingVersionItem"]; + "application/json": components["schemas"]["SaasOfferingVersionItem"]; + "text/json": components["schemas"]["SaasOfferingVersionItem"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/saas/orders": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询平台 SaaS 订单 */ + get: { + parameters: { + query?: { + tenantId?: string; + status?: string; + limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["PlatformBillingOrder"][]; + "application/json": components["schemas"]["PlatformBillingOrder"][]; + "text/json": components["schemas"]["PlatformBillingOrder"][]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/saas/payments": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询平台 SaaS 支付记录 */ + get: { + parameters: { + query?: { + tenantId?: string; + status?: string; + limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["PlatformBillingPayment"][]; + "application/json": components["schemas"]["PlatformBillingPayment"][]; + "text/json": components["schemas"]["PlatformBillingPayment"][]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/saas/refunds": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询平台 SaaS 退款记录 */ + get: { + parameters: { + query?: { + tenantId?: string; + status?: string; + limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["PlatformBillingRefund"][]; + "application/json": components["schemas"]["PlatformBillingRefund"][]; + "text/json": components["schemas"]["PlatformBillingRefund"][]; + }; + }; + }; + }; + put?: never; + /** 申请平台 SaaS 退款 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["RequestPlatformRefundDto"]; + "text/json": components["schemas"]["RequestPlatformRefundDto"]; + "application/*+json": components["schemas"]["RequestPlatformRefundDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["PlatformCommandSubmission"]; + "application/json": components["schemas"]["PlatformCommandSubmission"]; + "text/json": components["schemas"]["PlatformCommandSubmission"]; + }; + }; + /** @description Accepted */ + 202: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["PlatformCommandSubmission"]; + "application/json": components["schemas"]["PlatformCommandSubmission"]; + "text/json": components["schemas"]["PlatformCommandSubmission"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/saas/invoices": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询平台 SaaS 发票 */ + get: { + parameters: { + query?: { + tenantId?: string; + status?: string; + limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["PlatformBillingInvoice"][]; + "application/json": components["schemas"]["PlatformBillingInvoice"][]; + "text/json": components["schemas"]["PlatformBillingInvoice"][]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/saas/usage": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询租户 SaaS 用量 */ + get: { + parameters: { + query?: { + tenantId?: string; + limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["TenantFeatureUsage"][]; + "application/json": components["schemas"]["TenantFeatureUsage"][]; + "text/json": components["schemas"]["TenantFeatureUsage"][]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/saas/invoices/reminders": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询平台 SaaS 账单提醒 */ + get: { + parameters: { + query?: { + tenantId?: string; + status?: string; + limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["PlatformBillingInvoiceReminder"][]; + "application/json": components["schemas"]["PlatformBillingInvoiceReminder"][]; + "text/json": components["schemas"]["PlatformBillingInvoiceReminder"][]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/saas/subscriptions": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询租户 SaaS 订阅 */ + get: { + parameters: { + query?: { + tenantId?: string; + status?: string; + limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["TenantSaasSubscription"][]; + "application/json": components["schemas"]["TenantSaasSubscription"][]; + "text/json": components["schemas"]["TenantSaasSubscription"][]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/saas/payments/manual/confirm": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 确认平台手工支付 */ + post: { + parameters: { + query?: never; + header: { + "Idempotency-Key": string; + }; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["ConfirmManualPlatformPaymentDto"]; + "text/json": components["schemas"]["ConfirmManualPlatformPaymentDto"]; + "application/*+json": components["schemas"]["ConfirmManualPlatformPaymentDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["PlatformCommandSubmission"]; + "application/json": components["schemas"]["PlatformCommandSubmission"]; + "text/json": components["schemas"]["PlatformCommandSubmission"]; + }; + }; + /** @description Accepted */ + 202: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["PlatformCommandSubmission"]; + "application/json": components["schemas"]["PlatformCommandSubmission"]; + "text/json": components["schemas"]["PlatformCommandSubmission"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/saas/tenant-feature-overrides": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + /** 新增或更新租户功能覆盖规则 */ + put: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["UpsertTenantFeatureOverrideDto"]; + "text/json": components["schemas"]["UpsertTenantFeatureOverrideDto"]; + "application/*+json": components["schemas"]["UpsertTenantFeatureOverrideDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["TenantFeatureOverride"]; + "application/json": components["schemas"]["TenantFeatureOverride"]; + "text/json": components["schemas"]["TenantFeatureOverride"]; + }; + }; + }; + }; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/saas/metrics": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询 SaaS 商业经营指标 */ + get: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["CommercialMetrics"]; + "application/json": components["schemas"]["CommercialMetrics"]; + "text/json": components["schemas"]["CommercialMetrics"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/saas/subscriptions/trial": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 为已有租户补录试用订阅 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["GrantTenantTrialDto"]; + "text/json": components["schemas"]["GrantTenantTrialDto"]; + "application/*+json": components["schemas"]["GrantTenantTrialDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["TenantSaasSubscription"]; + "application/json": components["schemas"]["TenantSaasSubscription"]; + "text/json": components["schemas"]["TenantSaasSubscription"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/saas/subscriptions/{subscriptionId}/suspend": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 暂停租户 SaaS 订阅 */ + post: { + parameters: { + query?: never; + header?: never; + path: { + subscriptionId: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["ChangePlatformSubscriptionDto"]; + "text/json": components["schemas"]["ChangePlatformSubscriptionDto"]; + "application/*+json": components["schemas"]["ChangePlatformSubscriptionDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["TenantSaasSubscription"]; + "application/json": components["schemas"]["TenantSaasSubscription"]; + "text/json": components["schemas"]["TenantSaasSubscription"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/saas/subscriptions/{subscriptionId}/resume": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 恢复租户 SaaS 订阅 */ + post: { + parameters: { + query?: never; + header?: never; + path: { + subscriptionId: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["ChangePlatformSubscriptionDto"]; + "text/json": components["schemas"]["ChangePlatformSubscriptionDto"]; + "application/*+json": components["schemas"]["ChangePlatformSubscriptionDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["TenantSaasSubscription"]; + "application/json": components["schemas"]["TenantSaasSubscription"]; + "text/json": components["schemas"]["TenantSaasSubscription"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/saas/subscriptions/{subscriptionId}/cancel": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 立即取消租户 SaaS 订阅 */ + post: { + parameters: { + query?: never; + header?: never; + path: { + subscriptionId: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["ChangePlatformSubscriptionDto"]; + "text/json": components["schemas"]["ChangePlatformSubscriptionDto"]; + "application/*+json": components["schemas"]["ChangePlatformSubscriptionDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["TenantSaasSubscription"]; + "application/json": components["schemas"]["TenantSaasSubscription"]; + "text/json": components["schemas"]["TenantSaasSubscription"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/saas/subscriptions/{subscriptionId}/extend": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 延长租户 SaaS 订阅账期 */ + post: { + parameters: { + query?: never; + header?: never; + path: { + subscriptionId: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["ChangePlatformSubscriptionDto"]; + "text/json": components["schemas"]["ChangePlatformSubscriptionDto"]; + "application/*+json": components["schemas"]["ChangePlatformSubscriptionDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["TenantSaasSubscription"]; + "application/json": components["schemas"]["TenantSaasSubscription"]; + "text/json": components["schemas"]["TenantSaasSubscription"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/saas/refunds/{refundId}/approve": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 批准平台 SaaS 退款 */ + post: { + parameters: { + query?: never; + header?: never; + path: { + refundId: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["ReviewPlatformRefundDto"]; + "text/json": components["schemas"]["ReviewPlatformRefundDto"]; + "application/*+json": components["schemas"]["ReviewPlatformRefundDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["PlatformBillingRefund"]; + "application/json": components["schemas"]["PlatformBillingRefund"]; + "text/json": components["schemas"]["PlatformBillingRefund"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/saas/refunds/{refundId}/reject": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 拒绝平台 SaaS 退款 */ + post: { + parameters: { + query?: never; + header?: never; + path: { + refundId: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["ReviewPlatformRefundDto"]; + "text/json": components["schemas"]["ReviewPlatformRefundDto"]; + "application/*+json": components["schemas"]["ReviewPlatformRefundDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["PlatformBillingRefund"]; + "application/json": components["schemas"]["PlatformBillingRefund"]; + "text/json": components["schemas"]["PlatformBillingRefund"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/saas/refunds/{refundId}/retry": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 重试失败的平台 SaaS 退款 */ + post: { + parameters: { + query?: never; + header?: never; + path: { + refundId: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["ReviewPlatformRefundDto"]; + "text/json": components["schemas"]["ReviewPlatformRefundDto"]; + "application/*+json": components["schemas"]["ReviewPlatformRefundDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["PlatformBillingRefund"]; + "application/json": components["schemas"]["PlatformBillingRefund"]; + "text/json": components["schemas"]["PlatformBillingRefund"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/staff": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询平台员工列表 */ + get: { + parameters: { + query?: { + /** @description 状态。 */ + Status?: string; + /** @description 搜索关键字。 */ + Search?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PlatformStaffList"]; + }; + }; + }; + }; + /** 创建或更新平台员工 */ + put: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["UpsertPlatformStaffDto"]; + "text/json": components["schemas"]["UpsertPlatformStaffDto"]; + "application/*+json": components["schemas"]["UpsertPlatformStaffDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PlatformStaffItem"]; + }; + }; + }; + }; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/staff/status": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + /** 启用或禁用平台员工 */ + patch: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["UpdatePlatformStaffStatusDto"]; + "text/json": components["schemas"]["UpdatePlatformStaffStatusDto"]; + "application/*+json": components["schemas"]["UpdatePlatformStaffStatusDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PlatformStaffItem"]; + }; + }; + }; + }; + trace?: never; + }; + "/api/platform/staff/{userId}/password-reset": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 为平台员工设置一次性临时密码 */ + post: { + parameters: { + query?: never; + header?: never; + path: { + userId: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["AdministrativePasswordResetDto"]; + "text/json": components["schemas"]["AdministrativePasswordResetDto"]; + "application/*+json": components["schemas"]["AdministrativePasswordResetDto"]; + }; + }; + responses: { + /** @description No Content */ + 204: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": unknown; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/tenant-capabilities/crm/configs": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询租户 CRM 配置 */ + get: { + parameters: { + query?: { + /** @description 租户 ID。 */ + TenantId?: string; + /** @description 状态。 */ + Status?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PlatformTenantCapabilityListOfPlatformCrmConfigItem"]; + }; + }; + }; + }; + /** 新增或更新租户 CRM 配置 */ + put: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["UpsertPlatformCrmConfigDto"]; + "text/json": components["schemas"]["UpsertPlatformCrmConfigDto"]; + "application/*+json": components["schemas"]["UpsertPlatformCrmConfigDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PlatformCrmConfigItem"]; + }; + }; + }; + }; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/tenant-capabilities/crm/leads": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询租户 CRM 线索队列 */ + get: { + parameters: { + query?: { + /** @description 租户 ID。 */ + TenantId?: string; + /** @description 状态。 */ + Status?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PlatformTenantCapabilityListOfCrmWebhookQueueItem"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/tenant-capabilities/crm/leads/retry": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 重试租户 CRM 线索推送 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["RetryPlatformCrmLeadDto"]; + "text/json": components["schemas"]["RetryPlatformCrmLeadDto"]; + "application/*+json": components["schemas"]["RetryPlatformCrmLeadDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CrmWebhookQueueItem"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/tenant-capabilities/crm/logs": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询租户 CRM 推送日志 */ + get: { + parameters: { + query?: { + /** @description 队列任务 ID。 */ + QueueId?: string; + TenantId?: string; + Status?: string; + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PlatformTenantCapabilityListOfCrmWebhookLog"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/tenant-capabilities/sms/channels": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询租户短信渠道 */ + get: { + parameters: { + query?: { + /** @description 租户 ID。 */ + TenantId?: string; + /** @description 状态。 */ + Status?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PlatformTenantCapabilityListOfPlatformSmsChannelItem"]; + }; + }; + }; + }; + /** 新增或更新租户短信渠道 */ + put: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["UpsertPlatformSmsChannelDto"]; + "text/json": components["schemas"]["UpsertPlatformSmsChannelDto"]; + "application/*+json": components["schemas"]["UpsertPlatformSmsChannelDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PlatformSmsChannelItem"]; + }; + }; + }; + }; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/tenant-capabilities/sms/channels/{id}/disable": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 禁用租户短信渠道 */ + post: { + parameters: { + query?: never; + header?: never; + path: { + id: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PlatformSmsChannelItem"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/tenant-capabilities/sms/templates": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询租户短信模板 */ + get: { + parameters: { + query?: { + /** @description 租户 ID。 */ + TenantId?: string; + /** @description 状态。 */ + Status?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PlatformTenantCapabilityListOfPlatformSmsTemplateItem"]; + }; + }; + }; + }; + /** 新增或更新租户短信模板 */ + put: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["UpsertPlatformSmsTemplateDto"]; + "text/json": components["schemas"]["UpsertPlatformSmsTemplateDto"]; + "application/*+json": components["schemas"]["UpsertPlatformSmsTemplateDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PlatformSmsTemplateItem"]; + }; + }; + }; + }; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/tenant-capabilities/sms/templates/{id}/submit-review": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 提交租户短信模板审核 */ + post: { + parameters: { + query?: never; + header?: never; + path: { + id: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PlatformSmsTemplateItem"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/tenant-capabilities/sms/templates/{id}/disable": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 禁用租户短信模板 */ + post: { + parameters: { + query?: never; + header?: never; + path: { + id: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PlatformSmsTemplateItem"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/tenant-capabilities/sms/logs": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询租户短信发送日志 */ + get: { + parameters: { + query?: { + /** @description 租户 ID。 */ + TenantId?: string; + /** @description 状态。 */ + Status?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PlatformTenantCapabilityListOfSmsSendLog"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/tenant-capabilities/payments/apps": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询租户支付应用 */ + get: { + parameters: { + query?: { + /** @description 租户 ID。 */ + TenantId?: string; + /** @description 状态。 */ + Status?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PlatformTenantCapabilityListOfTenantExternalProviderItem"]; + }; + }; + }; + }; + /** 新增或更新租户支付应用 */ + put: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["UpsertPlatformTenantPaymentAppDto"]; + "text/json": components["schemas"]["UpsertPlatformTenantPaymentAppDto"]; + "application/*+json": components["schemas"]["UpsertPlatformTenantPaymentAppDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["TenantExternalProviderItem"]; + }; + }; + }; + }; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/tenant-capabilities/payments/events": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询租户支付事件 */ + get: { + parameters: { + query?: { + /** @description 租户 ID。 */ + TenantId?: string; + /** @description 状态。 */ + Status?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PlatformTenantCapabilityListOfObject"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/domains": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询租户域名状态 */ + get: { + parameters: { + query?: { + /** @description 状态。 */ + Status?: string; + /** @description 搜索关键字。 */ + Search?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PlatformDomainList"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/domains/{domainId}/recheck": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 重新触发租户域名 DNS/TLS 验证 */ + post: { + parameters: { + query?: never; + header?: never; + path: { + domainId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PlatformDomainRecheckResult"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/tenants/{tenantId}/archive-preview": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 预检租户归档条件 */ + get: { + parameters: { + query?: never; + header?: never; + path: { + tenantId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["TenantArchivePreview"]; + "application/json": components["schemas"]["TenantArchivePreview"]; + "text/json": components["schemas"]["TenantArchivePreview"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/tenants/{tenantId}/exports": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 创建租户数据导出 */ + post: { + parameters: { + query?: never; + header?: never; + path: { + tenantId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["TenantLifecycleOperationItem"]; + "application/json": components["schemas"]["TenantLifecycleOperationItem"]; + "text/json": components["schemas"]["TenantLifecycleOperationItem"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/tenants/{tenantId}/exports/{operationId}": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询租户数据导出状态 */ + get: { + parameters: { + query?: never; + header?: never; + path: { + tenantId: string; + operationId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["TenantLifecycleOperationItem"]; + "application/json": components["schemas"]["TenantLifecycleOperationItem"]; + "text/json": components["schemas"]["TenantLifecycleOperationItem"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/tenants/{tenantId}/exports/{operationId}/download": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 获取租户导出下载地址 */ + get: { + parameters: { + query?: never; + header?: never; + path: { + tenantId: string; + operationId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["ObjectStorageSignedUrl"]; + "application/json": components["schemas"]["ObjectStorageSignedUrl"]; + "text/json": components["schemas"]["ObjectStorageSignedUrl"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/tenants/{tenantId}/archive": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 逻辑归档租户 */ + post: { + parameters: { + query?: never; + header?: never; + path: { + tenantId: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["TenantLifecycleReasonDto"]; + "text/json": components["schemas"]["TenantLifecycleReasonDto"]; + "application/*+json": components["schemas"]["TenantLifecycleReasonDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["TenantLifecycleOperationItem"]; + "application/json": components["schemas"]["TenantLifecycleOperationItem"]; + "text/json": components["schemas"]["TenantLifecycleOperationItem"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/tenants/{tenantId}/restore": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 恢复租户到暂停状态 */ + post: { + parameters: { + query?: never; + header?: never; + path: { + tenantId: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["TenantLifecycleReasonDto"]; + "text/json": components["schemas"]["TenantLifecycleReasonDto"]; + "application/*+json": components["schemas"]["TenantLifecycleReasonDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["TenantLifecycleOperationItem"]; + "application/json": components["schemas"]["TenantLifecycleOperationItem"]; + "text/json": components["schemas"]["TenantLifecycleOperationItem"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/tenants/{tenantId}/owner-transfer": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 转移租户所有者 */ + post: { + parameters: { + query?: never; + header?: never; + path: { + tenantId: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["TenantOwnerTransferDto"]; + "text/json": components["schemas"]["TenantOwnerTransferDto"]; + "application/*+json": components["schemas"]["TenantOwnerTransferDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["TenantLifecycleOperationItem"]; + "application/json": components["schemas"]["TenantLifecycleOperationItem"]; + "text/json": components["schemas"]["TenantLifecycleOperationItem"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/commerce/point-activity-tasks": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询积分活动任务 */ + get: { + parameters: { + query?: { + /** @description 服务提供方。 */ + Provider?: string; + /** @description 状态。 */ + Status?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + /** @description 用户 ID。 */ + UserId?: string; + /** @description 地区 ID。 */ + RegionId?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["TenantPointTaskList"]; + }; + }; + }; + }; + /** 新增或更新积分活动任务 */ + put: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["UpsertPointTaskDto"]; + "text/json": components["schemas"]["UpsertPointTaskDto"]; + "application/*+json": components["schemas"]["UpsertPointTaskDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": unknown; + }; + }; + }; + }; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/commerce/point-activity-claims": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询积分任务领取记录 */ + get: { + parameters: { + query?: { + /** @description 服务提供方。 */ + Provider?: string; + /** @description 状态。 */ + Status?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + /** @description 用户 ID。 */ + UserId?: string; + /** @description 地区 ID。 */ + RegionId?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["TenantPointClaimList"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/commerce/point-exchange-items": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询积分兑换项 */ + get: { + parameters: { + query?: { + /** @description 服务提供方。 */ + Provider?: string; + /** @description 状态。 */ + Status?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + /** @description 用户 ID。 */ + UserId?: string; + /** @description 地区 ID。 */ + RegionId?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["TenantPointExchangeItemList"]; + }; + }; + }; + }; + /** 新增或更新积分兑换项 */ + put: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["UpsertPointExchangeItemDto"]; + "text/json": components["schemas"]["UpsertPointExchangeItemDto"]; + "application/*+json": components["schemas"]["UpsertPointExchangeItemDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": unknown; + }; + }; + }; + }; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/commerce/point-exchange-orders": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询积分兑换订单 */ + get: { + parameters: { + query?: { + /** @description 服务提供方。 */ + Provider?: string; + /** @description 状态。 */ + Status?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + /** @description 用户 ID。 */ + UserId?: string; + /** @description 地区 ID。 */ + RegionId?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["TenantPointExchangeOrderList"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/commerce/point-exchange-orders/status": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 更新积分兑换订单状态 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["UpdatePointExchangeOrderStatusDto"]; + "text/json": components["schemas"]["UpdatePointExchangeOrderStatusDto"]; + "application/*+json": components["schemas"]["UpdatePointExchangeOrderStatusDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": unknown; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/student/points/summary": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询当前用户积分摘要 */ + get: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PointSummaryItem"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/student/points/tasks": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询当前可领取积分任务 */ + get: { + parameters: { + query?: { + /** @description 返回数量上限。 */ + Limit?: number | string; + /** @description 状态。 */ + Status?: string; + /** @description 地区 ID。 */ + RegionId?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PointListOfPointTaskItem"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/student/points/tasks/claim": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 领取积分任务奖励 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["ClaimPointTaskDto"]; + "text/json": components["schemas"]["ClaimPointTaskDto"]; + "application/*+json": components["schemas"]["ClaimPointTaskDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PointClaimItem"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/student/points/exchange-items": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询积分兑换项 */ + get: { + parameters: { + query?: { + /** @description 返回数量上限。 */ + Limit?: number | string; + /** @description 状态。 */ + Status?: string; + /** @description 地区 ID。 */ + RegionId?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PointListOfPointExchangeItemDto"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/student/points/exchange-orders": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询当前用户积分兑换订单 */ + get: { + parameters: { + query?: { + /** @description 返回数量上限。 */ + Limit?: number | string; + /** @description 状态。 */ + Status?: string; + /** @description 地区 ID。 */ + RegionId?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PointListOfPointExchangeOrderItem"]; + }; + }; + }; + }; + put?: never; + /** 创建积分兑换订单 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["CreatePointExchangeOrderDto"]; + "text/json": components["schemas"]["CreatePointExchangeOrderDto"]; + "application/*+json": components["schemas"]["CreatePointExchangeOrderDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PointExchangeOrderItem"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/student/learning/practice-sessions/report": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 获取练习会话报告 */ + get: { + parameters: { + query?: { + /** @description 练习会话 ID。 */ + PracticeSessionId?: string; + /** @description 练习蓝图 ID。 */ + BlueprintId?: string; + /** @description 模式。 */ + Mode?: string; + /** @description 状态。 */ + Status?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PracticeSessionReportItem"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/student/learning/practice-reports": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询练习报告列表 */ + get: { + parameters: { + query?: { + /** @description 练习会话 ID。 */ + PracticeSessionId?: string; + /** @description 练习蓝图 ID。 */ + BlueprintId?: string; + /** @description 模式。 */ + Mode?: string; + /** @description 状态。 */ + Status?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["LearningListOfPracticeSessionReportItem"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/student/learning/practice-sessions/history": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询练习历史 */ + get: { + parameters: { + query?: { + /** @description 练习会话 ID。 */ + PracticeSessionId?: string; + /** @description 练习蓝图 ID。 */ + BlueprintId?: string; + /** @description 模式。 */ + Mode?: string; + /** @description 状态。 */ + Status?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["LearningListOfPracticeHistoryItem"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/student/learning/practice-sessions": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 创建练习会话 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["CreatePracticeSessionDto"]; + "text/json": components["schemas"]["CreatePracticeSessionDto"]; + "application/*+json": components["schemas"]["CreatePracticeSessionDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PracticeSessionItem"]; + }; + }; + /** @description Conflict */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/student/learning/practice-sessions/detail": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 获取练习会话详情 */ + get: { + parameters: { + query?: { + /** @description 练习会话 ID。 */ + PracticeSessionId?: string; + /** @description 练习蓝图 ID。 */ + BlueprintId?: string; + /** @description 模式。 */ + Mode?: string; + /** @description 状态。 */ + Status?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PracticeSessionDetailItem"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/student/learning/practice-sessions/submit": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 提交练习会话并生成报告 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["SubmitPracticeSessionDto"]; + "text/json": components["schemas"]["SubmitPracticeSessionDto"]; + "application/*+json": components["schemas"]["SubmitPracticeSessionDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PracticeSessionReportItem"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/student/profile/me": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 获取当前学生资料 */ + get: { + parameters: { + query?: { + /** @description 最近记录数量上限。 */ + RecentLimit?: number | string; + /** @description 返回数量上限。 */ + Limit?: number | string; + /** @description 状态。 */ + Status?: string; + /** @description 类型。 */ + Type?: string; + /** @description 分类。 */ + Category?: string; + /** @description 是否包含锁定资源。 */ + IncludeLocked?: boolean; + /** @description 来源类型。 */ + SourceType?: string; + /** @description 开始时间。 */ + From?: string; + /** @description 结束时间。 */ + To?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["StudentProfileItem"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + /** 更新当前学生资料 */ + patch: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["UpdateProfileDto"]; + "text/json": components["schemas"]["UpdateProfileDto"]; + "application/*+json": components["schemas"]["UpdateProfileDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["StudentProfileItem"]; + }; + }; + }; + }; + trace?: never; + }; + "/api/student/profile/exam-countdowns": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询考试倒计时 */ + get: { + parameters: { + query?: { + /** @description 最近记录数量上限。 */ + RecentLimit?: number | string; + /** @description 返回数量上限。 */ + Limit?: number | string; + /** @description 状态。 */ + Status?: string; + /** @description 类型。 */ + Type?: string; + /** @description 分类。 */ + Category?: string; + /** @description 是否包含锁定资源。 */ + IncludeLocked?: boolean; + /** @description 来源类型。 */ + SourceType?: string; + /** @description 开始时间。 */ + From?: string; + /** @description 结束时间。 */ + To?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ExamCountdownList"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/student/profile/notifications": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询用户通知 */ + get: { + parameters: { + query?: { + /** @description 最近记录数量上限。 */ + RecentLimit?: number | string; + /** @description 返回数量上限。 */ + Limit?: number | string; + /** @description 状态。 */ + Status?: string; + /** @description 类型。 */ + Type?: string; + /** @description 分类。 */ + Category?: string; + /** @description 是否包含锁定资源。 */ + IncludeLocked?: boolean; + /** @description 来源类型。 */ + SourceType?: string; + /** @description 开始时间。 */ + From?: string; + /** @description 结束时间。 */ + To?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProfileNotificationList"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/student/profile/notifications/status": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 更新通知状态 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["NotificationStatusDto"]; + "text/json": components["schemas"]["NotificationStatusDto"]; + "application/*+json": components["schemas"]["NotificationStatusDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProfileNotificationList"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/student/profile/badges": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询徽章列表 */ + get: { + parameters: { + query?: { + /** @description 最近记录数量上限。 */ + RecentLimit?: number | string; + /** @description 返回数量上限。 */ + Limit?: number | string; + /** @description 状态。 */ + Status?: string; + /** @description 类型。 */ + Type?: string; + /** @description 分类。 */ + Category?: string; + /** @description 是否包含锁定资源。 */ + IncludeLocked?: boolean; + /** @description 来源类型。 */ + SourceType?: string; + /** @description 开始时间。 */ + From?: string; + /** @description 结束时间。 */ + To?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BadgeList"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/student/profile/feedbacks": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询反馈记录 */ + get: { + parameters: { + query?: { + /** @description 最近记录数量上限。 */ + RecentLimit?: number | string; + /** @description 返回数量上限。 */ + Limit?: number | string; + /** @description 状态。 */ + Status?: string; + /** @description 类型。 */ + Type?: string; + /** @description 分类。 */ + Category?: string; + /** @description 是否包含锁定资源。 */ + IncludeLocked?: boolean; + /** @description 来源类型。 */ + SourceType?: string; + /** @description 开始时间。 */ + From?: string; + /** @description 结束时间。 */ + To?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["FeedbackItem"][]; + }; + }; + }; + }; + put?: never; + /** 提交意见反馈 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["SubmitFeedbackDto"]; + "text/json": components["schemas"]["SubmitFeedbackDto"]; + "application/*+json": components["schemas"]["SubmitFeedbackDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["FeedbackItem"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/student/profile/check-in": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 每日签到 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CheckInResult"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/student/profile/score-events": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询积分流水 */ + get: { + parameters: { + query?: { + /** @description 最近记录数量上限。 */ + RecentLimit?: number | string; + /** @description 返回数量上限。 */ + Limit?: number | string; + /** @description 状态。 */ + Status?: string; + /** @description 类型。 */ + Type?: string; + /** @description 分类。 */ + Category?: string; + /** @description 是否包含锁定资源。 */ + IncludeLocked?: boolean; + /** @description 来源类型。 */ + SourceType?: string; + /** @description 开始时间。 */ + From?: string; + /** @description 结束时间。 */ + To?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProfileScoreEventList"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/content/questions": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 创建题目及首个版本 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["DirectQuestionWriteDto"]; + "text/json": components["schemas"]["DirectQuestionWriteDto"]; + "application/*+json": components["schemas"]["DirectQuestionWriteDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ContentManagementResultOfQuestionManagementItem"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + /** 更新题目并可选择创建新版本 */ + patch: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["DirectQuestionWriteDto"]; + "text/json": components["schemas"]["DirectQuestionWriteDto"]; + "application/*+json": components["schemas"]["DirectQuestionWriteDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ContentManagementResultOfQuestionManagementItem"]; + }; + }; + }; + }; + trace?: never; + }; + "/api/student/learning/favorites/questions": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询收藏题目 */ + get: { + parameters: { + query?: { + /** @description 返回数量上限。 */ + Limit?: number | string; + /** @description 状态。 */ + Status?: string; + /** @description 单元 ID。 */ + UnitId?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["LearningListOfFavoriteQuestionItem"]; + }; + }; + }; + }; + put?: never; + /** 收藏或取消收藏题目 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["QuestionActionDto"]; + "text/json": components["schemas"]["QuestionActionDto"]; + "application/*+json": components["schemas"]["QuestionActionDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["LearningActionResult"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/student/learning/wrong-questions": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询错题列表 */ + get: { + parameters: { + query?: { + /** @description 返回数量上限。 */ + Limit?: number | string; + /** @description 状态。 */ + Status?: string; + /** @description 单元 ID。 */ + UnitId?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["LearningListOfWrongQuestionItem"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/student/learning/wrong-questions/review-plan": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 生成错题复习计划 */ + get: { + parameters: { + query?: { + /** @description 返回数量上限。 */ + Limit?: number | string; + /** @description 状态。 */ + Status?: string; + /** @description 单元 ID。 */ + UnitId?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["WrongQuestionReviewPlan"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/student/learning/wrong-questions/resolve": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 将错题标记为已解决 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["QuestionActionDto"]; + "text/json": components["schemas"]["QuestionActionDto"]; + "application/*+json": components["schemas"]["QuestionActionDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["LearningActionResult"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/student/questions/videos": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询单道题目的解析视频 */ + get: { + parameters: { + query?: { + /** @description 题目 ID。 */ + QuestionId?: string; + /** @description 题目 ID 列表。 */ + QuestionIds?: string[]; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfQuestionVideoCatalogItem"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/student/questions/videos/batch": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 批量查询题目解析视频 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["QuestionVideoQueryDto"]; + "text/json": components["schemas"]["QuestionVideoQueryDto"]; + "application/*+json": components["schemas"]["QuestionVideoQueryDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfQuestionVideoCatalogItem"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/commerce/reconciliation/batches": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询对账批次 */ + get: { + parameters: { + query?: { + /** @description 服务提供方。 */ + Provider?: string; + /** @description 状态。 */ + Status?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + /** @description 用户 ID。 */ + UserId?: string; + /** @description 地区 ID。 */ + RegionId?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["TenantReconciliationBatchList"]; + }; + }; + }; + }; + put?: never; + /** 创建对账批次 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["CreateReconciliationBatchDto"]; + "text/json": components["schemas"]["CreateReconciliationBatchDto"]; + "application/*+json": components["schemas"]["CreateReconciliationBatchDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CommerceReconciliationBatch"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/commerce/reconciliation/issues": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询对账异常 */ + get: { + parameters: { + query?: { + /** @description 服务提供方。 */ + Provider?: string; + /** @description 状态。 */ + Status?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + /** @description 用户 ID。 */ + UserId?: string; + /** @description 地区 ID。 */ + RegionId?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["TenantReconciliationIssueList"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/commerce/reconciliation/items": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询对账明细 */ + get: { + parameters: { + query?: { + batchId?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["TenantReconciliationItemList"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/commerce/reconciliation/issues/events": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询对账工单事件 */ + get: { + parameters: { + query?: { + issueId?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["TenantReconciliationIssueEventList"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/commerce/reconciliation/issues/status": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 更新对账异常状态 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["UpdateReconciliationIssueDto"]; + "text/json": components["schemas"]["UpdateReconciliationIssueDto"]; + "application/*+json": components["schemas"]["UpdateReconciliationIssueDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CommerceReconciliationIssue"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/commerce/reconciliation/preview": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 预览支付渠道账单对账 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["PreviewReconciliationImportDto"]; + "text/json": components["schemas"]["PreviewReconciliationImportDto"]; + "application/*+json": components["schemas"]["PreviewReconciliationImportDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ReconciliationImportPreview"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/commerce/reconciliation/import": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 导入支付渠道账单并创建对账批次 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["PreviewReconciliationImportDto"]; + "text/json": components["schemas"]["PreviewReconciliationImportDto"]; + "application/*+json": components["schemas"]["PreviewReconciliationImportDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CommerceReconciliationBatch"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/commerce/reconciliation/provider-bills/jobs": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询渠道账单下载任务 */ + get: { + parameters: { + query?: { + /** @description 服务提供方。 */ + Provider?: string; + /** @description 状态。 */ + Status?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + /** @description 用户 ID。 */ + UserId?: string; + /** @description 地区 ID。 */ + RegionId?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BackgroundJobItem"][]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/commerce/reconciliation/provider-bills/request": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 创建渠道官方账单下载任务 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["RequestProviderBillJobDto"]; + "text/json": components["schemas"]["RequestProviderBillJobDto"]; + "application/*+json": components["schemas"]["RequestProviderBillJobDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BackgroundJobItem"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/student/referral/invite-code": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 生成或查询当前成员邀请码 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["ReferralInviteDto"]; + "text/json": components["schemas"]["ReferralInviteDto"]; + "application/*+json": components["schemas"]["ReferralInviteDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ReferralInviteItem"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/student/referral/resolve": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 解析推荐邀请码 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["ResolveReferralDto"]; + "text/json": components["schemas"]["ResolveReferralDto"]; + "application/*+json": components["schemas"]["ResolveReferralDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ReferralResolutionItem"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/student/referral/track-event": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 记录推荐行为 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["TrackReferralEventDto"]; + "text/json": components["schemas"]["TrackReferralEventDto"]; + "application/*+json": components["schemas"]["TrackReferralEventDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ReferralTrackResult"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/student/referral/bind": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 绑定当前用户推荐归属 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["BindReferralDto"]; + "text/json": components["schemas"]["BindReferralDto"]; + "application/*+json": components["schemas"]["BindReferralDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ReferralBindResult"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/student/referral/qrcode": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 生成或查询推广二维码 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["ReferralQrcodeDto"]; + "text/json": components["schemas"]["ReferralQrcodeDto"]; + "application/*+json": components["schemas"]["ReferralQrcodeDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ReferralQrcodeItem"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/referral/stats": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询推荐人个人统计 */ + get: { + parameters: { + query?: { + /** @description 推荐人用户 ID。 */ + ReferrerUserId?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ReferralStatsItem"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/referral/sales-stats": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询销售推荐统计排行 */ + get: { + parameters: { + query?: { + /** @description 推荐人用户 ID。 */ + ReferrerUserId?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ReferralListOfReferralStatsItem"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/referral/conversion-report": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询推荐转化报告 */ + get: { + parameters: { + query?: { + /** @description 推荐人用户 ID。 */ + ReferrerUserId?: string; + /** @description 开始日期,格式为 yyyy-MM-dd。 */ + StartDate?: string; + /** @description 结束日期,格式为 yyyy-MM-dd。 */ + EndDate?: string; + /** @description 天数。 */ + Days?: number | string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ReferralConversionReport"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/referral/sales-clients": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询推荐人名下客户 */ + get: { + parameters: { + query?: { + /** @description 推荐人用户 ID。 */ + ReferrerUserId?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ReferralListOfReferralLeadItem"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/referral/manual-bind": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 人工调整学生推荐归属 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["ManualBindReferralDto"]; + "text/json": components["schemas"]["ManualBindReferralDto"]; + "application/*+json": components["schemas"]["ManualBindReferralDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ReferralBindResult"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/referral/team": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询推荐团队成员 */ + get: { + parameters: { + query?: { + /** @description 上级成员用户 ID。 */ + LeaderUserId?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ReferralListOfReferralTeamItem"]; + }; + }; + }; + }; + /** 新增或更新推荐团队关系 */ + put: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["UpsertReferralTeamDto"]; + "text/json": components["schemas"]["UpsertReferralTeamDto"]; + "application/*+json": components["schemas"]["UpsertReferralTeamDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ReferralTeamItem"]; + }; + }; + }; + }; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/commerce/refunds": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询退款申请 */ + get: { + parameters: { + query?: { + /** @description 服务提供方。 */ + Provider?: string; + /** @description 状态。 */ + Status?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + /** @description 用户 ID。 */ + UserId?: string; + /** @description 地区 ID。 */ + RegionId?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["TenantRefundList"]; + }; + }; + }; + }; + put?: never; + /** 创建退款申请 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["CreateRefundRequestDto"]; + "text/json": components["schemas"]["CreateRefundRequestDto"]; + "application/*+json": components["schemas"]["CreateRefundRequestDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CommerceRefundRequest"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/commerce/refunds/status": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 更新退款状态 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["UpdateRefundStatusDto"]; + "text/json": components["schemas"]["UpdateRefundStatusDto"]; + "application/*+json": components["schemas"]["UpdateRefundStatusDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CommerceRefundRequest"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/commerce/refunds/{refundRequestId}/events": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询退款事件 */ + get: { + parameters: { + query?: never; + header?: never; + path: { + refundRequestId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["TenantRefundEventList"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/public/runtime/bootstrap": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 获取租户前端运行时配置 */ + get: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["TenantRuntimeBootstrap"]; + }; + }; + /** @description Not Modified */ + 304: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": unknown; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/public/scoreline/fields": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询分数线字段配置 */ + get: { + parameters: { + query?: { + /** @description 租户编码。 */ + TenantCode?: string; + /** @description 地区 ID。 */ + RegionId?: string; + /** @description 院校 ID。 */ + SchoolId?: string; + /** @description 专业 ID。 */ + MajorId?: string; + /** @description 关键字。 */ + Keyword?: string; + /** @description 年份。 */ + Year?: number | string; + /** @description 页码。 */ + Page?: number | string; + /** @description 每页数量。 */ + PageSize?: number | string; + /** @description 返回数量上限。 */ + Limit?: number | string; + /** @description 版本化的不透明游标,仅用于游标分页接口。 */ + Cursor?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfScorelineFieldItem"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/public/scoreline/records": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 分页查询分数线记录 */ + get: { + parameters: { + query?: { + /** @description 租户编码。 */ + TenantCode?: string; + /** @description 地区 ID。 */ + RegionId?: string; + /** @description 院校 ID。 */ + SchoolId?: string; + /** @description 专业 ID。 */ + MajorId?: string; + /** @description 关键字。 */ + Keyword?: string; + /** @description 年份。 */ + Year?: number | string; + /** @description 页码。 */ + Page?: number | string; + /** @description 每页数量。 */ + PageSize?: number | string; + /** @description 返回数量上限。 */ + Limit?: number | string; + /** @description 版本化的不透明游标,仅用于游标分页接口。 */ + Cursor?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ScorelineRecordPage"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/public/scoreline/records/cursor": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 游标分页查询分数线记录 */ + get: { + parameters: { + query?: { + /** @description 租户编码。 */ + TenantCode?: string; + /** @description 地区 ID。 */ + RegionId?: string; + /** @description 院校 ID。 */ + SchoolId?: string; + /** @description 专业 ID。 */ + MajorId?: string; + /** @description 关键字。 */ + Keyword?: string; + /** @description 年份。 */ + Year?: number | string; + /** @description 页码。 */ + Page?: number | string; + /** @description 每页数量。 */ + PageSize?: number | string; + /** @description 返回数量上限。 */ + Limit?: number | string; + /** @description 版本化的不透明游标,仅用于游标分页接口。 */ + Cursor?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ScorelineRecordCursorPage"]; + }; + }; + /** @description Bad Request */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/public/scoreline/trend": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询历年分数线趋势 */ + get: { + parameters: { + query?: { + /** @description 租户编码。 */ + TenantCode?: string; + /** @description 地区 ID。 */ + RegionId?: string; + /** @description 院校 ID。 */ + SchoolId?: string; + /** @description 专业 ID。 */ + MajorId?: string; + /** @description 关键字。 */ + Keyword?: string; + /** @description 年份。 */ + Year?: number | string; + /** @description 页码。 */ + Page?: number | string; + /** @description 每页数量。 */ + PageSize?: number | string; + /** @description 返回数量上限。 */ + Limit?: number | string; + /** @description 版本化的不透明游标,仅用于游标分页接口。 */ + Cursor?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfScorelineRecordItem"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/public/scoreline/years": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询分数线可用年份 */ + get: { + parameters: { + query?: { + /** @description 租户编码。 */ + TenantCode?: string; + /** @description 地区 ID。 */ + RegionId?: string; + /** @description 院校 ID。 */ + SchoolId?: string; + /** @description 专业 ID。 */ + MajorId?: string; + /** @description 关键字。 */ + Keyword?: string; + /** @description 年份。 */ + Year?: number | string; + /** @description 页码。 */ + Page?: number | string; + /** @description 每页数量。 */ + PageSize?: number | string; + /** @description 返回数量上限。 */ + Limit?: number | string; + /** @description 版本化的不透明游标,仅用于游标分页接口。 */ + Cursor?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfint"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/content/scoreline/fields": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询管理侧分数线字段 */ + get: { + parameters: { + query?: { + /** @description 地区 ID。 */ + RegionId?: string; + /** @description 内容入口 ID。 */ + EntryId?: string; + /** @description 内容节点 ID。 */ + ContentNodeId?: string; + /** @description 父节点 ID。 */ + ParentId?: string; + /** @description 科目 ID。 */ + SubjectId?: string; + /** @description 章节 ID。 */ + ChapterId?: string; + /** @description 单元 ID。 */ + UnitId?: string; + /** @description 院校 ID。 */ + SchoolId?: string; + /** @description 专业 ID。 */ + MajorId?: string; + /** @description 题目 ID。 */ + QuestionId?: string; + /** @description 状态。 */ + Status?: string; + /** @description 关键字。 */ + Keyword?: string; + /** @description 年份。 */ + Year?: number | string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfScorelineField"]; + }; + }; + }; + }; + /** 新增或更新动态分数线字段 */ + put: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["DirectScorelineFieldDto"]; + "text/json": components["schemas"]["DirectScorelineFieldDto"]; + "application/*+json": components["schemas"]["DirectScorelineFieldDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ContentManagementResultOfScorelineField"]; + }; + }; + }; + }; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/content/scoreline/records": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询管理侧分数线记录 */ + get: { + parameters: { + query?: { + /** @description 地区 ID。 */ + RegionId?: string; + /** @description 内容入口 ID。 */ + EntryId?: string; + /** @description 内容节点 ID。 */ + ContentNodeId?: string; + /** @description 父节点 ID。 */ + ParentId?: string; + /** @description 科目 ID。 */ + SubjectId?: string; + /** @description 章节 ID。 */ + ChapterId?: string; + /** @description 单元 ID。 */ + UnitId?: string; + /** @description 院校 ID。 */ + SchoolId?: string; + /** @description 专业 ID。 */ + MajorId?: string; + /** @description 题目 ID。 */ + QuestionId?: string; + /** @description 状态。 */ + Status?: string; + /** @description 关键字。 */ + Keyword?: string; + /** @description 年份。 */ + Year?: number | string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfScorelineRecord"]; + }; + }; + }; + }; + /** 新增或更新分数线记录 */ + put: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["DirectScorelineRecordDto"]; + "text/json": components["schemas"]["DirectScorelineRecordDto"]; + "application/*+json": components["schemas"]["DirectScorelineRecordDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ContentManagementResultOfScorelineRecord"]; + }; + }; + }; + }; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/content/scoreline/years": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询分数线年份 */ + get: { + parameters: { + query?: { + /** @description 地区 ID。 */ + RegionId?: string; + /** @description 内容入口 ID。 */ + EntryId?: string; + /** @description 内容节点 ID。 */ + ContentNodeId?: string; + /** @description 父节点 ID。 */ + ParentId?: string; + /** @description 科目 ID。 */ + SubjectId?: string; + /** @description 章节 ID。 */ + ChapterId?: string; + /** @description 单元 ID。 */ + UnitId?: string; + /** @description 院校 ID。 */ + SchoolId?: string; + /** @description 专业 ID。 */ + MajorId?: string; + /** @description 题目 ID。 */ + QuestionId?: string; + /** @description 状态。 */ + Status?: string; + /** @description 关键字。 */ + Keyword?: string; + /** @description 年份。 */ + Year?: number | string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfint"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/content/scoreline/trend": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询分数线趋势摘要 */ + get: { + parameters: { + query?: { + /** @description 地区 ID。 */ + RegionId?: string; + /** @description 内容入口 ID。 */ + EntryId?: string; + /** @description 内容节点 ID。 */ + ContentNodeId?: string; + /** @description 父节点 ID。 */ + ParentId?: string; + /** @description 科目 ID。 */ + SubjectId?: string; + /** @description 章节 ID。 */ + ChapterId?: string; + /** @description 单元 ID。 */ + UnitId?: string; + /** @description 院校 ID。 */ + SchoolId?: string; + /** @description 专业 ID。 */ + MajorId?: string; + /** @description 题目 ID。 */ + QuestionId?: string; + /** @description 状态。 */ + Status?: string; + /** @description 关键字。 */ + Keyword?: string; + /** @description 年份。 */ + Year?: number | string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfScorelineTrendItem"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/taxonomy/nodes": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询租户分类节点 */ + get: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["TaxonomyNodeItem"][]; + }; + }; + }; + }; + put?: never; + /** 创建租户分类节点 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["CreateTaxonomyNodeDto"]; + "text/json": components["schemas"]["CreateTaxonomyNodeDto"]; + "application/*+json": components["schemas"]["CreateTaxonomyNodeDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["TaxonomyNodeItem"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/overview": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询租户后台运营概览 */ + get: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["TenantAdminOverviewItem"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/access/ui-bootstrap": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * 查询租户后台菜单与权限 + * @description 返回当前租户管理员可见的后台菜单、权限和模块启用状态。 + */ + get: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["BackofficeUiBootstrap"]; + "application/json": components["schemas"]["BackofficeUiBootstrap"]; + "text/json": components["schemas"]["BackofficeUiBootstrap"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/access/bootstrap": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询租户角色管理初始化数据 */ + get: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["BackofficeBootstrap"]; + "application/json": components["schemas"]["BackofficeBootstrap"]; + "text/json": components["schemas"]["BackofficeBootstrap"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/access/roles": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 创建或更新租户后台角色 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["UpsertBackofficeRoleDto"]; + "text/json": components["schemas"]["UpsertBackofficeRoleDto"]; + "application/*+json": components["schemas"]["UpsertBackofficeRoleDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["BackofficeRoleItem"]; + "application/json": components["schemas"]["BackofficeRoleItem"]; + "text/json": components["schemas"]["BackofficeRoleItem"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/access/roles/{roleId}/bindings": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + /** 替换租户后台角色权限绑定 */ + put: { + parameters: { + query?: never; + header?: never; + path: { + roleId: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["ReplaceRoleBindingsDto"]; + "text/json": components["schemas"]["ReplaceRoleBindingsDto"]; + "application/*+json": components["schemas"]["ReplaceRoleBindingsDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["BackofficeRoleItem"]; + "application/json": components["schemas"]["BackofficeRoleItem"]; + "text/json": components["schemas"]["BackofficeRoleItem"]; + }; + }; + }; + }; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/access/users/{userId}/roles": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + /** 替换租户用户后台角色 */ + put: { + parameters: { + query?: never; + header?: never; + path: { + userId: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["ReplaceUserRolesDto"]; + "text/json": components["schemas"]["ReplaceUserRolesDto"]; + "application/*+json": components["schemas"]["ReplaceUserRolesDto"]; + }; + }; + responses: { + /** @description No Content */ + 204: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + }; + }; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/billing/catalog": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询租户可购买 SaaS 目录 */ + get: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["TenantBillingCatalog"]; + "application/json": components["schemas"]["TenantBillingCatalog"]; + "text/json": components["schemas"]["TenantBillingCatalog"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/billing/quotes": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 创建租户账务报价 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["CreatePlatformBillingQuoteDto"]; + "text/json": components["schemas"]["CreatePlatformBillingQuoteDto"]; + "application/*+json": components["schemas"]["CreatePlatformBillingQuoteDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["PlatformBillingQuoteView"]; + "application/json": components["schemas"]["PlatformBillingQuoteView"]; + "text/json": components["schemas"]["PlatformBillingQuoteView"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/billing/orders": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询租户账务订单 */ + get: { + parameters: { + query?: { + limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["PlatformBillingOrderView"][]; + "application/json": components["schemas"]["PlatformBillingOrderView"][]; + "text/json": components["schemas"]["PlatformBillingOrderView"][]; + }; + }; + }; + }; + put?: never; + /** 创建租户账务订单 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["CreatePlatformBillingOrderDto"]; + "text/json": components["schemas"]["CreatePlatformBillingOrderDto"]; + "application/*+json": components["schemas"]["CreatePlatformBillingOrderDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["PlatformBillingOrderView"]; + "application/json": components["schemas"]["PlatformBillingOrderView"]; + "text/json": components["schemas"]["PlatformBillingOrderView"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/billing/orders/{orderNo}/payments": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 创建租户账务订单支付 */ + post: { + parameters: { + query?: never; + header?: never; + path: { + orderNo: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["CreatePlatformBillingPaymentDto"]; + "text/json": components["schemas"]["CreatePlatformBillingPaymentDto"]; + "application/*+json": components["schemas"]["CreatePlatformBillingPaymentDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["PlatformBillingPaymentView"]; + "application/json": components["schemas"]["PlatformBillingPaymentView"]; + "text/json": components["schemas"]["PlatformBillingPaymentView"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/billing/orders/{orderNo}/cancel": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 取消待支付租户账务订单 */ + post: { + parameters: { + query?: never; + header?: never; + path: { + orderNo: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["PlatformBillingOrderView"]; + "application/json": components["schemas"]["PlatformBillingOrderView"]; + "text/json": components["schemas"]["PlatformBillingOrderView"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/billing/orders/{orderNo}": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询租户账务订单详情 */ + get: { + parameters: { + query?: never; + header?: never; + path: { + orderNo: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["PlatformBillingOrderView"]; + "application/json": components["schemas"]["PlatformBillingOrderView"]; + "text/json": components["schemas"]["PlatformBillingOrderView"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/billing/subscription": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询当前租户 SaaS 订阅 */ + get: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["TenantSubscriptionView"]; + "application/json": components["schemas"]["TenantSubscriptionView"]; + "text/json": components["schemas"]["TenantSubscriptionView"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/billing/subscription/change": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 变更当前租户 SaaS 订阅 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["ChangeTenantSubscriptionDto"]; + "text/json": components["schemas"]["ChangeTenantSubscriptionDto"]; + "application/*+json": components["schemas"]["ChangeTenantSubscriptionDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["PlatformBillingOrderView"]; + "application/json": components["schemas"]["PlatformBillingOrderView"]; + "text/json": components["schemas"]["PlatformBillingOrderView"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/billing/subscription/renew": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 续费当前租户 SaaS 订阅 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["IdempotentTenantBillingDto"]; + "text/json": components["schemas"]["IdempotentTenantBillingDto"]; + "application/*+json": components["schemas"]["IdempotentTenantBillingDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["PlatformBillingOrderView"]; + "application/json": components["schemas"]["PlatformBillingOrderView"]; + "text/json": components["schemas"]["PlatformBillingOrderView"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/billing/subscription/cancel": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 取消当前租户 SaaS 订阅 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["TenantSubscriptionView"]; + "application/json": components["schemas"]["TenantSubscriptionView"]; + "text/json": components["schemas"]["TenantSubscriptionView"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/billing/usage": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询当前租户功能用量 */ + get: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["FeatureQuotaSnapshot"][]; + "application/json": components["schemas"]["FeatureQuotaSnapshot"][]; + "text/json": components["schemas"]["FeatureQuotaSnapshot"][]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/billing/invoices": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询当前租户发票 */ + get: { + parameters: { + query?: { + limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["PlatformBillingInvoice"][]; + "application/json": components["schemas"]["PlatformBillingInvoice"][]; + "text/json": components["schemas"]["PlatformBillingInvoice"][]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/billing/receivables": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询当前租户应收账单 */ + get: { + parameters: { + query?: { + limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["TenantReceivableView"][]; + "application/json": components["schemas"]["TenantReceivableView"][]; + "text/json": components["schemas"]["TenantReceivableView"][]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/billing/refunds": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询当前租户 SaaS 退款 */ + get: { + parameters: { + query?: { + limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["PlatformBillingRefund"][]; + "application/json": components["schemas"]["PlatformBillingRefund"][]; + "text/json": components["schemas"]["PlatformBillingRefund"][]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/classes": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询租户班级 */ + get: { + parameters: { + query?: { + /** @description 地区 ID。 */ + RegionId?: string; + /** @description 状态。 */ + Status?: string; + /** @description 关键字。 */ + Keyword?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["TenantAdminClassList"]; + }; + }; + }; + }; + /** 新增或更新租户班级 */ + put: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["UpsertTenantAdminClassDto"]; + "text/json": components["schemas"]["UpsertTenantAdminClassDto"]; + "application/*+json": components["schemas"]["UpsertTenantAdminClassDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ContentManagementResultOfTenantAdminClassItem"]; + }; + }; + }; + }; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/classes/disable": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 停用租户班级 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": string; + "text/json": string; + "application/*+json": string; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ContentManagementResultOfTenantAdminClassItem"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/classes/members": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询班级成员 */ + get: { + parameters: { + query?: { + /** @description 班级 ID。 */ + ClassId?: string; + /** @description 成员类型。 */ + MemberType?: string; + /** @description 状态。 */ + Status?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfTenantAdminClassMemberItem"]; + }; + }; + }; + }; + /** 新增或更新班级成员 */ + put: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["UpsertTenantAdminClassMemberDto"]; + "text/json": components["schemas"]["UpsertTenantAdminClassMemberDto"]; + "application/*+json": components["schemas"]["UpsertTenantAdminClassMemberDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ContentManagementResultOfTenantAdminClassMemberItem"]; + }; + }; + }; + }; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/classes/members/remove": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 移除班级成员 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["RemoveTenantAdminClassMemberDto"]; + "text/json": components["schemas"]["RemoveTenantAdminClassMemberDto"]; + "application/*+json": components["schemas"]["RemoveTenantAdminClassMemberDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ContentManagementResultOfTenantAdminClassMemberItem"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/content/entries": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询租户内容入口 */ + get: { + parameters: { + query?: { + /** @description 地区 ID。 */ + RegionId?: string; + /** @description 内容入口 ID。 */ + EntryId?: string; + /** @description 节点 ID。 */ + NodeId?: string; + /** @description 题集 ID。 */ + CollectionId?: string; + /** @description 父节点 ID;传 root 表示根节点。 */ + ParentId?: string; + /** @description 入口类型。 */ + EntryType?: string; + /** @description 题集类型。 */ + CollectionType?: string; + /** @description 模式。 */ + Mode?: string; + /** @description 标记类型。 */ + MarkerType?: string; + /** @description 关键字。 */ + Keyword?: string; + /** @description 是否包含停用数据。 */ + IncludeInactive?: boolean; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfContentEntryManagementItem"]; + }; + }; + }; + }; + put?: never; + /** 创建或更新内容入口 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["UpsertContentEntryDto"]; + "text/json": components["schemas"]["UpsertContentEntryDto"]; + "application/*+json": components["schemas"]["UpsertContentEntryDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ContentManagementResultOfContentEntryManagementItem"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/content/nodes": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询租户内容节点 */ + get: { + parameters: { + query?: { + /** @description 地区 ID。 */ + RegionId?: string; + /** @description 内容入口 ID。 */ + EntryId?: string; + /** @description 节点 ID。 */ + NodeId?: string; + /** @description 题集 ID。 */ + CollectionId?: string; + /** @description 父节点 ID;传 root 表示根节点。 */ + ParentId?: string; + /** @description 入口类型。 */ + EntryType?: string; + /** @description 题集类型。 */ + CollectionType?: string; + /** @description 模式。 */ + Mode?: string; + /** @description 标记类型。 */ + MarkerType?: string; + /** @description 关键字。 */ + Keyword?: string; + /** @description 是否包含停用数据。 */ + IncludeInactive?: boolean; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfContentNodeManagementItem"]; + }; + }; + }; + }; + put?: never; + /** 创建或更新内容节点 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["UpsertContentNodeDto"]; + "text/json": components["schemas"]["UpsertContentNodeDto"]; + "application/*+json": components["schemas"]["UpsertContentNodeDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ContentManagementResultOfContentNodeManagementItem"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/content/question-collections": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询租户题集 */ + get: { + parameters: { + query?: { + /** @description 地区 ID。 */ + RegionId?: string; + /** @description 内容入口 ID。 */ + EntryId?: string; + /** @description 节点 ID。 */ + NodeId?: string; + /** @description 题集 ID。 */ + CollectionId?: string; + /** @description 父节点 ID;传 root 表示根节点。 */ + ParentId?: string; + /** @description 入口类型。 */ + EntryType?: string; + /** @description 题集类型。 */ + CollectionType?: string; + /** @description 模式。 */ + Mode?: string; + /** @description 标记类型。 */ + MarkerType?: string; + /** @description 关键字。 */ + Keyword?: string; + /** @description 是否包含停用数据。 */ + IncludeInactive?: boolean; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfQuestionCollectionManagementItem"]; + }; + }; + }; + }; + put?: never; + /** 创建或更新题集 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["UpsertQuestionCollectionDto"]; + "text/json": components["schemas"]["UpsertQuestionCollectionDto"]; + "application/*+json": components["schemas"]["UpsertQuestionCollectionDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ContentManagementResultOfQuestionCollectionManagementItem"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/content/question-collections/items/replace": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 替换题集题目 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["ReplaceCollectionItemsDto"]; + "text/json": components["schemas"]["ReplaceCollectionItemsDto"]; + "application/*+json": components["schemas"]["ReplaceCollectionItemsDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CollectionItemsReplaceResult"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/content/practice-blueprints": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询练习蓝图 */ + get: { + parameters: { + query?: { + /** @description 地区 ID。 */ + RegionId?: string; + /** @description 内容入口 ID。 */ + EntryId?: string; + /** @description 节点 ID。 */ + NodeId?: string; + /** @description 题集 ID。 */ + CollectionId?: string; + /** @description 父节点 ID;传 root 表示根节点。 */ + ParentId?: string; + /** @description 入口类型。 */ + EntryType?: string; + /** @description 题集类型。 */ + CollectionType?: string; + /** @description 模式。 */ + Mode?: string; + /** @description 标记类型。 */ + MarkerType?: string; + /** @description 关键字。 */ + Keyword?: string; + /** @description 是否包含停用数据。 */ + IncludeInactive?: boolean; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfPracticeBlueprintManagementItem"]; + }; + }; + }; + }; + put?: never; + /** 创建或更新练习蓝图 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["UpsertPracticeBlueprintDto"]; + "text/json": components["schemas"]["UpsertPracticeBlueprintDto"]; + "application/*+json": components["schemas"]["UpsertPracticeBlueprintDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ContentManagementResultOfPracticeBlueprintManagementItem"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/content/imports/field-mapping": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询导入字段映射 */ + get: { + parameters: { + query?: { + /** @description 导入Type。 */ + ImportType?: string; + /** @description 导出格式。 */ + Format?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ImportFieldMappingItem"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/content/imports/templates": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 获取内容导入模板 */ + get: { + parameters: { + query?: { + /** @description 导入Type。 */ + ImportType?: string; + /** @description 导出格式。 */ + Format?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ImportTemplateItem"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/content/assets": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询租户内容资产 */ + get: { + parameters: { + query?: { + /** @description 地区 ID。 */ + RegionId?: string; + /** @description 科目 ID。 */ + SubjectId?: string; + /** @description 分类 ID。 */ + CategoryId?: string; + /** @description 内容节点 ID。 */ + ContentNodeId?: string; + /** @description 资产类型。 */ + AssetType?: string; + /** @description 分类。 */ + Category?: string; + /** @description 上传状态。 */ + UploadStatus?: string; + /** @description 安全扫描状态。 */ + SecurityScanStatus?: string; + /** @description 关键字。 */ + Keyword?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfContentAssetManagementItem"]; + }; + }; + }; + }; + /** 新增或更新内容资产 */ + put: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["UpsertAssetDto"]; + "text/json": components["schemas"]["UpsertAssetDto"]; + "application/*+json": components["schemas"]["UpsertAssetDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ContentManagementResultOfContentAssetManagementItem"]; + }; + }; + }; + }; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/content/assets/access-events": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询资产访问审计事件 */ + get: { + parameters: { + query?: { + /** @description 资产 ID。 */ + AssetId?: string; + /** @description 用户 ID。 */ + UserId?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfContentAssetAccessEventItem"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/content/assets/security-scan-events": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询资产安全扫描事件 */ + get: { + parameters: { + query?: { + /** @description 资产 ID。 */ + AssetId?: string; + /** @description 用户 ID。 */ + UserId?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfContentAssetSecurityScanEventItem"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/content/assets/uploads/sign": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 创建资产上传签名 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["AssetUploadSignDto"]; + "text/json": components["schemas"]["AssetUploadSignDto"]; + "application/*+json": components["schemas"]["AssetUploadSignDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["AssetUploadSignResult"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + /** @description Forbidden */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/content/assets/uploads/confirm": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 确认资产上传完成 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["AssetUploadConfirmDto"]; + "text/json": components["schemas"]["AssetUploadConfirmDto"]; + "application/*+json": components["schemas"]["AssetUploadConfirmDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["AssetUploadConfirmResult"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + /** @description Conflict */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/content/assets/{assetId}": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + post?: never; + /** 归档内容资产 */ + delete: { + parameters: { + query?: never; + header?: never; + path: { + assetId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ContentManagementResultOfContentAssetManagementItem"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/content/assets/sign-download": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 签发管理侧资产下载地址 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["AssetAccessSignDto"]; + "text/json": components["schemas"]["AssetAccessSignDto"]; + "application/*+json": components["schemas"]["AssetAccessSignDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["AssetManagementSignedAccessResult"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/content/assets/sign-preview": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 签发管理侧资产预览地址 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["AssetAccessSignDto"]; + "text/json": components["schemas"]["AssetAccessSignDto"]; + "application/*+json": components["schemas"]["AssetAccessSignDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["AssetManagementSignedAccessResult"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/content/import-jobs": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询内容导入任务 */ + get: { + parameters: { + query?: { + /** @description 状态。 */ + Status?: string; + /** @description 导入Type。 */ + ImportType?: string; + /** @description 来源格式。 */ + SourceFormat?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfContentImportJobItem"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/content/import-jobs/{jobId}": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询内容导入任务详情 */ + get: { + parameters: { + query?: never; + header?: never; + path: { + jobId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ContentImportJobDetail"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/domains": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询租户域名 */ + get: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfTenantDomainItem"]; + }; + }; + }; + }; + put?: never; + /** 添加租户域名 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["CreateTenantDomainDto"]; + "text/json": components["schemas"]["CreateTenantDomainDto"]; + "application/*+json": components["schemas"]["CreateTenantDomainDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ContentManagementResultOfTenantDomainItem"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/auth-providers": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询租户登录 Provider 公开配置 */ + get: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfTenantIdentityProviderItem"]; + }; + }; + }; + }; + /** 新增或更新租户登录 Provider */ + put: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["UpsertTenantIdentityProviderDto"]; + "text/json": components["schemas"]["UpsertTenantIdentityProviderDto"]; + "application/*+json": components["schemas"]["UpsertTenantIdentityProviderDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ContentManagementResultOfTenantIdentityProviderItem"]; + }; + }; + }; + }; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/badges": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询租户勋章 */ + get: { + parameters: { + query?: { + /** @description 分类。 */ + Category?: string; + /** @description 是否包含停用数据。 */ + IncludeInactive?: boolean; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfTenantAdminBadgeItem"]; + }; + }; + }; + }; + /** 新增或更新租户勋章 */ + put: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["UpsertTenantAdminBadgeDto"]; + "text/json": components["schemas"]["UpsertTenantAdminBadgeDto"]; + "application/*+json": components["schemas"]["UpsertTenantAdminBadgeDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ContentManagementResultOfTenantAdminBadgeItem"]; + }; + }; + }; + }; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/badge-grants": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询勋章发放记录 */ + get: { + parameters: { + query?: { + /** @description 用户 ID。 */ + UserId?: string; + /** @description 徽章 ID。 */ + BadgeId?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfTenantAdminBadgeGrantItem"]; + }; + }; + }; + }; + put?: never; + /** 向租户成员发放勋章 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["GrantTenantAdminBadgeDto"]; + "text/json": components["schemas"]["GrantTenantAdminBadgeDto"]; + "application/*+json": components["schemas"]["GrantTenantAdminBadgeDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ContentManagementResultOfTenantAdminBadgeGrantItem"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/notifications": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询用户站内通知 */ + get: { + parameters: { + query?: { + /** @description 用户 ID。 */ + UserId?: string; + /** @description 状态。 */ + Status?: string; + /** @description 通知类型。 */ + NotificationType?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfTenantAdminNotificationItem"]; + }; + }; + }; + }; + /** 新增或更新用户站内通知 */ + put: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["UpsertTenantAdminNotificationDto"]; + "text/json": components["schemas"]["UpsertTenantAdminNotificationDto"]; + "application/*+json": components["schemas"]["UpsertTenantAdminNotificationDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ContentManagementResultOfTenantAdminNotificationItem"]; + }; + }; + }; + }; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/feedbacks": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询用户反馈 */ + get: { + parameters: { + query?: { + /** @description 用户 ID。 */ + UserId?: string; + /** @description 状态。 */ + Status?: string; + /** @description 类型。 */ + Type?: string; + /** @description 关键字。 */ + Keyword?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfTenantAdminFeedbackItem"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/feedbacks/status": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 处理用户反馈 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["UpdateTenantAdminFeedbackDto"]; + "text/json": components["schemas"]["UpdateTenantAdminFeedbackDto"]; + "application/*+json": components["schemas"]["UpdateTenantAdminFeedbackDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ContentManagementResultOfTenantAdminFeedbackItem"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/frontend-config": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询租户前端配置 */ + get: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["TenantFrontendConfigItem"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/frontend-config/draft": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + /** 保存租户前端配置草稿 */ + put: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["SaveTenantFrontendConfigDraftDto"]; + "text/json": components["schemas"]["SaveTenantFrontendConfigDraftDto"]; + "application/*+json": components["schemas"]["SaveTenantFrontendConfigDraftDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["TenantFrontendConfigItem"]; + }; + }; + }; + }; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/frontend-config/publish": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 发布租户前端配置 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["PublishTenantFrontendConfigDto"]; + "text/json": components["schemas"]["PublishTenantFrontendConfigDto"]; + "application/*+json": components["schemas"]["PublishTenantFrontendConfigDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["TenantFrontendConfigItem"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/members": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询租户成员 */ + get: { + parameters: { + query?: { + /** @description 角色。 */ + Role?: string; + /** @description 状态。 */ + Status?: string; + /** @description 关键字。 */ + Keyword?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfTenantAdminMemberItem"]; + }; + }; + }; + }; + /** 新增或更新租户成员 */ + put: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["UpsertTenantAdminMemberDto"]; + "text/json": components["schemas"]["UpsertTenantAdminMemberDto"]; + "application/*+json": components["schemas"]["UpsertTenantAdminMemberDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ContentManagementResultOfTenantAdminMemberItem"]; + }; + }; + }; + }; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/members/disable": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 停用租户成员并撤销会话 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["DisableTenantAdminMemberDto"]; + "text/json": components["schemas"]["DisableTenantAdminMemberDto"]; + "application/*+json": components["schemas"]["DisableTenantAdminMemberDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ContentManagementResultOfTenantAdminMemberItem"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/members/{userId}/password-reset": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 为租户成员设置一次性临时密码 */ + post: { + parameters: { + query?: never; + header?: never; + path: { + userId: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["AdministrativePasswordResetDto"]; + "text/json": components["schemas"]["AdministrativePasswordResetDto"]; + "application/*+json": components["schemas"]["AdministrativePasswordResetDto"]; + }; + }; + responses: { + /** @description No Content */ + 204: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": unknown; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/onboarding/status": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询租户开通引导状态 */ + get: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["TenantOnboardingStatus"]; + "application/json": components["schemas"]["TenantOnboardingStatus"]; + "text/json": components["schemas"]["TenantOnboardingStatus"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/tenants": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询平台租户列表 */ + get: { + parameters: { + query?: { + /** @description 状态。 */ + Status?: string; + /** @description 搜索关键字。 */ + Search?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PlatformTenantList"]; + }; + }; + }; + }; + put?: never; + /** 创建平台租户 */ + post: { + parameters: { + query?: never; + header: { + "Idempotency-Key": string; + }; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["CreatePlatformTenantDto"]; + "text/json": components["schemas"]["CreatePlatformTenantDto"]; + "application/*+json": components["schemas"]["CreatePlatformTenantDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PlatformTenantProvisioningResult"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/tenants/{tenantId}/primary-domain": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + /** 更正租户主域名 */ + put: { + parameters: { + query?: never; + header?: never; + path: { + tenantId: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["ReplacePlatformPrimaryDomainDto"]; + "text/json": components["schemas"]["ReplacePlatformPrimaryDomainDto"]; + "application/*+json": components["schemas"]["ReplacePlatformPrimaryDomainDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PlatformTenantDomainItem"]; + }; + }; + }; + }; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/tenants/{tenantId}/owner-activation-links": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * 一次性领取租户 Owner 激活链接 + * @description 仅在主域名和试用/订阅有效时签发;幂等重放不会再次返回明文链接。 + */ + post: { + parameters: { + query?: never; + header: { + "Idempotency-Key": string; + }; + path: { + tenantId: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["IssuePlatformOwnerActivationLinkDto"]; + "text/json": components["schemas"]["IssuePlatformOwnerActivationLinkDto"]; + "application/*+json": components["schemas"]["IssuePlatformOwnerActivationLinkDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PlatformOwnerActivationLinkResult"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/tenants/{tenantId}/billing-policy": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询租户收款策略 */ + get: { + parameters: { + query?: never; + header?: never; + path: { + tenantId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["TenantBillingPolicyItem"]; + }; + }; + }; + }; + /** 更新租户收款策略 */ + put: { + parameters: { + query?: never; + header?: never; + path: { + tenantId: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["UpsertTenantBillingPolicyDto"]; + "text/json": components["schemas"]["UpsertTenantBillingPolicyDto"]; + "application/*+json": components["schemas"]["UpsertTenantBillingPolicyDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["TenantBillingPolicyItem"]; + }; + }; + }; + }; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/tenants/detail": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询平台租户详情 */ + get: { + parameters: { + query?: { + tenantId?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PlatformTenantDetail"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/platform/tenants/status": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + /** 更新租户业务状态 */ + patch: { + parameters: { + query?: never; + header: { + "Idempotency-Key": string; + }; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["UpdatePlatformTenantStatusDto"]; + "text/json": components["schemas"]["UpdatePlatformTenantStatusDto"]; + "application/*+json": components["schemas"]["UpdatePlatformTenantStatusDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PlatformCommandSubmission"]; + }; + }; + /** @description Accepted */ + 202: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PlatformCommandSubmission"]; + }; + }; + }; + }; + trace?: never; + }; + "/api/platform/tenants/billing-profile": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + /** 保存租户账务与开票资料 */ + put: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["UpsertPlatformTenantBillingProfileDto"]; + "text/json": components["schemas"]["UpsertPlatformTenantBillingProfileDto"]; + "application/*+json": components["schemas"]["UpsertPlatformTenantBillingProfileDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["TenantBillingProfileItem"]; + }; + }; + }; + }; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/public/tenant/resolve": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * 解析当前租户 + * @description 根据访问域名、host 参数、x-tenant-code 或 tenantCode 查询启用中的租户及公开品牌配置。 + */ + get: { + parameters: { + query?: { + /** @description 访问域名。 */ + Host?: string; + /** @description 租户编码。 */ + TenantCode?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["TenantResolveResponseDto"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/public/tenant/current-public": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * 获取公开租户配置 + * @description 公开页面使用的租户品牌、功能开关和 public config。和 resolve 返回结构一致。 + */ + get: { + parameters: { + query?: { + /** @description 访问域名。 */ + Host?: string; + /** @description 租户编码。 */ + TenantCode?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["TenantResolveResponseDto"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/context/current": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * 查询当前租户 + * @description 返回当前请求租户及当前用户在该租户内的成员角色。 + */ + get: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/plain": components["schemas"]["CurrentTenantResponse"]; + "application/json": components["schemas"]["CurrentTenantResponse"]; + "text/json": components["schemas"]["CurrentTenantResponse"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/audit-logs": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询租户审计日志 */ + get: { + parameters: { + query?: { + /** @description 操作。 */ + Action?: string; + /** @description 目标类型。 */ + TargetType?: string; + /** @description 操作人用户 ID。 */ + ActorUserId?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfTenantAdminAuditLogItem"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/branding": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + /** 更新租户品牌信息 */ + put: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["UpsertTenantBrandingDto"]; + "text/json": components["schemas"]["UpsertTenantBrandingDto"]; + "application/*+json": components["schemas"]["UpsertTenantBrandingDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ContentManagementResultOfTenantBrandingItem"]; + }; + }; + }; + }; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/settings": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + /** 更新租户公开设置与功能开关 */ + put: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["UpsertTenantSettingsDto"]; + "text/json": components["schemas"]["UpsertTenantSettingsDto"]; + "application/*+json": components["schemas"]["UpsertTenantSettingsDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ContentManagementResultOfTenantSettingsItem"]; + }; + }; + }; + }; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/theme-templates": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询可用租户主题模板 */ + get: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfTenantThemeTemplateItem"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/theme": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询租户当前主题与草稿 */ + get: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ContentManagementResultOfTenantThemeItem"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/theme/preview": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 生成租户主题草稿 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["PreviewTenantThemeDto"]; + "text/json": components["schemas"]["PreviewTenantThemeDto"]; + "application/*+json": components["schemas"]["PreviewTenantThemeDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ContentManagementResultOfTenantThemeItem"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/theme/publish": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 发布租户主题 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["PublishTenantThemeDto"]; + "text/json": components["schemas"]["PublishTenantThemeDto"]; + "application/*+json": components["schemas"]["PublishTenantThemeDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ContentManagementResultOfTenantThemeItem"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/students": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询租户学生 */ + get: { + parameters: { + query?: { + /** @description 地区 ID。 */ + RegionId?: string; + /** @description 班级 ID。 */ + ClassId?: string; + /** @description 状态。 */ + Status?: string; + /** @description 关键字。 */ + Keyword?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["TenantAdminStudentList"]; + }; + }; + }; + }; + /** 新增或更新租户学生档案 */ + put: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["UpsertTenantAdminStudentDto"]; + "text/json": components["schemas"]["UpsertTenantAdminStudentDto"]; + "application/*+json": components["schemas"]["UpsertTenantAdminStudentDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ContentManagementResultOfTenantAdminStudentItem"]; + }; + }; + }; + }; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/students/status": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 更新租户学生状态 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["UpdateTenantAdminStudentStatusDto"]; + "text/json": components["schemas"]["UpdateTenantAdminStudentStatusDto"]; + "application/*+json": components["schemas"]["UpdateTenantAdminStudentStatusDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ContentManagementResultOfTenantAdminStudentStatusItem"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/students/import/preview": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 预览学生批量导入 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["TenantAdminStudentImportDto"]; + "text/json": components["schemas"]["TenantAdminStudentImportDto"]; + "application/*+json": components["schemas"]["TenantAdminStudentImportDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["TenantAdminStudentImportPreview"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/students/import": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 提交学生批量导入 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["TenantAdminStudentImportDto"]; + "text/json": components["schemas"]["TenantAdminStudentImportDto"]; + "application/*+json": components["schemas"]["TenantAdminStudentImportDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["TenantAdminStudentImportResult"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/students/bulk-assign-class": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 批量分班 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["TenantAdminBulkAssignClassDto"]; + "text/json": components["schemas"]["TenantAdminBulkAssignClassDto"]; + "application/*+json": components["schemas"]["TenantAdminBulkAssignClassDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["TenantAdminBulkOperationResult"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/students/bulk-status": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 批量调整学生状态 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["TenantAdminBulkStatusDto"]; + "text/json": components["schemas"]["TenantAdminBulkStatusDto"]; + "application/*+json": components["schemas"]["TenantAdminBulkStatusDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["TenantAdminBulkOperationResult"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/student-notes": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询学生备注 */ + get: { + parameters: { + query?: { + /** @description 学生用户 ID。 */ + StudentUserId?: string; + /** @description 状态。 */ + Status?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfTenantAdminStudentNoteItem"]; + }; + }; + }; + }; + /** 新增或更新学生备注 */ + put: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["UpsertTenantAdminStudentNoteDto"]; + "text/json": components["schemas"]["UpsertTenantAdminStudentNoteDto"]; + "application/*+json": components["schemas"]["UpsertTenantAdminStudentNoteDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ContentManagementResultOfTenantAdminStudentNoteItem"]; + }; + }; + }; + }; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/student-followups": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询学生跟进 */ + get: { + parameters: { + query?: { + /** @description 学生用户 ID。 */ + StudentUserId?: string; + /** @description 状态。 */ + Status?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfTenantAdminStudentFollowupItem"]; + }; + }; + }; + }; + /** 新增或更新学生跟进 */ + put: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["UpsertTenantAdminStudentFollowupDto"]; + "text/json": components["schemas"]["UpsertTenantAdminStudentFollowupDto"]; + "application/*+json": components["schemas"]["UpsertTenantAdminStudentFollowupDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ContentManagementResultOfTenantAdminStudentFollowupItem"]; + }; + }; + }; + }; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/students/supervision/rules": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询学习督导规则 */ + get: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfTenantSupervisionRuleItem"]; + }; + }; + }; + }; + /** 新增或更新学习督导规则 */ + put: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["UpsertTenantSupervisionRuleDto"]; + "text/json": components["schemas"]["UpsertTenantSupervisionRuleDto"]; + "application/*+json": components["schemas"]["UpsertTenantSupervisionRuleDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ContentManagementResultOfTenantSupervisionRuleItem"]; + }; + }; + }; + }; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/students/supervision/preview": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 预览学习风险学生 */ + get: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["TenantSupervisionPreview"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/students/supervision/generate": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 批量生成学习督导跟进任务 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["TenantSupervisionGenerateDto"]; + "text/json": components["schemas"]["TenantSupervisionGenerateDto"]; + "application/*+json": components["schemas"]["TenantSupervisionGenerateDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["TenantSupervisionGenerateResult"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/student-followups/report": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询学生跟进统计报表 */ + get: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["TenantFollowupReport"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/feedbacks/report": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询反馈处理统计报表 */ + get: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["TenantFeedbackReport"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/points/risk-report": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询积分风险统计报表 */ + get: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["TenantPointRiskReport"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/content/videos": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询租户视频解析 */ + get: { + parameters: { + query?: { + /** @description 地区 ID。 */ + RegionId?: string; + /** @description 内容入口 ID。 */ + EntryId?: string; + /** @description 内容节点 ID。 */ + ContentNodeId?: string; + /** @description 父节点 ID。 */ + ParentId?: string; + /** @description 科目 ID。 */ + SubjectId?: string; + /** @description 章节 ID。 */ + ChapterId?: string; + /** @description 单元 ID。 */ + UnitId?: string; + /** @description 院校 ID。 */ + SchoolId?: string; + /** @description 专业 ID。 */ + MajorId?: string; + /** @description 题目 ID。 */ + QuestionId?: string; + /** @description 状态。 */ + Status?: string; + /** @description 关键字。 */ + Keyword?: string; + /** @description 年份。 */ + Year?: number | string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfVideoManagementItem"]; + }; + }; + }; + }; + /** 新增或更新视频解析 */ + put: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["DirectVideoDto"]; + "text/json": components["schemas"]["DirectVideoDto"]; + "application/*+json": components["schemas"]["DirectVideoDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ContentManagementResultOfVideoManagementItem"]; + }; + }; + }; + }; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/content/question-videos": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 绑定题目与解析视频 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["DirectQuestionVideoDto"]; + "text/json": components["schemas"]["DirectQuestionVideoDto"]; + "application/*+json": components["schemas"]["DirectQuestionVideoDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ContentManagementResultOfQuestionVideoManagementItem"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/student/videos/search": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 搜索通用解析视频 */ + get: { + parameters: { + query?: { + /** @description 关键字。 */ + Keyword?: string; + /** @description 科目 ID。 */ + SubjectId?: string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfVideoExplanationCatalogItem"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/student/videos/play": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 申请视频播放信息 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["VideoPlayDto"]; + "text/json": components["schemas"]["VideoPlayDto"]; + "application/*+json": components["schemas"]["VideoPlayDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["VideoPlaybackItem"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/student/videos/progress": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 上报视频播放进度 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["VideoProgressDto"]; + "text/json": components["schemas"]["VideoProgressDto"]; + "application/*+json": components["schemas"]["VideoProgressDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["VideoProgressItem"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/content/vocabulary-units": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询管理侧词汇单元 */ + get: { + parameters: { + query?: { + /** @description 地区 ID。 */ + RegionId?: string; + /** @description 内容入口 ID。 */ + EntryId?: string; + /** @description 内容节点 ID。 */ + ContentNodeId?: string; + /** @description 父节点 ID。 */ + ParentId?: string; + /** @description 科目 ID。 */ + SubjectId?: string; + /** @description 章节 ID。 */ + ChapterId?: string; + /** @description 单元 ID。 */ + UnitId?: string; + /** @description 院校 ID。 */ + SchoolId?: string; + /** @description 专业 ID。 */ + MajorId?: string; + /** @description 题目 ID。 */ + QuestionId?: string; + /** @description 状态。 */ + Status?: string; + /** @description 关键字。 */ + Keyword?: string; + /** @description 年份。 */ + Year?: number | string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfVocabularyUnit"]; + }; + }; + }; + }; + /** 新增或更新词汇单元 */ + put: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["DirectVocabularyUnitDto"]; + "text/json": components["schemas"]["DirectVocabularyUnitDto"]; + "application/*+json": components["schemas"]["DirectVocabularyUnitDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ContentManagementResultOfVocabularyUnit"]; + }; + }; + }; + }; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/tenant/content/vocabulary-words": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询管理侧词汇 */ + get: { + parameters: { + query?: { + /** @description 地区 ID。 */ + RegionId?: string; + /** @description 内容入口 ID。 */ + EntryId?: string; + /** @description 内容节点 ID。 */ + ContentNodeId?: string; + /** @description 父节点 ID。 */ + ParentId?: string; + /** @description 科目 ID。 */ + SubjectId?: string; + /** @description 章节 ID。 */ + ChapterId?: string; + /** @description 单元 ID。 */ + UnitId?: string; + /** @description 院校 ID。 */ + SchoolId?: string; + /** @description 专业 ID。 */ + MajorId?: string; + /** @description 题目 ID。 */ + QuestionId?: string; + /** @description 状态。 */ + Status?: string; + /** @description 关键字。 */ + Keyword?: string; + /** @description 年份。 */ + Year?: number | string; + /** @description 返回数量上限。 */ + Limit?: number | string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CatalogListOfVocabularyWord"]; + }; + }; + }; + }; + /** 新增或更新词汇 */ + put: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["DirectVocabularyWordDto"]; + "text/json": components["schemas"]["DirectVocabularyWordDto"]; + "application/*+json": components["schemas"]["DirectVocabularyWordDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ContentManagementResultOfVocabularyWord"]; + }; + }; + }; + }; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/student/learning/vocabulary/progress": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询单词学习进度 */ + get: { + parameters: { + query?: { + /** @description 返回数量上限。 */ + Limit?: number | string; + /** @description 状态。 */ + Status?: string; + /** @description 单元 ID。 */ + UnitId?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["LearningListOfWordProgressItem"]; + }; + }; + }; + }; + put?: never; + /** 更新单词学习进度 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["WordProgressDto"]; + "text/json": components["schemas"]["WordProgressDto"]; + "application/*+json": components["schemas"]["WordProgressDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["WordProgressItem"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/student/learning/vocabulary/review-plan": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 生成单词复习计划 */ + get: { + parameters: { + query?: { + /** @description 返回数量上限。 */ + Limit?: number | string; + /** @description 状态。 */ + Status?: string; + /** @description 单元 ID。 */ + UnitId?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["WordReviewPlan"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/student/learning/vocabulary/review": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** 提交单词复习结果 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["WordReviewDto"]; + "text/json": components["schemas"]["WordReviewDto"]; + "application/*+json": components["schemas"]["WordReviewDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["WordProgressItem"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/student/learning/vocabulary/stats": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询单词学习统计 */ + get: { + parameters: { + query?: { + /** @description 返回数量上限。 */ + Limit?: number | string; + /** @description 状态。 */ + Status?: string; + /** @description 单元 ID。 */ + UnitId?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["WordStatsItem"]; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/student/learning/vocabulary/favorites": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** 查询收藏单词 */ + get: { + parameters: { + query?: { + /** @description 返回数量上限。 */ + Limit?: number | string; + /** @description 状态。 */ + Status?: string; + /** @description 单元 ID。 */ + UnitId?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["LearningListOfFavoriteWordItem"]; + }; + }; + }; + }; + put?: never; + /** 收藏或取消收藏单词 */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["FavoriteWordDto"]; + "text/json": components["schemas"]["FavoriteWordDto"]; + "application/*+json": components["schemas"]["FavoriteWordDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["LearningActionResult"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProblemDetails"]; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; +} +export type webhooks = Record; +export interface components { + schemas: { + ActivationCodeItem: { + /** Format: uuid */ + id: string; + /** Format: uuid */ + batchId: null | string; + code: string; + /** Format: int32 */ + days: number | string; + isUsed: boolean; + /** Format: uuid */ + usedBy: null | string; + /** Format: date-time */ + usedAt: null | string; + saleType: null | string; + soldTo: null | string; + remark: null | string; + /** Format: date-time */ + createdAt: string; + }; + ActivationCodeList: { + items: components["schemas"]["ActivationCodeItem"][]; + }; + /** @description 管理员为用户设置一次性临时密码。 */ + AdministrativePasswordResetDto: { + /** @description 符合当前密码策略的临时密码。 */ + temporaryPassword: string; + /** @description 审计原因。 */ + reason: string; + }; + AdminOrderList: { + items: components["schemas"]["CommerceOrderItem"][]; + }; + AdminPaymentList: { + items: components["schemas"]["CommercePaymentItem"][]; + }; + AnnouncementCatalogItem: { + /** Format: uuid */ + id: string; + legacyId: null | string; + content: null | string; + link: null | string; + backgroundColor: null | string; + /** Format: int32 */ + order: number | string; + isActive: boolean; + }; + AnswerRecordItem: { + /** Format: uuid */ + id: string; + /** Format: uuid */ + sessionQuestionId: string; + /** Format: uuid */ + practiceSessionId: string; + selectedOptionIndices: components["schemas"]["JsonElement"]; + answerText: null | string; + status: string; + /** Format: int32 */ + revision: number | string; + /** Format: int64 */ + clientSequence: number | string; + /** Format: int64 */ + sessionVersion: number | string; + /** Format: date-time */ + acceptedAt: string; + }; + AppAssetCatalogItem: { + /** Format: uuid */ + id: string; + legacyId: null | string; + assetKey: string; + fileName: null | string; + description: null | string; + metadata: components["schemas"]["JsonElement"]; + }; + ArchivePlatformQuestionsCommand: { + questionIds: string[]; + }; + AssetAccessActorRole: number; + AssetAccessDisposition: number; + /** @description 资产访问Principal请求 DTO。 */ + AssetAccessPrincipalDto: { + /** Format: uuid */ + userId: null | string; + isMember: boolean; + hasSvip: boolean; + }; + /** @description 资产访问签名响应。 */ + AssetAccessResponseDto: { + item: components["schemas"]["ContentAssetAccessSummaryDto"]; + access: components["schemas"]["AssetAccessPrincipalDto"]; + url: components["schemas"]["SignedStorageUrlDto"]; + watermark: components["schemas"]["JsonElement"]; + }; + AssetAccessResult: number; + /** @description 创建资产访问签名请求。 */ + AssetAccessSignDto: { + /** + * Format: uuid + * @description 资产 ID。 + */ + assetId: string; + /** + * Format: int32 + * @description 有效期秒数。 + */ + expiresInSeconds?: null | number | string; + }; + AssetAccessType: number; + AssetManagementSignedAccessResult: { + item: components["schemas"]["ContentAssetManagementItem"]; + url: components["schemas"]["ObjectStorageSignedUrl"]; + }; + AssetPreviewStatus: number; + AssetSecurityRiskLevel: number; + AssetSecurityScanStatus: number; + AssetStorageProvider: number; + /** @description 确认资产上传请求。 */ + AssetUploadConfirmDto: { + /** + * Format: uuid + * @description 资产 ID。 + */ + assetId: string; + /** @description MIME 类型。 */ + mimeType?: null | string; + /** + * Format: int64 + * @description 文件大小,单位为字节。 + */ + fileSizeBytes?: null | number | string; + /** @description SHA-256 校验值。 */ + checksumSha256?: null | string; + }; + AssetUploadConfirmResult: { + item: components["schemas"]["ContentAssetManagementItem"]; + metadata: components["schemas"]["ObjectStorageMetadata"]; + }; + /** @description 创建资产上传签名请求。 */ + AssetUploadSignDto: { + /** + * Format: uuid + * @description 资产 ID。 + */ + assetId?: null | string; + /** + * Format: uuid + * @description 地区 ID。 + */ + regionId?: null | string; + /** + * Format: uuid + * @description 科目 ID。 + */ + subjectId?: null | string; + /** + * Format: uuid + * @description 分类 ID。 + */ + categoryId?: null | string; + /** + * Format: uuid + * @description 内容节点 ID。 + */ + contentNodeId?: null | string; + /** @description 资产键。 */ + assetKey?: null | string; + /** @description 标题。 */ + title?: null | string; + /** @description 分类。 */ + category?: null | string; + /** @description 说明。 */ + description?: null | string; + /** @description 文件名。 */ + fileName: string; + /** @description MIME 类型。 */ + mimeType: string; + /** + * Format: int64 + * @description 文件大小,单位为字节。 + */ + fileSizeBytes?: null | number | string; + /** @description SHA-256 校验值。 */ + checksumSha256?: null | string; + /** @description 资产类型。 */ + assetType?: null | string; + /** @description 可见性。 */ + visibility?: null | string; + /** @description 是否公开。 */ + isPublic?: null | boolean; + /** @description 服务提供方。 */ + provider?: null | string; + /** @description 存储桶。 */ + bucket?: null | string; + /** @description 对象存储键。 */ + objectKey?: null | string; + /** + * Format: int32 + * @description 有效期秒数。 + */ + expiresInSeconds?: null | number | string; + /** @description 扩展元数据。 */ + metadata?: components["schemas"]["JsonElement"]; + }; + AssetUploadSignResult: { + item: components["schemas"]["ContentAssetManagementItem"]; + upload: components["schemas"]["ObjectStorageSignedUrl"]; + }; + AssetUploadStatus: number; + /** @description 已登录用户修改密码。 */ + AuthenticatedPasswordChangeDto: { + /** @description 当前密码。 */ + currentPassword: string; + /** @description 符合当前密码策略的新密码。 */ + newPassword: string; + }; + /** @description Authenticated用户请求 DTO。 */ + AuthenticatedUserDto: { + /** + * Format: uuid + * @description 用户 ID。 + */ + userId?: string; + /** @description 手机号。 */ + phone?: null | string; + /** @description 邮箱。 */ + email?: null | string; + /** @description 名称。 */ + name?: null | string; + /** @description 认证域。 */ + realm?: components["schemas"]["AuthRealm"]; + tenant?: null | components["schemas"]["TenantMembershipSummary"]; + /** @description 访问令牌和刷新令牌。 */ + tokens?: components["schemas"]["AuthTokenPair"]; + }; + /** @description 登录认证结果。 */ + AuthenticationResultDto: { + /** @description 状态。 */ + status?: components["schemas"]["AuthenticationStatus"]; + user?: null | components["schemas"]["AuthenticatedUserDto"]; + /** @description 挑战令牌。 */ + challengeToken?: null | string; + /** + * Format: date-time + * @description 挑战令牌过期时间。 + */ + challengeExpiresAt?: null | string; + }; + AuthenticationStatus: number; + AuthRealm: number; + AuthSessionSummary: { + /** Format: uuid */ + sessionFamilyId: string; + realm: components["schemas"]["AuthRealm"]; + /** Format: uuid */ + tenantId: null | string; + provider: string; + /** Format: date-time */ + createdAt: string; + /** Format: date-time */ + lastRotatedAt: string; + /** Format: date-time */ + expiresAt: string; + ipAddressMasked: null | string; + userAgent: null | string; + isCurrent: boolean; + }; + /** @description 认证令牌对。 */ + AuthTokenPair: { + /** @description 用于访问 API 的 JWT access token。 */ + accessToken: string; + /** @description 用于刷新会话的 refresh token,服务端只保存哈希。 */ + refreshToken: string; + /** + * Format: date-time + * @description access token 过期时间。 + */ + accessTokenExpiresAt: string; + /** + * Format: date-time + * @description refresh token 过期时间。 + */ + refreshTokenExpiresAt: string; + }; + BackendPermissionArea: number; + BackendRoleStatus: number; + BackgroundJobItem: { + /** Format: uuid */ + id: string; + /** Format: uuid */ + tenantId: string; + jobType: string; + idempotencyKey: null | string; + status: components["schemas"]["BackgroundJobStatus"]; + /** Format: int32 */ + retryCount: number | string; + /** Format: int32 */ + maxRetries: number | string; + /** Format: date-time */ + runAfter: null | string; + /** Format: date-time */ + startedAt: null | string; + /** Format: date-time */ + completedAt: null | string; + /** Format: date-time */ + cancellationRequestedAt: null | string; + /** Format: uuid */ + cancellationRequestedBy: null | string; + cancellationReason: null | string; + lastError: null | string; + /** Format: uuid */ + outputAssetId: null | string; + result: components["schemas"]["JsonElement"]; + }; + BackgroundJobStatus: number; + BackofficeBootstrap: { + permissions: components["schemas"]["BackofficePermissionItem"][]; + menus: components["schemas"]["BackofficeMenuItem"][]; + roles: components["schemas"]["BackofficeRoleItem"][]; + }; + BackofficeMenuItem: { + /** Format: uuid */ + id: string; + code: string; + parentCode: null | string; + title: string; + area: components["schemas"]["BackendPermissionArea"]; + path: null | string; + icon: null | string; + permissionCode: null | string; + /** Format: int32 */ + sortOrder: number | string; + isActive: boolean; + }; + BackofficePermissionItem: { + /** Format: uuid */ + id: string; + code: string; + name: string; + area: components["schemas"]["BackendPermissionArea"]; + permissionModuleCode: string; + description: null | string; + /** Format: int32 */ + sortOrder: number | string; + }; + BackofficeRoleItem: { + /** Format: uuid */ + id: string; + code: string; + name: string; + status: components["schemas"]["BackendRoleStatus"]; + isSystem: boolean; + description: null | string; + permissionCodes: string[]; + menuCodes: string[]; + dataScope?: unknown; + }; + BackofficeUiBootstrap: { + permissionCodes: string[]; + menus: components["schemas"]["BackofficeMenuItem"][]; + enabledFeatures: string[]; + quotas: components["schemas"]["FeatureQuotaSnapshot"][]; + }; + BadgeItem: { + /** Format: uuid */ + id: string; + name: string; + description: null | string; + category: null | string; + iconUrl: null | string; + /** Format: int32 */ + level: null | number | string; + unlockType: null | string; + conditionExtra: components["schemas"]["JsonElement"]; + isUnlocked: boolean; + /** Format: date-time */ + grantedAt: null | string; + note: null | string; + /** Format: int32 */ + order: number | string; + }; + BadgeList: { + items: components["schemas"]["BadgeItem"][]; + /** Format: int32 */ + total: number | string; + /** Format: int32 */ + unlocked: number | string; + includeLocked: boolean; + }; + BannerCatalogItem: { + /** Format: uuid */ + id: string; + legacyId: null | string; + /** Format: uuid */ + regionId: null | string; + title: null | string; + subtitle: null | string; + content: null | string; + buttonText: null | string; + buttonLink: null | string; + backgroundColor: null | string; + borderColor: null | string; + /** Format: int32 */ + order: number | string; + isActive: boolean; + }; + BatchCreatePlatformQuestionBankNodesCommand: { + /** Format: uuid */ + questionBankId: string; + /** Format: uuid */ + parentId: null | string; + nodeType: components["schemas"]["ContentNodeType"]; + names: string[]; + }; + BillingStatus: number; + /** @description 绑定推荐请求 DTO。 */ + BindReferralDto: { + /** @description 推荐码。 */ + refCode: string; + /** @description 来源。 */ + source?: null | string; + metadata?: null | components["schemas"]["JsonElement"]; + }; + /** @description 后台任务取消请求。 */ + CancelBackgroundJobDto: { + /** @description 取消原因。 */ + reason: string; + }; + CatalogListOfAnnouncementCatalogItem: { + items: components["schemas"]["AnnouncementCatalogItem"][]; + }; + CatalogListOfAppAssetCatalogItem: { + items: components["schemas"]["AppAssetCatalogItem"][]; + }; + CatalogListOfBannerCatalogItem: { + items: components["schemas"]["BannerCatalogItem"][]; + }; + CatalogListOfCategoryCatalogItem: { + items: components["schemas"]["CategoryCatalogItem"][]; + }; + CatalogListOfCollectionQuestionCatalogItem: { + items: components["schemas"]["CollectionQuestionCatalogItem"][]; + }; + CatalogListOfContentAssetAccessEventItem: { + items: components["schemas"]["ContentAssetAccessEventItem"][]; + }; + CatalogListOfContentAssetCatalogItem: { + items: components["schemas"]["ContentAssetCatalogItem"][]; + }; + CatalogListOfContentAssetManagementItem: { + items: components["schemas"]["ContentAssetManagementItem"][]; + }; + CatalogListOfContentAssetSecurityScanEventItem: { + items: components["schemas"]["ContentAssetSecurityScanEventItem"][]; + }; + CatalogListOfContentEntryCatalogItem: { + items: components["schemas"]["ContentEntryCatalogItem"][]; + }; + CatalogListOfContentEntryManagementItem: { + items: components["schemas"]["ContentEntryManagementItem"][]; + }; + CatalogListOfContentImportIssueModel: { + items: components["schemas"]["ContentImportIssueModel"][]; + }; + CatalogListOfContentImportJobItem: { + items: components["schemas"]["ContentImportJobItem"][]; + }; + CatalogListOfContentNodeCatalogItem: { + items: components["schemas"]["ContentNodeCatalogItem"][]; + }; + CatalogListOfContentNodeManagementItem: { + items: components["schemas"]["ContentNodeManagementItem"][]; + }; + CatalogListOfExamDateCatalogItem: { + items: components["schemas"]["ExamDateCatalogItem"][]; + }; + CatalogListOfFaqCatalogItem: { + items: components["schemas"]["FaqCatalogItem"][]; + }; + CatalogListOfHandbookChapter: { + items: components["schemas"]["HandbookChapter"][]; + }; + CatalogListOfHandbookChapterCatalogItem: { + items: components["schemas"]["HandbookChapterCatalogItem"][]; + }; + CatalogListOfHandbookEntry: { + items: components["schemas"]["HandbookEntry"][]; + }; + CatalogListOfHandbookEntryCatalogItem: { + items: components["schemas"]["HandbookEntryCatalogItem"][]; + }; + CatalogListOfHandbookSubject: { + items: components["schemas"]["HandbookSubject"][]; + }; + CatalogListOfHandbookSubjectCatalogItem: { + items: components["schemas"]["HandbookSubjectCatalogItem"][]; + }; + CatalogListOfImageAssetCatalogItem: { + items: components["schemas"]["ImageAssetCatalogItem"][]; + }; + CatalogListOfint: { + items: (number | string)[]; + }; + CatalogListOfMajor: { + items: components["schemas"]["Major"][]; + }; + CatalogListOfMajorCatalogItem: { + items: components["schemas"]["MajorCatalogItem"][]; + }; + CatalogListOfModuleNodeCatalogItem: { + items: components["schemas"]["ModuleNodeCatalogItem"][]; + }; + CatalogListOfOperationContentItem: { + items: components["schemas"]["OperationContentItem"][]; + }; + CatalogListOfPracticeBlueprintCatalogItem: { + items: components["schemas"]["PracticeBlueprintCatalogItem"][]; + }; + CatalogListOfPracticeBlueprintManagementItem: { + items: components["schemas"]["PracticeBlueprintManagementItem"][]; + }; + CatalogListOfProductCatalogItem: { + items: components["schemas"]["ProductCatalogItem"][]; + }; + CatalogListOfQuestionBankCatalogItem: { + items: components["schemas"]["QuestionBankCatalogItem"][]; + }; + CatalogListOfQuestionCatalogItem: { + items: components["schemas"]["QuestionCatalogItem"][]; + }; + CatalogListOfQuestionCollectionCatalogItem: { + items: components["schemas"]["QuestionCollectionCatalogItem"][]; + }; + CatalogListOfQuestionCollectionManagementItem: { + items: components["schemas"]["QuestionCollectionManagementItem"][]; + }; + CatalogListOfQuestionVersionCatalogItem: { + items: components["schemas"]["QuestionVersionCatalogItem"][]; + }; + CatalogListOfQuestionVideoCatalogItem: { + items: components["schemas"]["QuestionVideoCatalogItem"][]; + }; + CatalogListOfRegionCatalogItem: { + items: components["schemas"]["RegionCatalogItem"][]; + }; + CatalogListOfRegionModuleCatalogItem: { + items: components["schemas"]["RegionModuleCatalogItem"][]; + }; + CatalogListOfSchool: { + items: components["schemas"]["School"][]; + }; + CatalogListOfSchoolCatalogItem: { + items: components["schemas"]["SchoolCatalogItem"][]; + }; + CatalogListOfScorelineField: { + items: components["schemas"]["ScorelineField"][]; + }; + CatalogListOfScorelineFieldItem: { + items: components["schemas"]["ScorelineFieldItem"][]; + }; + CatalogListOfScorelineRecord: { + items: components["schemas"]["ScorelineRecord"][]; + }; + CatalogListOfScorelineRecordItem: { + items: components["schemas"]["ScorelineRecordItem"][]; + }; + CatalogListOfScorelineTrendItem: { + items: components["schemas"]["ScorelineTrendItem"][]; + }; + CatalogListOfSubjectCatalogItem: { + items: components["schemas"]["SubjectCatalogItem"][]; + }; + CatalogListOfSvipPlanCatalogItem: { + items: components["schemas"]["SvipPlanCatalogItem"][]; + }; + CatalogListOfTenantAdminAuditLogItem: { + items: components["schemas"]["TenantAdminAuditLogItem"][]; + }; + CatalogListOfTenantAdminBadgeGrantItem: { + items: components["schemas"]["TenantAdminBadgeGrantItem"][]; + }; + CatalogListOfTenantAdminBadgeItem: { + items: components["schemas"]["TenantAdminBadgeItem"][]; + }; + CatalogListOfTenantAdminClassMemberItem: { + items: components["schemas"]["TenantAdminClassMemberItem"][]; + }; + CatalogListOfTenantAdminFeedbackItem: { + items: components["schemas"]["TenantAdminFeedbackItem"][]; + }; + CatalogListOfTenantAdminMemberItem: { + items: components["schemas"]["TenantAdminMemberItem"][]; + }; + CatalogListOfTenantAdminNotificationItem: { + items: components["schemas"]["TenantAdminNotificationItem"][]; + }; + CatalogListOfTenantAdminStudentFollowupItem: { + items: components["schemas"]["TenantAdminStudentFollowupItem"][]; + }; + CatalogListOfTenantAdminStudentNoteItem: { + items: components["schemas"]["TenantAdminStudentNoteItem"][]; + }; + CatalogListOfTenantDomainItem: { + items: components["schemas"]["TenantDomainItem"][]; + }; + CatalogListOfTenantIdentityProviderItem: { + items: components["schemas"]["TenantIdentityProviderItem"][]; + }; + CatalogListOfTenantSupervisionRuleItem: { + items: components["schemas"]["TenantSupervisionRuleItem"][]; + }; + CatalogListOfTenantThemeTemplateItem: { + items: components["schemas"]["TenantThemeTemplateItem"][]; + }; + CatalogListOfVideoExplanationCatalogItem: { + items: components["schemas"]["VideoExplanationCatalogItem"][]; + }; + CatalogListOfVideoManagementItem: { + items: components["schemas"]["VideoManagementItem"][]; + }; + CatalogListOfVocabularyUnit: { + items: components["schemas"]["VocabularyUnit"][]; + }; + CatalogListOfVocabularyUnitCatalogItem: { + items: components["schemas"]["VocabularyUnitCatalogItem"][]; + }; + CatalogListOfVocabularyWord: { + items: components["schemas"]["VocabularyWord"][]; + }; + CatalogListOfVocabularyWordCatalogItem: { + items: components["schemas"]["VocabularyWordCatalogItem"][]; + }; + CategoryCatalogItem: { + /** Format: uuid */ + id: string; + legacyId: null | string; + /** Format: uuid */ + subjectId: null | string; + /** Format: uuid */ + nodeId: null | string; + name: string; + categoryType: null | components["schemas"]["CategoryType"]; + /** Format: int32 */ + order: number | string; + /** Format: int32 */ + svipQuestionLimit: null | number | string; + }; + CategoryType: number; + /** @description 平台修改订阅状态。 */ + ChangePlatformSubscriptionDto: { + reason: string; + /** Format: int32 */ + extendDays?: null | number | string; + }; + /** @description 变更租户订阅请求 DTO。 */ + ChangeTenantSubscriptionDto: { + /** Format: uuid */ + baseOfferingVersionId: string; + addOnOfferingVersionIds: null | string[]; + idempotencyKey: string; + }; + /** @description 校验交易优惠券请求 DTO。 */ + CheckCommerceCouponDto: { + /** @description 优惠券码。 */ + couponCode?: null | string; + /** + * Format: uuid + * @description 优惠券领取记录 ID。 + */ + couponRedemptionId?: null | string; + /** + * Format: uuid + * @description 套餐 ID。 + */ + planId: string; + /** + * Format: int32 + * @description 数量。 + */ + quantity?: number | string; + /** + * Format: uuid + * @description 地区 ID。 + */ + regionId?: null | string; + }; + CheckInResult: { + /** Format: date */ + checkInDate: string; + alreadyCheckedIn: boolean; + /** Format: int32 */ + points: number | string; + /** Format: int32 */ + balanceAfter: number | string; + /** Format: uuid */ + claimId: null | string; + /** Format: uuid */ + scoreEventId: null | string; + }; + /** @description 领取交易优惠券请求 DTO。 */ + ClaimCommerceCouponDto: { + /** @description 优惠券码。 */ + couponCode: string; + }; + /** @description 领取积分任务请求 DTO。 */ + ClaimPointTaskDto: { + /** @description 任务键。 */ + taskKey: string; + /** @description 来源类型。 */ + sourceType?: null | string; + /** + * Format: uuid + * @description 来源 ID。 + */ + sourceId?: null | string; + }; + CodeBatchItem: { + /** Format: uuid */ + id: string; + name: string; + /** Format: int32 */ + totalCount: number | string; + /** Format: int32 */ + days: number | string; + /** Format: uuid */ + regionId: null | string; + saleType: null | string; + channel: null | string; + /** Format: int32 */ + defaultUnitPriceCents: number | string; + /** Format: int32 */ + costPriceCents: number | string; + /** Format: date-time */ + issuedAt: null | string; + remark: null | string; + /** Format: date-time */ + createdAt: string; + }; + CollectionItemsReplaceResult: { + /** Format: uuid */ + collectionId: string; + /** Format: int32 */ + questionCount: number | string; + items: components["schemas"]["QuestionCollectionItemManagementItem"][]; + }; + CollectionQuestionCatalogItem: { + /** Format: uuid */ + id: string; + legacyId: null | string; + /** Format: uuid */ + entryId: null | string; + /** Format: uuid */ + contentNodeId: null | string; + /** Format: uuid */ + primaryCollectionId: null | string; + /** Format: uuid */ + subjectId: null | string; + /** Format: uuid */ + categoryId: null | string; + /** Format: uuid */ + nodeId: null | string; + type: string; + typeLabel: null | string; + /** Format: int32 */ + difficulty: null | number | string; + tags: components["schemas"]["JsonElement"]; + examMarkers: components["schemas"]["JsonElement"]; + mediaUrl: null | string; + hasVideoExplanation: boolean; + sectionKey: null | string; + /** Format: double */ + score: null | number | string; + /** Format: int32 */ + order: number | string; + /** Format: uuid */ + versionId: null | string; + content: null | string; + options: components["schemas"]["JsonElement"]; + /** Format: int32 */ + correctOptionIndex: null | number | string; + correctOptionIndices: components["schemas"]["JsonElement"]; + answerText: null | string; + explanation: null | string; + subQuestions: components["schemas"]["JsonElement"]; + codeLang: null | string; + codeTemplate: null | string; + }; + /** @description 题集题目请求 DTO。 */ + CollectionQuestionDto: { + /** + * Format: uuid + * @description 题目 ID。 + */ + questionId: string; + /** @description 来源。 */ + source: components["schemas"]["QuestionSource"]; + /** @description 分段键。 */ + sectionKey?: null | string; + /** + * Format: int32 + * @description 显示顺序。 + */ + order?: null | number | string; + /** + * Format: double + * @description 分数。 + */ + score?: null | number | string; + /** @description 是否必填。 */ + required?: null | boolean; + /** @description 扩展元数据。 */ + metadata?: components["schemas"]["JsonElement"]; + }; + CommerceAdjustmentDirection: number; + CommerceAdjustmentVoucher: { + /** Format: uuid */ + issueId?: null | string; + /** Format: uuid */ + batchId?: null | string; + /** Format: uuid */ + itemId?: null | string; + /** Format: uuid */ + orderId?: null | string; + /** Format: uuid */ + paymentId?: null | string; + /** Format: uuid */ + refundRequestId?: null | string; + /** Format: uuid */ + createdBy?: null | string; + /** Format: uuid */ + reviewedBy?: null | string; + voucherNo?: string; + status?: components["schemas"]["CommerceAdjustmentVoucherStatus"]; + direction?: components["schemas"]["CommerceAdjustmentDirection"]; + /** Format: int32 */ + amountCents?: number | string; + currency?: string; + reason?: string; + proofAssetKey?: null | string; + /** Format: date-time */ + reviewedAt?: null | string; + /** Format: date-time */ + closedAt?: null | string; + metadata?: components["schemas"]["JsonElement"]; + /** Format: date-time */ + createdAt?: string; + /** Format: date-time */ + updatedAt?: string; + /** Format: uuid */ + tenantId?: string; + /** Format: uuid */ + id?: string; + }; + CommerceAdjustmentVoucherEvent: { + /** Format: uuid */ + voucherId?: string; + fromStatus?: null | components["schemas"]["CommerceAdjustmentVoucherStatus"]; + toStatus?: components["schemas"]["CommerceAdjustmentVoucherStatus"]; + /** Format: uuid */ + actorUserId?: null | string; + note?: null | string; + details?: components["schemas"]["JsonElement"]; + /** Format: date-time */ + createdAt?: string; + /** Format: uuid */ + tenantId?: string; + /** Format: uuid */ + id?: string; + }; + CommerceAdjustmentVoucherStatus: number; + CommerceCouponCheckResult: { + valid: boolean; + reasonCode: null | string; + /** Format: uuid */ + couponId: null | string; + /** Format: uuid */ + couponRedemptionId: null | string; + couponCode: null | string; + /** Format: int32 */ + originalAmountCents: number | string; + /** Format: int32 */ + discountCents: number | string; + /** Format: int32 */ + payableAmountCents: number | string; + payablePrice: string; + }; + CommerceCouponItem: { + /** Format: uuid */ + id: string; + /** Format: uuid */ + couponId: null | string; + couponCode: string; + status: string; + /** Format: uuid */ + planId: null | string; + /** Format: uuid */ + regionId: null | string; + discountType: null | string; + /** Format: double */ + discountValue: null | number | string; + /** Format: int32 */ + discountPreviewCents: null | number | string; + discountPreview: null | string; + /** Format: date-time */ + validFrom: null | string; + /** Format: date-time */ + validTo: null | string; + /** Format: date-time */ + claimedAt: null | string; + /** Format: date-time */ + usedAt: null | string; + }; + CommerceCouponList: { + items: components["schemas"]["CommerceCouponItem"][]; + }; + CommerceOrderItem: { + /** Format: uuid */ + id: string; + orderNo: string; + status: string; + /** Format: uuid */ + planId: null | string; + /** Format: uuid */ + regionId: null | string; + productType: null | string; + productName: null | string; + /** Format: int32 */ + amountCents: number | string; + price: string; + payMethod: null | string; + payProvider: null | string; + tradeNo: null | string; + /** Format: int32 */ + days: null | number | string; + /** Format: date-time */ + paidAt: null | string; + /** Format: date-time */ + createdAt: string; + rawPayload: components["schemas"]["JsonElement"]; + }; + CommerceOrderList: { + items: components["schemas"]["CommerceOrderItem"][]; + }; + CommercePaymentItem: { + /** Format: uuid */ + id: string; + /** Format: uuid */ + orderId: string; + orderNo: string; + provider: string; + method: null | string; + status: string; + /** Format: int32 */ + amountCents: number | string; + price: string; + providerTradeNo: null | string; + /** Format: date-time */ + paidAt: null | string; + clientPayload: components["schemas"]["JsonElement"]; + rawPayload: components["schemas"]["JsonElement"]; + }; + CommerceReconciliationBatch: { + /** Format: uuid */ + createdBy?: null | string; + provider?: string; + /** Format: date */ + billDate?: string; + billType?: components["schemas"]["ReconciliationBillType"]; + source?: components["schemas"]["ReconciliationSource"]; + sourceName?: null | string; + sourceHash?: string; + status?: components["schemas"]["ReconciliationBatchStatus"]; + /** Format: int32 */ + totalCount?: number | string; + /** Format: int32 */ + matchedCount?: number | string; + /** Format: int32 */ + mismatchCount?: number | string; + /** Format: int32 */ + missingLocalCount?: number | string; + /** Format: int32 */ + missingProviderCount?: number | string; + /** Format: int32 */ + duplicateCount?: number | string; + /** Format: int32 */ + ignoredCount?: number | string; + /** Format: int32 */ + amountCents?: number | string; + /** Format: int32 */ + refundAmountCents?: number | string; + /** Format: int32 */ + feeCents?: number | string; + /** Format: date-time */ + completedAt?: null | string; + error?: null | string; + metadata?: components["schemas"]["JsonElement"]; + /** Format: date-time */ + createdAt?: string; + /** Format: date-time */ + updatedAt?: string; + /** Format: uuid */ + tenantId?: string; + /** Format: uuid */ + id?: string; + }; + CommerceReconciliationIssue: { + /** Format: uuid */ + batchId?: null | string; + /** Format: uuid */ + itemId?: null | string; + /** Format: uuid */ + orderId?: null | string; + /** Format: uuid */ + paymentId?: null | string; + /** Format: uuid */ + refundRequestId?: null | string; + /** Format: uuid */ + assignedTo?: null | string; + /** Format: uuid */ + createdBy?: null | string; + /** Format: uuid */ + resolvedBy?: null | string; + issueNo?: string; + provider?: string; + transactionType?: components["schemas"]["ReconciliationTransactionType"]; + issueCode?: null | string; + matchStatus?: components["schemas"]["ReconciliationIssueMatchStatus"]; + severity?: components["schemas"]["NotificationSeverity"]; + status?: components["schemas"]["ReconciliationIssueStatus"]; + resolutionType?: components["schemas"]["ReconciliationResolutionType"]; + orderNo?: null | string; + refundNo?: null | string; + providerTradeNo?: null | string; + providerRefundNo?: null | string; + /** Format: int32 */ + amountCents?: number | string; + /** Format: int32 */ + refundAmountCents?: number | string; + /** Format: date-time */ + resolvedAt?: null | string; + /** Format: date-time */ + dueAt?: null | string; + summary?: null | string; + resolutionNote?: null | string; + metadata?: components["schemas"]["JsonElement"]; + /** Format: date-time */ + createdAt?: string; + /** Format: date-time */ + updatedAt?: string; + /** Format: uuid */ + tenantId?: string; + /** Format: uuid */ + id?: string; + }; + CommerceReconciliationIssueEvent: { + /** Format: uuid */ + issueId?: string; + fromStatus?: null | components["schemas"]["ReconciliationIssueStatus"]; + toStatus?: null | components["schemas"]["ReconciliationIssueStatus"]; + eventType?: string; + /** Format: uuid */ + actorUserId?: null | string; + note?: null | string; + details?: components["schemas"]["JsonElement"]; + /** Format: date-time */ + createdAt?: string; + /** Format: uuid */ + tenantId?: string; + /** Format: uuid */ + id?: string; + }; + CommerceReconciliationItem: { + /** Format: uuid */ + batchId?: string; + /** Format: uuid */ + orderId?: null | string; + /** Format: uuid */ + paymentId?: null | string; + /** Format: uuid */ + refundRequestId?: null | string; + /** Format: int32 */ + rowNo?: number | string; + provider?: string; + transactionType?: components["schemas"]["ReconciliationTransactionType"]; + providerTradeNo?: null | string; + providerRefundNo?: null | string; + orderNo?: null | string; + refundNo?: null | string; + /** Format: int32 */ + amountCents?: number | string; + /** Format: int32 */ + refundAmountCents?: number | string; + /** Format: int32 */ + feeCents?: number | string; + /** Format: date-time */ + paidAt?: null | string; + /** Format: date-time */ + refundedAt?: null | string; + providerStatus?: null | string; + localStatus?: null | string; + matchStatus?: components["schemas"]["ReconciliationMatchStatus"]; + severity?: components["schemas"]["NotificationSeverity"]; + issueCode?: null | string; + details?: components["schemas"]["JsonElement"]; + /** Format: date-time */ + createdAt?: string; + /** Format: uuid */ + tenantId?: string; + /** Format: uuid */ + id?: string; + }; + CommerceRefundEvent: { + /** Format: uuid */ + refundRequestId?: string; + fromStatus?: null | components["schemas"]["CommerceRefundStatus"]; + toStatus?: components["schemas"]["CommerceRefundStatus"]; + eventType?: string; + /** Format: uuid */ + actorUserId?: null | string; + details?: components["schemas"]["JsonElement"]; + /** Format: date-time */ + createdAt?: string; + /** Format: uuid */ + tenantId?: string; + /** Format: uuid */ + id?: string; + }; + CommerceRefundRequest: { + /** Format: uuid */ + orderId?: string; + /** Format: uuid */ + paymentId?: null | string; + /** Format: uuid */ + requestedBy?: null | string; + /** Format: uuid */ + reviewedBy?: null | string; + /** Format: uuid */ + processedBy?: null | string; + refundNo?: string; + provider?: null | string; + providerRefundNo?: null | string; + status?: components["schemas"]["CommerceRefundStatus"]; + /** Format: int32 */ + amountCents?: number | string; + reason?: null | string; + entitlementAction?: components["schemas"]["RefundEntitlementAction"]; + /** Format: date-time */ + requestedAt?: string; + /** Format: date-time */ + reviewedAt?: null | string; + /** Format: date-time */ + processedAt?: null | string; + /** Format: date-time */ + succeededAt?: null | string; + /** Format: date-time */ + failedAt?: null | string; + /** Format: date-time */ + cancelledAt?: null | string; + failureReason?: null | string; + metadata?: components["schemas"]["JsonElement"]; + /** Format: date-time */ + createdAt?: string; + /** Format: date-time */ + updatedAt?: string; + /** Format: uuid */ + tenantId?: string; + /** Format: uuid */ + id?: string; + }; + CommerceRefundStatus: number; + CommercialMetrics: { + /** Format: int32 */ + activeSubscriptions: number | string; + /** Format: int32 */ + trialSubscriptions: number | string; + /** Format: int32 */ + pastDueSubscriptions: number | string; + /** Format: int32 */ + mrrCents: number | string; + /** Format: int32 */ + arrCents: number | string; + /** Format: int32 */ + collectedCents: number | string; + /** Format: int32 */ + outstandingCents: number | string; + /** Format: int32 */ + overdueCents: number | string; + /** Format: int32 */ + refundedCents: number | string; + /** Format: int32 */ + churnedSubscriptions: number | string; + }; + CommissionExportItem: { + /** Format: uuid */ + settlementId: string; + filename: string; + format: string; + mimeType: string; + /** Format: int32 */ + rowCount: number | string; + contentBase64: string; + sha256: string; + /** Format: int32 */ + sizeBytes: number | string; + }; + CommissionListOfCommissionProofItem: { + items: components["schemas"]["CommissionProofItem"][]; + }; + CommissionListOfCommissionSettlementItemDto: { + items: components["schemas"]["CommissionSettlementItemDto"][]; + }; + CommissionListOfCommissionSourceItem: { + items: components["schemas"]["CommissionSourceItem"][]; + }; + CommissionProofItem: { + /** Format: uuid */ + id: string; + /** Format: uuid */ + settlementId: string; + proofType: string; + status: string; + title: null | string; + /** Format: uuid */ + assetId: null | string; + externalUrl: null | string; + /** Format: int32 */ + amountCents: null | number | string; + paymentMethod: null | string; + paymentAccount: null | string; + /** Format: date-time */ + paidAt: null | string; + /** Format: date-time */ + reviewedAt: null | string; + }; + CommissionSettingsItem: { + /** Format: double */ + defaultRate: number | string; + /** Format: int32 */ + minSettlementCents: number | string; + settlementCycle: string; + config: components["schemas"]["JsonElement"]; + }; + CommissionSettlementItemDto: { + /** Format: uuid */ + id: string; + settlementNo: string; + /** Format: uuid */ + referrerUserId: string; + status: string; + /** Format: date */ + periodStart: string; + /** Format: date */ + periodEnd: string; + /** Format: int32 */ + sourceCount: number | string; + /** Format: int32 */ + paidUserCount: number | string; + /** Format: int32 */ + grossAmountCents: number | string; + /** Format: int32 */ + commissionAmountCents: number | string; + /** Format: date-time */ + reviewedAt: null | string; + /** Format: date-time */ + paidAt: null | string; + }; + CommissionSourceItem: { + sourceType: string; + /** Format: uuid */ + sourceId: string; + sourceNo: null | string; + /** Format: uuid */ + referrerUserId: string; + /** Format: uuid */ + studentUserId: null | string; + /** Format: int32 */ + grossAmountCents: number | string; + /** Format: double */ + commissionRate: number | string; + /** Format: int32 */ + commissionAmountCents: number | string; + rateSource: string; + /** Format: uuid */ + settlementId: null | string; + }; + CommissionSummaryItem: { + /** Format: int32 */ + sourceCount: number | string; + /** Format: int32 */ + paidUserCount: number | string; + /** Format: int32 */ + grossAmountCents: number | string; + /** Format: int32 */ + commissionAmountCents: number | string; + }; + /** @description 完成租户负责人一次性激活。 */ + CompleteOwnerActivationDto: { + /** + * Format: uuid + * @description 激活记录 ID。 + */ + activationId: string; + /** @description 只显示一次的激活令牌。 */ + token: string; + /** @description 符合当前密码策略的新密码。 */ + newPassword: string; + }; + /** @description 确认人工平台支付请求 DTO。 */ + ConfirmManualPlatformPaymentDto: { + /** Format: uuid */ + paymentId: string; + providerTradeNo: null | string; + /** Format: date-time */ + paidAt: null | string; + reason: string; + }; + ContentAssetAccessEventItem: { + /** Format: uuid */ + id: string; + /** Format: uuid */ + assetId: null | string; + /** Format: uuid */ + userId: null | string; + actorRole: components["schemas"]["AssetAccessActorRole"]; + accessType: components["schemas"]["AssetAccessType"]; + visibility: null | string; + assetType: null | string; + storageProvider: null | string; + disposition: null | components["schemas"]["AssetAccessDisposition"]; + /** Format: int32 */ + expiresInSeconds: null | number | string; + signatureMode: null | string; + result: components["schemas"]["AssetAccessResult"]; + denyCode: null | string; + ipAddress: null | string; + userAgent: null | string; + metadata: components["schemas"]["JsonElement"]; + /** Format: date-time */ + createdAt: string; + }; + /** @description 内容资产访问摘要。 */ + ContentAssetAccessSummaryDto: { + /** Format: uuid */ + id: string; + assetType: components["schemas"]["ContentAssetType"]; + title: null | string; + fileName: null | string; + previewUrl: null | string; + uploadStatus: components["schemas"]["AssetUploadStatus"]; + securityScanStatus: components["schemas"]["AssetSecurityScanStatus"]; + previewStatus: components["schemas"]["AssetPreviewStatus"]; + visibility: components["schemas"]["ContentVisibility"]; + }; + ContentAssetCatalogItem: { + /** Format: uuid */ + id: string; + legacyId: null | string; + /** Format: uuid */ + regionId: null | string; + /** Format: uuid */ + subjectId: null | string; + /** Format: uuid */ + categoryId: null | string; + /** Format: uuid */ + contentNodeId: null | string; + assetKey: null | string; + title: null | string; + category: null | string; + description: null | string; + fileName: null | string; + cdnUrl: null | string; + isPublic: boolean; + assetType: components["schemas"]["ContentAssetType"]; + storageProvider: components["schemas"]["AssetStorageProvider"]; + bucket: null | string; + objectKey: null | string; + mimeType: null | string; + /** Format: int64 */ + fileSizeBytes: null | number | string; + checksumSha256: null | string; + visibility: components["schemas"]["ContentVisibility"]; + previewUrl: null | string; + status: components["schemas"]["ContentStatus"]; + /** Format: int32 */ + order: number | string; + uploadStatus: components["schemas"]["AssetUploadStatus"]; + /** Format: date-time */ + verifiedAt: null | string; + previewStatus: components["schemas"]["AssetPreviewStatus"]; + securityScanStatus: components["schemas"]["AssetSecurityScanStatus"]; + metadata: components["schemas"]["JsonElement"]; + }; + ContentAssetManagementItem: { + /** Format: uuid */ + id: string; + legacyId: null | string; + /** Format: uuid */ + regionId: null | string; + /** Format: uuid */ + subjectId: null | string; + /** Format: uuid */ + categoryId: null | string; + /** Format: uuid */ + contentNodeId: null | string; + assetKey: null | string; + title: null | string; + category: null | string; + description: null | string; + fileName: null | string; + cdnUrl: null | string; + isPublic: boolean; + assetType: components["schemas"]["ContentAssetType"]; + storageProvider: components["schemas"]["AssetStorageProvider"]; + bucket: null | string; + objectKey: null | string; + mimeType: null | string; + /** Format: int64 */ + fileSizeBytes: null | number | string; + checksumSha256: null | string; + visibility: components["schemas"]["ContentVisibility"]; + status: components["schemas"]["ContentStatus"]; + /** Format: int32 */ + order: number | string; + uploadStatus: components["schemas"]["AssetUploadStatus"]; + /** Format: date-time */ + verifiedAt: null | string; + /** Format: int64 */ + verifiedSizeBytes: null | number | string; + verifiedChecksumSha256: null | string; + previewStatus: components["schemas"]["AssetPreviewStatus"]; + securityScanStatus: components["schemas"]["AssetSecurityScanStatus"]; + metadata: components["schemas"]["JsonElement"]; + /** Format: date-time */ + createdAt: string; + /** Format: date-time */ + updatedAt: null | string; + }; + ContentAssetSecurityScanEventItem: { + /** Format: uuid */ + id: string; + /** Format: uuid */ + assetId: null | string; + provider: string; + scanStatus: components["schemas"]["AssetSecurityScanStatus"]; + riskLevel: components["schemas"]["AssetSecurityRiskLevel"]; + issueCodes: string[]; + details: components["schemas"]["JsonElement"]; + /** Format: date-time */ + createdAt: string; + }; + ContentAssetType: number; + ContentEntryCatalogItem: { + /** Format: uuid */ + id: string; + /** Format: uuid */ + regionId: null | string; + legacyId: null | string; + entryKey: string; + name: string; + entryType: components["schemas"]["ContentEntryType"]; + icon: null | string; + route: null | string; + description: null | string; + visibility: components["schemas"]["ContentVisibility"]; + accessRules: components["schemas"]["JsonElement"]; + layoutConfig: components["schemas"]["JsonElement"]; + /** Format: int32 */ + order: number | string; + }; + ContentEntryManagementItem: { + /** Format: uuid */ + id: string; + /** Format: uuid */ + regionId: null | string; + legacyId: null | string; + entryKey: string; + name: string; + entryType: components["schemas"]["ContentEntryType"]; + icon: null | string; + route: null | string; + description: null | string; + visibility: components["schemas"]["ContentVisibility"]; + accessRules: components["schemas"]["JsonElement"]; + layoutConfig: components["schemas"]["JsonElement"]; + /** Format: int32 */ + order: number | string; + isActive: boolean; + /** Format: date-time */ + createdAt: string; + /** Format: date-time */ + updatedAt: null | string; + }; + ContentEntryType: number; + ContentImportIssueModel: { + /** Format: uuid */ + id: string; + /** Format: uuid */ + jobId: string; + /** Format: uuid */ + itemId: null | string; + /** Format: int32 */ + rowNo: null | number | string; + severity: components["schemas"]["ImportIssueSeverity"]; + code: string; + fieldPath: null | string; + message: string; + details: components["schemas"]["JsonElement"]; + }; + ContentImportItemModel: { + /** Format: uuid */ + id: string; + /** Format: uuid */ + jobId: string; + /** Format: int32 */ + rowNo: number | string; + externalId: null | string; + status: components["schemas"]["ContentImportItemStatus"]; + targetType: null | string; + /** Format: uuid */ + targetId: null | string; + sourcePayload: components["schemas"]["JsonElement"]; + normalizedPayload: components["schemas"]["JsonElement"]; + contentHash: null | string; + /** Format: int32 */ + issuesCount: number | string; + }; + ContentImportItemStatus: number; + ContentImportJobDetail: { + job: components["schemas"]["ContentImportJobItem"]; + items: components["schemas"]["ContentImportItemModel"][]; + issues: components["schemas"]["ContentImportIssueModel"][]; + }; + ContentImportJobItem: { + /** Format: uuid */ + id: string; + /** Format: uuid */ + targetRegionId: null | string; + /** Format: uuid */ + targetSubjectId: null | string; + /** Format: uuid */ + targetCategoryId: null | string; + /** Format: uuid */ + targetContentNodeId: null | string; + /** Format: uuid */ + targetQuestionBankId: null | string; + importType: components["schemas"]["ContentImportType"]; + sourceFormat: components["schemas"]["ImportSourceFormat"]; + status: components["schemas"]["ContentImportStatus"]; + sourceName: null | string; + sourceHash: null | string; + dryRun: boolean; + /** Format: int32 */ + totalCount: number | string; + /** Format: int32 */ + validCount: number | string; + /** Format: int32 */ + errorCount: number | string; + /** Format: int32 */ + warningCount: number | string; + /** Format: int32 */ + insertedCount: number | string; + /** Format: int32 */ + updatedCount: number | string; + /** Format: int32 */ + skippedCount: number | string; + summary: components["schemas"]["JsonElement"]; + errorMessage: null | string; + /** Format: date-time */ + startedAt: null | string; + /** Format: date-time */ + finishedAt: null | string; + /** Format: date-time */ + createdAt: string; + /** Format: date-time */ + updatedAt: null | string; + }; + ContentImportStatus: number; + ContentImportType: number; + ContentManagementResultOfContentAssetManagementItem: { + item: null | components["schemas"]["ContentAssetManagementItem"]; + }; + ContentManagementResultOfContentEntryManagementItem: { + item: null | components["schemas"]["ContentEntryManagementItem"]; + }; + ContentManagementResultOfContentNodeManagementItem: { + item: null | components["schemas"]["ContentNodeManagementItem"]; + }; + ContentManagementResultOfHandbookChapter: { + item: null | components["schemas"]["HandbookChapter"]; + }; + ContentManagementResultOfHandbookEntry: { + item: null | components["schemas"]["HandbookEntry"]; + }; + ContentManagementResultOfHandbookSubject: { + item: null | components["schemas"]["HandbookSubject"]; + }; + ContentManagementResultOfMajor: { + item: null | components["schemas"]["Major"]; + }; + ContentManagementResultOfOperationContentItem: { + item: null | components["schemas"]["OperationContentItem"]; + }; + ContentManagementResultOfPracticeBlueprintManagementItem: { + item: null | components["schemas"]["PracticeBlueprintManagementItem"]; + }; + ContentManagementResultOfQuestionCollectionManagementItem: { + item: null | components["schemas"]["QuestionCollectionManagementItem"]; + }; + ContentManagementResultOfQuestionManagementItem: { + item: null | components["schemas"]["QuestionManagementItem"]; + }; + ContentManagementResultOfQuestionVideoManagementItem: { + item: null | components["schemas"]["QuestionVideoManagementItem"]; + }; + ContentManagementResultOfSchool: { + item: null | components["schemas"]["School"]; + }; + ContentManagementResultOfScorelineField: { + item: null | components["schemas"]["ScorelineField"]; + }; + ContentManagementResultOfScorelineRecord: { + item: null | components["schemas"]["ScorelineRecord"]; + }; + ContentManagementResultOfTenantAdminBadgeGrantItem: { + item: null | components["schemas"]["TenantAdminBadgeGrantItem"]; + }; + ContentManagementResultOfTenantAdminBadgeItem: { + item: null | components["schemas"]["TenantAdminBadgeItem"]; + }; + ContentManagementResultOfTenantAdminClassItem: { + item: null | components["schemas"]["TenantAdminClassItem"]; + }; + ContentManagementResultOfTenantAdminClassMemberItem: { + item: null | components["schemas"]["TenantAdminClassMemberItem"]; + }; + ContentManagementResultOfTenantAdminFeedbackItem: { + item: null | components["schemas"]["TenantAdminFeedbackItem"]; + }; + ContentManagementResultOfTenantAdminMemberItem: { + item: null | components["schemas"]["TenantAdminMemberItem"]; + }; + ContentManagementResultOfTenantAdminNotificationItem: { + item: null | components["schemas"]["TenantAdminNotificationItem"]; + }; + ContentManagementResultOfTenantAdminStudentFollowupItem: { + item: null | components["schemas"]["TenantAdminStudentFollowupItem"]; + }; + ContentManagementResultOfTenantAdminStudentItem: { + item: null | components["schemas"]["TenantAdminStudentItem"]; + }; + ContentManagementResultOfTenantAdminStudentNoteItem: { + item: null | components["schemas"]["TenantAdminStudentNoteItem"]; + }; + ContentManagementResultOfTenantAdminStudentStatusItem: { + item: null | components["schemas"]["TenantAdminStudentStatusItem"]; + }; + ContentManagementResultOfTenantBrandingItem: { + item: null | components["schemas"]["TenantBrandingItem"]; + }; + ContentManagementResultOfTenantDomainItem: { + item: null | components["schemas"]["TenantDomainItem"]; + }; + ContentManagementResultOfTenantIdentityProviderItem: { + item: null | components["schemas"]["TenantIdentityProviderItem"]; + }; + ContentManagementResultOfTenantSettingsItem: { + item: null | components["schemas"]["TenantSettingsItem"]; + }; + ContentManagementResultOfTenantSupervisionRuleItem: { + item: null | components["schemas"]["TenantSupervisionRuleItem"]; + }; + ContentManagementResultOfTenantThemeItem: { + item: null | components["schemas"]["TenantThemeItem"]; + }; + ContentManagementResultOfVideoManagementItem: { + item: null | components["schemas"]["VideoManagementItem"]; + }; + ContentManagementResultOfVocabularyUnit: { + item: null | components["schemas"]["VocabularyUnit"]; + }; + ContentManagementResultOfVocabularyWord: { + item: null | components["schemas"]["VocabularyWord"]; + }; + ContentMarkerType: number; + ContentNodeCatalogItem: { + /** Format: uuid */ + id: string; + /** Format: uuid */ + entryId: string; + /** Format: uuid */ + regionId: null | string; + /** Format: uuid */ + parentId: null | string; + legacyId: null | string; + nodeKey: null | string; + name: string; + nodeType: components["schemas"]["ContentNodeType"]; + markerType: null | components["schemas"]["ContentMarkerType"]; + markerConfig: components["schemas"]["JsonElement"]; + path: null | string; + /** Format: int32 */ + depth: number | string; + /** Format: int32 */ + order: number | string; + isSelectable: boolean; + isLeaf: boolean; + accessRules: components["schemas"]["JsonElement"]; + metadata: components["schemas"]["JsonElement"]; + }; + ContentNodeManagementItem: { + /** Format: uuid */ + id: string; + /** Format: uuid */ + entryId: string; + /** Format: uuid */ + regionId: null | string; + /** Format: uuid */ + parentId: null | string; + legacyId: null | string; + nodeKey: null | string; + name: string; + nodeType: components["schemas"]["ContentNodeType"]; + markerType: null | components["schemas"]["ContentMarkerType"]; + markerConfig: components["schemas"]["JsonElement"]; + path: null | string; + /** Format: int32 */ + depth: number | string; + /** Format: int32 */ + order: number | string; + isActive: boolean; + isSelectable: boolean; + isLeaf: boolean; + accessRules: components["schemas"]["JsonElement"]; + metadata: components["schemas"]["JsonElement"]; + /** Format: date-time */ + createdAt: string; + /** Format: date-time */ + updatedAt: null | string; + }; + ContentNodeType: number; + ContentStatus: number; + ContentVisibility: number; + Coupon: { + /** Format: uuid */ + planId?: null | string; + legacyId?: null | string; + code?: string; + discountType?: null | components["schemas"]["DiscountType"]; + /** Format: double */ + discountValue?: null | number | string; + /** Format: date-time */ + validFrom?: null | string; + /** Format: date-time */ + validTo?: null | string; + /** Format: int32 */ + maxUses?: null | number | string; + /** Format: int32 */ + usedCount?: number | string; + source?: null | string; + remark?: null | string; + /** Format: date-time */ + createdAt?: string; + /** Format: date-time */ + updatedAt?: string; + /** Format: uuid */ + tenantId?: string; + /** Format: uuid */ + id?: string; + }; + CouponRedemption: { + /** Format: uuid */ + couponId?: null | string; + /** Format: uuid */ + userId?: null | string; + /** Format: uuid */ + planId?: null | string; + /** Format: uuid */ + orderId?: null | string; + /** Format: uuid */ + regionId?: null | string; + legacyId?: null | string; + couponCode?: null | string; + status?: components["schemas"]["CouponRedemptionStatus"]; + /** Format: int32 */ + discountAppliedCents?: null | number | string; + source?: null | string; + remark?: null | string; + /** Format: date-time */ + claimedAt?: null | string; + /** Format: date-time */ + usedAt?: null | string; + /** Format: date-time */ + createdAt?: string; + /** Format: date-time */ + updatedAt?: string; + /** Format: uuid */ + tenantId?: string; + /** Format: uuid */ + id?: string; + }; + CouponRedemptionStatus: number; + /** @description 创建调账凭证请求 DTO。 */ + CreateAdjustmentVoucherDto: { + /** + * Format: uuid + * @description 工单 ID。 + */ + issueId?: null | string; + /** + * Format: uuid + * @description 批次 ID。 + */ + batchId?: null | string; + /** + * Format: uuid + * @description 兑换项 ID。 + */ + itemId?: null | string; + /** + * Format: uuid + * @description 订单 ID。 + */ + orderId?: null | string; + /** + * Format: uuid + * @description 支付记录 ID。 + */ + paymentId?: null | string; + /** + * Format: uuid + * @description 退款申请 ID。 + */ + refundRequestId?: null | string; + /** @description 方向。 */ + direction?: components["schemas"]["CommerceAdjustmentDirection"]; + /** + * Format: int32 + * @description 金额,单位为分。 + */ + amountCents?: number | string; + /** @description 币种。 */ + currency?: null | string; + /** @description 原因。 */ + reason: string; + /** @description 证明资产键。 */ + proofAssetKey?: null | string; + /** @description 扩展元数据。 */ + metadata?: components["schemas"]["JsonElement"]; + }; + /** @description 创建租户后台任务请求。 */ + CreateBackgroundJobDto: { + /** @description 任务类型。 */ + jobType?: string; + /** @description 任务载荷。 */ + payload?: components["schemas"]["JsonElement"]; + /** + * Format: date-time + * @description 计划运行时间。 + */ + runAfter?: null | string; + /** + * Format: int32 + * @description 最大重试次数。 + */ + maxRetries?: number | string; + /** @description 同租户同任务类型内的可选幂等键。 */ + idempotencyKey?: null | string; + }; + /** @description 创建编码批次请求 DTO。 */ + CreateCodeBatchDto: { + /** @description 名称。 */ + name: string; + /** + * Format: int32 + * @description 总数量。 + */ + totalCount?: number | string; + /** + * Format: int32 + * @description 天数。 + */ + days?: number | string; + /** + * Format: uuid + * @description 地区 ID。 + */ + regionId?: null | string; + /** @description 售卖类型。 */ + saleType?: null | string; + /** @description 渠道。 */ + channel?: null | string; + /** + * Format: int32 + * @description 默认单价,单位为分。 + */ + defaultUnitPriceCents?: null | number | string; + /** + * Format: int32 + * @description 成本价,单位为分。 + */ + costPriceCents?: null | number | string; + /** @description 备注。 */ + remark?: null | string; + }; + /** @description 创建交易订单请求 DTO。 */ + CreateCommerceOrderDto: { + /** + * Format: uuid + * @description 套餐 ID。 + */ + planId: string; + /** + * Format: int32 + * @description 数量。 + */ + quantity?: number | string; + /** @description 支付方式。 */ + payMethod?: null | string; + /** @description 支付渠道。 */ + payProvider?: null | string; + /** + * Format: uuid + * @description 地区 ID。 + */ + regionId?: null | string; + /** @description 优惠券码。 */ + couponCode?: null | string; + /** + * Format: uuid + * @description 优惠券领取记录 ID。 + */ + couponRedemptionId?: null | string; + }; + /** @description 创建交易支付请求 DTO。 */ + CreateCommercePaymentDto: { + /** @description 订单号。 */ + orderNo: string; + /** @description 服务提供方。 */ + provider: string; + /** @description 方式。 */ + method: string; + /** @description 微信或支付渠道 openid。 */ + openId?: null | string; + /** @description 支付完成返回地址。 */ + returnUrl?: null | string; + /** @description 支付取消返回地址。 */ + quitUrl?: null | string; + }; + /** @description 创建佣金结算凭证请求。 */ + CreateCommissionProofDto: { + /** + * Format: uuid + * @description 结算单 ID。 + */ + settlementId: string; + /** @description 凭证类型。 */ + proofType?: null | string; + /** @description 标题。 */ + title?: null | string; + /** @description 说明。 */ + description?: null | string; + /** + * Format: uuid + * @description 资产 ID。 + */ + assetId?: null | string; + /** @description 外部链接。 */ + externalUrl?: null | string; + /** + * Format: int32 + * @description 金额,单位为分。 + */ + amountCents?: null | number | string; + /** @description 支付方式。 */ + paymentMethod?: null | string; + /** @description 收款账号。 */ + paymentAccount?: null | string; + /** + * Format: date-time + * @description 支付时间。 + */ + paidAt?: null | string; + metadata?: null | components["schemas"]["JsonElement"]; + }; + /** @description 创建平台账务订单请求 DTO。 */ + CreatePlatformBillingOrderDto: { + /** Format: uuid */ + quoteId: string; + idempotencyKey: string; + }; + /** @description 创建平台账务支付请求 DTO。 */ + CreatePlatformBillingPaymentDto: { + provider: string; + method: string; + idempotencyKey: string; + openId: null | string; + returnUrl: null | string; + quitUrl: null | string; + }; + /** @description 创建平台账务报价请求 DTO。 */ + CreatePlatformBillingQuoteDto: { + /** Format: uuid */ + baseOfferingVersionId: string; + addOnOfferingVersionIds: null | string[]; + purpose: components["schemas"]["PlatformBillingOrderPurpose"]; + idempotencyKey: string; + }; + /** @description 创建平台租户请求 DTO。 */ + CreatePlatformTenantDto: { + /** @description 短编码。 */ + slug: string; + /** @description 名称。 */ + name: string; + /** @description 法定名称。 */ + legalName?: null | string; + /** @description 状态。 */ + status?: components["schemas"]["TenantStatus"]; + /** @description 账务状态。 */ + billingStatus?: components["schemas"]["BillingStatus"]; + /** @description 扩展元数据。 */ + metadata?: components["schemas"]["JsonElement"]; + /** @description 租户首次开通使用的自定义主域名。 */ + primaryDomainHost: string; + /** @description 租户负责人邮箱。 */ + ownerEmail?: null | string; + /** @description 租户负责人手机号。 */ + ownerPhone?: null | string; + /** @description 租户负责人姓名。 */ + ownerName: string; + /** + * Format: uuid + * @description 初始试用套餐版本;为空时使用平台配置的默认基础套餐。 + */ + initialOfferingVersionId?: null | string; + /** + * Format: int32 + * @description 试用天数;为空时使用平台配置的默认天数。 + */ + trialDays?: null | number | string; + /** @description 收款模式。 */ + collectionMode?: components["schemas"]["TenantBillingCollectionMode"]; + /** @description 默认支付 Provider。 */ + defaultPaymentProvider: string; + /** @description 是否自动生成续费应收。 */ + autoGenerateRenewal?: boolean; + /** + * Format: int32 + * @description 续费应收提前生成天数。 + */ + renewalLeadDays?: number | string; + }; + /** @description 创建积分兑换订单请求 DTO。 */ + CreatePointExchangeOrderDto: { + /** + * Format: uuid + * @description 兑换项 ID。 + */ + itemId: string; + }; + /** @description 创建练习会话请求 DTO。 */ + CreatePracticeSessionDto: { + /** @description 模式。 */ + mode?: null | string; + /** @description 目标类型。 */ + targetType?: null | string; + /** + * Format: uuid + * @description 目标 ID。 + */ + targetId?: null | string; + /** + * Format: uuid + * @description 练习蓝图 ID。 + */ + blueprintId?: null | string; + /** + * Format: uuid + * @description 题集 ID。 + */ + collectionId?: null | string; + /** + * Format: uuid + * @description 内容入口 ID。 + */ + entryId?: null | string; + /** + * Format: uuid + * @description 内容节点 ID。 + */ + contentNodeId?: null | string; + /** + * Format: int32 + * @description 题目数量上限。 + */ + questionLimit?: null | number | string; + /** + * Format: int32 + * @description 时长,单位为分钟。 + */ + durationMinutes?: null | number | string; + /** + * Format: double + * @description 总分。 + */ + totalScore?: null | number | string; + /** @description 扩展元数据。 */ + metadata?: components["schemas"]["JsonElement"]; + }; + /** @description 创建对账批次请求 DTO。 */ + CreateReconciliationBatchDto: { + /** @description 服务提供方。 */ + provider: string; + /** + * Format: date + * @description 账单日期。 + */ + billDate?: string; + /** @description 账单类型。 */ + billType?: components["schemas"]["ReconciliationBillType"]; + /** @description 来源。 */ + source?: components["schemas"]["ReconciliationSource"]; + /** @description 来源名称。 */ + sourceName?: null | string; + /** @description 来源哈希。 */ + sourceHash: string; + /** @description 扩展元数据。 */ + metadata?: components["schemas"]["JsonElement"]; + }; + /** @description 创建退款Request请求 DTO。 */ + CreateRefundRequestDto: { + /** + * Format: uuid + * @description 订单 ID。 + */ + orderId: string; + /** + * Format: uuid + * @description 支付记录 ID。 + */ + paymentId?: null | string; + /** + * Format: int32 + * @description 金额,单位为分。 + */ + amountCents?: number | string; + /** @description 原因。 */ + reason?: null | string; + /** @description 权益动作。 */ + entitlementAction?: components["schemas"]["RefundEntitlementAction"]; + /** @description 扩展元数据。 */ + metadata?: components["schemas"]["JsonElement"]; + }; + /** @description 创建分类节点请求 DTO。 */ + CreateTaxonomyNodeDto: { + /** + * Format: uuid + * @description 父节点 ID。 + */ + parentId?: null | string; + parentSource?: null | components["schemas"]["QuestionSource"]; + /** @description 节点Type。 */ + nodeType: components["schemas"]["TaxonomyNodeType"]; + /** @description 编码。 */ + code: string; + /** @description 名称。 */ + name: string; + /** + * Format: int32 + * @description 排序值。 + */ + sortOrder?: number | string; + /** @description 扩展元数据。 */ + metadata?: components["schemas"]["JsonElement"]; + }; + /** @description 创建租户域名请求 DTO。 */ + CreateTenantDomainDto: { + /** @description 访问域名。 */ + host: string; + /** @description 域名类型。 */ + domainType?: null | string; + /** @description 是否主域名。 */ + isPrimary?: boolean; + }; + CrmConfigItem: { + /** Format: uuid */ + id: string; + enabled: boolean; + url: null | string; + secretRef: null | string; + assignmentMode: string; + assignmentPool: components["schemas"]["JsonElement"]; + formName: null | string; + examType: null | string; + /** Format: int32 */ + timeoutSeconds: null | number | string; + /** Format: int32 */ + delaySeconds: null | number | string; + /** Format: date-time */ + updatedAt: string; + }; + CrmDeadLetterResult: { + summary: components["schemas"]["CrmDeadLetterSummary"]; + items: components["schemas"]["CrmQueueItem"][]; + }; + CrmDeadLetterSummary: { + /** Format: int32 */ + failed: number | string; + /** Format: int32 */ + discarded: number | string; + /** Format: int32 */ + total: number | string; + /** Format: date-time */ + oldestOpenAt: null | string; + }; + CrmListOfCrmQueueItem: { + items: components["schemas"]["CrmQueueItem"][]; + }; + CrmListOfCrmQueueLogItem: { + items: components["schemas"]["CrmQueueLogItem"][]; + }; + /** @description CRM队列Action请求 DTO。 */ + CrmQueueActionDto: { + /** + * Format: uuid + * @description 队列任务 ID。 + */ + queueId: string; + /** @description 操作。 */ + action?: null | string; + /** @description 备注。 */ + note?: null | string; + metadata?: null | components["schemas"]["JsonElement"]; + }; + CrmQueueItem: { + /** Format: uuid */ + id: string; + status: string; + /** Format: int32 */ + attempts: number | string; + leadId: null | string; + recordId: null | string; + source: null | string; + provider: null | string; + lastError: null | string; + /** Format: date-time */ + scheduledAt: null | string; + /** Format: date-time */ + nextAttemptAt: null | string; + payload: components["schemas"]["JsonElement"]; + }; + CrmQueueLogItem: { + /** Format: uuid */ + id: string; + /** Format: uuid */ + queueId: null | string; + recordId: null | string; + leadId: null | string; + /** Format: int32 */ + httpCode: null | number | string; + outcome: string; + errorMessage: null | string; + operation: null | string; + requestPayload: components["schemas"]["JsonElement"]; + responseSummary: null | string; + /** Format: date-time */ + createdAt: string; + }; + CrmQueuePreviewItem: { + /** Format: uuid */ + id: string; + status: string; + source: null | string; + }; + CrmWebhookLog: { + legacyId?: null | string; + recordId?: null | string; + leadId?: null | string; + /** Format: int32 */ + httpCode?: null | number | string; + outcome?: null | string; + errorMessage?: null | string; + requestBody?: null | string; + requestPayload?: components["schemas"]["JsonElement"]; + responseSummary?: null | string; + /** Format: date-time */ + signedAt?: null | string; + /** Format: int32 */ + attempt?: null | number | string; + /** Format: date-time */ + createdAt?: string; + /** Format: date-time */ + updatedAt?: string; + /** Format: uuid */ + tenantId?: string; + /** Format: uuid */ + id?: string; + }; + CrmWebhookQueueItem: { + legacyId?: null | string; + recordId?: null | string; + leadId?: null | string; + source?: null | string; + provider?: null | string; + status?: components["schemas"]["CrmWebhookQueueStatus"]; + /** Format: date-time */ + scheduledAt?: null | string; + /** Format: int32 */ + attempts?: number | string; + /** Format: date-time */ + nextAttemptAt?: null | string; + /** Format: date-time */ + lastAttemptAt?: null | string; + lastError?: null | string; + /** Format: int32 */ + lastHttpCode?: null | number | string; + lastResponseSummary?: null | string; + /** Format: date-time */ + sentAt?: null | string; + idempotencyKey?: null | string; + targetUrl?: null | string; + payload?: components["schemas"]["JsonElement"]; + /** Format: date-time */ + createdAt?: string; + /** Format: date-time */ + updatedAt?: string; + /** Format: uuid */ + tenantId?: string; + /** Format: uuid */ + id?: string; + }; + CrmWebhookQueueStatus: number; + CurrentEntitlementItem: { + isActive: boolean; + entitlementType: string; + /** Format: date-time */ + startsAt: null | string; + /** Format: date-time */ + expiresAt: null | string; + status: string; + /** Format: int32 */ + daysLeft: null | number | string; + }; + /** @description 当前请求租户和当前用户在该租户内的权限摘要。 */ + CurrentTenantResponse: { + /** + * Format: uuid + * @description 租户 ID。 + */ + tenantId: string; + /** @description 租户名称。 */ + tenantName: string; + /** @description 租户编码。 */ + tenantSlug: string; + /** @description 租户状态。 */ + status: components["schemas"]["TenantStatus"]; + /** @description 当前用户在租户内的角色。 */ + role: components["schemas"]["TenantRole"]; + }; + /** @description 管理侧知识手册章节写入请求。 */ + DirectHandbookChapterDto: { + /** + * Format: uuid + * @description ID。 + */ + id?: null | string; + /** + * Format: uuid + * @description 科目 ID。 + */ + subjectId?: null | string; + /** + * Format: uuid + * @description 内容入口 ID。 + */ + entryId?: null | string; + /** + * Format: uuid + * @description 内容节点 ID。 + */ + contentNodeId?: null | string; + /** @description 历史系统 ID。 */ + legacyId?: null | string; + /** @description 名称。 */ + name: string; + /** @description 说明。 */ + description?: null | string; + /** + * Format: int32 + * @description 显示顺序。 + */ + order?: null | number | string; + /** @description 是否启用。 */ + isActive?: null | boolean; + /** @description 扩展元数据。 */ + metadata?: components["schemas"]["JsonElement"]; + }; + /** @description 管理侧知识手册条目写入请求。 */ + DirectHandbookEntryDto: { + /** + * Format: uuid + * @description ID。 + */ + id?: null | string; + /** + * Format: uuid + * @description 章节 ID。 + */ + chapterId?: null | string; + /** + * Format: uuid + * @description 内容入口 ID。 + */ + entryId?: null | string; + /** + * Format: uuid + * @description 内容节点 ID。 + */ + contentNodeId?: null | string; + /** @description 历史系统 ID。 */ + legacyId?: null | string; + /** @description 标题。 */ + title: string; + /** @description 摘要。 */ + summary?: null | string; + /** @description 内容。 */ + content?: null | string; + /** @description 标签列表。 */ + tags?: components["schemas"]["JsonElement"]; + /** + * Format: int32 + * @description 显示顺序。 + */ + order?: null | number | string; + /** @description 是否启用。 */ + isActive?: null | boolean; + /** @description 扩展元数据。 */ + metadata?: components["schemas"]["JsonElement"]; + }; + /** @description 管理侧知识手册科目写入请求。 */ + DirectHandbookSubjectDto: { + /** + * Format: uuid + * @description ID。 + */ + id?: null | string; + /** + * Format: uuid + * @description 地区 ID。 + */ + regionId?: null | string; + /** + * Format: uuid + * @description 院校 ID。 + */ + schoolId?: null | string; + /** + * Format: uuid + * @description 专业 ID。 + */ + majorId?: null | string; + /** + * Format: uuid + * @description 内容入口 ID。 + */ + entryId?: null | string; + /** + * Format: uuid + * @description 内容节点 ID。 + */ + contentNodeId?: null | string; + /** @description 历史系统 ID。 */ + legacyId?: null | string; + /** @description 名称。 */ + name: string; + /** @description 类型。 */ + type?: null | string; + /** @description 图标。 */ + icon?: null | string; + /** @description 颜色。 */ + color?: null | string; + /** @description 说明。 */ + description?: null | string; + /** + * Format: int32 + * @description 显示顺序。 + */ + order?: null | number | string; + /** @description 是否启用。 */ + isActive?: null | boolean; + /** @description 扩展元数据。 */ + metadata?: components["schemas"]["JsonElement"]; + }; + /** @description 管理侧内容导入请求。 */ + DirectImportDto: { + /** @description 来源格式。 */ + sourceFormat?: null | string; + /** @description 来源名称。 */ + sourceName?: null | string; + /** + * Format: uuid + * @description 地区 ID。 + */ + regionId?: null | string; + /** + * Format: uuid + * @description 内容入口 ID。 + */ + entryId?: null | string; + /** + * Format: uuid + * @description 内容节点 ID。 + */ + contentNodeId?: null | string; + /** + * Format: uuid + * @description 科目 ID。 + */ + subjectId?: null | string; + /** + * Format: uuid + * @description 分类 ID。 + */ + categoryId?: null | string; + /** + * Format: uuid + * @description 题库 ID。 + */ + questionBankId?: null | string; + /** + * Format: uuid + * @description 题集 ID。 + */ + collectionId?: null | string; + /** @description 是否异步执行。 */ + async?: null | boolean; + /** @description 数据项列表。 */ + items?: null | unknown[]; + /** @description 单元数据列表。 */ + units?: null | unknown[]; + /** @description 单词数据列表。 */ + words?: null | unknown[]; + /** @description 科目数据列表。 */ + subjects?: null | unknown[]; + /** @description 条目数据列表。 */ + entries?: null | unknown[]; + /** @description 字段数据列表。 */ + fields?: null | unknown[]; + /** @description 院校数据列表。 */ + schools?: null | unknown[]; + /** @description 专业数据列表。 */ + majors?: null | unknown[]; + /** @description 记录数据列表。 */ + records?: null | unknown[]; + /** @description 视频数据列表。 */ + videos?: null | unknown[]; + }; + /** @description 管理侧内容导入任务查询请求。 */ + DirectImportJobDto: { + /** + * Format: uuid + * @description 任务 ID。 + */ + jobId?: string; + }; + /** @description 管理侧专业写入请求。 */ + DirectMajorDto: { + /** + * Format: uuid + * @description ID。 + */ + id?: null | string; + /** + * Format: uuid + * @description 地区 ID。 + */ + regionId?: null | string; + /** + * Format: uuid + * @description 院校 ID。 + */ + schoolId?: null | string; + /** @description 历史系统 ID。 */ + legacyId?: null | string; + /** @description 名称。 */ + name: string; + /** @description 说明。 */ + description?: null | string; + /** @description 备考建议。 */ + studyTips?: null | string; + /** + * Format: int32 + * @description 显示顺序。 + */ + order?: null | number | string; + /** @description 是否启用。 */ + isActive?: null | boolean; + }; + /** @description 管理侧运营内容写入请求。 */ + DirectOperationContentDto: { + /** + * Format: uuid + * @description ID。 + */ + id?: null | string; + /** + * Format: uuid + * @description 地区 ID。 + */ + regionId?: null | string; + /** + * Format: uuid + * @description 院校 ID。 + */ + schoolId?: null | string; + /** @description 历史系统 ID。 */ + legacyId?: null | string; + /** @description 标题。 */ + title?: null | string; + /** @description 副标题。 */ + subtitle?: null | string; + /** @description 内容。 */ + content?: null | string; + /** @description 问题。 */ + question?: null | string; + /** @description 答案。 */ + answer?: null | string; + /** @description 链接地址。 */ + link?: null | string; + /** @description 按钮文案。 */ + buttonText?: null | string; + /** @description 按钮链接。 */ + buttonLink?: null | string; + /** @description 背景颜色。 */ + backgroundColor?: null | string; + /** @description 边框颜色。 */ + borderColor?: null | string; + /** @description 考试名称。 */ + examName?: null | string; + /** + * Format: date-time + * @description 考试时间。 + */ + examAt?: null | string; + /** @description 考试类型。 */ + examType?: null | string; + /** @description 说明。 */ + description?: null | string; + /** + * Format: int32 + * @description 显示顺序。 + */ + order?: null | number | string; + /** @description 是否启用。 */ + isActive?: null | boolean; + /** @description 扩展元数据。 */ + metadata?: components["schemas"]["JsonElement"]; + }; + /** @description 管理侧题目视频绑定请求。 */ + DirectQuestionVideoDto: { + /** + * Format: uuid + * @description 题目 ID。 + */ + questionId?: string; + /** + * Format: uuid + * @description 视频 ID。 + */ + videoId?: string; + /** @description 历史系统 ID。 */ + legacyId?: null | string; + /** @description 视频类型。 */ + videoType?: null | string; + /** + * Format: int32 + * @description 显示顺序。 + */ + order?: null | number | string; + /** @description 扩展元数据。 */ + metadata?: components["schemas"]["JsonElement"]; + }; + /** @description 管理侧题目写入请求。 */ + DirectQuestionWriteDto: { + /** + * Format: uuid + * @description 题目 ID。 + */ + questionId?: null | string; + /** + * Format: uuid + * @description 题库 ID。 + */ + questionBankId?: null | string; + /** + * Format: uuid + * @description 科目 ID。 + */ + subjectId?: null | string; + /** + * Format: uuid + * @description 分类 ID。 + */ + categoryId?: null | string; + /** + * Format: uuid + * @description 节点 ID。 + */ + nodeId?: null | string; + /** + * Format: uuid + * @description 内容入口 ID。 + */ + entryId?: null | string; + /** + * Format: uuid + * @description 内容节点 ID。 + */ + contentNodeId?: null | string; + /** + * Format: uuid + * @description 主题集 ID。 + */ + primaryCollectionId?: null | string; + /** @description 历史系统 ID。 */ + legacyId?: null | string; + /** @description 类型。 */ + type?: null | string; + /** @description 类型显示名。 */ + typeLabel?: null | string; + /** + * Format: int32 + * @description 难度。 + */ + difficulty?: null | number | string; + /** @description 标签列表。 */ + tags?: components["schemas"]["JsonElement"]; + /** @description 内容。 */ + content?: null | string; + /** @description 选项配置。 */ + options?: components["schemas"]["JsonElement"]; + /** + * Format: int32 + * @description 正确选项索引。 + */ + correctOptionIndex?: null | number | string; + /** @description 正确选项索引列表。 */ + correctOptionIndices?: components["schemas"]["JsonElement"]; + /** @description 文字答案。 */ + answerText?: null | string; + /** @description 解析。 */ + explanation?: null | string; + /** @description 子题列表。 */ + subQuestions?: components["schemas"]["JsonElement"]; + /** @description 代码语言。 */ + codeLang?: null | string; + /** @description 代码模板。 */ + codeTemplate?: null | string; + /** @description 媒体地址。 */ + mediaUrl?: null | string; + /** @description 状态。 */ + status?: null | string; + /** @description 考试标记配置。 */ + examMarkers?: components["schemas"]["JsonElement"]; + /** @description 来源哈希。 */ + sourceHash?: null | string; + /** @description 是否创建题目版本。 */ + createVersion?: null | boolean; + }; + /** @description 管理侧院校写入请求。 */ + DirectSchoolDto: { + /** + * Format: uuid + * @description ID。 + */ + id?: null | string; + /** + * Format: uuid + * @description 地区 ID。 + */ + regionId?: null | string; + /** @description 历史系统 ID。 */ + legacyId?: null | string; + /** @description 名称。 */ + name: string; + /** @description 专业考试日期。 */ + professionalExamDate?: null | string; + /** @description 扩展元数据。 */ + metadata?: components["schemas"]["JsonElement"]; + }; + /** @description 管理侧分数线字段写入请求。 */ + DirectScorelineFieldDto: { + /** + * Format: uuid + * @description ID。 + */ + id?: null | string; + /** + * Format: uuid + * @description 地区 ID。 + */ + regionId?: null | string; + /** @description 历史系统 ID。 */ + legacyId?: null | string; + /** @description 字段键。 */ + fieldKey: string; + /** @description 字段名称。 */ + fieldName: string; + /** @description 字段类型。 */ + fieldType?: null | string; + /** @description 单位。 */ + unit?: null | string; + /** @description 是否可筛选。 */ + isFilter?: null | boolean; + /** @description 是否必填。 */ + isRequired?: null | boolean; + /** @description 是否可见。 */ + isVisible?: null | boolean; + /** @description 是否参与趋势展示。 */ + isTrend?: null | boolean; + /** @description 选项配置。 */ + options?: components["schemas"]["JsonElement"]; + /** @description 占位提示。 */ + placeholder?: null | string; + /** @description 说明。 */ + description?: null | string; + /** + * Format: int32 + * @description 显示顺序。 + */ + order?: null | number | string; + }; + /** @description 管理侧分数线记录写入请求。 */ + DirectScorelineRecordDto: { + /** + * Format: uuid + * @description ID。 + */ + id?: null | string; + /** + * Format: uuid + * @description 地区 ID。 + */ + regionId?: null | string; + /** + * Format: uuid + * @description 院校 ID。 + */ + schoolId?: null | string; + /** + * Format: uuid + * @description 专业 ID。 + */ + majorId?: null | string; + /** @description 历史系统 ID。 */ + legacyId?: null | string; + /** + * Format: int32 + * @description 年份。 + */ + year?: number | string; + /** @description 院校名称。 */ + schoolName?: null | string; + /** @description 专业名称。 */ + majorName?: null | string; + /** @description 动态字段值。 */ + fieldValues?: components["schemas"]["JsonElement"]; + }; + /** @description 管理侧视频写入请求。 */ + DirectVideoDto: { + /** + * Format: uuid + * @description ID。 + */ + id?: null | string; + /** + * Format: uuid + * @description 科目 ID。 + */ + subjectId?: null | string; + /** @description 历史系统 ID。 */ + legacyId?: null | string; + /** @description 标题。 */ + title: string; + /** @description 说明。 */ + description?: null | string; + /** @description 视频地址。 */ + videoUrl?: null | string; + /** @description 缩略图地址。 */ + thumbnailUrl?: null | string; + /** + * Format: int32 + * @description 时长,单位为秒。 + */ + durationSeconds?: null | number | string; + /** @description 知识标签。 */ + knowledgeTags?: components["schemas"]["JsonElement"]; + /** @description 是否通用视频。 */ + isGeneral?: null | boolean; + /** + * Format: int32 + * @description 难度。 + */ + difficulty?: null | number | string; + /** + * Format: int32 + * @description 显示顺序。 + */ + order?: null | number | string; + /** @description 是否启用。 */ + isActive?: null | boolean; + /** @description 扩展元数据。 */ + metadata?: components["schemas"]["JsonElement"]; + }; + /** @description 管理侧词汇单元写入请求。 */ + DirectVocabularyUnitDto: { + /** + * Format: uuid + * @description ID。 + */ + id?: null | string; + /** + * Format: uuid + * @description 地区 ID。 + */ + regionId?: null | string; + /** + * Format: uuid + * @description 内容入口 ID。 + */ + entryId?: null | string; + /** + * Format: uuid + * @description 内容节点 ID。 + */ + contentNodeId?: null | string; + /** @description 历史系统 ID。 */ + legacyId?: null | string; + /** @description 名称。 */ + name: string; + /** @description 说明。 */ + description?: null | string; + /** + * Format: int32 + * @description 单词数量。 + */ + wordCount?: null | number | string; + /** + * Format: int32 + * @description 显示顺序。 + */ + order?: null | number | string; + /** @description 是否启用。 */ + isActive?: null | boolean; + /** @description 扩展元数据。 */ + metadata?: components["schemas"]["JsonElement"]; + }; + /** @description 管理侧词汇单词写入请求。 */ + DirectVocabularyWordDto: { + /** + * Format: uuid + * @description ID。 + */ + id?: null | string; + /** + * Format: uuid + * @description 单元 ID。 + */ + unitId?: null | string; + /** + * Format: uuid + * @description 内容入口 ID。 + */ + entryId?: null | string; + /** + * Format: uuid + * @description 内容节点 ID。 + */ + contentNodeId?: null | string; + /** @description 历史系统 ID。 */ + legacyId?: null | string; + /** @description 单词。 */ + word: string; + /** @description 音标。 */ + phonetic?: null | string; + /** @description 释义。 */ + meaning?: null | string; + /** @description 例句。 */ + example?: null | string; + /** @description 例句翻译。 */ + exampleTranslation?: null | string; + /** + * Format: int32 + * @description 难度。 + */ + difficulty?: null | number | string; + /** @description 标签列表。 */ + tags?: components["schemas"]["JsonElement"]; + /** + * Format: int32 + * @description 显示顺序。 + */ + order?: null | number | string; + /** @description 是否启用。 */ + isActive?: null | boolean; + /** @description 扩展元数据。 */ + metadata?: components["schemas"]["JsonElement"]; + }; + /** @description 禁用平台DunningChannel请求 DTO。 */ + DisablePlatformBillingDunningChannelDto: { + /** + * Format: uuid + * @description 通知渠道 ID。 + */ + channelId: string; + /** @description 原因。 */ + reason?: null | string; + }; + /** @description 禁用租户管理端成员请求 DTO。 */ + DisableTenantAdminMemberDto: { + /** + * Format: uuid + * @description 成员关系 ID。 + */ + membershipId: string; + }; + DiscountType: number; + ExamCountdownItem: { + /** Format: uuid */ + id: string; + legacyId: null | string; + /** Format: uuid */ + regionId: null | string; + /** Format: uuid */ + schoolId: null | string; + examName: string; + /** Format: date-time */ + examAt: null | string; + examType: null | string; + description: null | string; + metadata: components["schemas"]["JsonElement"]; + /** Format: int32 */ + order: number | string; + isActive: boolean; + /** Format: int32 */ + daysLeft: null | number | string; + }; + ExamCountdownList: { + items: components["schemas"]["ExamCountdownItem"][]; + /** Format: uuid */ + regionId: null | string; + /** Format: uuid */ + schoolId: null | string; + }; + ExamDateCatalogItem: { + /** Format: uuid */ + id: string; + legacyId: null | string; + /** Format: uuid */ + regionId: null | string; + /** Format: uuid */ + schoolId: null | string; + examName: string; + /** Format: date-time */ + examAt: null | string; + examType: null | string; + description: null | string; + metadata: components["schemas"]["JsonElement"]; + /** Format: int32 */ + order: number | string; + isActive: boolean; + /** Format: int32 */ + daysLeft: null | number | string; + }; + FaqCatalogItem: { + /** Format: uuid */ + id: string; + legacyId: null | string; + /** Format: uuid */ + regionId: null | string; + question: null | string; + answer: null | string; + /** Format: int32 */ + order: number | string; + isActive: boolean; + }; + FavoriteQuestionItem: { + /** Format: uuid */ + questionReferenceId: string; + locator: components["schemas"]["QuestionLocator"]; + /** Format: date-time */ + createdAt: string; + }; + /** @description 收藏单词请求 DTO。 */ + FavoriteWordDto: { + /** + * Format: uuid + * @description 单词 ID。 + */ + wordId: string; + /** @description 是否收藏。 */ + favorite?: null | boolean; + /** @description 备注。 */ + note?: null | string; + }; + FavoriteWordItem: { + /** Format: uuid */ + wordId: string; + note: null | string; + /** Format: date-time */ + favoritedAt: null | string; + }; + FeatureQuotaSnapshot: { + metricCode: string; + /** Format: int64 */ + usedValue: number | string; + /** Format: int64 */ + limitValue: number | string; + /** Format: int32 */ + usedPercent: number | string; + warning: boolean; + exceeded: boolean; + /** Format: date-time */ + periodStart: string; + /** Format: date-time */ + periodEnd: string; + }; + FeedbackItem: { + /** Format: uuid */ + id: string; + /** Format: uuid */ + questionId: null | string; + type: null | string; + title: null | string; + category: null | string; + description: null | string; + status: string; + priority: string; + contact: null | string; + attachments: components["schemas"]["JsonElement"]; + metadata: components["schemas"]["JsonElement"]; + /** Format: date-time */ + createdAt: string; + /** Format: date-time */ + updatedAt: string; + }; + /** @description 生成佣金结算单请求 DTO。 */ + GenerateCommissionSettlementDto: { + /** @description 开始日期,格式为 yyyy-MM-dd。 */ + startDate: string; + /** @description 结束日期,格式为 yyyy-MM-dd。 */ + endDate: string; + /** + * Format: uuid + * @description 推荐人用户 ID。 + */ + referrerUserId: string; + /** @description 状态。 */ + status?: null | string; + /** @description 备注。 */ + remark?: null | string; + metadata?: null | components["schemas"]["JsonElement"]; + }; + /** @description 授予租户管理端徽章请求 DTO。 */ + GrantTenantAdminBadgeDto: { + /** + * Format: uuid + * @description 用户 ID。 + */ + userId: string; + /** + * Format: uuid + * @description 徽章 ID。 + */ + badgeId: string; + /** @description 历史系统 ID。 */ + legacyId?: null | string; + /** @description 备注。 */ + note?: null | string; + /** + * Format: date-time + * @description 授予时间。 + */ + grantedAt?: null | string; + /** @description 扩展元数据。 */ + metadata?: components["schemas"]["JsonElement"]; + }; + /** @description 为已有租户补录试用订阅。 */ + GrantTenantTrialDto: { + /** Format: uuid */ + tenantId: string; + /** Format: uuid */ + baseOfferingVersionId: string; + /** Format: int32 */ + trialDays: number | string; + idempotencyKey: string; + reason: string; + }; + HandbookChapter: { + /** Format: uuid */ + subjectId?: null | string; + /** Format: uuid */ + entryId?: null | string; + /** Format: uuid */ + contentNodeId?: null | string; + legacyId?: null | string; + name?: string; + description?: null | string; + /** Format: int32 */ + sortOrder?: number | string; + isActive?: boolean; + sourceHash?: null | string; + metadata?: components["schemas"]["JsonElement"]; + /** Format: date-time */ + createdAt?: string; + /** Format: date-time */ + updatedAt?: string; + /** Format: uuid */ + tenantId?: string; + /** Format: uuid */ + id?: string; + }; + HandbookChapterCatalogItem: { + /** Format: uuid */ + id: string; + legacyId: null | string; + /** Format: uuid */ + subjectId: null | string; + /** Format: uuid */ + entryId: null | string; + /** Format: uuid */ + contentNodeId: null | string; + name: string; + description: null | string; + /** Format: int32 */ + order: number | string; + metadata: components["schemas"]["JsonElement"]; + }; + HandbookEntry: { + /** Format: uuid */ + chapterId?: null | string; + /** Format: uuid */ + entryId?: null | string; + /** Format: uuid */ + contentNodeId?: null | string; + legacyId?: null | string; + title?: string; + summary?: null | string; + content?: null | string; + tags?: components["schemas"]["JsonElement"]; + /** Format: int32 */ + sortOrder?: number | string; + isActive?: boolean; + sourceHash?: null | string; + metadata?: components["schemas"]["JsonElement"]; + /** Format: date-time */ + createdAt?: string; + /** Format: date-time */ + updatedAt?: string; + /** Format: uuid */ + tenantId?: string; + /** Format: uuid */ + id?: string; + }; + HandbookEntryCatalogItem: { + /** Format: uuid */ + id: string; + legacyId: null | string; + /** Format: uuid */ + chapterId: null | string; + /** Format: uuid */ + entryId: null | string; + /** Format: uuid */ + contentNodeId: null | string; + title: string; + summary: null | string; + content: null | string; + tags: components["schemas"]["JsonElement"]; + /** Format: int32 */ + order: number | string; + metadata: components["schemas"]["JsonElement"]; + }; + HandbookSubject: { + /** Format: uuid */ + regionId?: null | string; + /** Format: uuid */ + schoolId?: null | string; + /** Format: uuid */ + majorId?: null | string; + /** Format: uuid */ + entryId?: null | string; + /** Format: uuid */ + contentNodeId?: null | string; + legacyId?: null | string; + name?: string; + type?: null | components["schemas"]["HandbookSubjectType"]; + icon?: null | string; + color?: null | string; + description?: null | string; + majorLegacyIds?: components["schemas"]["JsonElement"]; + /** Format: int32 */ + sortOrder?: number | string; + isActive?: boolean; + sourceHash?: null | string; + metadata?: components["schemas"]["JsonElement"]; + /** Format: date-time */ + createdAt?: string; + /** Format: date-time */ + updatedAt?: string; + /** Format: uuid */ + tenantId?: string; + /** Format: uuid */ + id?: string; + }; + HandbookSubjectCatalogItem: { + /** Format: uuid */ + id: string; + legacyId: null | string; + /** Format: uuid */ + regionId: null | string; + /** Format: uuid */ + schoolId: null | string; + /** Format: uuid */ + majorId: null | string; + /** Format: uuid */ + entryId: null | string; + /** Format: uuid */ + contentNodeId: null | string; + name: string; + type: null | components["schemas"]["HandbookSubjectType"]; + icon: null | string; + color: null | string; + description: null | string; + /** Format: int32 */ + order: number | string; + metadata: components["schemas"]["JsonElement"]; + }; + HandbookSubjectType: number; + /** @description 健康检查响应。 */ + HealthResponseDto: { + /** @description 服务状态,例如 ok。 */ + status: string; + /** @description 服务名称。 */ + service: string; + /** + * Format: date-time + * @description 检查时间。 + */ + checkedAt: string; + }; + /** @description Idempotent租户账务请求 DTO。 */ + IdempotentTenantBillingDto: { + idempotencyKey: string; + }; + ImageAssetCatalogItem: { + /** Format: uuid */ + id: string; + legacyId: null | string; + title: null | string; + category: null | string; + fileName: null | string; + isPublic: boolean; + cdnUrl: null | string; + metadata: components["schemas"]["JsonElement"]; + }; + ImportFieldMappingItem: { + importType: string; + title: string; + description: string; + fields: components["schemas"]["ImportFieldSpec"][]; + requiredFields: string[]; + }; + ImportFieldSpec: { + field: string; + label: string; + required: boolean; + aliases: string[]; + description: string; + example: components["schemas"]["JsonElement"]; + }; + ImportIssueSeverity: number; + ImportPostCheckResult: { + /** Format: uuid */ + jobId: string; + status: string; + counts: components["schemas"]["JsonElement"]; + issues: components["schemas"]["ContentImportIssueModel"][]; + }; + ImportSourceFormat: number; + ImportTemplateItem: { + importType: string; + format: string; + fileName: string; + mimeType: string; + contentBase64: string; + contentPreview: string; + fields: components["schemas"]["ImportFieldSpec"][]; + }; + IssuePlatformOwnerActivationLinkDto: { + reason: string; + replaceExisting?: boolean; + }; + JsonElement: unknown; + LearningActionResult: { + ok: boolean; + isFavorite?: null | boolean; + }; + LearningLeaderboardItem: { + /** Format: uuid */ + userId: string; + displayName: null | string; + /** Format: int32 */ + answerCount: number | string; + /** Format: int32 */ + correctCount: number | string; + /** Format: int32 */ + wrongCount: number | string; + /** Format: double */ + accuracy: number | string; + }; + LearningLeaderboardResult: { + metric: string; + period: string; + items: components["schemas"]["LearningLeaderboardItem"][]; + currentUser: null | components["schemas"]["LearningLeaderboardItem"]; + /** Format: date-time */ + generatedAt: string; + }; + LearningListOfFavoriteQuestionItem: { + items: components["schemas"]["FavoriteQuestionItem"][]; + }; + LearningListOfFavoriteWordItem: { + items: components["schemas"]["FavoriteWordItem"][]; + }; + LearningListOfLearningTrendItem: { + items: components["schemas"]["LearningTrendItem"][]; + }; + LearningListOfPracticeHistoryItem: { + items: components["schemas"]["PracticeHistoryItem"][]; + }; + LearningListOfPracticeSessionReportItem: { + items: components["schemas"]["PracticeSessionReportItem"][]; + }; + LearningListOfWordProgressItem: { + items: components["schemas"]["WordProgressItem"][]; + }; + LearningListOfWrongQuestionItem: { + items: components["schemas"]["WrongQuestionItem"][]; + }; + LearningStatsItem: { + /** Format: int32 */ + answerCount: number | string; + /** Format: int32 */ + correctCount: number | string; + /** Format: int32 */ + wrongCount: number | string; + /** Format: int32 */ + favoriteQuestionCount: number | string; + /** Format: int32 */ + favoriteWordCount: number | string; + /** Format: int32 */ + wordProgressCount: number | string; + /** Format: int32 */ + practiceSessionCount: number | string; + /** Format: int32 */ + practiceReportCount: number | string; + }; + LearningTrendItem: { + /** Format: date */ + date: string; + /** Format: int32 */ + answerCount: number | string; + /** Format: int32 */ + correctCount: number | string; + /** Format: int32 */ + wrongCount: number | string; + }; + Major: { + /** Format: uuid */ + regionId?: null | string; + /** Format: uuid */ + schoolId?: null | string; + legacyId?: null | string; + name?: string; + description?: null | string; + studyTips?: null | string; + /** Format: int32 */ + sortOrder?: number | string; + isActive?: boolean; + /** Format: date-time */ + createdAt?: string; + /** Format: date-time */ + updatedAt?: string; + /** Format: uuid */ + tenantId?: string; + /** Format: uuid */ + id?: string; + }; + MajorCatalogItem: { + /** Format: uuid */ + id: string; + legacyId: null | string; + /** Format: uuid */ + regionId: null | string; + /** Format: uuid */ + schoolId: null | string; + name: string; + description: null | string; + studyTips: null | string; + /** Format: int32 */ + order: number | string; + }; + /** @description 人工绑定推荐请求 DTO。 */ + ManualBindReferralDto: { + /** + * Format: uuid + * @description 学生用户 ID。 + */ + studentUserId: string; + /** + * Format: uuid + * @description 推荐人用户 ID。 + */ + referrerUserId: string; + /** @description 来源。 */ + source?: null | string; + /** @description 是否强制执行。 */ + force?: boolean; + metadata?: null | components["schemas"]["JsonElement"]; + }; + MembershipStatus: number; + /** @description 当前用户基础信息和租户成员摘要。 */ + MeResponse: { + /** + * Format: uuid + * @description 用户 ID。 + */ + userId: string; + /** @description 手机号。 */ + phone: null | string; + /** @description 邮箱。 */ + email: null | string; + /** @description 用户显示名称。 */ + name: null | string; + /** @description 当前用户拥有的活跃租户成员列表。 */ + tenants: components["schemas"]["TenantMembershipResponse"][]; + }; + ModuleNodeCatalogItem: { + /** Format: uuid */ + id: string; + legacyId: null | string; + /** Format: uuid */ + regionId: null | string; + /** Format: uuid */ + moduleId: null | string; + /** Format: uuid */ + parentId: null | string; + legacyParentId: null | string; + type: components["schemas"]["ModuleNodeType"]; + name: string; + path: null | string; + /** Format: int32 */ + order: number | string; + metadata: components["schemas"]["JsonElement"]; + }; + ModuleNodeType: number; + NotificationSeverity: number; + NotificationStatus: number; + /** @description 通知状态请求 DTO。 */ + NotificationStatusDto: { + /** @description 通知 ID 列表。 */ + notificationIds: string[]; + /** @description 状态。 */ + status?: null | string; + }; + /** @description O认证编码请求 DTO。 */ + OAuthCodeDto: { + realm: null | components["schemas"]["AuthRealm"]; + /** @description 租户编码。 */ + tenantCode?: null | string; + /** @description 编码。 */ + code: string; + /** @description 公开用户资料。 */ + profile?: null | Record; + /** @description 语言。 */ + lang?: null | string; + }; + ObjectStorageMetadata: { + provider: string; + bucket: null | string; + objectKey: null | string; + exists: boolean; + /** Format: int64 */ + sizeBytes: null | number | string; + mimeType: null | string; + checksumSha256: null | string; + eTag: null | string; + lastModified: null | string; + rawHeaders: { + [key: string]: string; + }; + verificationSource: string; + }; + ObjectStorageSignedUrl: { + provider: string; + bucket: null | string; + objectKey: null | string; + method: string; + /** Format: uri */ + url: string; + headers: { + [key: string]: string; + }; + /** Format: date-time */ + expiresAt: string; + expiresIn: string; + signatureMode: string; + }; + OperationContentItem: { + /** Format: uuid */ + id: string; + kind: string; + /** Format: uuid */ + regionId: null | string; + /** Format: uuid */ + schoolId: null | string; + legacyId: null | string; + title: null | string; + content: null | string; + question: null | string; + answer: null | string; + /** Format: date-time */ + examAt: null | string; + examType: null | string; + /** Format: int32 */ + order: number | string; + isActive: boolean; + metadata: components["schemas"]["JsonElement"]; + }; + PagedResultOfPlatformNotificationDeliveryItem: { + items: components["schemas"]["PlatformNotificationDeliveryItem"][]; + /** Format: int32 */ + total: number | string; + /** Format: int32 */ + page: number | string; + /** Format: int32 */ + pageSize: number | string; + }; + /** @description PasswordLogin请求 DTO。 */ + PasswordLoginDto: { + realm: null | components["schemas"]["AuthRealm"]; + /** @description 租户编码。 */ + tenantCode?: null | string; + /** @description 账号标识。 */ + identifier?: null | string; + /** @description 兼容手机号字段;新客户端应使用 identifier。 */ + phone?: null | string; + /** @description 密码。 */ + password: string; + }; + /** @description 使用短信验证码重置租户账号密码。 */ + PasswordResetDto: { + /** @description 租户编码;使用租户自定义域名时可省略。 */ + tenantCode?: null | string; + /** @description 绑定到账号的手机号。 */ + phone: string; + /** @description 短信验证码。 */ + code: string; + /** @description 符合当前密码策略的新密码。 */ + newPassword: string; + }; + /** @description 请求租户短信密码重置验证码。 */ + PasswordResetSmsSendDto: { + /** @description 租户编码;使用租户自定义域名时可省略。 */ + tenantCode?: null | string; + /** @description 绑定到账号的手机号。 */ + phone: string; + /** @description 客户端设备标识,用于安全频控。 */ + deviceId?: null | string; + }; + PaymentNotificationProcessResult: { + provider: string; + eventId: string; + orderNo: string; + status: string; + idempotent: boolean; + }; + PlatformAlertSeverity: number; + PlatformApprovalDecisionDto: { + reason: string; + }; + PlatformApprovalPolicyItem: { + /** Format: uuid */ + id: string; + code: string; + name: string; + requiredPermission: string; + enabled: boolean; + alwaysRequireApproval: boolean; + /** Format: int32 */ + amountThresholdCents: null | number | string; + /** Format: int32 */ + version: number | string; + /** Format: int32 */ + expiresAfterHours: number | string; + conditions: components["schemas"]["JsonElement"]; + }; + PlatformApprovalRequestItem: { + /** Format: uuid */ + id: string; + requestNo: string; + policyCode: string; + /** Format: int32 */ + policyVersion: number | string; + status: components["schemas"]["PlatformApprovalRequestStatus"]; + /** Format: uuid */ + requestedBy: string; + /** Format: uuid */ + decidedBy: null | string; + requiredPermission: string; + commandType: string; + targetType: string; + targetId: string; + /** Format: int32 */ + amountCents: null | number | string; + requestSnapshot: components["schemas"]["JsonElement"]; + requestReason: null | string; + decisionReason: null | string; + error: null | string; + /** Format: date-time */ + expiresAt: string; + /** Format: date-time */ + createdAt: string; + /** Format: date-time */ + updatedAt: string; + }; + PlatformApprovalRequestStatus: number; + PlatformAuditAlert: { + /** Format: uuid */ + ruleId?: string; + /** Format: uuid */ + auditLogId?: string; + /** Format: uuid */ + tenantId?: null | string; + /** Format: uuid */ + acknowledgedBy?: null | string; + /** Format: uuid */ + resolvedBy?: null | string; + severity?: components["schemas"]["PlatformAlertSeverity"]; + status?: components["schemas"]["PlatformAuditAlertStatus"]; + action?: string; + targetType?: null | string; + targetId?: null | string; + title?: string; + summary?: null | string; + details?: components["schemas"]["JsonElement"]; + /** Format: date-time */ + firstSeenAt?: string; + /** Format: date-time */ + lastSeenAt?: string; + /** Format: date-time */ + acknowledgedAt?: null | string; + /** Format: date-time */ + resolvedAt?: null | string; + resolutionNote?: null | string; + /** Format: date-time */ + createdAt?: string; + /** Format: date-time */ + updatedAt?: string; + /** Format: uuid */ + id?: string; + }; + PlatformAuditAlertList: { + items: components["schemas"]["PlatformAuditAlert"][]; + }; + PlatformAuditAlertStatus: number; + PlatformAuditLogItem: { + /** Format: uuid */ + id: string; + /** Format: uuid */ + tenantId: null | string; + /** Format: uuid */ + actorUserId: null | string; + action: string; + targetType: null | string; + targetId: null | string; + details: components["schemas"]["JsonElement"]; + ipAddress: null | string; + userAgent: null | string; + /** Format: date-time */ + createdAt: string; + }; + PlatformAuditLogList: { + items: components["schemas"]["PlatformAuditLogItem"][]; + }; + PlatformBillingCycle: number; + PlatformBillingDunningChannelItem: { + /** Format: uuid */ + id: string; + channelCode: string; + name: string; + description: null | string; + enabled: boolean; + provider: components["schemas"]["PlatformBillingDunningProvider"]; + webhookUrlMasked: string; + secretRef: null | string; + reminderTypes: string[]; + reminderChannels: string[]; + /** Format: int32 */ + minReminderLevel: number | string; + tenantIds: string[]; + /** Format: int32 */ + timeoutSeconds: number | string; + metadata: components["schemas"]["JsonElement"]; + /** Format: date-time */ + createdAt: string; + /** Format: date-time */ + updatedAt: string; + }; + PlatformBillingDunningChannelList: { + items: components["schemas"]["PlatformBillingDunningChannelItem"][]; + }; + PlatformBillingDunningEventItem: { + /** Format: uuid */ + id: string; + /** Format: uuid */ + tenantId: string; + /** Format: uuid */ + channelId: string; + /** Format: uuid */ + reminderId: string; + /** Format: uuid */ + invoiceId: string; + provider: components["schemas"]["PlatformBillingDunningProvider"]; + status: components["schemas"]["PlatformBillingDunningNotificationStatus"]; + /** Format: int32 */ + attempts: number | string; + /** Format: date-time */ + scheduledAt: string; + /** Format: date-time */ + nextAttemptAt: null | string; + /** Format: date-time */ + lastAttemptAt: null | string; + /** Format: date-time */ + sentAt: null | string; + lastError: null | string; + /** Format: int32 */ + lastHttpCode: null | number | string; + lastResponseSummary: null | string; + requestPayload: components["schemas"]["JsonElement"]; + metadata: components["schemas"]["JsonElement"]; + /** Format: date-time */ + createdAt: string; + /** Format: date-time */ + updatedAt: string; + }; + PlatformBillingDunningEventList: { + items: components["schemas"]["PlatformBillingDunningEventItem"][]; + }; + PlatformBillingDunningNotificationStatus: number; + PlatformBillingDunningProvider: number; + PlatformBillingInvoice: { + /** Format: uuid */ + orderId?: null | string; + invoiceNo?: string; + status?: components["schemas"]["PlatformBillingInvoiceStatus"]; + /** Format: int32 */ + totalAmountCents?: number | string; + currency?: string; + /** Format: date */ + dueDate?: null | string; + /** Format: date-time */ + issuedAt?: null | string; + /** Format: date-time */ + paidAt?: null | string; + billingProfileSnapshot?: components["schemas"]["JsonElement"]; + /** Format: date-time */ + createdAt?: string; + /** Format: date-time */ + updatedAt?: string; + /** Format: uuid */ + tenantId?: string; + /** Format: uuid */ + id?: string; + }; + PlatformBillingInvoiceReminder: { + /** Format: uuid */ + invoiceId?: string; + /** Format: uuid */ + createdBy?: null | string; + reminderType?: components["schemas"]["PlatformBillingInvoiceReminderType"]; + channel?: components["schemas"]["PlatformBillingInvoiceReminderChannel"]; + status?: components["schemas"]["PlatformBillingInvoiceReminderStatus"]; + /** Format: date */ + reminderDate?: string; + /** Format: int32 */ + reminderLevel?: number | string; + /** Format: date */ + dueDate?: null | string; + /** Format: int32 */ + balanceCentsSnapshot?: number | string; + message?: null | string; + metadata?: components["schemas"]["JsonElement"]; + /** Format: date-time */ + sentAt?: null | string; + /** Format: date-time */ + acknowledgedAt?: null | string; + /** Format: date-time */ + createdAt?: string; + /** Format: date-time */ + updatedAt?: string; + /** Format: uuid */ + tenantId?: string; + /** Format: uuid */ + id?: string; + }; + PlatformBillingInvoiceReminderChannel: number; + PlatformBillingInvoiceReminderStatus: number; + PlatformBillingInvoiceReminderType: number; + PlatformBillingInvoiceStatus: number; + PlatformBillingItemType: number; + PlatformBillingOrder: { + /** Format: uuid */ + quoteId?: string; + orderNo?: string; + idempotencyKey?: string; + purpose?: components["schemas"]["PlatformBillingOrderPurpose"]; + status?: components["schemas"]["PlatformBillingOrderStatus"]; + /** Format: int32 */ + originalAmountCents?: number | string; + /** Format: int32 */ + discountAmountCents?: number | string; + /** Format: int32 */ + totalAmountCents?: number | string; + currency?: string; + /** Format: date-time */ + expiresAt?: string; + /** Format: date-time */ + paidAt?: null | string; + /** Format: date-time */ + cancelledAt?: null | string; + snapshot?: components["schemas"]["JsonElement"]; + /** Format: date-time */ + createdAt?: string; + /** Format: date-time */ + updatedAt?: string; + /** Format: uuid */ + tenantId?: string; + /** Format: uuid */ + id?: string; + }; + PlatformBillingOrderPurpose: number; + PlatformBillingOrderStatus: number; + PlatformBillingOrderView: { + /** Format: uuid */ + id: string; + orderNo: string; + purpose: components["schemas"]["PlatformBillingOrderPurpose"]; + status: components["schemas"]["PlatformBillingOrderStatus"]; + /** Format: int32 */ + totalAmountCents: number | string; + currency: string; + /** Format: date-time */ + expiresAt: string; + /** Format: date-time */ + paidAt: null | string; + items: components["schemas"]["PlatformBillingQuoteItemView"][]; + }; + PlatformBillingPayment: { + /** Format: uuid */ + orderId?: string; + paymentNo?: string; + idempotencyKey?: string; + provider?: string; + method?: string; + status?: components["schemas"]["PlatformBillingPaymentStatus"]; + /** Format: int32 */ + amountCents?: number | string; + providerTradeNo?: null | string; + /** Format: date-time */ + paidAt?: null | string; + clientPayload?: components["schemas"]["JsonElement"]; + /** Format: date-time */ + createdAt?: string; + /** Format: date-time */ + updatedAt?: string; + /** Format: uuid */ + tenantId?: string; + /** Format: uuid */ + id?: string; + }; + PlatformBillingPaymentEvent: { + /** Format: uuid */ + paymentId?: string; + provider?: string; + providerEventId?: string; + eventType?: string; + payload?: components["schemas"]["JsonElement"]; + /** Format: date-time */ + createdAt?: string; + /** Format: uuid */ + tenantId?: string; + /** Format: uuid */ + id?: string; + }; + PlatformBillingPaymentStatus: number; + PlatformBillingPaymentView: { + /** Format: uuid */ + id: string; + paymentNo: string; + provider: string; + method: string; + status: components["schemas"]["PlatformBillingPaymentStatus"]; + /** Format: int32 */ + amountCents: number | string; + clientPayload: components["schemas"]["JsonElement"]; + }; + PlatformBillingQuoteItemView: { + /** Format: uuid */ + offeringVersionId: string; + offeringCode: string; + offeringName: string; + itemType: components["schemas"]["PlatformBillingItemType"]; + /** Format: int32 */ + unitAmountCents: number | string; + /** Format: int32 */ + amountCents: number | string; + }; + PlatformBillingQuoteStatus: number; + PlatformBillingQuoteView: { + /** Format: uuid */ + id: string; + quoteNo: string; + status: components["schemas"]["PlatformBillingQuoteStatus"]; + purpose: components["schemas"]["PlatformBillingOrderPurpose"]; + /** Format: int32 */ + originalAmountCents: number | string; + /** Format: int32 */ + discountAmountCents: number | string; + /** Format: int32 */ + totalAmountCents: number | string; + currency: string; + /** Format: date-time */ + expiresAt: string; + items: components["schemas"]["PlatformBillingQuoteItemView"][]; + featureCodes: string[]; + limits: { + [key: string]: number | string; + }; + }; + PlatformBillingRefund: { + /** Format: uuid */ + orderId?: string; + /** Format: uuid */ + paymentId?: null | string; + refundNo?: string; + status?: components["schemas"]["PlatformBillingRefundStatus"]; + /** Format: int32 */ + amountCents?: number | string; + reason?: string; + providerRefundNo?: null | string; + /** Format: date-time */ + completedAt?: null | string; + idempotencyKey?: string; + subscriptionEffect?: components["schemas"]["PlatformBillingRefundSubscriptionEffect"]; + /** Format: uuid */ + requestedBy?: null | string; + /** Format: uuid */ + reviewedBy?: null | string; + /** Format: date-time */ + reviewedAt?: null | string; + reviewReason?: null | string; + lastError?: null | string; + /** Format: date-time */ + createdAt?: string; + /** Format: date-time */ + updatedAt?: string; + /** Format: uuid */ + tenantId?: string; + /** Format: uuid */ + id?: string; + }; + PlatformBillingRefundStatus: number; + PlatformBillingRefundSubscriptionEffect: number; + PlatformCommandSubmission: { + executionStatus: string; + result: null | components["schemas"]["JsonElement"]; + approvalRequest: null | components["schemas"]["PlatformApprovalRequestItem"]; + }; + PlatformConfigurationDefinitionItem: { + /** Format: uuid */ + id: string; + code: string; + name: string; + category: string; + valueType: components["schemas"]["PlatformConfigurationValueType"]; + allowRuntimeManagement: boolean; + isSensitive: boolean; + description: null | string; + validationSchema: components["schemas"]["JsonElement"]; + }; + PlatformConfigurationValueType: number; + PlatformConfigurationVersionItem: { + /** Format: uuid */ + id: string; + /** Format: uuid */ + definitionId: string; + environment: string; + /** Format: int32 */ + version: number | string; + status: components["schemas"]["PlatformConfigurationVersionStatus"]; + value: null | components["schemas"]["JsonElement"]; + secretRef: null | string; + /** Format: uuid */ + createdBy: string; + /** Format: uuid */ + publishedBy: null | string; + /** Format: uuid */ + rolledBackFromVersionId: null | string; + reason: string; + /** Format: date-time */ + publishedAt: null | string; + /** Format: date-time */ + createdAt: string; + }; + PlatformConfigurationVersionStatus: number; + PlatformCrmConfigItem: { + /** Format: uuid */ + id: string; + /** Format: uuid */ + tenantId: string; + tenantName: string; + enabled: boolean; + url: null | string; + secretRef: null | string; + formName: null | string; + examType: null | string; + /** Format: int32 */ + timeoutSeconds: null | number | string; + /** Format: int32 */ + delaySeconds: null | number | string; + assignmentMode: components["schemas"]["ReferralAssignmentMode"]; + assignmentPool: components["schemas"]["JsonElement"]; + assignmentConfig: components["schemas"]["JsonElement"]; + /** Format: date-time */ + updatedAt: string; + }; + PlatformDomainList: { + items: components["schemas"]["PlatformTenantDomainItem"][]; + }; + PlatformDomainRecheckResult: { + /** Format: uuid */ + domainId: string; + status: components["schemas"]["TenantDomainStatus"]; + /** Format: date-time */ + lastCheckedAt: string; + }; + PlatformNotificationChannel: number; + PlatformNotificationDeliveryItem: { + /** Format: uuid */ + id: string; + /** Format: uuid */ + templateId: string; + /** Format: uuid */ + recipientUserId: string; + recipientRoleCode: string; + channel: components["schemas"]["PlatformNotificationChannel"]; + status: components["schemas"]["PlatformNotificationDeliveryStatus"]; + subject: string; + body: string; + /** Format: int32 */ + attempts: number | string; + lastError: null | string; + /** Format: date-time */ + sentAt: null | string; + /** Format: date-time */ + createdAt: string; + }; + PlatformNotificationDeliveryStatus: number; + PlatformNotificationTemplateItem: { + /** Format: uuid */ + id: string; + code: string; + name: string; + channel: components["schemas"]["PlatformNotificationChannel"]; + subjectTemplate: string; + bodyTemplate: string; + enabled: boolean; + variables: components["schemas"]["JsonElement"]; + /** Format: date-time */ + updatedAt: string; + }; + PlatformOverview: { + /** Format: int32 */ + tenantCount: number | string; + /** Format: int32 */ + activeTenantCount: number | string; + /** Format: int32 */ + suspendedTenantCount: number | string; + /** Format: int32 */ + orderCount: number | string; + /** Format: int32 */ + paidOrderCount: number | string; + /** Format: int32 */ + revenueCents: number | string; + /** Format: int32 */ + questionBankCount: number | string; + /** Format: int32 */ + questionCount: number | string; + /** Format: int32 */ + learningActiveUserCount: number | string; + }; + PlatformOwnerActivationLinkResult: { + /** Format: uuid */ + activationId: string; + activationUrl: null | string; + /** Format: date-time */ + expiresAt: string; + isReplay: boolean; + }; + PlatformOwnerActivationStatus: { + status: string; + /** Format: uuid */ + activationId: null | string; + /** Format: date-time */ + expiresAt: null | string; + }; + PlatformPaymentApp: { + appCode?: string; + appName?: string; + status?: components["schemas"]["PlatformPaymentAppStatus"]; + settlementMode?: string; + description?: null | string; + metadata?: components["schemas"]["JsonElement"]; + /** Format: date-time */ + createdAt?: string; + /** Format: date-time */ + updatedAt?: string; + /** Format: uuid */ + id?: string; + }; + PlatformPaymentAppStatus: number; + PlatformPaymentChannel: { + /** Format: uuid */ + appId?: string; + provider?: string; + mode?: string; + status?: components["schemas"]["PlatformPaymentChannelStatus"]; + displayName?: string; + secretRef?: null | string; + callbackPath?: null | string; + /** Format: int32 */ + priority?: number | string; + configPublic?: components["schemas"]["JsonElement"]; + metadata?: components["schemas"]["JsonElement"]; + /** Format: date-time */ + createdAt?: string; + /** Format: date-time */ + updatedAt?: string; + /** Format: uuid */ + id?: string; + }; + PlatformPaymentChannelStatus: number; + PlatformQuestionBankItem: { + /** Format: uuid */ + id: string; + /** Format: uuid */ + contentEntryId: null | string; + name: string; + status: components["schemas"]["QuestionBankStatus"]; + /** Format: int32 */ + nodeCount: number | string; + /** Format: int32 */ + questionCount: number | string; + metadata: components["schemas"]["JsonElement"]; + /** Format: date-time */ + createdAt: string; + /** Format: date-time */ + updatedAt: null | string; + }; + PlatformQuestionBankNodeItem: { + /** Format: uuid */ + id: string; + /** Format: uuid */ + questionBankId: string; + /** Format: uuid */ + entryId: string; + /** Format: uuid */ + parentId: null | string; + nodeKey: null | string; + name: string; + nodeType: components["schemas"]["ContentNodeType"]; + /** Format: int32 */ + depth: number | string; + /** Format: int32 */ + sortOrder: number | string; + isActive: boolean; + isSelectable: boolean; + isLeaf: boolean; + /** Format: int32 */ + questionCount: number | string; + metadata: components["schemas"]["JsonElement"]; + }; + PlatformQuestionImportCommand: { + /** Format: uuid */ + questionBankId: string; + /** Format: uuid */ + contentNodeId: null | string; + format: string; + sourceName: null | string; + payload: components["schemas"]["JsonElement"]; + }; + PlatformQuestionImportResult: { + detail: components["schemas"]["ContentImportJobDetail"]; + /** Format: int32 */ + createdNodeCount: number | string; + /** Format: int32 */ + insertedQuestionCount: number | string; + /** Format: int32 */ + updatedQuestionCount: number | string; + /** Format: int32 */ + skippedQuestionCount: number | string; + }; + PlatformQuestionItem: { + /** Format: uuid */ + id: string; + /** Format: uuid */ + versionId: null | string; + /** Format: uuid */ + questionBankId: string; + /** Format: uuid */ + entryId: string; + /** Format: uuid */ + contentNodeId: string; + legacyId: null | string; + type: string; + typeLabel: null | string; + /** Format: int32 */ + difficulty: null | number | string; + tags: components["schemas"]["JsonElement"]; + content: null | string; + options: components["schemas"]["JsonElement"]; + /** Format: int32 */ + correctOptionIndex: null | number | string; + correctOptionIndices: components["schemas"]["JsonElement"]; + answerText: null | string; + explanation: null | string; + subQuestions: components["schemas"]["JsonElement"]; + codeLang: null | string; + codeTemplate: null | string; + mediaUrl: null | string; + status: components["schemas"]["QuestionStatus"]; + /** Format: int32 */ + versionNo: number | string; + /** Format: date-time */ + createdAt: string; + /** Format: date-time */ + updatedAt: null | string; + }; + PlatformQuestionPage: { + items: components["schemas"]["PlatformQuestionItem"][]; + /** Format: int32 */ + total: number | string; + /** Format: int32 */ + page: number | string; + /** Format: int32 */ + pageSize: number | string; + }; + PlatformRebateSummary: { + /** Format: int32 */ + grossAmountCents: number | string; + /** Format: int32 */ + commissionAmountCents: number | string; + /** Format: int32 */ + pendingSettlementCents: number | string; + /** Format: int32 */ + paidSettlementCents: number | string; + /** Format: int32 */ + exceptionCount: number | string; + }; + PlatformRollbackDto: { + reason: string; + }; + PlatformSmsChannelItem: { + /** Format: uuid */ + id: string; + /** Format: uuid */ + tenantId: string; + tenantName: string; + provider: string; + name: string; + signature: string; + scene: string; + status: components["schemas"]["TenantExternalProviderStatus"]; + secretRef: null | string; + /** Format: int32 */ + priority: number | string; + /** Format: int32 */ + monthlyQuota: number | string; + /** Format: int32 */ + sentThisMonth: number | string; + configPublic: components["schemas"]["JsonElement"]; + metadata: components["schemas"]["JsonElement"]; + /** Format: date-time */ + updatedAt: string; + }; + PlatformSmsTemplateItem: { + /** Format: uuid */ + id: string; + /** Format: uuid */ + tenantId: string; + tenantName: string; + /** Format: uuid */ + channelId: string; + channelName: string; + code: string; + name: string; + type: components["schemas"]["SmsTemplateType"]; + auditStatus: components["schemas"]["SmsTemplateAuditStatus"]; + status: components["schemas"]["SmsTemplateStatus"]; + providerTemplateCode: null | string; + content: string; + remark: null | string; + /** Format: int32 */ + sentCount: number | string; + /** Format: int32 */ + failedCount: number | string; + /** Format: date-time */ + updatedAt: string; + }; + PlatformStaffItem: { + /** Format: uuid */ + userId: string; + name: null | string; + phoneMasked: null | string; + email: null | string; + status: components["schemas"]["UserStatus"]; + roleCodes: string[]; + /** Format: date-time */ + createdAt: string; + /** Format: date-time */ + updatedAt: string; + }; + PlatformStaffList: { + items: components["schemas"]["PlatformStaffItem"][]; + }; + PlatformTenantCapabilityListOfCrmWebhookLog: { + items: components["schemas"]["CrmWebhookLog"][]; + }; + PlatformTenantCapabilityListOfCrmWebhookQueueItem: { + items: components["schemas"]["CrmWebhookQueueItem"][]; + }; + PlatformTenantCapabilityListOfObject: { + items: unknown[]; + }; + PlatformTenantCapabilityListOfPlatformCrmConfigItem: { + items: components["schemas"]["PlatformCrmConfigItem"][]; + }; + PlatformTenantCapabilityListOfPlatformSmsChannelItem: { + items: components["schemas"]["PlatformSmsChannelItem"][]; + }; + PlatformTenantCapabilityListOfPlatformSmsTemplateItem: { + items: components["schemas"]["PlatformSmsTemplateItem"][]; + }; + PlatformTenantCapabilityListOfSmsSendLog: { + items: components["schemas"]["SmsSendLog"][]; + }; + PlatformTenantCapabilityListOfTenantExternalProviderItem: { + items: components["schemas"]["TenantExternalProviderItem"][]; + }; + PlatformTenantDetail: { + tenant: components["schemas"]["PlatformTenantItem"]; + domains: components["schemas"]["PlatformTenantDomainItem"][]; + subscriptions: components["schemas"]["PlatformTenantSubscriptionItem"][]; + billingProfile: null | components["schemas"]["TenantBillingProfileItem"]; + billingPolicy: null | components["schemas"]["TenantBillingPolicyItem"]; + ownerActivation: components["schemas"]["PlatformOwnerActivationStatus"]; + }; + PlatformTenantDomainItem: { + /** Format: uuid */ + id: string; + /** Format: uuid */ + tenantId: string; + host: string; + domainType: components["schemas"]["TenantDomainType"]; + status: components["schemas"]["TenantDomainStatus"]; + isPrimary: boolean; + /** Format: date-time */ + verifiedAt: null | string; + /** Format: date-time */ + dnsVerifiedAt: null | string; + /** Format: date-time */ + tlsReadyAt: null | string; + /** Format: date-time */ + lastCheckedAt: null | string; + lastFailureReason: null | string; + verificationRecordName: null | string; + verificationToken: null | string; + cnameTarget: null | string; + }; + PlatformTenantItem: { + /** Format: uuid */ + id: string; + slug: string; + name: string; + legalName: null | string; + status: components["schemas"]["TenantStatus"]; + mode: components["schemas"]["TenantMode"]; + billingStatus: components["schemas"]["BillingStatus"]; + /** Format: date-time */ + subscriptionExpiresAt: null | string; + /** Format: int32 */ + domainCount: number | string; + /** Format: date-time */ + createdAt: string; + /** Format: date-time */ + updatedAt: string; + }; + PlatformTenantList: { + items: components["schemas"]["PlatformTenantItem"][]; + }; + PlatformTenantProvisioningResult: { + tenant: components["schemas"]["PlatformTenantItem"]; + /** Format: uuid */ + ownerUserId: string; + ownerIdentifier: string; + mustChangePassword: boolean; + primaryDomain: components["schemas"]["PlatformTenantDomainItem"]; + ownerActivation: components["schemas"]["PlatformOwnerActivationStatus"]; + isReplay: boolean; + }; + PlatformTenantSubscriptionItem: { + /** Format: uuid */ + id: string; + /** Format: uuid */ + tenantId: string; + /** Format: uuid */ + baseOfferingVersionId: string; + status: components["schemas"]["TenantSaasSubscriptionStatus"]; + /** Format: date-time */ + startsAt: string; + /** Format: date-time */ + currentPeriodStart: string; + /** Format: date-time */ + currentPeriodEnd: string; + cancelAtPeriodEnd: boolean; + metadata: components["schemas"]["JsonElement"]; + }; + PointActivityClaim: { + /** Format: uuid */ + taskId?: string; + /** Format: uuid */ + userId?: string; + taskKey?: string; + /** Format: int32 */ + points?: number | string; + status?: components["schemas"]["PointActivityClaimStatus"]; + sourceType?: null | string; + /** Format: uuid */ + sourceId?: null | string; + /** Format: date-time */ + claimedAt?: string; + metadata?: components["schemas"]["JsonElement"]; + /** Format: date-time */ + createdAt?: string; + /** Format: date-time */ + updatedAt?: string; + /** Format: uuid */ + tenantId?: string; + /** Format: uuid */ + id?: string; + }; + PointActivityClaimStatus: number; + PointActivityTask: { + taskKey?: string; + title?: string; + description?: null | string; + taskType?: components["schemas"]["PointActivityTaskType"]; + status?: components["schemas"]["PointActivityTaskStatus"]; + /** Format: int32 */ + points?: number | string; + /** Format: int32 */ + maxClaimsPerUser?: number | string; + /** Format: date-time */ + startsAt?: null | string; + /** Format: date-time */ + endsAt?: null | string; + /** Format: int32 */ + sortOrder?: number | string; + rules?: components["schemas"]["JsonElement"]; + metadata?: components["schemas"]["JsonElement"]; + /** Format: date-time */ + createdAt?: string; + /** Format: date-time */ + updatedAt?: string; + /** Format: uuid */ + tenantId?: string; + /** Format: uuid */ + id?: string; + }; + PointActivityTaskStatus: number; + PointActivityTaskType: number; + PointClaimItem: { + /** Format: uuid */ + id: string; + /** Format: uuid */ + taskId: string; + taskKey: string; + /** Format: int32 */ + points: number | string; + status: string; + sourceType: null | string; + /** Format: uuid */ + sourceId: null | string; + /** Format: date-time */ + claimedAt: string; + metadata: components["schemas"]["JsonElement"]; + }; + PointExchangeItem: { + /** Format: uuid */ + regionId?: null | string; + itemKey?: string; + name?: string; + description?: null | string; + itemType?: components["schemas"]["PointExchangeItemType"]; + status?: components["schemas"]["PointExchangeItemStatus"]; + /** Format: int32 */ + pointsCost?: number | string; + /** Format: int32 */ + stock?: null | number | string; + /** Format: int32 */ + days?: null | number | string; + /** Format: int32 */ + sortOrder?: number | string; + /** Format: date-time */ + startsAt?: null | string; + /** Format: date-time */ + endsAt?: null | string; + fulfillmentPayload?: components["schemas"]["JsonElement"]; + metadata?: components["schemas"]["JsonElement"]; + /** Format: date-time */ + createdAt?: string; + /** Format: date-time */ + updatedAt?: string; + /** Format: uuid */ + tenantId?: string; + /** Format: uuid */ + id?: string; + }; + PointExchangeItemDto: { + /** Format: uuid */ + id: string; + /** Format: uuid */ + regionId: null | string; + itemKey: string; + name: string; + description: null | string; + itemType: string; + status: string; + /** Format: int32 */ + pointsCost: number | string; + /** Format: int32 */ + stock: null | number | string; + /** Format: int32 */ + days: null | number | string; + canExchange: boolean; + /** Format: int32 */ + sortOrder: number | string; + fulfillmentPayload: components["schemas"]["JsonElement"]; + metadata: components["schemas"]["JsonElement"]; + }; + PointExchangeItemStatus: number; + PointExchangeItemType: number; + PointExchangeOrder: { + /** Format: uuid */ + itemId?: string; + /** Format: uuid */ + userId?: string; + orderNo?: string; + itemName?: string; + itemType?: components["schemas"]["PointExchangeItemType"]; + status?: components["schemas"]["PointExchangeOrderStatus"]; + /** Format: int32 */ + pointsCost?: number | string; + /** Format: date-time */ + orderedAt?: string; + /** Format: date-time */ + completedAt?: null | string; + /** Format: date-time */ + cancelledAt?: null | string; + fulfillmentSnapshot?: components["schemas"]["JsonElement"]; + metadata?: components["schemas"]["JsonElement"]; + /** Format: date-time */ + createdAt?: string; + /** Format: date-time */ + updatedAt?: string; + /** Format: uuid */ + tenantId?: string; + /** Format: uuid */ + id?: string; + }; + PointExchangeOrderItem: { + /** Format: uuid */ + id: string; + /** Format: uuid */ + itemId: string; + orderNo: string; + itemName: string; + itemType: string; + status: string; + /** Format: int32 */ + pointsCost: number | string; + /** Format: date-time */ + orderedAt: string; + /** Format: date-time */ + completedAt: null | string; + fulfillmentSnapshot: components["schemas"]["JsonElement"]; + metadata: components["schemas"]["JsonElement"]; + }; + PointExchangeOrderStatus: number; + PointListOfPointExchangeItemDto: { + items: components["schemas"]["PointExchangeItemDto"][]; + }; + PointListOfPointExchangeOrderItem: { + items: components["schemas"]["PointExchangeOrderItem"][]; + }; + PointListOfPointTaskItem: { + items: components["schemas"]["PointTaskItem"][]; + }; + PointSummaryItem: { + /** Format: int32 */ + earnedPoints: number | string; + /** Format: int32 */ + spentPoints: number | string; + /** Format: int32 */ + balancePoints: number | string; + }; + PointTaskItem: { + /** Format: uuid */ + id: string; + taskKey: string; + title: string; + description: null | string; + taskType: string; + status: string; + /** Format: int32 */ + points: number | string; + /** Format: int32 */ + maxClaimsPerUser: number | string; + /** Format: int32 */ + claimedCount: number | string; + canClaim: boolean; + /** Format: date-time */ + startsAt: null | string; + /** Format: date-time */ + endsAt: null | string; + /** Format: int32 */ + sortOrder: number | string; + rules: components["schemas"]["JsonElement"]; + metadata: components["schemas"]["JsonElement"]; + }; + PracticeAccessMode: number; + PracticeAssemblyType: number; + PracticeBlueprintCatalogItem: { + /** Format: uuid */ + id: string; + /** Format: uuid */ + regionId: null | string; + /** Format: uuid */ + entryId: null | string; + /** Format: uuid */ + nodeId: null | string; + /** Format: uuid */ + collectionId: null | string; + legacyId: null | string; + name: string; + mode: components["schemas"]["PracticeMode"]; + assemblyType: components["schemas"]["PracticeAssemblyType"]; + /** Format: int32 */ + questionLimit: null | number | string; + /** Format: int32 */ + durationMinutes: null | number | string; + /** Format: double */ + totalScore: null | number | string; + /** Format: double */ + passScore: null | number | string; + sections: components["schemas"]["JsonElement"]; + rules: components["schemas"]["JsonElement"]; + accessRules: components["schemas"]["JsonElement"]; + status: components["schemas"]["ContentStatus"]; + /** Format: int32 */ + order: number | string; + }; + PracticeBlueprintManagementItem: { + /** Format: uuid */ + id: string; + /** Format: uuid */ + regionId: null | string; + /** Format: uuid */ + entryId: null | string; + /** Format: uuid */ + nodeId: null | string; + /** Format: uuid */ + collectionId: null | string; + legacyId: null | string; + name: string; + mode: components["schemas"]["PracticeMode"]; + assemblyType: components["schemas"]["PracticeAssemblyType"]; + /** Format: int32 */ + questionLimit: null | number | string; + /** Format: int32 */ + durationMinutes: null | number | string; + /** Format: double */ + totalScore: null | number | string; + /** Format: double */ + passScore: null | number | string; + sections: components["schemas"]["JsonElement"]; + rules: components["schemas"]["JsonElement"]; + accessRules: components["schemas"]["JsonElement"]; + status: components["schemas"]["ContentStatus"]; + /** Format: int32 */ + order: number | string; + /** Format: date-time */ + createdAt: string; + /** Format: date-time */ + updatedAt: null | string; + }; + PracticeHistoryItem: { + /** Format: uuid */ + id: string; + mode: string; + targetType: null | string; + /** Format: uuid */ + targetId: null | string; + /** Format: uuid */ + blueprintId: null | string; + /** Format: uuid */ + collectionId: null | string; + /** Format: uuid */ + entryId: null | string; + /** Format: uuid */ + contentNodeId: null | string; + /** Format: int32 */ + questionCount: number | string; + /** Format: int32 */ + answeredCount: number | string; + /** Format: int32 */ + correctCount: number | string; + /** Format: int32 */ + wrongCount: number | string; + /** Format: date-time */ + startedAt: string; + /** Format: date-time */ + finishedAt: null | string; + /** Format: date-time */ + expiresAt: null | string; + status: string; + /** Format: uuid */ + reportId: null | string; + /** Format: double */ + score: null | number | string; + /** Format: double */ + reportTotalScore: null | number | string; + /** Format: double */ + accuracy: null | number | string; + }; + PracticeMode: number; + PracticeReportStatus: number; + PracticeSessionDetailItem: { + session: components["schemas"]["PracticeSessionItem"]; + questions: components["schemas"]["PracticeSessionQuestionItem"][]; + answersBySessionQuestion: { + [key: string]: components["schemas"]["AnswerRecordItem"]; + }; + }; + PracticeSessionItem: { + /** Format: uuid */ + id: string; + mode: string; + targetType: null | string; + /** Format: uuid */ + targetId: null | string; + /** Format: uuid */ + blueprintId: null | string; + /** Format: uuid */ + collectionId: null | string; + /** Format: uuid */ + entryId: null | string; + /** Format: uuid */ + contentNodeId: null | string; + /** Format: int32 */ + questionCount: number | string; + /** Format: int32 */ + durationMinutes: null | number | string; + /** Format: double */ + totalScore: null | number | string; + accessMode: components["schemas"]["PracticeAccessMode"]; + /** Format: uuid */ + accessEntitlementId: null | string; + /** Format: int32 */ + consumedFreeQuota: number | string; + accessSnapshot: components["schemas"]["JsonElement"]; + /** Format: date-time */ + startedAt: string; + /** Format: date-time */ + finishedAt: null | string; + /** Format: date-time */ + expiresAt: null | string; + metadata: components["schemas"]["JsonElement"]; + status: components["schemas"]["PracticeSessionStatus"]; + /** Format: int64 */ + version: number | string; + /** Format: int64 */ + lastClientSequence: number | string; + }; + PracticeSessionQuestionItem: { + /** Format: uuid */ + sessionQuestionId: string; + /** Format: uuid */ + questionReferenceId: string; + locator: components["schemas"]["QuestionLocator"]; + /** Format: uuid */ + questionId: string; + type: string; + typeLabel: null | string; + /** Format: int32 */ + difficulty: null | number | string; + tags: components["schemas"]["JsonElement"]; + /** Format: uuid */ + versionId: null | string; + content: null | string; + options: components["schemas"]["JsonElement"]; + }; + PracticeSessionReportItem: { + /** Format: uuid */ + id: string; + /** Format: uuid */ + practiceSessionId: string; + /** Format: uuid */ + blueprintId: null | string; + /** Format: uuid */ + collectionId: null | string; + mode: string; + /** Format: int32 */ + totalQuestions: number | string; + /** Format: int32 */ + answeredCount: number | string; + /** Format: int32 */ + correctCount: number | string; + /** Format: int32 */ + wrongCount: number | string; + /** Format: int32 */ + unansweredCount: number | string; + /** Format: double */ + score: number | string; + /** Format: double */ + totalScore: number | string; + /** Format: double */ + accuracy: number | string; + /** Format: int32 */ + durationSeconds: number | string; + /** Format: date-time */ + startedAt: null | string; + /** Format: date-time */ + submittedAt: string; + status: components["schemas"]["PracticeReportStatus"]; + /** Format: int32 */ + version: number | string; + isFinal: boolean; + /** Format: int32 */ + pendingReviewCount: number | string; + /** Format: int32 */ + scoringVersion: number | string; + sectionStats: components["schemas"]["JsonElement"]; + questionResults: components["schemas"]["JsonElement"]; + wrongQuestionIds: components["schemas"]["JsonElement"]; + metadata: components["schemas"]["JsonElement"]; + }; + PracticeSessionStatus: number; + /** @description 预览对账导入请求 DTO。 */ + PreviewReconciliationImportDto: { + /** @description 服务提供方。 */ + provider: string; + /** + * Format: date + * @description 账单日期。 + */ + billDate?: string; + /** @description 账单类型。 */ + billType?: components["schemas"]["ReconciliationBillType"]; + /** @description 来源名称。 */ + sourceName: string; + /** @description 数据行列表。 */ + rows?: components["schemas"]["JsonElement"]; + }; + /** @description 预览租户主题请求 DTO。 */ + PreviewTenantThemeDto: { + /** @description 模板编码。 */ + templateCode: string; + /** @description 主题配置。 */ + theme?: components["schemas"]["JsonElement"]; + /** @description 公开资源配置。 */ + publicAssets?: components["schemas"]["JsonElement"]; + }; + ProblemDetails: { + type?: null | string; + title?: null | string; + /** Format: int32 */ + status?: null | number | string; + detail?: null | string; + instance?: null | string; + }; + ProductCatalogItem: { + /** Format: uuid */ + id: string; + legacyId: null | string; + /** Format: uuid */ + regionId: null | string; + title: string; + /** Format: double */ + price: null | number | string; + priceLabel: null | string; + link: null | string; + type: components["schemas"]["ProductType"]; + tags: components["schemas"]["JsonElement"]; + cover: null | string; + previewIframe: null | string; + detailImages: components["schemas"]["JsonElement"]; + /** Format: int32 */ + order: number | string; + isActive: boolean; + }; + ProductType: number; + ProfileNotificationItem: { + /** Format: uuid */ + id: string; + notificationType: string; + status: string; + severity: string; + title: string; + message: string; + actionLabel: null | string; + actionPath: null | string; + sourceType: null | string; + /** Format: uuid */ + sourceId: null | string; + metadata: components["schemas"]["JsonElement"]; + /** Format: date-time */ + readAt: null | string; + /** Format: date-time */ + createdAt: string; + }; + ProfileNotificationList: { + items: components["schemas"]["ProfileNotificationItem"][]; + summary: { + [key: string]: number | string; + }; + }; + ProfileScoreEventItem: { + /** Format: uuid */ + id: string; + eventType: string; + /** Format: int32 */ + points: number | string; + /** Format: int32 */ + balanceAfter: number | string; + sourceType: null | string; + /** Format: uuid */ + sourceId: null | string; + metadata: components["schemas"]["JsonElement"]; + /** Format: date-time */ + createdAt: string; + }; + ProfileScoreEventList: { + items: components["schemas"]["ProfileScoreEventItem"][]; + }; + /** @description 可公开给客户端的租户品牌信息。 */ + PublicTenantBrandingDto: { + /** @description 品牌名称。 */ + brandName: null | string; + /** @description 品牌短名称。 */ + shortName: null | string; + /** @description 品牌标语。 */ + slogan: null | string; + /** @description Logo 地址。 */ + logoUrl: null | string; + /** @description Favicon 地址。 */ + faviconUrl: null | string; + /** @description 客服微信。 */ + serviceWechat: null | string; + /** @description 公众号或服务号名称。 */ + serviceAccountName: null | string; + /** @description 公开主题配置。 */ + theme: components["schemas"]["JsonElement"]; + /** @description 公开资源配置。 */ + publicAssets: components["schemas"]["JsonElement"]; + }; + /** @description 可公开给客户端的租户基础信息。 */ + PublicTenantDto: { + /** + * Format: uuid + * @description 租户 ID。 + */ + id: string; + /** @description 租户编码。 */ + slug: string; + /** @description 租户名称。 */ + name: string; + /** @description 租户状态。 */ + status: components["schemas"]["TenantStatus"]; + /** @description 租户模式。 */ + mode: components["schemas"]["TenantMode"]; + /** @description 当前匹配到的访问域名。 */ + host: null | string; + }; + /** @description 发布租户前端配置请求。 */ + PublishTenantFrontendConfigDto: { + /** + * Format: int32 + * @description 期望配置版本。 + */ + expectedVersion?: number | string; + }; + /** @description 发布租户主题请求 DTO。 */ + PublishTenantThemeDto: { + /** @description 是否使用草稿配置。 */ + useDraft?: null | boolean; + /** @description 模板编码。 */ + templateCode?: null | string; + /** @description 主题配置。 */ + theme?: components["schemas"]["JsonElement"]; + /** @description 公开资源配置。 */ + publicAssets?: components["schemas"]["JsonElement"]; + }; + /** @description 题目Action请求 DTO。 */ + QuestionActionDto: { + /** + * Format: uuid + * @description 题目 ID。 + */ + questionId: string; + /** @description 来源。 */ + source: components["schemas"]["QuestionSource"]; + /** @description 是否收藏。 */ + favorite?: null | boolean; + }; + QuestionBankCatalogItem: { + /** Format: uuid */ + id: string; + /** Format: uuid */ + regionId: null | string; + name: string; + source: components["schemas"]["QuestionSource"]; + status: components["schemas"]["QuestionBankStatus"]; + metadata: components["schemas"]["JsonElement"]; + }; + QuestionBankStatus: number; + QuestionCatalogItem: { + /** Format: uuid */ + id: string; + /** Format: uuid */ + questionBankId: null | string; + /** Format: uuid */ + subjectId: null | string; + /** Format: uuid */ + categoryId: null | string; + /** Format: uuid */ + nodeId: null | string; + /** Format: uuid */ + entryId: null | string; + /** Format: uuid */ + contentNodeId: null | string; + /** Format: uuid */ + primaryCollectionId: null | string; + legacyId: null | string; + legacySubjectId: null | string; + legacyCategoryId: null | string; + legacyNodeId: null | string; + type: string; + typeLabel: null | string; + /** Format: int32 */ + difficulty: null | number | string; + tags: components["schemas"]["JsonElement"]; + examMarkers: components["schemas"]["JsonElement"]; + mediaUrl: null | string; + hasVideoExplanation: boolean; + status: components["schemas"]["QuestionStatus"]; + /** Format: uuid */ + versionId: null | string; + /** Format: int32 */ + versionNo: null | number | string; + content: null | string; + options: components["schemas"]["JsonElement"]; + /** Format: int32 */ + correctOptionIndex: null | number | string; + correctOptionIndices: components["schemas"]["JsonElement"]; + answerText: null | string; + explanation: null | string; + subQuestions: components["schemas"]["JsonElement"]; + codeLang: null | string; + codeTemplate: null | string; + locator: components["schemas"]["QuestionLocator"]; + }; + QuestionCollectionCatalogItem: { + /** Format: uuid */ + id: string; + /** Format: uuid */ + regionId: null | string; + /** Format: uuid */ + entryId: null | string; + /** Format: uuid */ + nodeId: null | string; + /** Format: uuid */ + subjectId: null | string; + /** Format: uuid */ + categoryId: null | string; + /** Format: uuid */ + questionBankId: null | string; + legacyId: null | string; + name: string; + collectionType: components["schemas"]["QuestionCollectionType"]; + sourceType: components["schemas"]["QuestionCollectionSourceType"]; + filters: components["schemas"]["JsonElement"]; + /** Format: int32 */ + questionCount: number | string; + /** Format: double */ + totalScore: null | number | string; + /** Format: int32 */ + durationMinutes: null | number | string; + status: components["schemas"]["ContentStatus"]; + /** Format: int32 */ + order: number | string; + accessRules: components["schemas"]["JsonElement"]; + metadata: components["schemas"]["JsonElement"]; + }; + QuestionCollectionItemManagementItem: { + /** Format: uuid */ + id: string; + /** Format: uuid */ + collectionId: string; + /** Format: uuid */ + questionId: string; + locator: components["schemas"]["QuestionLocator"]; + sectionKey: null | string; + /** Format: int32 */ + order: number | string; + /** Format: double */ + score: null | number | string; + required: boolean; + metadata: components["schemas"]["JsonElement"]; + }; + QuestionCollectionManagementItem: { + /** Format: uuid */ + id: string; + /** Format: uuid */ + regionId: null | string; + /** Format: uuid */ + entryId: null | string; + /** Format: uuid */ + nodeId: null | string; + /** Format: uuid */ + subjectId: null | string; + /** Format: uuid */ + categoryId: null | string; + /** Format: uuid */ + questionBankId: null | string; + legacyId: null | string; + name: string; + collectionType: components["schemas"]["QuestionCollectionType"]; + sourceType: components["schemas"]["QuestionCollectionSourceType"]; + filters: components["schemas"]["JsonElement"]; + /** Format: int32 */ + questionCount: number | string; + /** Format: double */ + totalScore: null | number | string; + /** Format: int32 */ + durationMinutes: null | number | string; + status: components["schemas"]["ContentStatus"]; + /** Format: int32 */ + order: number | string; + accessRules: components["schemas"]["JsonElement"]; + metadata: components["schemas"]["JsonElement"]; + /** Format: date-time */ + createdAt: string; + /** Format: date-time */ + updatedAt: null | string; + }; + QuestionCollectionSourceType: number; + QuestionCollectionType: number; + QuestionLocator: { + source: components["schemas"]["QuestionSource"]; + /** Format: uuid */ + questionId: string; + }; + QuestionManagementItem: { + /** Format: uuid */ + id: string; + /** Format: uuid */ + versionId: null | string; + /** Format: uuid */ + questionBankId: null | string; + /** Format: uuid */ + subjectId: null | string; + /** Format: uuid */ + categoryId: null | string; + /** Format: uuid */ + nodeId: null | string; + /** Format: uuid */ + entryId: null | string; + /** Format: uuid */ + contentNodeId: null | string; + /** Format: uuid */ + primaryCollectionId: null | string; + legacyId: null | string; + type: string; + typeLabel: null | string; + /** Format: int32 */ + difficulty: null | number | string; + tags: components["schemas"]["JsonElement"]; + content: null | string; + options: components["schemas"]["JsonElement"]; + /** Format: int32 */ + correctOptionIndex: null | number | string; + correctOptionIndices: components["schemas"]["JsonElement"]; + answerText: null | string; + explanation: null | string; + subQuestions: components["schemas"]["JsonElement"]; + codeLang: null | string; + codeTemplate: null | string; + mediaUrl: null | string; + hasVideoExplanation: boolean; + status: components["schemas"]["QuestionStatus"]; + }; + QuestionSource: number; + QuestionStatus: number; + QuestionVersionCatalogItem: { + /** Format: uuid */ + id: string; + /** Format: uuid */ + questionId: string; + /** Format: int32 */ + versionNo: number | string; + content: null | string; + options: components["schemas"]["JsonElement"]; + /** Format: int32 */ + correctOptionIndex: null | number | string; + correctOptionIndices: components["schemas"]["JsonElement"]; + answerText: null | string; + explanation: null | string; + subQuestions: components["schemas"]["JsonElement"]; + codeLang: null | string; + codeTemplate: null | string; + /** Format: date-time */ + createdAt: string; + }; + QuestionVideoCatalogItem: { + /** Format: uuid */ + id: string; + legacyId: null | string; + /** Format: uuid */ + questionId: null | string; + /** Format: uuid */ + videoId: null | string; + videoType: components["schemas"]["QuestionVideoType"]; + /** Format: int32 */ + order: number | string; + metadata: components["schemas"]["JsonElement"]; + video: null | components["schemas"]["VideoExplanationCatalogItem"]; + }; + QuestionVideoManagementItem: { + /** Format: uuid */ + id: string; + /** Format: uuid */ + questionId: null | string; + /** Format: uuid */ + videoId: null | string; + legacyId: null | string; + videoType: components["schemas"]["QuestionVideoType"]; + /** Format: int32 */ + order: number | string; + metadata: components["schemas"]["JsonElement"]; + }; + /** @description 题目视频查询参数。 */ + QuestionVideoQueryDto: { + /** + * Format: uuid + * @description 题目 ID。 + */ + questionId?: null | string; + /** @description 题目 ID 列表。 */ + questionIds?: null | string[]; + /** + * Format: int32 + * @description 返回数量上限。 + */ + limit?: null | number | string; + }; + QuestionVideoType: number; + RecentPracticeItem: { + /** Format: uuid */ + id: string; + practiceType: null | string; + targetName: null | string; + /** Format: int32 */ + progress: number | string; + /** Format: date-time */ + lastAccessAt: null | string; + /** Format: date-time */ + lastPracticeAt: null | string; + }; + ReconciliationBatchStatus: number; + ReconciliationBillType: number; + ReconciliationImportPreview: { + /** Format: int32 */ + totalCount: number | string; + /** Format: int32 */ + paymentCount: number | string; + /** Format: int32 */ + refundCount: number | string; + /** Format: int32 */ + invalidCount: number | string; + /** Format: int32 */ + amountCents: number | string; + /** Format: int32 */ + refundAmountCents: number | string; + sourceHash: string; + }; + ReconciliationIssueMatchStatus: number; + ReconciliationIssueStatus: number; + ReconciliationMatchStatus: number; + ReconciliationResolutionType: number; + ReconciliationSource: number; + ReconciliationTransactionType: number; + /** @description 核销激活码编码请求 DTO。 */ + RedeemActivationCodeDto: { + /** @description 编码。 */ + code: string; + /** + * Format: uuid + * @description 用户 ID。 + */ + userId: string; + /** + * Format: uuid + * @description 地区 ID。 + */ + regionId?: null | string; + }; + ReferralAssignmentMode: number; + ReferralBindResult: { + lead: components["schemas"]["ReferralLeadItem"]; + crmQueue: null | components["schemas"]["CrmQueuePreviewItem"]; + }; + ReferralConversionReport: { + /** Format: date */ + startDate: string; + /** Format: date */ + endDate: string; + /** Format: int32 */ + leadCount: number | string; + /** Format: int32 */ + paidLeadCount: number | string; + /** Format: int32 */ + paidAmountCents: number | string; + /** Format: double */ + conversionRate: number | string; + topReferrers: components["schemas"]["ReferralStatsItem"][]; + recentUnconvertedLeads: components["schemas"]["ReferralLeadItem"][]; + }; + /** @description 推荐邀请码请求 DTO。 */ + ReferralInviteDto: { + /** @description 渠道。 */ + channel?: null | string; + /** @description 落地页路径。 */ + landingPath?: null | string; + }; + ReferralInviteItem: { + inviteCode: string; + }; + ReferralLeadItem: { + /** Format: uuid */ + id: string; + /** Format: uuid */ + studentUserId: string; + /** Format: uuid */ + referrerUserId: null | string; + refCode: null | string; + status: string; + /** Format: date-time */ + boundAt: string; + changed: boolean; + }; + ReferralListOfReferralLeadItem: { + items: components["schemas"]["ReferralLeadItem"][]; + }; + ReferralListOfReferralStatsItem: { + items: components["schemas"]["ReferralStatsItem"][]; + }; + ReferralListOfReferralTeamItem: { + items: components["schemas"]["ReferralTeamItem"][]; + }; + /** @description 推荐二维码请求 DTO。 */ + ReferralQrcodeDto: { + /** @description 页码。 */ + page?: null | string; + /** @description 场景参数。 */ + scene?: null | string; + /** @description 服务提供方。 */ + provider?: null | string; + /** @description 二维码地址。 */ + qrcodeUrl?: null | string; + metadata?: null | components["schemas"]["JsonElement"]; + }; + ReferralQrcodeItem: { + /** Format: uuid */ + id: string; + refCode: string; + scene: string; + page: string; + provider: string; + qrcodeUrl: null | string; + status: string; + metadata: components["schemas"]["JsonElement"]; + }; + ReferralResolutionItem: { + valid: boolean; + /** Format: uuid */ + inviterId: null | string; + inviteCode: null | string; + role: null | string; + name: null | string; + }; + ReferralStatsItem: { + /** Format: uuid */ + referrerUserId: string; + name: null | string; + role: string; + inviteCode: null | string; + /** Format: int32 */ + leadCount: number | string; + /** Format: int32 */ + paidLeadCount: number | string; + /** Format: int32 */ + paidAmountCents: number | string; + /** Format: int32 */ + trackCount: number | string; + /** Format: double */ + conversionRate: number | string; + }; + ReferralTeamItem: { + /** Format: uuid */ + id: string; + /** Format: uuid */ + memberUserId: string; + /** Format: uuid */ + leaderUserId: null | string; + relationType: string; + status: string; + metadata: components["schemas"]["JsonElement"]; + }; + ReferralTrackItem: { + /** Format: uuid */ + id: string; + eventType: string; + refCode: null | string; + /** Format: uuid */ + referrerUserId: null | string; + /** Format: uuid */ + targetUserId: null | string; + source: null | string; + /** Format: date-time */ + createdAt: string; + }; + ReferralTrackResult: { + item: components["schemas"]["ReferralTrackItem"]; + lead: null | components["schemas"]["ReferralLeadItem"]; + crmQueue: null | components["schemas"]["CrmQueuePreviewItem"]; + }; + /** @description 刷新会话请求 DTO。 */ + RefreshSessionDto: { + /** @description 刷新令牌。 */ + refreshToken: string; + }; + RefundEntitlementAction: number; + /** @description 退款通知请求 DTO。 */ + RefundNotificationDto: { + /** @description 退款单号。 */ + refundNo: string; + /** @description 渠道退款单号。 */ + providerRefundNo?: null | string; + /** @description 状态。 */ + status?: components["schemas"]["CommerceRefundStatus"]; + /** @description 事件 ID。 */ + eventId?: null | string; + /** @description 任务载荷。 */ + payload?: components["schemas"]["JsonElement"]; + }; + RegionCatalogItem: { + /** Format: uuid */ + id: string; + legacyId: null | string; + name: string; + code: null | string; + shortName: null | string; + fullName: null | string; + icon: null | string; + pinyin: null | string; + /** Format: int32 */ + order: number | string; + isHot: boolean; + }; + RegionModuleCatalogItem: { + /** Format: uuid */ + id: string; + legacyId: null | string; + /** Format: uuid */ + regionId: null | string; + name: string; + type: null | string; + icon: null | string; + color: null | string; + textColor: null | string; + description: null | string; + route: null | string; + /** Format: int32 */ + order: number | string; + isPrimarySchoolModule: boolean; + }; + /** @description 移除租户管理端班级成员请求 DTO。 */ + RemoveTenantAdminClassMemberDto: { + /** + * Format: uuid + * @description 班级成员 ID。 + */ + classMemberId: string; + }; + /** @description 替换题集Items请求 DTO。 */ + ReplaceCollectionItemsDto: { + /** + * Format: uuid + * @description 题集 ID。 + */ + collectionId: string; + /** @description 题目列表。 */ + questions?: components["schemas"]["CollectionQuestionDto"][]; + }; + ReplacePlatformPrimaryDomainDto: { + host: string; + reason: string; + }; + /** @description 替换角色权限绑定请求。 */ + ReplaceRoleBindingsDto: { + /** @description 权限编码列表。 */ + permissionCodes?: string[]; + /** @description 菜单编码列表。 */ + menuCodes?: string[]; + }; + /** @description 替换用户角色请求。 */ + ReplaceUserRolesDto: { + /** @description 角色 ID 列表。 */ + roleIds?: string[]; + }; + ReportPriority: number; + ReportStatus: number; + ReportType: number; + /** @description 申请 SaaS 退款。 */ + RequestPlatformRefundDto: { + /** Format: uuid */ + paymentId: string; + /** Format: int32 */ + amountCents: number | string; + reason: string; + idempotencyKey: string; + subscriptionEffect: components["schemas"]["PlatformBillingRefundSubscriptionEffect"]; + }; + /** @description RequestProviderBill任务请求 DTO。 */ + RequestProviderBillJobDto: { + /** @description 服务提供方。 */ + provider: string; + /** + * Format: date + * @description 账单日期。 + */ + billDate?: string; + /** @description 账单类型。 */ + billType?: components["schemas"]["ReconciliationBillType"]; + /** + * Format: date-time + * @description 计划运行时间。 + */ + runAfter?: null | string; + }; + /** @description 首次登录必改密码请求。 */ + RequiredPasswordChangeDto: { + /** @description 挑战令牌。 */ + challengeToken: string; + /** @description 新密码。 */ + newPassword: string; + }; + /** @description 人工确认或忽略催缴投递事件。 */ + ResolvePlatformBillingDunningEventDto: { + /** Format: uuid */ + eventId: string; + reason: string; + }; + /** @description 解析推荐请求 DTO。 */ + ResolveReferralDto: { + /** @description 编码。 */ + code?: null | string; + /** @description 租户编码。 */ + tenantCode?: null | string; + }; + /** @description 重试平台Dunning事件请求 DTO。 */ + RetryPlatformBillingDunningEventDto: { + /** + * Format: uuid + * @description 事件 ID。 + */ + eventId: string; + /** @description 原因。 */ + reason?: null | string; + }; + /** @description 重试租户 CRM 线索推送请求。 */ + RetryPlatformCrmLeadDto: { + /** + * Format: uuid + * @description 队列任务 ID。 + */ + queueId: string; + /** @description 备注。 */ + note?: null | string; + }; + /** @description 审核或重试 SaaS 退款。 */ + ReviewPlatformRefundDto: { + reason: string; + }; + SaasCatalogSnapshot: { + features: components["schemas"]["SaasFeature"][]; + limitDefinitions: components["schemas"]["SaasFeatureLimitDefinition"][]; + offerings: components["schemas"]["SaasOffering"][]; + versions: components["schemas"]["SaasOfferingVersionItem"][]; + }; + SaasFeature: { + code?: string; + name?: string; + category?: string; + description?: null | string; + /** Format: int32 */ + referencePriceCents?: number | string; + currency?: string; + status?: components["schemas"]["SaasFeatureStatus"]; + isCore?: boolean; + /** Format: int32 */ + sortOrder?: number | string; + /** Format: date-time */ + createdAt?: string; + /** Format: date-time */ + updatedAt?: string; + /** Format: uuid */ + id?: string; + }; + SaasFeatureLimitDefinition: { + metricCode?: string; + featureCode?: string; + name?: string; + unit?: string; + kind?: components["schemas"]["SaasFeatureLimitKind"]; + /** Format: int32 */ + warningPercent?: number | string; + isHardLimit?: boolean; + /** Format: date-time */ + createdAt?: string; + /** Format: date-time */ + updatedAt?: string; + /** Format: uuid */ + id?: string; + }; + SaasFeatureLimitKind: number; + SaasFeatureStatus: number; + SaasOffering: { + code?: string; + name?: string; + type?: components["schemas"]["SaasOfferingType"]; + status?: components["schemas"]["SaasOfferingStatus"]; + description?: null | string; + /** Format: int32 */ + sortOrder?: number | string; + /** Format: date-time */ + createdAt?: string; + /** Format: date-time */ + updatedAt?: string; + /** Format: uuid */ + id?: string; + }; + SaasOfferingStatus: number; + SaasOfferingType: number; + SaasOfferingVersionItem: { + /** Format: uuid */ + id: string; + /** Format: uuid */ + offeringId: string; + offeringCode: string; + offeringName: string; + offeringType: components["schemas"]["SaasOfferingType"]; + /** Format: int32 */ + version: number | string; + status: components["schemas"]["SaasOfferingVersionStatus"]; + billingCycle: components["schemas"]["PlatformBillingCycle"]; + /** Format: int32 */ + originalAmountCents: number | string; + /** Format: int32 */ + amountCents: number | string; + currency: string; + /** Format: date-time */ + effectiveAt: null | string; + /** Format: date-time */ + publishedAt: null | string; + featureCodes: string[]; + limits: { + [key: string]: number | string; + }; + }; + SaasOfferingVersionStatus: number; + SavePlatformConfigurationDraftDto: { + definitionCode: string; + environment: string; + value: null | components["schemas"]["JsonElement"]; + secretRef: null | string; + reason: string; + }; + /** @description 保存租户前端配置草稿请求。 */ + SaveTenantFrontendConfigDraftDto: { + /** @description 品牌配置。 */ + branding?: components["schemas"]["JsonElement"]; + /** @description 主题配置。 */ + theme?: components["schemas"]["JsonElement"]; + /** @description 功能配置。 */ + features?: components["schemas"]["JsonElement"]; + /** @description 导航配置。 */ + navigation?: components["schemas"]["JsonElement"]; + /** @description 首页模块配置。 */ + homeModules?: components["schemas"]["JsonElement"]; + }; + School: { + /** Format: uuid */ + regionId?: null | string; + /** Format: uuid */ + moduleId?: null | string; + legacyId?: null | string; + name?: string; + professionalExamDate?: null | string; + metadata?: components["schemas"]["JsonElement"]; + /** Format: date-time */ + createdAt?: string; + /** Format: date-time */ + updatedAt?: string; + /** Format: uuid */ + tenantId?: string; + /** Format: uuid */ + id?: string; + }; + SchoolCatalogItem: { + /** Format: uuid */ + id: string; + legacyId: null | string; + /** Format: uuid */ + regionId: null | string; + /** Format: uuid */ + moduleId: null | string; + name: string; + professionalExamDate: null | string; + metadata: components["schemas"]["JsonElement"]; + }; + ScorelineField: { + /** Format: uuid */ + regionId?: null | string; + legacyId?: null | string; + fieldKey?: string; + fieldName?: string; + fieldType?: string; + unit?: null | string; + isFilter?: boolean; + isRequired?: boolean; + isVisible?: boolean; + isTrend?: boolean; + options?: components["schemas"]["JsonElement"]; + placeholder?: null | string; + description?: null | string; + /** Format: int32 */ + sortOrder?: number | string; + /** Format: date-time */ + createdAt?: string; + /** Format: date-time */ + updatedAt?: string; + /** Format: uuid */ + tenantId?: string; + /** Format: uuid */ + id?: string; + }; + ScorelineFieldItem: { + /** Format: uuid */ + id: string; + legacyId: null | string; + /** Format: uuid */ + regionId: null | string; + fieldKey: string; + fieldName: string; + fieldType: string; + unit: null | string; + isFilter: boolean; + isRequired: boolean; + isVisible: boolean; + isTrend: boolean; + options: components["schemas"]["JsonElement"]; + placeholder: null | string; + description: null | string; + /** Format: int32 */ + sortOrder: number | string; + }; + ScorelineRecord: { + /** Format: uuid */ + regionId?: null | string; + /** Format: uuid */ + schoolId?: null | string; + /** Format: uuid */ + majorId?: null | string; + legacyId?: null | string; + /** Format: int32 */ + year?: number | string; + schoolName?: null | string; + majorName?: null | string; + fieldValues?: components["schemas"]["JsonElement"]; + /** Format: date-time */ + createdAt?: string; + /** Format: date-time */ + updatedAt?: string; + /** Format: uuid */ + tenantId?: string; + /** Format: uuid */ + id?: string; + }; + ScorelineRecordCursorPage: { + /** Format: int32 */ + pageSize: number | string; + hasMore: boolean; + nextCursor: null | string; + items: components["schemas"]["ScorelineRecordItem"][]; + }; + ScorelineRecordItem: { + /** Format: uuid */ + id: string; + legacyId: null | string; + /** Format: uuid */ + regionId: null | string; + /** Format: uuid */ + schoolId: null | string; + /** Format: uuid */ + majorId: null | string; + /** Format: int32 */ + year: number | string; + schoolName: null | string; + majorName: null | string; + fieldValues: components["schemas"]["JsonElement"]; + }; + ScorelineRecordPage: { + /** Format: int32 */ + page: number | string; + /** Format: int32 */ + pageSize: number | string; + /** Format: int32 */ + total: number | string; + items: components["schemas"]["ScorelineRecordItem"][]; + }; + ScorelineTrendItem: { + /** Format: int32 */ + year: number | string; + /** Format: int32 */ + schoolCount: number | string; + /** Format: int32 */ + majorCount: number | string; + }; + SendPlatformNotificationDto: { + /** Format: uuid */ + templateId: string; + roleCodes: string[]; + variables: null | { + [key: string]: string; + }; + idempotencyKey: string; + }; + /** @description 发送短信验证码请求。 */ + SendSmsCodeDto: { + realm: null | components["schemas"]["AuthRealm"]; + /** @description 租户编码。 */ + tenantCode?: null | string; + /** @description 手机号。 */ + phone: string; + /** @description 设备 ID。 */ + deviceId?: null | string; + }; + /** @description SignedStorageUrl请求 DTO。 */ + SignedStorageUrlDto: { + provider: string; + bucket: null | string; + objectKey: null | string; + method: string; + url: string; + headers: { + [key: string]: string; + }; + /** Format: date-time */ + expiresAt: string; + /** Format: int32 */ + expiresInSeconds: number | string; + signatureMode: string; + }; + SimpleImportResult: { + job: components["schemas"]["ContentImportJobItem"]; + items: components["schemas"]["ContentImportItemModel"][]; + issues: components["schemas"]["ContentImportIssueModel"][]; + }; + /** @description SmsLogin请求 DTO。 */ + SmsLoginDto: { + realm: null | components["schemas"]["AuthRealm"]; + /** @description 租户编码。 */ + tenantCode?: null | string; + /** @description 手机号。 */ + phone: string; + /** @description 编码。 */ + code: string; + }; + SmsSendLog: { + /** Format: uuid */ + channelId?: null | string; + /** Format: uuid */ + templateId?: null | string; + provider?: string; + scene?: string; + phoneMasked?: null | string; + status?: components["schemas"]["SmsSendLogStatus"]; + providerMessageId?: null | string; + errorCode?: null | string; + errorMessage?: null | string; + /** Format: date-time */ + sentAt?: null | string; + metadata?: components["schemas"]["JsonElement"]; + /** Format: date-time */ + createdAt?: string; + /** Format: uuid */ + tenantId?: string; + /** Format: uuid */ + id?: string; + }; + SmsSendLogStatus: number; + SmsSendResult: { + /** Format: uuid */ + verificationId: string; + /** Format: date-time */ + expiresAt: string; + }; + SmsTemplateAuditStatus: number; + SmsTemplateStatus: number; + SmsTemplateType: number; + StudentFollowupPriority: number; + StudentFollowupStatus: number; + StudentFollowupType: number; + StudentMembershipItem: { + isSvip: boolean; + /** Format: date-time */ + expiresAt: null | string; + }; + StudentNoteType: number; + StudentNoteVisibility: number; + StudentProfileItem: { + /** Format: uuid */ + profileId: string; + /** Format: uuid */ + userId: string; + username: null | string; + phone: null | string; + email: null | string; + name: null | string; + avatarPreset: string; + avatarDisplayUrl: string; + primaryRole: string; + /** Format: int32 */ + score: number | string; + /** Format: uuid */ + regionId: null | string; + regionName: null | string; + /** Format: uuid */ + selectedSchoolId: null | string; + selectedSchoolName: null | string; + /** Format: uuid */ + selectedMajorId: null | string; + selectedMajorName: null | string; + /** Format: int32 */ + questionsAnsweredToday: number | string; + /** Format: int32 */ + masteredWordsCount: number | string; + /** Format: date */ + lastCheckInDate: null | string; + stats: components["schemas"]["JsonElement"]; + progress: components["schemas"]["JsonElement"]; + moduleSelections: components["schemas"]["JsonElement"]; + recentActivities: components["schemas"]["JsonElement"]; + recentPractices: components["schemas"]["RecentPracticeItem"][]; + membership: components["schemas"]["StudentMembershipItem"]; + }; + SubjectCatalogItem: { + /** Format: uuid */ + id: string; + legacyId: null | string; + /** Format: uuid */ + regionId: null | string; + /** Format: uuid */ + moduleId: null | string; + /** Format: uuid */ + schoolId: null | string; + /** Format: uuid */ + majorId: null | string; + /** Format: uuid */ + nodeId: null | string; + name: string; + type: null | components["schemas"]["SubjectType"]; + icon: null | string; + description: null | string; + stats: components["schemas"]["JsonElement"]; + /** Format: int32 */ + order: number | string; + }; + SubjectType: number; + /** @description 提交答案请求 DTO。 */ + SubmitAnswerDto: { + /** + * Format: uuid + * @description 会话题目 ID。 + */ + sessionQuestionId: string; + /** + * Format: int64 + * @description 客户端读取会话时获得的版本。 + */ + expectedSessionVersion: number | string; + /** + * Format: int64 + * @description 客户端在本会话内单调递增的序列。 + */ + clientSequence: number | string; + /** @description 网络重试幂等键。 */ + idempotencyKey: string; + /** @description 已选选项的零基索引。 */ + selectedOptionIndices?: null | (number | string)[]; + /** @description 文字答案。 */ + answerText?: null | string; + }; + /** @description 提交反馈请求 DTO。 */ + SubmitFeedbackDto: { + /** + * Format: uuid + * @description 题目 ID。 + */ + questionId?: null | string; + /** @description 类型。 */ + type?: null | string; + /** @description 分类。 */ + category?: null | string; + /** @description 标题。 */ + title?: null | string; + /** @description 说明。 */ + description: string; + /** @description 优先级。 */ + priority?: null | string; + /** @description 联系方式。 */ + contact?: null | string; + /** @description 附件列表。 */ + attachments?: components["schemas"]["JsonElement"]; + /** @description 扩展元数据。 */ + metadata?: components["schemas"]["JsonElement"]; + }; + /** @description 提交练习会话请求 DTO。 */ + SubmitPracticeSessionDto: { + /** + * Format: uuid + * @description 练习会话 ID。 + */ + practiceSessionId: string; + /** Format: int64 */ + expectedSessionVersion: number | string; + idempotencyKey: string; + }; + SvipPlanCatalogItem: { + /** Format: uuid */ + id: string; + legacyId: null | string; + /** Format: uuid */ + regionId: null | string; + name: string; + /** Format: int32 */ + priceCents: number | string; + /** Format: double */ + price: number | string; + /** Format: int32 */ + originalPriceCents: null | number | string; + /** Format: double */ + originalPrice: null | number | string; + /** Format: int32 */ + days: number | string; + description: null | string; + perDayLabel: null | string; + badge: null | string; + recommended: boolean; + couponOnly: boolean; + vpProductId: null | string; + vpEnabled: boolean; + /** Format: int32 */ + order: number | string; + isActive: boolean; + }; + TaxonomyNodeItem: { + /** Format: uuid */ + id: string; + source: components["schemas"]["QuestionSource"]; + /** Format: uuid */ + parentId: null | string; + parentSource: null | components["schemas"]["QuestionSource"]; + nodeType: components["schemas"]["TaxonomyNodeType"]; + code: string; + name: string; + path: null | string; + /** Format: int32 */ + depth: number | string; + /** Format: int32 */ + sortOrder: number | string; + metadata: components["schemas"]["JsonElement"]; + }; + TaxonomyNodeType: number; + TenantAdjustmentReport: { + /** Format: int32 */ + draftCount: number | string; + /** Format: int32 */ + pendingReviewCount: number | string; + /** Format: int32 */ + approvedCount: number | string; + /** Format: int32 */ + closedCount: number | string; + /** Format: int32 */ + increaseRevenueCents: number | string; + /** Format: int32 */ + decreaseRevenueCents: number | string; + }; + TenantAdjustmentVoucherEventList: { + items: components["schemas"]["CommerceAdjustmentVoucherEvent"][]; + }; + TenantAdjustmentVoucherList: { + items: components["schemas"]["CommerceAdjustmentVoucher"][]; + }; + TenantAdminAuditLogItem: { + /** Format: uuid */ + id: string; + /** Format: uuid */ + actorUserId: null | string; + action: string; + targetType: null | string; + targetId: null | string; + details: components["schemas"]["JsonElement"]; + ipAddress: null | string; + userAgent: null | string; + actorName: null | string; + actorPhone: null | string; + /** Format: date-time */ + createdAt: string; + }; + TenantAdminBadgeGrantItem: { + /** Format: uuid */ + id: string; + legacyId: null | string; + /** Format: uuid */ + userId: null | string; + userName: null | string; + userPhone: null | string; + /** Format: uuid */ + badgeId: null | string; + badgeName: null | string; + badgeCategory: null | string; + iconUrl: null | string; + /** Format: int32 */ + level: null | number | string; + /** Format: uuid */ + grantedBy: null | string; + grantedByName: null | string; + note: null | string; + /** Format: date-time */ + grantedAt: null | string; + /** Format: date-time */ + createdAt: string; + /** Format: date-time */ + updatedAt: string; + }; + TenantAdminBadgeItem: { + /** Format: uuid */ + id: string; + legacyId: null | string; + name: string; + description: null | string; + category: null | string; + iconUrl: null | string; + /** Format: int32 */ + level: null | number | string; + unlockType: null | string; + conditionField: null | string; + conditionOperator: null | string; + /** Format: double */ + conditionValue: null | number | string; + conditionExtra: components["schemas"]["JsonElement"]; + /** Format: int32 */ + order: number | string; + isActive: boolean; + /** Format: date-time */ + createdAt: string; + /** Format: date-time */ + updatedAt: string; + }; + /** @description 租户管理端批量分配班级请求 DTO。 */ + TenantAdminBulkAssignClassDto: { + /** + * Format: uuid + * @description 班级 ID。 + */ + classId: string; + /** @description 用户 ID 列表。 */ + userIds: string[]; + }; + TenantAdminBulkOperationResult: { + /** Format: int32 */ + requestedCount: number | string; + /** Format: int32 */ + succeededCount: number | string; + /** Format: int32 */ + failedCount: number | string; + failedUserIds: string[]; + }; + /** @description 租户管理端批量状态请求 DTO。 */ + TenantAdminBulkStatusDto: { + /** @description 用户 ID 列表。 */ + userIds: string[]; + /** @description 状态。 */ + status?: null | string; + /** @description 原因。 */ + reason?: null | string; + }; + TenantAdminClassItem: { + /** Format: uuid */ + id: string; + /** Format: uuid */ + regionId: null | string; + regionName: null | string; + legacyId: null | string; + code: null | string; + name: string; + description: null | string; + status: components["schemas"]["TenantRecordStatus"]; + /** Format: int32 */ + order: number | string; + metadata: components["schemas"]["JsonElement"]; + /** Format: int32 */ + studentCount: number | string; + /** Format: int32 */ + staffCount: number | string; + /** Format: date-time */ + createdAt: string; + /** Format: date-time */ + updatedAt: string; + }; + TenantAdminClassList: { + items: components["schemas"]["TenantAdminClassItem"][]; + scoped: boolean; + }; + TenantAdminClassMemberItem: { + /** Format: uuid */ + id: string; + /** Format: uuid */ + classId: string; + /** Format: uuid */ + userId: string; + memberType: components["schemas"]["TenantClassMemberType"]; + status: components["schemas"]["TenantClassMemberStatus"]; + /** Format: date-time */ + joinedAt: string; + /** Format: date-time */ + leftAt: null | string; + metadata: components["schemas"]["JsonElement"]; + user: components["schemas"]["TenantAdminUserSummary"]; + }; + TenantAdminFeedbackItem: { + /** Format: uuid */ + id: string; + /** Format: uuid */ + userId: null | string; + userName: null | string; + userPhone: null | string; + /** Format: uuid */ + questionId: null | string; + type: null | components["schemas"]["ReportType"]; + title: null | string; + category: null | string; + description: null | string; + status: components["schemas"]["ReportStatus"]; + priority: components["schemas"]["ReportPriority"]; + /** Format: uuid */ + handledBy: null | string; + /** Format: date-time */ + handledAt: null | string; + resolution: null | string; + contact: null | string; + attachments: components["schemas"]["JsonElement"]; + metadata: components["schemas"]["JsonElement"]; + /** Format: date-time */ + createdAt: string; + /** Format: date-time */ + updatedAt: string; + }; + TenantAdminMemberItem: { + /** Format: uuid */ + membershipId: string; + /** Format: uuid */ + userId: string; + role: components["schemas"]["TenantRole"]; + status: components["schemas"]["MembershipStatus"]; + legacyRole: null | string; + user: components["schemas"]["TenantAdminUserSummary"]; + /** Format: date-time */ + createdAt: string; + /** Format: date-time */ + updatedAt: string; + }; + TenantAdminNotificationItem: { + /** Format: uuid */ + id: string; + /** Format: uuid */ + userId: string; + notificationType: string; + status: components["schemas"]["NotificationStatus"]; + severity: components["schemas"]["NotificationSeverity"]; + title: string; + message: string; + actionLabel: null | string; + actionPath: null | string; + sourceType: null | string; + /** Format: uuid */ + sourceId: null | string; + dedupeKey: null | string; + metadata: components["schemas"]["JsonElement"]; + /** Format: uuid */ + createdBy: null | string; + /** Format: date-time */ + readAt: null | string; + /** Format: date-time */ + createdAt: string; + /** Format: date-time */ + updatedAt: string; + }; + TenantAdminOverviewItem: { + /** Format: int32 */ + studentCount: number | string; + /** Format: int32 */ + classCount: number | string; + /** Format: int32 */ + staffCount: number | string; + /** Format: int32 */ + activePracticeCount: number | string; + /** Format: int32 */ + todayPracticeCount: number | string; + /** Format: int32 */ + pendingFollowupCount: number | string; + /** Format: int32 */ + unreadNotificationCount: number | string; + /** Format: int32 */ + paidOrderCount: number | string; + /** Format: int32 */ + revenueCents: number | string; + /** Format: int32 */ + pendingRefundCount: number | string; + /** Format: int32 */ + openReconciliationIssueCount: number | string; + /** Format: date-time */ + generatedAt: string; + }; + TenantAdminStudentClassSummary: { + /** Format: uuid */ + classId: string; + className: string; + classCode: null | string; + memberType: components["schemas"]["TenantClassMemberType"]; + /** Format: date-time */ + joinedAt: string; + }; + TenantAdminStudentFollowupItem: { + /** Format: uuid */ + id: string; + /** Format: uuid */ + studentUserId: string; + /** Format: uuid */ + assignedToUserId: null | string; + /** Format: uuid */ + classId: null | string; + title: string; + description: null | string; + followupType: components["schemas"]["StudentFollowupType"]; + priority: components["schemas"]["StudentFollowupPriority"]; + status: components["schemas"]["StudentFollowupStatus"]; + /** Format: date-time */ + dueAt: null | string; + /** Format: date-time */ + completedAt: null | string; + /** Format: uuid */ + completedBy: null | string; + metadata: components["schemas"]["JsonElement"]; + /** Format: uuid */ + createdBy: null | string; + /** Format: uuid */ + updatedBy: null | string; + /** Format: date-time */ + createdAt: string; + /** Format: date-time */ + updatedAt: string; + }; + /** @description 租户管理端学生导入请求 DTO。 */ + TenantAdminStudentImportDto: { + /** @description 数据行列表。 */ + rows: components["schemas"]["TenantAdminStudentImportRowDto"][]; + }; + TenantAdminStudentImportPreview: { + /** Format: int32 */ + totalCount: number | string; + /** Format: int32 */ + validCount: number | string; + /** Format: int32 */ + invalidCount: number | string; + items: components["schemas"]["TenantAdminStudentImportPreviewItem"][]; + }; + TenantAdminStudentImportPreviewItem: { + /** Format: int32 */ + rowNo: number | string; + valid: boolean; + reason: null | string; + phone: null | string; + email: null | string; + name: null | string; + /** Format: uuid */ + regionId: null | string; + /** Format: uuid */ + classId: null | string; + }; + TenantAdminStudentImportResult: { + /** Format: int32 */ + totalCount: number | string; + /** Format: int32 */ + createdOrUpdatedCount: number | string; + /** Format: int32 */ + classAssignedCount: number | string; + invalidItems: components["schemas"]["TenantAdminStudentImportPreviewItem"][]; + }; + /** @description 租户管理端学生导入行请求 DTO。 */ + TenantAdminStudentImportRowDto: { + /** @description 用户信息。 */ + user?: components["schemas"]["TenantAdminUserLookupDto"]; + /** + * Format: uuid + * @description 地区 ID。 + */ + regionId?: null | string; + /** + * Format: uuid + * @description 班级 ID。 + */ + classId?: null | string; + /** @description 头像预设。 */ + avatarPreset?: null | string; + /** @description 原始用户资料。 */ + rawProfile?: components["schemas"]["JsonElement"]; + }; + TenantAdminStudentItem: { + /** Format: uuid */ + membershipId: string; + /** Format: uuid */ + userId: string; + status: components["schemas"]["MembershipStatus"]; + user: components["schemas"]["TenantAdminUserSummary"]; + /** Format: uuid */ + profileId: null | string; + avatarPreset: string; + /** Format: uuid */ + regionId: null | string; + regionName: null | string; + /** Format: uuid */ + selectedSchoolId: null | string; + selectedSchoolName: null | string; + /** Format: uuid */ + selectedMajorId: null | string; + selectedMajorName: null | string; + stats: components["schemas"]["JsonElement"]; + progress: components["schemas"]["JsonElement"]; + moduleSelections: components["schemas"]["JsonElement"]; + classes: components["schemas"]["TenantAdminStudentClassSummary"][]; + /** Format: date-time */ + createdAt: string; + /** Format: date-time */ + updatedAt: string; + }; + TenantAdminStudentList: { + items: components["schemas"]["TenantAdminStudentItem"][]; + scoped: boolean; + }; + TenantAdminStudentNoteItem: { + /** Format: uuid */ + id: string; + /** Format: uuid */ + studentUserId: string; + noteType: components["schemas"]["StudentNoteType"]; + content: string; + visibility: components["schemas"]["StudentNoteVisibility"]; + isPinned: boolean; + metadata: components["schemas"]["JsonElement"]; + /** Format: uuid */ + createdBy: null | string; + /** Format: uuid */ + updatedBy: null | string; + /** Format: date-time */ + createdAt: string; + /** Format: date-time */ + updatedAt: string; + }; + TenantAdminStudentStatusItem: { + /** Format: uuid */ + membershipId: string; + /** Format: uuid */ + userId: string; + role: components["schemas"]["TenantRole"]; + status: components["schemas"]["MembershipStatus"]; + /** Format: date-time */ + updatedAt: string; + }; + /** @description 租户管理端用户查找请求 DTO。 */ + TenantAdminUserLookupDto: { + /** + * Format: uuid + * @description 用户 ID。 + */ + userId?: null | string; + /** @description 用户名。 */ + username?: null | string; + /** @description 邮箱。 */ + email?: null | string; + /** @description 手机号。 */ + phone?: null | string; + /** @description 名称。 */ + name?: null | string; + /** @description 头像地址。 */ + avatarUrl?: null | string; + }; + TenantAdminUserSummary: { + /** Format: uuid */ + id: string; + username: null | string; + email: null | string; + phone: null | string; + name: null | string; + avatarUrl: null | string; + primaryRole: string; + }; + TenantArchivePreview: { + /** Format: uuid */ + tenantId: string; + canArchive: boolean; + hasRecentSuccessfulExport: boolean; + blockers: string[]; + }; + TenantBillingCatalog: { + features: components["schemas"]["SaasFeature"][]; + basePlans: components["schemas"]["SaasOfferingVersionItem"][]; + addOns: components["schemas"]["SaasOfferingVersionItem"][]; + }; + TenantBillingCollectionMode: number; + TenantBillingInvoiceTitleType: number; + TenantBillingPolicyItem: { + /** Format: uuid */ + tenantId: string; + collectionMode: components["schemas"]["TenantBillingCollectionMode"]; + defaultPaymentProvider: string; + autoGenerateRenewal: boolean; + /** Format: int32 */ + renewalLeadDays: number | string; + /** Format: date-time */ + createdAt: string; + /** Format: date-time */ + updatedAt: string; + }; + TenantBillingProfileItem: { + /** Format: uuid */ + tenantId: string; + billingName: null | string; + taxId: null | string; + contactName: null | string; + contactPhoneMasked: null | string; + contactEmail: null | string; + billingAddress: null | string; + invoiceTitle: null | string; + invoiceType: null | components["schemas"]["TenantBillingInvoiceTitleType"]; + bankName: null | string; + bankAccountMasked: null | string; + metadata: components["schemas"]["JsonElement"]; + }; + TenantBrandingItem: { + /** Format: uuid */ + tenantId: string; + brandName: string; + shortName: null | string; + slogan: null | string; + organizationName: null | string; + logoUrl: null | string; + faviconUrl: null | string; + serviceWechat: null | string; + serviceAccountName: null | string; + theme: components["schemas"]["JsonElement"]; + publicAssets: components["schemas"]["JsonElement"]; + /** Format: date-time */ + updatedAt: string; + }; + TenantClassMemberStatus: number; + TenantClassMemberType: number; + TenantCommerceAnomalySummary: { + /** Format: int32 */ + openRefundCount: number | string; + /** Format: int32 */ + processingRefundCount: number | string; + /** Format: int32 */ + openReconciliationIssueCount: number | string; + /** Format: int32 */ + failedReconciliationBatchCount: number | string; + /** Format: int32 */ + pendingPaymentCount: number | string; + /** Format: int32 */ + paymentMismatchCount: number | string; + }; + TenantCouponList: { + items: components["schemas"]["Coupon"][]; + }; + TenantCouponRedemptionList: { + items: components["schemas"]["CouponRedemption"][]; + }; + TenantCouponReport: { + /** Format: int32 */ + couponCount: number | string; + /** Format: int32 */ + claimedCount: number | string; + /** Format: int32 */ + usedCount: number | string; + /** Format: int32 */ + discountAppliedCents: number | string; + }; + TenantDomainItem: { + /** Format: uuid */ + id: string; + host: string; + domainType: components["schemas"]["TenantDomainType"]; + status: components["schemas"]["TenantDomainStatus"]; + isPrimary: boolean; + verificationToken: null | string; + /** Format: date-time */ + verifiedAt: null | string; + /** Format: date-time */ + lastCheckedAt: null | string; + /** Format: date-time */ + dnsVerifiedAt: null | string; + /** Format: date-time */ + tlsReadyAt: null | string; + lastFailureReason: null | string; + /** Format: date-time */ + createdAt: string; + /** Format: date-time */ + updatedAt: string; + }; + TenantDomainStatus: number; + TenantDomainType: number; + TenantExternalProviderCapability: number; + TenantExternalProviderItem: { + /** Format: uuid */ + id: string; + capability: components["schemas"]["TenantExternalProviderCapability"]; + provider: string; + status: components["schemas"]["TenantExternalProviderStatus"]; + displayName: null | string; + secretRef: null | string; + /** Format: int32 */ + priority: number | string; + configPublic: components["schemas"]["JsonElement"]; + metadata: components["schemas"]["JsonElement"]; + /** Format: date-time */ + createdAt: string; + /** Format: date-time */ + updatedAt: string; + }; + TenantExternalProviderStatus: number; + TenantFeatureOverride: { + featureCode?: string; + mode?: components["schemas"]["TenantFeatureOverrideMode"]; + /** Format: date-time */ + expiresAt?: null | string; + reason?: string; + /** Format: date-time */ + createdAt?: string; + /** Format: date-time */ + updatedAt?: string; + /** Format: uuid */ + tenantId?: string; + /** Format: uuid */ + id?: string; + }; + TenantFeatureOverrideMode: number; + TenantFeatureUsage: { + metricCode?: string; + /** Format: date-time */ + periodStart?: string; + /** Format: date-time */ + periodEnd?: string; + /** Format: int64 */ + usedValue?: number | string; + /** Format: int64 */ + limitValueSnapshot?: number | string; + warningIssued?: boolean; + /** Format: int64 */ + version?: number | string; + /** Format: date-time */ + createdAt?: string; + /** Format: date-time */ + updatedAt?: string; + /** Format: uuid */ + tenantId?: string; + /** Format: uuid */ + id?: string; + }; + TenantFeedbackReport: { + /** Format: int32 */ + pendingCount: number | string; + /** Format: int32 */ + acceptedCount: number | string; + /** Format: int32 */ + rejectedCount: number | string; + /** Format: int32 */ + resolvedCount: number | string; + /** Format: int32 */ + closedCount: number | string; + }; + TenantFollowupReport: { + /** Format: int32 */ + openCount: number | string; + /** Format: int32 */ + inProgressCount: number | string; + /** Format: int32 */ + doneCount: number | string; + /** Format: int32 */ + overdueCount: number | string; + }; + TenantFrontendConfigDraft: { + branding: components["schemas"]["JsonElement"]; + theme: components["schemas"]["JsonElement"]; + features: components["schemas"]["JsonElement"]; + navigation: components["schemas"]["JsonElement"]; + homeModules: components["schemas"]["JsonElement"]; + }; + TenantFrontendConfigItem: { + /** Format: int32 */ + schemaVersion: number | string; + /** Format: int32 */ + configVersion: number | string; + published: components["schemas"]["TenantFrontendConfigDraft"]; + draft: components["schemas"]["TenantFrontendConfigDraft"]; + /** Format: date-time */ + publishedAt: null | string; + }; + TenantIdentityProviderItem: { + /** Format: uuid */ + id: string; + provider: string; + status: components["schemas"]["TenantExternalProviderStatus"]; + displayName: null | string; + secretRef: null | string; + /** Format: int32 */ + priority: number | string; + configPublic: components["schemas"]["JsonElement"]; + /** Format: date-time */ + createdAt: string; + /** Format: date-time */ + updatedAt: string; + }; + TenantLifecycleOperationItem: { + /** Format: uuid */ + id: string; + /** Format: uuid */ + tenantId: string; + operationType: components["schemas"]["TenantLifecycleOperationType"]; + status: components["schemas"]["TenantLifecycleOperationStatus"]; + /** Format: uuid */ + requestedBy: string; + /** Format: uuid */ + targetUserId: null | string; + /** Format: uuid */ + exportAssetId: null | string; + reason: null | string; + lastError: null | string; + /** Format: date-time */ + createdAt: string; + /** Format: date-time */ + completedAt: null | string; + }; + TenantLifecycleOperationStatus: number; + TenantLifecycleOperationType: number; + /** @description 租户生命周期变更原因。 */ + TenantLifecycleReasonDto: { + /** @description 审计原因。 */ + reason: string; + }; + /** @description 用户在某个租户内的成员摘要。 */ + TenantMembershipResponse: { + /** + * Format: uuid + * @description 租户 ID。 + */ + tenantId: string; + /** @description 租户名称。 */ + tenantName: string; + /** @description 租户编码。 */ + tenantSlug: string; + /** @description 当前用户在该租户内的角色。 */ + role: components["schemas"]["TenantRole"]; + /** @description 租户成员状态。 */ + status: components["schemas"]["MembershipStatus"]; + }; + /** @description 当前登录租户成员摘要。 */ + TenantMembershipSummary: { + /** + * Format: uuid + * @description 租户 ID。 + */ + tenantId: string; + /** @description 租户名称。 */ + tenantName: string; + /** @description 当前用户在租户内的角色。 */ + role: components["schemas"]["TenantRole"]; + /** @description 租户成员状态。 */ + status: components["schemas"]["MembershipStatus"]; + }; + TenantMode: number; + TenantOnboardingStatus: { + /** Format: uuid */ + tenantId: string; + readyForStudentTraffic: boolean; + /** Format: int32 */ + completedRequiredSteps: number | string; + /** Format: int32 */ + requiredSteps: number | string; + steps: components["schemas"]["TenantOnboardingStep"][]; + }; + TenantOnboardingStep: { + code: string; + required: boolean; + completed: boolean; + detail: null | string; + }; + /** @description 租户所有者转移请求。 */ + TenantOwnerTransferDto: { + /** + * Format: uuid + * @description 新的所有者用户 ID;必须是现有活跃成员。 + */ + targetUserId: string; + /** @description 审计原因。 */ + reason: string; + }; + TenantPaymentProviderItem: { + /** Format: uuid */ + id: string; + provider: string; + mode: string; + displayName: null | string; + status: components["schemas"]["TenantExternalProviderStatus"]; + secretRef: null | string; + /** Format: int32 */ + priority: number | string; + configPublic: components["schemas"]["JsonElement"]; + /** Format: date-time */ + createdAt: string; + /** Format: date-time */ + updatedAt: string; + }; + TenantPointClaimList: { + items: components["schemas"]["PointActivityClaim"][]; + }; + TenantPointExchangeItemList: { + items: components["schemas"]["PointExchangeItem"][]; + }; + TenantPointExchangeOrderList: { + items: components["schemas"]["PointExchangeOrder"][]; + }; + TenantPointRiskReport: { + /** Format: int32 */ + negativeScoreUserCount: number | string; + /** Format: int32 */ + highPointClaimUserCount: number | string; + /** Format: int32 */ + cancelledExchangeOrderCount: number | string; + }; + TenantPointTaskList: { + items: components["schemas"]["PointActivityTask"][]; + }; + TenantReceivableView: { + /** Format: uuid */ + id: string; + /** Format: uuid */ + orderId: null | string; + invoiceNo: string; + status: components["schemas"]["PlatformBillingInvoiceStatus"]; + /** Format: int32 */ + totalAmountCents: number | string; + currency: string; + /** Format: date */ + dueDate: null | string; + /** Format: date-time */ + issuedAt: null | string; + /** Format: date-time */ + paidAt: null | string; + }; + TenantReconciliationBatchList: { + items: components["schemas"]["CommerceReconciliationBatch"][]; + }; + TenantReconciliationIssueEventList: { + items: components["schemas"]["CommerceReconciliationIssueEvent"][]; + }; + TenantReconciliationIssueList: { + items: components["schemas"]["CommerceReconciliationIssue"][]; + }; + TenantReconciliationItemList: { + items: components["schemas"]["CommerceReconciliationItem"][]; + }; + TenantRecordStatus: number; + TenantRefundEventList: { + items: components["schemas"]["CommerceRefundEvent"][]; + }; + TenantRefundList: { + items: components["schemas"]["CommerceRefundRequest"][]; + }; + /** @description 租户解析响应。 */ + TenantResolveResponseDto: { + /** @description 公开租户基础信息。 */ + tenant: components["schemas"]["PublicTenantDto"]; + /** @description 公开品牌配置。 */ + branding: components["schemas"]["PublicTenantBrandingDto"]; + /** @description 面向前端公开的功能开关。 */ + features: components["schemas"]["JsonElement"]; + /** @description 面向管理端公开的功能开关。 */ + adminFeatures: components["schemas"]["JsonElement"]; + /** @description 可公开的租户配置,不包含密钥或内部配置。 */ + publicConfig: components["schemas"]["JsonElement"]; + }; + TenantRole: number; + TenantRuntimeBootstrap: { + /** Format: int32 */ + schemaVersion: number | string; + /** Format: int32 */ + configVersion: number | string; + tenantCode: string; + tenantName: string; + siteState: string; + branding: components["schemas"]["JsonElement"]; + theme: components["schemas"]["JsonElement"]; + features: components["schemas"]["JsonElement"]; + navigation: components["schemas"]["JsonElement"]; + homeModules: components["schemas"]["JsonElement"]; + enabledFeatures: string[]; + loginMethods: string[]; + }; + TenantSaasSubscription: { + /** Format: uuid */ + baseOfferingVersionId?: string; + /** Format: uuid */ + scheduledBaseOfferingVersionId?: null | string; + status?: components["schemas"]["TenantSaasSubscriptionStatus"]; + /** Format: date-time */ + startsAt?: string; + /** Format: date-time */ + currentPeriodStart?: string; + /** Format: date-time */ + currentPeriodEnd?: string; + cancelAtPeriodEnd?: boolean; + /** Format: date-time */ + cancelledAt?: null | string; + /** Format: int64 */ + lifecycleVersion?: number | string; + metadata?: components["schemas"]["JsonElement"]; + /** Format: date-time */ + createdAt?: string; + /** Format: date-time */ + updatedAt?: string; + /** Format: uuid */ + tenantId?: string; + /** Format: uuid */ + id?: string; + }; + TenantSaasSubscriptionStatus: number; + TenantSecretItem: { + /** Format: uuid */ + id: string; + purpose: string; + provider: string; + secretKey: string; + secretRef: string; + status: string; + /** Format: date-time */ + rotatedAt: null | string; + /** Format: date-time */ + expiresAt: null | string; + /** Format: date-time */ + updatedAt: string; + }; + TenantSecretStatus: number; + TenantSettingsItem: { + /** Format: uuid */ + tenantId: string; + featureFlags: components["schemas"]["JsonElement"]; + adminFeatureFlags: components["schemas"]["JsonElement"]; + publicConfig: components["schemas"]["JsonElement"]; + /** Format: date-time */ + updatedAt: string; + }; + TenantStatus: number; + TenantSubscriptionView: { + /** Format: uuid */ + id: string; + status: components["schemas"]["TenantSaasSubscriptionStatus"]; + /** Format: date-time */ + startsAt: string; + /** Format: date-time */ + currentPeriodStart: string; + /** Format: date-time */ + currentPeriodEnd: string; + cancelAtPeriodEnd: boolean; + /** Format: uuid */ + baseOfferingVersionId: string; + /** Format: uuid */ + scheduledBaseOfferingVersionId: null | string; + featureCodes: string[]; + }; + /** @description 租户督导生成请求 DTO。 */ + TenantSupervisionGenerateDto: { + /** @description 用户 ID 列表。 */ + userIds?: null | string[]; + /** + * Format: uuid + * @description 分配处理人用户 ID。 + */ + assignedToUserId?: null | string; + /** + * Format: date-time + * @description 到期时间。 + */ + dueAt?: null | string; + }; + TenantSupervisionGenerateResult: { + /** Format: int32 */ + createdCount: number | string; + }; + TenantSupervisionPreview: { + items: components["schemas"]["TenantSupervisionRiskStudentItem"][]; + }; + TenantSupervisionRiskStudentItem: { + /** Format: uuid */ + userId: string; + name: null | string; + phoneMasked: null | string; + /** Format: uuid */ + regionId: null | string; + ruleCodes: string[]; + reasons: string[]; + }; + TenantSupervisionRuleItem: { + code: string; + title: string; + enabled: boolean; + /** Format: int32 */ + daysWithoutCheckIn: null | number | string; + /** Format: int32 */ + maxQuestionsAnsweredToday: null | number | string; + followupType: string; + priority: string; + metadata: components["schemas"]["JsonElement"]; + }; + TenantThemeConfigStatus: number; + TenantThemeItem: { + /** Format: uuid */ + tenantId: string; + activeTemplateCode: null | string; + activeTheme: components["schemas"]["JsonElement"]; + activePublicAssets: components["schemas"]["JsonElement"]; + draftTemplateCode: null | string; + draftTheme: components["schemas"]["JsonElement"]; + draftPublicAssets: components["schemas"]["JsonElement"]; + status: components["schemas"]["TenantThemeConfigStatus"]; + /** Format: date-time */ + publishedAt: null | string; + /** Format: uuid */ + publishedBy: null | string; + /** Format: uuid */ + draftUpdatedBy: null | string; + /** Format: date-time */ + updatedAt: string; + }; + TenantThemeTemplateItem: { + code: string; + name: string; + description: null | string; + previewImageUrl: null | string; + theme: components["schemas"]["JsonElement"]; + publicAssets: components["schemas"]["JsonElement"]; + /** Format: int32 */ + order: number | string; + }; + /** @description 记录推荐事件请求 DTO。 */ + TrackReferralEventDto: { + /** @description 推荐码。 */ + refCode: string; + /** @description 事件类型。 */ + eventType?: null | string; + /** @description 来源。 */ + source?: null | string; + /** + * Format: uuid + * @description 目标用户 ID。 + */ + targetUserId?: null | string; + metadata?: null | components["schemas"]["JsonElement"]; + /** @description 租户编码。 */ + tenantCode?: null | string; + }; + /** @description 更新调账凭证状态请求 DTO。 */ + UpdateAdjustmentVoucherStatusDto: { + /** + * Format: uuid + * @description 凭证 ID。 + */ + voucherId: string; + /** @description 状态。 */ + status?: components["schemas"]["CommerceAdjustmentVoucherStatus"]; + /** @description 备注。 */ + note?: null | string; + }; + /** @description 更新佣金结算凭证状态请求。 */ + UpdateCommissionProofStatusDto: { + /** + * Format: uuid + * @description 凭证 ID。 + */ + proofId: string; + /** @description 状态。 */ + status?: null | string; + /** @description 审核备注。 */ + reviewNote?: null | string; + metadata?: null | components["schemas"]["JsonElement"]; + }; + /** @description 保存佣金配置请求。 */ + UpdateCommissionSettingsDto: { + /** + * Format: double + * @description 默认佣金比例。 + */ + defaultRate?: null | number | string; + /** + * Format: int32 + * @description 最低结算金额,单位为分。 + */ + minSettlementCents?: null | number | string; + /** @description 结算周期。 */ + settlementCycle?: null | string; + config?: null | components["schemas"]["JsonElement"]; + }; + /** @description 更新佣金结算单状态请求 DTO。 */ + UpdateCommissionSettlementStatusDto: { + /** + * Format: uuid + * @description 结算单 ID。 + */ + settlementId: string; + /** @description 状态。 */ + status?: null | string; + /** @description 审核备注。 */ + reviewNote?: null | string; + /** @description 支付方式。 */ + paymentMethod?: null | string; + /** @description 收款账号。 */ + paymentAccount?: null | string; + metadata?: null | components["schemas"]["JsonElement"]; + }; + /** @description 调整成员佣金比例请求。 */ + UpdateMemberCommissionRateDto: { + /** + * Format: uuid + * @description 用户 ID。 + */ + userId: string; + /** + * Format: double + * @description 成员佣金比例。 + */ + commissionRate?: null | number | string; + commissionConfig?: null | components["schemas"]["JsonElement"]; + }; + UpdatePlatformApprovalPolicyDto: { + enabled: boolean; + alwaysRequireApproval: boolean; + /** Format: int32 */ + amountThresholdCents: null | number | string; + /** Format: int32 */ + expiresAfterHours: number | string; + conditions: null | components["schemas"]["JsonElement"]; + }; + /** @description 更新平台审计Alert状态请求 DTO。 */ + UpdatePlatformAuditAlertStatusDto: { + /** + * Format: uuid + * @description 告警 ID。 + */ + alertId: string; + /** @description 状态。 */ + status?: components["schemas"]["PlatformAuditAlertStatus"]; + /** @description 处理备注。 */ + resolutionNote?: null | string; + }; + /** @description 更新平台Staff状态请求 DTO。 */ + UpdatePlatformStaffStatusDto: { + /** + * Format: uuid + * @description 用户 ID。 + */ + userId: string; + /** @description 状态。 */ + status?: components["schemas"]["UserStatus"]; + /** @description 原因。 */ + reason?: null | string; + }; + /** @description 更新平台租户状态请求 DTO。 */ + UpdatePlatformTenantStatusDto: { + /** + * Format: uuid + * @description 租户 ID。 + */ + tenantId: string; + /** @description 状态。 */ + status?: components["schemas"]["TenantStatus"]; + /** @description 原因。 */ + reason?: null | string; + }; + /** @description 更新积分兑换订单状态请求 DTO。 */ + UpdatePointExchangeOrderStatusDto: { + /** + * Format: uuid + * @description 订单 ID。 + */ + orderId: string; + /** @description 状态。 */ + status?: components["schemas"]["PointExchangeOrderStatus"]; + }; + /** @description 更新资料请求 DTO。 */ + UpdateProfileDto: { + /** @description 名称。 */ + name?: null | string; + /** @description 头像预设。 */ + avatarPreset?: null | string; + /** + * Format: uuid + * @description 地区 ID。 + */ + regionId?: null | string; + /** + * Format: uuid + * @description 已选择院校 ID。 + */ + selectedSchoolId?: null | string; + /** + * Format: uuid + * @description 已选择专业 ID。 + */ + selectedMajorId?: null | string; + stats?: null | components["schemas"]["JsonElement"]; + progress?: null | components["schemas"]["JsonElement"]; + moduleSelections?: null | components["schemas"]["JsonElement"]; + recentActivities?: null | components["schemas"]["JsonElement"]; + }; + /** @description 更新对账Issue请求 DTO。 */ + UpdateReconciliationIssueDto: { + /** + * Format: uuid + * @description 工单 ID。 + */ + issueId: string; + /** @description 状态。 */ + status?: components["schemas"]["ReconciliationIssueStatus"]; + /** @description 处理类型。 */ + resolutionType?: components["schemas"]["ReconciliationResolutionType"]; + /** @description 备注。 */ + note?: null | string; + /** + * Format: uuid + * @description 分配处理人。 + */ + assignedTo?: null | string; + }; + /** @description 更新退款状态请求 DTO。 */ + UpdateRefundStatusDto: { + /** + * Format: uuid + * @description 退款申请 ID。 + */ + refundRequestId: string; + /** @description 状态。 */ + status?: components["schemas"]["CommerceRefundStatus"]; + /** @description 原因。 */ + reason?: null | string; + /** @description 渠道退款单号。 */ + providerRefundNo?: null | string; + }; + /** @description 更新租户管理端反馈请求 DTO。 */ + UpdateTenantAdminFeedbackDto: { + /** + * Format: uuid + * @description 反馈 ID。 + */ + feedbackId: string; + /** @description 状态。 */ + status?: null | string; + /** @description 优先级。 */ + priority?: null | string; + /** @description 处理结果。 */ + resolution?: null | string; + /** @description 备注。 */ + note?: null | string; + /** @description 扩展元数据。 */ + metadata?: components["schemas"]["JsonElement"]; + }; + /** @description 更新租户管理端学生状态请求 DTO。 */ + UpdateTenantAdminStudentStatusDto: { + /** + * Format: uuid + * @description 用户 ID。 + */ + userId: string; + /** @description 状态。 */ + status?: null | string; + /** @description 原因。 */ + reason?: null | string; + }; + /** @description 新增或更新内容资产请求。 */ + UpsertAssetDto: { + /** + * Format: uuid + * @description 资产 ID。 + */ + assetId?: null | string; + /** + * Format: uuid + * @description 地区 ID。 + */ + regionId?: null | string; + /** + * Format: uuid + * @description 科目 ID。 + */ + subjectId?: null | string; + /** + * Format: uuid + * @description 分类 ID。 + */ + categoryId?: null | string; + /** + * Format: uuid + * @description 内容节点 ID。 + */ + contentNodeId?: null | string; + /** @description 历史系统 ID。 */ + legacyId?: null | string; + /** @description 资产键。 */ + assetKey?: null | string; + /** @description 标题。 */ + title?: null | string; + /** @description 分类。 */ + category?: null | string; + /** @description 说明。 */ + description?: null | string; + /** @description 文件名。 */ + fileName?: null | string; + /** @description CDN 地址。 */ + cdnUrl?: null | string; + /** @description 是否公开。 */ + isPublic?: null | boolean; + /** @description 资产类型。 */ + assetType?: null | string; + /** @description 可见性。 */ + visibility?: null | string; + /** @description 状态。 */ + status?: null | string; + /** @description 服务提供方。 */ + provider?: null | string; + /** @description 存储桶。 */ + bucket?: null | string; + /** @description 对象存储键。 */ + objectKey?: null | string; + /** @description MIME 类型。 */ + mimeType?: null | string; + /** + * Format: int64 + * @description 文件大小,单位为字节。 + */ + fileSizeBytes?: null | number | string; + /** @description SHA-256 校验值。 */ + checksumSha256?: null | string; + /** @description 预览地址。 */ + previewUrl?: null | string; + /** @description 预览对象存储键。 */ + previewObjectKey?: null | string; + /** + * Format: int32 + * @description 显示顺序。 + */ + order?: null | number | string; + /** @description 访问规则。 */ + accessRules?: components["schemas"]["JsonElement"]; + /** @description 扩展元数据。 */ + metadata?: components["schemas"]["JsonElement"]; + }; + /** @description 创建或更新后台角色请求。 */ + UpsertBackofficeRoleDto: { + /** + * Format: uuid + * @description ID。 + */ + id?: null | string; + /** @description 编码。 */ + code?: string; + /** @description 名称。 */ + name?: string; + /** @description 状态。 */ + status?: components["schemas"]["BackendRoleStatus"]; + /** @description 说明。 */ + description?: null | string; + dataScope?: null | components["schemas"]["JsonElement"]; + }; + /** @description 新增或更新内容条目请求 DTO。 */ + UpsertContentEntryDto: { + /** + * Format: uuid + * @description ID。 + */ + id?: null | string; + /** + * Format: uuid + * @description 地区 ID。 + */ + regionId?: null | string; + /** @description 历史系统 ID。 */ + legacyId?: null | string; + /** @description 入口键。 */ + entryKey?: null | string; + /** @description 名称。 */ + name: string; + /** @description 入口类型。 */ + entryType?: null | string; + /** @description 图标。 */ + icon?: null | string; + /** @description 路由地址。 */ + route?: null | string; + /** @description 说明。 */ + description?: null | string; + /** @description 可见性。 */ + visibility?: null | string; + /** @description 访问规则。 */ + accessRules?: components["schemas"]["JsonElement"]; + /** @description 布局配置。 */ + layoutConfig?: components["schemas"]["JsonElement"]; + /** + * Format: int32 + * @description 显示顺序。 + */ + order?: null | number | string; + /** @description 是否启用。 */ + isActive?: null | boolean; + }; + /** @description 新增或更新内容节点请求 DTO。 */ + UpsertContentNodeDto: { + /** + * Format: uuid + * @description ID。 + */ + id?: null | string; + /** + * Format: uuid + * @description 内容入口 ID。 + */ + entryId: string; + /** + * Format: uuid + * @description 地区 ID。 + */ + regionId?: null | string; + /** + * Format: uuid + * @description 父节点 ID。 + */ + parentId?: null | string; + /** @description 历史系统 ID。 */ + legacyId?: null | string; + /** @description 节点键。 */ + nodeKey?: null | string; + /** @description 名称。 */ + name: string; + /** @description 节点Type。 */ + nodeType?: null | string; + /** @description 标记类型。 */ + markerType?: null | string; + /** @description 标记配置。 */ + markerConfig?: components["schemas"]["JsonElement"]; + /** + * Format: int32 + * @description 显示顺序。 + */ + order?: null | number | string; + /** @description 是否启用。 */ + isActive?: null | boolean; + /** @description 是否可选择。 */ + isSelectable?: null | boolean; + /** @description 是否叶子节点。 */ + isLeaf?: null | boolean; + /** @description 访问规则。 */ + accessRules?: components["schemas"]["JsonElement"]; + /** @description 扩展元数据。 */ + metadata?: components["schemas"]["JsonElement"]; + }; + /** @description 新增或更新CRM配置请求 DTO。 */ + UpsertCrmConfigDto: { + /** @description 是否启用。 */ + enabled?: boolean; + /** @description 访问地址。 */ + url?: null | string; + /** @description 密钥引用。 */ + secretRef?: null | string; + /** @description 密钥内容。 */ + secret?: null | string; + /** @description 表单名称。 */ + formName?: null | string; + /** @description 考试类型。 */ + examType?: null | string; + /** + * Format: int32 + * @description 超时时长,单位为秒。 + */ + timeoutSeconds?: null | number | string; + /** + * Format: int32 + * @description 延迟秒数。 + */ + delaySeconds?: null | number | string; + /** @description 分配模式。 */ + assignmentMode?: null | string; + assignmentPool?: null | components["schemas"]["JsonElement"]; + assignmentConfig?: null | components["schemas"]["JsonElement"]; + }; + /** @description 新增或更新支付账号请求 DTO。 */ + UpsertPaymentAccountDto: { + /** @description 服务提供方。 */ + provider: string; + /** @description 模式。 */ + mode?: null | string; + /** @description 显示名称。 */ + displayName?: null | string; + /** @description 状态。 */ + status?: components["schemas"]["TenantExternalProviderStatus"]; + /** @description 密钥引用。 */ + secretRef?: null | string; + /** + * Format: int32 + * @description 优先级。 + */ + priority?: null | number | string; + /** @description 公开配置内容。 */ + configPublic?: components["schemas"]["JsonElement"]; + }; + /** @description 新增或更新平台DunningChannel请求 DTO。 */ + UpsertPlatformBillingDunningChannelDto: { + /** + * Format: uuid + * @description 通知渠道 ID。 + */ + channelId?: null | string; + /** @description 渠道编码。 */ + channelCode: string; + /** @description 名称。 */ + name: string; + /** @description 说明。 */ + description?: null | string; + /** @description 是否启用。 */ + enabled?: boolean; + /** @description 服务提供方。 */ + provider?: components["schemas"]["PlatformBillingDunningProvider"]; + /** @description Webhook 地址。 */ + webhookUrl: string; + /** @description 密钥引用。 */ + secretRef?: null | string; + /** @description 提醒类型列表。 */ + reminderTypes?: string[]; + /** @description 提醒渠道列表。 */ + reminderChannels?: string[]; + /** + * Format: int32 + * @description 最低提醒级别。 + */ + minReminderLevel?: number | string; + /** @description 租户 ID 列表。 */ + tenantIds?: string[]; + /** + * Format: int32 + * @description 超时时长,单位为秒。 + */ + timeoutSeconds?: number | string; + /** @description 扩展元数据。 */ + metadata?: components["schemas"]["JsonElement"]; + }; + /** @description 新增或更新租户 CRM 配置请求。 */ + UpsertPlatformCrmConfigDto: { + /** + * Format: uuid + * @description ID。 + */ + id?: null | string; + /** + * Format: uuid + * @description 租户 ID。 + */ + tenantId: string; + /** @description 是否启用。 */ + enabled?: boolean; + /** @description 回调地址。 */ + url?: null | string; + /** @description 密钥引用。 */ + secretRef?: null | string; + /** @description 表单名称。 */ + formName?: null | string; + /** @description 考试类型。 */ + examType?: null | string; + /** + * Format: int32 + * @description 超时时长,单位为秒。 + */ + timeoutSeconds?: null | number | string; + /** + * Format: int32 + * @description 延迟秒数。 + */ + delaySeconds?: null | number | string; + /** @description 分配模式。 */ + assignmentMode?: null | string; + assignmentPool?: null | components["schemas"]["JsonElement"]; + assignmentConfig?: null | components["schemas"]["JsonElement"]; + }; + UpsertPlatformNotificationTemplateDto: { + /** Format: uuid */ + id: null | string; + code: string; + name: string; + channel: components["schemas"]["PlatformNotificationChannel"]; + subjectTemplate: string; + bodyTemplate: string; + enabled: boolean; + variables: null | components["schemas"]["JsonElement"]; + }; + /** @description 新增或更新平台支付应用请求。 */ + UpsertPlatformPaymentAppDto: { + /** + * Format: uuid + * @description ID。 + */ + id?: null | string; + /** @description 支付应用编码。 */ + appCode: string; + /** @description 支付应用名称。 */ + appName: string; + /** @description 状态。 */ + status?: components["schemas"]["PlatformPaymentAppStatus"]; + /** @description 结算模式。 */ + settlementMode?: string; + /** @description 说明。 */ + description?: null | string; + /** @description 扩展元数据。 */ + metadata?: components["schemas"]["JsonElement"]; + }; + /** @description 新增或更新平台支付渠道请求。 */ + UpsertPlatformPaymentChannelDto: { + /** + * Format: uuid + * @description ID。 + */ + id?: null | string; + /** + * Format: uuid + * @description 支付应用 ID。 + */ + appId: string; + /** @description 服务提供方。 */ + provider: string; + /** @description 模式。 */ + mode?: string; + /** @description 状态。 */ + status?: components["schemas"]["PlatformPaymentChannelStatus"]; + /** @description 显示名称。 */ + displayName: string; + /** @description 密钥引用。 */ + secretRef?: null | string; + /** @description 回调路径。 */ + callbackPath?: null | string; + /** + * Format: int32 + * @description 优先级。 + */ + priority?: null | number | string; + /** @description 公开配置内容。 */ + configPublic?: components["schemas"]["JsonElement"]; + /** @description 扩展元数据。 */ + metadata?: components["schemas"]["JsonElement"]; + }; + UpsertPlatformQuestionBankCommand: { + /** Format: uuid */ + id: null | string; + name: string; + metadata: components["schemas"]["JsonElement"]; + }; + UpsertPlatformQuestionBankNodeCommand: { + /** Format: uuid */ + id: null | string; + /** Format: uuid */ + questionBankId: string; + /** Format: uuid */ + parentId: null | string; + nodeKey: null | string; + name: string; + nodeType: components["schemas"]["ContentNodeType"]; + /** Format: int32 */ + sortOrder: number | string; + isSelectable: boolean; + metadata: components["schemas"]["JsonElement"]; + }; + UpsertPlatformQuestionCommand: { + /** Format: uuid */ + id: null | string; + /** Format: uuid */ + questionBankId: string; + /** Format: uuid */ + contentNodeId: string; + legacyId: null | string; + type: null | string; + typeLabel: null | string; + /** Format: int32 */ + difficulty: null | number | string; + tags: components["schemas"]["JsonElement"]; + content: null | string; + options: components["schemas"]["JsonElement"]; + /** Format: int32 */ + correctOptionIndex: null | number | string; + correctOptionIndices: components["schemas"]["JsonElement"]; + answerText: null | string; + explanation: null | string; + subQuestions: components["schemas"]["JsonElement"]; + codeLang: null | string; + codeTemplate: null | string; + mediaUrl: null | string; + status: null | string; + examMarkers: components["schemas"]["JsonElement"]; + sourceHash: null | string; + }; + /** @description 新增或更新租户短信渠道请求。 */ + UpsertPlatformSmsChannelDto: { + /** + * Format: uuid + * @description ID。 + */ + id?: null | string; + /** + * Format: uuid + * @description 租户 ID。 + */ + tenantId: string; + /** @description 服务提供方。 */ + provider: string; + /** @description 名称。 */ + name: string; + /** @description 短信签名。 */ + signature: string; + /** @description 使用场景。 */ + scene: string; + /** @description 状态。 */ + status?: components["schemas"]["TenantExternalProviderStatus"]; + /** @description 密钥引用。 */ + secretRef?: null | string; + /** + * Format: int32 + * @description 优先级。 + */ + priority?: null | number | string; + /** + * Format: int32 + * @description 月度配额。 + */ + monthlyQuota?: null | number | string; + /** @description 公开配置内容。 */ + configPublic?: components["schemas"]["JsonElement"]; + /** @description 扩展元数据。 */ + metadata?: components["schemas"]["JsonElement"]; + }; + /** @description 新增或更新租户短信模板请求。 */ + UpsertPlatformSmsTemplateDto: { + /** + * Format: uuid + * @description ID。 + */ + id?: null | string; + /** + * Format: uuid + * @description 租户 ID。 + */ + tenantId: string; + /** + * Format: uuid + * @description 短信渠道 ID。 + */ + channelId: string; + /** @description 编码。 */ + code: string; + /** @description 名称。 */ + name: string; + /** @description 类型。 */ + type?: components["schemas"]["SmsTemplateType"]; + /** @description 审核状态。 */ + auditStatus?: components["schemas"]["SmsTemplateAuditStatus"]; + /** @description 状态。 */ + status?: components["schemas"]["SmsTemplateStatus"]; + /** @description 渠道模板编码。 */ + providerTemplateCode?: null | string; + /** @description 模板内容。 */ + content: string; + /** @description Remark。 */ + remark?: null | string; + /** @description 扩展元数据。 */ + metadata?: components["schemas"]["JsonElement"]; + }; + /** @description 新增或更新平台Staff请求 DTO。 */ + UpsertPlatformStaffDto: { + /** + * Format: uuid + * @description 用户 ID。 + */ + userId?: null | string; + /** @description 邮箱。 */ + email?: null | string; + /** @description 手机号。 */ + phone?: null | string; + /** @description 名称。 */ + name?: null | string; + /** @description 状态。 */ + status?: components["schemas"]["UserStatus"]; + /** @description 角色 ID 列表。 */ + roleIds?: string[]; + }; + /** @description 新增或更新平台租户账务资料请求 DTO。 */ + UpsertPlatformTenantBillingProfileDto: { + /** + * Format: uuid + * @description 租户 ID。 + */ + tenantId: string; + /** @description 账务名称。 */ + billingName?: null | string; + /** @description 税号。 */ + taxId?: null | string; + /** @description 联系人姓名。 */ + contactName?: null | string; + /** @description 联系人手机号。 */ + contactPhone?: null | string; + /** @description 联系人邮箱。 */ + contactEmail?: null | string; + /** @description 账务地址。 */ + billingAddress?: null | string; + /** @description 发票抬头。 */ + invoiceTitle?: null | string; + invoiceType?: null | components["schemas"]["TenantBillingInvoiceTitleType"]; + /** @description 开户银行。 */ + bankName?: null | string; + /** @description 脱敏银行账号。 */ + bankAccountMasked?: null | string; + /** @description 扩展元数据。 */ + metadata?: components["schemas"]["JsonElement"]; + }; + /** @description 新增或更新租户支付应用请求。 */ + UpsertPlatformTenantPaymentAppDto: { + /** + * Format: uuid + * @description 租户 ID。 + */ + tenantId: string; + /** @description 服务提供方。 */ + provider: string; + /** @description 状态。 */ + status?: components["schemas"]["TenantExternalProviderStatus"]; + /** @description 显示名称。 */ + displayName?: null | string; + /** @description 密钥引用。 */ + secretRef?: null | string; + /** + * Format: int32 + * @description 优先级。 + */ + priority?: null | number | string; + /** @description 公开配置内容。 */ + configPublic?: components["schemas"]["JsonElement"]; + /** @description 扩展元数据。 */ + metadata?: components["schemas"]["JsonElement"]; + }; + /** @description 新增或更新积分兑换Item请求 DTO。 */ + UpsertPointExchangeItemDto: { + /** + * Format: uuid + * @description ID。 + */ + id?: null | string; + /** + * Format: uuid + * @description 地区 ID。 + */ + regionId?: null | string; + /** @description 兑换项键。 */ + itemKey: string; + /** @description 名称。 */ + name: string; + /** @description 说明。 */ + description?: null | string; + /** @description 兑换项类型。 */ + itemType?: components["schemas"]["PointExchangeItemType"]; + /** @description 状态。 */ + status?: components["schemas"]["PointExchangeItemStatus"]; + /** + * Format: int32 + * @description 所需积分。 + */ + pointsCost?: number | string; + /** + * Format: int32 + * @description 库存数量。 + */ + stock?: null | number | string; + /** + * Format: int32 + * @description 天数。 + */ + days?: null | number | string; + /** + * Format: int32 + * @description 排序值。 + */ + sortOrder?: number | string; + /** + * Format: date-time + * @description 开始时间。 + */ + startsAt?: null | string; + /** + * Format: date-time + * @description 结束时间。 + */ + endsAt?: null | string; + /** @description 履约载荷。 */ + fulfillmentPayload?: components["schemas"]["JsonElement"]; + /** @description 扩展元数据。 */ + metadata?: components["schemas"]["JsonElement"]; + }; + /** @description 新增或更新积分任务请求 DTO。 */ + UpsertPointTaskDto: { + /** + * Format: uuid + * @description ID。 + */ + id?: null | string; + /** @description 任务键。 */ + taskKey: string; + /** @description 标题。 */ + title: string; + /** @description 说明。 */ + description?: null | string; + /** @description 任务类型。 */ + taskType?: components["schemas"]["PointActivityTaskType"]; + /** @description 状态。 */ + status?: components["schemas"]["PointActivityTaskStatus"]; + /** + * Format: int32 + * @description 积分数量。 + */ + points?: number | string; + /** + * Format: int32 + * @description 每用户最多领取次数。 + */ + maxClaimsPerUser?: number | string; + /** + * Format: date-time + * @description 开始时间。 + */ + startsAt?: null | string; + /** + * Format: date-time + * @description 结束时间。 + */ + endsAt?: null | string; + /** + * Format: int32 + * @description 排序值。 + */ + sortOrder?: number | string; + /** @description 规则配置。 */ + rules?: components["schemas"]["JsonElement"]; + /** @description 扩展元数据。 */ + metadata?: components["schemas"]["JsonElement"]; + }; + /** @description 新增或更新练习Blueprint请求 DTO。 */ + UpsertPracticeBlueprintDto: { + /** + * Format: uuid + * @description ID。 + */ + id?: null | string; + /** + * Format: uuid + * @description 地区 ID。 + */ + regionId?: null | string; + /** + * Format: uuid + * @description 内容入口 ID。 + */ + entryId?: null | string; + /** + * Format: uuid + * @description 节点 ID。 + */ + nodeId?: null | string; + /** + * Format: uuid + * @description 题集 ID。 + */ + collectionId?: null | string; + /** @description 历史系统 ID。 */ + legacyId?: null | string; + /** @description 名称。 */ + name: string; + /** @description 模式。 */ + mode?: null | string; + /** @description 组卷方式。 */ + assemblyType?: null | string; + /** + * Format: int32 + * @description 题目数量上限。 + */ + questionLimit?: null | number | string; + /** + * Format: int32 + * @description 时长,单位为分钟。 + */ + durationMinutes?: null | number | string; + /** + * Format: double + * @description 总分。 + */ + totalScore?: null | number | string; + /** + * Format: double + * @description 及格分。 + */ + passScore?: null | number | string; + /** @description 分段配置。 */ + sections?: components["schemas"]["JsonElement"]; + /** @description 规则配置。 */ + rules?: components["schemas"]["JsonElement"]; + /** @description 访问规则。 */ + accessRules?: components["schemas"]["JsonElement"]; + /** @description 状态。 */ + status?: null | string; + /** + * Format: int32 + * @description 显示顺序。 + */ + order?: null | number | string; + }; + /** @description 新增或更新题目题集请求 DTO。 */ + UpsertQuestionCollectionDto: { + /** + * Format: uuid + * @description ID。 + */ + id?: null | string; + /** + * Format: uuid + * @description 地区 ID。 + */ + regionId?: null | string; + /** + * Format: uuid + * @description 内容入口 ID。 + */ + entryId?: null | string; + /** + * Format: uuid + * @description 节点 ID。 + */ + nodeId?: null | string; + /** + * Format: uuid + * @description 科目 ID。 + */ + subjectId?: null | string; + /** + * Format: uuid + * @description 分类 ID。 + */ + categoryId?: null | string; + /** + * Format: uuid + * @description 题库 ID。 + */ + questionBankId?: null | string; + /** @description 历史系统 ID。 */ + legacyId?: null | string; + /** @description 名称。 */ + name: string; + /** @description 题集类型。 */ + collectionType?: null | string; + /** @description 来源类型。 */ + sourceType?: null | string; + /** @description 筛选条件。 */ + filters?: components["schemas"]["JsonElement"]; + /** + * Format: double + * @description 总分。 + */ + totalScore?: null | number | string; + /** + * Format: int32 + * @description 时长,单位为分钟。 + */ + durationMinutes?: null | number | string; + /** @description 状态。 */ + status?: null | string; + /** + * Format: int32 + * @description 显示顺序。 + */ + order?: null | number | string; + /** @description 访问规则。 */ + accessRules?: components["schemas"]["JsonElement"]; + /** @description 扩展元数据。 */ + metadata?: components["schemas"]["JsonElement"]; + }; + /** @description 新增或更新推荐团队请求 DTO。 */ + UpsertReferralTeamDto: { + /** + * Format: uuid + * @description 成员用户 ID。 + */ + memberUserId: string; + /** + * Format: uuid + * @description 上级成员用户 ID。 + */ + leaderUserId?: null | string; + /** @description 关系类型。 */ + relationType?: null | string; + /** @description 状态。 */ + status?: null | string; + metadata?: null | components["schemas"]["JsonElement"]; + }; + /** @description 新增或更新SaaS功能请求 DTO。 */ + UpsertSaasFeatureDto: { + /** Format: uuid */ + id: null | string; + code: string; + name: string; + category: string; + description: null | string; + /** Format: int32 */ + referencePriceCents: number | string; + currency: string; + status: components["schemas"]["SaasFeatureStatus"]; + /** Format: int32 */ + sortOrder: number | string; + }; + /** @description 新增或更新 SaaS 功能额度定义。 */ + UpsertSaasFeatureLimitDto: { + /** Format: uuid */ + id: null | string; + metricCode: string; + featureCode: string; + name: string; + unit: string; + kind: components["schemas"]["SaasFeatureLimitKind"]; + /** Format: int32 */ + warningPercent: number | string; + isHardLimit: boolean; + }; + /** @description 新增或更新SaaS套餐请求 DTO。 */ + UpsertSaasOfferingDto: { + /** Format: uuid */ + id: null | string; + code: string; + name: string; + type: components["schemas"]["SaasOfferingType"]; + status: components["schemas"]["SaasOfferingStatus"]; + description: null | string; + /** Format: int32 */ + sortOrder: number | string; + }; + /** @description 新增或更新SaaS套餐版本请求 DTO。 */ + UpsertSaasOfferingVersionDto: { + /** Format: uuid */ + id: null | string; + /** Format: uuid */ + offeringId: string; + billingCycle: components["schemas"]["PlatformBillingCycle"]; + /** Format: int32 */ + originalAmountCents: number | string; + /** Format: int32 */ + amountCents: number | string; + currency: string; + /** Format: date-time */ + effectiveAt: null | string; + featureCodes: null | string[]; + limits: null | { + [key: string]: number | string; + }; + metadata: components["schemas"]["JsonElement"]; + }; + /** @description 新增或更新租户管理端徽章请求 DTO。 */ + UpsertTenantAdminBadgeDto: { + /** + * Format: uuid + * @description ID。 + */ + id?: null | string; + /** @description 历史系统 ID。 */ + legacyId?: null | string; + /** @description 名称。 */ + name: string; + /** @description 说明。 */ + description?: null | string; + /** @description 分类。 */ + category?: null | string; + /** @description 图标地址。 */ + iconUrl?: null | string; + /** + * Format: int32 + * @description 级别。 + */ + level?: null | number | string; + /** @description 解锁类型。 */ + unlockType?: null | string; + /** @description 条件字段。 */ + conditionField?: null | string; + /** @description 条件运算符。 */ + conditionOperator?: null | string; + /** + * Format: double + * @description 条件值。 + */ + conditionValue?: null | number | string; + /** @description 条件扩展配置。 */ + conditionExtra?: components["schemas"]["JsonElement"]; + /** + * Format: int32 + * @description 显示顺序。 + */ + order?: null | number | string; + /** @description 是否启用。 */ + isActive?: null | boolean; + }; + /** @description 新增或更新租户管理端班级请求 DTO。 */ + UpsertTenantAdminClassDto: { + /** + * Format: uuid + * @description ID。 + */ + id?: null | string; + /** + * Format: uuid + * @description 地区 ID。 + */ + regionId?: null | string; + /** @description 历史系统 ID。 */ + legacyId?: null | string; + /** @description 编码。 */ + code?: null | string; + /** @description 名称。 */ + name: string; + /** @description 说明。 */ + description?: null | string; + /** @description 状态。 */ + status?: null | string; + /** + * Format: int32 + * @description 显示顺序。 + */ + order?: null | number | string; + /** @description 扩展元数据。 */ + metadata?: components["schemas"]["JsonElement"]; + }; + /** @description 新增或更新租户管理端班级成员请求 DTO。 */ + UpsertTenantAdminClassMemberDto: { + /** + * Format: uuid + * @description 班级 ID。 + */ + classId: string; + /** @description 用户信息。 */ + user?: components["schemas"]["TenantAdminUserLookupDto"]; + /** @description 成员类型。 */ + memberType?: null | string; + /** @description 状态。 */ + status?: null | string; + /** @description 扩展元数据。 */ + metadata?: components["schemas"]["JsonElement"]; + }; + /** @description 新增或更新租户管理端成员请求 DTO。 */ + UpsertTenantAdminMemberDto: { + /** + * Format: uuid + * @description 成员关系 ID。 + */ + membershipId?: null | string; + /** @description 用户信息。 */ + user?: components["schemas"]["TenantAdminUserLookupDto"]; + /** @description 角色。 */ + role?: null | string; + /** @description 状态。 */ + status?: null | string; + /** @description 主要角色。 */ + primaryRole?: null | string; + }; + /** @description 新增或更新租户管理端通知请求 DTO。 */ + UpsertTenantAdminNotificationDto: { + /** + * Format: uuid + * @description 用户 ID。 + */ + userId: string; + /** @description 通知类型。 */ + notificationType: string; + /** @description 严重级别。 */ + severity?: null | string; + /** @description 标题。 */ + title: string; + /** @description 消息内容。 */ + message: string; + /** @description 操作按钮文案。 */ + actionLabel?: null | string; + /** @description 操作路径。 */ + actionPath?: null | string; + /** @description 来源类型。 */ + sourceType?: null | string; + /** + * Format: uuid + * @description 来源 ID。 + */ + sourceId?: null | string; + /** @description 去重键。 */ + dedupeKey?: null | string; + /** @description 扩展元数据。 */ + metadata?: components["schemas"]["JsonElement"]; + }; + /** @description 新增或更新租户管理端学生请求 DTO。 */ + UpsertTenantAdminStudentDto: { + /** @description 用户信息。 */ + user?: components["schemas"]["TenantAdminUserLookupDto"]; + /** + * Format: uuid + * @description 地区 ID。 + */ + regionId?: null | string; + /** + * Format: uuid + * @description 已选择院校 ID。 + */ + selectedSchoolId?: null | string; + /** + * Format: uuid + * @description 已选择专业 ID。 + */ + selectedMajorId?: null | string; + /** @description 头像预设。 */ + avatarPreset?: null | string; + /** @description 统计数据。 */ + stats?: components["schemas"]["JsonElement"]; + /** @description 进度数据。 */ + progress?: components["schemas"]["JsonElement"]; + /** @description 模块选择数据。 */ + moduleSelections?: components["schemas"]["JsonElement"]; + /** @description 原始用户资料。 */ + rawProfile?: components["schemas"]["JsonElement"]; + }; + /** @description 新增或更新租户管理端学生跟进请求 DTO。 */ + UpsertTenantAdminStudentFollowupDto: { + /** + * Format: uuid + * @description ID。 + */ + id?: null | string; + /** + * Format: uuid + * @description 学生用户 ID。 + */ + studentUserId: string; + /** + * Format: uuid + * @description 分配处理人用户 ID。 + */ + assignedToUserId?: null | string; + /** + * Format: uuid + * @description 班级 ID。 + */ + classId?: null | string; + /** @description 标题。 */ + title: string; + /** @description 说明。 */ + description?: null | string; + /** @description 跟进类型。 */ + followupType?: null | string; + /** @description 优先级。 */ + priority?: null | string; + /** @description 状态。 */ + status?: null | string; + /** + * Format: date-time + * @description 到期时间。 + */ + dueAt?: null | string; + /** @description 扩展元数据。 */ + metadata?: components["schemas"]["JsonElement"]; + }; + /** @description 新增或更新租户管理端学生Note请求 DTO。 */ + UpsertTenantAdminStudentNoteDto: { + /** + * Format: uuid + * @description ID。 + */ + id?: null | string; + /** + * Format: uuid + * @description 学生用户 ID。 + */ + studentUserId: string; + /** @description 备注类型。 */ + noteType?: null | string; + /** @description 内容。 */ + content: string; + /** @description 可见性。 */ + visibility?: null | string; + /** @description 是否置顶。 */ + isPinned?: null | boolean; + /** @description 扩展元数据。 */ + metadata?: components["schemas"]["JsonElement"]; + }; + /** @description 更新租户收款策略。 */ + UpsertTenantBillingPolicyDto: { + collectionMode?: components["schemas"]["TenantBillingCollectionMode"]; + defaultPaymentProvider: string; + autoGenerateRenewal?: boolean; + /** Format: int32 */ + renewalLeadDays?: number | string; + reason: string; + }; + /** @description 新增或更新租户品牌请求 DTO。 */ + UpsertTenantBrandingDto: { + /** @description 品牌名称。 */ + brandName: string; + /** @description 品牌简称。 */ + shortName?: null | string; + /** @description 品牌标语。 */ + slogan?: null | string; + /** @description 机构名称。 */ + organizationName?: null | string; + /** @description Logo 地址。 */ + logoUrl?: null | string; + /** @description 站点图标地址。 */ + faviconUrl?: null | string; + /** @description 客服微信。 */ + serviceWechat?: null | string; + /** @description 客服账号名称。 */ + serviceAccountName?: null | string; + }; + /** @description 新增或更新租户优惠券请求 DTO。 */ + UpsertTenantCouponDto: { + /** + * Format: uuid + * @description ID。 + */ + id?: null | string; + /** @description 编码。 */ + code: string; + /** + * Format: uuid + * @description 套餐 ID。 + */ + planId?: null | string; + /** @description 优惠类型。 */ + discountType?: components["schemas"]["DiscountType"]; + /** + * Format: double + * @description 优惠值。 + */ + discountValue?: number | string; + /** + * Format: date-time + * @description 有效期开始时间。 + */ + validFrom?: null | string; + /** + * Format: date-time + * @description 有效期结束时间。 + */ + validTo?: null | string; + /** + * Format: int32 + * @description 最大使用次数。 + */ + maxUses?: null | number | string; + /** @description 来源。 */ + source?: null | string; + /** @description 备注。 */ + remark?: null | string; + }; + /** @description 新增或更新租户功能覆盖规则请求 DTO。 */ + UpsertTenantFeatureOverrideDto: { + /** Format: uuid */ + tenantId: string; + featureCode: string; + mode: components["schemas"]["TenantFeatureOverrideMode"]; + /** Format: date-time */ + expiresAt: null | string; + reason: string; + }; + /** @description 新增或更新租户身份源Provider请求 DTO。 */ + UpsertTenantIdentityProviderDto: { + /** @description 服务提供方。 */ + provider: string; + /** @description 状态。 */ + status?: null | string; + /** @description 显示名称。 */ + displayName?: null | string; + /** @description 密钥引用。 */ + secretRef?: null | string; + /** + * Format: int32 + * @description 优先级。 + */ + priority?: null | number | string; + /** @description 公开配置内容。 */ + configPublic?: components["schemas"]["JsonElement"]; + }; + /** @description 新增或更新租户Secret请求 DTO。 */ + UpsertTenantSecretDto: { + /** @description 用途。 */ + purpose: string; + /** @description 服务提供方。 */ + provider: string; + /** @description 密钥键。 */ + secretKey: string; + /** @description 密钥引用。 */ + secretRef?: string; + /** @description 状态。 */ + status?: components["schemas"]["TenantSecretStatus"]; + /** @description 密钥载荷。 */ + secretPayload?: components["schemas"]["JsonElement"]; + /** + * Format: date-time + * @description 过期时间。 + */ + expiresAt?: null | string; + }; + /** @description 新增或更新租户设置请求 DTO。 */ + UpsertTenantSettingsDto: { + /** @description 前端功能开关。 */ + featureFlags?: components["schemas"]["JsonElement"]; + /** @description 管理端功能开关。 */ + adminFeatureFlags?: components["schemas"]["JsonElement"]; + /** @description 公开配置。 */ + publicConfig?: components["schemas"]["JsonElement"]; + }; + /** @description 新增或更新租户督导规则请求 DTO。 */ + UpsertTenantSupervisionRuleDto: { + /** @description 编码。 */ + code: string; + /** @description 标题。 */ + title: string; + /** @description 是否启用。 */ + enabled?: boolean; + /** + * Format: int32 + * @description 未签到天数。 + */ + daysWithoutCheckIn?: null | number | string; + /** + * Format: int32 + * @description 当天最大答题数。 + */ + maxQuestionsAnsweredToday?: null | number | string; + /** @description 跟进类型。 */ + followupType?: null | string; + /** @description 优先级。 */ + priority?: null | string; + /** @description 扩展元数据。 */ + metadata?: components["schemas"]["JsonElement"]; + }; + UserStatus: number; + VideoExplanationCatalogItem: { + /** Format: uuid */ + id: string; + legacyId: null | string; + /** Format: uuid */ + subjectId: null | string; + title: string; + description: null | string; + videoUrl: null | string; + thumbnailUrl: null | string; + /** Format: int32 */ + durationSeconds: null | number | string; + knowledgeTags: components["schemas"]["JsonElement"]; + isGeneral: boolean; + /** Format: int32 */ + difficulty: null | number | string; + /** Format: int32 */ + order: number | string; + isActive: boolean; + metadata: components["schemas"]["JsonElement"]; + }; + VideoManagementItem: { + /** Format: uuid */ + id: string; + /** Format: uuid */ + subjectId: null | string; + legacyId: null | string; + title: string; + description: null | string; + videoUrl: null | string; + thumbnailUrl: null | string; + /** Format: int32 */ + durationSeconds: null | number | string; + knowledgeTags: components["schemas"]["JsonElement"]; + isGeneral: boolean; + /** Format: int32 */ + difficulty: null | number | string; + /** Format: int32 */ + order: number | string; + isActive: boolean; + metadata: components["schemas"]["JsonElement"]; + }; + VideoPlaybackItem: { + /** Format: uuid */ + videoId: string; + /** Format: uuid */ + questionId: null | string; + title: string; + description: null | string; + playUrl: null | string; + thumbnailUrl: null | string; + /** Format: int32 */ + durationSeconds: null | number | string; + progress: null | components["schemas"]["VideoProgressItem"]; + metadata: components["schemas"]["JsonElement"]; + }; + /** @description 视频Play请求 DTO。 */ + VideoPlayDto: { + /** + * Format: uuid + * @description 视频 ID。 + */ + videoId: string; + /** + * Format: uuid + * @description 题目 ID。 + */ + questionId?: null | string; + }; + /** @description 视频Progress请求 DTO。 */ + VideoProgressDto: { + /** + * Format: uuid + * @description 视频 ID。 + */ + videoId: string; + /** + * Format: uuid + * @description 题目 ID。 + */ + questionId?: null | string; + /** + * Format: int32 + * @description 播放位置,单位为秒。 + */ + positionSeconds?: number | string; + /** + * Format: int32 + * @description 时长,单位为秒。 + */ + durationSeconds?: null | number | string; + /** + * Format: int32 + * @description 已观看时长,单位为秒。 + */ + watchedSeconds?: null | number | string; + /** @description 是否已完成。 */ + isCompleted?: null | boolean; + /** @description 扩展元数据。 */ + metadata?: components["schemas"]["JsonElement"]; + }; + VideoProgressItem: { + /** Format: uuid */ + id: string; + /** Format: uuid */ + videoId: string; + /** Format: uuid */ + questionId: null | string; + /** Format: int32 */ + positionSeconds: number | string; + /** Format: int32 */ + durationSeconds: null | number | string; + /** Format: int32 */ + watchedSeconds: number | string; + isCompleted: boolean; + /** Format: date-time */ + completedAt: null | string; + /** Format: date-time */ + lastPlayedAt: string; + /** Format: int32 */ + playCount: number | string; + metadata: components["schemas"]["JsonElement"]; + }; + VocabularyUnit: { + /** Format: uuid */ + regionId?: null | string; + /** Format: uuid */ + entryId?: null | string; + /** Format: uuid */ + contentNodeId?: null | string; + legacyId?: null | string; + name?: string; + description?: null | string; + /** Format: int32 */ + wordCount?: null | number | string; + /** Format: int32 */ + sortOrder?: number | string; + isActive?: boolean; + sourceHash?: null | string; + metadata?: components["schemas"]["JsonElement"]; + /** Format: date-time */ + createdAt?: string; + /** Format: date-time */ + updatedAt?: string; + /** Format: uuid */ + tenantId?: string; + /** Format: uuid */ + id?: string; + }; + VocabularyUnitCatalogItem: { + /** Format: uuid */ + id: string; + legacyId: null | string; + /** Format: uuid */ + regionId: null | string; + /** Format: uuid */ + entryId: null | string; + /** Format: uuid */ + contentNodeId: null | string; + name: string; + description: null | string; + /** Format: int32 */ + wordCount: null | number | string; + /** Format: int32 */ + order: number | string; + metadata: components["schemas"]["JsonElement"]; + }; + VocabularyWord: { + /** Format: uuid */ + unitId?: null | string; + /** Format: uuid */ + entryId?: null | string; + /** Format: uuid */ + contentNodeId?: null | string; + legacyId?: null | string; + word?: string; + phonetic?: null | string; + meaning?: null | string; + example?: null | string; + exampleTranslation?: null | string; + /** Format: int32 */ + difficulty?: null | number | string; + tags?: components["schemas"]["JsonElement"]; + /** Format: int32 */ + sortOrder?: number | string; + isActive?: boolean; + sourceHash?: null | string; + metadata?: components["schemas"]["JsonElement"]; + /** Format: date-time */ + createdAt?: string; + /** Format: date-time */ + updatedAt?: string; + /** Format: uuid */ + tenantId?: string; + /** Format: uuid */ + id?: string; + }; + VocabularyWordCatalogItem: { + /** Format: uuid */ + id: string; + legacyId: null | string; + /** Format: uuid */ + unitId: null | string; + /** Format: uuid */ + entryId: null | string; + /** Format: uuid */ + contentNodeId: null | string; + word: string; + phonetic: null | string; + meaning: null | string; + example: null | string; + exampleTranslation: null | string; + /** Format: int32 */ + difficulty: null | number | string; + tags: components["schemas"]["JsonElement"]; + /** Format: int32 */ + order: number | string; + metadata: components["schemas"]["JsonElement"]; + }; + WordDueLevel: number; + /** @description 单词Progress请求 DTO。 */ + WordProgressDto: { + /** + * Format: uuid + * @description 单词 ID。 + */ + wordId: string; + /** @description 状态。 */ + status?: null | string; + /** + * Format: int32 + * @description 答对数量变化。 + */ + correctDelta?: null | number | string; + /** + * Format: int32 + * @description 答错数量变化。 + */ + wrongDelta?: null | number | string; + /** + * Format: date-time + * @description 下次复习时间。 + */ + nextReviewAt?: null | string; + }; + WordProgressItem: { + /** Format: uuid */ + wordId: string; + status: components["schemas"]["WordProgressStatus"]; + /** Format: int32 */ + correctCount: number | string; + /** Format: int32 */ + wrongCount: number | string; + /** Format: date-time */ + lastReviewAt: null | string; + /** Format: date-time */ + nextReviewAt: null | string; + /** Format: int32 */ + reviewCount: number | string; + /** Format: int32 */ + correctStreak: number | string; + lastResult: null | components["schemas"]["WordReviewResult"]; + dueLevel: components["schemas"]["WordDueLevel"]; + metadata: components["schemas"]["JsonElement"]; + }; + WordProgressStatus: number; + /** @description 单词Review请求 DTO。 */ + WordReviewDto: { + /** + * Format: uuid + * @description 单词 ID。 + */ + wordId: string; + /** @description 结果。 */ + result?: null | string; + /** + * Format: date-time + * @description 下次复习时间。 + */ + nextReviewAt?: null | string; + }; + WordReviewPlan: { + items: components["schemas"]["WordReviewPlanItem"][]; + nextAction: components["schemas"]["JsonElement"]; + }; + WordReviewPlanItem: { + /** Format: uuid */ + wordId: string; + status: components["schemas"]["WordProgressStatus"]; + /** Format: date-time */ + nextReviewAt: null | string; + /** Format: int32 */ + correctCount: number | string; + /** Format: int32 */ + wrongCount: number | string; + dueLevel: components["schemas"]["WordDueLevel"]; + }; + WordReviewResult: number; + WordStatsItem: { + /** Format: int32 */ + total: number | string; + /** Format: int32 */ + newCount: number | string; + /** Format: int32 */ + learningCount: number | string; + /** Format: int32 */ + reviewingCount: number | string; + /** Format: int32 */ + masteredCount: number | string; + /** Format: int32 */ + dueCount: number | string; + /** Format: int32 */ + favoriteCount: number | string; + }; + WrongQuestionItem: { + /** Format: uuid */ + questionReferenceId: string; + locator: components["schemas"]["QuestionLocator"]; + /** Format: int32 */ + wrongCount: number | string; + /** Format: date-time */ + lastWrongAt: string; + /** Format: date-time */ + resolvedAt: null | string; + }; + WrongQuestionReviewPlan: { + items: components["schemas"]["WrongQuestionReviewPlanItem"][]; + nextAction: components["schemas"]["JsonElement"]; + }; + WrongQuestionReviewPlanItem: { + /** Format: uuid */ + questionReferenceId: string; + locator: components["schemas"]["QuestionLocator"]; + /** Format: int32 */ + wrongCount: number | string; + /** Format: date-time */ + lastWrongAt: string; + }; + }; + responses: never; + parameters: never; + requestBodies: never; + headers: never; + pathItems: never; +} +export type $defs = Record; +export type operations = Record; diff --git a/src/api/studentApi.ts b/src/api/studentApi.ts new file mode 100644 index 0000000..5c32cc6 --- /dev/null +++ b/src/api/studentApi.ts @@ -0,0 +1,105 @@ +import type { components } from "./schema.generated"; +import { apiClient, unwrap } from "./client"; + +type Schema = components["schemas"][Name]; + +const catalogQuery = (filters: Record = {}) => ({ + params: { query: { Limit: 200, ...filters } }, +}); + +export const studentAuthApi = { + passwordLogin: (tenantCode: string, identifier: string, password: string) => + unwrap(apiClient.POST("/api/tenant/auth/browser/login/password", { + body: { realm: 0, tenantCode, identifier, password }, + })), + sendSms: (tenantCode: string, phone: string) => + unwrap(apiClient.POST("/api/tenant/auth/browser/sms/send", { + body: { realm: 0, tenantCode, phone }, + })), + smsLogin: (tenantCode: string, phone: string, code: string) => + unwrap(apiClient.POST("/api/tenant/auth/browser/login/sms", { + body: { realm: 0, tenantCode, phone, code }, + })), + sendPasswordResetSms: (tenantCode: string, phone: string) => + unwrap(apiClient.POST("/api/tenant/auth/browser/password/reset/sms/send", { + body: { tenantCode, phone }, + })), + resetPassword: (tenantCode: string, phone: string, code: string, newPassword: string) => + unwrap(apiClient.POST("/api/tenant/auth/browser/password/reset", { + body: { tenantCode, phone, code, newPassword }, + })), + refresh: () => unwrap(apiClient.POST("/api/tenant/auth/browser/refresh")), +}; + +export const profileApi = { + me: () => unwrap(apiClient.GET("/api/student/profile/me", { + params: { query: { RecentLimit: 8 } }, + })), + updateRegion: (regionId: string) => + unwrap(apiClient.PATCH("/api/student/profile/me", { body: { regionId } })), + countdowns: () => unwrap(apiClient.GET("/api/student/profile/exam-countdowns", { + params: { query: { Limit: 8 } }, + })), +}; + +export const catalogApi = { + regions: () => unwrap(apiClient.GET("/api/public/catalog/regions", catalogQuery())), + subjects: (regionId?: string | null) => unwrap(apiClient.GET( + "/api/public/catalog/subjects", + catalogQuery({ RegionId: regionId ?? undefined }), + )), + categories: (subjectId: string) => unwrap(apiClient.GET( + "/api/public/catalog/categories", + catalogQuery({ SubjectId: subjectId }), + )), + blueprints: (regionId?: string | null, targetId?: string | null) => unwrap(apiClient.GET( + "/api/public/catalog/practice-blueprints", + catalogQuery({ RegionId: regionId ?? undefined, NodeId: targetId ?? undefined }), + )), + banners: (regionId?: string | null) => unwrap(apiClient.GET( + "/api/public/catalog/banners", + catalogQuery({ RegionId: regionId ?? undefined, Limit: 8 }), + )), + announcements: (regionId?: string | null) => unwrap(apiClient.GET( + "/api/public/catalog/announcements", + catalogQuery({ RegionId: regionId ?? undefined, Limit: 8 }), + )), + vocabularyUnits: (regionId?: string | null) => unwrap(apiClient.GET("/api/public/catalog/vocabulary-units", catalogQuery({ RegionId: regionId ?? undefined }))), + vocabularyWords: (unitId: string) => unwrap(apiClient.GET("/api/public/catalog/vocabulary-words", catalogQuery({ UnitId: unitId }))), + handbookSubjects: (regionId?: string | null) => unwrap(apiClient.GET("/api/public/catalog/handbook-subjects", catalogQuery({ RegionId: regionId ?? undefined }))), + handbookChapters: (subjectId: string) => unwrap(apiClient.GET("/api/public/catalog/handbook-chapters", catalogQuery({ SubjectId: subjectId }))), + handbookEntries: (chapterId: string, includeContent = false) => unwrap(apiClient.GET("/api/public/catalog/handbook-entries", catalogQuery({ ChapterId: chapterId, IncludeContent: includeContent }))), + scorelineRecords: (regionId?: string | null, keyword?: string, year?: number) => unwrap(apiClient.GET("/api/public/scoreline/records", { params: { query: { RegionId: regionId ?? undefined, Keyword: keyword || undefined, Year: year, Page: 1, PageSize: 50 } } })), + scorelineYears: (regionId?: string | null) => unwrap(apiClient.GET("/api/public/scoreline/years", { params: { query: { RegionId: regionId ?? undefined, Limit: 50 } } })), +}; + +export const learningApi = { + stats: () => unwrap(apiClient.GET("/api/student/learning/stats")), + trend: () => unwrap(apiClient.GET("/api/student/learning/trend", { + params: { query: { Limit: 28 } }, + })), + createSession: (body: Schema<"CreatePracticeSessionDto">) => + unwrap(apiClient.POST("/api/student/learning/practice-sessions", { body })), + sessionDetail: (practiceSessionId: string) => + unwrap(apiClient.GET("/api/student/learning/practice-sessions/detail", { + params: { query: { PracticeSessionId: practiceSessionId } }, + })), + submitAnswer: (body: Schema<"SubmitAnswerDto">) => + unwrap(apiClient.POST("/api/student/learning/answers", { body })), + submitSession: (body: Schema<"SubmitPracticeSessionDto">) => + unwrap(apiClient.POST("/api/student/learning/practice-sessions/submit", { body })), + report: (practiceSessionId: string) => + unwrap(apiClient.GET("/api/student/learning/practice-sessions/report", { + params: { query: { PracticeSessionId: practiceSessionId } }, + })), + favorites: () => unwrap(apiClient.GET("/api/student/learning/favorites/questions", { + params: { query: { Limit: 200 } }, + })), + toggleFavorite: (questionId: string, source: number, favorite: boolean) => + unwrap(apiClient.POST("/api/student/learning/favorites/questions", { + body: { questionId, source, favorite }, + })), + wrongQuestions: () => unwrap(apiClient.GET("/api/student/learning/wrong-questions", { + params: { query: { Limit: 200 } }, + })), +}; diff --git a/src/api/types.ts b/src/api/types.ts new file mode 100644 index 0000000..a015fdc --- /dev/null +++ b/src/api/types.ts @@ -0,0 +1,23 @@ +import type { components } from "./schema.generated"; + +export type ApiSchema = components["schemas"][Name]; +export type StudentProfile = ApiSchema<"StudentProfileItem">; +export type LearningStats = ApiSchema<"LearningStatsItem">; +export type LearningTrend = ApiSchema<"LearningTrendItem">; +export type Region = ApiSchema<"RegionCatalogItem">; +export type Subject = ApiSchema<"SubjectCatalogItem">; +export type Category = ApiSchema<"CategoryCatalogItem">; +export type PracticeBlueprint = ApiSchema<"PracticeBlueprintCatalogItem">; +export type PracticeSession = ApiSchema<"PracticeSessionItem">; +export type PracticeDetail = ApiSchema<"PracticeSessionDetailItem">; +export type PracticeQuestion = ApiSchema<"PracticeSessionQuestionItem">; +export type AnswerRecord = ApiSchema<"AnswerRecordItem">; +export type PracticeReport = ApiSchema<"PracticeSessionReportItem">; +export type FavoriteQuestion = ApiSchema<"FavoriteQuestionItem">; +export type WrongQuestion = ApiSchema<"WrongQuestionItem">; +export type Banner = ApiSchema<"BannerCatalogItem">; +export type Announcement = ApiSchema<"AnnouncementCatalogItem">; +export type ExamCountdown = ApiSchema<"ExamCountdownItem">; +export type AssetUploadSignResult = ApiSchema<"AssetUploadSignResult">; +export type AssetUploadConfirmResult = ApiSchema<"AssetUploadConfirmResult">; +export type AssetAccessResponse = ApiSchema<"AssetAccessResponseDto">; diff --git a/src/app/RuntimeProvider.tsx b/src/app/RuntimeProvider.tsx index 6f8237d..41b9c8d 100644 --- a/src/app/RuntimeProvider.tsx +++ b/src/app/RuntimeProvider.tsx @@ -1,11 +1,13 @@ import { createContext, useCallback, useContext, useEffect, useMemo, useState, type ReactNode } from 'react'; -import type { TenantRuntimeBootstrap } from '../contracts'; +import type { ResolvedThemeAssets, TenantRuntimeBootstrap } from '../contracts'; import { runtimeApi } from '../api'; +import { useThemeAssets } from '../theme/useThemeAssets'; interface RuntimeContextValue { runtime: TenantRuntimeBootstrap | null; loading: boolean; error: Error | null; + assets: ResolvedThemeAssets; refresh: () => Promise; } @@ -15,6 +17,7 @@ export function RuntimeProvider({ children }: { children: ReactNode }) { const [runtime, setRuntime] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); + const assets = useThemeAssets(runtime?.branding); const refresh = useCallback(async () => { setLoading(true); @@ -23,7 +26,18 @@ export function RuntimeProvider({ children }: { children: ReactNode }) { setRuntime(next); setError(null); document.title = next.branding.brandName; - document.documentElement.style.setProperty('--tenant-primary', next.theme.primaryColor); + const root = document.documentElement.style; + root.setProperty('--tenant-primary', next.theme.primaryColor); + root.setProperty('--tenant-secondary', next.theme.secondaryColor); + root.setProperty('--tenant-background', next.theme.backgroundColor); + root.setProperty('--tenant-foreground', next.theme.textColor); + root.setProperty('--tenant-surface', next.theme.surfaceColor ?? '#ffffff'); + root.setProperty('--tenant-muted', next.theme.mutedColor ?? '#eef2f8'); + root.setProperty('--tenant-border', next.theme.borderColor ?? '#dfe5ef'); + root.setProperty('--tenant-success', next.theme.successColor ?? '#15803d'); + root.setProperty('--tenant-warning', next.theme.warningColor ?? '#b45309'); + root.setProperty('--tenant-danger', next.theme.dangerColor ?? '#dc2626'); + root.setProperty('--tenant-radius', `${next.theme.radius}px`); } catch (reason) { setError(reason instanceof Error ? reason : new Error('站点加载失败')); } finally { @@ -33,7 +47,18 @@ export function RuntimeProvider({ children }: { children: ReactNode }) { useEffect(() => { void refresh(); }, [refresh]); - const value = useMemo(() => ({ runtime, loading, error, refresh }), [runtime, loading, error, refresh]); + useEffect(() => { + if (!assets.favicon) return; + let link = document.querySelector('link[rel="icon"]'); + if (!link) { + link = document.createElement('link'); + link.rel = 'icon'; + document.head.append(link); + } + link.href = assets.favicon; + }, [assets.favicon]); + + const value = useMemo(() => ({ runtime, loading, error, assets, refresh }), [runtime, loading, error, assets, refresh]); return {children}; } diff --git a/src/contracts/site.ts b/src/contracts/site.ts index 40257f5..df41523 100644 --- a/src/contracts/site.ts +++ b/src/contracts/site.ts @@ -7,6 +7,36 @@ export interface BrandingConfig { logoUrl: string; faviconUrl: string; serviceWechat: string; + logoAssetId?: string; + faviconAssetId?: string; + loginBackgroundAssetId?: string; + heroAssetId?: string; + serviceQrAssetId?: string; + featureCardAssetIds?: Record; + imageAlt?: string; + assetAlt?: Partial>; +} + +export type ThemeAssetRole = + | 'logo' + | 'favicon' + | 'loginBackground' + | 'hero' + | 'featureCard' + | 'serviceQr'; + +export interface ThemeAssetReference { + assetId: string; + role: ThemeAssetRole; + alt?: string; +} + +export interface ResolvedThemeAssets { + logo?: string; + favicon?: string; + loginBackground?: string; + hero?: string; + serviceQr?: string; } export interface ThemeConfig { @@ -16,6 +46,12 @@ export interface ThemeConfig { textColor: string; fontFamily: string; radius: number; + surfaceColor?: string; + mutedColor?: string; + borderColor?: string; + successColor?: string; + warningColor?: string; + dangerColor?: string; } export interface FeatureConfig { diff --git a/src/index.css b/src/index.css index c9eddf8..b883fe6 100644 --- a/src/index.css +++ b/src/index.css @@ -6,15 +6,292 @@ background: #f5f7fb; font-synthesis: none; text-rendering: optimizeLegibility; + --tenant-primary: #3157d5; + --tenant-secondary: #20b486; + --tenant-background: #f4f6fa; + --tenant-foreground: #14213d; + --tenant-surface: #ffffff; + --tenant-muted: #eef2f8; + --tenant-border: #dfe5ef; + --tenant-success: #15803d; + --tenant-warning: #b45309; + --tenant-danger: #dc2626; + --tenant-radius: 18px; } * { box-sizing: border-box; } html, body, #root { min-height: 100%; margin: 0; } body { min-width: 320px; } button, input, textarea, select { font: inherit; } +a { color: inherit; text-decoration: none; } +button, a { -webkit-tap-highlight-color: transparent; } +button:not(:disabled), a { cursor: pointer; } +button:focus-visible, a:focus-visible, input:focus-visible, textarea:focus-visible, select:focus-visible { outline: 3px solid color-mix(in srgb, var(--tenant-primary) 35%, transparent); outline-offset: 2px; } +.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0; } +.skip-link { position: fixed; left: 16px; top: -80px; z-index: 1000; padding: 12px 18px; border-radius: 12px; background: #111827; color: #fff; transition: top .2s ease; } +.skip-link:focus { top: 16px; } +.eyebrow { margin: 0 0 10px; color: var(--tenant-primary); font-size: 11px; font-weight: 800; letter-spacing: .16em; } +.primary-button, .quiet-button { min-height: 44px; display: inline-flex; align-items: center; justify-content: center; gap: 9px; border: 0; border-radius: 13px; padding: 0 18px; font-weight: 750; transition: transform .18s ease, box-shadow .18s ease, background .18s ease; } +.primary-button { background: var(--tenant-primary); color: #fff; box-shadow: 0 10px 25px color-mix(in srgb, var(--tenant-primary) 22%, transparent); } +.primary-button:hover { transform: translateY(-1px); box-shadow: 0 14px 30px color-mix(in srgb, var(--tenant-primary) 28%, transparent); } +.primary-button:disabled { cursor: not-allowed; opacity: .52; transform: none; box-shadow: none; } +.primary-button svg, .quiet-button svg { width: 18px; height: 18px; } +.primary-button--wide { width: 100%; } +.quiet-button { border: 1px solid var(--tenant-border); background: var(--tenant-surface); color: var(--tenant-foreground); } +.icon-button { min-width: 44px; min-height: 44px; display: inline-grid; place-items: center; border: 0; border-radius: 13px; background: transparent; color: #64748b; } +.icon-button:hover { background: var(--tenant-muted); color: var(--tenant-foreground); } +.icon-button svg { width: 19px; height: 19px; } +.back-link { min-height: 44px; display: inline-flex; align-items: center; gap: 8px; color: #64748b; font-size: 14px; font-weight: 650; } +.back-link svg { width: 17px; } +.form-message { margin: 0; padding: 11px 13px; border-radius: 11px; background: color-mix(in srgb, var(--tenant-danger) 8%, white); color: var(--tenant-danger); font-size: 13px; line-height: 1.5; } +.development-notice { max-width: 680px; margin: -12px 0 24px; padding: 12px 15px; border: 1px solid #f4d38b; border-radius: 12px; background: #fff9e9; color: #805600; font-size: 13px; line-height: 1.6; } +.spin { animation: spin .8s linear infinite; } +@keyframes spin { to { transform: rotate(360deg); } } -.tenant-admin-shell .ant-layout { min-height: 100vh; } -.tenant-admin-shell .ant-layout-sider { box-shadow: 12px 0 40px rgba(17, 28, 62, 0.06); } +/* Public site and authentication */ +.public-landing { min-height: 100dvh; color: var(--tenant-foreground); background: radial-gradient(circle at 80% 12%, color-mix(in srgb, var(--tenant-primary) 12%, transparent), transparent 34%), var(--tenant-background); } +.public-header { height: 80px; max-width: 1240px; margin: auto; padding: 0 28px; display: flex; align-items: center; justify-content: space-between; } +.public-logo { display: flex; align-items: center; gap: 12px; font-size: 18px; } +.public-logo span, .public-logo img { width: 40px; height: 40px; display: grid; place-items: center; object-fit: cover; border-radius: 13px; background: var(--tenant-primary); color: #fff; font-weight: 900; } +.public-landing main { max-width: 1240px; margin: auto; padding: 50px 28px 90px; } +.public-hero { min-height: 540px; display: grid; grid-template-columns: 1.08fr .92fr; gap: 72px; align-items: center; } +.public-hero h1 { max-width: 720px; margin: 0; font-size: clamp(46px, 6vw, 78px); line-height: 1.04; letter-spacing: -.055em; } +.public-hero__lead { max-width: 640px; margin: 28px 0; color: #667085; font-size: 18px; line-height: 1.8; } +.public-hero__actions { display: flex; align-items: center; gap: 22px; } +.public-hero__actions > span { display: inline-flex; align-items: center; gap: 7px; color: #667085; font-size: 13px; } +.public-hero__actions svg { width: 18px; } +.public-hero__visual { position: relative; aspect-ratio: 1; display: grid; place-items: center; overflow: hidden; border-radius: 40px; background: linear-gradient(145deg, var(--tenant-primary), color-mix(in srgb, var(--tenant-primary) 60%, #6d5dfc)); box-shadow: 0 40px 80px color-mix(in srgb, var(--tenant-primary) 25%, transparent); } +.public-hero__visual > svg { width: 30%; height: 30%; color: white; stroke-width: 1.1; } +.public-hero__visual > img { width: 100%; height: 100%; object-fit: cover; } +.public-hero__visual i { position: absolute; border: 1px solid rgba(255,255,255,.22); border-radius: 30px; transform: rotate(20deg); } +.public-hero__visual i:nth-child(2) { width: 75%; height: 28%; top: 12%; right: -12%; }.public-hero__visual i:nth-child(3) { width: 50%; height: 18%; bottom: 17%; left: -8%; }.public-hero__visual i:nth-child(4) { width: 32%; height: 32%; top: 30%; left: 9%; } +.public-feature-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; } +.public-feature-grid article { padding: 28px; border: 1px solid var(--tenant-border); border-radius: var(--tenant-radius); background: color-mix(in srgb, var(--tenant-surface) 92%, transparent); } +.public-feature-grid svg { width: 28px; color: var(--tenant-primary); }.public-feature-grid h2 { margin: 22px 0 8px; font-size: 18px; }.public-feature-grid p { margin: 0; color: #667085; line-height: 1.7; } +.auth-page { min-height: 100dvh; display: grid; grid-template-columns: 1fr 1fr; background: var(--tenant-background); } +.auth-story { padding: 56px clamp(36px, 7vw, 110px); display: flex; flex-direction: column; justify-content: space-between; color: #fff; background: radial-gradient(circle at 80% 15%, rgba(255,255,255,.17), transparent 28%), linear-gradient(145deg, color-mix(in srgb, var(--tenant-primary) 76%, #152a56), var(--tenant-primary)); } +.auth-story .eyebrow { color: rgba(255,255,255,.67); }.auth-story h1 { max-width: 600px; margin: 0; font-size: clamp(48px, 5vw, 76px); line-height: 1.04; letter-spacing: -.05em; }.auth-story p { max-width: 540px; color: rgba(255,255,255,.72); font-size: 17px; line-height: 1.8; }.auth-story > span, .auth-back { display: flex; align-items: center; gap: 8px; color: rgba(255,255,255,.68); font-size: 13px; }.auth-story svg { width: 18px; } +.auth-panel, .simple-auth-page { display: grid; place-items: center; padding: 32px; } +.simple-auth-page { min-height: 100dvh; background: var(--tenant-background); } +.auth-card { width: min(100%, 440px); display: flex; flex-direction: column; gap: 20px; padding: 38px; border: 1px solid var(--tenant-border); border-radius: 24px; background: var(--tenant-surface); box-shadow: 0 24px 70px rgba(15,23,42,.08); } +.auth-card h1, .auth-card h2 { margin: 0 0 8px; font-size: 30px; letter-spacing: -.03em; }.auth-card > div > p:last-child, .auth-card > p { margin: 0; color: #667085; line-height: 1.6; } +.auth-card label, .subjective-answer { display: flex; flex-direction: column; gap: 8px; color: #344054; font-size: 13px; font-weight: 700; } +.auth-card input, .auth-card textarea, .auth-card select, .subjective-answer textarea { min-height: 48px; width: 100%; border: 1px solid var(--tenant-border); border-radius: 12px; padding: 0 14px; background: #fff; color: var(--tenant-foreground); } +.auth-card input:focus, .subjective-answer textarea:focus { border-color: var(--tenant-primary); } +.input-with-action { display: grid; grid-template-columns: 1fr auto; gap: 8px; }.input-with-action button { min-width: 110px; border: 1px solid var(--tenant-border); border-radius: 12px; background: var(--tenant-muted); color: var(--tenant-primary); font-weight: 700; }.input-with-action button:disabled { opacity: .5; cursor: not-allowed; } +.segmented-control { display: grid; grid-template-columns: 1fr 1fr; padding: 4px; border-radius: 13px; background: var(--tenant-muted); }.segmented-control button { min-height: 42px; display: flex; align-items: center; justify-content: center; gap: 7px; border: 0; border-radius: 10px; background: transparent; color: #667085; font-size: 13px; font-weight: 700; }.segmented-control button[aria-selected="true"] { background: #fff; color: var(--tenant-primary); box-shadow: 0 5px 15px rgba(15,23,42,.08); }.segmented-control svg { width: 17px; } +.auth-help { text-align: center; color: var(--tenant-primary); font-size: 13px; font-weight: 650; }.success-icon { width: 54px; height: 54px; color: var(--tenant-success); } + +/* Student app shell */ +.student-app { min-height: 100dvh; display: grid; grid-template-columns: 252px minmax(0, 1fr); color: var(--tenant-foreground); background: var(--tenant-background); } +.student-sidebar { position: fixed; inset: 0 auto 0 0; z-index: 50; width: 252px; display: flex; flex-direction: column; border-right: 1px solid var(--tenant-border); background: color-mix(in srgb, var(--tenant-surface) 95%, transparent); backdrop-filter: blur(18px); transition: width .2s ease; } +.student-app--collapsed { grid-template-columns: 82px minmax(0,1fr); }.student-app--collapsed .student-sidebar { width: 82px; }.student-app--collapsed .student-nav-link { justify-content: center; padding-inline: 0; }.student-app--collapsed .student-nav-link span { display: none; } +.student-brand { min-height: 82px; display: flex; align-items: center; gap: 11px; padding: 16px; }.student-brand img, .student-brand__mark { flex: 0 0 43px; width: 43px; height: 43px; object-fit: cover; display: grid; place-items: center; border-radius: 14px; background: var(--tenant-primary); color: #fff; font-weight: 900; }.student-brand div { min-width: 0; flex: 1; }.student-brand strong, .student-brand small { display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }.student-brand small { margin-top: 2px; color: #98a2b3; font-size: 10px; }.student-sidebar__toggle { margin-left: auto; flex-shrink: 0; } +.student-sidebar nav { flex: 1; display: flex; flex-direction: column; gap: 6px; padding: 20px 14px; }.student-nav-link { min-height: 48px; display: flex; align-items: center; gap: 12px; border-radius: 13px; padding: 0 15px; color: #667085; font-size: 14px; font-weight: 650; transition: background .18s, color .18s; }.student-nav-link:hover { background: var(--tenant-muted); color: var(--tenant-foreground); }.student-nav-link.is-active { background: color-mix(in srgb, var(--tenant-primary) 10%, white); color: var(--tenant-primary); }.student-nav-link svg { width: 20px; flex: 0 0 auto; } +.student-sidebar__account { min-height: 84px; display: flex; align-items: center; gap: 9px; margin: 12px; padding: 12px; border-radius: 15px; background: var(--tenant-muted); }.student-sidebar__account div { min-width: 0; flex: 1; }.student-sidebar__account strong, .student-sidebar__account small { display: block; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }.student-sidebar__account strong { font-size: 13px; }.student-sidebar__account small { color: #98a2b3; font-size: 10px; } +.student-workspace { grid-column: 2; min-width: 0; }.student-topbar { height: 72px; display: flex; align-items: center; justify-content: space-between; padding: 0 clamp(20px, 4vw, 52px); border-bottom: 1px solid var(--tenant-border); background: color-mix(in srgb, var(--tenant-background) 88%, transparent); backdrop-filter: blur(16px); }.student-topbar__location, .student-topbar__actions { display: flex; align-items: center; gap: 10px; }.student-topbar__location { color: #667085; font-size: 13px; font-weight: 650; }.student-topbar__location svg { width: 17px; color: var(--tenant-primary); }.student-main { max-width: 1450px; margin: 0 auto; padding: 36px clamp(20px, 4vw, 52px) 90px; }.student-mobile-dock { display: none; } +.page-heading, .dashboard-heading { display: flex; align-items: flex-end; justify-content: space-between; gap: 24px; margin-bottom: 30px; }.page-heading h1, .dashboard-heading h1 { margin: 0; font-size: clamp(30px, 3vw, 44px); letter-spacing: -.045em; }.page-heading p:last-child, .dashboard-heading p:last-child { margin: 10px 0 0; color: #667085; line-height: 1.6; } + +/* Dashboard */ +.dashboard-page { display: flex; flex-direction: column; gap: 22px; }.dashboard-hero { min-height: 290px; display: grid; grid-template-columns: 1fr 240px; align-items: center; gap: 30px; overflow: hidden; padding: clamp(30px, 5vw, 58px); border-radius: calc(var(--tenant-radius) + 8px); color: #fff; background: radial-gradient(circle at 80% 20%, rgba(255,255,255,.19), transparent 25%), linear-gradient(135deg, color-mix(in srgb, var(--tenant-primary) 80%, #172554), var(--tenant-primary)); box-shadow: 0 24px 60px color-mix(in srgb, var(--tenant-primary) 20%, transparent); }.dashboard-hero__badge { display: inline-flex; align-items: center; gap: 7px; padding: 7px 11px; border-radius: 999px; background: rgba(255,255,255,.14); font-size: 12px; font-weight: 750; }.dashboard-hero__badge svg { width: 16px; }.dashboard-hero h2 { max-width: 780px; margin: 24px 0 12px; font-size: clamp(28px, 3.4vw, 48px); line-height: 1.14; letter-spacing: -.045em; }.dashboard-hero p { max-width: 680px; color: rgba(255,255,255,.72); line-height: 1.7; }.dashboard-hero a { margin-top: 16px; display: inline-flex; align-items: center; gap: 8px; font-weight: 800; }.dashboard-hero a svg { width: 18px; }.dashboard-hero__target { aspect-ratio: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; border: 1px solid rgba(255,255,255,.15); border-radius: 38%; background: rgba(255,255,255,.09); }.dashboard-hero__target svg { width: 30px; }.dashboard-hero__target strong { margin: 9px 0 2px; font-size: 62px; line-height: 1; }.dashboard-hero__target span { color: rgba(255,255,255,.65); font-size: 12px; text-align: center; } +.metric-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; }.metric-card { display: flex; align-items: center; gap: 15px; min-height: 102px; padding: 20px; border: 1px solid var(--tenant-border); border-radius: var(--tenant-radius); background: var(--tenant-surface); }.metric-card__icon { width: 48px; height: 48px; display: grid; place-items: center; border-radius: 15px; }.metric-card__icon svg { width: 22px; }.metric-card__icon.blue { background: #eaf0ff; color: #3157d5; }.metric-card__icon.green { background: #e7f8ef; color: #15803d; }.metric-card__icon.orange { background: #fff1e7; color: #c2410c; }.metric-card__icon.purple { background: #f2eaff; color: #7c3aed; }.metric-card small, .metric-card strong { display: block; }.metric-card small { color: #98a2b3; font-size: 11px; }.metric-card strong { margin-top: 4px; font-size: 24px; letter-spacing: -.03em; } +.dashboard-columns { display: grid; grid-template-columns: 1.1fr .9fr; gap: 18px; }.content-card { border: 1px solid var(--tenant-border); border-radius: var(--tenant-radius); padding: 24px; background: var(--tenant-surface); }.section-heading { display: flex; align-items: center; justify-content: space-between; gap: 20px; margin-bottom: 20px; }.section-heading h2 { margin: 0; font-size: 20px; letter-spacing: -.02em; }.section-heading > svg { color: #98a2b3; }.mini-chart { height: 180px; display: flex; align-items: end; gap: 5px; padding-top: 25px; border-bottom: 1px solid var(--tenant-border); }.mini-chart span { min-width: 4px; flex: 1; border-radius: 5px 5px 0 0; background: color-mix(in srgb, var(--tenant-primary) 72%, white); transition: height .25s ease; }.recent-list { display: flex; flex-direction: column; gap: 12px; }.recent-list a { display: grid; grid-template-columns: minmax(130px,1fr) minmax(80px, 1fr) auto; align-items: center; gap: 12px; padding: 12px; border-radius: 13px; background: var(--tenant-muted); }.recent-list strong, .recent-list small { display: block; }.recent-list strong { font-size: 13px; }.recent-list small { margin-top: 3px; color: #98a2b3; font-size: 10px; }.recent-list i { height: 5px; overflow: hidden; border-radius: 999px; background: #dbe2ed; }.recent-list b { display: block; height: 100%; border-radius: inherit; background: var(--tenant-primary); }.recent-list em { color: #667085; font-size: 11px; font-style: normal; }.announcements > div:last-child { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; }.announcements article { display: flex; align-items: center; gap: 10px; padding: 12px; border-radius: 12px; background: var(--tenant-muted); }.announcements article i { width: 7px; height: 7px; border-radius: 50%; background: var(--tenant-primary); }.announcements article p { margin: 0; font-size: 13px; }.empty-inline { min-height: 100px; display: grid; place-items: center; color: #98a2b3; font-size: 13px; } + +/* Catalog and collections */ +.search-field { min-width: 280px; min-height: 46px; display: flex; align-items: center; gap: 9px; padding: 0 14px; border: 1px solid var(--tenant-border); border-radius: 13px; background: var(--tenant-surface); }.search-field svg { width: 18px; color: #98a2b3; }.search-field input { width: 100%; border: 0; outline: 0; background: transparent; }.subject-toolbar { display: flex; justify-content: space-between; align-items: center; margin-bottom: 18px; color: #667085; font-size: 13px; }.subject-toolbar span, .subject-toolbar a { display: flex; align-items: center; gap: 7px; }.subject-toolbar svg { width: 17px; }.subject-toolbar a { color: var(--tenant-primary); font-weight: 700; } +.subject-grid { display: grid; grid-template-columns: repeat(3, minmax(0,1fr)); gap: 17px; }.subject-card { position: relative; min-height: 260px; display: flex; flex-direction: column; padding: 25px; overflow: hidden; border: 1px solid var(--tenant-border); border-radius: calc(var(--tenant-radius) + 2px); background: var(--tenant-surface); transition: transform .2s ease, box-shadow .2s ease, border-color .2s ease; }.subject-card:hover { transform: translateY(-3px); border-color: color-mix(in srgb, var(--tenant-primary) 35%, var(--tenant-border)); box-shadow: 0 18px 40px rgba(15,23,42,.08); }.subject-card > span { width: 48px; height: 48px; display: grid; place-items: center; border-radius: 15px; color: var(--tenant-primary); background: color-mix(in srgb, var(--tenant-primary) 10%, white); }.subject-card > span svg { width: 23px; }.subject-card small { margin-top: 26px; color: var(--tenant-primary); font-weight: 750; }.subject-card h2 { margin: 7px 0; font-size: 22px; }.subject-card p { margin: 0; color: #667085; line-height: 1.65; font-size: 13px; }.subject-card em { margin-top: auto; display: flex; align-items: center; gap: 7px; color: var(--tenant-primary); font-size: 13px; font-style: normal; font-weight: 750; }.subject-card em svg { width: 16px; } +.subject-detail-hero { min-height: 260px; display: flex; align-items: center; justify-content: space-between; gap: 32px; margin-top: 12px; padding: 36px; border-radius: calc(var(--tenant-radius) + 4px); background: linear-gradient(135deg, color-mix(in srgb, var(--tenant-primary) 9%, white), white); border: 1px solid color-mix(in srgb, var(--tenant-primary) 15%, var(--tenant-border)); }.subject-detail-hero h1 { margin: 0; font-size: clamp(34px,4vw,54px); letter-spacing: -.05em; }.subject-detail-hero p:last-child { max-width: 650px; color: #667085; line-height: 1.7; } +.practice-mode-grid { display: grid; grid-template-columns: repeat(3,1fr); gap: 14px; margin: 20px 0 34px; }.practice-mode-grid > a { min-height: 120px; display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 14px; padding: 20px; border: 1px solid var(--tenant-border); border-radius: var(--tenant-radius); background: var(--tenant-surface); }.practice-mode-grid > a > svg:first-child { width: 24px; color: var(--tenant-primary); }.practice-mode-grid > a > svg:last-child { width: 17px; color: #98a2b3; }.practice-mode-grid strong { display: block; }.practice-mode-grid p { margin: 6px 0 0; color: #98a2b3; font-size: 12px; line-height: 1.55; } +.category-section { margin-top: 20px; }.chapter-list { display: flex; flex-direction: column; gap: 10px; }.chapter-list article { min-height: 88px; display: grid; grid-template-columns: 45px 1fr auto; align-items: center; gap: 16px; padding: 17px 20px; border: 1px solid var(--tenant-border); border-radius: 15px; background: var(--tenant-surface); }.chapter-list article > span { color: var(--tenant-primary); font-size: 12px; font-weight: 800; }.chapter-list h3, .chapter-list p { margin: 0; }.chapter-list h3 { font-size: 15px; }.chapter-list p { margin-top: 5px; color: #98a2b3; font-size: 12px; }.chapter-list a { min-height: 40px; display: flex; align-items: center; gap: 7px; color: var(--tenant-primary); font-size: 13px; font-weight: 750; }.chapter-list a svg { width: 16px; } +.selection-page { min-height: 100dvh; max-width: 980px; margin: auto; padding: 70px 24px; }.selection-page > header { max-width: 650px; }.selection-page h1 { margin: 0; font-size: clamp(36px,5vw,56px); letter-spacing: -.05em; }.selection-page header p:last-child { color: #667085; line-height: 1.7; }.selection-page > .search-field { max-width: 480px; margin: 30px 0; }.selection-page section { margin-top: 30px; }.selection-page section h2 { display: flex; align-items: center; gap: 8px; font-size: 17px; }.selection-page section h2 svg { width: 19px; color: var(--tenant-primary); }.region-grid { display: grid; grid-template-columns: repeat(4,1fr); gap: 11px; }.region-grid button { min-height: 68px; display: flex; align-items: center; justify-content: space-between; padding: 0 17px; border: 1px solid var(--tenant-border); border-radius: 14px; background: var(--tenant-surface); color: var(--tenant-foreground); }.region-grid button:hover { border-color: var(--tenant-primary); color: var(--tenant-primary); }.region-grid svg { width: 17px; } +.collection-tabs { max-width: 390px; margin-bottom: 24px; }.collection-list { display: grid; grid-template-columns: repeat(2,1fr); gap: 12px; }.collection-list article { min-height: 90px; display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 13px; padding: 17px; border: 1px solid var(--tenant-border); border-radius: 15px; background: var(--tenant-surface); }.collection-list article > span { width: 42px; height: 42px; display: grid; place-items: center; border-radius: 13px; color: var(--tenant-primary); background: color-mix(in srgb, var(--tenant-primary) 9%, white); }.collection-list article > svg { width: 17px; color: #98a2b3; }.collection-list p { margin: 4px 0 0; color: #98a2b3; font-size: 12px; } + +/* Quiz and report */ +.quiz-start-page { min-height: 100dvh; padding: 30px clamp(20px,5vw,70px); background: var(--tenant-background); }.quiz-start-page section { width: min(100%, 620px); margin: 9vh auto; padding: 45px; border: 1px solid var(--tenant-border); border-radius: 24px; background: var(--tenant-surface); box-shadow: 0 24px 60px rgba(15,23,42,.08); }.quiz-start-page h1 { margin: 0; font-size: 38px; letter-spacing: -.04em; }.quiz-start-page section > p:not(.eyebrow) { color: #667085; line-height: 1.7; }.quiz-start-page label { display: flex; flex-direction: column; gap: 8px; margin: 24px 0; color: #344054; font-size: 13px; font-weight: 700; }.quiz-start-page select { min-height: 46px; border: 1px solid var(--tenant-border); border-radius: 12px; padding: 0 13px; background: #fff; }.quiz-loading { min-height: 60vh; display: grid; place-items: center; align-content: center; gap: 14px; color: #667085; }.quiz-loading svg { width: 32px; color: var(--tenant-primary); } +.quiz-page { min-height: 100dvh; display: flex; flex-direction: column; background: var(--tenant-background); }.quiz-header { min-height: 70px; display: grid; grid-template-columns: 48px minmax(0, 600px) auto; align-items: center; justify-content: center; gap: 24px; padding: 10px 28px; border-bottom: 1px solid var(--tenant-border); background: var(--tenant-surface); }.quiz-header > a { width: 44px; height: 44px; display: grid; place-items: center; border-radius: 13px; }.quiz-header > div { display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 12px; }.quiz-header strong { font-size: 13px; }.quiz-header div > span { height: 5px; overflow: hidden; border-radius: 999px; background: var(--tenant-muted); }.quiz-header div > span i { display: block; height: 100%; background: var(--tenant-primary); }.quiz-header small { color: #98a2b3; }.quiz-header > span { display: flex; align-items: center; gap: 7px; color: #667085; font-size: 12px; }.quiz-header svg { width: 18px; } +.quiz-workspace { width: min(100%, 1280px); margin: 0 auto; padding: 30px; display: grid; grid-template-columns: minmax(0, 1fr) 270px; align-items: start; gap: 20px; }.question-card, .question-navigator { border: 1px solid var(--tenant-border); border-radius: 20px; background: var(--tenant-surface); }.question-card { min-height: 620px; padding: clamp(24px,4vw,45px); }.question-meta { display: flex; align-items: center; gap: 10px; margin-bottom: 26px; }.question-meta span, .question-meta em { padding: 6px 10px; border-radius: 999px; background: var(--tenant-muted); color: #667085; font-size: 11px; font-style: normal; font-weight: 750; }.question-meta em { color: var(--tenant-primary); background: color-mix(in srgb, var(--tenant-primary) 9%, white); }.question-meta button { margin-left: auto; width: 44px; height: 44px; display: grid; place-items: center; border: 0; border-radius: 12px; background: transparent; color: #98a2b3; }.question-meta svg { width: 18px; }.safe-markdown { line-height: 1.75; }.safe-markdown > :first-child { margin-top: 0; }.safe-markdown > :last-child { margin-bottom: 0; }.safe-markdown table { width: 100%; border-collapse: collapse; }.safe-markdown th, .safe-markdown td { border: 1px solid var(--tenant-border); padding: 8px 10px; text-align: left; }.safe-markdown a { color: var(--tenant-primary); text-decoration: underline; }.question-content { margin-bottom: 30px; font-size: 18px; }.answer-options { display: flex; flex-direction: column; gap: 11px; }.answer-options > button { min-height: 58px; display: grid; grid-template-columns: 34px 1fr 20px; align-items: center; gap: 12px; padding: 10px 14px; border: 1px solid var(--tenant-border); border-radius: 14px; background: #fff; color: var(--tenant-foreground); text-align: left; transition: border .18s, background .18s; }.answer-options > button:hover:not(:disabled), .answer-options > button.is-selected { border-color: var(--tenant-primary); background: color-mix(in srgb, var(--tenant-primary) 5%, white); }.answer-options > button > span { width: 32px; height: 32px; display: grid; place-items: center; border-radius: 10px; background: var(--tenant-muted); font-size: 12px; font-weight: 800; }.answer-options > button.is-selected > span { background: var(--tenant-primary); color: #fff; }.answer-options > button > svg { width: 18px; color: var(--tenant-primary); }.subjective-answer textarea { padding: 13px; resize: vertical; line-height: 1.6; }.question-answer > .primary-button { margin-top: 22px; }.answer-status { display: flex; align-items: center; gap: 8px; margin-top: 20px; color: var(--tenant-success); font-size: 13px; font-weight: 700; }.answer-status.is-pending { color: var(--tenant-warning); }.answer-status svg { width: 18px; } +.question-navigator { position: sticky; top: 20px; padding: 20px; }.question-navigator h2 { margin: 0 0 16px; font-size: 16px; }.question-navigator > div { display: grid; grid-template-columns: repeat(5,1fr); gap: 7px; }.question-navigator > div button { aspect-ratio: 1; border: 1px solid var(--tenant-border); border-radius: 9px; background: #fff; color: #667085; font-size: 11px; }.question-navigator > div button.is-answered { border-color: color-mix(in srgb, var(--tenant-success) 30%, white); background: color-mix(in srgb, var(--tenant-success) 8%, white); color: var(--tenant-success); }.question-navigator > div button.is-current { border-color: var(--tenant-primary); background: var(--tenant-primary); color: #fff; }.submit-paper-button { width: 100%; min-height: 46px; margin-top: 18px; display: flex; align-items: center; justify-content: center; gap: 8px; border: 0; border-radius: 12px; background: #111827; color: #fff; font-weight: 750; }.submit-paper-button svg { width: 17px; }.quiz-footer { margin-top: auto; min-height: 72px; display: flex; justify-content: center; gap: 12px; padding: 12px; border-top: 1px solid var(--tenant-border); background: var(--tenant-surface); }.quiz-footer button { min-width: 140px; min-height: 44px; display: flex; align-items: center; justify-content: center; gap: 7px; border: 1px solid var(--tenant-border); border-radius: 12px; background: #fff; color: var(--tenant-foreground); font-weight: 700; }.quiz-footer button:disabled { opacity: .4; cursor: not-allowed; }.quiz-footer svg { width: 17px; } +.report-page { max-width: 900px; margin: auto; }.report-page > header { text-align: center; }.report-page > header h1 { margin: 0; font-size: clamp(34px,5vw,52px); letter-spacing: -.05em; }.report-page > header p:last-child { color: #667085; }.report-score { margin: 35px auto 24px; text-align: center; }.report-score > div strong { font-size: 78px; letter-spacing: -.06em; }.report-score > div span { color: #98a2b3; }.report-score > i { width: min(100%, 440px); height: 10px; display: block; margin: 15px auto 0; border-radius: 999px; background: linear-gradient(to right, var(--tenant-primary) var(--score), var(--tenant-muted) var(--score)); }.report-score p { color: var(--tenant-primary); font-weight: 750; }.report-metrics { display: grid; grid-template-columns: repeat(4,1fr); gap: 12px; }.report-metrics article { display: flex; align-items: center; gap: 12px; min-height: 95px; padding: 17px; border: 1px solid var(--tenant-border); border-radius: 15px; background: var(--tenant-surface); }.report-metrics article > svg { color: var(--tenant-primary); }.report-metrics small, .report-metrics strong { display: block; }.report-metrics small { color: #98a2b3; }.report-metrics strong { margin-top: 4px; }.pending-review-note { display: flex; gap: 14px; margin-top: 16px; padding: 20px; border: 1px solid #fed7aa; border-radius: 15px; background: #fff7ed; color: #9a3412; }.pending-review-note p { margin: 5px 0 0; color: #c2410c; font-size: 13px; }.report-actions { display: flex; justify-content: center; gap: 12px; margin-top: 28px; } + +.empty-panel, .error-panel { min-height: 220px; display: grid; place-items: center; align-content: center; gap: 12px; padding: 30px; border: 1px dashed var(--tenant-border); border-radius: var(--tenant-radius); color: #667085; text-align: center; background: color-mix(in srgb, var(--tenant-surface) 75%, transparent); }.error-panel button { min-height: 42px; border: 1px solid var(--tenant-border); border-radius: 11px; padding: 0 16px; background: #fff; color: var(--tenant-primary); font-weight: 700; }.skeleton-grid { display: grid; grid-template-columns: repeat(4,1fr); gap: 14px; }.skeleton-grid i, .chart-skeleton { min-height: 120px; display: block; border-radius: var(--tenant-radius); background: linear-gradient(100deg, var(--tenant-muted) 20%, #fff 38%, var(--tenant-muted) 56%); background-size: 200% 100%; animation: shimmer 1.3s infinite; }.subject-grid.skeleton-grid i { min-height: 260px; }.chart-skeleton { min-height: 180px; }.site-state-page { min-height: 100dvh; display: grid; place-items: center; padding: 24px; background: #0f172a; color: #fff; }.site-state-page > div { width: min(100%, 560px); padding: 45px; border: 1px solid rgba(255,255,255,.1); border-radius: 28px; background: rgba(255,255,255,.06); text-align: center; }.site-state-page > div > span { width: 64px; height: 64px; display: grid; place-items: center; margin: auto; border-radius: 20px; }.site-state-page h1 { font-size: 36px; }.site-state-page p, .site-state-page article, .site-state-page small { color: rgba(255,255,255,.62); }.site-state-page small { display: flex; justify-content: center; align-items: center; gap: 7px; margin-top: 30px; } +@keyframes shimmer { to { background-position-x: -200%; } } + +@media (max-width: 1050px) { + .public-hero { grid-template-columns: 1fr; gap: 30px; }.public-hero__visual { width: min(100%, 540px); justify-self: center; }.public-feature-grid, .subject-grid { grid-template-columns: repeat(2,1fr); }.metric-grid, .report-metrics { grid-template-columns: repeat(2,1fr); }.dashboard-columns { grid-template-columns: 1fr; }.practice-mode-grid { grid-template-columns: 1fr; } +} +@media (max-width: 760px) { + body { font-size: 16px; }.public-header { height: 68px; padding: 0 18px; }.public-header .primary-button { min-height: 42px; padding: 0 13px; font-size: 12px; }.public-landing main { padding: 35px 18px 65px; }.public-hero { min-height: auto; }.public-hero h1 { font-size: 45px; }.public-hero__lead { font-size: 16px; }.public-hero__actions { align-items: flex-start; flex-direction: column; }.public-feature-grid { grid-template-columns: 1fr; margin-top: 45px; }.auth-page { grid-template-columns: 1fr; }.auth-story { min-height: 340px; padding: 28px 24px; }.auth-story h1 { font-size: 42px; }.auth-story > span { display: none; }.auth-panel { padding: 20px 16px 40px; }.auth-card { padding: 25px 20px; } + .student-app, .student-app--collapsed { display: block; }.student-sidebar { display: none; }.student-workspace { min-height: 100dvh; }.student-topbar { height: 62px; padding: 0 16px; }.student-topbar .quiet-button { min-height: 40px; padding: 0 12px; font-size: 11px; }.student-main { padding: 24px 16px 105px; }.student-mobile-dock { position: fixed; z-index: 80; left: 10px; right: 10px; bottom: max(10px, env(safe-area-inset-bottom)); min-height: 68px; display: flex; align-items: center; justify-content: space-around; padding: 7px; border: 1px solid rgba(255,255,255,.8); border-radius: 20px; background: rgba(255,255,255,.94); box-shadow: 0 15px 45px rgba(15,23,42,.18); backdrop-filter: blur(18px); }.student-mobile-dock a { min-width: 62px; min-height: 50px; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px; border-radius: 14px; color: #98a2b3; font-size: 9px; }.student-mobile-dock a.is-active { color: var(--tenant-primary); background: color-mix(in srgb, var(--tenant-primary) 8%, white); }.student-mobile-dock svg { width: 21px; height: 21px; }.page-heading, .dashboard-heading { align-items: flex-start; flex-direction: column; }.page-heading .search-field { width: 100%; min-width: 0; }.dashboard-heading .primary-button { width: 100%; }.dashboard-hero { grid-template-columns: 1fr; padding: 28px 22px; }.dashboard-hero__target { display: none; }.dashboard-hero h2 { font-size: 32px; }.metric-grid { grid-template-columns: repeat(2,1fr); gap: 9px; }.metric-card { min-height: 90px; padding: 13px; }.metric-card__icon { width: 39px; height: 39px; }.metric-card strong { font-size: 19px; }.content-card { padding: 18px; }.announcements > div:last-child { grid-template-columns: 1fr; }.subject-grid, .collection-list { grid-template-columns: 1fr; }.subject-card { min-height: 230px; }.subject-detail-hero { align-items: flex-start; flex-direction: column; padding: 26px 20px; }.subject-detail-hero .primary-button { width: 100%; }.chapter-list article { grid-template-columns: 35px 1fr; }.chapter-list article a { grid-column: 2; }.region-grid { grid-template-columns: repeat(2,1fr); }.selection-page { padding-top: 40px; }.selection-page h1 { font-size: 40px; }.quiz-start-page section { margin-top: 30px; padding: 28px 20px; }.quiz-header { grid-template-columns: 44px 1fr; gap: 8px; padding: 8px 12px; }.quiz-header > span { display: none; }.quiz-header > div { grid-template-columns: 1fr auto; }.quiz-header div > span { grid-column: 1 / -1; grid-row: 2; }.quiz-workspace { display: block; padding: 14px; }.question-card { min-height: 0; padding: 22px 17px; }.question-navigator { position: static; margin-top: 14px; }.quiz-footer { position: sticky; bottom: 0; z-index: 20; }.quiz-footer button { min-width: 0; flex: 1; }.report-metrics { grid-template-columns: repeat(2,1fr); }.report-actions { flex-direction: column; }.report-actions > * { width: 100%; } +} + +.site-student-preview { --preview-primary: #3157d5; min-height: 620px; display: grid; grid-template-columns: 190px minmax(0,1fr); overflow: hidden; border: 1px solid #e4e7ec; border-radius: 18px; background: #f4f6f9; text-align: left; } +.site-student-preview > aside { display: flex; flex-direction: column; min-width: 0; border-right: 1px solid #e5e7eb; background: rgba(255,255,255,.96); } +.site-student-preview > aside > header { min-height: 64px; display: flex; align-items: center; gap: 9px; padding: 12px; border-bottom: 1px solid #f0f2f5; }.site-student-preview aside header img, .site-student-preview aside header > i { width: 36px; height: 36px; display: grid; place-items: center; border-radius: 10px; object-fit: cover; background: var(--preview-primary); color: #fff; }.site-student-preview aside header svg { width: 18px; }.site-student-preview aside header strong, .site-student-preview aside header small { display: block; }.site-student-preview aside header strong { font-size: 12px; }.site-student-preview aside header small { margin-top: 2px; color: #98a2b3; font-size: 8px; } +.site-student-preview aside nav { flex: 1; padding: 10px 8px; }.site-student-preview aside nav section { margin-bottom: 9px; }.site-student-preview aside nav p { margin: 0 8px 3px; color: #a0a7b4; font-size: 7px; font-weight: 800; letter-spacing: .1em; }.site-student-preview aside nav span { min-height: 32px; display: flex; align-items: center; gap: 8px; padding: 0 9px; border-radius: 8px; color: #667085; font-size: 9px; font-weight: 650; }.site-student-preview aside nav span.is-active { background: #111827; color: #fff; }.site-student-preview aside nav svg { width: 13px; }.site-student-preview aside nav em { margin-left: auto; color: #98a2b3; font-size: 6px; font-style: normal; }.site-student-preview aside footer { display: flex; align-items: center; gap: 8px; padding: 10px; border-top: 1px solid #eef0f3; }.site-student-preview aside footer > i { width: 30px; height: 30px; display: grid; place-items: center; border-radius: 50%; background: var(--preview-primary); color: #fff; font-size: 10px; font-style: normal; font-weight: 800; }.site-student-preview aside footer strong, .site-student-preview aside footer small { display: block; font-size: 8px; }.site-student-preview aside footer small { color: #98a2b3; } +.site-student-preview > main { min-width: 0; background-image: linear-gradient(to right,rgba(15,23,42,.03) 1px,transparent 1px),linear-gradient(to bottom,rgba(15,23,42,.03) 1px,transparent 1px); background-size: 28px 28px; }.site-student-preview > main > header { min-height: 48px; display: flex; align-items: center; justify-content: space-between; padding: 0 18px; border-bottom: 1px solid #e5e7eb; background: rgba(244,246,249,.9); color: #667085; font-size: 9px; }.site-student-preview > main > header button { min-height: 28px; padding: 0 10px; border: 1px solid #dfe3e9; border-radius: 8px; background: #fff; font-size: 8px; }.site-preview-content { padding: 18px; }.site-preview-welcome { display: flex; justify-content: space-between; align-items: center; }.site-preview-welcome small { color: var(--preview-primary); font-size: 7px; font-weight: 800; }.site-preview-welcome h2 { margin: 3px 0; font-size: 19px; }.site-preview-welcome p { margin: 0; color: #98a2b3; font-size: 8px; }.site-preview-welcome button { min-height: 30px; padding: 0 12px; border: 0; border-radius: 8px; background: var(--preview-primary); color: #fff; font-size: 8px; font-weight: 700; }.site-preview-hero { min-height: 145px; display: grid; grid-template-columns: 1fr 110px; align-items: center; margin-top: 12px; padding: 18px 22px; overflow: hidden; border-radius: 16px; color: #fff; }.site-preview-hero small { font-size: 7px; }.site-preview-hero h1 { margin: 8px 0 5px; font-size: 21px; }.site-preview-hero p { margin: 0; color: rgba(255,255,255,.72); font-size: 8px; }.site-preview-hero > svg { justify-self: center; width: 58px; height: 58px; opacity: .32; }.site-preview-hero img { width: 100px; height: 100px; justify-self: end; border-radius: 20px; object-fit: cover; }.site-preview-stats { display: grid; grid-template-columns: repeat(3,1fr); gap: 8px; margin-top: 9px; }.site-preview-stats article { min-height: 54px; display: flex; align-items: center; gap: 8px; padding: 9px; border: 1px solid #e5e7eb; border-radius: 10px; background: #fff; }.site-preview-stats svg { width: 16px; color: var(--preview-primary); }.site-preview-stats small, .site-preview-stats strong { display: block; }.site-preview-stats small { color: #98a2b3; font-size: 7px; }.site-preview-stats strong { margin-top: 2px; font-size: 12px; }.site-preview-modules { display: grid; grid-template-columns: repeat(2,1fr); gap: 8px; margin-top: 9px; }.site-preview-module { min-height: 50px; display: flex; align-items: center; justify-content: space-between; padding: 10px; border: 1px solid #e5e7eb; border-radius: 10px; background: #fff; }.site-preview-module strong { font-size: 9px; }.site-preview-module span { display: flex; align-items: center; gap: 2px; color: var(--preview-primary); font-size: 7px; }.site-preview-module svg { width: 9px; } +.builder-preview-device.is-mobile .site-student-preview { min-height: 650px; display: block; }.builder-preview-device.is-mobile .site-student-preview > aside { display: none; }.builder-preview-device.is-mobile .site-preview-content { padding: 12px; }.builder-preview-device.is-mobile .site-preview-hero { grid-template-columns: 1fr; min-height: 170px; }.builder-preview-device.is-mobile .site-preview-hero img, .builder-preview-device.is-mobile .site-preview-hero > svg { display: none; }.builder-preview-device.is-mobile .site-preview-stats { grid-template-columns: 1fr; }.builder-preview-device.is-mobile .site-preview-modules { grid-template-columns: 1fr; } +.builder-navigation-row { grid-template-columns: minmax(120px,1fr) minmax(100px,auto) auto auto !important; } +.catalog-learning-page, .vocabulary-unit-page, .handbook-reader-list, .handbook-entry-reader, .scoreline-page { max-width: 1120px; margin: auto; } +.learning-catalog-grid { display: grid; grid-template-columns: repeat(3,minmax(0,1fr)); gap: 12px; }.learning-catalog-grid > a { min-height: 210px; display: grid; grid-template-rows: 44px 1fr auto; padding: 20px; border: 1px solid #e2e6ed; border-radius: 18px; background: #fff; box-shadow: 0 5px 16px rgba(15,23,42,.035); }.learning-catalog-grid > a:hover { border-color: var(--tenant-primary); transform: translateY(-1px); }.learning-catalog-grid > a > span { width: 42px; height: 42px; display: grid; place-items: center; border-radius: 12px; background: color-mix(in srgb,var(--tenant-primary) 10%,white); color: var(--tenant-primary); font-size: 12px; font-weight: 850; }.learning-catalog-grid small { color: #98a2b3; font-size: 9px; letter-spacing: .1em; }.learning-catalog-grid h2 { margin: 8px 0; font-size: 20px; }.learning-catalog-grid p { color: #667085; font-size: 12px; line-height: 1.6; }.learning-catalog-grid strong { color: var(--tenant-primary); font-size: 11px; }.learning-catalog-grid > a > svg { justify-self: end; width: 17px; color: #98a2b3; } +.word-list { display: grid; grid-template-columns: repeat(2,minmax(0,1fr)); gap: 11px; }.word-list article { position: relative; min-height: 190px; padding: 20px; border: 1px solid #e2e6ed; border-radius: 17px; background: #fff; }.word-list article > div { display: flex; align-items: baseline; gap: 9px; }.word-list article > div strong { font-size: 24px; }.word-list article > div span { color: #98a2b3; }.word-list article > button { position: absolute; top: 15px; right: 15px; width: 40px; height: 40px; display: grid; place-items: center; border: 0; border-radius: 11px; background: #f2f4f7; color: #98a2b3; }.word-list article > button svg { width: 17px; }.word-list article > p { color: #475467; }.word-list blockquote { margin: 16px 0 0; padding: 12px 14px; border-left: 3px solid var(--tenant-primary); background: #f8fafc; color: #344054; font-size: 12px; line-height: 1.6; }.word-list blockquote small { display: block; margin-top: 5px; color: #98a2b3; } +.handbook-reader-list > section { display: grid; gap: 10px; }.handbook-reader-list > section > a { min-height: 82px; display: grid; grid-template-columns: 48px 1fr 20px; align-items: center; gap: 14px; padding: 14px 18px; border: 1px solid #e3e7ed; border-radius: 15px; background: #fff; }.handbook-reader-list > section > a:hover { border-color: var(--tenant-primary); }.handbook-reader-list > section > a > span { width: 42px; height: 42px; display: grid; place-items: center; border-radius: 11px; background: #f2f4f7; color: var(--tenant-primary); font-size: 11px; font-weight: 800; }.handbook-reader-list strong { font-size: 15px; }.handbook-reader-list p { margin: 5px 0 0; color: #98a2b3; font-size: 11px; }.handbook-reader-list a > svg { width: 17px; color: #b0b7c3; }.handbook-entry-reader { max-width: 820px; padding: 34px 42px; border: 1px solid #e2e6ed; border-radius: 20px; background: #fff; }.handbook-entry-reader header { margin: 22px 0 32px; padding-bottom: 24px; border-bottom: 1px solid #eef0f3; }.handbook-entry-reader h1 { margin: 6px 0 10px; font-size: 34px; }.handbook-entry-reader header > p:last-child { color: #667085; }.handbook-entry-reader .safe-markdown { font-size: 16px; line-height: 1.9; } +.scoreline-toolbar { display: flex; gap: 10px; margin-bottom: 16px; }.scoreline-toolbar .search-field { flex: 1; }.scoreline-toolbar select { min-width: 150px; min-height: 46px; padding: 0 13px; border: 1px solid var(--tenant-border); border-radius: 12px; background: #fff; }.scoreline-list { display: grid; gap: 10px; }.scoreline-list article { min-height: 100px; display: grid; grid-template-columns: 46px 1fr minmax(120px,auto); align-items: center; gap: 14px; padding: 17px; border: 1px solid #e3e7ed; border-radius: 15px; background: #fff; }.scoreline-list article > span { width: 44px; height: 44px; display: grid; place-items: center; border-radius: 12px; background: color-mix(in srgb,var(--tenant-primary) 9%,white); color: var(--tenant-primary); }.scoreline-list article > span svg { width: 20px; }.scoreline-list small { color: var(--tenant-primary); font-weight: 700; }.scoreline-list h2 { margin: 4px 0; font-size: 17px; }.scoreline-list p { margin: 0; color: #667085; font-size: 11px; }.scoreline-list code { max-width: 280px; overflow: hidden; color: #98a2b3; font-size: 9px; text-overflow: ellipsis; white-space: nowrap; } +@media (max-width: 760px) { .learning-catalog-grid, .word-list { grid-template-columns: 1fr; }.learning-catalog-grid > a { min-height: 180px; }.handbook-entry-reader { padding: 24px 18px; }.scoreline-toolbar { flex-direction: column; }.scoreline-list article { grid-template-columns: 42px 1fr; }.scoreline-list code { grid-column: 2; } } +@media (prefers-reduced-motion: reduce) { *, *::before, *::after { scroll-behavior: auto !important; animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; } } + +.tenant-admin-shell { --admin-ink: #172033; min-height: 100dvh; color: #172033; background: #f3f5f8; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif; } +.tenant-admin-header { position: sticky; top: 0; z-index: 100; min-height: 72px; display: grid; grid-template-columns: 240px minmax(520px, 1fr) auto; align-items: center; gap: 18px; padding: 0 22px; border-bottom: 1px solid #e6e9ef; background: rgba(255,255,255,.96); box-shadow: 0 8px 30px rgba(15,23,42,.045); backdrop-filter: blur(16px); } +.tenant-admin-brand { min-width: 0; display: flex; align-items: center; gap: 11px; }.tenant-admin-brand > img, .tenant-admin-brand > span { flex: 0 0 40px; width: 40px; height: 40px; display: grid; place-items: center; border-radius: 12px; object-fit: cover; background: var(--tenant-primary); color: #fff; font-weight: 850; box-shadow: 0 8px 18px color-mix(in srgb,var(--tenant-primary) 18%,transparent); }.tenant-admin-brand > div { min-width: 0; }.tenant-admin-brand strong, .tenant-admin-brand small { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }.tenant-admin-brand strong { font-size: 15px; }.tenant-admin-brand small { margin-top: 2px; color: #98a2b3; font-size: 10px; } +.tenant-admin-menu-trigger { flex: 0 0 auto; min-width: 40px; min-height: 40px; } +.tenant-admin-category-nav { min-width: 0; height: 72px; display: flex; align-items: center; justify-content: center; gap: 4px; overflow-x: auto; scrollbar-width: none; }.tenant-admin-category-nav::-webkit-scrollbar { display: none; }.tenant-admin-category-nav button { position: relative; flex: 0 0 auto; min-height: 44px; display: inline-flex; align-items: center; gap: 8px; padding: 0 15px; border: 0; border-radius: 11px; background: transparent; color: #667085; font-size: 13px; font-weight: 700; transition: color .18s ease, background .18s ease; }.tenant-admin-category-nav button:hover { color: #111827; background: #f3f4f6; }.tenant-admin-category-nav button.is-active { color: #111827; background: #eef1f5; }.tenant-admin-category-nav button.is-active::after { content: ""; position: absolute; left: 15px; right: 15px; bottom: -14px; height: 3px; border-radius: 3px 3px 0 0; background: var(--tenant-primary); }.tenant-admin-category-nav svg { font-size: 16px; } +.tenant-admin-header-actions { display: flex; align-items: center; justify-content: flex-end; gap: 10px; }.tenant-admin-region-select { width: 142px; }.tenant-admin-site-state { margin: 0; white-space: nowrap; } +.tenant-admin-body { min-height: calc(100dvh - 72px); display: grid; grid-template-columns: 240px minmax(0,1fr); gap: 22px; padding: 18px 22px 24px; } +.tenant-admin-sidebar { position: sticky; top: 90px; align-self: start; height: calc(100dvh - 108px); display: flex; flex-direction: column; overflow: hidden; border: 1px solid #e8ebf0; border-radius: 24px; background: #fff; box-shadow: 0 10px 30px rgba(15,23,42,.04); }.tenant-admin-sidebar-heading { min-height: 82px; display: flex; align-items: center; gap: 12px; padding: 18px; border-bottom: 1px solid #eef0f3; }.tenant-admin-sidebar-heading > span { width: 40px; height: 40px; display: grid; place-items: center; border-radius: 12px; background: #eef1f5; color: #344054; font-size: 18px; }.tenant-admin-sidebar-heading small, .tenant-admin-sidebar-heading strong { display: block; }.tenant-admin-sidebar-heading small { color: #98a2b3; font-size: 10px; }.tenant-admin-sidebar-heading strong { margin-top: 2px; font-size: 15px; }.tenant-admin-sidebar nav { flex: 1; display: flex; flex-direction: column; gap: 4px; overflow-y: auto; padding: 12px; } +.tenant-admin-nav-item { min-height: 44px; display: flex; align-items: center; gap: 11px; padding: 0 12px; border-radius: 11px; color: #667085; font-size: 13px; font-weight: 650; transition: color .18s ease, background .18s ease, box-shadow .18s ease; }.tenant-admin-nav-item:hover { color: #111827; background: #f4f5f7; }.tenant-admin-nav-item.is-active { color: #fff; background: var(--admin-ink, #172033); box-shadow: 0 8px 18px rgba(17,24,39,.15); }.tenant-admin-nav-icon { width: 20px; display: grid; place-items: center; font-size: 16px; }.tenant-admin-nav-item > span:nth-child(2) { min-width: 0; flex: 1; }.tenant-admin-nav-item .ant-tag { flex: 0 0 auto; margin: 0; padding-inline: 5px; color: #98a2b3; background: #f2f4f7; font-size: 9px; line-height: 18px; }.tenant-admin-nav-item.is-active .ant-tag { color: rgba(255,255,255,.68); background: rgba(255,255,255,.1); }.tenant-admin-sidebar-footnote { padding: 13px 16px; border-top: 1px solid #eef0f3; color: #a0a7b4; font-size: 9px; line-height: 1.5; } +.tenant-admin-content { min-width: 0; min-height: calc(100dvh - 114px); padding: 26px 28px 34px; border: 1px solid #e8ebf0; border-radius: 24px; outline: 0; background: #fff; box-shadow: 0 10px 30px rgba(15,23,42,.035); } +.tenant-page-header { min-height: 62px; display: flex; align-items: flex-start; justify-content: space-between; gap: 24px; margin-bottom: 22px; }.tenant-page-header h2 { margin: 0 !important; font-size: 28px !important; letter-spacing: -.035em; }.tenant-page-title-line { display: flex; align-items: center; gap: 10px; }.tenant-page-title-line .ant-tag { margin: 0; color: #667085; background: #f2f4f7; }.tenant-dashboard-toolbar { display: flex; align-items: center; gap: 10px; } + +/* Tenant dashboard */ +.tenant-dashboard-page { max-width: 1500px; margin: 0 auto; }.tenant-dashboard-page > .ant-alert { margin-bottom: 18px; }.tenant-metric-grid { display: grid; grid-template-columns: repeat(4,minmax(0,1fr)); gap: 14px; margin-bottom: 16px; }.tenant-metric-card .ant-card-body { min-height: 130px; display: flex; align-items: flex-start; gap: 15px; padding: 20px; }.tenant-metric-icon { flex: 0 0 42px; width: 42px; height: 42px; display: grid; place-items: center; border-radius: 12px; font-size: 19px; }.tenant-metric-icon.is-blue { color: #3157d5; background: #edf2ff; }.tenant-metric-icon.is-green { color: #15803d; background: #e9f8ef; }.tenant-metric-icon.is-cyan { color: #0f766e; background: #e8f8f6; }.tenant-metric-icon.is-orange { color: #c46b16; background: #fff4e8; }.tenant-metric-icon.is-purple { color: #7c3aed; background: #f3edff; }.tenant-metric-card small, .tenant-metric-card strong, .tenant-metric-card em { display: block; }.tenant-metric-card small { color: #667085; font-size: 11px; }.tenant-metric-card strong { margin-top: 8px; color: #111827; font-size: 25px; line-height: 1.1; letter-spacing: -.035em; }.tenant-metric-card em { margin-top: 8px; color: #98a2b3; font-size: 10px; font-style: normal; } +.tenant-dashboard-grid { display: grid; grid-template-columns: 1.08fr .92fr; gap: 16px; margin-bottom: 16px; }.tenant-dashboard-grid.is-wide-left { grid-template-columns: 1.35fr .65fr; }.tenant-dashboard-panel { min-width: 0; border-color: #e8ebf0; }.tenant-dashboard-panel .ant-card-head { min-height: 56px; padding-inline: 20px; }.tenant-dashboard-panel .ant-card-head-title { font-size: 14px; }.tenant-dashboard-panel .ant-card-body { padding: 20px; }.tenant-dashboard-panel .ant-empty { min-height: 180px; display: grid; place-items: center; align-content: center; } +.tenant-user-composition { min-height: 220px; display: grid; grid-template-columns: 210px 1fr; align-items: center; gap: 24px; }.tenant-donut { width: 176px; height: 176px; display: grid; place-items: center; margin: auto; border-radius: 50%; background: conic-gradient(#4c7df0 0 17%,#f6c453 17% 19%,#e5e7eb 19% 100%); }.tenant-donut::before { content: ""; grid-area: 1/1; width: 116px; height: 116px; border-radius: 50%; background: #fff; }.tenant-donut span { z-index: 1; grid-area: 1/1; text-align: center; }.tenant-donut strong, .tenant-donut small { display: block; }.tenant-donut strong { font-size: 25px; }.tenant-donut small { color: #98a2b3; font-size: 10px; }.tenant-user-legend p { display: grid; grid-template-columns: 8px 1fr auto; align-items: center; gap: 9px; margin: 0; padding: 11px 0; border-bottom: 1px solid #f0f2f5; color: #667085; font-size: 12px; }.tenant-user-legend p:last-child { border-bottom: 0; }.tenant-user-legend i { width: 8px; height: 8px; border-radius: 50%; background: #d9dde4; }.tenant-user-legend i.is-primary { background: #4c7df0; }.tenant-user-legend i.is-warning { background: #f6c453; }.tenant-user-legend strong { color: #111827; } +.tenant-onboarding-list { display: grid; grid-template-columns: repeat(2,minmax(0,1fr)); gap: 8px; margin: 18px 0; }.tenant-onboarding-list > div { min-width: 0; display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 10px 12px; border-radius: 10px; background: #f7f8fa; }.tenant-onboarding-list span { overflow: hidden; color: #667085; font-size: 10px; text-overflow: ellipsis; white-space: nowrap; }.tenant-onboarding-list .ant-tag { margin: 0; font-size: 9px; } +.tenant-bar-chart { height: 210px; display: flex; align-items: end; gap: 10px; padding: 20px 8px 0; border-bottom: 1px solid #e9ecf1; background-image: linear-gradient(to bottom,#eef0f4 1px,transparent 1px); background-size: 100% 25%; }.tenant-bar-chart i { flex: 1; max-height: 92%; min-height: 12px; border-radius: 5px 5px 0 0; background: linear-gradient(180deg,#6f94ef,#3157d5); opacity: .86; } +.tenant-resource-list { display: grid; gap: 10px; }.tenant-resource-list > div { min-height: 58px; display: grid; grid-template-columns: 34px 1fr auto; align-items: center; gap: 10px; padding: 9px 12px; border-radius: 11px; background: #f7f8fa; }.tenant-resource-list svg { color: #3157d5; }.tenant-resource-list span { color: #667085; font-size: 11px; }.tenant-resource-list strong { font-size: 17px; }.tenant-activity-list { display: grid; }.tenant-activity-list > div { min-height: 53px; display: grid; grid-template-columns: 8px 1fr auto; align-items: center; gap: 10px; border-bottom: 1px solid #eef0f3; }.tenant-activity-list > div:last-child { border-bottom: 0; }.tenant-activity-list i { width: 7px; height: 7px; border-radius: 50%; background: #3157d5; }.tenant-activity-list p { margin: 0; }.tenant-activity-list strong, .tenant-activity-list span { display: block; }.tenant-activity-list strong { font-size: 11px; }.tenant-activity-list span, .tenant-activity-list time { margin-top: 3px; color: #98a2b3; font-size: 9px; }.tenant-feature-placeholder { max-width: 880px; margin: 40px auto; }.tenant-feature-placeholder .ant-result { padding-bottom: 16px; }.tenant-feature-placeholder-detail { max-width: 620px; margin: 0 auto; padding: 20px 0 12px; border-top: 1px solid #eef0f3; text-align: center; } + +/* Tenant site builder workspace */ +.site-builder-workspace { max-width: 1480px; margin: 0 auto; } +.site-builder-header { display: flex; align-items: flex-start; justify-content: space-between; gap: 24px; margin-bottom: 20px; } +.site-builder-header h2 { margin: 0 0 4px !important; } +.site-builder-tabs { margin-bottom: 18px; padding: 0 18px; border: 1px solid #e7ebf2; border-radius: 14px; background: #f8f9fb; } +.site-builder-tabs .ant-tabs-nav { margin: 0 !important; }.site-builder-tabs .ant-tabs-tab { min-height: 54px; padding: 0 5px !important; font-weight: 650; } +.site-builder-canvas { min-width: 0; } +.site-builder-footer { display: flex; justify-content: space-between; margin-top: 20px; } +.builder-panel-stack { display: grid; gap: 16px; } +.builder-asset-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; } +.builder-asset-card { min-width: 0; } +.builder-upload-button { position: relative; display: inline-flex; min-height: 44px; align-items: center; justify-content: center; gap: 8px; padding: 8px 16px; border: 1px dashed #8fa2c2; border-radius: 10px; color: #3157d5; cursor: pointer; transition: background-color 180ms ease, border-color 180ms ease; } +.builder-upload-button:hover { border-color: #3157d5; background: #f3f6ff; } +.builder-upload-button.is-disabled { opacity: .5; cursor: not-allowed; } +.builder-upload-button input { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; } +.builder-template { display: grid; width: 100%; min-height: 150px; grid-template-columns: 1fr auto; gap: 12px; align-items: center; padding: 12px; border: 1px solid #e1e7f0; border-radius: 14px; background: #fff; text-align: left; cursor: pointer; transition: border-color 180ms ease, box-shadow 180ms ease, transform 180ms ease; } +.builder-template:hover { border-color: #9badd0; transform: translateY(-1px); } +.builder-template.is-active { border-color: #3157d5; box-shadow: 0 0 0 2px rgb(49 87 213 / 12%); } + +/* Student workspace — high-fidelity migration of the original student product */ +.student-app { --student-sidebar-width: 256px; min-height: 100dvh; display: grid; grid-template-columns: var(--student-sidebar-width) minmax(0, 1fr); background: #f4f6f9; } +.student-app--collapsed { --student-sidebar-width: 80px; } +.student-grid-background { position: fixed; inset: 0; pointer-events: none; opacity: .55; background-image: linear-gradient(to right, rgba(15,23,42,.035) 1px, transparent 1px), linear-gradient(to bottom, rgba(15,23,42,.035) 1px, transparent 1px); background-size: 40px 40px; } +.student-sidebar { width: var(--student-sidebar-width); border-right: 1px solid #e5e7eb; background: rgba(255,255,255,.94); box-shadow: none; backdrop-filter: blur(16px); } +.student-brand { min-height: 76px; padding: 14px 16px; border-bottom: 1px solid #f0f2f5; } +.student-brand img, .student-brand__mark { flex-basis: 42px; width: 42px; height: 42px; border-radius: 12px; box-shadow: 0 8px 18px color-mix(in srgb, var(--tenant-primary) 18%, transparent); } +.student-brand strong { color: #111827; font-size: 15px; font-weight: 800; } +.student-brand small { color: var(--tenant-primary); font-size: 10px; font-weight: 650; } +.student-sidebar nav { overflow-y: auto; padding: 14px 12px 18px; gap: 0; } +.student-nav-group { display: grid; gap: 4px; margin-bottom: 14px; } +.student-nav-group > p { margin: 0 10px 4px; color: #a0a7b4; font-size: 10px; font-weight: 800; letter-spacing: .12em; } +.student-nav-link { position: relative; min-height: 44px; gap: 12px; padding: 0 13px; border-radius: 11px; color: #667085; font-size: 13px; font-weight: 650; } +.student-nav-link:hover { background: #f3f4f6; color: #111827; } +.student-nav-link.is-active { background: #111827; color: #fff; box-shadow: 0 8px 18px rgba(17,24,39,.14); } +.student-nav-link em { margin-left: auto; padding: 3px 6px; border-radius: 999px; background: #f2f4f7; color: #98a2b3; font-size: 9px; font-style: normal; font-weight: 700; } +.student-nav-link.is-active em { background: rgba(255,255,255,.14); color: rgba(255,255,255,.72); } +.student-app--collapsed .student-nav-group { margin-bottom: 8px; } +.student-app--collapsed .student-nav-link { justify-content: center; padding: 0; } +.student-app--collapsed .student-nav-link span, .student-app--collapsed .student-nav-link em { display: none; } +.student-sidebar__account { min-height: auto; gap: 10px; margin: 0; padding: 14px 12px; border-radius: 0; border-top: 1px solid #eef0f3; background: #fff; } +.student-account-avatar { flex: 0 0 38px; width: 38px; height: 38px; display: grid; place-items: center; border-radius: 50%; background: linear-gradient(135deg, var(--tenant-primary), color-mix(in srgb, var(--tenant-primary) 55%, #60a5fa)); color: white; font-size: 14px; font-weight: 850; } +.student-sidebar__account strong { color: #344054; } +.student-sidebar__account small { display: inline-block; margin-top: 3px; padding: 2px 7px; border-radius: 999px; background: #f2f4f7; color: #667085; } +.student-logout { min-height: 38px; display: inline-flex; align-items: center; justify-content: center; gap: 5px; margin-left: auto; padding: 0 10px; border: 0; border-radius: 10px; background: #fff1f2; color: #e11d48; font-size: 11px; font-weight: 750; } +.student-logout:hover { background: #ffe4e6; } +.student-logout svg { width: 16px; } +.student-workspace { grid-column: 2; position: relative; z-index: 1; min-width: 0; } +.student-topbar { position: sticky; top: 0; z-index: 30; height: 58px; padding: 0 clamp(18px,3vw,36px); background: rgba(244,246,249,.88); border-bottom-color: rgba(223,229,239,.8); } +.student-topbar .quiet-button { min-height: 36px; padding: 0 13px; border-radius: 10px; font-size: 11px; } +.student-main { width: min(100%, 1380px); max-width: none; padding: 24px clamp(18px,3vw,36px) 80px; } +.dashboard-page { max-width: 1240px; margin: auto; } +.dashboard-heading, .page-heading { margin-bottom: 18px; } +.dashboard-heading h1, .page-heading h1 { font-size: clamp(25px,3vw,34px); letter-spacing: -.035em; } +.dashboard-heading > div > p:last-child, .page-heading > div > p:last-child { margin-top: 7px; color: #667085; font-size: 13px; } +.dashboard-hero { min-height: 210px; grid-template-columns: minmax(0,1fr) 190px; padding: 28px 34px; border-radius: 22px; box-shadow: 0 16px 40px color-mix(in srgb, var(--tenant-primary) 22%, transparent); } +.dashboard-hero h2 { max-width: 640px; margin: 15px 0 8px; font-size: clamp(26px,3vw,38px); } +.dashboard-hero p { margin: 0 0 20px; font-size: 13px; } +.dashboard-service-grid { display: grid; grid-template-columns: repeat(4,minmax(0,1fr)); gap: 11px; margin: 14px 0; } +.dashboard-service-card { min-height: 92px; display: grid; grid-template-columns: 44px minmax(0,1fr) 18px; align-items: center; gap: 11px; padding: 14px; border: 1px solid #e5e7eb; border-radius: 16px; background: rgba(255,255,255,.94); box-shadow: 0 5px 14px rgba(15,23,42,.035); } +.dashboard-service-card:hover { border-color: color-mix(in srgb, var(--tenant-primary) 30%, #e5e7eb); box-shadow: 0 9px 24px rgba(15,23,42,.07); } +.dashboard-service-card > span { width: 44px; height: 44px; display: grid; place-items: center; border-radius: 13px; } +.dashboard-service-card > span svg { width: 21px; } +.dashboard-service-card.blue > span { background: #e8f0ff; color: #3157d5; }.dashboard-service-card.rose > span { background: #fff0f3; color: #e11d48; }.dashboard-service-card.amber > span { background: #fff7e5; color: #d97706; }.dashboard-service-card.green > span { background: #eafaf3; color: #15803d; } +.dashboard-service-card strong, .dashboard-service-card small { display: block; }.dashboard-service-card strong { color: #1d2939; font-size: 14px; }.dashboard-service-card small { margin-top: 4px; color: #98a2b3; font-size: 10px; }.dashboard-service-card > svg { width: 16px; color: #b4bac4; } +.metric-grid { gap: 11px; margin: 0 0 14px; } +.metric-card { min-height: 88px; padding: 14px; border-radius: 15px; box-shadow: 0 4px 14px rgba(15,23,42,.035); } +.metric-card__icon { width: 42px; height: 42px; border-radius: 12px; } +.metric-card strong { font-size: 21px; } +.content-card { padding: 20px; border-radius: 17px; box-shadow: 0 5px 16px rgba(15,23,42,.035); } +.dashboard-columns { gap: 14px; } +.section-heading h2 { font-size: 17px; } +.feature-placeholder { min-height: calc(100dvh - 150px); display: grid; place-items: center; } +.feature-placeholder > section { width: min(100%,650px); padding: 42px; border: 1px solid #e3e7ee; border-radius: 24px; background: rgba(255,255,255,.95); box-shadow: 0 18px 50px rgba(15,23,42,.07); text-align: center; } +.feature-placeholder > section > span { width: 64px; height: 64px; display: grid; place-items: center; margin: auto; border-radius: 18px; background: color-mix(in srgb, var(--tenant-primary) 10%, white); color: var(--tenant-primary); } +.feature-placeholder > section > span svg { width: 28px; } +.feature-placeholder h1 { margin: 8px 0 20px; font-size: 36px; }.feature-placeholder h2 { margin: 0; font-size: 18px; }.feature-placeholder section > p:not(.eyebrow) { max-width: 510px; margin: 12px auto 24px; color: #667085; line-height: 1.8; }.feature-placeholder section > div { display: flex; justify-content: center; align-items: center; gap: 18px; } +.services-page, .profile-page { max-width: 1080px; margin: auto; }.service-section { margin-top: 26px; }.service-section > h2 { margin: 0 0 12px; color: #475467; font-size: 14px; }.service-grid { display: grid; grid-template-columns: repeat(2,minmax(0,1fr)); gap: 11px; }.service-grid > a { min-height: 112px; display: grid; grid-template-columns: 48px 1fr 18px; align-items: center; gap: 13px; padding: 18px; border: 1px solid #e2e6ed; border-radius: 16px; background: #fff; }.service-grid > a:hover { border-color: var(--tenant-primary); }.service-grid > a > span { width: 48px; height: 48px; display: grid; place-items: center; border-radius: 14px; background: color-mix(in srgb, var(--tenant-primary) 9%, white); color: var(--tenant-primary); }.service-grid strong, .service-grid p, .service-grid small { display: block; }.service-grid p { margin: 5px 0; color: #667085; font-size: 12px; }.service-grid small { display: flex; align-items: center; gap: 4px; color: #98a2b3; font-size: 10px; }.service-grid small svg { width: 12px; }.service-grid > a > svg { width: 17px; color: #b0b7c3; } +.profile-hero { min-height: 180px; display: flex; align-items: center; gap: 22px; padding: 30px; border-radius: 22px; background: linear-gradient(135deg,#111827,#344054); color: #fff; }.profile-hero > span { width: 76px; height: 76px; display: grid; place-items: center; border-radius: 50%; background: var(--tenant-primary); font-size: 28px; font-weight: 850; }.profile-hero p { margin: 0; color: rgba(255,255,255,.55); font-size: 11px; }.profile-hero h1 { margin: 7px 0; font-size: 30px; }.profile-hero small { padding: 4px 9px; border-radius: 999px; background: rgba(255,255,255,.12); }.profile-stat-grid { display: grid; grid-template-columns: repeat(3,1fr); gap: 12px; margin: 14px 0; }.profile-stat-grid article { min-height: 105px; display: grid; grid-template-columns: 38px 1fr; align-items: center; padding: 18px; border: 1px solid #e5e7eb; border-radius: 16px; background: #fff; }.profile-stat-grid svg { grid-row: 1 / 3; color: var(--tenant-primary); }.profile-stat-grid small { color: #98a2b3; }.profile-stat-grid strong { font-size: 22px; }.profile-menu { border: 1px solid #e5e7eb; border-radius: 17px; overflow: hidden; background: #fff; }.profile-menu a { min-height: 76px; display: grid; grid-template-columns: 40px 1fr 18px; align-items: center; gap: 12px; padding: 12px 18px; border-bottom: 1px solid #eef0f3; }.profile-menu a:last-child { border-bottom: 0; }.profile-menu a > svg:first-child { color: var(--tenant-primary); }.profile-menu strong, .profile-menu small { display: block; }.profile-menu small { margin-top: 4px; color: #98a2b3; } + +@media (max-width: 1050px) { + .dashboard-service-grid { grid-template-columns: repeat(2,minmax(0,1fr)); } +} +@media (max-width: 760px) { + .student-app, .student-app--collapsed { display: block; }.student-sidebar { display: none; }.student-workspace { min-height: 100dvh; }.student-main { padding: 18px 14px 105px; }.student-grid-background { background-size: 32px 32px; } + .student-mobile-dock { left: 12px; right: 12px; min-height: 66px; padding: 7px 5px; border-radius: 18px; background: rgba(255,255,255,.97); box-shadow: 0 8px 30px rgba(15,23,42,.15); } + .student-mobile-dock a { flex: 1; min-width: 0; min-height: 50px; font-size: 10px; }.student-mobile-dock svg { width: 22px; } + .dashboard-heading { flex-direction: row; align-items: center; }.dashboard-heading > div > p:last-child { display: none; }.dashboard-heading .primary-button { width: auto; min-height: 40px; padding: 0 13px; font-size: 11px; }.dashboard-heading h1 { font-size: 24px; } + .dashboard-hero { min-height: 190px; padding: 23px 20px; border-radius: 20px; }.dashboard-hero h2 { font-size: 26px; }.dashboard-service-grid { grid-template-columns: repeat(2,minmax(0,1fr)); gap: 8px; }.dashboard-service-card { min-height: 84px; grid-template-columns: 38px 1fr; padding: 11px; }.dashboard-service-card > span { width: 38px; height: 38px; }.dashboard-service-card > svg { display: none; }.dashboard-service-card small { font-size: 9px; } + .service-grid { grid-template-columns: 1fr; }.feature-placeholder > section { padding: 30px 20px; }.feature-placeholder section > div { flex-direction: column; }.profile-stat-grid { grid-template-columns: 1fr; }.profile-hero { padding: 24px 20px; }.profile-hero > span { width: 62px; height: 62px; } +} +.builder-template-swatch { grid-column: 1 / -1; display: block; height: 80px; border-radius: 10px; } +.builder-color-field { display: grid; gap: 8px; color: #475569; } +.builder-color-field input[type='color'] { width: 48px; min-height: 40px; padding: 3px; border: 1px solid #d9d9d9; background: #fff; cursor: pointer; } +.builder-navigation-row { display: grid; grid-template-columns: minmax(0, 1fr) auto auto; gap: 10px; align-items: center; padding: 12px; border-radius: 12px; background: #f7f9fc; } +.builder-navigation-row code { max-width: 120px; overflow: hidden; color: #64748b; text-overflow: ellipsis; } +.builder-sortable { display: grid; grid-template-columns: 44px minmax(0, 1fr) 130px auto; gap: 10px; align-items: center; padding: 12px; border: 1px solid #e5eaf2; border-radius: 12px; background: #fff; box-shadow: 0 2px 10px rgb(15 23 42 / 4%); } +.builder-drag-handle { width: 44px; height: 44px; border: 0; border-radius: 8px; background: transparent; color: #64748b; cursor: grab; } +.builder-drag-handle:hover { background: #f1f5f9; } +.builder-preview-device { margin: 0 auto; overflow: auto; border: 10px solid #172033; background: #fff; box-shadow: 0 24px 60px rgb(15 23 42 / 18%); transition: max-width 200ms ease, border-radius 200ms ease; } +.builder-preview-device.is-desktop { min-height: 680px; max-width: 1180px; border-radius: 24px; } +.builder-preview-device.is-mobile { height: 720px; max-width: 390px; border-radius: 38px; } + +@media (max-width: 1280px) { + .tenant-admin-header { grid-template-columns: auto minmax(0,1fr) auto; } + .tenant-admin-site-state { display: none; } + .tenant-metric-grid { grid-template-columns: repeat(2,minmax(0,1fr)); } +} + +@media (max-width: 991px) { + .tenant-admin-header { min-height: 118px; grid-template-columns: minmax(0,1fr) auto; grid-template-rows: 64px 54px; gap: 0 12px; padding: 0 16px; } + .tenant-admin-category-nav { grid-column: 1 / -1; grid-row: 2; height: 54px; justify-content: flex-start; margin: 0 -16px; padding: 0 16px; border-top: 1px solid #f0f2f5; } + .tenant-admin-category-nav button { min-height: 40px; padding-inline: 12px; } + .tenant-admin-category-nav button.is-active::after { bottom: -7px; } + .tenant-admin-body { min-height: calc(100dvh - 118px); display: block; padding: 14px 16px 22px; } + .tenant-admin-content { min-height: calc(100dvh - 154px); padding: 22px; } + .tenant-admin-mobile-drawer .ant-drawer-body { padding: 0; background: #f5f7fa; } + .tenant-admin-mobile-drawer .tenant-admin-sidebar { position: static; height: calc(100dvh - 56px); border: 0; border-radius: 0; box-shadow: none; } + .tenant-dashboard-grid, .tenant-dashboard-grid.is-wide-left { grid-template-columns: 1fr; } +} + +@media (max-width: 900px) { + .site-builder-header { align-items: stretch; flex-direction: column; } + .builder-asset-grid { grid-template-columns: 1fr; } +} + +@media (max-width: 600px) { + .tenant-admin-category-nav { margin-inline: -12px; padding-inline: 12px; } + .tenant-admin-header { padding-inline: 12px; }.tenant-admin-brand > img, .tenant-admin-brand > span { flex-basis: 36px; width: 36px; height: 36px; }.tenant-admin-brand strong { max-width: 120px; font-size: 13px; }.tenant-admin-header-actions { gap: 0; }.tenant-admin-body { padding: 0; }.tenant-admin-content { min-height: calc(100dvh - 118px); padding: 18px 14px 28px; border: 0; border-radius: 0; box-shadow: none; }.tenant-page-header { align-items: stretch; flex-direction: column; gap: 14px; }.tenant-page-header h2 { font-size: 24px !important; }.tenant-dashboard-toolbar { justify-content: space-between; overflow-x: auto; }.tenant-dashboard-toolbar .ant-segmented { flex: 1; }.tenant-dashboard-toolbar .ant-segmented-item-label { padding-inline: 8px; }.tenant-metric-grid { grid-template-columns: repeat(2,minmax(0,1fr)); gap: 9px; }.tenant-metric-card .ant-card-body { min-height: 118px; display: block; padding: 14px; }.tenant-metric-icon { width: 36px; height: 36px; margin-bottom: 10px; }.tenant-metric-card strong { font-size: 20px; }.tenant-user-composition { grid-template-columns: 1fr; }.tenant-onboarding-list { grid-template-columns: 1fr; }.tenant-dashboard-panel .ant-card-body { padding: 15px; }.tenant-feature-placeholder { margin: 0; }.site-builder-tabs { margin-inline: -4px; padding-inline: 10px; overflow: hidden; } + .builder-sortable { grid-template-columns: 44px minmax(0, 1fr) auto; } + .builder-sortable .ant-typography { grid-column: 2; } + .builder-navigation-row { grid-template-columns: minmax(0, 1fr) auto; } + .builder-navigation-row code { grid-column: 1 / -1; grid-row: 2; } +} .preview-frame { container-type: inline-size; diff --git a/src/main.tsx b/src/main.tsx index dc93ee8..e26f9c2 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -1,8 +1,10 @@ import React from 'react'; import ReactDOM from 'react-dom/client'; +import { QueryClientProvider } from '@tanstack/react-query'; import 'antd/dist/reset.css'; import './index.css'; import { App } from './app/App'; +import { queryClient } from './api'; async function enableMocking(): Promise { const dataMode = import.meta.env.VITE_DATA_MODE ?? (import.meta.env.DEV ? 'mock' : 'api'); @@ -15,6 +17,8 @@ await enableMocking(); ReactDOM.createRoot(document.getElementById('root')!).render( - + + + , ); diff --git a/src/mocks/handlers.ts b/src/mocks/handlers.ts index a0a9e93..41b33ce 100644 --- a/src/mocks/handlers.ts +++ b/src/mocks/handlers.ts @@ -8,9 +8,20 @@ import { onboardingOf, runtimeOf, updateTenant, + MOCK_OWNER_PERMISSIONS, } from './store'; import { cloneConfig } from '../shared/defaults'; +const demoRegionId = '10000000-0000-0000-0000-000000000001'; +const demoSubjectId = '20000000-0000-0000-0000-000000000001'; +const demoCategoryId = '30000000-0000-0000-0000-000000000001'; +const demoQuestionId = '40000000-0000-0000-0000-000000000001'; +const demoSessionId = '50000000-0000-0000-0000-000000000001'; +const demoSessionQuestionId = '60000000-0000-0000-0000-000000000001'; +const mockAssets = new Map(); +let mockSessionVersion = 1; +let mockLastAnswer: Record | null = null; + function hostOf(request: Request): string { return request.headers.get('X-Demo-Host') || new URL(request.url).hostname; } @@ -38,13 +49,15 @@ export const handlers = [ const host = hostOf(request); const body = await request.json() as LoginRequest; const state = ensureTenant(host); - if (body.identifier !== state.ownerIdentifier || body.password !== state.password) { + const ownerLogin = body.identifier === state.ownerIdentifier && body.password === state.password; + const studentLogin = body.identifier === 'student@example.com' && body.password === 'Demo1234'; + if (!ownerLogin && !studentLogin) { return HttpResponse.json({ code: 'login_failed', title: '账号或密码错误。' }, { status: 401 }); } const next = updateTenant(host, current => { current.session = { user: { userId: current.tenantId, name: '租户负责人', email: 'owner@academy.example' }, - permissions: ['tenant:dashboard:view', 'tenant:settings:manage', 'tenant:site-content:manage'], + permissions: ownerLogin ? [...MOCK_OWNER_PERMISSIONS] : [], }; }); return HttpResponse.json({ status: 'Authenticated', user: next.session!.user }); @@ -128,4 +141,98 @@ export const handlers = [ return problem(error); } }), + + http.post('/api/tenant/auth/browser/sms/send', () => HttpResponse.json({ verificationId: crypto.randomUUID(), expiresAt: new Date(Date.now() + 300_000).toISOString() })), + http.post('/api/tenant/auth/browser/password/reset/sms/send', () => HttpResponse.json({ verificationId: crypto.randomUUID(), expiresAt: new Date(Date.now() + 300_000).toISOString() })), + http.post('/api/tenant/auth/browser/login/sms', ({ request }) => { + const next = updateTenant(hostOf(request), current => { + current.session = { user: { userId: current.tenantId, name: '演示学生', phone: '13800000000' }, permissions: [] }; + }); + return HttpResponse.json({ status: 'Authenticated', user: next.session!.user }); + }), + http.post('/api/tenant/auth/browser/password/reset', () => HttpResponse.json({ status: 'PasswordReset' })), + http.post('/api/tenant/auth/browser/refresh', () => HttpResponse.json({ status: 'Authenticated' })), + + http.get('/api/student/profile/me', ({ request }) => { + const state = ensureTenant(hostOf(request)); + if (!state.session) return HttpResponse.json({ code: 'authentication_required' }, { status: 401 }); + return HttpResponse.json({ + profileId: state.tenantId, + userId: state.session.user.userId, + username: 'demo-student', + name: state.session.user.name ?? '演示学生', + phone: state.session.user.phone ?? null, + email: state.session.user.email ?? null, + primaryRole: 'Student', + membership: { isSvip: false, expiresAt: null }, + score: 120, + questionsAnsweredToday: 8, + masteredWordsCount: 36, + regionId: state.studentRegionId ?? null, + regionName: state.studentRegionId ? '天津' : null, + recentPractices: [], + }); + }), + http.patch('/api/student/profile/me', async ({ request }) => { + const body = await request.json() as { regionId: string }; + const state = updateTenant(hostOf(request), current => { current.studentRegionId = body.regionId; }); + return HttpResponse.json({ profileId: state.tenantId, userId: state.session?.user.userId ?? state.tenantId, username: 'demo-student', name: '演示学生', phone: null, email: null, primaryRole: 'Student', membership: { isSvip: false, expiresAt: null }, score: 120, questionsAnsweredToday: 8, masteredWordsCount: 36, regionId: body.regionId, regionName: '天津', recentPractices: [] }); + }), + http.get('/api/student/profile/exam-countdowns', () => HttpResponse.json({ items: [{ id: crypto.randomUUID(), examName: '目标考试', examDate: '2026-12-20', daysLeft: 138 }] })), + + http.get('/api/public/catalog/regions', () => HttpResponse.json({ items: [{ id: demoRegionId, name: '天津', code: 'tianjin', isActive: true }], total: 1 })), + http.get('/api/public/catalog/subjects', () => HttpResponse.json({ items: [{ id: demoSubjectId, name: '公共基础', description: '面向成人考试的综合基础科目', type: null, isActive: true }], total: 1 })), + http.get('/api/public/catalog/categories', () => HttpResponse.json({ items: [{ id: demoCategoryId, subjectId: demoSubjectId, name: '第一章 基础训练', isActive: true }], total: 1 })), + http.get('/api/public/catalog/practice-blueprints', () => HttpResponse.json({ items: [], total: 0 })), + http.get('/api/public/catalog/banners', () => HttpResponse.json({ items: [{ id: crypto.randomUUID(), title: '从今天的一组真题开始', subtitle: '稳步练习,及时复盘。', buttonText: '开始练习', buttonLink: '/subjects', isActive: true }], total: 1 })), + http.get('/api/public/catalog/announcements', () => HttpResponse.json({ items: [{ id: crypto.randomUUID(), content: '本周题库内容已更新。', isActive: true }], total: 1 })), + http.get('/api/public/catalog/vocabulary-units', () => HttpResponse.json({ items: [{ id: '71000000-0000-0000-0000-000000000001', name: '考研核心词汇', description: '高频基础词与真题常见表达', wordCount: 120, order: 1, regionId: demoRegionId, legacyId: null, entryId: null, contentNodeId: null, metadata: {} }], total: 1 })), + http.get('/api/public/catalog/vocabulary-words', () => HttpResponse.json({ items: [{ id: '72000000-0000-0000-0000-000000000001', unitId: '71000000-0000-0000-0000-000000000001', word: 'essential', phonetic: '/ɪˈsenʃl/', meaning: 'adj. 必不可少的;本质的', example: 'Practice is essential for steady improvement.', exampleTranslation: '练习对于稳定进步至关重要。', difficulty: 2, order: 1, legacyId: null, entryId: null, contentNodeId: null, tags: [], metadata: {} }], total: 1 })), + http.get('/api/public/catalog/handbook-subjects', () => HttpResponse.json({ items: [{ id: '73000000-0000-0000-0000-000000000001', name: '高等数学', description: '核心公式、题型与解题方法', regionId: demoRegionId, schoolId: null, majorId: null, entryId: null, contentNodeId: null, legacyId: null, type: null, icon: null, color: null, order: 1, metadata: {} }], total: 1 })), + http.get('/api/public/catalog/handbook-chapters', () => HttpResponse.json({ items: [{ id: '74000000-0000-0000-0000-000000000001', subjectId: '73000000-0000-0000-0000-000000000001', name: '第一章 函数与极限', description: '极限定义、性质和常用计算方法', entryId: null, contentNodeId: null, legacyId: null, order: 1, metadata: {} }], total: 1 })), + http.get('/api/public/catalog/handbook-entries', () => HttpResponse.json({ items: [{ id: '75000000-0000-0000-0000-000000000001', chapterId: '74000000-0000-0000-0000-000000000001', title: '两个重要极限', summary: '掌握常见等价无穷小与两个重要极限。', content: '## 重点公式\n\n当 $x \\to 0$ 时:\n\n$$\\frac{\\sin x}{x} \\to 1$$', entryId: null, contentNodeId: null, legacyId: null, tags: ['极限'], order: 1, metadata: {} }], total: 1 })), + http.get('/api/public/scoreline/years', () => HttpResponse.json({ items: [2026, 2025, 2024], total: 3 })), + http.get('/api/public/scoreline/records', () => HttpResponse.json({ page: 1, pageSize: 50, total: 1, items: [{ id: '76000000-0000-0000-0000-000000000001', legacyId: null, regionId: demoRegionId, schoolId: null, majorId: null, year: 2025, schoolName: '天津示例大学', majorName: '计算机科学与技术', fieldValues: { lowestScore: 248, averageScore: 276 } }] })), + + http.get('/api/student/learning/stats', () => HttpResponse.json({ answerCount: 24, correctCount: 18, wrongCount: 6, favoriteQuestionCount: 2 })), + http.get('/api/student/learning/trend', () => HttpResponse.json({ items: [{ date: '2026-08-02', answerCount: 8 }, { date: '2026-08-03', answerCount: 16 }] })), + http.get('/api/student/learning/wrong-questions', () => HttpResponse.json({ items: [], total: 0 })), + http.get('/api/student/learning/favorites/questions', () => HttpResponse.json({ items: [], total: 0 })), + http.post('/api/student/learning/favorites/questions', () => HttpResponse.json({ favorite: true })), + http.post('/api/student/learning/practice-sessions', () => { + mockSessionVersion = 1; + mockLastAnswer = null; + return HttpResponse.json({ id: demoSessionId, version: mockSessionVersion, status: 'Active' }); + }), + http.get('/api/student/learning/practice-sessions/detail', () => HttpResponse.json({ + session: { id: demoSessionId, version: mockSessionVersion, lastClientSequence: mockLastAnswer ? 1 : 0, durationMinutes: null, status: 'Active' }, + questions: [{ sessionQuestionId: demoSessionQuestionId, questionReferenceId: demoQuestionId, type: 'single_choice', typeLabel: '单选题', content: '下列 HTML 中,语义化主内容标签是?', options: [{ key: 'A', content: '`
`' }, { key: 'B', content: '`
`' }] }], + answersBySessionQuestion: mockLastAnswer ? { [demoSessionQuestionId]: mockLastAnswer } : {}, + })), + http.post('/api/student/learning/answers', async ({ request }) => { + const body = await request.json() as { clientSequence?: number }; + mockSessionVersion += 1; + mockLastAnswer = { status: 'Graded', isCorrect: true, sessionVersion: mockSessionVersion, clientSequence: body.clientSequence ?? 1 }; + return HttpResponse.json(mockLastAnswer); + }), + http.post('/api/student/learning/practice-sessions/submit', () => { + mockSessionVersion += 1; + return HttpResponse.json({ id: demoSessionId, version: mockSessionVersion, status: 'Submitted' }); + }), + http.get('/api/student/learning/practice-sessions/report', () => HttpResponse.json({ practiceSessionId: demoSessionId, status: 'Final', score: 1, totalScore: 1, accuracy: 1, correctCount: 1, wrongCount: 0, pendingReviewCount: 0, durationSeconds: 42 })), + + http.post('/api/tenant/content/assets/uploads/sign', async ({ request }) => { + const body = await request.json() as { fileName: string; mimeType: string }; + const id = crypto.randomUUID(); + mockAssets.set(id, { fileName: body.fileName, mimeType: body.mimeType }); + return HttpResponse.json({ item: { id }, upload: { method: 'PUT', url: `/mock-oss/${id}`, headers: { 'x-mock-upload': 'theme' }, expiresAt: new Date(Date.now() + 900_000).toISOString() } }); + }), + http.put('/mock-oss/:assetId', () => new HttpResponse(null, { status: 200 })), + http.post('/api/tenant/content/assets/uploads/confirm', () => HttpResponse.json({ status: 'Completed' })), + http.get('/api/student/assets/:assetId/preview', ({ params }) => { + const id = String(params.assetId); + const item = mockAssets.get(id); + if (!item) return HttpResponse.json({ code: 'asset_not_found' }, { status: 404 }); + return HttpResponse.json({ item: { id, fileName: item.fileName, previewUrl: null, uploadStatus: 2, securityScanStatus: 2, previewStatus: 2, visibility: 0 }, access: { userId: null, isMember: false, hasSvip: false }, url: { provider: 'mock', bucket: null, objectKey: id, method: 'GET', url: `/mock-oss/${id}`, headers: {}, expiresAt: new Date(Date.now() + 1_800_000).toISOString(), expiresInSeconds: 1800, signatureMode: 'mock' }, watermark: null }); + }), ]; diff --git a/src/mocks/store.ts b/src/mocks/store.ts index c17954d..9009597 100644 --- a/src/mocks/store.ts +++ b/src/mocks/store.ts @@ -12,9 +12,40 @@ import { cloneConfig, createDefaultConfig } from '../shared/defaults'; const PREFIX = 'tiku-saas-demo:v1:'; const OWNER_PERMISSIONS = [ 'tenant:dashboard:view', - 'tenant:settings:manage', - 'tenant:site-content:manage', 'tenant:staff:manage', + 'tenant:role:manage', + 'tenant:student:manage', + 'tenant:question-bank:manage', + 'tenant:vocabulary:manage', + 'tenant:handbook:manage', + 'tenant:video:manage', + 'tenant:scoreline:manage', + 'tenant:site-content:manage', + 'tenant:settings:manage', + 'tenant:provider:manage', + 'tenant:commerce:operate', + 'tenant:crm:manage', + 'tenant:commission:manage', + 'tenant:job:manage', + 'tenant:billing:manage', +]; + +export const MOCK_OWNER_PERMISSIONS = [...OWNER_PERMISSIONS]; + +const MOCK_BACKOFFICE_FEATURES = [ + 'core.backoffice', + 'question_bank.private', + 'learning.practice', + 'learning.exam', + 'content.vocabulary', + 'content.handbook', + 'content.video', + 'content.scoreline', + 'marketing.site_content', + 'student.management', + 'commerce.student_store', + 'crm.followup', + 'growth.referral_commission', ]; export interface DemoActivation { @@ -39,6 +70,7 @@ export interface DemoTenantState { password: string | null; activation: DemoActivation; session: DemoSession | null; + studentRegionId?: string | null; config: TenantSiteConfig; } @@ -56,7 +88,7 @@ export function createDemoTenant(host = 'academy.localhost'): DemoTenantState { return { host, tenantId: randomId(), - tenantCode: host.split('.')[0].replace(/[^a-z0-9-]/gi, '-').toLowerCase() || 'academy', + tenantCode: (host.split('.')[0] ?? 'academy').replace(/[^a-z0-9-]/gi, '-').toLowerCase() || 'academy', tenantName: config.branding.brandName, siteState: 'setup_required', ownerIdentifier: 'owner@academy.example', @@ -68,6 +100,7 @@ export function createDemoTenant(host = 'academy.localhost'): DemoTenantState { consumedAt: null, }, session: null, + studentRegionId: null, config: { schemaVersion: 1, configVersion: 1, @@ -141,7 +174,7 @@ export function runtimeOf(state: DemoTenantState): TenantRuntimeBootstrap { tenantName: state.tenantName, siteState: state.siteState, ...cloneConfig(state.config.published), - enabledFeatures: ['core.backoffice', 'student.practice', 'site.content'], + enabledFeatures: ['core.backoffice', 'learning.practice', 'content.vocabulary', 'content.handbook', 'content.scoreline', 'commerce.student_store', 'marketing.site_content'], loginMethods: ['password', 'sms'], }; } @@ -149,13 +182,24 @@ export function runtimeOf(state: DemoTenantState): TenantRuntimeBootstrap { export function backofficeOf(state: DemoTenantState): BackofficeBootstrap { if (!state.session) throw new DemoStoreError(401, 'authentication_required'); if (state.session.permissions.length === 0) throw new DemoStoreError(403, 'backoffice_access_denied'); + const permissions = OWNER_PERMISSIONS; const menus = [ - { code: 'tenant.dashboard', name: '工作台', path: '/tenant/dashboard', requiredPermission: 'tenant:dashboard:view' }, - { code: 'tenant.site-content', name: '站点设计', path: '/tenant/site-content', requiredPermission: 'tenant:settings:manage' }, - ].filter(menu => state.session!.permissions.includes(menu.requiredPermission)); + { code: 'tenant.dashboard', name: '租户总览', path: '/tenant/dashboard', requiredPermission: 'tenant:dashboard:view' }, + { code: 'tenant.staff', name: '员工与权限', path: '/tenant/staff', requiredPermission: 'tenant:staff:manage' }, + { code: 'tenant.students', name: '班级与学生', path: '/tenant/students', requiredPermission: 'tenant:student:manage' }, + { code: 'tenant.question-bank', name: '私有题库', path: '/tenant/question-bank', requiredPermission: 'tenant:question-bank:manage' }, + { code: 'tenant.vocabulary', name: '词汇', path: '/tenant/vocabulary', requiredPermission: 'tenant:vocabulary:manage' }, + { code: 'tenant.handbook', name: '知识手册', path: '/tenant/handbook', requiredPermission: 'tenant:handbook:manage' }, + { code: 'tenant.video', name: '视频', path: '/tenant/video', requiredPermission: 'tenant:video:manage' }, + { code: 'tenant.scoreline', name: '分数线', path: '/tenant/scoreline', requiredPermission: 'tenant:scoreline:manage' }, + { code: 'tenant.site-content', name: '运营内容', path: '/tenant/site-content', requiredPermission: 'tenant:site-content:manage' }, + { code: 'tenant.providers', name: '外部服务', path: '/tenant/providers', requiredPermission: 'tenant:provider:manage' }, + { code: 'tenant.commerce', name: '交易运营', path: '/tenant/commerce', requiredPermission: 'tenant:commerce:operate' }, + { code: 'tenant.billing', name: 'SaaS 账务', path: '/tenant/billing', requiredPermission: 'tenant:billing:manage' }, + ].filter(menu => permissions.includes(menu.requiredPermission)); return { - permissions: [...state.session.permissions], - enabledFeatures: ['core.backoffice', 'site.content'], + permissions: [...permissions], + enabledFeatures: [...MOCK_BACKOFFICE_FEATURES], menus, }; } diff --git a/src/shared/SafeMarkdown.tsx b/src/shared/SafeMarkdown.tsx new file mode 100644 index 0000000..ce2d0ea --- /dev/null +++ b/src/shared/SafeMarkdown.tsx @@ -0,0 +1,42 @@ +import Markdown, { defaultUrlTransform } from "react-markdown"; +import remarkGfm from "remark-gfm"; +import remarkMath from "remark-math"; +import rehypeKatex from "rehype-katex"; +import rehypeSanitize from "rehype-sanitize"; +import "katex/dist/katex.min.css"; + +interface MarkdownNode { + type: string; + value?: string; + children?: MarkdownNode[]; +} + +/** Keep raw tags visible for HTML questions while ensuring React only receives text. */ +function preserveHtmlQuestionSource() { + return (tree: MarkdownNode) => { + const visit = (node: MarkdownNode) => { + if (node.type === "html") node.type = "text"; + node.children?.forEach(visit); + }; + visit(tree); + }; +} + +export function SafeMarkdown({ children, className = "" }: { children: string; className?: string }) { + return ( +
+ ( + {label} + ), + }} + > + {children} + +
+ ); +} diff --git a/src/shared/SitePreview.tsx b/src/shared/SitePreview.tsx index 71dcecf..25682d8 100644 --- a/src/shared/SitePreview.tsx +++ b/src/shared/SitePreview.tsx @@ -1,45 +1,18 @@ -import { BookOpen, ChartNoAxesCombined, GraduationCap, Megaphone, MessageCircle, ShoppingBag, Sparkles } from 'lucide-react'; +import { ArrowRight, BarChart3, BookOpenCheck, Clock3, GraduationCap, Target } from 'lucide-react'; import type { HomeModule, TenantFrontendConfigDraft } from '../contracts'; +import { normalizeStudentNavigation, studentFeatures, studentNavigationGroups } from '../student/features'; +import { useThemeAssets } from '../theme/useThemeAssets'; -const moduleIcons = { - announcement: Megaphone, - 'feature-grid': Sparkles, - 'subject-entry': BookOpen, - 'scoreline-entry': ChartNoAxesCombined, - 'store-entry': ShoppingBag, - 'contact-cta': MessageCircle, - hero: GraduationCap, -} as const; - -function ModuleCard({ module, primary }: { module: HomeModule; primary: string }) { - const Icon = moduleIcons[module.type]; - if (module.type === 'announcement') { - return
{module.title}新学期课程安排已经发布
; - } - return

{module.title}

精选学习内容与服务,为你的成长提供清晰路径。

; +function PreviewModule({ module }: { module: HomeModule }) { + return
{module.title}查看内容
; } export function SitePreview({ config, compact = false }: { config: TenantFrontendConfigDraft; compact?: boolean }) { const { branding, theme } = config; - return ( -
-
-
- {branding.logoUrl ? :
} -
{branding.shortName || branding.brandName}

学习服务平台

-
- - -
-
- {config.homeModules.filter(item => item.visible && item.type === 'hero').map(module => ( -
-
专属学习空间

{branding.brandName}
{branding.slogan}

课程、题库和成长规划汇聚在一个清晰、可信赖的学习平台。

-
-
- ))} -
{config.homeModules.filter(item => item.visible && item.type !== 'hero').map(module => )}
-
-
- ); + const assets = useThemeAssets(branding); + const navigation = normalizeStudentNavigation(config.navigation).filter((item) => item.visible); + return
+ +
天津 · 学习工作台
TODAY'S FOCUS

你好,演示学员

保持节奏,完成今天的学习任务。

今日学习计划

{branding.slogan || '让每一次学习都有方向'}

课程、题库和成长规划汇聚在同一个学习工作台。

{assets.hero ? {branding.assetAlt?.hero : }
累计答题1,280
正确率82%
学习天数36
{config.homeModules.filter((item) => item.visible && item.type !== 'hero').slice(0, 4).map((module) => )}
+
; } diff --git a/src/shared/access.ts b/src/shared/access.ts index 8c3fe23..5383c93 100644 --- a/src/shared/access.ts +++ b/src/shared/access.ts @@ -1,6 +1,7 @@ import type { BackofficeBootstrap } from '../contracts'; export const SITE_SETTINGS_PERMISSION = 'tenant:settings:manage'; +export const THEME_ASSET_PERMISSION = 'tenant:question-bank:manage'; export function hasBackofficeAccess(bootstrap: BackofficeBootstrap | null): boolean { return Boolean(bootstrap?.permissions.length); @@ -9,3 +10,7 @@ export function hasBackofficeAccess(bootstrap: BackofficeBootstrap | null): bool export function canManageSite(bootstrap: BackofficeBootstrap | null): boolean { return Boolean(bootstrap?.permissions.includes(SITE_SETTINGS_PERMISSION)); } + +export function canManageThemeAssets(bootstrap: BackofficeBootstrap | null): boolean { + return Boolean(bootstrap?.permissions.includes(THEME_ASSET_PERMISSION)); +} diff --git a/src/shared/defaults.ts b/src/shared/defaults.ts index f4e7ace..d233e05 100644 --- a/src/shared/defaults.ts +++ b/src/shared/defaults.ts @@ -1,4 +1,5 @@ import type { TenantFrontendConfigDraft } from '../contracts'; +import { knownStudentNavigation } from '../student/features'; export const templateNames = { clarity: '清朗学习', @@ -26,14 +27,15 @@ export function createDefaultConfig(): TenantFrontendConfigDraft { ...templateThemes.clarity, fontFamily: 'system-ui, sans-serif', radius: 18, + surfaceColor: '#ffffff', + mutedColor: '#eef2f8', + borderColor: '#dfe5ef', + successColor: '#15803d', + warningColor: '#b45309', + dangerColor: '#dc2626', }, features: { template: 'clarity' }, - navigation: [ - { id: 'home', label: '首页', href: '/', visible: true }, - { id: 'subjects', label: '学习中心', href: '/subjects', visible: true }, - { id: 'scoreline', label: '院校分数线', href: '/scoreline', visible: true }, - { id: 'profile', label: '个人中心', href: '/profile', visible: true }, - ], + navigation: knownStudentNavigation(), homeModules: [ { id: 'hero', type: 'hero', title: '首页主视觉', visible: true }, { id: 'notice', type: 'announcement', title: '最新公告', visible: true }, diff --git a/src/shared/number.ts b/src/shared/number.ts new file mode 100644 index 0000000..53011ba --- /dev/null +++ b/src/shared/number.ts @@ -0,0 +1,8 @@ +export function numeric(value: number | string | null | undefined): number { + const parsed = Number(value ?? 0); + return Number.isFinite(parsed) ? parsed : 0; +} + +export function percent(value: number | string | null | undefined): string { + return `${Math.round(numeric(value) * (numeric(value) <= 1 ? 100 : 1))}%`; +} diff --git a/src/site-builder/AssetLibraryPanel.tsx b/src/site-builder/AssetLibraryPanel.tsx new file mode 100644 index 0000000..b67b596 --- /dev/null +++ b/src/site-builder/AssetLibraryPanel.tsx @@ -0,0 +1,60 @@ +import { DeleteOutlined, ReloadOutlined, UploadOutlined } from '@ant-design/icons'; +import { Alert, Button, Card, Input, Progress, Space, Typography } from 'antd'; +import type { BrandingConfig } from '../contracts'; +import type { AssetSlotDefinition, AssetUploadState } from './types'; + +const slots: AssetSlotDefinition[] = [ + { role: 'logo', title: '品牌 Logo', description: '用于学生端导航、登录页和后台标识。', ratio: '建议 1:1,PNG / WebP' }, + { role: 'favicon', title: '浏览器图标', description: '发布后显示在浏览器标签页。', ratio: '建议 1:1,PNG / SVG' }, + { role: 'loginBackground', title: '登录背景', description: '登录页宽屏品牌背景,移动端会自适应裁切。', ratio: '建议 16:10,WebP' }, + { role: 'hero', title: '首页 Hero', description: '公开品牌首页的主视觉资源。', ratio: '建议 4:3,WebP' }, + { role: 'serviceQr', title: '客服二维码', description: '用于联系顾问模块,不应包含敏感信息。', ratio: '建议 1:1,PNG' }, +]; + +const fieldByRole = { + logo: 'logoAssetId', favicon: 'faviconAssetId', loginBackground: 'loginBackgroundAssetId', + hero: 'heroAssetId', serviceQr: 'serviceQrAssetId', +} as const; + +export function AssetLibraryPanel({ + branding, canUpload, uploads, onUpload, onRetry, onRemove, onAltChange, +}: { + branding: BrandingConfig; + canUpload: boolean; + uploads: Partial>; + onUpload: (slot: AssetSlotDefinition, file: File) => void; + onRetry: (slot: AssetSlotDefinition) => void; + onRemove: (slot: AssetSlotDefinition) => void; + onAltChange: (slot: AssetSlotDefinition, alt: string) => void; +}) { + return ( +
+ {!canUpload && } +
+ {slots.map((slot) => { + const state = uploads[slot.role]; + const assetId = branding[fieldByRole[slot.role]]; + return ( + 已配置 : null}> + {slot.description}
{slot.ratio},最大 8 MB
+ + {state?.status === 'uploading' && } + {state?.status === 'error' && } onClick={() => onRetry(slot)}>重试} />} + {assetId && <> + onAltChange(slot, event.target.value)} /> + {assetId} + } +
+ ); + })} +
+
+ ); +} diff --git a/src/site-builder/BrandPanel.tsx b/src/site-builder/BrandPanel.tsx new file mode 100644 index 0000000..ff6b4b1 --- /dev/null +++ b/src/site-builder/BrandPanel.tsx @@ -0,0 +1,18 @@ +import { Card, Col, Form, Input, Row, Typography } from 'antd'; +import type { BrandingConfig } from '../contracts'; + +export function BrandPanel({ branding, onChange }: { branding: BrandingConfig; onChange: (patch: Partial) => void }) { + return ( + 公开页面与学习端共用}> +
+ + onChange({ brandName: event.target.value })} /> + onChange({ shortName: event.target.value })} /> + + onChange({ slogan: event.target.value })} /> + onChange({ serviceWechat: event.target.value })} /> + onChange({ imageAlt: event.target.value })} /> +
+
+ ); +} diff --git a/src/site-builder/ModulesPanel.tsx b/src/site-builder/ModulesPanel.tsx new file mode 100644 index 0000000..bf195df --- /dev/null +++ b/src/site-builder/ModulesPanel.tsx @@ -0,0 +1,34 @@ +import { DndContext, PointerSensor, useSensor, useSensors, type DragEndEvent } from '@dnd-kit/core'; +import { SortableContext, useSortable, verticalListSortingStrategy } from '@dnd-kit/sortable'; +import { CSS } from '@dnd-kit/utilities'; +import { HolderOutlined } from '@ant-design/icons'; +import { Card, Col, Input, Row, Switch, Tag, Typography } from 'antd'; +import type { HomeModule, NavigationItem } from '../contracts'; +import { studentFeatures } from '../student/features'; + +function SortableModule({ module, onChange }: { module: HomeModule; onChange: (patch: Partial) => void }) { + const sortable = useSortable({ id: module.id }); + return
+ + onChange({ title: event.target.value })} /> + {module.type} + onChange({ visible })} /> +
; +} + +export function ModulesPanel({ navigation, modules, onNavigation, onModule, onReorder }: { + navigation: NavigationItem[]; + modules: HomeModule[]; + onNavigation: (id: string, patch: Partial) => void; + onModule: (id: string, patch: Partial) => void; + onReorder: (activeId: string, overId: string) => void; +}) { + const sensors = useSensors(useSensor(PointerSensor, { activationConstraint: { distance: 6 } })); + const dragEnd = ({ active, over }: DragEndEvent) => { if (over && active.id !== over.id) onReorder(String(active.id), String(over.id)); }; + return +
+ {navigation.map((item) => { const feature = studentFeatures.find((value) => value.path === item.href); return
onNavigation(item.id, { label: event.target.value })} />{item.href}{feature?.implementation === 'ready' ? '已开放' : feature?.implementation === 'backend_missing' ? '缺后端契约' : '迁移中'} onNavigation(item.id, { visible })} />
; })} +
+ item.id)} strategy={verticalListSortingStrategy}>
{modules.map((module) => onModule(module.id, patch)} />)}
+
; +} diff --git a/src/site-builder/PreviewPanel.tsx b/src/site-builder/PreviewPanel.tsx new file mode 100644 index 0000000..f669825 --- /dev/null +++ b/src/site-builder/PreviewPanel.tsx @@ -0,0 +1,12 @@ +import { DesktopOutlined, MobileOutlined } from '@ant-design/icons'; +import { Segmented } from 'antd'; +import type { TenantFrontendConfigDraft } from '../contracts'; +import { SitePreview } from '../shared/SitePreview'; +import type { PreviewMode } from './types'; + +export function PreviewPanel({ draft, mode, onModeChange }: { draft: TenantFrontendConfigDraft; mode: PreviewMode; onModeChange: (mode: PreviewMode) => void }) { + return
+
onModeChange(value as PreviewMode)} options={[{ label: '桌面端', value: 'desktop', icon: }, { label: '移动端', value: 'mobile', icon: }]} />
+
+
; +} diff --git a/src/site-builder/ThemePanel.tsx b/src/site-builder/ThemePanel.tsx new file mode 100644 index 0000000..331b93e --- /dev/null +++ b/src/site-builder/ThemePanel.tsx @@ -0,0 +1,41 @@ +import { CheckOutlined } from '@ant-design/icons'; +import { Card, Col, Form, Input, InputNumber, Radio, Row, Space, Tag, Typography } from 'antd'; +import type { ThemeConfig } from '../contracts'; +import { templateNames, templateThemes } from '../shared/defaults'; + +const colors: Array<[keyof Pick, string]> = [ + ['primaryColor', '品牌主色'], ['secondaryColor', '品牌辅助色'], ['backgroundColor', '页面背景'], ['surfaceColor', '卡片表面'], + ['textColor', '正文文字'], ['mutedColor', '弱化表面'], ['borderColor', '边框'], ['successColor', '成功状态'], ['warningColor', '警告状态'], ['dangerColor', '错误状态'], +]; + +export function ThemePanel({ theme, template, onTemplate, onChange }: { + theme: ThemeConfig; + template: keyof typeof templateNames; + onTemplate: (value: keyof typeof templateNames) => void; + onChange: (patch: Partial) => void; +}) { + return
+ 模板只提供起点,颜色仍可细调}> + + {(Object.keys(templateNames) as Array).map((key) => + + )} + + + + {colors.map(([field, label]) => + + )} +
+ onChange({ fontFamily: event.target.value })}> + 专业无衬线 + 学院标题衬线 + + onChange({ radius: value ?? 0 })} /> +
+
+
; +} diff --git a/src/site-builder/types.ts b/src/site-builder/types.ts new file mode 100644 index 0000000..5f912c7 --- /dev/null +++ b/src/site-builder/types.ts @@ -0,0 +1,19 @@ +import type { ThemeAssetRole } from '../contracts'; + +export type BuilderTab = 'brand' | 'theme' | 'modules' | 'assets' | 'preview'; +export type PreviewMode = 'desktop' | 'mobile'; +export type SaveState = 'idle' | 'saving' | 'saved' | 'error'; + +export interface AssetUploadState { + file?: File; + progress: number; + status: 'idle' | 'uploading' | 'success' | 'error'; + message?: string; +} + +export interface AssetSlotDefinition { + role: Exclude; + title: string; + description: string; + ratio: string; +} diff --git a/src/site-builder/useSiteBuilder.ts b/src/site-builder/useSiteBuilder.ts new file mode 100644 index 0000000..06d1567 --- /dev/null +++ b/src/site-builder/useSiteBuilder.ts @@ -0,0 +1,157 @@ +import { useCallback, useEffect, useRef, useState } from 'react'; +import type { TenantFrontendConfigDraft, TenantSiteConfig, ThemeAssetRole } from '../contracts'; +import { ApiError, assetApi, siteConfigApi } from '../api'; +import { cloneConfig, templateNames, templateThemes } from '../shared/defaults'; +import type { AssetUploadState, PreviewMode, SaveState } from './types'; +import { normalizeStudentNavigation } from '../student/features'; + +const assetFieldByRole = { + logo: 'logoAssetId', + favicon: 'faviconAssetId', + loginBackground: 'loginBackgroundAssetId', + hero: 'heroAssetId', + serviceQr: 'serviceQrAssetId', +} as const; + +function normalizeDraft(value: TenantFrontendConfigDraft): TenantFrontendConfigDraft { + const next = cloneConfig(value); + next.navigation = normalizeStudentNavigation(next.navigation); + return next; +} + +export function useSiteBuilder(onPublished: () => Promise) { + const [siteConfig, setSiteConfig] = useState(null); + const [draft, setDraft] = useState(null); + const [saveState, setSaveState] = useState('idle'); + const [previewMode, setPreviewMode] = useState('desktop'); + const [error, setError] = useState(''); + const [published, setPublished] = useState(false); + const [dirty, setDirty] = useState(false); + const [uploads, setUploads] = useState>>({}); + const revisionRef = useRef(0); + + const load = useCallback(async () => { + setError(''); + try { + const value = await siteConfigApi.get(); + setSiteConfig(value); + setDraft(normalizeDraft(value.draft)); + setDirty(false); + setSaveState('saved'); + } catch { + setError('无法读取站点配置,请重新登录后再试。'); + } + }, []); + + useEffect(() => { void load(); }, [load]); + + const update = useCallback((mutator: (next: TenantFrontendConfigDraft) => void) => { + setDraft((current) => { + if (!current) return current; + const next = cloneConfig(current); + mutator(next); + revisionRef.current += 1; + setDirty(true); + setPublished(false); + return next; + }); + }, []); + + useEffect(() => { + if (!draft || !dirty) return; + const revision = revisionRef.current; + setSaveState('saving'); + const timer = window.setTimeout(async () => { + try { + const value = await siteConfigApi.saveDraft(draft); + setSiteConfig(value); + setSaveState('saved'); + if (revisionRef.current === revision) setDirty(false); + } catch { + setSaveState('error'); + } + }, 700); + return () => window.clearTimeout(timer); + }, [draft, dirty]); + + useEffect(() => { + const warn = (event: BeforeUnloadEvent) => { + if (!dirty && saveState !== 'saving') return; + event.preventDefault(); + }; + window.addEventListener('beforeunload', warn); + return () => window.removeEventListener('beforeunload', warn); + }, [dirty, saveState]); + + const chooseTemplate = (template: keyof typeof templateNames) => update((next) => { + next.features.template = template; + Object.assign(next.theme, templateThemes[template]); + }); + + const uploadAsset = useCallback(async ( + role: Exclude, + file: File, + title: string, + ) => { + setUploads((current) => ({ ...current, [role]: { file, progress: 0, status: 'uploading' } })); + try { + const uploaded = await assetApi.uploadThemeImage(file, title, (progress) => { + setUploads((current) => ({ ...current, [role]: { file, progress, status: 'uploading' } })); + }); + update((next) => { + next.branding[assetFieldByRole[role]] = uploaded.assetId; + next.branding.assetAlt ??= {}; + }); + setUploads((current) => ({ ...current, [role]: { file, progress: 100, status: 'success' } })); + } catch (reason) { + setUploads((current) => ({ + ...current, + [role]: { + file, + progress: current[role]?.progress ?? 0, + status: 'error', + message: reason instanceof Error ? reason.message : '上传失败,请重试。', + }, + })); + } + }, [update]); + + const removeAsset = useCallback((role: Exclude) => { + update((next) => { delete next.branding[assetFieldByRole[role]]; }); + setUploads((current) => ({ ...current, [role]: { progress: 0, status: 'idle' } })); + }, [update]); + + const retryAsset = useCallback((role: Exclude, title: string) => { + const file = uploads[role]?.file; + if (file) void uploadAsset(role, file, title); + }, [uploadAsset, uploads]); + + const publish = useCallback(async () => { + if (!draft) return; + setError(''); + try { + setSaveState('saving'); + const saved = await siteConfigApi.saveDraft(draft); + const next = await siteConfigApi.publish(saved.configVersion); + setSiteConfig(next); + setDraft(normalizeDraft(next.draft)); + setDirty(false); + setSaveState('saved'); + setPublished(true); + await onPublished(); + } catch (reason) { + setSaveState('error'); + if (reason instanceof ApiError && reason.code === 'frontend_config_version_conflict') { + setError('配置已经被其他管理员修改。请重新载入最新草稿,确认后再发布。'); + } else { + setError('发布失败,草稿仍保留在当前页面,请稍后重试。'); + } + } + }, [draft, onPublished]); + + return { + siteConfig, draft, saveState, previewMode, error, published, dirty, uploads, + setPreviewMode, setPublished, update, chooseTemplate, uploadAsset, removeAsset, + retryAsset, publish, reload: load, + }; +} diff --git a/src/student/StudentSession.tsx b/src/student/StudentSession.tsx new file mode 100644 index 0000000..4fa0ddc --- /dev/null +++ b/src/student/StudentSession.tsx @@ -0,0 +1,40 @@ +import { createContext, useContext, type ReactNode } from "react"; +import { useQuery } from "@tanstack/react-query"; +import { profileApi, queryKeys } from "../api"; +import { ApiError } from "../api/http"; +import type { StudentProfile } from "../api/types"; +import { applyRememberedDevelopmentRegion } from "./developmentCatalog"; + +interface StudentSessionValue { + profile: StudentProfile | null; + loading: boolean; + authenticated: boolean; + error: Error | null; + refresh: () => Promise; +} + +const StudentSessionContext = createContext(null); + +export function StudentSessionProvider({ children }: { children: ReactNode }) { + const query = useQuery({ + queryKey: queryKeys.profile, + queryFn: profileApi.me, + retry: false, + staleTime: 60_000, + }); + const isGuest = query.error instanceof ApiError && query.error.status === 401; + const value: StudentSessionValue = { + profile: query.data ? applyRememberedDevelopmentRegion(query.data) : null, + loading: query.isLoading, + authenticated: Boolean(query.data), + error: query.error && !isGuest ? query.error : null, + refresh: query.refetch, + }; + return {children}; +} + +export function useStudentSession(): StudentSessionValue { + const value = useContext(StudentSessionContext); + if (!value) throw new Error("useStudentSession must be used inside StudentSessionProvider"); + return value; +} diff --git a/src/student/StudentShell.tsx b/src/student/StudentShell.tsx index 6ad086a..2f42abb 100644 --- a/src/student/StudentShell.tsx +++ b/src/student/StudentShell.tsx @@ -1,44 +1,107 @@ -import { useEffect, useState } from 'react'; -import { Link } from 'react-router'; -import { Clock3, CloudOff, LockKeyhole, Settings, ShieldCheck } from 'lucide-react'; -import { backofficeApi } from '../api'; -import { useRuntime } from '../app/RuntimeProvider'; -import { SitePreview } from '../shared/SitePreview'; -import { NotFoundPage } from '../shared/StatusPages'; +import { Clock3, CloudOff, LockKeyhole, ShieldCheck } from "lucide-react"; +import { lazy, Suspense, type ReactNode } from "react"; +import { Navigate, Route, Routes, useLocation } from "react-router"; +import { useRuntime } from "../app/RuntimeProvider"; +import { FullScreenLoading, NotFoundPage } from "../shared/StatusPages"; +import { StudentLayout } from "./components/StudentLayout"; +import { StudentSessionProvider, useStudentSession } from "./StudentSession"; +import { getStudentFeature, isStudentFeatureAvailable } from "./features"; + +const PublicLandingPage = lazy(() => import("./pages/PublicLandingPage")); +const StudentLoginPage = lazy(() => import("./pages/StudentLoginPage")); +const ResetPasswordPage = lazy(() => import("./pages/ResetPasswordPage")); +const RegionSelectorPage = lazy(() => import("./pages/RegionSelectorPage")); +const DashboardPage = lazy(() => import("./pages/DashboardPage")); +const SubjectsPage = lazy(() => import("./pages/SubjectsPage")); +const SubjectDetailPage = lazy(() => import("./pages/SubjectDetailPage")); +const QuizPage = lazy(() => import("./pages/QuizPage")); +const PracticeReportPage = lazy(() => import("./pages/PracticeReportPage")); +const CollectionsPage = lazy(() => import("./pages/CollectionsPage")); +const ServicesPage = lazy(() => import("./pages/ServicesPage")); +const ProfilePage = lazy(() => import("./pages/ProfilePage")); +const FeaturePlaceholderPage = lazy(() => import("./pages/FeaturePlaceholderPage")); +const VocabularyPage = lazy(() => import("./pages/VocabularyPage")); +const VocabularyUnitPage = lazy(() => import("./pages/VocabularyUnitPage")); +const HandbookPage = lazy(() => import("./pages/HandbookPage")); +const HandbookChaptersPage = lazy(() => import("./pages/HandbookChaptersPage")); +const HandbookEntriesPage = lazy(() => import("./pages/HandbookEntriesPage")); +const HandbookEntryReaderPage = lazy(() => import("./pages/HandbookEntryReaderPage")); +const ScorelinePage = lazy(() => import("./pages/ScorelinePage")); function StatePage({ icon: Icon, title, detail }: { icon: typeof Clock3; title: string; detail: string }) { const { runtime } = useRuntime(); - return ( -
-
-
-

{runtime!.branding.brandName}

-

{title}

-

{detail}

-
该站点由平台安全托管
-
-
- ); + return

{runtime!.branding.brandName}

{title}

{detail}
该站点由平台安全托管
; +} + +function Protected({ children, requireRegion = true, layout = true, feature }: { children: ReactNode; requireRegion?: boolean; layout?: boolean; feature?: string }) { + const location = useLocation(); + const { runtime } = useRuntime(); + const { authenticated, loading, profile, error } = useStudentSession(); + if (loading) return ; + if (error) return

{error.message}

; + if (!authenticated) return ; + if (requireRegion && !profile?.regionId) return ; + if (feature && runtime && !isStudentFeatureAvailable(runtime, feature)) { + const registered = getStudentFeature(runtime, feature); + if (!registered) return ; + const placeholder = ; + return layout ? {placeholder} : placeholder; + } + return layout ? {children} : children; +} + +function HomeRoute() { + const { runtime } = useRuntime(); + const { authenticated, loading, profile } = useStudentSession(); + if (loading) return ; + if (!authenticated) return ; + if (!profile?.regionId) return ; + if (!runtime || !isStudentFeatureAvailable(runtime, "dashboard")) return ; + return ; +} + +function RegisteredFeatureRoute({ code }: { code: string }) { + const { runtime } = useRuntime(); + if (!runtime) return ; + const feature = getStudentFeature(runtime, code); + if (!feature) return ; + return ; +} + +function ActiveSiteRoutes() { + return }> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + ; } export default function StudentShell() { const { runtime } = useRuntime(); - const [canManage, setCanManage] = useState(false); - - useEffect(() => { - backofficeApi.bootstrap().then(value => setCanManage(value.permissions.length > 0)).catch(() => setCanManage(false)); - }, []); - if (!runtime) return ; - if (runtime.siteState === 'domain_pending') return ; - if (runtime.siteState === 'setup_required') return ; - if (runtime.siteState === 'ready_to_launch') return ; - if (runtime.siteState === 'suspended') return ; - - return ( -
- - {canManage && 管理后台} -
- ); + if (runtime.siteState === "domain_pending") return ; + if (runtime.siteState === "setup_required") return ; + if (runtime.siteState === "ready_to_launch") return ; + if (runtime.siteState === "suspended") return ; + return ; } diff --git a/src/student/components/StudentLayout.tsx b/src/student/components/StudentLayout.tsx new file mode 100644 index 0000000..e88ed14 --- /dev/null +++ b/src/student/components/StudentLayout.tsx @@ -0,0 +1,39 @@ +import { MapPin } from "lucide-react"; +import { useEffect, useState, type ReactNode } from "react"; +import { Link, useLocation, useNavigate } from "react-router"; +import { authApi } from "../../api"; +import { useRuntime } from "../../app/RuntimeProvider"; +import { useStudentSession } from "../StudentSession"; +import { StudentMobileDock, StudentSidebar } from "./StudentNavigation"; + +const COLLAPSED_KEY = "tiku-saas-student-sidebar-collapsed"; + +export function StudentLayout({ children }: { children: ReactNode }) { + const { runtime, assets } = useRuntime(); + const { profile } = useStudentSession(); + const location = useLocation(); + const navigate = useNavigate(); + const [collapsed, setCollapsed] = useState(() => window.localStorage.getItem(COLLAPSED_KEY) === "1"); + const focusedRoute = location.pathname === "/quiz"; + + useEffect(() => { window.localStorage.setItem(COLLAPSED_KEY, collapsed ? "1" : "0"); }, [collapsed]); + if (!runtime) return null; + + const logout = async () => { + await authApi.logout(); + navigate("/", { replace: true }); + window.location.reload(); + }; + + return
+ 跳到主要内容 + {!focusedRoute && setCollapsed((value) => !value)} onLogout={() => void logout()} />} + ; +} diff --git a/src/student/components/StudentNavigation.tsx b/src/student/components/StudentNavigation.tsx new file mode 100644 index 0000000..ee7a7fd --- /dev/null +++ b/src/student/components/StudentNavigation.tsx @@ -0,0 +1,57 @@ +import { LogOut, PanelLeftClose, PanelLeftOpen, Settings } from "lucide-react"; +import { NavLink } from "react-router"; +import type { ResolvedThemeAssets, TenantRuntimeBootstrap } from "../../contracts"; +import type { StudentProfile } from "../../api/types"; +import { mobileStudentFeatures, publishedStudentFeatures, studentNavigationGroups } from "../features"; + +interface NavigationProps { + runtime: TenantRuntimeBootstrap; + assets: ResolvedThemeAssets; + profile: StudentProfile | null; + collapsed: boolean; + onToggle: () => void; + onLogout: () => void; +} + +function FeatureLink({ feature, mobile = false }: { feature: ReturnType[number]; mobile?: boolean }) { + const Icon = feature.icon; + return mobile ? (isActive ? "is-active" : "") : `student-nav-link ${isActive ? "is-active" : ""}`}> + {mobile ? feature.shortLabel || feature.label : feature.label} + {!mobile && feature.status === "placeholder" && 建设中} + ; +} + +export function StudentSidebar({ runtime, assets, profile, collapsed, onToggle, onLogout }: NavigationProps) { + const features = publishedStudentFeatures(runtime); + const role = profile?.primaryRole?.toLowerCase() ?? ""; + const canEnterBackoffice = role.includes("owner") || role.includes("admin"); + const displayName = profile?.name || profile?.username || "同学"; + return ; +} + +export function StudentMobileDock({ runtime }: { runtime: TenantRuntimeBootstrap }) { + return ; +} diff --git a/src/student/developmentCatalog.ts b/src/student/developmentCatalog.ts new file mode 100644 index 0000000..ee9b7a0 --- /dev/null +++ b/src/student/developmentCatalog.ts @@ -0,0 +1,35 @@ +import type { Region, StudentProfile } from "../api/types"; + +const DEVELOPMENT_REGION_STORAGE_KEY = "tiku-saas-development-region"; + +export const developmentRegion: Region = { + id: "10000000-0000-0000-0000-000000000002", + legacyId: null, + name: "天津", + shortName: "津", + fullName: "天津市", + icon: null, + pinyin: "tianjin", + code: "120000", + isHot: true, + order: 0, +}; + +export function withDevelopmentRegionFallback(items: Region[], enabled = import.meta.env.DEV): Region[] { + return enabled && items.length === 0 ? [developmentRegion] : items; +} + +export function isDevelopmentRegion(regionId: string): boolean { + return regionId === developmentRegion.id; +} + +export function rememberDevelopmentRegion(): void { + if (import.meta.env.DEV) window.sessionStorage.setItem(DEVELOPMENT_REGION_STORAGE_KEY, developmentRegion.id); +} + +export function applyRememberedDevelopmentRegion(profile: StudentProfile): StudentProfile { + if (!import.meta.env.DEV || profile.regionId || window.sessionStorage.getItem(DEVELOPMENT_REGION_STORAGE_KEY) !== developmentRegion.id) { + return profile; + } + return { ...profile, regionId: developmentRegion.id, regionName: `${developmentRegion.name}(演示)` }; +} diff --git a/src/student/features.ts b/src/student/features.ts new file mode 100644 index 0000000..0a966ff --- /dev/null +++ b/src/student/features.ts @@ -0,0 +1,100 @@ +import { + BadgeHelp, + BookMarked, + BookOpen, + ChartNoAxesCombined, + CodeXml, + Compass, + FileText, + GraduationCap, + KeyRound, + LayoutGrid, + ShoppingBag, + UserRound, + type LucideIcon, +} from "lucide-react"; +import type { NavigationItem, TenantRuntimeBootstrap } from "../contracts"; + +export type StudentFeatureStatus = "live" | "placeholder" | "hidden"; +export type StudentPlaceholderReason = "frontend_pending" | "backend_missing" | "tenant_disabled"; +export type StudentNavigationGroup = "learning" | "specialized" | "planning" | "account"; + +export interface StudentFeature { + code: string; + label: string; + shortLabel?: string; + path: string; + group: StudentNavigationGroup; + requiredFeature?: string; + implementation: "ready" | "frontend_pending" | "backend_missing"; + icon: LucideIcon; + mobileOrder?: number; + sidebar?: boolean; + description: string; +} + +export interface ResolvedStudentFeature extends StudentFeature { + status: StudentFeatureStatus; + placeholderReason?: StudentPlaceholderReason; +} + +export const studentNavigationGroups: Array<{ code: StudentNavigationGroup; label: string }> = [ + { code: "learning", label: "学习" }, + { code: "specialized", label: "专项能力" }, + { code: "planning", label: "升学服务" }, + { code: "account", label: "账户" }, +]; + +export const studentFeatures: StudentFeature[] = [ + { code: "dashboard", label: "学习工作台", shortLabel: "首页", path: "/", group: "learning", implementation: "ready", icon: LayoutGrid, mobileOrder: 1, sidebar: true, description: "今日任务、学习进度和继续学习" }, + { code: "practice", label: "题库练习", shortLabel: "题库", path: "/subjects", group: "learning", requiredFeature: "learning.practice", implementation: "ready", icon: BookOpen, mobileOrder: 2, sidebar: true, description: "按科目和章节开始练习" }, + { code: "collections", label: "错题收藏", shortLabel: "复习", path: "/collections", group: "learning", requiredFeature: "learning.practice", implementation: "ready", icon: BookMarked, mobileOrder: 3, sidebar: true, description: "集中复习错题和收藏题" }, + { code: "vocabulary", label: "背单词", path: "/vocabulary", group: "specialized", requiredFeature: "content.vocabulary", implementation: "ready", icon: GraduationCap, sidebar: true, description: "词汇单元、记忆进度和收藏复习" }, + { code: "handbook", label: "知识手册", path: "/handbook", group: "specialized", requiredFeature: "content.handbook", implementation: "ready", icon: FileText, sidebar: true, description: "按科目与章节阅读知识要点" }, + { code: "store", label: "学习商城", path: "/store", group: "specialized", requiredFeature: "commerce.student_store", implementation: "frontend_pending", icon: ShoppingBag, sidebar: true, description: "课程套餐、订单和优惠权益" }, + { code: "scoreline", label: "院校分数线", path: "/scoreline", group: "planning", requiredFeature: "content.scoreline", implementation: "ready", icon: ChartNoAxesCombined, sidebar: true, description: "历年院校与专业分数线" }, + { code: "school-planning", label: "择校规划", path: "/school-planning", group: "planning", requiredFeature: "planning.school", implementation: "backend_missing", icon: Compass, sidebar: true, description: "根据目标和成绩生成择校建议" }, + { code: "profile", label: "个人中心", shortLabel: "我的", path: "/profile", group: "account", implementation: "ready", icon: UserRound, mobileOrder: 5, sidebar: true, description: "账户资料、学习数据和会员权益" }, + { code: "services", label: "学习服务", shortLabel: "服务", path: "/services", group: "specialized", implementation: "ready", icon: BadgeHelp, mobileOrder: 4, sidebar: false, description: "查看全部学习与升学服务" }, + { code: "activation-code", label: "激活码", path: "/activation-code", group: "account", requiredFeature: "commerce.activation.student", implementation: "backend_missing", icon: KeyRound, sidebar: false, description: "学生自助核销学习权益" }, + { code: "code-runner", label: "代码运行器", path: "/code-runner", group: "specialized", requiredFeature: "learning.code_runner", implementation: "backend_missing", icon: CodeXml, sidebar: false, description: "安全运行编程题代码" }, +]; + +export const knownStudentNavigation = (): NavigationItem[] => studentFeatures + .filter((feature) => feature.sidebar) + .map((feature) => ({ id: feature.code, label: feature.label, href: feature.path, visible: true })); + +export function normalizeStudentNavigation(items: NavigationItem[]): NavigationItem[] { + const configured = new Map(items.map((item) => [item.href, item])); + return knownStudentNavigation().map((fallback) => configured.get(fallback.href) ?? fallback); +} + +export function resolveStudentFeatures(runtime: TenantRuntimeBootstrap): ResolvedStudentFeature[] { + const navigation = normalizeStudentNavigation(runtime.navigation); + return studentFeatures.reduce((resolved, feature) => { + const configured = feature.sidebar ? navigation.find((item) => item.href === feature.path) : undefined; + if (configured && !configured.visible) return resolved; + const label = configured?.label || feature.label; + if (feature.implementation === "backend_missing") resolved.push({ ...feature, label, status: "placeholder", placeholderReason: "backend_missing" }); + else if (feature.implementation === "frontend_pending") resolved.push({ ...feature, label, status: "placeholder", placeholderReason: "frontend_pending" }); + else if (feature.requiredFeature && !runtime.enabledFeatures.includes(feature.requiredFeature)) resolved.push({ ...feature, label, status: "placeholder", placeholderReason: "tenant_disabled" }); + else resolved.push({ ...feature, label, status: "live" }); + return resolved; + }, []); +} + +export function publishedStudentFeatures(runtime: TenantRuntimeBootstrap) { + return resolveStudentFeatures(runtime).filter((feature) => feature.sidebar); +} + +export function mobileStudentFeatures(runtime: TenantRuntimeBootstrap) { + return resolveStudentFeatures(runtime).filter((feature) => feature.mobileOrder).sort((a, b) => a.mobileOrder! - b.mobileOrder!).slice(0, 5); +} + +export function getStudentFeature(runtime: TenantRuntimeBootstrap, code: string) { + return resolveStudentFeatures(runtime).find((feature) => feature.code === code); +} + +export function isStudentFeatureAvailable(runtime: TenantRuntimeBootstrap, code: string): boolean { + return getStudentFeature(runtime, code)?.status === "live"; +} diff --git a/src/student/pages/CollectionsPage.tsx b/src/student/pages/CollectionsPage.tsx new file mode 100644 index 0000000..1349dc1 --- /dev/null +++ b/src/student/pages/CollectionsPage.tsx @@ -0,0 +1,17 @@ +import { ArrowRight, Bookmark, Heart, LoaderCircle, RotateCcw } from "lucide-react"; +import { useMutation, useQuery } from "@tanstack/react-query"; +import { useState } from "react"; +import { useNavigate } from "react-router"; +import { learningApi, queryKeys } from "../../api"; +import { numeric } from "../../shared/number"; + +export default function CollectionsPage() { + const navigate = useNavigate(); + const [tab, setTab] = useState<"wrong" | "favorite">("wrong"); + const wrong = useQuery({ queryKey: queryKeys.wrongQuestions, queryFn: learningApi.wrongQuestions }); + const favorites = useQuery({ queryKey: queryKeys.favorites, queryFn: learningApi.favorites }); + const start = useMutation({ mutationFn: (mode: string) => learningApi.createSession({ mode, questionLimit: 50 }), onSuccess: (session) => navigate(`/quiz?sessionId=${session.id}`) }); + const items = tab === "wrong" ? wrong.data?.items ?? [] : favorites.data?.items ?? []; + const loading = tab === "wrong" ? wrong.isLoading : favorites.isLoading; + return

REVIEW CENTER

错题与收藏

把薄弱点变成下一组明确的复习任务。

{loading ?
: items.length ?
{items.map((item) =>
{tab === "wrong" ? : }
题目 {item.locator.questionId.slice(0, 8)}

{tab === "wrong" ? `累计答错 ${numeric("wrongCount" in item ? item.wrongCount : 0)} 次` : `收藏于 ${new Date("createdAt" in item ? item.createdAt : Date.now()).toLocaleDateString("zh-CN")}`}

)}
:
这里还没有内容。完成练习后,错题和收藏会自动沉淀在这里。
}{start.error &&

{start.error.message}

}
; +} diff --git a/src/student/pages/DashboardPage.tsx b/src/student/pages/DashboardPage.tsx new file mode 100644 index 0000000..cb2c8a2 --- /dev/null +++ b/src/student/pages/DashboardPage.tsx @@ -0,0 +1,62 @@ +import { ArrowRight, BookMarked, BookOpen, BookOpenCheck, CalendarDays, CheckCircle2, Clock3, FileText, Flame, GraduationCap, Heart, Megaphone, Target } from "lucide-react"; +import { useQuery } from "@tanstack/react-query"; +import { Link } from "react-router"; +import { catalogApi, learningApi, profileApi, queryKeys } from "../../api"; +import { numeric, percent } from "../../shared/number"; +import { useStudentSession } from "../StudentSession"; +import { useRuntime } from "../../app/RuntimeProvider"; +import { getStudentFeature } from "../features"; + +function Metric({ label, value, icon: Icon, tone }: { label: string; value: string; icon: typeof Target; tone: string }) { + return
{label}{value}
; +} + +export default function DashboardPage() { + const { profile } = useStudentSession(); + const { runtime } = useRuntime(); + const regionId = profile?.regionId; + const stats = useQuery({ queryKey: [...queryKeys.dashboard, "stats"], queryFn: learningApi.stats }); + const trend = useQuery({ queryKey: [...queryKeys.dashboard, "trend"], queryFn: learningApi.trend }); + const countdowns = useQuery({ queryKey: [...queryKeys.dashboard, "countdowns"], queryFn: profileApi.countdowns }); + const banners = useQuery({ queryKey: [...queryKeys.dashboard, "banners", regionId], queryFn: () => catalogApi.banners(regionId) }); + const announcements = useQuery({ queryKey: [...queryKeys.dashboard, "announcements", regionId], queryFn: () => catalogApi.announcements(regionId) }); + const answerCount = numeric(stats.data?.answerCount); + const accuracy = answerCount ? numeric(stats.data?.correctCount) / answerCount : 0; + const trendItems = trend.data?.items ?? []; + const maxTrend = Math.max(1, ...trendItems.map((item) => numeric(item.answerCount))); + const banner = banners.data?.items.find((item) => item.isActive); + const countdown = countdowns.data?.items[0]; + const quickServices = [ + { code: "practice", title: "章节练习", detail: "按科目进入题库", path: "/subjects", icon: BookOpen, tone: "blue" }, + { code: "collections", title: "错题复习", detail: "集中解决薄弱项", path: "/collections", icon: BookMarked, tone: "rose" }, + { code: "vocabulary", title: "核心词汇", detail: "按单元巩固记忆", path: "/vocabulary", icon: GraduationCap, tone: "amber" }, + { code: "handbook", title: "知识手册", detail: "考前重点快速查", path: "/handbook", icon: FileText, tone: "green" }, + ].filter((item) => runtime && getStudentFeature(runtime, item.code)); + + return
+

TODAY'S FOCUS

你好,{profile?.name || profile?.username || "同学"}

保持节奏,今天的每一次练习都会沉淀为下一次进步。

开始练习
+
+
今日学习计划

{banner?.title || "专注完成一组练习,再认真复盘一次"}

{banner?.subtitle || "系统会保存你的进度,客观题由服务端判分,错题自动进入复习清单。"}

{banner?.buttonText || "继续学习"}
+
{countdown?.daysLeft === null || countdown?.daysLeft === undefined ? "--" : numeric(countdown.daysLeft)}{countdown?.examName || "目标考试"}倒计时
+
+
{quickServices.map((service) => { const Icon = service.icon; return
{service.title}{service.detail}
; })}
+
+ + + + +
+
+

LEARNING RHYTHM

近期学习节奏

+ {trend.isLoading ?
: trendItems.length ?
{trendItems.map((item) => )}
:
完成第一组练习后,这里会出现学习趋势。
} +
+

CONTINUE

继续学习

+ {profile?.recentPractices.length ?
{profile.recentPractices.slice(0, 4).map((item) => {item.targetName || "未完成练习"}{item.practiceType || "练习"}{numeric(item.progress)}%)}
:
还没有未完成练习,从科目中心开始吧。
} +
+
+

UPDATES

公告与提醒

+
{(announcements.data?.items ?? []).filter((item) => item.isActive).slice(0, 4).map((item) =>

{item.content || "学习内容已更新"}

)}
+ {!announcements.isLoading && !(announcements.data?.items.length) &&
当前没有新公告。
} +
+
; +} diff --git a/src/student/pages/FeaturePlaceholderPage.tsx b/src/student/pages/FeaturePlaceholderPage.tsx new file mode 100644 index 0000000..010f4c0 --- /dev/null +++ b/src/student/pages/FeaturePlaceholderPage.tsx @@ -0,0 +1,16 @@ +import { ArrowLeft, Construction, DatabaseZap, ShieldAlert } from "lucide-react"; +import { Link } from "react-router"; +import type { ResolvedStudentFeature, StudentPlaceholderReason } from "../features"; + +const reasonContent: Record = { + frontend_pending: { title: "页面正在迁移", detail: "后端能力已经具备,学生端正在按旧版体验完成高保真迁移。", icon: Construction }, + backend_missing: { title: "等待服务能力接入", detail: "当前后端还没有完整业务契约,页面不会调用猜测接口或生成虚假结果。", icon: DatabaseZap }, + tenant_disabled: { title: "当前机构暂未开通", detail: "该服务尚未包含在当前机构的产品版本中,如有需要请联系机构老师。", icon: ShieldAlert }, +}; + +export default function FeaturePlaceholderPage({ feature }: { feature: ResolvedStudentFeature }) { + const reason = feature.placeholderReason ?? "frontend_pending"; + const content = reasonContent[reason]; + const Icon = content.icon; + return

{feature.group.toUpperCase()} SERVICE

{feature.label}

{content.title}

{feature.description}。{content.detail}

查看其他学习服务 返回学习工作台
; +} diff --git a/src/student/pages/HandbookChaptersPage.tsx b/src/student/pages/HandbookChaptersPage.tsx new file mode 100644 index 0000000..e6efdc9 --- /dev/null +++ b/src/student/pages/HandbookChaptersPage.tsx @@ -0,0 +1,10 @@ +import { ArrowLeft, ArrowRight } from "lucide-react"; +import { useQuery } from "@tanstack/react-query"; +import { Link, useParams } from "react-router"; +import { catalogApi, queryKeys } from "../../api"; + +export default function HandbookChaptersPage() { + const subjectId = useParams().subjectId ?? ""; + const query = useQuery({ queryKey: queryKeys.handbookChapters(subjectId), queryFn: () => catalogApi.handbookChapters(subjectId), enabled: Boolean(subjectId) }); + return
返回知识手册

HANDBOOK CHAPTERS

选择章节

按章节阅读重点知识和考点总结。

{query.isLoading ?
: query.data?.items.length ?
{query.data.items.map((item, index) => {String(index + 1).padStart(2, "0")}
{item.name}

{item.description || "查看本章知识条目"}

)}
:
该科目还没有发布章节。
}
; +} diff --git a/src/student/pages/HandbookEntriesPage.tsx b/src/student/pages/HandbookEntriesPage.tsx new file mode 100644 index 0000000..d9e0150 --- /dev/null +++ b/src/student/pages/HandbookEntriesPage.tsx @@ -0,0 +1,10 @@ +import { ArrowLeft, ArrowRight } from "lucide-react"; +import { useQuery } from "@tanstack/react-query"; +import { Link, useParams } from "react-router"; +import { catalogApi, queryKeys } from "../../api"; + +export default function HandbookEntriesPage() { + const chapterId = useParams().chapterId ?? ""; + const query = useQuery({ queryKey: queryKeys.handbookEntries(chapterId), queryFn: () => catalogApi.handbookEntries(chapterId, true), enabled: Boolean(chapterId) }); + return
返回知识手册

KNOWLEDGE ENTRIES

知识条目

{query.isLoading ?
: query.data?.items.length ?
{query.data.items.map((item, index) => {String(index + 1).padStart(2, "0")}
{item.title}

{item.summary || "阅读完整内容"}

)}
:
本章还没有发布知识条目。
}
; +} diff --git a/src/student/pages/HandbookEntryReaderPage.tsx b/src/student/pages/HandbookEntryReaderPage.tsx new file mode 100644 index 0000000..a6021aa --- /dev/null +++ b/src/student/pages/HandbookEntryReaderPage.tsx @@ -0,0 +1,11 @@ +import { ArrowLeft } from "lucide-react"; +import { Link, useLocation, useParams } from "react-router"; +import type { components } from "../../api/schema.generated"; +import { SafeMarkdown } from "../../shared/SafeMarkdown"; + +type Entry = components["schemas"]["HandbookEntryCatalogItem"]; +export default function HandbookEntryReaderPage() { + const entryId = useParams().entryId; + const entry = (useLocation().state as { entry?: Entry } | null)?.entry; + return
返回知识手册{entry && entry.id === entryId ? <>

KNOWLEDGE ENTRY

{entry.title}

{entry.summary}

{entry.content || "该条目暂未发布正文。"} :
请从知识手册章节进入该条目。
}
; +} diff --git a/src/student/pages/HandbookPage.tsx b/src/student/pages/HandbookPage.tsx new file mode 100644 index 0000000..4468782 --- /dev/null +++ b/src/student/pages/HandbookPage.tsx @@ -0,0 +1,11 @@ +import { ArrowRight, FileText } from "lucide-react"; +import { useQuery } from "@tanstack/react-query"; +import { Link } from "react-router"; +import { catalogApi, queryKeys } from "../../api"; +import { useStudentSession } from "../StudentSession"; + +export default function HandbookPage() { + const { profile } = useStudentSession(); + const query = useQuery({ queryKey: queryKeys.handbookSubjects(profile?.regionId), queryFn: () => catalogApi.handbookSubjects(profile?.regionId) }); + return

KNOWLEDGE HANDBOOK

知识手册

按科目梳理知识体系,考前快速定位重点内容。

{query.isLoading ?
: query.isError ?

知识手册加载失败。

: query.data?.items.length ?
{query.data.items.map((item) =>
HANDBOOK SUBJECT

{item.name}

{item.description || "查看章节和知识条目。"}

)}
:
当前地区还没有发布知识手册。
}
; +} diff --git a/src/student/pages/PracticeReportPage.tsx b/src/student/pages/PracticeReportPage.tsx new file mode 100644 index 0000000..6bedac9 --- /dev/null +++ b/src/student/pages/PracticeReportPage.tsx @@ -0,0 +1,14 @@ +import { ArrowRight, CheckCircle2, Clock3, RotateCcw, Target, TriangleAlert } from "lucide-react"; +import { useQuery } from "@tanstack/react-query"; +import { Link, useParams } from "react-router"; +import { learningApi, queryKeys } from "../../api"; +import { numeric, percent } from "../../shared/number"; + +export default function PracticeReportPage() { + const { sessionId = "" } = useParams(); + const report = useQuery({ queryKey: queryKeys.practiceReport(sessionId), queryFn: () => learningApi.report(sessionId), enabled: Boolean(sessionId) }); + if (report.isLoading) return
正在生成练习报告…
; + if (report.isError || !report.data) return

{report.error?.message || "报告加载失败。"}

; + const item = report.data; + return

PRACTICE REPORT

{numeric(item.pendingReviewCount) ? "练习已提交,部分题目待审核" : "本次练习已完成"}

结果来自服务端锁定的题目版本与判分规则。

{Math.round(numeric(item.score))}/ {numeric(item.totalScore)} 分

正确率 {percent(item.accuracy)}

答对{numeric(item.correctCount)}
答错{numeric(item.wrongCount)}
待审核{numeric(item.pendingReviewCount)}
用时{Math.ceil(numeric(item.durationSeconds) / 60)} 分钟
{numeric(item.pendingReviewCount) > 0 &&
主观题正在等待审核

当前分数不是最终结果,审核完成后报告状态会更新。

}
复盘错题继续学习
; +} diff --git a/src/student/pages/ProfilePage.tsx b/src/student/pages/ProfilePage.tsx new file mode 100644 index 0000000..5fbb83d --- /dev/null +++ b/src/student/pages/ProfilePage.tsx @@ -0,0 +1,14 @@ +import { Award, BookOpenCheck, CalendarDays, ChevronRight, MapPin, UserRound } from "lucide-react"; +import { Link } from "react-router"; +import { numeric } from "../../shared/number"; +import { useStudentSession } from "../StudentSession"; + +export default function ProfilePage() { + const { profile } = useStudentSession(); + if (!profile) return null; + const name = profile.name || profile.username || "同学"; + return
{name.slice(0, 1)}

个人中心

{name}

{profile.membership?.isSvip ? "SVIP 学员" : "普通会员"}
+
当前积分{numeric(profile.score)}
今日答题{numeric(profile.questionsAnsweredToday)}
掌握词汇{numeric(profile.masteredWordsCount)}
+
报考地区{profile.regionName || "尚未选择"}学习服务查看机构提供的全部能力
+
; +} diff --git a/src/student/pages/PublicLandingPage.tsx b/src/student/pages/PublicLandingPage.tsx new file mode 100644 index 0000000..78968c4 --- /dev/null +++ b/src/student/pages/PublicLandingPage.tsx @@ -0,0 +1,35 @@ +import { ArrowRight, BookOpenCheck, Layers3, ShieldCheck } from "lucide-react"; +import { Link } from "react-router"; +import { useRuntime } from "../../app/RuntimeProvider"; + +export default function PublicLandingPage() { + const { runtime, assets } = useRuntime(); + if (!runtime) return null; + return ( +
+
+ + {assets.logo ? {runtime.branding.assetAlt?.logo : {runtime.branding.shortName.slice(0, 1)}} + {runtime.branding.brandName} + + 登录学习 +
+
+
+
+

TENANT LEARNING SPACE

+

{runtime.branding.slogan || "把每一步学习,变成看得见的进步"}

+

题库练习、错题复盘和学习趋势汇聚在一个清晰、可信赖的学习空间。

+
开始学习 由平台安全托管
+
+
{assets.hero ? {runtime.branding.assetAlt?.hero : <>}
+
+
+

真实学习闭环

从科目选择到练习报告,每一步都由服务端记录与判分。

+

清晰内容路径

按地区、科目和章节组织内容,快速找到当前学习目标。

+

专属租户空间

品牌、内容和学习数据按机构边界安全隔离。

+
+
+
+ ); +} diff --git a/src/student/pages/QuizPage.tsx b/src/student/pages/QuizPage.tsx new file mode 100644 index 0000000..a5a313c --- /dev/null +++ b/src/student/pages/QuizPage.tsx @@ -0,0 +1,112 @@ +import { ArrowLeft, ArrowRight, Bookmark, Check, ChevronLeft, ChevronRight, Clock3, Flag, LoaderCircle, Send } from "lucide-react"; +import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; +import { useEffect, useMemo, useState } from "react"; +import { Link, useNavigate, useSearchParams } from "react-router"; +import { learningApi, queryKeys } from "../../api"; +import type { AnswerRecord, PracticeQuestion } from "../../api/types"; +import { SafeMarkdown } from "../../shared/SafeMarkdown"; +import { numeric } from "../../shared/number"; + +interface ParsedOption { key: string; content: string } +function parseOptions(value: unknown): ParsedOption[] { + if (!Array.isArray(value)) return []; + return value.map((item, index) => { + if (typeof item === "string") return { key: String(index), content: item }; + if (item && typeof item === "object") { + const record = item as Record; + return { key: String(record.key ?? record.label ?? index), content: String(record.content ?? record.text ?? record.value ?? "") }; + } + return { key: String(index), content: String(item ?? "") }; + }); +} + +function QuestionAnswer({ question, existing, version, sequence, onAccepted }: { + question: PracticeQuestion; + existing?: AnswerRecord; + version: number; + sequence: number; + onAccepted: (answer: AnswerRecord) => void; +}) { + const options = useMemo(() => parseOptions(question.options), [question.options]); + const isMultiple = /multiple|多选/i.test(question.type); + const [selected, setSelected] = useState([]); + const [text, setText] = useState(""); + const answer = useMutation({ + mutationFn: () => learningApi.submitAnswer({ + sessionQuestionId: question.sessionQuestionId, + expectedSessionVersion: version, + clientSequence: sequence, + idempotencyKey: crypto.randomUUID(), + selectedOptionIndices: options.length ? selected : undefined, + answerText: options.length ? undefined : text, + }), + onSuccess: onAccepted, + }); + const toggle = (index: number) => setSelected((current) => isMultiple + ? current.includes(index) ? current.filter((value) => value !== index) : [...current, index] + : [index]); + const disabled = answer.isPending || Boolean(existing); + return
+ {options.length ?
{options.map((option, index) => )}
: