+
diff --git a/Tiku.Api/wwwroot/.gitkeep b/Tiku.Api/wwwroot/.gitkeep
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/Tiku.Api/wwwroot/.gitkeep
@@ -0,0 +1 @@
+
diff --git a/Tiku.Api/wwwroot/platform-admin/app.js b/Tiku.Api/wwwroot/platform-admin/app.js
deleted file mode 100644
index 58a7bfd..0000000
--- a/Tiku.Api/wwwroot/platform-admin/app.js
+++ /dev/null
@@ -1,1756 +0,0 @@
-const mainView = document.querySelector('#mainView');
-const sideNav = document.querySelector('#sideNav');
-const pageTitle = document.querySelector('#pageTitle');
-const toast = document.querySelector('.toast');
-const app = document.querySelector('.platform-app');
-const overlayRoot = document.querySelector('#overlayRoot');
-const roleSelect = document.querySelector('#roleSelect');
-const scenarioSelect = document.querySelector('#scenarioSelect');
-const responseSelect = document.querySelector('#responseSelect');
-const menuButton = document.querySelector('#menuButton');
-const taskCount = document.querySelector('#taskCount');
-const alertCount = document.querySelector('#alertCount');
-const platformApi = window.GongxuePlatformApi;
-const STORAGE_KEY = 'gongxue-platform-spec-v1.1';
-const TENANT_PORTAL_ORIGIN = 'http://127.0.0.1:4174/';
-const HISTORY_APP_KEY = 'gongxuePlatform';
-const API_CONNECTED_PAGES = new Set([
- 'overview',
- 'tenants',
- 'domains',
- 'tenantDetail',
- 'billingProfile',
- 'subscriptions',
- 'catalog',
- 'saasFinance',
- 'billing',
- 'usage',
- 'dunning',
- 'bank',
- 'crm',
- 'sms',
- 'paymentSettings',
- 'staff',
- 'roles',
- 'audit',
- 'alerts',
-]);
-
-const pageMeta = {
- overview: { id: 'P-01', title: '平台经营工作台', permission: 'platform:overview:read' },
- tenants: { id: 'P-02', title: '租户列表与创建', permission: 'platform:tenant:read' },
- domains: { id: 'P-02A', title: '租户域名与证书', permission: 'platform:tenant:read' },
- tenantDetail: { id: 'P-03', title: '租户详情与生命周期', permission: 'platform:tenant:read', level: 2 },
- billingProfile: { id: 'P-04', title: '租户账务资料', permission: 'platform:tenant:billing_profile', level: 3 },
- subscriptions: { id: 'P-05', title: 'SaaS 套餐与订阅', permission: 'platform:plan:read' },
- catalog: { id: 'P-05A', title: 'SaaS 商品与版本', permission: 'platform:plan:read' },
- saasFinance: { id: 'P-05B', title: 'SaaS 订单与交易', permission: 'platform:billing:read' },
- billing: { id: 'P-06', title: '服务费账单', permission: 'platform:billing:read' },
- usage: { id: 'P-07', title: '用量与超额计费', permission: 'platform:usage:read' },
- dunning: { id: 'P-08', title: '收款、逾期与催缴', permission: 'platform:billing:read' },
- bank: { id: 'P-09', title: '公共题库', permission: 'platform:question-bank:manage' },
- crm: { id: 'P-10', title: 'CRM 接入与线索流转', permission: 'platform:crm:read' },
- sms: { id: 'P-11', title: 'SMS 短信服务', permission: 'platform:sms:read' },
- paymentSettings: { id: 'P-12', title: '支付设置', permission: 'platform:payment:read' },
- staff: { id: 'P-13', title: '平台员工与权限', permission: 'platform:staff:read' },
- roles: { id: 'P-13A', title: '平台角色与功能', permission: 'platform:staff:read' },
- audit: { id: 'P-14', title: '平台审计日志', permission: 'platform:audit:read' },
- alerts: { id: 'P-15', title: '审计告警与通知', permission: 'platform:audit:alert' },
-};
-
-const navGroups = [
- ['平台概览', [['overview', 'gauge', '经营工作台']]],
- ['租户管理', [['tenants', 'building-2', '租户列表'], ['domains', 'globe-2', '域名与证书']]],
- ['SaaS 商品与账务', [['catalog', 'packages', '商品与版本'], ['subscriptions', 'badge-check', '租户订阅'], ['saasFinance', 'landmark', '订单与交易'], ['billing', 'receipt-text', '服务费账单'], ['usage', 'chart-column-big', '用量与超额'], ['dunning', 'bell-ring', '收款与催缴']]],
- ['平台资产', [['bank', 'database-zap', '公共题库']]],
- ['租户能力', [['crm', 'handshake', 'CRM 接入'], ['sms', 'message-square-text', '短信服务'], ['paymentSettings', 'credit-card', '支付设置']]],
- ['安全治理', [['staff', 'user-cog', '平台员工'], ['roles', 'shield-check', '角色与功能'], ['audit', 'scroll-text', '审计日志'], ['alerts', 'shield-alert', '告警与通知']]],
-];
-
-const roleDefinitions = {
- super: { label: '超级管理员', permissions: ['*'] },
- tenant_ops: { label: '租户运营', permissions: ['platform:overview:read', 'platform:tenant:read', 'platform:tenant:write', 'platform:tenant:status', 'platform:tenant:billing_profile', 'platform:plan:read', 'platform:billing:read', 'platform:crm:read', 'platform:crm:write', 'platform:sms:read', 'platform:sms:write'] },
- finance: { label: '平台财务', permissions: ['platform:overview:read', 'platform:tenant:read', 'platform:tenant:billing_profile', 'platform:plan:read', 'platform:billing:read', 'platform:billing:write', 'platform:billing:payment', 'platform:billing:dunning', 'platform:billing:notification', 'platform:usage:read', 'platform:usage:write', 'platform:payment:read', 'platform:payment:write', 'platform:audit:read'] },
- audit: { label: '安全审计', permissions: ['platform:overview:read', 'platform:audit:read', 'platform:audit:export', 'platform:audit:alert', 'platform:audit:notification'] },
- bank_ops: { label: '题库运营', permissions: ['platform:dashboard:view', 'platform:question-bank:manage'] },
- readonly: { label: '只读观察员', permissions: ['platform:overview:read', 'platform:tenant:read', 'platform:plan:read', 'platform:billing:read', 'platform:crm:read', 'platform:sms:read', 'platform:payment:read', 'platform:audit:read'] },
-};
-
-const seed = {
- version: 11,
- tenants: [
- { id: 'tenant_gongxue_tj', slug: 'gongxue-tj', name: '恭学教育 · 天津', legal: '天津恭学教育科技有限公司', brand: '恭学教育', shortName: '恭学天津', host: 'study.gongxue.cn', plan: '旗舰版', planCode: 'enterprise', status: '正常', billing: '正常', mode: '正式', students: 2846, questions: 42680, storageGB: 186, trafficTB: 1.8, expires: '2027-07-22', balance: 0, owner: '张校长', ownerPhone: '138****6008', createdAt: '2025-07-22 10:18' },
- { id: 'tenant_qihang_gd', slug: 'qihang-gd', name: '启航专升本 · 广东', legal: '广州启航教育咨询有限公司', brand: '启航专升本', shortName: '启航广东', host: 'study.qihangzsb.cn', plan: '专业版', planCode: 'pro', status: '正常', billing: '待付款', mode: '正式', students: 5280, questions: 68420, storageGB: 248, trafficTB: 3.2, expires: '2026-08-05', balance: 12800, owner: '林老师', ownerPhone: '139****2288', createdAt: '2025-08-05 09:12' },
- { id: 'tenant_bosi_sd', slug: 'bosi-sd', name: '博思升本 · 山东', legal: '山东博思教育集团有限公司', brand: '博思升本', shortName: '博思山东', host: 'tiku.bosiedu.cn', plan: '基础版', planCode: 'basic', status: '试用', billing: '正常', mode: '试用', students: 642, questions: 12860, storageGB: 42, trafficTB: .6, expires: '2026-08-12', balance: 0, owner: '孙老师', ownerPhone: '136****1209', createdAt: '2026-07-12 14:20' },
- { id: 'tenant_mingtu_hn', slug: 'mingtu-hn', name: '明途教育 · 河南', legal: '郑州明途教育科技有限公司', brand: '明途教育', shortName: '明途河南', host: 'learn.mingtu.cn', plan: '基础版', planCode: 'basic', status: '暂停', billing: '逾期', mode: '正式', students: 1280, questions: 18620, storageGB: 86, trafficTB: .9, expires: '2026-07-18', balance: 8600, owner: '魏校长', ownerPhone: '135****8806', createdAt: '2025-01-18 11:03' },
- { id: 'tenant_xuezhi_heb', slug: 'xuezhi-heb', name: '学知专接本 · 河北', legal: '石家庄学知教育有限公司', brand: '学知专接本', shortName: '学知河北', host: 'app.xuezhizjb.cn', plan: '专业版', planCode: 'pro', status: '正常', billing: '正常', mode: '正式', students: 3160, questions: 39860, storageGB: 164, trafficTB: 2.1, expires: '2027-01-08', balance: 0, owner: '赵老师', ownerPhone: '137****6116', createdAt: '2025-01-08 08:40' },
- { id: 'tenant_youcai_js', slug: 'youcai-js', name: '优才专转本 · 江苏', legal: '南京优才教育科技有限公司', brand: '优才专转本', shortName: '优才江苏', host: 'study.youcai.cn', plan: '专业版', planCode: 'pro', status: '待配置', billing: '正常', mode: '试用', students: 0, questions: 0, storageGB: 0, trafficTB: 0, expires: '', balance: 0, owner: '顾老师', ownerPhone: '138****1120', createdAt: '2026-07-22 16:08' },
- ],
- domains: [],
- saasCatalog: { features: [], limitDefinitions: [], offerings: [], versions: [] },
- saasOrders: [],
- saasRefunds: [],
- paymentChannels: [],
- rebateSummary: {},
- crmLogs: [],
- billingProfiles: {
- tenant_gongxue_tj: { billingName: '天津恭学教育科技有限公司', taxId: '91120101MA07GX2026', contactName: '李会计', phone: '13800138000', email: 'finance@gongxue.cn', billingAddress: '天津市南开区科研西路 12 号', invoiceTitle: '天津恭学教育科技有限公司', type: '增值税专用发票', bankName: '招商银行天津南开支行', bankAccountMasked: '**** **** **** 8826' },
- tenant_qihang_gd: { billingName: '广州启航教育咨询有限公司', taxId: '91440101MA5QH2026X', contactName: '黄会计', phone: '13900139000', email: 'billing@qihangzsb.cn', billingAddress: '广州市天河区科韵路 18 号', invoiceTitle: '广州启航教育咨询有限公司', type: '增值税普通发票', bankName: '中国银行广州天河支行', bankAccountMasked: '**** **** **** 6672' },
- },
- plans: [
- { code: 'basic', name: '基础版', description: '适合单地区小型机构', cycle: '年度', amount: 4800, quotas: ['2,000 学生席位', '30,000 题目', '100 GB 存储', '基础内容运营'], tenantCount: 12 },
- { code: 'pro', name: '专业版', description: '适合成熟区域型机构', cycle: '年度', amount: 9800, quotas: ['8,000 学生席位', '100,000 题目', '500 GB 存储', 'CRM 与营销能力'], tenantCount: 24 },
- { code: 'enterprise', name: '旗舰版', description: '适合多校区与高内容规模', cycle: '年度', amount: 16800, quotas: ['20,000 学生席位', '300,000 题目', '2 TB 存储', '财务对账与高级审计'], tenantCount: 12 },
- ],
- subscriptions: [
- { id: 'SUB-202607-001', tenantId: 'tenant_gongxue_tj', planCode: 'enterprise', status: '活跃', cycle: '年度', amount: 16800, start: '2026-07-22', expires: '2027-07-22', autoRenew: true },
- { id: 'SUB-202608-002', tenantId: 'tenant_qihang_gd', planCode: 'pro', status: '活跃', cycle: '年度', amount: 9800, start: '2025-08-05', expires: '2026-08-05', autoRenew: true },
- { id: 'SUB-TRIAL-003', tenantId: 'tenant_bosi_sd', planCode: 'basic', status: '试用中', cycle: '试用', amount: 0, start: '2026-07-12', expires: '2026-08-12', autoRenew: false },
- { id: 'SUB-202501-004', tenantId: 'tenant_mingtu_hn', planCode: 'basic', status: '暂停', cycle: '年度', amount: 4800, start: '2025-01-18', expires: '2026-07-18', autoRenew: false },
- { id: 'SUB-202601-005', tenantId: 'tenant_xuezhi_heb', planCode: 'pro', status: '活跃', cycle: '年度', amount: 9800, start: '2026-01-08', expires: '2027-01-08', autoRenew: true },
- ],
- invoices: [
- { id: 'INV-202607-0018', tenantId: 'tenant_qihang_gd', type: '订阅服务费', period: '2026年7月', total: 12800, paid: 0, balance: 12800, due: '2026-08-05', status: '待付款', note: '2026年7月服务费' },
- { id: 'INV-202607-0017', tenantId: 'tenant_mingtu_hn', type: '订阅服务费', period: '2026年7月', total: 8600, paid: 0, balance: 8600, due: '2026-07-18', status: '已逾期', note: '2026年7月服务费' },
- { id: 'INV-202607-0016', tenantId: 'tenant_gongxue_tj', type: '订阅服务费', period: '2026年7月', total: 16800, paid: 16800, balance: 0, due: '2026-07-15', status: '已支付', note: '2026年7月服务费' },
- { id: 'INV-202607-0015', tenantId: 'tenant_xuezhi_heb', type: '订阅服务费', period: '2026年7月', total: 9800, paid: 9800, balance: 0, due: '2026-07-15', status: '已支付', note: '2026年7月服务费' },
- ],
- billingPayments: [],
- usage: [
- { tenantId: 'tenant_gongxue_tj', period: '2026-07', source: 'Worker 自动采集', students: 2846, questions: 42680, storageGB: 186, trafficTB: 1.8, overage: [], estimated: 0 },
- { tenantId: 'tenant_qihang_gd', period: '2026-07', source: 'Worker 自动采集', students: 5280, questions: 68420, storageGB: 248, trafficTB: 3.2, overage: ['流量'], estimated: 7820 },
- { tenantId: 'tenant_bosi_sd', period: '2026-07', source: 'Worker 自动采集', students: 642, questions: 12860, storageGB: 42, trafficTB: .6, overage: [], estimated: 0 },
- { tenantId: 'tenant_mingtu_hn', period: '2026-07', source: '人工补录', students: 1280, questions: 18620, storageGB: 86, trafficTB: .9, overage: ['题目', '存储'], estimated: 4260 },
- { tenantId: 'tenant_xuezhi_heb', period: '2026-07', source: 'Worker 自动采集', students: 3160, questions: 39860, storageGB: 164, trafficTB: 2.1, overage: [], estimated: 0 },
- ],
- reminders: [
- { id: 'REM-260723-01', invoiceId: 'INV-202607-0017', tenantId: 'tenant_mingtu_hn', level: 3, channel: '邮件 + 短信', status: '已送达', date: '2026-07-23 09:20', message: '服务费账单已逾期 5 天,请尽快处理。' },
- { id: 'REM-260722-02', invoiceId: 'INV-202607-0018', tenantId: 'tenant_qihang_gd', level: 1, channel: '邮件', status: '已送达', date: '2026-07-22 15:40', message: '账单将在 13 天后到期。' },
- ],
- dunningChannels: [
- { id: 'DUN-EMAIL', code: 'finance_email', name: '财务邮件', provider: 'SMTP', endpoint: 'finance@gongxue.cn', enabled: true, retry: 3 },
- { id: 'DUN-WX', code: 'finance_wecom', name: '财务企微群', provider: 'Webhook', endpoint: 'https://qyapi.weixin.qq.com/***', enabled: true, retry: 5 },
- ],
- banks: [
- { id: 'QB-TJ-MATH', name: '高等数学公共题库', catalog: '天津专升本 / 高等数学', source: '平台自建', questions: 12860, version: 'v2026.7', status: '稳定版' },
- { id: 'QB-EN', name: '公共英语能力库', catalog: '全国 / 公共英语', source: '平台自建', questions: 86640, version: 'v2026.6', status: '稳定版' },
- { id: 'QB-SD', name: '山东专升本全科', catalog: '山东专升本', source: '合作内容方', questions: 52360, version: 'v2026.7', status: '稳定版' },
- ],
- bankNodes: [
- { id: 'NODE-MATH', questionBankId: 'QB-TJ-MATH', parentId: null, name: '高等数学', nodeType: 'subject', depth: 0, sortOrder: 0, isActive: true, questionCount: 12860 },
- { id: 'NODE-MATH-01', questionBankId: 'QB-TJ-MATH', parentId: 'NODE-MATH', name: '函数、极限与连续', nodeType: 'chapter', depth: 1, sortOrder: 0, isActive: true, questionCount: 1260 },
- ],
- bankQuestions: [],
- bankImportResult: null,
- crmConfigs: [
- { id: 'CRM-GX-TJ', tenantId: 'tenant_gongxue_tj', provider: '标准 CRM', endpoint: 'https://crm.gongxue.cn/open/leads', assignmentMode: '按地区轮转', pool: '天津升本线索池', enabled: true, status: '正常', timeout: 8, retry: 3, updatedAt: '2026-07-23 09:12' },
- { id: 'CRM-QH-GD', tenantId: 'tenant_qihang_gd', provider: '自建 CRM', endpoint: 'https://crm.qihangzsb.cn/api/leads', assignmentMode: '按校区容量', pool: '广东转化队列', enabled: true, status: '异常', timeout: 10, retry: 5, updatedAt: '2026-07-22 18:40' },
- { id: 'CRM-BS-SD', tenantId: 'tenant_bosi_sd', provider: '手工队列', endpoint: '-', assignmentMode: '手工分配', pool: '试用线索池', enabled: false, status: '未启用', timeout: 8, retry: 0, updatedAt: '2026-07-18 11:30' },
- ],
- crmLeads: [
- { id: 'LEAD-260723-018', tenantId: 'tenant_qihang_gd', source: '公开课报名', student: '陈同学', phone: '139****8201', subject: '广东专升本英语', owner: '广州一校区', status: '推送失败', attempts: 4, lastError: 'CRM 422: campus required', createdAt: '2026-07-23 09:48' },
- { id: 'LEAD-260723-016', tenantId: 'tenant_gongxue_tj', source: '题库体验页', student: '王同学', phone: '138****2098', subject: '高等数学', owner: '天津转化组', status: '已推送', attempts: 1, lastError: '', createdAt: '2026-07-23 09:26' },
- { id: 'LEAD-260722-044', tenantId: 'tenant_mingtu_hn', source: '学生端留资', student: '李同学', phone: '135****6172', subject: '河南专升本语文', owner: '默认队列', status: '待推送', attempts: 0, lastError: '', createdAt: '2026-07-22 21:05' },
- ],
- smsChannels: [
- { id: 'SMS-ALI-GX', tenantId: 'tenant_gongxue_tj', provider: '阿里云短信', signature: '恭学教育', scene: 'login,notice,dunning', status: '正常', enabled: true, secretRef: 'tenant/gongxue/sms/aliyun', quota: 50000, used: 21860, updatedAt: '2026-07-22 16:10' },
- { id: 'SMS-TENCENT-QH', tenantId: 'tenant_qihang_gd', provider: '腾讯云短信', signature: '启航专升本', scene: 'login,marketing', status: '模板待审', enabled: true, secretRef: 'tenant/qihang/sms/tencent', quota: 80000, used: 64220, updatedAt: '2026-07-21 19:30' },
- { id: 'SMS-GENERIC-BS', tenantId: 'tenant_bosi_sd', provider: '通用短信网关', signature: '博思升本', scene: 'login', status: '未启用', enabled: false, secretRef: 'redacted', quota: 10000, used: 0, updatedAt: '2026-07-18 10:00' },
- ],
- smsTemplates: [
- { id: 'TPL-LOGIN-001', channelId: 'SMS-ALI-GX', code: 'student_login_otp', name: '学生登录验证码', type: '登录验证', status: '已通过', lastSend: '2026-07-23 09:58', successRate: '99.2%' },
- { id: 'TPL-DUN-001', channelId: 'SMS-ALI-GX', code: 'invoice_due_notice', name: '租户账单到期提醒', type: '平台催缴', status: '已通过', lastSend: '2026-07-23 09:20', successRate: '98.7%' },
- { id: 'TPL-MKT-009', channelId: 'SMS-TENCENT-QH', code: 'open_class_reminder', name: '公开课提醒', type: '营销触达', status: '审核中', lastSend: '-', successRate: '-' },
- ],
- paymentApps: [
- { id: 'PAY-GX-STUDENT', tenantId: 'tenant_gongxue_tj', appName: '恭学学生端收款', provider: 'wechat_pay', mode: 'production', status: '正常', settlement: 'T+1 至租户商户号', secretRef: 'tenant/gongxue/pay/wechat', updatedAt: '2026-07-22 15:08' },
- { id: 'PAY-QH-ALI', tenantId: 'tenant_qihang_gd', appName: '启航课程收款', provider: 'alipay', mode: 'production', status: '证书即将过期', settlement: 'T+1 至租户支付宝商户', secretRef: 'tenant/qihang/pay/alipay', updatedAt: '2026-07-20 13:40' },
- { id: 'PAY-BS-MANUAL', tenantId: 'tenant_bosi_sd', appName: '试用线下收款', provider: 'manual', mode: 'sandbox', status: '未启用', settlement: '人工确认', secretRef: 'redacted', updatedAt: '2026-07-18 10:20' },
- ],
- paymentEvents: [
- { id: 'PEVT-260723-031', appId: 'PAY-GX-STUDENT', orderNo: 'ORD-260723-2048', amount: 398, status: '支付成功', channel: '微信 JSAPI', notified: '已回调', updatedAt: '2026-07-23 09:56' },
- { id: 'PEVT-260723-029', appId: 'PAY-QH-ALI', orderNo: 'ORD-260723-2021', amount: 1280, status: '回调失败', channel: '支付宝 WAP', notified: '重试中', updatedAt: '2026-07-23 09:49' },
- { id: 'PEVT-260722-188', appId: 'PAY-BS-MANUAL', orderNo: 'ORD-260722-1098', amount: 99, status: '待确认', channel: '线下转账', notified: '无', updatedAt: '2026-07-22 20:18' },
- ],
- platformPermissions: {
- 'platform:dashboard:view': '平台总览',
- 'platform:tenant:manage': '平台租户管理',
- 'platform:staff:manage': '平台员工管理',
- 'platform:role:manage': '平台角色权限管理',
- 'platform:question-bank:manage': '平台公共题库运营',
- 'platform:audit:view': '平台审计查询',
- 'platform:billing:notification': '平台账务通知',
- 'platform:saas-catalog:manage': 'SaaS 商品目录管理',
- 'platform:saas-billing:manage': 'SaaS 订单与账务管理',
- 'platform:crm:read': 'CRM 配置查询',
- 'platform:crm:write': 'CRM 配置管理',
- 'platform:sms:read': '短信服务查询',
- 'platform:sms:write': '短信服务管理',
- 'platform:payment:read': '支付设置查询',
- 'platform:payment:write': '支付设置管理',
- },
- platformRoles: [
- { id: 'role-super', code: 'platform_super_admin', name: '超级管理员', description: '拥有全部平台管理权限', permissionCodes: ['*'] },
- { id: 'role-tenant', code: 'platform_tenant_operator', name: '租户运营', description: '负责租户开通与生命周期管理', permissionCodes: ['platform:dashboard:view', 'platform:tenant:manage', 'platform:crm:read', 'platform:crm:write'] },
- { id: 'role-finance', code: 'platform_finance', name: '平台财务', description: '负责 SaaS 商品、订单、账务与支付', permissionCodes: ['platform:dashboard:view', 'platform:saas-catalog:manage', 'platform:saas-billing:manage', 'platform:billing:notification', 'platform:payment:read', 'platform:payment:write'] },
- { id: 'role-audit', code: 'platform_auditor', name: '安全审计', description: '查询审计日志与处理安全告警', permissionCodes: ['platform:dashboard:view', 'platform:audit:view'] },
- { id: 'role-bank', code: 'platform_question_bank_operator', name: '题库运营', description: '负责公共题库结构、题目与导入', permissionCodes: ['platform:dashboard:view', 'platform:question-bank:manage'] },
- ],
- staff: [
- { id: 'STAFF-01', userId: 'STAFF-01', roleIds: ['role-super'], roleCodes: ['platform_super_admin'], name: '陈浩', email: 'chenhao@gongxue.cn', phone: '138****6600', role: '超级管理员', permissions: ['*'], status: '正常', lastActive: '刚刚' },
- { id: 'STAFF-02', authUserId: 'auth-zhoumin', username: 'zhoumin', name: '周敏', email: 'zhoumin@gongxue.cn', phone: '139****2188', role: '题库运营', permissions: ['platform:question-bank:manage'], status: '正常', lastActive: '8分钟前' },
- { id: 'STAFF-03', authUserId: 'auth-liujia', username: 'liujia', name: '刘佳', email: 'liujia@gongxue.cn', phone: '136****9028', role: '平台财务', permissions: ['platform:billing:read', 'platform:billing:write', 'platform:billing:payment', 'platform:usage:read', 'platform:usage:write'], status: '正常', lastActive: '21分钟前' },
- { id: 'STAFF-04', authUserId: 'auth-wanglei', username: 'wanglei', name: '王磊', email: 'wanglei@gongxue.cn', phone: '135****2086', role: '租户运营', permissions: ['platform:tenant:read', 'platform:tenant:write', 'platform:tenant:status'], status: '正常', lastActive: '1小时前' },
- { id: 'STAFF-05', authUserId: 'auth-sunchen', username: 'sunchen', name: '孙晨', email: 'sunchen@gongxue.cn', phone: '137****1118', role: '安全审计', permissions: ['platform:audit:read', 'platform:audit:alert'], status: '已停用', lastActive: '3天前' },
- ],
- auditLogs: [
- { id: 'AUD-20260723-094218', time: '2026-07-23 09:42:18 CST', actor: '陈浩', role: '平台管理员', action: 'tenant.status.update', targetType: 'tenant', targetId: 'tenant_mingtu_hn', target: '明途教育 · 河南', severity: '高', result: '成功', ip: '172.16.4.28', details: '将业务状态由正常更新为暂停,原因:账单逾期。' },
- { id: 'AUD-20260723-093602', time: '2026-07-23 09:36:02 CST', actor: 'system-billing', role: '系统任务', action: 'invoice.batch.create', targetType: 'invoice_batch', targetId: 'TASK-260723-001', target: '2026年7月账单', severity: '中', result: '成功', ip: 'internal', details: '生成 48 张账单,跳过 2 条重复候选。' },
- { id: 'AUD-20260723-085844', time: '2026-07-23 08:58:44 CST', actor: '周敏', role: '题库运营', action: 'platform.question_bank.import_executed', targetType: 'question_bank', targetId: 'QB-TJ-MATH', target: '高数公共题库 v2026.7', severity: '中', result: '成功', ip: '172.16.3.16', details: '结构化 JSON 导入完成,新增 8 个内容节点和 126 道题。' },
- { id: 'AUD-20260723-084127', time: '2026-07-23 08:41:27 CST', actor: '刘佳', role: '平台财务', action: 'invoice.payment.confirm', targetType: 'invoice', targetId: 'INV-202607-0016', target: 'INV-202607-0016', severity: '高', result: '成功', ip: '172.16.8.12', details: '人工确认收款 ¥16,800,流水号已脱敏。' },
- { id: 'AUD-20260723-081209', time: '2026-07-23 08:12:09 CST', actor: 'unknown', role: '-', action: 'auth.login.failed', targetType: 'application', targetId: 'platform-console', target: 'platform-console', severity: '严重', result: '失败', ip: '45.62.18.9', details: '5 分钟内连续登录失败 12 次。' },
- { id: 'AUD-20260720-163510', time: '2026-07-20 16:35:10 CST', actor: '周敏', role: '题库运营', action: 'bank.catalog.read', targetType: 'question_bank', targetId: 'QB-SD', target: '山东专升本全科', severity: '中', result: '成功', ip: '172.16.3.16', details: '查看公共题库版本与租户采用状态。' },
- ],
- alerts: [
- { id: 'ALT-20260723-008', title: '异常登录尝试', summary: '5 分钟内 12 次平台登录失败', severity: '严重', status: 'open', owner: '安全审计', targetType: 'application', targetId: 'platform-console', evidence: ['来源 IP 45.62.18.9', '账号枚举行为 12 次', '命中规则 LOGIN_FAILURE_BURST'], updatedAt: '2分钟前', note: '' },
- { id: 'ALT-20260723-006', title: '租户账单逾期', summary: '明途教育服务费账单逾期 5 天', severity: '高', status: 'acknowledged', owner: '平台财务', targetType: 'invoice', targetId: 'INV-202607-0017', evidence: ['余额 ¥8,600', '到期日 2026-07-18', '已发送 3 次催缴'], updatedAt: '18分钟前', note: '财务已联系租户。' },
- { id: 'ALT-20260723-004', title: '公共题库导入失败', summary: '结构化 JSON 文件存在 12 个稳定编码冲突', severity: '中', status: 'open', owner: '题库运营', targetType: 'question_bank', targetId: 'QB-EN', evidence: ['文件版本 2.0', '目标题库 公共英语能力库', '冲突 12 条'], updatedAt: '42分钟前', note: '' },
- { id: 'ALT-20260722-019', title: '存储用量告警', summary: '启航专升本存储用量达到套餐 92%', severity: '中', status: 'open', owner: '租户运营', targetType: 'tenant', targetId: 'tenant_qihang_gd', evidence: ['当前 460 GB', '套餐上限 500 GB'], updatedAt: '昨天', note: '' },
- { id: 'ALT-20260722-011', title: 'Provider 密钥即将过期', summary: '优才专转本支付 Provider 密钥 7 天后到期', severity: '高', status: 'resolved', owner: '平台运维', targetType: 'tenant', targetId: 'tenant_youcai_js', evidence: ['密钥只写不可回显', '新密钥已于昨天更新'], updatedAt: '昨天', note: '完成轮换。' },
- ],
- alertRules: [
- { id: 'RULE-LOGIN-BURST', code: 'LOGIN_FAILURE_BURST', name: '平台登录失败突增', severity: '严重', enabled: true, window: '5 分钟', threshold: '≥ 10 次', target: '平台账号与来源 IP' },
- { id: 'RULE-INVOICE-OVERDUE', code: 'INVOICE_OVERDUE', name: '服务费账单逾期', severity: '高', enabled: true, window: '每日 09:00', threshold: '逾期 ≥ 1 天', target: '未结清平台账单' },
- { id: 'RULE-BANK-IMPORT', code: 'QUESTION_BANK_IMPORT_FAILED', name: '公共题库导入失败', severity: '中', enabled: true, window: '导入结束时', threshold: '无效记录或冲突 ≥ 10', target: '平台公共题库导入任务' },
- ],
- auditChannels: [
- { id: 'CH-SEC-MAIL', code: 'security_email', name: '平台安全邮箱', provider: '邮件', endpoint: 'security@gongxue.cn', minSeverity: '中', statusFilter: 'open,acknowledged', timeout: 8, maxAttempts: 3, enabled: true, lastStatus: '正常' },
- { id: 'CH-SEC-WX', code: 'security_wecom', name: '财务告警群', provider: 'Webhook', endpoint: 'Webhook · 企业微信', minSeverity: '高', statusFilter: 'open', timeout: 5, maxAttempts: 5, enabled: true, lastStatus: '正常' },
- { id: 'CH-DUTY-SMS', code: 'duty_sms', name: '值班手机', provider: '短信', endpoint: '138****6008', minSeverity: '严重', statusFilter: 'open', timeout: 10, maxAttempts: 3, enabled: true, lastStatus: '失败1次' },
- ],
- notificationEvents: [
- { id: 'EVT-260723-001', channelId: 'CH-DUTY-SMS', subject: '异常登录尝试', status: '失败', attempts: 2, updatedAt: '2026-07-23 09:44 CST', error: '运营商返回频率限制' },
- { id: 'EVT-260723-002', channelId: 'CH-SEC-MAIL', subject: '异常登录尝试', status: '成功', attempts: 1, updatedAt: '2026-07-23 09:43 CST', error: '' },
- ],
- dunningEvents: [],
- tasks: [],
-};
-
-function clone(value) { return JSON.parse(JSON.stringify(value)); }
-function normalizeData(saved) {
- const normalized = clone(seed);
- if (!saved || typeof saved !== 'object') return normalized;
- Object.keys(normalized).forEach(key => {
- if (key === 'version') return;
- if (Array.isArray(normalized[key])) {
- if (Array.isArray(saved[key])) normalized[key] = saved[key];
- return;
- }
- if (normalized[key] && typeof normalized[key] === 'object') {
- if (saved[key] && typeof saved[key] === 'object' && !Array.isArray(saved[key])) normalized[key] = { ...normalized[key], ...saved[key] };
- return;
- }
- if (saved[key] !== undefined) normalized[key] = saved[key];
- });
- normalized.usage = normalized.usage.map(item => ({ overage: [], estimated: 0, source: 'Worker 自动采集', ...item }));
- normalized.crmConfigs = normalized.crmConfigs.map(item => ({ enabled: false, status: '未启用', retry: 0, ...item }));
- normalized.crmLeads = normalized.crmLeads.map(item => ({ attempts: 0, lastError: '', ...item }));
- normalized.smsChannels = normalized.smsChannels.map(item => ({ enabled: false, quota: 0, used: 0, ...item }));
- normalized.smsTemplates = normalized.smsTemplates.map(item => ({ lastSend: '-', successRate: '-', ...item }));
- normalized.paymentApps = normalized.paymentApps.map(item => ({ mode: 'sandbox', status: '未启用', ...item }));
- normalized.paymentEvents = normalized.paymentEvents.map(item => ({ notified: '无', ...item }));
- normalized.platformPermissions = Object.fromEntries(Object.entries(normalized.platformPermissions || {}).map(([code, name]) => [
- code,
- seed.platformPermissions[code] || name,
- ]));
- normalized.platformRoles = normalized.platformRoles.map(item => item.code === 'platform_super_admin'
- ? { ...item, name: '超级管理员', description: '拥有全部平台管理权限' }
- : item);
- normalized.staff = normalized.staff.map(item => {
- const roleIds = item.roleIds?.length ? item.roleIds : normalized.platformRoles.filter(role => role.name === item.role).map(role => role.id);
- const assignedRoles = normalized.platformRoles.filter(role => roleIds.includes(role.id));
- return {
- permissions: assignedRoles.flatMap(role => role.permissionCodes),
- status: '正常',
- lastActive: '尚未登录',
- ...item,
- userId: item.userId || item.id,
- roleIds,
- roleCodes: item.roleCodes || assignedRoles.map(role => role.code),
- };
- });
- normalized.alerts = normalized.alerts.map(item => ({ evidence: [], note: '', status: 'open', ...item }));
- normalized.tasks = normalized.tasks.map(item => ({ status: 'failed', error: '', resultTarget: '任务中心', updatedAt: item.createdAt || todayTime(), ...item }));
- normalized.version = seed.version;
- return normalized;
-}
-function loadData() {
- try {
- const saved = JSON.parse(localStorage.getItem(STORAGE_KEY));
- if (saved?.version === seed.version) {
- const normalized = normalizeData(saved);
- normalized.tasks.forEach(task => {
- if (['pending', 'processing'].includes(task.status)) {
- task.status = 'failed';
- task.error = '页面重载中断了本次 Mock 执行,可从任务中心重试。';
- task.updatedAt = todayTime();
- }
- });
- return normalized;
- }
- } catch (error) {
- console.warn('Mock state restore failed', error);
- }
- return clone(seed);
-}
-let data = loadData();
-if (platformApi?.isEnabled()) {
- [
- 'tenants', 'plans', 'subscriptions', 'invoices', 'usage', 'reminders',
- 'dunningChannels', 'dunningEvents', 'banks', 'bankNodes', 'bankQuestions', 'staff',
- 'auditLogs', 'alerts', 'alertRules', 'auditChannels', 'notificationEvents', 'tasks',
- ].forEach(key => { data[key] = []; });
- data.billingProfiles = {};
-}
-const state = {
- view: 'overview', previousView: '', selectedTenant: data.tenants[0]?.id || '', tenantFilter: 'all', tenantPlan: 'all', tenantSearch: '', globalSearch: '',
- billingTab: 'invoices', bankTab: 'structure', selectedBank: data.banks[0]?.id || '', selectedBankNode: '', bankQuestionPage: 1, bankQuestionTotal: 0,
- crmTab: 'configs', smsTab: 'channels', paymentTab: 'apps', saasFinanceTab: 'orders',
- invoiceSearch: '', invoiceStatus: 'all', bankSearch: '', staffSearch: '', usagePeriod: '2026-07', auditRange: '24h', auditSeverity: 'all', auditSearch: '', alertStatus: 'all', selectedAlert: '', selectedInvoice: '',
- role: 'super', scenario: 'normal', response: 'success', modal: '', modalData: {}, submitting: '', reading: '', contractResults: {}, history: [],
- apiConnection: platformApi?.isEnabled() ? 'connecting' : 'mock', apiLoadedAt: '', apiLoadedOperations: 0, apiFailedOperations: 0,
-};
-let pendingLeave = null;
-let historySequence = Number(history.state?.sequence) || 0;
-let restoringHistory = false;
-let bypassHistoryGuard = false;
-const dirtyScopes = new Set();
-const loadedTenantDetails = new Set();
-
-let storageWarningShown = false;
-function saveData() {
- if (platformApi?.isEnabled()) return true;
- try {
- localStorage.setItem(STORAGE_KEY, JSON.stringify(data));
- return true;
- } catch (error) {
- console.warn('Mock state persistence failed', error);
- if (!storageWarningShown) {
- storageWarningShown = true;
- showToast('浏览器存储不可用,本次修改仅在当前页面保留', 'error');
- }
- return false;
- }
-}
-function backendStatusLabel() {
- if (!platformApi?.isEnabled()) return '静态演示数据';
- if (state.apiConnection === 'connecting') return '正在连接后端';
- if (state.apiConnection === 'connected') {
- const partial = state.apiFailedOperations ? ` · ${state.apiFailedOperations} 项加载失败` : '';
- return `后端已连接${partial}`;
- }
- return '后端不可用 · 已保留静态演示';
-}
-function backendErrorText(error, fallback = '平台接口请求失败') {
- if (!error) return fallback;
- const pieces = [error.message || fallback];
- if (error.code) pieces.push(`code=${error.code}`);
- if (error.requestId) pieces.push(`requestId=${error.requestId}`);
- return pieces.join(' · ');
-}
-function apiItems(payload) {
- if (Array.isArray(payload)) return payload;
- if (Array.isArray(payload?.items)) return payload.items;
- return [];
-}
-function apiItem(payload) {
- return payload?.item || payload || {};
-}
-function updateBackendStatus() {
- const status = document.querySelector('.top-status > span');
- if (!status) return;
- status.innerHTML = `${escapeHtml(backendStatusLabel())}`;
- status.title = platformApi?.isEnabled()
- ? `${platformApi.publicConfig().apiBaseUrl || '未配置 API 地址'}${state.apiLoadedAt ? ` · ${state.apiLoadedAt}` : ''}`
- : 'runtime-config.js 当前为 mock 模式';
- status.classList.toggle('is-degraded', state.apiConnection === 'degraded');
-}
-function applyBackendPatch(patch) {
- Object.entries(patch).forEach(([key, value]) => { data[key] = value; });
- if (patch.tenants) {
- const tenantIds = new Set(data.tenants.map(tenant => tenant.id));
- if (!tenantIds.has(state.selectedTenant)) state.selectedTenant = data.tenants[0]?.id || '';
- }
- if (patch.banks && !data.banks.some(bank => bank.id === state.selectedBank)) state.selectedBank = data.banks[0]?.id || '';
- if (patch.usage) {
- const latestUsage = new Map();
- data.usage.forEach(item => {
- const current = latestUsage.get(item.tenantId);
- if (!current || item.period > current.period) latestUsage.set(item.tenantId, item);
- });
- data.tenants.forEach(tenant => {
- const usage = latestUsage.get(tenant.id);
- if (!usage) return;
- tenant.students = usage.students;
- tenant.questions = usage.questions;
- tenant.storageGB = usage.storageGB;
- tenant.trafficTB = usage.trafficTB;
- });
- }
- if (patch.plans || patch.tenants) {
- data.plans.forEach(plan => {
- plan.tenantCount = data.tenants.filter(tenant => tenant.planCode === plan.code).length;
- });
- }
-}
-async function hydrateFromBackend({ silent = false } = {}) {
- if (!platformApi?.isEnabled()) {
- state.apiConnection = 'mock';
- updateBackendStatus();
- return false;
- }
- state.apiConnection = 'connecting';
- updateBackendStatus();
- try {
- const result = await platformApi.bootstrap({ period: state.usagePeriod });
- const successful = Object.keys(result.payloads).length;
- if (!successful) throw Object.values(result.errors)[0] || new Error('没有平台接口成功返回');
- applyBackendPatch(platformApi.adaptBootstrap(result.payloads, data));
- state.apiConnection = 'connected';
- state.apiLoadedAt = todayTime();
- state.apiLoadedOperations = successful;
- state.apiFailedOperations = Object.keys(result.errors).length;
- render();
- if (!silent) showToast(`后端数据已刷新 · ${successful}/${result.requested} 项成功`);
- return true;
- } catch (error) {
- if (error?.status === 401) {
- window.GongxuePlatformAuth?.requireReauthentication();
- return false;
- }
- state.apiConnection = 'degraded';
- state.apiFailedOperations = 1;
- render();
- if (!silent) showToast(`${backendErrorText(error, '后端连接失败')} · 已保留静态演示`, 'error');
- return false;
- }
-}
-async function hydrateTenantDetail(tenantId, { force = false } = {}) {
- if (!platformApi?.isEnabled() || !tenantId || (!force && loadedTenantDetails.has(tenantId))) return;
- try {
- const detail = await platformApi.tenantDetail(tenantId);
- const tenant = tenantById(tenantId);
- if (tenant && detail.tenant) {
- tenant.legal = detail.tenant.legalName || tenant.legal;
- tenant.brand = detail.tenant.brandName || tenant.brand;
- tenant.shortName = detail.tenant.shortName || tenant.shortName;
- tenant.createdAt = detail.tenant.createdAt ? String(detail.tenant.createdAt).slice(0, 10) : tenant.createdAt;
- tenant.host = detail.domains.find(domain => domain.isPrimary)?.host || detail.domains[0]?.host || tenant.host;
- }
- data.subscriptions = [
- ...data.subscriptions.filter(item => item.tenantId !== tenantId),
- ...detail.subscriptions,
- ];
- if (detail.billingProfile) data.billingProfiles[tenantId] = detail.billingProfile;
- loadedTenantDetails.add(tenantId);
- render();
- } catch (error) {
- showToast(backendErrorText(error, '租户详情加载失败'), 'error');
- }
-}
-function icon(name) { return ``; }
-function refreshIcons() { if (window.lucide) window.lucide.createIcons({ attrs: { 'stroke-width': 1.8 } }); }
-function formatNumber(value) { return Number(value || 0).toLocaleString('zh-CN'); }
-function money(value) { return `¥${Number(value || 0).toLocaleString('zh-CN')}`; }
-function todayTime() { return new Intl.DateTimeFormat('zh-CN', { timeZone: 'Asia/Shanghai', dateStyle: 'short', timeStyle: 'medium' }).format(new Date()).replaceAll('/', '-'); }
-function requestId() { return `req_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 7)}`; }
-function entityId(prefix) { return `${prefix}-${Date.now().toString(36).toUpperCase()}`; }
-function tenantById(id) { return data.tenants.find(item => item.id === id); }
-function planByCode(code) { return data.plans.find(item => item.code === code); }
-function invoiceById(id) { return data.invoices.find(item => item.id === id); }
-function paymentForInvoice(invoice) { return data.billingPayments.find(item => item.orderId && item.orderId === invoice?.orderId && item.status === 'pending'); }
-function canConfirmInvoicePayment(invoice) { return !platformApi?.isEnabled() || Boolean(paymentForInvoice(invoice)); }
-function bankById(id) { return data.banks.find(item => item.id === id); }
-function bankNodeById(id) { return data.bankNodes.find(item => item.id === id); }
-function questionTypeLabel(value) { return ({ choice: '单选题', multiple_choice: '多选题', true_false: '判断题', fill_blank: '填空题', short_answer: '简答题', reading: '阅读材料题', programming: '编程题' })[String(value || '').toLowerCase()] || value || '-'; }
-function bankNodeTypeLabel(value) { return ({ category: '分类', subject: '科目', chapter: '章节', paper: '试卷', custom: '自定义' })[String(value || '').toLowerCase()] || value || '-'; }
-function adaptBankNode(item) { return { ...item, questionBankId: item.questionBankId, nodeType: String(item.nodeType || '').replace(/([a-z0-9])([A-Z])/g, '$1_$2').toLowerCase(), questionCount: Number(item.questionCount || 0) }; }
-function adaptBankQuestion(item) { return { ...item, statusLabel: businessStatusLabel(item.status), versionNo: Number(item.versionNo || 0) }; }
-function parseJsonText(value, fallback) { try { return String(value || '').trim() ? JSON.parse(value) : fallback; } catch { return null; } }
-async function loadBankWorkspace({ questions = true } = {}) {
- const bank = bankById(state.selectedBank);
- if (!bank || !platformApi?.isEnabled()) return;
- try {
- const nodes = await platformApi.request('PlatformQuestionBanksController_getNodes', { pathParams: { bankId: bank.id } });
- data.bankNodes = apiItems(nodes).map(adaptBankNode);
- if (!state.selectedBankNode || !data.bankNodes.some(item => item.id === state.selectedBankNode)) state.selectedBankNode = data.bankNodes.find(item => item.isActive && ['chapter', 'paper'].includes(item.nodeType))?.id || data.bankNodes.find(item => item.isActive)?.id || '';
- if (questions) {
- const result = await platformApi.request('PlatformQuestionBanksController_getQuestions', { query: { questionBankId: bank.id, contentNodeId: state.selectedBankNode || undefined, page: state.bankQuestionPage, pageSize: 20 } });
- data.bankQuestions = apiItems(result).map(adaptBankQuestion);
- state.bankQuestionTotal = Number(result.total || data.bankQuestions.length);
- }
- saveData(); render();
- } catch (error) {
- showToast(backendErrorText(error, '公共题库加载失败'), 'error');
- }
-}
-function notificationChannelName(id) {
- return [...data.dunningChannels, ...data.auditChannels].find(channel => channel.id === id)?.name || id;
-}
-function setAccessibleControlName(element, label) {
- if (!element || !label) return;
- element.setAttribute('aria-label', label);
- element.setAttribute('title', label);
-}
-function recordLabel(name, id) { return [name, id].filter(Boolean).join(' · '); }
-function rowActionAccessibleName(control) {
- const tenantId = control.dataset.tenantDetail || control.dataset.tenantId;
- const tenant = tenantById(tenantId);
- if (control.dataset.tenantDetail) return `查看租户 ${recordLabel(tenant?.name, tenantId)} 详情`;
- if (control.dataset.invoiceDetail) {
- const invoice = invoiceById(control.dataset.invoiceDetail);
- return `查看账单 ${recordLabel(invoice?.id, tenantById(invoice?.tenantId)?.name)} 详情`;
- }
- if (control.dataset.notificationDetail) {
- const event = [...(data.notificationEvents || []), ...(data.dunningEvents || [])].find(item => item.id === control.dataset.notificationDetail);
- return `查看通知事件 ${recordLabel(event?.subject, event?.id || control.dataset.notificationDetail)} 详情`;
- }
- if (control.dataset.auditDetail) {
- const log = data.auditLogs.find(item => item.id === control.dataset.auditDetail);
- return `查看审计日志 ${recordLabel(log?.id || control.dataset.auditDetail, log?.target)} 详情`;
- }
- const action = control.dataset.action;
- if (action === 'prepare-tenant-status') return `${tenant?.status === '暂停' ? '恢复' : '暂停'}租户 ${recordLabel(tenant?.name, tenantId)}`;
- if (action === 'tenant-to-billing') return `查看租户 ${recordLabel(tenant?.name, tenantId)} 账务`;
- if (action === 'confirm-payment') {
- const invoice = invoiceById(control.dataset.invoiceId);
- return `确认账单 ${recordLabel(invoice?.id || control.dataset.invoiceId, tenantById(invoice?.tenantId)?.name)} 收款`;
- }
- if (action === 'edit-dunning-channel') {
- const channel = data.dunningChannels.find(item => item.id === control.dataset.channelId);
- return `编辑催缴渠道 ${recordLabel(channel?.name, channel?.id || control.dataset.channelId)}`;
- }
- if (action === 'edit-staff') {
- const person = data.staff.find(item => item.id === control.dataset.staffId);
- return `编辑员工 ${recordLabel(person?.name, person?.id || control.dataset.staffId)}`;
- }
- if (action === 'edit-crm-config') {
- const config = data.crmConfigs.find(item => item.id === control.dataset.crmId);
- return `编辑 CRM 接入 ${recordLabel(tenantById(config?.tenantId)?.name, config?.id || control.dataset.crmId)}`;
- }
- if (action === 'retry-crm-lead') {
- const lead = data.crmLeads.find(item => item.id === control.dataset.leadId);
- return `重试 CRM 线索 ${recordLabel(lead?.student, lead?.id || control.dataset.leadId)}`;
- }
- if (action === 'edit-sms-channel') {
- const channel = data.smsChannels.find(item => item.id === control.dataset.smsId);
- return `编辑短信渠道 ${recordLabel(channel?.signature, channel?.id || control.dataset.smsId)}`;
- }
- if (action === 'edit-payment-app') {
- const paymentApp = data.paymentApps.find(item => item.id === control.dataset.paymentId);
- return `编辑支付应用 ${recordLabel(paymentApp?.appName, paymentApp?.id || control.dataset.paymentId)}`;
- }
- if (action === 'edit-audit-channel') {
- const channel = data.auditChannels.find(item => item.id === control.dataset.channelId);
- return `编辑审计通知渠道 ${recordLabel(channel?.name, channel?.id || control.dataset.channelId)}`;
- }
- return control.title || control.textContent.trim();
-}
-function switchAccessibleName(control) {
- const enabled = control.classList.contains('is-on');
- const action = control.dataset.action;
- if (action === 'toggle-auto-renew') {
- const subscription = data.subscriptions.find(item => item.id === control.dataset.subscriptionId);
- const tenant = tenantById(subscription?.tenantId);
- return `${enabled ? '关闭' : '开启'}${tenant?.name || '该租户'}订阅 ${subscription?.id || control.dataset.subscriptionId} 自动续费`;
- }
- if (action === 'toggle-dunning-channel') {
- const channel = data.dunningChannels.find(item => item.id === control.dataset.channelId);
- return `${enabled ? '停用' : '启用'}催缴渠道 ${recordLabel(channel?.name, channel?.id || control.dataset.channelId)}`;
- }
- if (action === 'toggle-staff') {
- const person = data.staff.find(item => item.id === control.dataset.staffId);
- return `${enabled ? '停用员工' : '启用员工'} ${recordLabel(person?.name, person?.id || control.dataset.staffId)}${enabled ? '并撤销会话' : ''}`;
- }
- if (action === 'toggle-crm-config') {
- const config = data.crmConfigs.find(item => item.id === control.dataset.crmId);
- return `${enabled ? '停用' : '启用'} CRM 接入 ${recordLabel(tenantById(config?.tenantId)?.name, config?.id || control.dataset.crmId)}`;
- }
- if (action === 'toggle-sms-channel') {
- const channel = data.smsChannels.find(item => item.id === control.dataset.smsId);
- return `${enabled ? '停用' : '启用'}短信渠道 ${recordLabel(channel?.signature, channel?.id || control.dataset.smsId)}`;
- }
- if (action === 'toggle-payment-app') {
- const paymentApp = data.paymentApps.find(item => item.id === control.dataset.paymentId);
- return `${enabled ? '停用' : '启用'}支付应用 ${recordLabel(paymentApp?.appName, paymentApp?.id || control.dataset.paymentId)}`;
- }
- if (action === 'toggle-audit-channel') {
- const channel = data.auditChannels.find(item => item.id === control.dataset.channelId);
- return `${enabled ? '停用' : '启用'}审计通知渠道 ${recordLabel(channel?.name, channel?.id || control.dataset.channelId)}`;
- }
- return enabled ? '关闭此设置' : '开启此设置';
-}
-function updateMenuButtonAccessibility() {
- const expanded = app.classList.contains('menu-open');
- setAccessibleControlName(menuButton, expanded ? '关闭平台导航菜单' : '打开平台导航菜单');
- menuButton.setAttribute('aria-expanded', String(expanded));
- menuButton.setAttribute('aria-controls', 'sideNav');
-}
-function decorateAccessibleControls(root) {
- const selectLabels = {
- tenantPlanFilter: '租户套餐筛选',
- invoiceStatusFilter: '账单状态筛选',
- roleSelect: '演示角色',
- scenarioSelect: '页面状态演练',
- responseSelect: '下一次 Mock 写请求结果',
- };
- Object.entries(selectLabels).forEach(([id, label]) => setAccessibleControlName(document.querySelector(`#${id}`), label));
- root.querySelectorAll('.row-action').forEach(control => setAccessibleControlName(control, rowActionAccessibleName(control)));
- root.querySelectorAll('.switch').forEach(control => {
- setAccessibleControlName(control, switchAccessibleName(control));
- control.setAttribute('role', 'switch');
- control.setAttribute('aria-checked', String(control.classList.contains('is-on')));
- });
- document.querySelectorAll('.icon-button').forEach(control => {
- const fallback = control.title || control.getAttribute('aria-label');
- if (fallback) setAccessibleControlName(control, fallback);
- });
- updateMenuButtonAccessibility();
-}
-function hasPermission(permission) {
- if (platformApi?.isEnabled() && data.apiPermissions?.effective && Object.prototype.hasOwnProperty.call(data.apiPermissions.effective, permission)) {
- return data.apiPermissions.effective[permission] === true;
- }
- const grants = roleDefinitions[state.role]?.permissions || [];
- if (grants.includes('*') || grants.includes(permission)) return true;
- return grants.some(grant => grant.endsWith('*') && permission.startsWith(grant.slice(0, -1)));
-}
-function tone(text) {
- const value = String(text || '');
- if (/正常|活跃|已支付|resolved|已解决|已授权|成功|已完成|启用|已送达/.test(value)) return 'success';
- if (/逾期|暂停|严重|失败|阻断|已停用|同步失败/.test(value)) return 'danger';
- if (/待|试用|警告|即将|acknowledged|已确认|同步中|执行中|开放|open/.test(value)) return 'warning';
- return 'neutral';
-}
-function alertStatusLabel(status) { return ({ open: '开放', acknowledged: '已确认', resolved: '已解决', ignored: '已忽略' })[status] || status; }
-function taskStatusLabel(status) { return ({ pending: '待处理', processing: '执行中', completed: '已完成', failed: '失败' })[status] || status; }
-function escapeHtml(value) { return String(value ?? '').replace(/[&<>'"]/g, char => ({ '&': '&', '<': '<', '>': '>', "'": ''', '"': '"' })[char]); }
-function fieldValue(form, name) { return String(new FormData(form).get(name) || '').trim(); }
-function parseMoney(value) { return Number(String(value || '').replaceAll(',', '')); }
-function addAudit(action, targetType, targetId, target, severity, details, result = '成功') {
- data.auditLogs.unshift({ id: entityId('AUD'), time: `${todayTime()} CST`, actor: roleDefinitions[state.role].label, role: roleDefinitions[state.role].label, action, targetType, targetId, target, severity, result, ip: '127.0.0.1', details });
- saveData();
-}
-function addTask(label, resultTarget, execute) {
- const task = { id: entityId('TASK'), label, resultTarget, status: 'pending', createdAt: todayTime(), updatedAt: todayTime(), error: '' };
- data.tasks.unshift(task); saveData(); updateCounters();
- setTimeout(() => { task.status = 'processing'; task.updatedAt = todayTime(); saveData(); updateCounters(); renderOverlay(); }, 350);
- setTimeout(() => {
- try { execute?.(task); task.status = 'completed'; }
- catch (error) { task.status = 'failed'; task.error = error.message || '任务执行失败'; }
- task.updatedAt = todayTime(); saveData(); updateCounters(); render(); renderOverlay();
- }, 1200);
- return task;
-}
-function contractResult(key) {
- const result = state.contractResults[key];
- if (!result) return '';
- const toneClass = result.status === 'error' ? 'is-error' : result.status === 'loading' ? 'is-loading' : 'is-success';
- const glyph = result.status === 'error' ? 'triangle-alert' : result.status === 'loading' ? 'loader-circle' : 'circle-check';
- return `${icon(glyph)}${escapeHtml(result.title)}${escapeHtml(result.detail)} · Request ID:${escapeHtml(result.requestId)}
`;
-}
-function runContractRead({ key, actionId, operationId, title, apply, suppliedRequestId = '', liveRequest }) {
- if (state.reading) return;
- const id = suppliedRequestId || requestId();
- state.reading = key;
- state.contractResults[key] = { status: 'loading', title: `${title}处理中`, detail: operationId, requestId: id };
- render();
- if (platformApi?.isEnabled()) {
- Promise.resolve(typeof liveRequest === 'function' ? liveRequest() : platformApi.request(operationId))
- .then(payload => {
- state.reading = '';
- const requestIdValue = payload?.meta?.requestId || payload?.requestId || payload?.traceId || id;
- const detail = apply?.(payload) || '查询结果已刷新';
- state.contractResults[key] = { status: 'success', title: `${title}完成`, detail, requestId: requestIdValue };
- if (actionId) window.recordPlatformSpecResult?.(actionId, { result: 'success', operationId, requestId: requestIdValue });
- render();
- })
- .catch(error => {
- state.reading = '';
- const requestIdValue = error.requestId || id;
- state.contractResults[key] = { status: 'error', title: `${title}失败`, detail: backendErrorText(error), requestId: requestIdValue };
- if (actionId) window.recordPlatformSpecResult?.(actionId, { result: 'failed', operationId, requestId: requestIdValue });
- render();
- });
- return;
- }
- const response = nextResponse();
- setTimeout(() => {
- state.reading = '';
- if (response !== 'success') {
- const detail = response === 'validation_error' ? '服务端拒绝查询参数,已保留当前筛选' : 'Mock 查询失败,已保留当前筛选';
- state.contractResults[key] = { status: 'error', title: `${title}失败`, detail, requestId: id };
- addAudit(`${key}.failed`, 'mock_request', id, operationId, response === 'validation_error' ? '中' : '高', `${detail}。Request ID:${id}。`, '失败');
- if (actionId) window.recordPlatformSpecResult?.(actionId, { result: 'failed', operationId, requestId: id });
- render();
- return;
- }
- const detail = apply?.() || '查询结果已刷新';
- state.contractResults[key] = { status: 'success', title: `${title}完成`, detail, requestId: id };
- if (actionId) window.recordPlatformSpecResult?.(actionId, { result: 'success', operationId, requestId: id });
- render();
- }, 520);
-}
-function addContractTask({ actionId, operationId, label, resultTarget, execute, suppliedRequestId = '' }) {
- const response = nextResponse();
- const id = suppliedRequestId || requestId();
- const task = addTask(label, resultTarget, taskItem => {
- if (response !== 'success') {
- const message = `${response === 'validation_error' ? '服务端字段校验失败' : 'Mock 异步请求失败'} · Request ID:${id}`;
- addAudit(`${actionId}.failed`, 'mock_request', id, operationId, '高', message, '失败');
- window.recordPlatformSpecResult?.(actionId, { result: 'failed', operationId, requestId: id, taskId: taskItem.id });
- throw new Error(message);
- }
- execute?.(taskItem, id);
- window.recordPlatformSpecResult?.(actionId, { result: 'success', operationId, requestId: id, taskId: taskItem.id });
- });
- task.requestId = id;
- task.operationId = operationId;
- saveData();
- return task;
-}
-function canWrite(permission) { return hasPermission(permission) && state.role !== 'readonly'; }
-function isCompactAdmin() { return window.matchMedia('(max-width: 767px)').matches; }
-function requireDesktop(actionLabel) {
- if (!isCompactAdmin()) return false;
- openModal('mobileBoundary', { actionLabel });
- return true;
-}
-function closeMobileMenu() {
- app.classList.remove('menu-open');
- document.body.classList.remove('menu-locked');
- updateMenuButtonAccessibility();
-}
-function toggleMobileMenu() {
- const opening = !app.classList.contains('menu-open');
- app.classList.toggle('menu-open', opening);
- document.body.classList.toggle('menu-locked', opening);
- updateMenuButtonAccessibility();
-}
-
-function setupPrototypeControls() {
- roleSelect.innerHTML = Object.entries(roleDefinitions).map(([value, role]) => ``).join('');
- scenarioSelect.innerHTML = [['normal', '正常'], ['loading', '加载中'], ['empty', '空状态'], ['partial_error', '局部失败'], ['error', '加载失败'], ['forbidden', '403 无权限'], ['session_invalid', '401 会话失效'], ['submitting', '提交中'], ['success', '成功结果']].map(([value, label]) => ``).join('');
- responseSelect.innerHTML = [['success', '下一次成功'], ['server_error', '下一次服务端失败'], ['validation_error', '下一次字段失败']].map(([value, label]) => ``).join('');
- roleSelect.value = state.role; scenarioSelect.value = state.scenario; responseSelect.value = state.response;
-}
-function renderNav() {
- const activeNav = ['tenantDetail', 'billingProfile'].includes(state.view) ? 'tenants' : state.view;
- sideNav.innerHTML = navGroups.map(([group, items]) => {
- const visible = items.filter(([id]) =>
- hasPermission(pageMeta[id].permission) && (!platformApi?.isEnabled() || API_CONNECTED_PAGES.has(id)));
- if (!visible.length) return '';
- return `${group}
${visible.map(([id, glyph, label]) => ``).join('')}`;
- }).join('');
- const staffShortcut = document.querySelector('.platform-foot>button');
- if (staffShortcut) staffShortcut.hidden = !hasPermission('platform:staff:read');
- const accountRole = document.querySelector('.platform-foot small');
- if (accountRole) accountRole.textContent = roleDefinitions[state.role]?.label || '平台管理员';
- const authenticatedUser = window.GongxuePlatformAuth?.getUser?.();
- const accountName = document.querySelector('.platform-foot strong');
- const accountAvatar = document.querySelector('.platform-foot>div>span');
- const displayName = authenticatedUser?.name || authenticatedUser?.email;
- if (accountName && displayName) accountName.textContent = displayName;
- if (accountAvatar && displayName) accountAvatar.textContent = displayName.slice(0, 1).toUpperCase();
-}
-function updateCounters() {
- const activeTasks = data.tasks.filter(task => ['pending', 'processing'].includes(task.status)).length;
- const openAlerts = data.alerts.filter(alert => alert.status === 'open').length;
- taskCount.textContent = activeTasks;
- taskCount.hidden = activeTasks === 0;
- alertCount.textContent = openAlerts;
- alertCount.hidden = openAlerts === 0;
-}
-function pageHead(title, description, actions = '', options = {}) {
- const level = options.level || pageMeta[state.view]?.level || 1;
- const nav = level > 1 ? `` : '';
- return `${nav}
${pageMeta[state.view]?.id || ''}${level > 1 ? ` · L${level}` : ''}${title}
${description}
${actions}
`;
-}
-function metric(label, value, note, glyph, style = 'blue') { return `${icon(glyph)}`; }
-function statusBadge(value) { return `${escapeHtml(value)}`; }
-function emptyBlock(title, description, action = '') { return `${icon('inbox')}${title}
${description}
${action}`; }
-function requestErrorBlock(partial = false) {
- const id = requestId();
- return `${icon(partial ? 'cloud-off' : 'triangle-alert')}${partial ? '部分数据暂时不可用' : '页面加载失败'}
${partial ? '主列表保留成功数据,右侧聚合区加载失败。' : 'Mock 服务返回错误,未泄露内部堆栈。'} Request ID:${id}
`;
-}
-function renderScenario(content) {
- if (state.scenario === 'session_invalid') return `${pageHead('会话已失效', '平台会话已过期或被管理员撤销。')}
${icon('log-in')}401 · 请重新登录
当前 Mock 已清理会话上下文,不展示任何平台业务数据。重新登录后返回安全首页。
`;
- if (!hasPermission(pageMeta[state.view]?.permission) || state.scenario === 'forbidden') return `${pageHead('没有访问权限', '当前演示角色无权访问此平台功能。')}
${icon('shield-x')}403 · 权限不足
需要权限 ${pageMeta[state.view]?.permission}。菜单会按权限隐藏,深链进入则显示此页面。
`;
- if (state.scenario === 'loading') return `${pageHead(pageMeta[state.view].title, '正在从 apps/api Mock 加载数据。')}
${Array.from({ length: 6 }, (_, index) => ``).join('')}超过 8 秒时可使用重试入口。
`;
- if (state.scenario === 'submitting') return `${pageHead(pageMeta[state.view].title, '正在提交 Mock 写请求。')}
${icon('loader-circle')}正在提交
按钮已防重复提交,输入内容会保留;完成后将显示结果摘要与唯一结果编号。
`;
- if (state.scenario === 'success') return `${pageHead(pageMeta[state.view].title, '本次 Mock 操作已完成。')}
${icon('circle-check')}操作成功
结果编号:RESULT-DEMO-20260723 · 已写入审计,可返回当前工作页继续处理。
`;
- if (state.scenario === 'error') return `${pageHead(pageMeta[state.view].title, '数据加载未完成。')}${requestErrorBlock()}
`;
- if (state.scenario === 'empty') return `${pageHead(pageMeta[state.view].title, '当前演示数据集为空。')}${emptyBlock('当前页面没有数据', '这是只存在于 Mock 原型的空状态演练。恢复“正常”即可继续测试真实交互。', '')}
`;
- if (state.scenario === 'partial_error') {
- const closingIndex = content.lastIndexOf('');
- return closingIndex >= 0 ? `${content.slice(0, closingIndex)}${requestErrorBlock(true)}${content.slice(closingIndex)}` : `${content}${requestErrorBlock(true)}`;
- }
- return content;
-}
-
-function businessStatusLabel(value) {
- const key = String(value || '').replace(/([a-z0-9])([A-Z])/g, '$1_$2').toLowerCase();
- return ({ draft: '草稿', active: '正常', published: '已发布', retired: '已下架', archived: '已归档', pending: '待处理', pending_payment: '待付款', paid: '已支付', succeeded: '已成功', failed: '失败', requested: '已申请', completed: '已完成', verified: '已验证', dns_pending: 'DNS 待验证', tls_pending: 'TLS 待就绪', disabled: '已停用' })[key] || value || '-';
-}
-
-function renderDomains() {
- return `${pageHead('租户域名与证书', '统一查看租户域名的 DNS 验证、证书和主域名状态,可对未就绪域名重新检查。')}
-
${data.domains.length ? '' : emptyBlock('暂无租户域名', '租户配置域名后将在这里显示。')} `;
-}
-
-function renderCatalog() {
- const catalog = data.saasCatalog || {};
- const features = catalog.features || [];
- const offerings = catalog.offerings || [];
- const versions = catalog.versions || [];
- const offeringName = id => offerings.find(item => item.id === id)?.name || id;
- return `${pageHead('SaaS 商品与版本', '管理可售套餐、增值服务、功能权益、使用限额和定价版本。', `
`)}
-
${icon('blocks')}功能${features.length}其中 ${features.filter(item => String(item.status).toLowerCase() === 'active').length} 项启用
${icon('packages')}商品${offerings.length}基础套餐与增值包
${icon('git-branch')}版本${versions.length}草稿、发布与下架生命周期
-
-
`;
-}
-
-function renderSaasFinance() {
- const tabs = [['orders', '订单'], ['payments', '支付'], ['refunds', '退款'], ['invoices', '发票'], ['subscriptions', '订阅']];
- const rows = state.saasFinanceTab === 'orders' ? data.saasOrders : state.saasFinanceTab === 'payments' ? data.billingPayments : state.saasFinanceTab === 'refunds' ? data.saasRefunds : state.saasFinanceTab === 'invoices' ? data.invoices : data.subscriptions;
- const cells = item => state.saasFinanceTab === 'orders' ? [item.orderNo, tenantById(item.tenantId)?.name || item.tenantId, item.purpose, money(Number(item.totalAmountCents || 0) / 100), businessStatusLabel(item.status), item.expiresAt] : state.saasFinanceTab === 'payments' ? [item.paymentNo || item.id, tenantById(item.tenantId)?.name || item.tenantId, item.provider || '-', money(item.amount), businessStatusLabel(item.status), item.paidAt || '-'] : state.saasFinanceTab === 'refunds' ? [item.refundNo || item.id, tenantById(item.tenantId)?.name || item.tenantId, item.reason || '-', money(Number(item.amountCents || 0) / 100), businessStatusLabel(item.status), item.completedAt || '-'] : state.saasFinanceTab === 'invoices' ? [item.id, tenantById(item.tenantId)?.name || item.tenantId, item.type, money(item.total), item.status, item.due] : [item.id, tenantById(item.tenantId)?.name || item.tenantId, item.planCode || '-', money(item.amount), item.status, item.expires];
- return `${pageHead('SaaS 订单与交易', '集中查看租户订购、收款、退款、开票和订阅情况。')}
${rows.length ? '' : emptyBlock('当前暂无数据', '有新的业务记录后会在这里显示。')} `;
-}
-
-function renderRoles() {
- return `${pageHead('平台角色与功能', '按岗位配置可访问的菜单和可执行的业务操作。', `
`)}
平台角色
${data.platformRoles.length} 个启用角色 ${data.platformRoles.map(role => `${icon('shield-check')}${escapeHtml(role.name)}${escapeHtml(role.description || '暂无角色说明')}
${role.permissionCodes.length} 项功能`).join('')}${Object.entries(data.platformPermissions).map(([code, name]) => `${icon('key-round')}${escapeHtml(name)}${escapeHtml(code)}
${data.platformRoles.filter(role => role.permissionCodes.includes(code) || role.permissionCodes.includes('*')).length} 个角色`).join('')} `;
-}
-
-function renderOverview() {
- if (platformApi?.isEnabled()) return renderApiOverview();
- const active = data.tenants.filter(tenant => tenant.status === '正常').length;
- const overdue = data.invoices.filter(invoice => invoice.status === '已逾期').reduce((sum, invoice) => sum + invoice.balance, 0);
- const openAlerts = data.alerts.filter(alert => alert.status === 'open').slice(0, 4);
- const totalStudents = data.tenants.reduce((sum, tenant) => sum + tenant.students, 0);
- const totalQuestions = data.banks.reduce((sum, bank) => sum + bank.questions, 0);
- return `${pageHead('平台经营工作台', '查看租户规模、订阅账务、平台用量与安全态势。数据更新时间:2026-07-23 10:10 CST。', `
`)}
-
${metric('有效租户', active, `共 ${data.tenants.length} 家`, 'building-2')}${metric('活跃订阅', data.subscriptions.filter(item => item.status === '活跃').length, '未来30天到期 2 条', 'badge-dollar-sign', 'green')}${metric('逾期应收', money(overdue), `涉及 ${data.invoices.filter(item => item.status === '已逾期').length} 家租户`, 'receipt-text', 'orange')}${metric('平台学生规模', formatNumber(totalStudents), 'Mock 最近30日活跃 82%', 'users', 'purple')}${metric('公共题库题目', formatNumber(totalQuestions), `${data.banks.length} 个公共来源库`, 'database-zap', 'cyan')}
-
平台收入与租户增长
最近 12 个月 · 不含租户学生端交易流水MRR有效租户
¥500k¥350k¥200k0
${[42, 48, 52, 58, 64, 71, 78, 82, 88, 94, 101, 108].map((value, index) => `${index + 1}月`).join('')}
-
${openAlerts.map(alert => ``).join('') || emptyBlock('没有开放告警', '平台当前没有需要处理的开放告警。')}
-
${data.tenants.length}全部租户
${[['正常', data.tenants.filter(t => t.status === '正常').length, 68], ['试用', data.tenants.filter(t => t.status === '试用').length, 16], ['待配置', data.tenants.filter(t => t.status === '待配置').length, 16], ['暂停/逾期', data.tenants.filter(t => t.status === '暂停' || t.billing === '逾期').length, 16]].map(([label, count, percent]) => `
${label}${count}
`).join('')}
-
待付款${money(data.invoices.filter(i => i.status === '待付款').reduce((s, i) => s + i.balance, 0))}可发送到期提醒
已逾期${money(overdue)}进入催缴处理
预估超额${money(data.usage.reduce((s, u) => s + u.estimated, 0))}需确认生成
-
`;
-}
-
-function renderApiOverview() {
- const overview = data.apiOverview || {};
- const openAlerts = data.alerts.filter(alert => alert.status === 'open').slice(0, 4);
- return `${pageHead('平台经营工作台', `真实 PostgreSQL 数据 · ${state.apiLoadedAt || '正在加载'}`, `
`)}
-
${metric('全部租户', overview.tenantCount ?? data.tenants.length, `活跃 ${overview.activeTenantCount ?? 0} 家`, 'building-2')}${metric('暂停租户', overview.suspendedTenantCount ?? 0, '来自真实租户状态', 'pause-circle', 'orange')}${metric('已支付订单', overview.paidOrderCount ?? 0, `全部订单 ${overview.orderCount ?? 0}`, 'receipt-text', 'green')}${metric('平台收入', money(Number(overview.revenueCents || 0) / 100), '按已支付订单统计', 'circle-dollar-sign', 'cyan')}${metric('题库 / 题目', `${overview.questionBankCount ?? 0} / ${formatNumber(overview.questionCount ?? 0)}`, `学习活跃用户 ${overview.learningActiveUserCount ?? 0}`, 'database-zap', 'purple')}
-
租户状态
来自 /api/platform-admin/tenants${data.tenants.length}全部租户
${[['正常', data.tenants.filter(item => item.status === '正常').length, 100], ['待配置', data.tenants.filter(item => item.status === '待配置').length, 100], ['暂停', data.tenants.filter(item => item.status === '暂停').length, 100]].map(([label, count, percent]) => `
${label}${count}
`).join('')}
-
${openAlerts.map(alert => ``).join('') || emptyBlock('没有开放告警', '当前数据库没有需要处理的开放告警。')}
-
`;
-}
-
-function renderTenants() {
- let rows = data.tenants.filter(tenant => state.tenantFilter === 'all' || tenant.status === state.tenantFilter || tenant.billing === state.tenantFilter);
- if (state.tenantPlan !== 'all') rows = rows.filter(tenant => tenant.planCode === state.tenantPlan);
- const query = state.tenantSearch.trim().toLowerCase();
- if (query) rows = rows.filter(tenant => [tenant.name, tenant.slug, tenant.legal, tenant.host].some(value => value.toLowerCase().includes(query)));
- if (state.scenario === 'empty') rows = [];
- return `${pageHead('租户列表与创建', '搜索租户并管理主体、域名、套餐、业务状态与账务状态。', `${platformApi?.isEnabled() ? '' : `
`}${canWrite('platform:tenant:write') ? `
` : ''}`)}
-
- ${rows.length ? `
` : emptyBlock(query || state.tenantFilter !== 'all' || state.tenantPlan !== 'all' ? '没有匹配的租户' : '还没有租户', query || state.tenantFilter !== 'all' || state.tenantPlan !== 'all' ? '调整搜索词或筛选条件后重试。' : '创建第一个租户及首期订阅基础。', canWrite('platform:tenant:write') ? `
` : '')}
`;
-}
-
-function renderTenantDetail() {
- const tenant = tenantById(state.selectedTenant) || data.tenants[0];
- if (!tenant) return `${pageHead('租户详情与生命周期', '租户不存在或已被移除。', '', { level: 2 })}${emptyBlock('租户不存在', '返回租户列表选择其他租户。', '')}
`;
- const subscription = data.subscriptions.find(item => item.tenantId === tenant.id);
- const invoices = data.invoices.filter(item => item.tenantId === tenant.id);
- const usage = data.usage.find(item => item.tenantId === tenant.id);
- return `${pageHead(tenant.name, `${tenant.slug} · ${tenant.legal}`, `
${canWrite('platform:tenant:status') ? `
` : ''}`, { level: 2 })}
-
业务状态${statusBadge(tenant.status)}
账务状态${statusBadge(tenant.billing)}
当前套餐${escapeHtml(tenant.plan)}
订阅到期${tenant.expires || '-'}
待付余额${money(tenant.balance)}
-
- 主体名称
- ${escapeHtml(tenant.legal)}
- 租户 ID
${tenant.id}- 负责人
- ${escapeHtml(tenant.owner)} · ${escapeHtml(tenant.ownerPhone)}
- 开通时间
- ${escapeHtml(tenant.createdAt)} CST
- 学生端域名
- ${escapeHtml(tenant.host)} ${statusBadge('已验证')}
- 租户后台域名
- admin.${escapeHtml(tenant.host.replace(/^study\.|^learn\.|^app\.|^tiku\./, ''))} ${statusBadge('已验证')}
-
-
租户创建${tenant.createdAt} CST · 主体与初始模式已保存
域名验证${tenant.host} · HTTPS 正常
订阅生效${subscription ? `${subscription.start} 至 ${subscription.expires}` : '待创建订阅'}
账务状态${tenant.billing}${tenant.balance ? ` · 待付 ${money(tenant.balance)}` : ''}
`;
-}
-
-function renderBillingProfile() {
- const tenant = tenantById(state.selectedTenant) || data.tenants[0];
- const profile = data.billingProfiles[tenant.id] || {};
- const readOnly = !canWrite('platform:tenant:billing_profile');
- return `${pageHead('租户账务资料', `${tenant.name} · 银行账号仅展示脱敏值,密钥和完整账号不得回显。`, `
`, { level: 3 })}
-
`;
-}
-
-function renderSubscriptions() {
- const selectedTenant = state.selectedTenant ? tenantById(state.selectedTenant) : null;
- const rows = state.scenario === 'empty' ? [] : data.subscriptions;
- return `${pageHead('SaaS 套餐与订阅', '查看套餐权益,并为租户创建或续订订阅。套餐内容请在“商品与版本”中维护。', `
${canWrite('platform:billing:write') ? `
` : ''}`)}
-
${data.plans.map((plan, index) => `
${plan.name}${plan.description}
${plan.tenantCount} 家租户${money(plan.amount)}/年${plan.quotas.map(item => `- ${icon('check')}${item}
`).join('')}
`).join('')}
- ${rows.length ? `
活跃与试用订阅
${rows.length} 条${selectedTenant ? ` · 已定位 ${selectedTenant.name}` : ''}` : emptyBlock('还没有订阅', '创建租户订阅后将在此显示。', canWrite('platform:billing:write') ? '
' : '')}
`;
-}
-
-function renderBilling() {
- const query = state.invoiceSearch.trim().toLowerCase();
- const rows = state.scenario === 'empty' ? [] : data.invoices.filter(invoice => (!state.selectedTenant || invoice.tenantId === state.selectedTenant) && (state.invoiceStatus === 'all' || invoice.status === state.invoiceStatus) && (!query || [invoice.id, invoice.type, invoice.period, invoice.note, tenantById(invoice.tenantId)?.name].some(value => String(value || '').toLowerCase().includes(query))));
- const unpaid = data.invoices.filter(invoice => invoice.status === '待付款').reduce((sum, invoice) => sum + invoice.balance, 0);
- const overdue = data.invoices.filter(invoice => invoice.status === '已逾期').reduce((sum, invoice) => sum + invoice.balance, 0);
- return `${pageHead('服务费账单', '查询、手工创建、预览订阅账单候选并通过 dry-run 确认批量生成。', `${canWrite('platform:billing:write') ? `
` : ''}`)}
-
${metric('本月应收', money(data.invoices.reduce((s, i) => s + i.total, 0)), `${data.invoices.length} 张账单`, 'receipt-text')}${metric('已收款', money(data.invoices.reduce((s, i) => s + i.paid, 0)), '人工收款需二次确认', 'circle-dollar-sign', 'green')}${metric('待付款', money(unpaid), '可发送到期提醒', 'clock-3', 'orange')}${metric('已逾期', money(overdue), `${data.invoices.filter(i => i.status === '已逾期').length} 家租户`, 'triangle-alert', 'red')}
-
${contractResult('invoice-query')}
-
- ${rows.length ? `
` : emptyBlock('没有匹配账单', query || state.invoiceStatus !== 'all' ? '调整账单查询条件后重试。' : state.selectedTenant ? '当前租户没有匹配账单,可清除租户上下文查看全部。' : '账单候选生成后会在这里显示。', state.selectedTenant ? '
' : '')}
`;
-}
-
-function renderUsage() {
- const periodRows = data.usage.filter(item => item.period === state.usagePeriod);
- const rows = state.scenario === 'empty' ? [] : periodRows.filter(item => !state.selectedTenant || item.tenantId === state.selectedTenant);
- const periodLabel = state.usagePeriod.replace('-', '年') + '月';
- return `${pageHead('用量与超额计费', '按账期查看学生席位、题目、存储与流量用量;区分 Worker 自动采集和人工补录。', `
${canWrite('platform:usage:write') ? `
` : ''}`)}
-
${periodLabel}学生席位${formatNumber(periodRows.reduce((s, i) => s + i.students, 0))}合同总量 176,000
题目数量${formatNumber(periodRows.reduce((s, i) => s + i.questions, 0))}合同总量 495,000
对象存储${formatNumber(periodRows.reduce((s, i) => s + i.storageGB, 0))} GB合同总量 13.5 TB
预估超额费${money(periodRows.reduce((s, i) => s + i.estimated, 0))}涉及 ${periodRows.filter(i => i.estimated).length} 家租户
- ${rows.length ? `
` : emptyBlock('本账期没有用量记录', '可以手工补录,或等待 Worker 自动采集。', canWrite('platform:usage:write') ? '
' : '')}
`;
-}
-
-function renderDunning() {
- const overdueInvoices = data.invoices.filter(invoice => invoice.status === '已逾期' || invoice.status === '待付款');
- return `${pageHead('收款、逾期与催缴', '人工确认收款、dry-run 预览逾期处理、生成催缴并跟踪通知事件。', `${canWrite('platform:billing:dunning') ? `
` : ''}${canWrite('platform:billing:notification') ? `
` : ''}`)}
-
- ${state.billingTab === 'collections' ? `
待收与逾期队列
${overdueInvoices.length} 张账单 ${overdueInvoices.map(invoice => { const tenant = tenantById(invoice.tenantId); return `${icon('building-2')}${escapeHtml(tenant?.name || '-')}${invoice.id} · 到期 ${invoice.due} · ${invoice.status}
${money(invoice.balance)}`; }).join('') || emptyBlock('没有待处理账单', '已无待收或逾期服务费账单。')}到期前 7 天邮件 + 租户后台通知
到期当天短信 + 邮件 + 租户后台通知
逾期 3 天升级财务负责人并限制部分写操作
逾期 7 天暂停租户业务,保留只读访问
` : state.billingTab === 'reminders' ? `
` : state.billingTab === 'channels' ? `
` : `
`}
`;
-}
-
-function renderBank() {
- const selected = bankById(state.selectedBank) || data.banks[0];
- if (selected && state.selectedBank !== selected.id) state.selectedBank = selected.id;
- const query = state.bankSearch.trim().toLowerCase();
- const bankRows = data.banks.filter(bank => !query || [bank.name, bank.status].some(value => String(value || '').toLowerCase().includes(query)));
- const nodes = data.bankNodes.filter(node => node.questionBankId === selected?.id);
- const nodeOptions = nodes.filter(node => node.isActive).map(node => ``).join('');
- const tabs = [['structure', '内容结构'], ['single', '单题录入'], ['batch', '批量导入'], ['manage', '题目管理'], ['structured', 'JSON 文件导入']];
- const bankSelect = ``;
- let content = emptyBlock('尚未创建公共题库', '点击“新建题库”后即可配置分类、科目、章节和试卷。');
- if (selected && state.bankTab === 'structure') content = `平台公共题库${escapeHtml(selected.name)}
通过分类、科目、章节和试卷组织题目。
内容节点${selected.nodes || nodes.length}
题目总数${formatNumber(selected.questions || 0)}
启用节点${nodes.filter(item => item.isActive).length}
题库状态${selected.status}
${state.selectedBankNode ? `${bankNodeTypeLabel(bankNodeById(state.selectedBankNode)?.nodeType)}${escapeHtml(bankNodeById(state.selectedBankNode)?.name || '')}
当前节点共 ${bankNodeById(state.selectedBankNode)?.questionCount || 0} 道未归档题目。
` : ''} `;
- if (selected && state.bankTab === 'structure' && state.selectedBankNode) content += `节点排序
调整当前节点在同级内容中的显示顺序 `;
- if (selected && state.bankTab === 'single') content = ``;
- if (selected && state.bankTab === 'batch') content = `${renderBankImportResult()}`;
- if (selected && state.bankTab === 'manage') content = `${data.bankQuestions.length ? `共 ${state.bankQuestionTotal} 道题 ` : emptyBlock('暂无题目', '选择节点后查询,或先录入、导入题目。')}`;
- if (selected && state.bankTab === 'structured') content = `JSON 文件导入
支持带分类、科目、章节/试卷和题目的 2.0 结构化文件 ${renderBankImportResult()}`;
- return `${pageHead('公共题库', '配置公共题库内容结构,完成单题录入、题目管理和两种 JSON 导入。', `${selected ? `` : ''}`)}${contractResult('bank-query')}${content}
`;
-}
-
-function renderBankImportResult() {
- const result = data.bankImportResult;
- if (!result) return '';
- const job = result.detail?.job || result.job || {};
- const issues = result.detail?.issues || result.issues || [];
- return `${job.dryRun ? '预检完成' : '导入完成'}共 ${job.totalCount || 0} 条,${job.validCount || 0} 条有效
新增题目 ${result.insertedQuestionCount || 0},更新 ${result.updatedQuestionCount || 0},跳过 ${result.skippedQuestionCount || 0},新建节点 ${result.createdNodeCount || 0}。
${issues.length ? `
${issues.slice(0, 8).map(item => `第 ${item.rowNo || '-'} 行:${escapeHtml(item.message)}`).join('
')}` : '
没有发现数据问题。'}
`;
-}
-
-function renderCrm() {
- const activeConfigs = data.crmConfigs.filter(item => item.enabled).length;
- const failedLeads = data.crmLeads.filter(item => item.status === '推送失败').length;
- const notice = '集中维护租户线索推送配置、失败队列、分配策略和同步日志。';
- if (state.crmTab === 'logs') return `${pageHead('CRM 推送日志', notice)}
${data.crmLogs.length ? '' : emptyBlock('暂无 CRM 推送日志', '线索推送后会在这里保留请求结果与错误摘要。')} `;
- return `${pageHead('CRM 接入与线索流转', notice, `${canWrite('platform:crm:write') ? `
` : ''}`)}
-
已启用接入${activeConfigs}共 ${data.crmConfigs.length} 家租户配置
待推送线索${data.crmLeads.filter(item => item.status === '待推送').length}来自学生端留资与活动报名
推送失败${failedLeads}进入重试或死信处理
权限${hasPermission('platform:crm:write') ? '可维护' : '只读'}platform:crm:read/write
-
- ${state.crmTab === 'configs' ? `
` : state.crmTab === 'leads' ? `
` : `
${[['按地区轮转', '地区、校区、课程标签优先,适合多校区机构'], ['按校区容量', '按顾问容量与当日跟进上限分配'], ['手工分配', '只进入队列,由租户管理员手工认领']].map(([name, desc]) => `${icon('route')}${name}${desc}
启用`).join('')}接入配置维护 endpoint、secret 引用、超时和重试策略
线索队列集中查看待推送、失败和重试中的线索
同步日志保留请求结果、错误摘要和审计线索
`}
`;
-}
-
-function renderSms() {
- const sent = data.smsChannels.reduce((sum, item) => sum + item.used, 0);
- const quota = data.smsChannels.reduce((sum, item) => sum + item.quota, 0);
- const notice = '集中管理租户短信渠道、模板审核状态和发送记录。';
- const smsNav = ``;
- if (state.smsTab === 'templates') return `${pageHead('短信模板与审核', notice, `
`)}${smsNav}
`;
- if (state.smsTab === 'logs') return `${pageHead('短信发送日志', notice)}${smsNav}
${data.smsLogs?.length ? '' : emptyBlock('暂无短信发送日志', '发送短信后会在这里显示脱敏记录。')} `;
- return `${pageHead('SMS 短信服务', notice, `${canWrite('platform:sms:write') ? `
` : ''}`)}
-
启用渠道${data.smsChannels.filter(item => item.enabled).length}租户自有短信服务
本月发送${formatNumber(sent)}总额度 ${formatNumber(quota)}
模板通过${data.smsTemplates.filter(item => item.status === '已通过').length}${data.smsTemplates.length} 个模板
权限${hasPermission('platform:sms:write') ? '可维护' : '只读'}platform:sms:read/write
-
- ${state.smsTab === 'channels' ? `
` : state.smsTab === 'templates' ? `
` : `
`}
`;
-}
-
-function renderPaymentSettings() {
- const activeApps = data.paymentApps.filter(item => item.status === '正常').length;
- const notice = '集中管理平台收款、租户支付代管、支付渠道和回调健康。';
- const paymentNav = ``;
- if (state.paymentTab === 'channels') return `${pageHead('平台支付渠道', '管理平台收款应用的支付服务商、回调地址和密钥引用。', `
`)}${paymentNav}
${data.paymentChannels.length ? '' : emptyBlock('暂无平台支付渠道', '请先创建平台收款应用。')} `;
- if (state.paymentTab === 'rebates') { const summary = data.rebateSummary || {}; return `${pageHead('平台返佣汇总', '查看平台交易的返佣、待结算、已结算与异常数据。')}${paymentNav}
交易总额${money(Number(summary.grossAmountCents || 0) / 100)}返佣总额${money(Number(summary.commissionAmountCents || 0) / 100)}待结算${money(Number(summary.pendingSettlementCents || 0) / 100)}已结算${money(Number(summary.paidSettlementCents || 0) / 100)}异常数${summary.exceptionCount || 0} `; }
- return `${pageHead('支付设置', notice, `${canWrite('platform:payment:write') ? `
` : ''}`)}
-
正常应用${activeApps}共 ${data.paymentApps.length} 个收款应用
本日支付事件${data.paymentEvents.length}含成功、回调失败与人工确认
回调异常${data.paymentEvents.filter(item => item.status === '回调失败').length}需要财务或运维介入
权限${hasPermission('platform:payment:write') ? '可维护' : '只读'}platform:payment:read/write
- ${paymentNav}
- ${state.paymentTab === 'apps' ? `
` : state.paymentTab === 'events' ? `
` : `
平台风控规则
配置证书、回调、人工确认等支付安全策略 ${[['证书过期提醒', '支付证书 14 天内过期生成高危告警'], ['回调失败重试', '按 1m/5m/30m/2h 退避重试并记录审计'], ['人工确认保护', '线下收款必须二次确认并保留流水号脱敏值']].map(([name, desc]) => `${icon('shield-check')}${name}${desc}
启用`).join('')}平台收款应用用于套餐、模块和增值服务收款
租户代管应用维护学生端收款渠道和回调地址
支付事件只读跟踪交易、退款、回调和人工确认状态
`}
`;
-}
-
-function renderStaff() {
- const query = state.staffSearch.trim().toLowerCase();
- const staffRows = data.staff.filter(person => !query || [person.name, person.username, person.email, person.phone, person.role, person.status].some(value => String(value || '').toLowerCase().includes(query)));
- return `${pageHead('平台员工与权限', '平台权限独立于租户权限;禁用员工可同步撤销会话,且不能禁用最后一名超级管理员。', `${canWrite('platform:staff:write') ? `
` : ''}`)}
-
-
平台员工
${staffRows.length} 名匹配 · ${data.staff.filter(item => item.status === '正常').length} 名活跃 ${staffRows.map(person => `${escapeHtml(person.name.slice(0, 1))}${escapeHtml(person.name)}${escapeHtml(person.email)} · ${escapeHtml(person.phone)}
${escapeHtml(person.role)}${person.permissions.includes('*') ? '全部平台功能' : `${person.permissions.length} 项功能`}${person.status}`).join('') || emptyBlock('没有匹配员工', '调整姓名、邮箱、手机号、角色或状态关键词。')}${data.platformRoles.map(role => { const features = role.permissionCodes.map(code => data.platformPermissions[code] || code); return `${icon('shield-check')}${escapeHtml(role.name)}${escapeHtml(role.description || (features.includes('*') ? '全部平台功能' : features.join('、')))}
${data.staff.filter(person => person.roleIds?.includes(role.id)).length}人`; }).join('') || emptyBlock('暂无可用平台角色', '请先创建平台角色并选择可用功能。')} `;
-}
-
-function renderAudit() {
- let rows = data.auditLogs.filter(log => state.auditSeverity === 'all' || log.severity === state.auditSeverity);
- if (state.auditRange === '24h') rows = rows.filter(log => log.time.startsWith('2026-07-23'));
- const query = state.auditSearch.toLowerCase();
- if (query) rows = rows.filter(log => [log.id, log.actor, log.action, log.target, log.ip].some(value => value.toLowerCase().includes(query)));
- if (state.scenario === 'empty') rows = [];
- const relatedAlertCount = data.alerts.filter(alert => rows.some(log => log.targetId === alert.targetId || log.targetId === alert.id)).length;
- return `${pageHead('平台审计日志', '检索跨租户敏感操作、账务变更与权限事件;导出任务提供文件、hash 和行数。', `
`)}
-
- ${rows.length ? `
` : emptyBlock('没有审计日志', '调整时间范围、严重级别或搜索条件。')}
`;
-}
-
-function renderAlerts() {
- let alerts = state.alertStatus === 'all' ? data.alerts : data.alerts.filter(alert => alert.status === state.alertStatus);
- if (state.scenario === 'empty') alerts = [];
- return `${pageHead('审计告警与通知', '按 open → acknowledged → resolved/ignored 流转;状态接口禁止重新打开。规则当前只读。', `${canWrite('platform:audit:notification') ? `
` : ''}`)}
-
告警规则
${data.alertRules.length} 条启用规则${data.alertRules.map(rule => `
${rule.severity}${escapeHtml(rule.name)}${escapeHtml(rule.code)} · ${escapeHtml(rule.window)} · ${escapeHtml(rule.threshold)}${escapeHtml(rule.target)}
${statusBadge(rule.enabled ? '启用' : '已停用')}`).join('')}
-
告警队列
开放 ${data.alerts.filter(a => a.status === 'open').length} · 已确认 ${data.alerts.filter(a => a.status === 'acknowledged').length} · 已结束 ${data.alerts.filter(a => ['resolved', 'ignored'].includes(a.status)).length}${[['all', '全部'], ['open', '开放'], ['acknowledged', '已确认'], ['resolved', '已解决'], ['ignored', '已忽略']].map(([value, label]) => ``).join('')}
${alerts.length ? alerts.map(alert => `${alert.severity}${alert.id} · ${alert.owner}${escapeHtml(alert.title)}${escapeHtml(alert.summary)}
${alert.updatedAt} ${alertStatusLabel(alert.status)}${alert.status === 'open' && canWrite('platform:audit:alert') ? `` : ''}${['open', 'acknowledged'].includes(alert.status) && canWrite('platform:audit:alert') ? `` : ''}
`).join('') : emptyBlock('当前筛选没有告警', '告警规则仍保持只读,可切换筛选查看历史状态。')}
-
`;
-}
-
-const templates = { overview: renderOverview, tenants: renderTenants, domains: renderDomains, tenantDetail: renderTenantDetail, billingProfile: renderBillingProfile, catalog: renderCatalog, subscriptions: renderSubscriptions, saasFinance: renderSaasFinance, billing: renderBilling, usage: renderUsage, dunning: renderDunning, bank: renderBank, crm: renderCrm, sms: renderSms, paymentSettings: renderPaymentSettings, staff: renderStaff, roles: renderRoles, audit: renderAudit, alerts: renderAlerts };
-
-function render() {
- renderNav();
- const meta = pageMeta[state.view] || pageMeta.overview;
- pageTitle.textContent = `${meta.id} · ${meta.title}`;
- mainView.innerHTML = renderScenario((templates[state.view] || renderOverview)());
- closeMobileMenu();
- roleSelect.value = state.role; scenarioSelect.value = state.scenario; responseSelect.value = state.response;
- updateCounters(); refreshIcons();
- window.decoratePlatformSpec?.(mainView, meta.id);
- decorateAccessibleControls(mainView);
- updateBackendStatus();
-}
-function renderOverlay() {
- if (!state.modal) { overlayRoot.innerHTML = ''; return; }
- const renderer = modalTemplates[state.modal];
- overlayRoot.innerHTML = renderer ? renderer() : '';
- refreshIcons();
- window.decoratePlatformSpec?.(overlayRoot, pageMeta[state.view]?.id || '');
- decorateAccessibleControls(overlayRoot);
- requestAnimationFrame(() => {
- const modal = overlayRoot.querySelector('.modal');
- modal?.querySelector('input:not([type="hidden"]),select,textarea,button')?.focus();
- });
-}
-let toastTimer;
-let lastOverlayTrigger = null;
-function showToast(message, kind = 'success') {
- toast.querySelector('span').textContent = message;
- toast.classList.toggle('is-error', kind === 'error');
- toast.classList.add('is-visible');
- clearTimeout(toastTimer); toastTimer = setTimeout(() => toast.classList.remove('is-visible'), 2800);
-}
-function openModal(name, modalData = {}) {
- const activeElement = document.activeElement;
- if (!state.modal && activeElement instanceof HTMLElement && activeElement !== document.body && !overlayRoot.contains(activeElement)) lastOverlayTrigger = activeElement;
- state.modal = name;
- state.modalData = { ...modalData, dirty: false };
- renderOverlay();
-}
-function markDirty(scope) { dirtyScopes.add(scope); if (scope === 'modal') state.modalData.dirty = true; }
-function clearDirty(scope = '') { if (scope) dirtyScopes.delete(scope); else dirtyScopes.clear(); if (!scope || scope === 'modal') state.modalData.dirty = false; }
-function hasUnsavedChanges(scope = '') { return scope ? dirtyScopes.has(scope) || (scope === 'modal' && state.modalData.dirty) : dirtyScopes.size > 0 || Boolean(state.modalData.dirty); }
-function renderLeaveGuard() {
- if (!pendingLeave) return;
- let root = document.querySelector('#unsavedLeaveGuard');
- if (!root) { root = document.createElement('div'); root.id = 'unsavedLeaveGuard'; document.body.append(root); }
- root.className = 'unsaved-leave-guard';
- root.innerHTML = `全局 · 离开保护有未保存的修改
离开前请确认如何处理当前编辑内容。
${icon('triangle-alert')}放弃离开后,本次尚未提交的表单修改不会写入 Mock 数据;已保存内容不受影响。
`;
- refreshIcons(); requestAnimationFrame(() => root.querySelector('[data-leave-choice="stay"]')?.focus());
-}
-function closeLeaveGuard() { document.querySelector('#unsavedLeaveGuard')?.remove(); }
-function requestLeave(execute, { scope = '' } = {}) {
- if (!hasUnsavedChanges(scope)) { execute(); return true; }
- pendingLeave = { execute, scope }; renderLeaveGuard(); return false;
-}
-function closeModal(options = {}) {
- const close = () => {
- clearDirty('modal');
- const trigger = lastOverlayTrigger;
- state.modal = '';
- state.modalData = {};
- lastOverlayTrigger = null;
- renderOverlay();
- if (trigger?.isConnected) requestAnimationFrame(() => trigger.focus());
- };
- if (state.modal && !options.force && hasUnsavedChanges('modal')) return requestLeave(close, { scope: 'modal' });
- close();
- return true;
-}
-function navigationSnapshot() {
- return { view: state.view, selectedTenant: state.selectedTenant, selectedInvoice: state.selectedInvoice, selectedAlert: state.selectedAlert, tenantFilter: state.tenantFilter, tenantPlan: state.tenantPlan, tenantSearch: state.tenantSearch, invoiceSearch: state.invoiceSearch, invoiceStatus: state.invoiceStatus, billingTab: state.billingTab, bankTab: state.bankTab, crmTab: state.crmTab, smsTab: state.smsTab, paymentTab: state.paymentTab, saasFinanceTab: state.saasFinanceTab, bankSearch: state.bankSearch, selectedBank: state.selectedBank, selectedBankNode: state.selectedBankNode, staffSearch: state.staffSearch, usagePeriod: state.usagePeriod, auditRange: state.auditRange, auditSeverity: state.auditSeverity, auditSearch: state.auditSearch, alertStatus: state.alertStatus, scrollY: window.scrollY };
-}
-function syncNavigationState() { if (history.state?.[HISTORY_APP_KEY]) history.replaceState({ ...history.state, snapshot: navigationSnapshot() }, '', location.href); }
-function navigate(view, options = {}) {
- if (!pageMeta[view]) return;
- if (platformApi?.isEnabled() && !API_CONNECTED_PAGES.has(view)) {
- showToast('该模块当前不可用,请先完成后端配置后再访问', 'error');
- return false;
- }
- const perform = () => {
- clearDirty();
- if (!hasPermission(pageMeta[view].permission)) { state.previousView = state.view; state.view = view; state.scenario = 'forbidden'; render(); return; }
- if (options.push !== false) {
- const nextEntry = navigationSnapshot();
- const last = state.history[state.history.length - 1];
- if (!last || last.view !== nextEntry.view || last.selectedTenant !== nextEntry.selectedTenant) state.history = [...state.history.slice(-2), nextEntry];
- if (options.browser !== false && history.state?.[HISTORY_APP_KEY]) history.replaceState({ ...history.state, snapshot: nextEntry }, '', location.href);
- }
- state.previousView = state.view; state.view = view; state.scenario = 'normal'; closeModal({ force: true }); render(); scrollTo(0, 0);
- if (options.browser !== false) { historySequence += 1; history.pushState({ [HISTORY_APP_KEY]: true, sequence: historySequence, snapshot: navigationSnapshot() }, '', location.href); }
- if (['tenantDetail', 'billingProfile'].includes(view)) hydrateTenantDetail(state.selectedTenant);
- if (view === 'bank') loadBankWorkspace();
- };
- if (!options.force && hasUnsavedChanges()) return requestLeave(perform);
- perform(); return true;
-}
-function navigateBack() {
- requestLeave(() => {
- clearDirty();
- if (history.state?.[HISTORY_APP_KEY] && history.length > 1) { history.back(); return; }
- const prior = state.history.pop();
- if (!prior) { state.view = 'overview'; state.previousView = ''; render(); scrollTo(0, 0); return; }
- Object.assign(state, prior); render(); requestAnimationFrame(() => scrollTo(0, prior.scrollY || 0));
- });
-}
-function closeSubpage() {
- requestLeave(() => { clearDirty(); state.history = []; state.view = 'overview'; state.previousView = ''; state.scenario = 'normal'; render(); scrollTo(0, 0); history.replaceState({ [HISTORY_APP_KEY]: true, sequence: historySequence, snapshot: navigationSnapshot() }, '', location.href); });
-}
-window.addEventListener('popstate', event => {
- const entry = event.state;
- if (!entry?.[HISTORY_APP_KEY] || !entry.snapshot) return;
- const targetSequence = Number(entry.sequence) || 0;
- if (restoringHistory) { restoringHistory = false; return; }
- if (hasUnsavedChanges() && !bypassHistoryGuard) {
- const delta = targetSequence - historySequence;
- restoringHistory = true; history.go(-delta);
- requestLeave(() => { bypassHistoryGuard = true; history.go(delta); });
- return;
- }
- bypassHistoryGuard = false; historySequence = targetSequence; clearDirty();
- const currentView = state.view;
- Object.assign(state, entry.snapshot, { previousView: currentView, scenario: 'normal', modal: '', modalData: {} });
- lastOverlayTrigger = null;
- if (state.history.length && state.history[state.history.length - 1].view === state.view) state.history.pop();
- render();
- requestAnimationFrame(() => scrollTo(0, entry.snapshot.scrollY || 0));
- if (entry.rootGuard) { historySequence += 1; history.pushState({ [HISTORY_APP_KEY]: true, sequence: historySequence, snapshot: navigationSnapshot() }, '', location.href); }
-});
-function nextResponse() {
- const response = state.response;
- if (response !== 'success') { state.response = 'success'; responseSelect.value = 'success'; }
- return response;
-}
-async function simulateWrite({ key, permission, validate, apply, success, close = true, rerender = true, operationId = '', body, request: executeRequest }) {
- if (!canWrite(permission)) { showToast(`缺少写权限:${permission}`, 'error'); return; }
- const validation = validate?.();
- if (validation) { showFormErrors(validation); return; }
- const mockResponse = platformApi?.isEnabled() ? 'success' : nextResponse();
- state.submitting = key;
- const activeForm = overlayRoot.querySelector('form') || mainView.querySelector('form');
- const submitButton = activeForm && (activeForm.querySelector('[type="submit"]') || document.querySelector(`[type="submit"][form="${activeForm.id}"]`));
- const submitMarkup = submitButton?.innerHTML;
- if (submitButton) { submitButton.disabled = true; submitButton.innerHTML = `${icon('loader-circle')}提交中`; refreshIcons(); }
- const finish = async () => {
- if (mockResponse !== 'success') {
- state.submitting = '';
- const id = requestId();
- addAudit(`${key}.failed`, 'mock_request', id, key, mockResponse === 'validation_error' ? '中' : '高', `${mockResponse === 'validation_error' ? '服务端字段校验失败' : 'Mock 写请求失败'},Request ID:${id}。`, '失败');
- showToast(`${mockResponse === 'validation_error' ? '服务端字段校验失败' : '提交失败'} · ${id}`, 'error');
- if (mockResponse === 'validation_error') showFormErrors({ server: `服务端拒绝本次输入(${id})` });
- if (submitButton) { submitButton.disabled = false; submitButton.innerHTML = submitMarkup; refreshIcons(); }
- return;
- }
- try {
- let payload = null;
- if (platformApi?.isEnabled()) {
- if (typeof executeRequest === 'function') payload = await executeRequest();
- else if (operationId) {
- const input = typeof body === 'function' ? body() : (body || {});
- payload = await platformApi.request(operationId, { body: platformApi.buildBody(operationId, input) });
- } else {
- throw new Error(`操作 ${key} 尚未配置后端 operationId`);
- }
- } else {
- await new Promise(resolve => setTimeout(resolve, 650));
- }
- state.submitting = '';
- clearDirty(activeForm?.closest('#overlayRoot') ? 'modal' : 'page');
- const result = apply(payload); saveData();
- if (close) closeModal({ force: true });
- if (rerender) render();
- showToast(typeof success === 'function' ? success(result) : success);
- if (platformApi?.isEnabled()) hydrateFromBackend({ silent: true });
- } catch (error) {
- const id = error.requestId || requestId();
- state.submitting = '';
- showToast(backendErrorText(error, '提交失败'), 'error');
- if (error.status === 400) showFormErrors({ server: backendErrorText(error, '服务端字段校验失败') });
- if (submitButton) { submitButton.disabled = false; submitButton.innerHTML = submitMarkup; refreshIcons(); }
- }
- };
- finish();
-}
-async function executeBackendMutation(operationId, input, apply, { refresh = true, pathParams = {} } = {}) {
- if (!platformApi?.isEnabled()) {
- apply?.(null);
- return true;
- }
- try {
- const payload = await platformApi.request(operationId, {
- body: platformApi.buildBody(operationId, typeof input === 'function' ? input() : input),
- pathParams,
- });
- apply?.(payload);
- if (refresh) hydrateFromBackend({ silent: true });
- return true;
- } catch (error) {
- showToast(backendErrorText(error, '提交失败'), 'error');
- return false;
- }
-}
-function showFormErrors(errors) {
- const form = overlayRoot.querySelector('form') || mainView.querySelector('form');
- if (!form) { showToast(Object.values(errors)[0], 'error'); return; }
- form.querySelectorAll('.field-error').forEach(node => node.remove());
- form.querySelectorAll('.is-invalid').forEach(node => node.classList.remove('is-invalid'));
- const summary = form.querySelector('.form-error-summary');
- if (summary) { summary.hidden = false; summary.innerHTML = `请修正以下问题${Object.values(errors).map(message => `- ${escapeHtml(message)}
`).join('')}
`; summary.focus(); }
- Object.entries(errors).forEach(([name, message]) => {
- const input = form.elements[name];
- if (!input) return;
- input.classList.add('is-invalid');
- input.insertAdjacentHTML('afterend', `${escapeHtml(message)}`);
- });
- const first = form.querySelector('.is-invalid'); first?.focus();
-}
-
-function modalFrame(title, description, content, actions = '', options = {}) {
- return `${options.id || '平台操作'}${title}
${description}
${content}${actions ? `` : ''} `;
-}
-function formField(label, name, value = '', attrs = '') { return ``; }
-function tenantOptions(selected = '') { return data.tenants.map(tenant => ``).join(''); }
-function planOptions(selected = '') { return data.plans.map(plan => ``).join(''); }
-function notificationProviderOptions(selected = '') {
- const normalized = ({ Webhook: 'generic', SMTP: 'generic', 邮件: 'generic', 短信: 'generic', 钉钉: 'dingtalk', 飞书: 'feishu', 企微: 'wecom' })[selected] || selected || 'generic';
- return [['generic', '通用 Webhook'], ['dingtalk', '钉钉'], ['feishu', '飞书'], ['wecom', '企微']]
- .map(([value, label]) => ``)
- .join('');
-}
-function channelEndpointFormValue(channel) {
- return platformApi?.isEnabled() && channel.endpointRedacted ? '' : channel.endpoint || '';
-}
-
-const modalTemplates = {
- saasFeature() {
- return modalFrame('新建 SaaS 功能', '功能将用于套餐版本与租户权益校验。', ``, ``, { id: 'SaaS 商品目录', wide: true });
- },
- saasOffering() {
- return modalFrame('新建 SaaS 商品', '商品可为基础套餐或增值包。', ``, ``, { id: 'SaaS 商品目录', wide: true });
- },
- saasLimit() {
- const features = data.saasCatalog?.features || [];
- return modalFrame('新建 SaaS 功能限额', '限额定义供套餐版本配置和运行时用量校验使用。', ``, ``, { id: 'SaaS 功能限额', wide: true });
- },
- tenantFeatureOverride() {
- const features = data.saasCatalog?.features || [];
- return modalFrame('租户功能覆盖', '对单个租户强制启用或停用某项 SaaS 功能,必须记录可审计原因。', ``, ``, { id: 'SaaS 租户权益', wide: true });
- },
- saasVersion() {
- const offerings = data.saasCatalog?.offerings || [];
- return modalFrame('新建套餐版本', '新版本先保存为草稿,确认后再单独发布。', ``, ``, { id: 'SaaS 版本管理', wide: true });
- },
- platformRole() {
- const role = data.platformRoles.find(item => item.id === state.modalData.roleId) || {};
- return modalFrame(role.id ? '编辑平台角色' : '新建平台角色', '选择该角色可以使用的业务功能,保存后对所属员工生效。', ``, ``, { id: '平台角色管理', wide: true });
- },
- paymentChannel() {
- const channel = data.paymentChannels.find(item => item.id === state.modalData.channelId) || {};
- const apps = data.paymentApps.filter(item => item.appScope === 'platform');
- return modalFrame(channel.id ? '编辑平台支付渠道' : '新建平台支付渠道', '渠道密钥只保存 Secret Ref,不在页面保存明文凭据。', ``, ``, { id: '平台支付设置', wide: true });
- },
- smsTemplate() {
- const template = data.smsTemplates.find(item => item.id === state.modalData.templateId) || {};
- const tenantId = template.tenantId || state.selectedTenant || data.smsChannels[0]?.tenantId || '';
- const channels = data.smsChannels.filter(item => !tenantId || item.tenantId === tenantId);
- return modalFrame(template.id ? '编辑短信模板' : '新建短信模板', '模板先保存为草稿,再通过独立动作提交审核。', ``, ``, { id: '短信模板管理', wide: true });
- },
- mobileBoundary() {
- return modalFrame('请在桌面端继续', `${state.modalData.actionLabel || '此操作'}需要完整工作区。`, `${icon('monitor-up')}移动端只支持查看与轻量处理租户、账务、用量、授权、员工和通知渠道的创建或复杂编辑,请在宽度不少于 768px 的桌面端完成,避免误操作。
`, ``, { id: '全局 · 移动端边界' });
- },
- createTenant() {
- return modalFrame('开通租户', '创建租户和首位负责人账号;套餐、域名和账务信息可在开通后继续配置。', ``, ``, { id: 'P-02 · 租户开通', wide: true });
- },
- tenantStatus() {
- const tenant = tenantById(state.modalData.tenantId);
- const restoring = tenant.status === '暂停';
- return modalFrame(restoring ? '恢复租户' : '暂停租户', `将 ${tenant.name} 的业务状态变更为“${restoring ? '正常' : '暂停'}”。${restoring ? '恢复业务写操作。' : '学生端保留只读访问,新增权益与部分写操作将受限。'}`, ``, ``, { id: 'P-03 · 生命周期' });
- },
- createSubscription() {
- const selectedPlan = state.modalData.planCode || tenantById(state.selectedTenant)?.planCode || 'pro';
- return modalFrame('创建租户订阅', '日期与金额必须有效;同一租户的重复活跃订阅会被阻止。', ``, ``, { id: 'P-05 · 订阅表单', wide: true });
- },
- createInvoice() {
- return modalFrame('手工创建服务费账单', '金额以元展示,Mock 写入时显式转换;到期日必须晚于今天。', ``, ``, { id: 'P-06 · 手工账单', wide: true });
- },
- invoiceCandidates() {
- const candidates = data.subscriptions.filter(subscription => !data.invoices.some(invoice => invoice.note.includes(subscription.id))).map(subscription => ({ subscription, tenant: tenantById(subscription.tenantId) }));
- return modalFrame('订阅账单候选 · Dry-run', '预览不会写入账单;已有账单候选将被幂等跳过。', `${candidates.map(({ subscription, tenant }) => `
`).join('') || '
没有可生成候选,全部订阅已存在对应账单。
'}
`, `${candidates.length ? `` : ''}`, { id: 'P-06 · Dry-run', wide: true });
- },
- payment() {
- const invoice = invoiceById(state.modalData.invoiceId);
- const payment = paymentForInvoice(invoice);
- return modalFrame('人工确认收款', `${invoice.id} · 待确认金额 ${money(payment?.amount || invoice.balance)}。本操作确认后端已存在的待支付记录。`, ``, ``, { id: 'P-08 · 资金动作', wide: true });
- },
- overduePreview() {
- const candidates = data.invoices.filter(invoice => invoice.status === '已逾期');
- return modalFrame('逾期处理预览 · Dry-run', '本次预览不改变账单或租户状态;确认后异步创建催缴记录。', `${candidates.map(invoice => `
`).join('') || '
当前没有逾期候选。
'}
`, `${candidates.length ? '' : ''}`, { id: 'P-08 · Dry-run' });
- },
- recordUsage() {
- return modalFrame('记录平台用量', '人工记录会标记来源;同租户同账期重复记录会被阻止。', ``, ``, { id: 'P-07 · 人工用量', wide: true });
- },
- overagePreview() {
- const candidates = data.usage.filter(item => item.period === state.usagePeriod && item.estimated > 0 && !data.invoices.some(invoice => invoice.note === `超额 ${item.period}` && invoice.tenantId === item.tenantId));
- return modalFrame('超额账单候选 · Dry-run', `${state.usagePeriod} 账期预览;确认后通过异步任务生成账单。`, `${candidates.map(item => `
`).join('') || '
当前账期无超额候选。
'}
`, `${candidates.length ? '' : ''}`, { id: 'P-07 · Dry-run' });
- },
- dunningChannel() {
- const channel = data.dunningChannels.find(item => item.id === state.modalData.channelId) || {};
- const redactedHint = platformApi?.isEnabled() && channel.endpointRedacted ? ' 后端不会回显完整 URL;编辑时必须重新输入完整 HTTPS Webhook。' : '';
- return modalFrame(channel.id ? '编辑催缴渠道' : '新建催缴渠道', `Webhook secret 为只写字段,保存后不会回显。${redactedHint}`, ``, ``, { id: 'P-08 · 通知渠道', wide: true });
- },
- bank() {
- const bank = bankById(state.modalData.bankId) || {};
- return modalFrame(bank.id ? '编辑公共题库' : '新建公共题库', '题库保存后可继续配置分类、科目、章节和试卷。', ``, ``, { id: 'P-09 · 公共题库' });
- },
- bankNode() {
- const node = bankNodeById(state.modalData.nodeId) || {};
- const parents = data.bankNodes.filter(item => item.questionBankId === state.selectedBank && item.isActive && item.id !== node.id);
- return modalFrame(node.id ? '编辑内容节点' : '新建内容节点', '使用中文业务层级组织题目,章节和试卷可直接录入题目。', ``, ``, { id: 'P-09 · 内容结构' });
- },
- batchBankNodes() {
- return modalFrame('批量创建章节或试卷', '每行一个名称,一次最多创建 100 个。', ``, ``, { id: 'P-09 · 批量创建', wide: true });
- },
- crmConfig() {
- const config = data.crmConfigs.find(item => item.id === state.modalData.crmId) || {};
- return modalFrame(config.id ? '编辑 CRM 接入' : '新建 CRM 接入', '平台代管租户 CRM webhook 接入;Secret 只保存引用,不提交明文密钥。', ``, ``, { id: 'P-10 · CRM 接入', wide: true });
- },
- smsChannel() {
- const channel = data.smsChannels.find(item => item.id === state.modalData.smsId) || {};
- return modalFrame(channel.id ? '编辑短信渠道' : '新建短信渠道', '渠道密钥只保存 Secret Ref;模板和发送日志会保留历史。', ``, ``, { id: 'P-11 · 短信渠道', wide: true });
- },
- paymentApp() {
- const appItem = data.paymentApps.find(item => item.id === state.modalData.paymentId) || {};
- const isTenant = appItem.appScope === 'tenant' || appItem.tenantId;
- return modalFrame(appItem.id ? '编辑支付应用' : '新建平台支付应用', '平台自有收款用于租户购买套餐/模块;租户代管应用可选择具体租户。', ``, ``, { id: 'P-12 · 支付设置', wide: true });
- },
- staff() {
- const person = data.staff.find(item => item.id === state.modalData.staffId) || {};
- const editablePhone = /^1\d{10}$/.test(person.phone || '') ? person.phone : '';
- const selectedRoleIds = person.roleIds?.length ? person.roleIds : (state.modalData.roleId ? [state.modalData.roleId] : []);
- const roleOptions = data.platformRoles.map(role => {
- const featureNames = role.permissionCodes.map(code => data.platformPermissions[code] || code).join('、') || '暂无功能';
- return ``;
- }).join('');
- return modalFrame(person.id ? '编辑平台员工' : '新建平台员工', '员工账号与平台角色由后端统一管理,功能说明来自当前权限目录。', ``, ``, { id: 'P-13 · 员工角色', wide: true });
- },
- auditDetail() {
- const log = data.auditLogs.find(item => item.id === state.modalData.auditId);
- return modalFrame('审计事件详情', `${log.id} · 敏感字段已脱敏。`, `- 时间
- ${escapeHtml(log.time)}
- 操作者
- ${escapeHtml(log.actor)} · ${escapeHtml(log.role)}
- 动作
${escapeHtml(log.action)}- 目标
- ${escapeHtml(log.targetType)} ·
${escapeHtml(log.targetId)} - 来源 IP
${escapeHtml(log.ip)}- 详情
- ${escapeHtml(log.details)}
`, ``, { id: 'P-14 · 只读详情', wide: true });
- },
- alertDetail() {
- const alert = data.alerts.find(item => item.id === (state.modalData.alertId || state.selectedAlert));
- return modalFrame('告警证据与处理', `${alert.id} · ${alert.title}`, `${alert.severity}${escapeHtml(alert.summary)}${alert.owner} · ${alert.updatedAt}
${statusBadge(alertStatusLabel(alert.status))}
${alert.evidence.map(item => `- ${icon('file-search')}${escapeHtml(item)}
`).join('')}
`, `${['open', 'acknowledged'].includes(alert.status) ? `` : ''}`, { id: 'P-15 · 状态机', wide: true });
- },
- notificationDetail() {
- const event = [...(data.notificationEvents || []), ...(data.dunningEvents || [])].find(item => item.id === state.modalData.eventId);
- const channel = event ? notificationChannelName(event.channelId) : '-';
- return modalFrame('通知事件详情', `${event?.id || '-'} · 请求与错误摘要已脱敏。`, `- 主题
- ${escapeHtml(event?.subject || '-')}
- 通知渠道
- ${escapeHtml(channel)}
- 状态
- ${statusBadge(event?.status || '-')}
- 尝试次数
- ${event?.attempts || 0}
- 更新时间
- ${escapeHtml(event?.updatedAt || '-')}
- 错误摘要
- ${escapeHtml(event?.error || '无')}
`, `${event?.status === '失败' ? `` : ''}`, { id: 'P-15 · 通知事件', wide: true });
- },
- auditChannel() {
- const channel = data.auditChannels.find(item => item.id === state.modalData.channelId) || {};
- const redactedHint = platformApi?.isEnabled() && channel.endpointRedacted ? ' 后端不会回显完整 URL;编辑时必须重新输入完整 HTTPS Webhook。' : '';
- return modalFrame(channel.id ? '编辑审计通知渠道' : '新建审计通知渠道', `secret 只写;状态和严重级别过滤由平台后端执行。${redactedHint}`, ``, ``, { id: 'P-15 · 通知渠道', wide: true });
- },
- confirmAction() {
- const { title, description, impact, confirmLabel = '确认操作', confirmActionName = 'execute-confirmed', tone: confirmTone = 'danger' } = state.modalData;
- return modalFrame(title, description, `${icon(confirmTone === 'danger' ? 'triangle-alert' : 'circle-help')}${escapeHtml(impact)}
`, ``, { id: '全局 · 二次确认' });
- },
- tasks() {
- return modalFrame('异步任务中心', '批量账单、超额账单和导出均返回 task_id,可跟踪、重试并跳转结果。', `${data.tasks.length ? data.tasks.map(task => `
${icon(task.status === 'completed' ? 'circle-check' : task.status === 'failed' ? 'circle-x' : 'loader-circle')}${escapeHtml(task.label)}${task.id} · ${task.updatedAt}${task.error ? escapeHtml(task.error) : `结果去向:${escapeHtml(task.resultTarget)}`}
${task.status === 'failed' ? `` : statusBadge(taskStatusLabel(task.status))}`).join('') : emptyBlock('没有异步任务', '批量生成、导出或重试后会出现在这里。')}
`, ``, { id: '全局 · 任务中心', wide: true });
- },
-};
-
-function confirmAction(config, execute) {
- openModal('confirmAction', config);
- state.modalData.execute = execute;
-}
-
-function validateBillingProfile(form) {
- const errors = {};
- ['billingName', 'contactName', 'phone', 'email', 'invoiceTitle'].forEach(name => { if (!fieldValue(form, name)) errors[name] = `${form.elements[name].previousElementSibling?.textContent.replace('*', '').trim() || name}不能为空`; });
- const phone = fieldValue(form, 'phone'); if (phone && !/^1\d{10}$/.test(phone)) errors.phone = '请输入 11 位中国大陆手机号';
- const email = fieldValue(form, 'email'); if (email && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) errors.email = '请输入有效邮箱地址';
- const taxId = fieldValue(form, 'taxId'); if (taxId && !/^[0-9A-Z]{15,20}$/.test(taxId)) errors.taxId = '税号应为 15-20 位大写字母或数字';
- const account = fieldValue(form, 'bankAccountMasked'); if (account && !account.includes('*')) errors.bankAccountMasked = '不得提交完整银行账号,请使用脱敏值';
- return Object.keys(errors).length ? errors : null;
-}
-function validateNotificationChannel(values) {
- const errors = {};
- if (!values.code) errors.code = '渠道代码不能为空';
- if (!values.name) errors.name = '渠道名称不能为空';
- if (!values.endpoint) errors.endpoint = 'Webhook URL 不能为空';
- if (platformApi?.isEnabled() && values.endpoint) {
- try {
- const url = new URL(values.endpoint);
- const local = ['localhost', '127.0.0.1', '::1'].includes(url.hostname);
- if (url.protocol !== 'https:' && !local) errors.endpoint = '联调/生产 Webhook 必须使用 HTTPS';
- } catch {
- errors.endpoint = '请输入完整有效的 Webhook URL';
- }
- }
- return Object.keys(errors).length ? errors : null;
-}
-
-document.addEventListener('submit', event => {
- event.preventDefault();
- const form = event.target;
- const desktopOnlyForms = new Set(['createTenantForm', 'tenantStatusForm', 'billingProfileForm', 'subscriptionForm', 'invoiceForm', 'paymentForm', 'usageForm', 'dunningChannelForm', 'bankForm', 'bankNodeForm', 'bankNodeBatchForm', 'crmConfigForm', 'smsChannelForm', 'paymentAppForm', 'staffForm', 'auditChannelForm']);
- if (desktopOnlyForms.has(form.id) && requireDesktop('提交复杂配置或资金操作')) return;
- if (form.id === 'saasFeatureForm') {
- const values = Object.fromEntries(new FormData(form));
- simulateWrite({ key: 'saas-feature', permission: 'platform:plan:write', operationId: 'PlatformSaasController_upsertFeature', body: values, validate: () => !values.code || !values.name || !values.category ? { code: '功能编码、名称和分类不能为空' } : null, apply: payload => { const item = payload || { ...values, id: entityId('FEATURE'), referencePriceCents: Math.round(Number(values.referencePrice || 0) * 100) }; data.saasCatalog.features.unshift(item); return item; }, success: 'SaaS 功能已保存' });
- }
- if (form.id === 'saasOfferingForm') {
- const values = Object.fromEntries(new FormData(form));
- simulateWrite({ key: 'saas-offering', permission: 'platform:plan:write', operationId: 'PlatformSaasController_upsertOffering', body: values, validate: () => !values.code || !values.name ? { code: '商品编码和名称不能为空' } : null, apply: payload => { const item = payload || { ...values, id: entityId('OFFERING') }; data.saasCatalog.offerings.unshift(item); return item; }, success: 'SaaS 商品已保存' });
- }
- if (form.id === 'saasLimitForm') {
- const values = Object.fromEntries(new FormData(form)); values.isHardLimit = Boolean(new FormData(form).get('isHardLimit'));
- simulateWrite({ key: 'saas-limit', permission: 'platform:plan:write', operationId: 'PlatformSaasController_upsertFeatureLimit', body: values, validate: () => !values.metricCode || !values.featureCode || !values.name ? { metricCode: '指标编码、所属功能和限额名称不能为空' } : null, apply: payload => { const item = payload || { ...values, id: entityId('LIMIT') }; data.saasCatalog.limitDefinitions.unshift(item); return item; }, success: 'SaaS 功能限额已保存' });
- }
- if (form.id === 'tenantFeatureOverrideForm') {
- const values = Object.fromEntries(new FormData(form));
- simulateWrite({ key: 'tenant-feature-override', permission: 'platform:plan:write', operationId: 'PlatformSaasController_upsertTenantFeatureOverride', body: values, validate: () => !values.tenantId || !values.featureCode || !values.reason ? { reason: '租户、功能和操作原因不能为空' } : null, apply: payload => payload || values, success: '租户功能覆盖规则已保存' });
- }
- if (form.id === 'saasVersionForm') {
- const values = Object.fromEntries(new FormData(form));
- simulateWrite({ key: 'saas-version', permission: 'platform:plan:write', operationId: 'PlatformSaasController_upsertVersion', body: values, validate: () => !values.offeringId ? { offeringId: '必须选择所属商品' } : Number(values.amount) < 0 ? { amount: '售价不能小于 0' } : null, apply: payload => { const item = payload || { ...values, id: entityId('VERSION'), version: 1, status: 'draft', amountCents: Math.round(Number(values.amount || 0) * 100), originalAmountCents: Math.round(Number(values.originalAmount || 0) * 100) }; data.saasCatalog.versions.unshift(item); return item; }, success: '套餐版本草稿已保存' });
- }
- if (form.id === 'platformRoleForm') {
- const values = Object.fromEntries(new FormData(form)); const permissionCodes = new FormData(form).getAll('permissionCodes');
- let savedRole = null;
- simulateWrite({ key: 'platform-role', permission: 'platform:staff:write', request: async () => { savedRole = await platformApi.request('PlatformBackofficeController_upsertRole', { body: platformApi.buildBody('PlatformBackofficeController_upsertRole', values) }); await platformApi.request('PlatformBackofficeController_replaceRoleBindings', { pathParams: { roleId: savedRole.id }, body: platformApi.buildBody('PlatformBackofficeController_replaceRoleBindings', { permissionCodes, menuCodes: savedRole.menuCodes || [] }) }); return savedRole; }, validate: () => { const errors = {}; if (!values.code) errors.code = '角色编码不能为空'; if (!values.name) errors.name = '角色名称不能为空'; if (!permissionCodes.length) errors.permissionCodes = '至少选择一项平台功能'; return Object.keys(errors).length ? errors : null; }, apply: payload => { const existing = data.platformRoles.find(item => item.id === values.id); const next = { id: payload?.id || values.id || entityId('ROLE'), code: values.code, name: values.name, description: values.description || '', permissionCodes, menuCodes: payload?.menuCodes || existing?.menuCodes || [] }; if (existing) Object.assign(existing, next); else data.platformRoles.unshift(next); return next; }, success: '平台角色与功能绑定已保存' });
- }
- if (form.id === 'paymentChannelForm') {
- const values = Object.fromEntries(new FormData(form));
- simulateWrite({ key: 'payment-channel', permission: 'platform:payment:write', operationId: 'PlatformAdminPaymentSettingsController_upsertChannel', body: values, validate: () => { const errors = {}; if (!values.appId) errors.appId = '必须选择平台支付应用'; if (!values.displayName) errors.displayName = '渠道名称不能为空'; if (!values.provider) errors.provider = 'Provider 不能为空'; return Object.keys(errors).length ? errors : null; }, apply: payload => { const existing = data.paymentChannels.find(item => item.id === values.id); const next = payload || { ...values, id: values.id || entityId('PAYCH') }; if (existing) Object.assign(existing, next); else data.paymentChannels.unshift(next); return next; }, success: '平台支付渠道已保存' });
- }
- if (form.id === 'smsTemplateForm') {
- const values = Object.fromEntries(new FormData(form));
- simulateWrite({ key: 'sms-template', permission: 'platform:sms:write', operationId: 'PlatformAdminSmsController_upsertTemplate', body: values, validate: () => { const errors = {}; ['tenantId', 'channelId', 'code', 'name', 'content'].forEach(name => { if (!values[name]) errors[name] = `${name} 不能为空`; }); return Object.keys(errors).length ? errors : null; }, apply: payload => { const existing = data.smsTemplates.find(item => item.id === values.id); const next = payload ? platformApi.adapters.smsTemplate(payload) : { ...values, id: values.id || entityId('SMSTPL'), status: '草稿', templateStatus: '正常', sentCount: 0, failedCount: 0 }; if (existing) Object.assign(existing, next); else data.smsTemplates.unshift(next); return next; }, success: '短信模板草稿已保存' });
- }
- if (form.id === 'createTenantForm') {
- const values = Object.fromEntries(new FormData(form)); const slug = values.slug; const name = values.name;
- simulateWrite({ key: 'create-tenant', permission: 'platform:tenant:write', operationId: 'PlatformAdminTenantsController_create', body: () => values, validate: () => {
- const errors = {}; if (!/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(slug)) errors.slug = 'slug 仅支持小写字母、数字和连字符';
- if (!name) errors.name = '租户名称不能为空';
- if (!values.ownerName) errors.ownerName = '负责人姓名不能为空';
- if (!values.ownerEmail && !values.ownerPhone) errors.ownerEmail = '负责人邮箱和手机号至少填写一项';
- if (values.ownerPhone && !/^1\d{10}$/.test(values.ownerPhone)) errors.ownerPhone = '请输入 11 位中国大陆手机号';
- if (!/^(?=.*[A-Za-z])(?=.*\d).{12,}$/.test(values.temporaryPassword || '')) errors.temporaryPassword = '临时密码至少 12 位且必须同时包含字母和数字';
- if (data.tenants.some(item => item.slug === slug)) errors.slug = 'slug 已存在'; return Object.keys(errors).length ? errors : null;
- }, apply: payload => { const fallback = { id: `tenant_${slug.replaceAll('-', '_')}`, slug, name, legal: values.legalName || name, brand: name, shortName: name, host: '-', plan: '未订阅', planCode: '', status: values.status, billing: values.billingStatus, mode: '-', students: 0, questions: 0, storageGB: 0, trafficTB: 0, expires: '', balance: 0, owner: values.ownerName, ownerPhone: values.ownerPhone || '-', createdAt: todayTime() }; const tenantPayload = payload?.tenant || payload?.item; const tenant = tenantPayload ? platformApi.adapters.tenant(tenantPayload, fallback, {}) : fallback; tenant.owner = values.ownerName; tenant.ownerPhone = values.ownerPhone || '-'; data.tenants.unshift(tenant); state.selectedTenant = tenant.id; addAudit('tenant.create', 'tenant', tenant.id, tenant.name, '高', `开通租户 ${tenant.name} 并创建首位负责人账号。`); state.modal = ''; navigate('tenantDetail'); return tenant; }, success: '租户与负责人账号已开通', close: false, rerender: false });
- }
- if (form.id === 'tenantStatusForm') {
- const tenant = tenantById(state.modalData.tenantId); const reason = fieldValue(form, 'reason');
- simulateWrite({ key: 'tenant-status', permission: 'platform:tenant:status', operationId: 'PlatformAdminTenantsController_status', body: () => ({ tenantId: tenant.id, status: tenant.status === '暂停' ? '正常' : '暂停', billingStatus: fieldValue(form, 'billingStatus'), reason }), validate: () => !reason ? { reason: '必须填写可审计的变更原因' } : !new FormData(form).get('confirm') ? { confirm: '请确认业务影响' } : null, apply: () => { const from = tenant.status; const billingFrom = tenant.billing; tenant.status = from === '暂停' ? '正常' : '暂停'; tenant.billing = fieldValue(form, 'billingStatus') || tenant.billing; addAudit('tenant.status.update', 'tenant', tenant.id, tenant.name, '高', `业务状态 ${from} → ${tenant.status};账务状态 ${billingFrom} → ${tenant.billing}。原因:${reason}`); return tenant.status; }, success: nextStatus => `租户已${nextStatus === '暂停' ? '暂停' : '恢复'},账务状态已同步` });
- }
- if (form.id === 'billingProfileForm') {
- simulateWrite({ key: 'billing-profile', permission: 'platform:tenant:billing_profile', operationId: 'PlatformAdminTenantsController_billingProfile', body: () => ({ tenantId: state.selectedTenant, ...Object.fromEntries(new FormData(form)) }), validate: () => validateBillingProfile(form), apply: () => { data.billingProfiles[state.selectedTenant] = Object.fromEntries(new FormData(form)); addAudit('tenant.billing_profile.update', 'tenant', state.selectedTenant, tenantById(state.selectedTenant).name, '高', '更新租户账务与开票资料,银行账号保持脱敏。'); navigateBack(); }, success: '账务资料已保存并回到租户详情', close: false, rerender: false });
- }
- if (form.id === 'subscriptionForm') {
- const values = Object.fromEntries(new FormData(form));
- simulateWrite({ key: 'subscription', permission: 'platform:billing:write', operationId: 'PlatformAdminBillingController_createSubscription', body: () => ({ ...values, autoRenew: Boolean(new FormData(form).get('autoRenew')) }), validate: () => { const errors = {}; if (data.subscriptions.some(item => item.tenantId === values.tenantId && item.status === '活跃')) errors.tenantId = '该租户已有活跃订阅,请先处理原订阅'; if (!values.amount || Number(values.amount) < 0) errors.amount = '金额必须大于等于 0'; if (!values.start) errors.start = '开始日期不能为空'; if (!values.expires || values.expires <= values.start) errors.expires = '到期日期必须晚于开始日期'; return Object.keys(errors).length ? errors : null; }, apply: () => { const subscription = { id: entityId('SUB'), tenantId: values.tenantId, planCode: values.planCode, status: values.status, cycle: values.cycle, amount: Number(values.amount), start: values.start, expires: values.expires, autoRenew: Boolean(new FormData(form).get('autoRenew')) }; data.subscriptions.unshift(subscription); const tenant = tenantById(values.tenantId); tenant.planCode = values.planCode; tenant.plan = planByCode(values.planCode).name; tenant.expires = values.expires; addAudit('subscription.create', 'subscription', subscription.id, tenant.name, '高', `创建 ${subscription.cycle} ${tenant.plan} 订阅,金额 ${money(subscription.amount)}。`); }, success: '订阅已创建并更新租户套餐' });
- }
- if (form.id === 'invoiceForm') {
- const values = Object.fromEntries(new FormData(form));
- simulateWrite({ key: 'invoice', permission: 'platform:billing:write', operationId: 'PlatformAdminBillingController_createInvoice', body: values, validate: () => { const errors = {}; if (!values.amount || Number(values.amount) <= 0) errors.amount = '金额必须大于 0'; if (!values.due) errors.due = '到期日不能为空'; if (!values.period) errors.period = '账期不能为空'; return Object.keys(errors).length ? errors : null; }, apply: () => { const invoice = { id: entityId('INV'), tenantId: values.tenantId, type: values.type, period: values.period, total: Number(values.amount), paid: 0, balance: Number(values.amount), due: values.due, status: '待付款', note: values.note || values.type }; data.invoices.unshift(invoice); const tenant = tenantById(values.tenantId); tenant.balance += invoice.balance; tenant.billing = '待付款'; addAudit('invoice.create', 'invoice', invoice.id, invoice.id, '高', `手工创建 ${money(invoice.total)} 服务费账单。`); }, success: '账单草稿已创建' });
- }
- if (form.id === 'paymentForm') {
- const invoice = invoiceById(state.modalData.invoiceId); const values = Object.fromEntries(new FormData(form)); const payment = paymentForInvoice(invoice); const amount = payment?.amount || invoice.balance;
- simulateWrite({ key: 'payment', permission: 'platform:billing:payment', operationId: 'PlatformAdminBillingController_confirmPayment', body: () => ({ ...values, paymentId: payment?.id, amount }), validate: () => { const errors = {}; if (platformApi?.isEnabled() && !payment) errors.paymentId = '该账单没有可确认的待支付记录'; if (!amount || amount <= 0) errors.amount = '收款金额必须大于 0'; if (amount > invoice.balance) errors.amount = `收款金额不可超过余额 ${money(invoice.balance)}`; if (!values.tradeNo) errors.tradeNo = '交易流水号不能为空'; if (!new FormData(form).get('confirm')) errors.confirm = '请先确认已核对银行流水'; return Object.keys(errors).length ? errors : null; }, apply: () => { invoice.paid += amount; invoice.balance -= amount; invoice.status = invoice.balance === 0 ? '已支付' : '部分支付'; if (payment) payment.status = 'succeeded'; const tenant = tenantById(invoice.tenantId); tenant.balance = Math.max(0, tenant.balance - amount); tenant.billing = tenant.balance === 0 ? '正常' : '待付款'; if (tenant.status === '暂停' && tenant.balance === 0) tenant.status = '正常'; addAudit('invoice.payment.confirm', 'invoice', invoice.id, invoice.id, '高', `人工确认收款 ${money(amount)},交易流水仅保存脱敏摘要。`); }, success: '收款已确认,账单与租户余额已更新' });
- }
- if (form.id === 'usageForm') {
- const values = Object.fromEntries(new FormData(form));
- simulateWrite({ key: 'usage', permission: 'platform:usage:write', operationId: 'PlatformAdminBillingController_recordUsage', request: () => Promise.all([['students', values.students], ['questions', values.questions], ['storage_gb', values.storageGB], ['traffic_tb', values.trafficTB]].map(([metricKey, metricValue]) => platformApi.request('PlatformAdminBillingController_recordUsage', { body: platformApi.buildBody('PlatformAdminBillingController_recordUsage', { tenantId: values.tenantId, period: values.period, metricKey, metricValue }) }))), validate: () => data.usage.some(item => item.tenantId === values.tenantId && item.period === values.period) ? { period: '该租户账期已有记录,避免周期重叠或重复' } : null, apply: () => { data.usage.unshift({ tenantId: values.tenantId, period: values.period, source: '人工补录', students: Number(values.students), questions: Number(values.questions), storageGB: Number(values.storageGB), trafficTB: Number(values.trafficTB), overage: [], estimated: 0 }); addAudit('usage.create', 'tenant', values.tenantId, tenantById(values.tenantId).name, '中', `人工补录 ${values.period} 平台用量。`); }, success: '用量记录已保存并标记人工来源' });
- }
- if (form.id === 'dunningChannelForm') {
- const values = Object.fromEntries(new FormData(form));
- const existing = data.dunningChannels.find(item => item.id === values.id);
- simulateWrite({ key: 'dunning-channel', permission: 'platform:billing:notification', operationId: 'PlatformAdminDunningChannelsController_upsertChannel', body: () => ({ ...values, secretRef: existing?.secretRef, reminderTypes: existing?.reminderTypes, reminderChannels: existing?.reminderChannels, minReminderLevel: existing?.minReminderLevel, enabled: Boolean(new FormData(form).get('enabled')) }), validate: () => validateNotificationChannel(values), apply: () => { const next = { id: values.id || entityId('DUN'), code: values.code, name: values.name, provider: values.provider, endpoint: values.endpoint, endpointRedacted: false, secretRef: existing?.secretRef || '', retry: Number(values.retry), enabled: Boolean(new FormData(form).get('enabled')) }; if (existing) Object.assign(existing, next); else data.dunningChannels.unshift(next); addAudit('dunning.channel.upsert', 'notification_channel', next.id, next.name, '高', `保存催缴渠道 ${next.code},secret 保持只写。`); }, success: '催缴通知渠道已保存' });
- }
- if (form.id === 'bankForm') {
- const values = Object.fromEntries(new FormData(form));
- simulateWrite({ key: 'question-bank', permission: 'platform:question-bank:manage', operationId: 'PlatformQuestionBanksController_upsertBank', body: () => ({ id: values.id || null, name: values.name, metadata: values.version ? { version: values.version } : {} }), validate: () => !values.name?.trim() ? { name: '题库名称不能为空' } : null, apply: payload => { const item = payload ? platformApi.adapters.bank(payload, bankById(payload.id)) : { id: values.id || entityId('QB'), name: values.name, version: values.version || '-', status: '正常', source: '平台自建', catalog: '平台公共题库', nodes: 0, questions: 0 }; const existing = bankById(item.id); if (existing) Object.assign(existing, item); else data.banks.unshift(item); state.selectedBank = item.id; state.selectedBankNode = ''; return item; }, success: '公共题库已保存' });
- }
- if (form.id === 'bankNodeForm') {
- const values = Object.fromEntries(new FormData(form));
- simulateWrite({ key: 'question-bank-node', permission: 'platform:question-bank:manage', operationId: 'PlatformQuestionBanksController_upsertNode', body: () => ({ id: values.id || null, questionBankId: state.selectedBank, parentId: values.parentId || null, nodeKey: null, name: values.name, nodeType: values.nodeType, sortOrder: Number(values.sortOrder || 0), isSelectable: true, metadata: {} }), validate: () => !values.name?.trim() ? { name: '节点名称不能为空' } : null, apply: payload => { const item = payload ? adaptBankNode(payload) : { id: values.id || entityId('NODE'), questionBankId: state.selectedBank, parentId: values.parentId || null, name: values.name, nodeType: values.nodeType, sortOrder: Number(values.sortOrder || 0), depth: values.parentId ? Number(bankNodeById(values.parentId)?.depth || 0) + 1 : 0, isActive: true, questionCount: 0 }; const existing = bankNodeById(item.id); if (existing) Object.assign(existing, item); else data.bankNodes.push(item); state.selectedBankNode = item.id; return item; }, success: '内容节点已保存' });
- }
- if (form.id === 'bankNodeBatchForm') {
- const values = Object.fromEntries(new FormData(form)); const names = String(values.names || '').split(/\r?\n/).map(item => item.trim()).filter(Boolean);
- simulateWrite({ key: 'question-bank-node-batch', permission: 'platform:question-bank:manage', operationId: 'PlatformQuestionBanksController_batchCreateNodes', body: () => ({ questionBankId: state.selectedBank, parentId: values.parentId || null, nodeType: values.nodeType, names }), validate: () => !names.length ? { names: '至少填写一个章节或试卷名称' } : names.length > 100 ? { names: '一次最多创建 100 个节点' } : null, apply: payload => { const items = apiItems(payload); if (items.length) data.bankNodes.push(...items.map(adaptBankNode)); return items.length || names.length; }, success: count => `已创建 ${count} 个内容节点` });
- }
- if (form.id === 'bankQuestionForm') {
- const values = Object.fromEntries(new FormData(form)); const options = parseJsonText(values.options, []); const tags = String(values.tags || '').split(/[、,,]/).map(item => item.trim()).filter(Boolean);
- simulateWrite({ key: 'question-bank-question', permission: 'platform:question-bank:manage', operationId: 'PlatformQuestionBanksController_upsertQuestion', body: () => ({ id: values.id || null, questionBankId: state.selectedBank, contentNodeId: values.contentNodeId, legacyId: values.legacyId || null, type: values.type, typeLabel: questionTypeLabel(values.type), difficulty: Number(values.difficulty || 3), tags, content: values.content, options, correctOptionIndex: null, correctOptionIndices: [], answerText: values.answerText || null, explanation: values.explanation || null, subQuestions: [], codeLang: null, codeTemplate: null, mediaUrl: values.mediaUrl || null, status: 'published', examMarkers: {}, sourceHash: null }), validate: () => { const errors = {}; if (!values.contentNodeId) errors.contentNodeId = '请选择章节或试卷'; if (!values.content?.trim()) errors.content = '题干不能为空'; if (options === null || !Array.isArray(options)) errors.options = '选项必须是 JSON 数组'; return Object.keys(errors).length ? errors : null; }, apply: payload => { const item = payload ? adaptBankQuestion(payload) : { ...values, id: values.id || entityId('Q'), questionBankId: state.selectedBank, contentNodeId: values.contentNodeId, options, tags, versionNo: 1, status: 'published', statusLabel: '已发布' }; const existing = data.bankQuestions.find(row => row.id === item.id); if (existing) Object.assign(existing, item); else data.bankQuestions.unshift(item); return item; }, success: '题目已保存并生成新版本', close: false });
- }
- if (form.id === 'bankBatchImportForm' || form.id === 'bankStructuredImportForm') {
- const values = Object.fromEntries(new FormData(form)); const payload = parseJsonText(values.payload, null); const execute = event.submitter?.dataset.importMode === 'execute'; const format = form.id === 'bankStructuredImportForm' ? 'structured-v2' : 'simple';
- simulateWrite({ key: `question-bank-import-${format}`, permission: 'platform:question-bank:manage', operationId: execute ? 'PlatformQuestionBanksController_executeImport' : 'PlatformQuestionBanksController_previewImport', body: () => ({ questionBankId: state.selectedBank, contentNodeId: values.contentNodeId || null, format, sourceName: values.sourceName || (format === 'structured-v2' ? '结构化题库文件' : '普通题目批量导入'), payload }), validate: () => { const errors = {}; if (format === 'simple' && !values.contentNodeId) errors.contentNodeId = '普通批量导入必须选择章节或试卷'; if (payload === null) errors.payload = '请输入有效的 JSON'; return Object.keys(errors).length ? errors : null; }, apply: result => { data.bankImportResult = result || { detail: { job: { dryRun: !execute, totalCount: Array.isArray(payload) ? payload.length : 0, validCount: Array.isArray(payload) ? payload.length : 0, errorCount: 0 }, issues: [] }, insertedQuestionCount: execute && Array.isArray(payload) ? payload.length : 0, updatedQuestionCount: 0, skippedQuestionCount: 0, createdNodeCount: 0 }; return data.bankImportResult; }, success: execute ? '题库导入已执行' : '导入预检已完成', close: false });
- }
- if (form.id === 'crmConfigForm') {
- const values = Object.fromEntries(new FormData(form));
- values.enabled = Boolean(new FormData(form).get('enabled'));
- simulateWrite({ key: 'crm-config', permission: 'platform:crm:write', operationId: 'PlatformAdminCrmController_upsertConfig', body: () => values, validate: () => { const errors = {}; if (!values.tenantId) errors.tenantId = '租户不能为空'; if (!values.endpoint) errors.endpoint = 'Webhook Endpoint 不能为空'; return Object.keys(errors).length ? errors : null; }, apply: payload => { const item = payload ? platformApi.adapters.crmConfig(payload) : { ...values, id: values.id || entityId('CRM'), enabled: values.enabled, status: values.enabled ? '正常' : '未启用' }; const index = data.crmConfigs.findIndex(row => row.id === item.id); if (index >= 0) data.crmConfigs[index] = item; else data.crmConfigs.unshift(item); addAudit('crm.config.upsert', 'crm_config', item.id, tenantById(item.tenantId)?.name || item.id, '中', '保存 CRM 接入配置。'); }, success: 'CRM 接入配置已保存' });
- }
- if (form.id === 'smsChannelForm') {
- const values = Object.fromEntries(new FormData(form));
- simulateWrite({ key: 'sms-channel', permission: 'platform:sms:write', operationId: 'PlatformAdminSmsController_upsertChannel', body: () => values, validate: () => { const errors = {}; if (!values.tenantId) errors.tenantId = '租户不能为空'; if (!values.provider) errors.provider = 'Provider 不能为空'; if (!values.signature) errors.signature = '短信签名不能为空'; return Object.keys(errors).length ? errors : null; }, apply: payload => { const item = payload ? platformApi.adapters.smsChannel(payload) : { ...values, id: values.id || entityId('SMS'), enabled: values.status === '正常', used: 0 }; const index = data.smsChannels.findIndex(row => row.id === item.id); if (index >= 0) data.smsChannels[index] = item; else data.smsChannels.unshift(item); addAudit('sms.channel.upsert', 'sms_channel', item.id, tenantById(item.tenantId)?.name || item.id, '中', '保存短信渠道配置。'); }, success: '短信渠道已保存' });
- }
- if (form.id === 'paymentAppForm') {
- const values = Object.fromEntries(new FormData(form));
- const operationId = values.appScope === 'tenant' ? 'PlatformAdminTenantPaymentSettingsController_upsertApp' : 'PlatformAdminPaymentSettingsController_upsertApp';
- simulateWrite({ key: 'payment-app', permission: 'platform:payment:write', operationId, body: () => values, validate: () => { const errors = {}; if (values.appScope === 'tenant' && !values.tenantId) errors.tenantId = '租户代管必须选择租户'; if (!values.appName) errors.appName = '应用名称不能为空'; return Object.keys(errors).length ? errors : null; }, apply: payload => { const item = payload ? (values.appScope === 'tenant' ? platformApi.adapters.tenantPaymentApp(payload) : platformApi.adapters.platformPaymentApp(payload)) : { ...values, id: values.id || entityId('PAYAPP'), status: values.status }; const index = data.paymentApps.findIndex(row => row.id === item.id); if (index >= 0) data.paymentApps[index] = item; else data.paymentApps.unshift(item); addAudit('payment.app.upsert', 'payment_app', item.id, item.appName, '高', '保存支付应用配置。'); }, success: '支付应用已保存' });
- }
- if (form.id === 'staffForm') {
- const values = Object.fromEntries(new FormData(form)); const roleIds = new FormData(form).getAll('roleIds');
- simulateWrite({ key: 'staff', permission: 'platform:staff:write', operationId: 'PlatformAdminOverviewController_upsertStaff', body: () => ({ ...values, roleIds }), validate: () => { const errors = {}; if (!values.name) errors.name = '姓名不能为空'; if (!values.email) errors.email = '邮箱不能为空'; if (values.phone && !/^1\d{10}$/.test(values.phone)) errors.phone = '请输入 11 位手机号'; if (!roleIds.length) errors.roleIds = '至少选择一个平台角色'; return Object.keys(errors).length ? errors : null; }, apply: payload => { const existing = data.staff.find(item => item.id === values.userId); const assignedRoles = data.platformRoles.filter(role => roleIds.includes(role.id)); const fallback = { id: values.userId || entityId('STAFF'), userId: values.userId || '', name: values.name, email: values.email, phone: values.phone || existing?.phone || '-', roleIds, roleCodes: assignedRoles.map(role => role.code), role: assignedRoles.map(role => role.name).join('、'), permissions: [...new Set(assignedRoles.flatMap(role => role.permissionCodes))], status: existing?.status || '正常', lastActive: existing?.lastActive || '尚未登录' }; const next = payload ? { ...fallback, ...platformApi.adapters.staff(payload), roleIds, roleCodes: fallback.roleCodes, role: fallback.role, permissions: fallback.permissions } : fallback; if (existing) Object.assign(existing, next); else data.staff.unshift(next); addAudit('staff.upsert', 'staff', next.id, next.name, '高', `保存平台员工及 ${assignedRoles.length} 个角色。`); }, success: '平台员工与角色已保存' });
- }
- if (form.id === 'auditChannelForm') {
- const values = Object.fromEntries(new FormData(form));
- const existing = data.auditChannels.find(item => item.id === values.id);
- simulateWrite({ key: 'audit-channel', permission: 'platform:audit:notification', operationId: 'PlatformAdminAuditController_upsertChannel', body: () => ({ ...values, secretRef: existing?.secretRef, enabled: Boolean(new FormData(form).get('enabled')) }), validate: () => validateNotificationChannel(values), apply: () => { const next = { id: values.id || entityId('CH'), code: values.code, name: values.name, provider: values.provider, endpoint: values.endpoint, endpointRedacted: false, secretRef: existing?.secretRef || '', minSeverity: values.minSeverity, statusFilter: values.statusFilter, timeout: Number(values.timeout), maxAttempts: Number(values.maxAttempts), enabled: Boolean(new FormData(form).get('enabled')), lastStatus: existing?.lastStatus || '正常' }; if (existing) Object.assign(existing, next); else data.auditChannels.unshift(next); addAudit('audit.channel.upsert', 'notification_channel', next.id, next.name, '高', `保存审计告警渠道 ${next.code},secret 保持只写。`); }, success: '审计通知渠道已保存' });
- }
-});
-
-document.addEventListener('click', event => {
- if (event.target.classList.contains('modal-backdrop')) {
- closeModal();
- return;
- }
- const copy = event.target.closest('[data-copy]'); if (copy) { navigator.clipboard?.writeText(copy.dataset.copy); showToast('已复制到剪贴板'); return; }
- const nav = event.target.closest('[data-nav]'); if (nav) { requestLeave(() => { state.selectedTenant = ''; navigate(nav.dataset.nav, { force: true }); }); return; }
- const tenant = event.target.closest('[data-tenant-detail]'); if (tenant) { requestLeave(() => { state.selectedTenant = tenant.dataset.tenantDetail; navigate('tenantDetail', { force: true }); }); return; }
- const invoice = event.target.closest('[data-invoice-detail]'); if (invoice) { if (requireDesktop('确认账单收款')) return; state.selectedInvoice = invoice.dataset.invoiceDetail; openModal('payment', { invoiceId: invoice.dataset.invoiceDetail }); return; }
- const audit = event.target.closest('[data-audit-detail]'); if (audit) { openModal('auditDetail', { auditId: audit.dataset.auditDetail }); return; }
- const alertDetail = event.target.closest('[data-alert-detail]'); if (alertDetail) { openModal('alertDetail', { alertId: alertDetail.dataset.alertDetail }); return; }
- const notificationDetail = event.target.closest('[data-notification-detail]'); if (notificationDetail) { openModal('notificationDetail', { eventId: notificationDetail.dataset.notificationDetail }); return; }
- const tf = event.target.closest('[data-tenant-filter]'); if (tf) { state.tenantFilter = tf.dataset.tenantFilter; syncNavigationState(); render(); return; }
- const billingTab = event.target.closest('[data-billing-tab]'); if (billingTab) { state.billingTab = billingTab.dataset.billingTab; syncNavigationState(); render(); return; }
- const bankTab = event.target.closest('[data-bank-tab]'); if (bankTab) { state.bankTab = bankTab.dataset.bankTab; syncNavigationState(); render(); if (['structure', 'manage'].includes(state.bankTab)) loadBankWorkspace(); return; }
- const crmTab = event.target.closest('[data-crm-tab]'); if (crmTab) { state.crmTab = crmTab.dataset.crmTab; syncNavigationState(); render(); return; }
- const smsTab = event.target.closest('[data-sms-tab]'); if (smsTab) { state.smsTab = smsTab.dataset.smsTab; syncNavigationState(); render(); return; }
- const paymentTab = event.target.closest('[data-payment-tab]'); if (paymentTab) { state.paymentTab = paymentTab.dataset.paymentTab; syncNavigationState(); render(); return; }
- const saasFinanceTab = event.target.closest('[data-saas-finance-tab]'); if (saasFinanceTab) { state.saasFinanceTab = saasFinanceTab.dataset.saasFinanceTab; syncNavigationState(); render(); return; }
- const bankSelect = event.target.closest('[data-bank-select]'); if (bankSelect) { state.selectedBank = bankSelect.dataset.bankSelect; state.selectedBankNode = ''; syncNavigationState(); render(); loadBankWorkspace(); return; }
- const bankNodeSelect = event.target.closest('[data-bank-node-select]'); if (bankNodeSelect) { state.selectedBankNode = bankNodeSelect.dataset.bankNodeSelect; syncNavigationState(); render(); return; }
- const auditSeverity = event.target.closest('[data-audit-severity]'); if (auditSeverity) { state.auditSeverity = auditSeverity.dataset.auditSeverity; syncNavigationState(); render(); return; }
- const alertStatus = event.target.closest('[data-alert-status]'); if (alertStatus) { state.alertStatus = alertStatus.dataset.alertStatus; syncNavigationState(); render(); return; }
- const actionElement = event.target.closest('[data-action]'); const action = actionElement?.dataset.action; if (!action) return;
- if (action === 'close-modal') { closeModal(); return; }
- if (action === 'execute-confirmed' || action === 'execute-staff-disable') { if (requireDesktop('执行高风险确认操作')) return; const execute = state.modalData.execute; closeModal({ force: true }); execute?.(); return; }
- if (action === 'subpage-back') { navigateBack(); return; }
- if (action === 'subpage-close') { closeSubpage(); return; }
- if (action === 'retry-page') { state.scenario = 'normal'; scenarioSelect.value = 'normal'; render(); return; }
- if (action === 'restore-session') { state.scenario = 'normal'; state.view = 'overview'; state.previousView = ''; state.history = []; scenarioSelect.value = 'normal'; render(); showToast('Mock 会话已恢复'); return; }
- if (action === 'logout' && platformApi?.isEnabled()) { window.GongxuePlatformAuth?.logout(); return; }
- if (action === 'logout') { closeModal(); state.scenario = 'session_invalid'; state.view = 'overview'; state.previousView = ''; state.history = []; scenarioSelect.value = 'session_invalid'; addAudit('auth.logout', 'application', 'platform-console', '平台管理控制台', '中', '超级管理员主动退出当前平台端会话。'); saveData(); render(); return; }
- if (action === 'refresh') {
- if (platformApi?.isEnabled()) { hydrateFromBackend(); return; }
- state.scenario = 'loading'; scenarioSelect.value = 'loading'; render();
- setTimeout(() => { state.scenario = 'normal'; scenarioSelect.value = 'normal'; render(); showToast('平台静态演示数据已刷新'); }, 700);
- return;
- }
- if (action === 'reset-mock') { if (requireDesktop('重置平台 Mock 数据')) return; confirmAction({ title: '重置平台 Mock 数据', description: '恢复到 v1.1 初始演示数据。', impact: '所有本地创建的租户、账单、任务、授权、员工修改和告警状态将被清除。', confirmLabel: '确认重置' }, () => { localStorage.removeItem(STORAGE_KEY); data = clone(seed); state.selectedTenant = data.tenants[0].id; saveData(); render(); showToast('平台 Mock 数据已重置'); }); return; }
- if (action === 'open-task-center') { openModal('tasks'); return; }
- if (action === 'create-tenant') { if (requireDesktop('创建租户')) return; openModal('createTenant'); return; }
- if (action === 'new-saas-feature') { openModal('saasFeature'); return; }
- if (action === 'new-saas-offering') { openModal('saasOffering'); return; }
- if (action === 'new-saas-version') { if (!(data.saasCatalog?.offerings || []).length) { showToast('请先创建 SaaS 商品', 'error'); return; } openModal('saasVersion'); return; }
- if (action === 'new-platform-role') { openModal('platformRole'); return; }
- if (action === 'edit-platform-role') { openModal('platformRole', { roleId: actionElement.dataset.roleId }); return; }
- if (action === 'new-payment-channel') { if (!data.paymentApps.some(item => item.appScope === 'platform')) { showToast('请先创建平台支付应用', 'error'); return; } openModal('paymentChannel'); return; }
- if (action === 'edit-payment-channel') { openModal('paymentChannel', { channelId: actionElement.dataset.channelId }); return; }
- if (action === 'disable-payment-channel') { const channelId = actionElement.dataset.channelId; if (!platformApi?.isEnabled()) { const channel = data.paymentChannels.find(item => item.id === channelId); if (channel) channel.status = 'disabled'; render(); showToast('支付渠道已停用'); return; } platformApi.request('PlatformAdminPaymentSettingsController_disableChannel', { pathParams: { channelId }, body: {} }).then(payload => { const channel = data.paymentChannels.find(item => item.id === channelId); if (channel) Object.assign(channel, payload); render(); showToast('支付渠道已停用'); }).catch(error => showToast(backendErrorText(error, '停用支付渠道失败'), 'error')); return; }
- if (action === 'new-sms-template') { if (!data.smsChannels.length) { showToast('请先创建租户短信渠道', 'error'); return; } openModal('smsTemplate'); return; }
- if (action === 'edit-sms-template') { openModal('smsTemplate', { templateId: actionElement.dataset.templateId }); return; }
- if (['submit-sms-template', 'disable-sms-template'].includes(action)) { const templateId = actionElement.dataset.templateId; const operationId = action === 'submit-sms-template' ? 'PlatformAdminSmsController_submitTemplateReview' : 'PlatformAdminSmsController_disableTemplate'; if (!platformApi?.isEnabled()) { const template = data.smsTemplates.find(item => item.id === templateId); if (template) { if (action === 'submit-sms-template') template.status = '审核中'; else template.templateStatus = '未启用'; } render(); showToast(action === 'submit-sms-template' ? '短信模板已提交审核' : '短信模板已停用'); return; } platformApi.request(operationId, { pathParams: { templateId }, body: {} }).then(payload => { const template = data.smsTemplates.find(item => item.id === templateId); if (template) Object.assign(template, platformApi.adapters.smsTemplate(payload)); render(); showToast(action === 'submit-sms-template' ? '短信模板已提交审核' : '短信模板已停用'); }).catch(error => showToast(backendErrorText(error, '短信模板操作失败'), 'error')); return; }
- if (['publish-saas-version', 'clone-saas-version', 'retire-saas-version'].includes(action)) { const operationId = action === 'publish-saas-version' ? 'PlatformSaasController_publishVersion' : action === 'clone-saas-version' ? 'PlatformSaasController_cloneVersion' : 'PlatformSaasController_retireVersion'; const versionId = actionElement.dataset.versionId; if (!platformApi?.isEnabled()) { const version = data.saasCatalog.versions.find(item => item.id === versionId); if (version) version.status = action === 'retire-saas-version' ? 'retired' : action === 'publish-saas-version' ? 'published' : version.status; render(); showToast('套餐版本状态已更新'); return; } platformApi.request(operationId, { pathParams: { versionId }, body: {} }).then(() => hydrateFromBackend({ silent: true })).then(() => showToast('套餐版本状态已更新')).catch(error => showToast(backendErrorText(error, '套餐版本操作失败'), 'error')); return; }
- if (action === 'recheck-domain') { const domain = data.domains.find(item => item.id === actionElement.dataset.domainId); if (!domain) return; if (!platformApi?.isEnabled()) { showToast('真实 API 模式才能重新检查域名', 'error'); return; } platformApi.request('PlatformAdminTenantsController_recheckDomain', { pathParams: { domainId: domain.id }, body: {} }).then(payload => { Object.assign(domain, payload); render(); showToast('域名 DNS/TLS 状态已重新检查'); }).catch(error => showToast(backendErrorText(error, '域名检查失败'), 'error')); return; }
- if (action === 'prepare-tenant-status') { if (requireDesktop('变更租户生命周期')) return; openModal('tenantStatus', { tenantId: actionElement.dataset.tenantId || state.selectedTenant }); return; }
- if (action === 'open-tenant-portal') { const tenant = tenantById(state.selectedTenant); let portalWindow = null; try { portalWindow = window.open(TENANT_PORTAL_ORIGIN, '_blank'); if (portalWindow) portalWindow.opener = null; } catch {} showToast(portalWindow ? `已在新标签打开独立租户端 · ${tenant?.name || '当前租户'}` : '已请求打开独立租户端;如未出现,请允许本站弹出窗口', portalWindow ? 'success' : 'error'); return; }
- if (action === 'edit-billing-profile') { if (requireDesktop('编辑租户账务资料')) return; navigate('billingProfile'); return; }
- if (action === 'billing-profile-to-invoices' || action === 'tenant-to-billing') { if (actionElement.dataset.tenantId) state.selectedTenant = actionElement.dataset.tenantId; navigate('billing'); return; }
- if (action === 'tenant-to-usage') { state.selectedTenant = actionElement.dataset.tenantId; navigate('usage'); return; }
- if (action === 'clear-tenant-context') { state.selectedTenant = ''; render(); return; }
- if (action === 'create-subscription-for-tenant') { if (requireDesktop('创建租户订阅')) return; navigate('subscriptions'); openModal('createSubscription'); return; }
- if (action === 'create-subscription') { if (requireDesktop('创建租户订阅')) return; openModal('createSubscription'); return; }
- if (action === 'select-plan') { if (requireDesktop('选择套餐并创建订阅')) return; openModal('createSubscription', { planCode: actionElement.dataset.planCode }); return; }
- if (action === 'subscription-to-billing') { navigate('billing'); return; }
- if (action === 'subscriptions-to-usage') { navigate('usage'); return; }
- if (action === 'toggle-auto-renew') { if (requireDesktop('变更订阅自动续费')) return; if (platformApi?.isEnabled()) { showToast('后端暂未提供订阅更新接口,真实模式禁止仅改本地状态', 'error'); return; } const item = data.subscriptions.find(subscription => subscription.id === actionElement.dataset.subscriptionId); if (!canWrite('platform:billing:write')) return; item.autoRenew = !item.autoRenew; addAudit('subscription.auto_renew.update', 'subscription', item.id, item.id, '中', `自动续费更新为 ${item.autoRenew ? '开启' : '关闭'}。`); saveData(); render(); showToast('自动续费设置已更新'); return; }
- if (action === 'create-invoice') { if (requireDesktop('手工创建账单')) return; openModal('createInvoice'); return; }
- if (action === 'apply-invoice-query') { runContractRead({ key: 'invoice-query', actionId: 'act.p-06.01', operationId: 'PlatformAdminBillingController_invoices', title: '账单查询', suppliedRequestId: actionElement.dataset.contractRequestId, liveRequest: () => platformApi.request('PlatformAdminBillingController_invoices', { query: { tenantId: state.selectedTenant || undefined, status: ({ 草稿: 'draft', 待付款: 'issued', 已支付: 'paid', 已作废: 'void', 已逾期: 'overdue' })[state.invoiceStatus], limit: 200 } }), apply: payload => { const items = apiItems(payload); if (items.length) data.invoices = items.map(platformApi.adapters.invoice); return `${data.invoices.filter(invoice => (!state.selectedTenant || invoice.tenantId === state.selectedTenant) && (state.invoiceStatus === 'all' || invoice.status === state.invoiceStatus) && (!state.invoiceSearch.trim() || [invoice.id, invoice.type, invoice.period, invoice.note, tenantById(invoice.tenantId)?.name].some(value => String(value || '').toLowerCase().includes(state.invoiceSearch.trim().toLowerCase())))).length} 张匹配账单`; } }); return; }
- if (action === 'preview-invoice-candidates') { if (requireDesktop('批量生成账单')) return; openModal('invoiceCandidates'); return; }
- if (action === 'run-invoice-dry-run' && platformApi?.isEnabled()) { const subscriptionIds = Array.from(overlayRoot.querySelectorAll('[name="candidate"]:checked')).map(input => input.value); executeBackendMutation('PlatformAdminBillingController_fromSubscriptionsBatch', { subscriptionIds, dryRun: true }, payload => { const result = apiItem(payload); showToast(`Dry-run 完成 · 可生成 ${result.items?.length || 0} 条,跳过 ${result.skippedCount || 0} 条`); }, { refresh: false }); return; }
- if (action === 'run-invoice-dry-run') { const count = overlayRoot.querySelectorAll('[name="candidate"]:checked').length; showToast(`Dry-run 已校验 ${count} 条订阅候选,未写入账单`); return; }
- if (action === 'generate-subscription-invoice' && platformApi?.isEnabled()) { if (requireDesktop('为单个订阅生成账单')) return; const subscription = data.subscriptions.find(item => item.id === actionElement.dataset.subscriptionId); if (!subscription) { showToast('订阅不存在或不可用', 'error'); return; } executeBackendMutation('PlatformAdminBillingController_fromSubscription', { tenantId: subscription.tenantId, subscriptionId: subscription.id, status: 'issued' }, payload => { closeModal({ force: true }); window.recordPlatformSpecResult?.('act.p-06.04', { result: 'success', operationId: 'PlatformAdminBillingController_fromSubscription', requestId: payload?.meta?.requestId || payload?.traceId || '' }); showToast('订阅账单已由后端生成'); }); return; }
- if (action === 'generate-subscription-invoice') { if (requireDesktop('为单个订阅生成账单')) return; const subscription = data.subscriptions.find(item => item.id === actionElement.dataset.subscriptionId); const suppliedRequestId = actionElement.dataset.contractRequestId || requestId(); if (!subscription || data.invoices.some(invoice => invoice.note.includes(subscription.id))) { state.contractResults['invoice-query'] = { status: 'error', title: '单订阅生成失败', detail: '该订阅已存在账单或订阅不可用', requestId: suppliedRequestId }; addAudit('invoice.from_subscription.failed', 'subscription', subscription?.id || '-', subscription?.id || '-', '中', `幂等冲突。Request ID:${suppliedRequestId}。`, '失败'); window.recordPlatformSpecResult?.('act.p-06.04', { result: 'failed', operationId: 'PlatformAdminBillingController_fromSubscription', requestId: suppliedRequestId }); render(); return; } const task = addContractTask({ actionId: 'act.p-06.04', operationId: 'PlatformAdminBillingController_fromSubscription', label: `为订阅 ${subscription.id} 生成账单`, resultTarget: '服务费账单', suppliedRequestId, execute: taskItem => { const invoice = { id: entityId('INV'), tenantId: subscription.tenantId, type: '订阅服务费', period: '下一订阅账期', total: subscription.amount, paid: 0, balance: subscription.amount, due: subscription.expires, status: '待付款', note: `订阅 ${subscription.id}` }; data.invoices.unshift(invoice); tenantById(subscription.tenantId).balance += invoice.balance; taskItem.invoiceId = invoice.id; addAudit('invoice.from_subscription.create', 'invoice', invoice.id, invoice.id, '高', `通过任务 ${taskItem.id} 为订阅 ${subscription.id} 生成单张账单。`); } }); showToast(`单订阅账单任务 ${task.id} 已创建`); return; }
- if (action === 'confirm-generate-candidates' && platformApi?.isEnabled()) { if (requireDesktop('批量生成账单')) return; const subscriptionIds = Array.from(overlayRoot.querySelectorAll('[name="candidate"]:checked')).map(input => input.value); if (!subscriptionIds.length) { showToast('请至少选择一条订阅账单候选', 'error'); return; } executeBackendMutation('PlatformAdminBillingController_fromSubscriptionsBatch', { subscriptionIds, dryRun: false, status: 'issued' }, payload => { closeModal({ force: true }); const result = apiItem(payload); showToast(`后端已生成 ${result.createdCount || 0} 张账单,跳过 ${result.skippedCount || 0} 条`); }); return; }
- if (action === 'confirm-generate-candidates') { if (requireDesktop('批量生成账单')) return; const selectedIds = Array.from(overlayRoot.querySelectorAll('[name="candidate"]:checked')).map(input => input.value); if (!selectedIds.length) { showToast('请至少选择一条订阅账单候选', 'error'); return; } const candidates = data.subscriptions.filter(subscription => selectedIds.includes(subscription.id) && !data.invoices.some(invoice => invoice.note.includes(subscription.id))); closeModal(); const task = addTask(`批量生成 ${candidates.length} 张订阅账单`, '服务费账单', () => { candidates.forEach(subscription => { const invoice = { id: entityId('INV'), tenantId: subscription.tenantId, type: '订阅服务费', period: '下一订阅账期', total: subscription.amount, paid: 0, balance: subscription.amount, due: subscription.expires, status: '待付款', note: `订阅 ${subscription.id}` }; data.invoices.unshift(invoice); const tenant = tenantById(subscription.tenantId); tenant.balance += invoice.balance; tenant.billing = '待付款'; }); addAudit('invoice.batch.create', 'invoice_batch', task.id, task.id, '高', `批量生成 ${candidates.length} 张订阅账单。`); }); showToast(`任务 ${task.id} 已创建`); return; }
- if (action === 'confirm-payment') { if (requireDesktop('确认账单收款')) return; openModal('payment', { invoiceId: actionElement.dataset.invoiceId }); return; }
- if (action === 'preview-overdue' && platformApi?.isEnabled()) { if (requireDesktop('批量处理逾期账单')) return; executeBackendMutation('PlatformAdminBillingController_processOverdue', { dryRun: true, limit: 100, channel: 'internal' }, payload => { const result = apiItem(payload); openModal('overduePreview'); showToast(`后端 Dry-run:${result.processed || result.items?.length || 0} 条候选`); }, { refresh: false }); return; }
- if (action === 'preview-overdue') { if (requireDesktop('批量处理逾期账单')) return; openModal('overduePreview'); return; }
- if (action === 'confirm-overdue-process' && platformApi?.isEnabled()) { showToast('后端逾期处理接口不支持指定 invoiceIds,真实模式禁止按当前勾选直接执行', 'error'); return; }
- if (action === 'confirm-overdue-process') { if (requireDesktop('批量处理逾期账单')) return; const selectedIds = Array.from(overlayRoot.querySelectorAll('[name="candidate"]:checked')).map(input => input.value); if (!selectedIds.length) { showToast('请至少选择一条逾期账单候选', 'error'); return; } const overdue = data.invoices.filter(invoice => invoice.status === '已逾期' && selectedIds.includes(invoice.id)); closeModal(); const task = addTask(`处理 ${overdue.length} 张逾期账单`, '收款与催缴', () => { overdue.forEach(invoice => data.reminders.unshift({ id: entityId('REM'), invoiceId: invoice.id, tenantId: invoice.tenantId, level: 3, channel: '邮件 + 短信', status: '发送中', date: todayTime(), message: `服务费账单 ${invoice.id} 已逾期,请尽快处理。` })); addAudit('invoice.overdue.process', 'invoice_batch', task.id, task.id, '高', `生成 ${overdue.length} 条催缴记录。`); }); showToast(`催缴任务 ${task.id} 已创建`); return; }
- if (action === 'generate-reminder' && platformApi?.isEnabled()) { showToast('后端仅提供批量逾期处理,没有单账单催缴创建接口', 'error'); return; }
- if (action === 'generate-reminder') { if (requireDesktop('生成账单催缴')) return; const invoice = invoiceById(actionElement.dataset.invoiceId); const reminder = { id: entityId('REM'), invoiceId: invoice.id, tenantId: invoice.tenantId, level: invoice.status === '已逾期' ? 3 : 1, channel: '邮件 + 短信', status: '已加入队列', date: todayTime(), message: invoice.status === '已逾期' ? `账单已逾期,请尽快支付 ${money(invoice.balance)}。` : `账单即将到期,应付 ${money(invoice.balance)}。` }; data.reminders.unshift(reminder); addAudit('invoice.reminder.create', 'reminder', reminder.id, reminder.id, '中', `为 ${invoice.id} 创建 L${reminder.level} 催缴。`); saveData(); render(); showToast('催缴已加入发送队列'); return; }
- if (action === 'record-usage') { if (requireDesktop('人工记录平台用量')) return; openModal('recordUsage'); return; }
- if (action === 'preview-overage') { if (requireDesktop('批量生成超额账单')) return; openModal('overagePreview'); return; }
- if (action === 'run-overage-dry-run' && platformApi?.isEnabled()) { const tenantIds = Array.from(overlayRoot.querySelectorAll('[name="candidate"]:checked')).map(input => input.value.split(':')[0]); executeBackendMutation('PlatformAdminBillingController_fromUsage', { tenantIds, period: state.usagePeriod, dryRun: true }, payload => { const result = apiItem(payload); showToast(`超额 Dry-run 完成 · 可生成 ${result.items?.length || 0} 条`); }, { refresh: false }); return; }
- if (action === 'run-overage-dry-run') { const count = overlayRoot.querySelectorAll('[name="candidate"]:checked').length; showToast(`Dry-run 已校验 ${count} 条超额候选,未写入账单`); return; }
- if (action === 'confirm-overage-invoices' && platformApi?.isEnabled()) { if (requireDesktop('批量生成超额账单')) return; const tenantIds = Array.from(overlayRoot.querySelectorAll('[name="candidate"]:checked')).map(input => input.value.split(':')[0]); if (!tenantIds.length) { showToast('请至少选择一条超额账单候选', 'error'); return; } executeBackendMutation('PlatformAdminBillingController_fromUsage', { tenantIds, period: state.usagePeriod, dryRun: false, status: 'issued' }, payload => { closeModal({ force: true }); showToast(`后端已生成 ${apiItem(payload).createdCount || 0} 张超额账单`); }); return; }
- if (action === 'confirm-overage-invoices') { if (requireDesktop('批量生成超额账单')) return; const selectedKeys = Array.from(overlayRoot.querySelectorAll('[name="candidate"]:checked')).map(input => input.value); if (!selectedKeys.length) { showToast('请至少选择一条超额账单候选', 'error'); return; } const candidates = data.usage.filter(item => item.period === state.usagePeriod && selectedKeys.includes(`${item.tenantId}:${item.period}`) && item.estimated > 0 && !data.invoices.some(invoice => invoice.note === `超额 ${item.period}` && invoice.tenantId === item.tenantId)); closeModal(); const task = addTask(`生成 ${candidates.length} 张超额账单`, '用量与超额计费', () => { candidates.forEach(item => { const invoice = { id: entityId('INV'), tenantId: item.tenantId, type: '用量超额费', period: item.period, total: item.estimated, paid: 0, balance: item.estimated, due: '2026-08-15', status: '待付款', note: `超额 ${item.period}` }; data.invoices.unshift(invoice); const tenant = tenantById(item.tenantId); tenant.balance += invoice.balance; tenant.billing = '待付款'; }); addAudit('usage.invoice.batch.create', 'invoice_batch', task.id, task.id, '高', `生成 ${candidates.length} 张用量超额账单。`); }); showToast(`超额账单任务 ${task.id} 已创建`); return; }
- if (action === 'new-dunning-channel') { if (requireDesktop('新建催缴渠道')) return; openModal('dunningChannel'); return; }
- if (action === 'edit-dunning-channel') { if (requireDesktop('编辑催缴渠道')) return; openModal('dunningChannel', { channelId: actionElement.dataset.channelId }); return; }
- if (action === 'toggle-dunning-channel') { if (requireDesktop('变更催缴渠道状态')) return; if (!canWrite('platform:billing:notification')) return; const channel = data.dunningChannels.find(item => item.id === actionElement.dataset.channelId); if (!channel) return; const nextEnabled = !channel.enabled; const apply = () => { channel.enabled = nextEnabled; addAudit('dunning.channel.status', 'notification_channel', channel.id, channel.name, '高', `催缴渠道${channel.enabled ? '启用' : '停用'}。`); saveData(); render(); showToast('渠道状态已更新'); }; if (!platformApi?.isEnabled()) { apply(); return; } if (!nextEnabled) { executeBackendMutation('PlatformAdminDunningChannelsController_disableChannel', { channelId: channel.id, reason: '平台管理员停用催缴渠道' }, apply); return; } if (channel.endpointRedacted) { openModal('dunningChannel', { channelId: channel.id }); showToast('重新启用前请填写完整的 HTTPS 通知地址', 'error'); return; } executeBackendMutation('PlatformAdminDunningChannelsController_upsertChannel', { ...channel, enabled: true }, apply); return; }
- if (action === 'new-bank') { if (requireDesktop('新建公共题库')) return; openModal('bank'); return; }
- if (action === 'edit-bank') { if (requireDesktop('编辑公共题库')) return; openModal('bank', { bankId: state.selectedBank }); return; }
- if (action === 'archive-bank') { const bank = bankById(state.selectedBank); if (!bank) return; confirmAction({ title: '归档公共题库', description: bank.name, impact: '仅当题库中的题目和内容节点均已归档时才能归档,历史版本不会删除。', confirmLabel: '确认归档' }, () => executeBackendMutation('PlatformQuestionBanksController_archiveBank', {}, payload => { Object.assign(bank, payload ? platformApi.adapters.bank(payload, bank) : { status: '已归档' }); render(); showToast('公共题库已归档'); }, { refresh: false, pathParams: { bankId: bank.id } })); return; }
- if (action === 'new-bank-node') { if (requireDesktop('新建内容节点')) return; openModal('bankNode'); return; }
- if (action === 'edit-bank-node') { if (requireDesktop('编辑内容节点')) return; openModal('bankNode', { nodeId: state.selectedBankNode }); return; }
- if (action === 'batch-bank-nodes') { if (requireDesktop('批量创建章节或试卷')) return; openModal('batchBankNodes'); return; }
- if (action === 'shift-bank-node') { const node = bankNodeById(state.selectedBankNode); if (!node) return; const sortOrder = Number(node.sortOrder || 0) + Number(actionElement.dataset.sortDelta || 0); executeBackendMutation('PlatformQuestionBanksController_upsertNode', { id: node.id, questionBankId: node.questionBankId, parentId: node.parentId || null, nodeKey: node.nodeKey || null, name: node.name, nodeType: node.nodeType, sortOrder, isSelectable: node.isSelectable !== false, metadata: node.metadata || {} }, payload => { Object.assign(node, payload ? adaptBankNode(payload) : { sortOrder }); data.bankNodes.sort((left, right) => Number(left.sortOrder || 0) - Number(right.sortOrder || 0)); render(); showToast('内容节点顺序已保存'); }, { refresh: false }); return; }
- if (action === 'apply-bank-search') { runContractRead({ key: 'bank-query', actionId: 'act.p-09.01', operationId: 'PlatformQuestionBanksController_getBanks', title: '公共题库查询', suppliedRequestId: actionElement.dataset.contractRequestId, liveRequest: () => platformApi.request('PlatformQuestionBanksController_getBanks', { query: { keyword: state.bankSearch || undefined, status: 'all' } }), apply: payload => { const items = apiItems(payload); data.banks = items.map(item => platformApi.adapters.bank(item, bankById(item.id))); if (!bankById(state.selectedBank)) state.selectedBank = data.banks[0]?.id || ''; return `${data.banks.length} 个匹配题库`; } }); return; }
- if (action === 'load-bank-questions' || action === 'bank-question-page') { if (action === 'bank-question-page') state.bankQuestionPage = Number(actionElement.dataset.page || 1); const query = { questionBankId: state.selectedBank, contentNodeId: state.selectedBankNode || undefined, keyword: document.querySelector('#bankQuestionSearch')?.value || undefined, type: document.querySelector('#bankQuestionType')?.value || undefined, status: document.querySelector('#bankQuestionStatus')?.value || undefined, page: state.bankQuestionPage, pageSize: 20 }; if (!platformApi?.isEnabled()) { render(); return; } platformApi.request('PlatformQuestionBanksController_getQuestions', { query }).then(payload => { data.bankQuestions = apiItems(payload).map(adaptBankQuestion); state.bankQuestionTotal = Number(payload.total || data.bankQuestions.length); render(); }).catch(error => showToast(backendErrorText(error, '题目查询失败'), 'error')); return; }
- if (action === 'edit-bank-question') { const question = data.bankQuestions.find(item => item.id === actionElement.dataset.questionId); if (!question) return; state.bankTab = 'single'; state.selectedBankNode = question.contentNodeId; render(); requestAnimationFrame(() => { const form = document.querySelector('#bankQuestionForm'); if (!form) return; form.elements.id.value = question.id; form.elements.contentNodeId.value = question.contentNodeId; form.elements.type.value = question.type; form.elements.difficulty.value = question.difficulty || 3; form.elements.legacyId.value = question.legacyId || ''; form.elements.content.value = question.content || ''; form.elements.options.value = JSON.stringify(question.options || [], null, 2); form.elements.answerText.value = question.answerText || ''; form.elements.explanation.value = question.explanation || ''; form.elements.mediaUrl.value = question.mediaUrl || ''; form.elements.tags.value = Array.isArray(question.tags) ? question.tags.join('、') : ''; }); return; }
- if (action === 'archive-bank-question') { const questionId = actionElement.dataset.questionId; const apply = () => { const question = data.bankQuestions.find(item => item.id === questionId); if (question) { question.status = 'archived'; question.statusLabel = '已归档'; } render(); showToast('题目已归档'); }; confirmAction({ title: '归档题目', description: '归档后题目历史版本仍会保留。', impact: '该题目不会再进入公共题库正常查询结果。', confirmLabel: '确认归档' }, () => executeBackendMutation('PlatformQuestionBanksController_archiveQuestions', { questionIds: [questionId] }, apply, { refresh: false })); return; }
- if (action === 'archive-bank-node') { const node = bankNodeById(state.selectedBankNode); if (!node) return; confirmAction({ title: '归档内容节点', description: node.name, impact: '仅当节点没有启用的下级节点和未归档题目时才能归档。', confirmLabel: '确认归档' }, () => executeBackendMutation('PlatformQuestionBanksController_archiveNode', {}, () => { node.isActive = false; render(); showToast('内容节点已归档'); }, { refresh: false, pathParams: { nodeId: node.id } })); return; }
- if (action === 'upload-question-image') { const input = document.querySelector('#bankQuestionImage'); const file = input?.files?.[0]; if (!file) { showToast('请先选择题目图片', 'error'); return; } if (!platformApi?.isEnabled()) { document.querySelector('#bankQuestionForm').elements.mediaUrl.value = `https://static.example.test/questions/${encodeURIComponent(file.name)}`; showToast('图片地址已填入'); return; } actionElement.disabled = true; platformApi.request('PlatformQuestionBanksController_signAssetUpload', { body: { contentNodeId: state.selectedBankNode || null, fileName: file.name, mimeType: file.type || 'application/octet-stream', fileSizeBytes: file.size, title: file.name, metadata: { usage: 'question' } } }).then(async signed => { await fetch(signed.upload.url, { method: signed.upload.method || 'PUT', headers: signed.upload.headers || {}, body: file }); const confirmed = await platformApi.request('PlatformQuestionBanksController_confirmAssetUpload', { body: { assetId: signed.item.id, mimeType: file.type, fileSizeBytes: file.size } }); document.querySelector('#bankQuestionForm').elements.mediaUrl.value = confirmed.item.cdnUrl || String(signed.upload.url).split('?')[0]; markDirty('page'); showToast('题目图片已上传并填入地址'); }).catch(error => showToast(backendErrorText(error, '题目图片上传失败'), 'error')).finally(() => { actionElement.disabled = false; }); return; }
- if (action === 'preview-question') { const form = document.querySelector('#bankQuestionForm'); showToast(form?.elements.content.value?.trim() ? `题目预览:${form.elements.content.value.trim().slice(0, 80)}` : '请先填写题干', form?.elements.content.value?.trim() ? 'success' : 'error'); return; }
- if (action === 'new-crm-config' || action === 'edit-crm-config') { if (!canWrite('platform:crm:write')) return; openModal('crmConfig', { crmId: actionElement.dataset.crmId || '' }); return; }
- if (action === 'crm-rule-detail') { showToast('CRM 分配策略保存在接入配置的 assignmentConfig 中'); return; }
- if (action === 'toggle-crm-config') { if (!canWrite('platform:crm:write')) return; const config = data.crmConfigs.find(item => item.id === actionElement.dataset.crmId); if (!config) return; const nextEnabled = !config.enabled; const apply = payload => { const next = payload ? platformApi.adapters.crmConfig(payload) : { ...config, enabled: nextEnabled, status: nextEnabled ? '正常' : '未启用' }; Object.assign(config, next); addAudit('crm.config.status', 'crm_config', config.id, tenantById(config.tenantId)?.name || config.id, '中', `CRM 接入${config.enabled ? '启用' : '停用'}。`); saveData(); render(); showToast('CRM 接入状态已更新'); }; if (platformApi?.isEnabled()) executeBackendMutation('PlatformAdminCrmController_upsertConfig', { ...config, enabled: nextEnabled }, apply); else apply(); return; }
- if (action === 'retry-crm-lead') { if (!canWrite('platform:crm:write')) return; const lead = data.crmLeads.find(item => item.id === actionElement.dataset.leadId); if (!lead) return; const apply = payload => { const next = payload ? platformApi.adapters.crmLead(payload) : { ...lead, status: '重试中', attempts: lead.attempts + 1, lastError: '' }; Object.assign(lead, next); addAudit('crm.lead.retry', 'crm_lead', lead.id, lead.student, '中', `CRM 线索 ${lead.id} 已重试推送。`); saveData(); render(); showToast('线索已进入重试队列'); }; if (platformApi?.isEnabled()) executeBackendMutation('PlatformAdminCrmController_retryLead', lead, apply); else apply(); return; }
- if (action === 'new-sms-channel' || action === 'edit-sms-channel') { if (!canWrite('platform:sms:write')) return; openModal('smsChannel', { smsId: actionElement.dataset.smsId || '' }); return; }
- if (action === 'toggle-sms-channel') { if (!canWrite('platform:sms:write')) return; const channel = data.smsChannels.find(item => item.id === actionElement.dataset.smsId); if (!channel) return; const nextStatus = channel.enabled ? '未启用' : '正常'; const apply = payload => { const next = payload ? platformApi.adapters.smsChannel(payload) : { ...channel, enabled: nextStatus === '正常', status: nextStatus }; Object.assign(channel, next); addAudit('sms.channel.status', 'sms_channel', channel.id, tenantById(channel.tenantId)?.name || channel.id, '中', `短信渠道${channel.enabled ? '启用' : '停用'}。`); saveData(); render(); showToast('短信渠道状态已更新'); }; if (!platformApi?.isEnabled()) { apply(); return; } if (channel.enabled) { executeBackendMutation('PlatformAdminSmsController_disableChannel', {}, apply, { refresh: false, pathParams: { channelId: channel.id } }); return; } executeBackendMutation('PlatformAdminSmsController_upsertChannel', { ...channel, status: nextStatus }, apply); return; }
- if (action === 'new-payment-app' || action === 'edit-payment-app') { if (!canWrite('platform:payment:write')) return; openModal('paymentApp', { paymentId: actionElement.dataset.paymentId || '' }); return; }
- if (action === 'payment-rule-detail') { showToast('支付风控规则用于证书提醒、回调重试和人工确认保护'); return; }
- if (action === 'toggle-payment-app') { if (!canWrite('platform:payment:write')) return; const paymentApp = data.paymentApps.find(item => item.id === actionElement.dataset.paymentId); if (!paymentApp) return; const disabling = paymentApp.status !== '未启用'; const nextStatus = disabling ? '未启用' : '正常'; const operationId = paymentApp.appScope === 'tenant' ? 'PlatformAdminTenantPaymentSettingsController_upsertApp' : 'PlatformAdminPaymentSettingsController_upsertApp'; const apply = payload => { const next = payload ? (paymentApp.appScope === 'tenant' ? platformApi.adapters.tenantPaymentApp(payload) : platformApi.adapters.platformPaymentApp(payload)) : { ...paymentApp, status: nextStatus }; Object.assign(paymentApp, next); addAudit('payment.app.status', 'payment_app', paymentApp.id, paymentApp.appName, '高', `支付应用${disabling ? '停用' : '启用'}。`); saveData(); render(); showToast('支付应用状态已更新'); }; if (platformApi?.isEnabled()) executeBackendMutation(operationId, { ...paymentApp, status: nextStatus }, apply); else apply(); return; }
- if (action === 'new-staff') { if (requireDesktop('新建平台员工与授权')) return; openModal('staff', { roleId: actionElement.dataset.roleId || '' }); return; }
- if (action === 'edit-staff') { if (requireDesktop('编辑平台员工与授权')) return; openModal('staff', { staffId: actionElement.dataset.staffId }); return; }
- if (action === 'toggle-staff') { if (requireDesktop('变更平台员工状态')) return; if (!canWrite('platform:staff:status')) return; const person = data.staff.find(item => item.id === actionElement.dataset.staffId); if (!person) return; const disabling = person.status === '正常'; const isSuperAdmin = person.roleCodes?.includes('platform_super_admin'); if (disabling && isSuperAdmin && data.staff.filter(item => item.roleCodes?.includes('platform_super_admin') && item.status === '正常').length === 1) { showToast('不能禁用最后一名超级管理员', 'error'); return; } const apply = () => { person.status = disabling ? '已停用' : '正常'; addAudit('staff.status.update', 'staff', person.id, person.name, '高', `${disabling ? '停用并撤销会话' : '启用'}平台员工。`); saveData(); render(); showToast(`员工已${disabling ? '停用并撤销会话' : '启用'}`); }; const execute = () => platformApi?.isEnabled() ? executeBackendMutation('PlatformAdminOverviewController_updateStaffStatus', { userId: person.userId || person.id, status: disabling ? 'disabled' : 'active', reason: disabling ? '平台控制台停用员工' : '平台控制台启用员工' }, apply) : apply(); if (disabling) confirmAction({ title: '停用平台员工', description: `${person.name} · ${person.role}`, impact: '该员工的全部平台会话将立即撤销,后续无法登录平台端;租户端权限不在本域名内处理。', confirmLabel: '停用并撤销会话', confirmActionName: 'execute-staff-disable' }, execute); else execute(); return; }
- if (action === 'select-permission-group') { const form = overlayRoot.querySelector('#staffForm'); const role = fieldValue(form, 'role'); const recommended = role === '平台财务' ? ['platform:billing:read', 'platform:billing:write', 'platform:billing:payment', 'platform:billing:dunning', 'platform:billing:notification', 'platform:usage:read', 'platform:usage:write', 'platform:payment:read', 'platform:payment:write'] : role === '安全审计' ? ['platform:audit:read', 'platform:audit:export', 'platform:audit:alert', 'platform:audit:notification'] : role === '题库运营' ? ['platform:dashboard:view', 'platform:question-bank:manage'] : role === '租户运营' ? ['platform:tenant:read', 'platform:tenant:write', 'platform:tenant:status', 'platform:tenant:billing_profile', 'platform:crm:read', 'platform:crm:write', 'platform:sms:read', 'platform:sms:write'] : Array.from(form.querySelectorAll('[name="permissions"]')).map(input => input.value); form.querySelectorAll('[name="permissions"]').forEach(input => { input.checked = recommended.includes(input.value); }); return; }
- if (action === 'clear-staff-form') { const form = overlayRoot.querySelector('#staffForm'); if (!form) return; form.querySelectorAll('input:not([type="hidden"]):not([type="checkbox"])').forEach(input => { input.value = ''; }); form.querySelectorAll('input[type="checkbox"]').forEach(input => { input.checked = false; }); state.modalData.dirty = true; form.querySelector('[name="name"]')?.focus(); return; }
- if (action === 'apply-staff-search') { render(); return; }
- if (action === 'export-audit') { if (!hasPermission('platform:audit:export')) { showToast('缺少导出权限:platform:audit:export', 'error'); return; } const format = actionElement.dataset.format || 'csv'; if (platformApi?.isEnabled()) { platformApi.request('PlatformAdminAuditController_exportLogs', { query: { format, q: state.auditSearch || undefined, limit: 500 } }).then(payload => { const item = platformApi.downloadExport(payload); showToast(`审计文件已下载 · ${item.rowCount ?? item.rows ?? 0} 行 · ${item.sha256 || item.hash || 'hash 见响应'}`); }).catch(error => showToast(backendErrorText(error, '审计导出失败'), 'error')); return; } const task = addTask(`导出平台审计日志 ${format.toUpperCase()}`, '任务中心下载文件', taskItem => { taskItem.file = `platform-audit-${Date.now()}.${format}`; taskItem.hash = `sha256:${Math.random().toString(36).slice(2).padEnd(32, '0')}`; taskItem.rows = data.auditLogs.length; }); showToast(`导出任务 ${task.id} 已创建`); return; }
- if (action === 'jump-related-alert') { state.alertStatus = 'all'; state.selectedAlert = data.alerts.find(alert => data.auditLogs.some(log => log.targetId === alert.targetId || log.targetId === alert.id))?.id || ''; navigate('alerts'); if (state.selectedAlert) openModal('alertDetail', { alertId: state.selectedAlert }); return; }
- if (action === 'jump-audit-target') { const log = data.auditLogs.find(item => item.id === actionElement.dataset.auditId); closeModal(); if (log.targetType === 'tenant') { state.selectedTenant = log.targetId; navigate('tenantDetail'); } else if (log.targetType === 'invoice') { state.selectedInvoice = log.targetId; navigate('billing'); } else if (log.targetType === 'question_bank') navigate('bank'); else navigate('alerts'); return; }
- if (action === 'transition-alert') { if (!canWrite('platform:audit:alert')) return; const alert = data.alerts.find(item => item.id === actionElement.dataset.alertId); const next = actionElement.dataset.nextStatus; if (!alert) return; if (!['open', 'acknowledged'].includes(alert.status)) { showToast('已结束告警禁止重新打开或再次处理', 'error'); return; } if (alert.status === 'open' && !['acknowledged', 'resolved', 'ignored'].includes(next)) return; if (alert.status === 'acknowledged' && !['resolved', 'ignored'].includes(next)) return; const note = document.querySelector('#alertNote')?.value.trim() || ''; const apply = () => { alert.status = next; alert.note = note; alert.updatedAt = '刚刚'; addAudit('audit.alert.status.update', 'audit_alert', alert.id, alert.title, '高', `告警状态更新为 ${alertStatusLabel(next)}${note ? `,备注:${note}` : ''}。`); clearDirty('modal'); saveData(); closeModal({ force: true }); render(); showToast(`告警已${alertStatusLabel(next)}`); }; if (platformApi?.isEnabled()) executeBackendMutation('PlatformAdminAuditController_updateAlert', { alertId: alert.id, status: next, note }, apply); else apply(); return; }
- if (action === 'new-audit-channel') { if (requireDesktop('新建审计通知渠道')) return; openModal('auditChannel'); return; }
- if (action === 'edit-audit-channel') { if (requireDesktop('编辑审计通知渠道')) return; openModal('auditChannel', { channelId: actionElement.dataset.channelId }); return; }
- if (action === 'toggle-audit-channel') { if (requireDesktop('变更审计通知渠道状态')) return; if (!canWrite('platform:audit:notification')) return; const channel = data.auditChannels.find(item => item.id === actionElement.dataset.channelId); if (!channel) return; if (platformApi?.isEnabled() && channel.endpointRedacted) { openModal('auditChannel', { channelId: channel.id }); showToast('后端不回显完整 Webhook;请重新输入完整 HTTPS URL 后保存状态', 'error'); return; } const nextEnabled = !channel.enabled; const apply = () => { channel.enabled = nextEnabled; addAudit('audit.channel.status', 'notification_channel', channel.id, channel.name, '高', `审计告警渠道${channel.enabled ? '启用' : '停用'}。`); saveData(); render(); showToast('审计通知渠道状态已更新'); }; if (platformApi?.isEnabled()) executeBackendMutation('PlatformAdminAuditController_upsertChannel', { ...channel, enabled: nextEnabled }, apply); else apply(); return; }
- if (action === 'retry-notification') { const eventId = actionElement.dataset.eventId; const dunningEvent = (data.dunningEvents || []).find(item => item.id === eventId); const notification = dunningEvent || (data.notificationEvents || []).find(item => item.id === eventId); if (!notification) return; if (platformApi?.isEnabled()) { if (!dunningEvent) { showToast('审计通知暂无后端重试接口', 'error'); return; } platformApi.request('PlatformAdminDunningEventsController_retryEvent', { body: { eventId, reason: '平台管理员手工重试' } }).then(payload => { Object.assign(dunningEvent, platformApi.adapters.event(payload, 'dunning')); closeModal({ force: true }); render(); showToast('催缴通知事件已重新标记待发送'); }).catch(error => showToast(backendErrorText(error, '催缴通知重试失败'), 'error')); return; } notification.status = '重试中'; notification.attempts += 1; notification.updatedAt = `${todayTime()} CST`; saveData(); render(); setTimeout(() => { notification.status = '成功'; notification.error = ''; saveData(); render(); showToast('通知重试成功'); }, 800); return; }
- if (action === 'retry-task') { const task = data.tasks.find(item => item.id === actionElement.dataset.taskId); task.status = 'processing'; task.error = ''; task.updatedAt = todayTime(); saveData(); renderOverlay(); setTimeout(() => { task.status = 'completed'; task.updatedAt = todayTime(); saveData(); renderOverlay(); updateCounters(); showToast('任务重试完成'); }, 900); return; }
-});
-
-document.addEventListener('input', event => {
- if (state.modal && event.target.closest('#overlayRoot') && event.target.matches('input,select,textarea')) markDirty('modal');
- if (event.target.closest('#mainView form')) markDirty('page');
- if (event.target.id === 'tenantSearch') { state.tenantSearch = event.target.value; clearTimeout(state.searchTimer); state.searchTimer = setTimeout(render, 180); }
- if (event.target.id === 'invoiceSearch') state.invoiceSearch = event.target.value;
- if (event.target.id === 'bankSearch') state.bankSearch = event.target.value;
- if (event.target.id === 'staffSearch') { state.staffSearch = event.target.value; clearTimeout(state.staffTimer); state.staffTimer = setTimeout(render, 180); }
- if (event.target.id === 'auditSearch') { state.auditSearch = event.target.value; clearTimeout(state.auditTimer); state.auditTimer = setTimeout(render, 180); }
- if (event.target.id === 'globalSearch') state.globalSearch = event.target.value;
- if (['tenantSearch', 'invoiceSearch', 'bankSearch', 'staffSearch', 'auditSearch'].includes(event.target.id)) syncNavigationState();
-});
-document.addEventListener('change', event => {
- if (state.modal && event.target.closest('#overlayRoot') && event.target.matches('input,select,textarea')) markDirty('modal');
- if (event.target.closest('#mainView form')) markDirty('page');
- if (event.target === roleSelect) { state.role = event.target.value; state.scenario = 'normal'; if (!hasPermission(pageMeta[state.view].permission)) state.view = 'overview'; render(); showToast(`已切换为${roleDefinitions[state.role].label}`); }
- if (event.target === scenarioSelect) { state.scenario = event.target.value; render(); }
- if (event.target === responseSelect) { state.response = event.target.value; showToast('下一次 Mock 写请求结果已设置'); }
- if (event.target.id === 'tenantPlanFilter') { state.tenantPlan = event.target.value; syncNavigationState(); render(); }
- if (event.target.id === 'invoiceStatusFilter') { state.invoiceStatus = event.target.value; syncNavigationState(); }
- if (event.target.id === 'usagePeriodFilter') { state.usagePeriod = event.target.value; syncNavigationState(); render(); }
- if (event.target.id === 'auditRangeFilter') { state.auditRange = event.target.value; syncNavigationState(); render(); }
- if (event.target.id === 'bankSelector') { state.selectedBank = event.target.value; state.selectedBankNode = ''; state.bankQuestionPage = 1; syncNavigationState(); render(); loadBankWorkspace(); }
- if (event.target.id === 'bankStructuredFile') { const file = event.target.files?.[0]; if (!file) return; file.text().then(text => { const target = document.querySelector('#bankStructuredPayload'); if (target) { target.value = text; markDirty('page'); } }).catch(() => showToast('无法读取所选 JSON 文件', 'error')); }
-});
-menuButton.addEventListener('click', toggleMobileMenu);
-document.querySelector('#sidebarBackdrop').addEventListener('click', closeMobileMenu);
-document.addEventListener('keydown', event => {
- if ((event.metaKey || event.ctrlKey) && event.key.toLowerCase() === 'k') { event.preventDefault(); document.querySelector('#globalSearch').focus(); }
- if (event.key === 'Enter' && event.target.id === 'globalSearch') {
- event.preventDefault();
- const query = event.target.value.trim().toLowerCase();
- if (!query) { showToast('请输入租户、账单、告警或审计关键词', 'error'); return; }
- const tenant = data.tenants.find(item => [item.name, item.slug, item.legal, item.host].some(value => value.toLowerCase().includes(query)));
- if (tenant) { state.selectedTenant = tenant.id; navigate('tenantDetail'); showToast(`已定位租户:${tenant.name}`); return; }
- const invoice = data.invoices.find(item => [item.id, item.type, item.period, item.note].some(value => String(value).toLowerCase().includes(query)));
- if (invoice) { state.selectedTenant = invoice.tenantId; state.selectedInvoice = invoice.id; navigate('billing'); showToast(`已定位账单:${invoice.id}`); return; }
- const alert = data.alerts.find(item => [item.id, item.title, item.summary].some(value => value.toLowerCase().includes(query)));
- if (alert) { state.selectedAlert = alert.id; navigate('alerts'); openModal('alertDetail', { alertId: alert.id }); return; }
- const audit = data.auditLogs.find(item => [item.id, item.actor, item.action, item.target, item.details].some(value => value.toLowerCase().includes(query)));
- if (audit) { navigate('audit'); openModal('auditDetail', { auditId: audit.id }); return; }
- showToast('没有找到匹配的租户、账单、告警或审计事件', 'error');
- }
- if (event.key === 'Tab' && state.modal) {
- const modal = overlayRoot.querySelector('.modal');
- const focusable = modal ? Array.from(modal.querySelectorAll('button:not([disabled]),input:not([disabled]):not([type="hidden"]),select:not([disabled]),textarea:not([disabled]),[tabindex]:not([tabindex="-1"])')).filter(element => element.offsetParent !== null) : [];
- if (focusable.length) {
- const first = focusable[0]; const last = focusable[focusable.length - 1];
- if (event.shiftKey && document.activeElement === first) { event.preventDefault(); last.focus(); }
- else if (!event.shiftKey && document.activeElement === last) { event.preventDefault(); first.focus(); }
- }
- }
- if (event.key === 'Escape') { if (state.modal) closeModal(); else if (app.classList.contains('menu-open')) closeMobileMenu(); else if (pageMeta[state.view]?.level > 1) navigateBack(); }
-});
-document.addEventListener('click', event => {
- const choice = event.target.closest('[data-leave-choice]')?.dataset.leaveChoice;
- if (!choice) return;
- event.preventDefault(); event.stopImmediatePropagation();
- if (choice === 'stay') { pendingLeave = null; closeLeaveGuard(); return; }
- const leave = pendingLeave; pendingLeave = null; clearDirty(leave?.scope || ''); closeLeaveGuard(); leave?.execute?.();
-}, true);
-window.addEventListener('beforeunload', event => { if (!hasUnsavedChanges()) return; event.preventDefault(); event.returnValue = ''; });
-window.addEventListener('DOMContentLoaded', async () => {
- if (platformApi?.isEnabled()) {
- const authenticated = await window.GongxuePlatformAuth?.requireSession();
- if (!authenticated) return;
- document.documentElement.dataset.platformMode = 'api';
- }
- setupPrototypeControls();
- if (platformApi?.isEnabled()) document.querySelector('.prototype-controls')?.setAttribute('hidden', '');
- render();
- const rootSnapshot = navigationSnapshot();
- history.replaceState({ [HISTORY_APP_KEY]: true, rootGuard: true, sequence: historySequence, snapshot: rootSnapshot }, '', location.href);
- historySequence += 1;
- history.pushState({ [HISTORY_APP_KEY]: true, sequence: historySequence, snapshot: rootSnapshot }, '', location.href);
- if (platformApi?.isEnabled()) hydrateFromBackend({ silent: true });
-});
diff --git a/Tiku.Api/wwwroot/platform-admin/index.html b/Tiku.Api/wwwroot/platform-admin/index.html
deleted file mode 100644
index 497d823..0000000
--- a/Tiku.Api/wwwroot/platform-admin/index.html
+++ /dev/null
@@ -1,35 +0,0 @@
-
-
-
-
-
-
- 恭学题库 SaaS · 平台管理
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Tiku.Api/wwwroot/platform-admin/platform-api.js b/Tiku.Api/wwwroot/platform-admin/platform-api.js
deleted file mode 100644
index 991bdf3..0000000
--- a/Tiku.Api/wwwroot/platform-admin/platform-api.js
+++ /dev/null
@@ -1,1318 +0,0 @@
-(() => {
- const defaults = {
- mode: 'mock',
- apiBaseUrl: '',
- fallbackToMock: true,
- timeoutMs: 10000,
- getAccessToken: null,
- };
- const runtime = { ...defaults, ...(window.GONGXUE_PLATFORM_RUNTIME_CONFIG || {}) };
- const operationCatalog = Object.fromEntries(
- (window.GONGXUE_PLATFORM_SPEC?.operations || []).map(operation => [operation.operationId, operation]),
- );
- const trace = [];
-
- class PlatformApiError extends Error {
- constructor(message, options = {}) {
- super(message);
- this.name = 'PlatformApiError';
- this.status = Number(options.status || 0);
- this.code = options.code || 'PLATFORM_API_ERROR';
- this.requestId = options.requestId || '';
- this.operationId = options.operationId || '';
- this.details = options.details;
- }
- }
-
- function normalizeBaseUrl(value) {
- return String(value || '').trim().replace(/\/+$/, '');
- }
-
- function isEnabled() {
- return runtime.mode === 'api' || (runtime.mode === 'auto' && Boolean(normalizeBaseUrl(runtime.apiBaseUrl)));
- }
-
- function publicConfig() {
- return {
- mode: runtime.mode,
- apiBaseUrl: normalizeBaseUrl(runtime.apiBaseUrl),
- fallbackToMock: runtime.fallbackToMock !== false,
- timeoutMs: Number(runtime.timeoutMs) || defaults.timeoutMs,
- configured: isEnabled(),
- };
- }
-
- async function accessToken() {
- const provider = typeof runtime.getAccessToken === 'function'
- ? runtime.getAccessToken
- : typeof window.GONGXUE_PLATFORM_ACCESS_TOKEN_PROVIDER === 'function'
- ? window.GONGXUE_PLATFORM_ACCESS_TOKEN_PROVIDER
- : null;
- const token = provider ? await provider() : '';
- return String(token || '').trim();
- }
-
- function buildUrl(path, query = {}, pathParams = {}) {
- const baseUrl = normalizeBaseUrl(runtime.apiBaseUrl);
- const resolvedPath = Object.entries(pathParams).reduce((value, [key, replacement]) => value.replace(`{${key}}`, encodeURIComponent(String(replacement))), path);
- const url = new URL(`${baseUrl}${resolvedPath.startsWith('/') ? resolvedPath : `/${resolvedPath}`}`, window.location.href);
- Object.entries(query).forEach(([key, value]) => {
- if (value === undefined || value === null || value === '') return;
- url.searchParams.set(key, Array.isArray(value) ? value.join(',') : String(value));
- });
- return url.toString();
- }
-
- function responseRequestId(payload, response) {
- return String(
- payload?.meta?.requestId
- || payload?.requestId
- || payload?.traceId
- || payload?.extensions?.traceId
- || response?.headers?.get?.('x-request-id')
- || '',
- );
- }
-
- function responseErrorCode(payload) {
- return String(payload?.code || payload?.extensions?.code || payload?.errorCode || 'PLATFORM_API_REQUEST_FAILED');
- }
-
- function responseErrorMessage(payload, status) {
- return String(payload?.message || payload?.title || payload?.error || `请求失败(HTTP ${status})`);
- }
-
- async function request(operationId, options = {}) {
- const operation = operationCatalog[operationId];
- if (!operation) {
- throw new PlatformApiError(`未知平台接口:${operationId}`, {
- code: 'PLATFORM_OPERATION_UNKNOWN',
- operationId,
- });
- }
- if (!isEnabled()) {
- throw new PlatformApiError('平台 API 未启用', {
- code: 'PLATFORM_API_DISABLED',
- operationId,
- });
- }
- const token = await accessToken();
- if (!token) {
- throw new PlatformApiError('缺少平台管理员 access token', {
- status: 401,
- code: 'PLATFORM_ACCESS_TOKEN_MISSING',
- operationId,
- });
- }
- const extraHeaders = Object.fromEntries(Object.entries(options.headers || {}).map(([key, value]) => [key, String(value)]));
- const forbiddenHeader = Object.keys(extraHeaders).find((key) => {
- const normalized = key.toLowerCase();
- return ['authorization', 'x-user-id', 'x-platform-admin-key'].includes(normalized)
- || normalized.startsWith('x-tenant-');
- });
- if (forbiddenHeader) {
- throw new PlatformApiError(`禁止页面覆盖身份头:${forbiddenHeader}`, {
- code: 'PLATFORM_IDENTITY_HEADER_FORBIDDEN',
- operationId,
- });
- }
-
- const controller = new AbortController();
- const timeout = setTimeout(() => controller.abort(), Number(runtime.timeoutMs) || defaults.timeoutMs);
- const startedAt = Date.now();
- if (options.signal) {
- if (options.signal.aborted) controller.abort();
- else options.signal.addEventListener('abort', () => controller.abort(), { once: true });
- }
- try {
- const response = await fetch(buildUrl(operation.path, options.query, options.pathParams), {
- method: operation.method,
- headers: {
- ...extraHeaders,
- Accept: 'application/json',
- Authorization: `Bearer ${token}`,
- ...(operation.method === 'GET' ? {} : { 'Content-Type': 'application/json' }),
- },
- body: operation.method === 'GET' || options.body === undefined
- ? undefined
- : JSON.stringify(options.body),
- credentials: 'omit',
- signal: controller.signal,
- });
- const text = await response.text();
- let payload = {};
- if (text) {
- try {
- payload = JSON.parse(text);
- } catch {
- payload = { error: text.slice(0, 500) };
- }
- }
- const requestId = responseRequestId(payload, response);
- trace.push({
- operationId,
- method: operation.method,
- path: operation.path,
- status: response.status,
- requestId,
- durationMs: Date.now() - startedAt,
- at: new Date().toISOString(),
- });
- if (trace.length > 120) trace.splice(0, trace.length - 120);
- if (!response.ok) {
- throw new PlatformApiError(
- responseErrorMessage(payload, response.status),
- {
- status: response.status,
- code: responseErrorCode(payload),
- requestId,
- operationId,
- details: payload,
- },
- );
- }
- return payload;
- } catch (error) {
- if (error instanceof PlatformApiError) throw error;
- const aborted = error?.name === 'AbortError';
- throw new PlatformApiError(aborted ? '平台接口请求超时' : (error?.message || '平台接口请求失败'), {
- code: aborted ? 'PLATFORM_API_TIMEOUT' : 'PLATFORM_API_NETWORK_ERROR',
- operationId,
- details: error,
- });
- } finally {
- clearTimeout(timeout);
- }
- }
-
- const dictionaries = {
- tenantStatusToApi: { 待配置: 'draft', 试用: 'active', 正常: 'active', 暂停: 'suspended', 已归档: 'archived' },
- tenantStatusFromApi: { draft: '待配置', active: '正常', suspended: '暂停', archived: '已归档' },
- billingStatusToApi: { 试用: 'trial', 正常: 'active', 待付款: 'active', 逾期: 'past_due', 暂停: 'suspended', 已取消: 'cancelled' },
- billingStatusFromApi: { trial: '试用', active: '正常', past_due: '逾期', suspended: '暂停', cancelled: '已取消' },
- subscriptionStatusToApi: { 试用中: 'trial', 活跃: 'active', 暂停: 'suspended', 已取消: 'cancelled', 已到期: 'expired' },
- subscriptionStatusFromApi: { trial: '试用中', active: '活跃', suspended: '暂停', cancelled: '已取消', expired: '已到期' },
- invoiceStatusFromApi: { draft: '草稿', issued: '待付款', paid: '已支付', void: '已作废', overdue: '已逾期' },
- invoiceTypeToApi: { 订阅服务费: 'subscription', 用量超额费: 'usage', 人工调整: 'adjustment', 首期服务费: 'manual' },
- invoiceTypeFromApi: { subscription: '订阅服务费', usage: '用量超额费', usage_overage: '用量超额费', manual: '人工账单', adjustment: '人工调整' },
- severityToApi: { 低: 'low', 中: 'medium', 高: 'high', 严重: 'critical' },
- severityFromApi: { low: '低', medium: '中', high: '高', critical: '严重' },
- providerToApi: { Webhook: 'generic', SMTP: 'generic', 邮件: 'generic', 短信: 'generic', 钉钉: 'dingtalk', 飞书: 'feishu', 企微: 'wecom' },
- providerFromApi: { generic: 'Webhook', dingtalk: '钉钉', feishu: '飞书', wecom: '企微' },
- eventStatusFromApi: { pending: '待处理', processing: '发送中', sent: '成功', retrying: '重试中', failed: '失败', discarded: '已丢弃' },
- crmStatusFromApi: { pending: '待推送', processing: '推送中', retrying: '重试中', sent: '已推送', failed: '推送失败', discarded: '已忽略' },
- providerStatusFromApi: { active: '正常', disabled: '未启用', testing: '测试中' },
- providerStatusToApi: { 正常: 'active', 未启用: 'disabled', 测试中: 'testing' },
- smsTemplateStatusFromApi: { active: '正常', disabled: '未启用' },
- smsAuditStatusFromApi: { draft: '草稿', pending_review: '审核中', approved: '已通过', rejected: '已拒绝' },
- paymentStatusFromApi: { active: '正常', disabled: '未启用', testing: '测试中' },
- paymentStatusToApi: { 正常: 'active', 未启用: 'disabled', 测试中: 'testing' },
- };
-
- const platformPermissionLabels = {
- 'platform:dashboard:view': '查看平台经营概览',
- 'platform:tenant:manage': '管理平台租户',
- 'platform:staff:manage': '管理平台员工',
- 'platform:role:manage': '管理平台角色与权限',
- 'platform:question-bank:manage': '运营平台公共题库',
- 'platform:audit:view': '查看平台审计与告警',
- 'platform:billing:notification': '管理账务催缴通知',
- 'platform:saas-catalog:manage': '管理 SaaS 商品与版本',
- 'platform:saas-billing:manage': '管理 SaaS 订单与账务',
- 'platform:crm:read': '查看租户 CRM 配置',
- 'platform:crm:write': '管理租户 CRM 配置',
- 'platform:sms:read': '查看租户短信服务',
- 'platform:sms:write': '管理租户短信服务',
- 'platform:payment:read': '查看平台支付设置',
- 'platform:payment:write': '管理平台支付设置',
- };
-
- const platformRoleLabels = {
- platform_super_admin: { name: '超级管理员', description: '拥有全部平台管理权限' },
- };
-
- function mapValue(map, value, fallback = value) {
- return Object.prototype.hasOwnProperty.call(map, value) ? map[value] : fallback;
- }
-
- function centsToYuan(value) {
- const number = Number(value || 0);
- return Number.isFinite(number) ? number / 100 : 0;
- }
-
- function yuanToCents(value) {
- const number = Number(value || 0);
- return Number.isFinite(number) ? Math.round(number * 100) : 0;
- }
-
- function dateOnly(value) {
- return value ? String(value).slice(0, 10) : '';
- }
-
- function monthOnly(value) {
- return value ? String(value).slice(0, 7) : '';
- }
-
- function dateTime(value) {
- if (!value) return '-';
- const parsed = new Date(value);
- if (Number.isNaN(parsed.getTime())) return String(value);
- return new Intl.DateTimeFormat('zh-CN', {
- timeZone: 'Asia/Shanghai',
- year: 'numeric',
- month: '2-digit',
- day: '2-digit',
- hour: '2-digit',
- minute: '2-digit',
- second: '2-digit',
- hour12: false,
- }).format(parsed).replaceAll('/', '-');
- }
-
- function isoStartOfDay(value) {
- if (!value) return undefined;
- return `${String(value).slice(0, 10)}T00:00:00+08:00`;
- }
-
- function splitList(value) {
- if (Array.isArray(value)) return value.map(String).map(item => item.trim()).filter(Boolean);
- return String(value || '').split(/[、,,]/).map(item => item.trim()).filter(Boolean);
- }
-
- function periodBounds(period) {
- const match = String(period || '').match(/^(\d{4})-(\d{2})$/);
- if (!match) return { periodStart: '', periodEnd: '' };
- const year = Number(match[1]);
- const month = Number(match[2]);
- const lastDay = new Date(Date.UTC(year, month, 0)).getUTCDate();
- return {
- periodStart: `${match[1]}-${match[2]}-01`,
- periodEnd: `${match[1]}-${match[2]}-${String(lastDay).padStart(2, '0')}`,
- };
- }
-
- function invoicePeriodBounds(label) {
- const match = String(label || '').match(/^(\d{4})年(\d{1,2})月$/);
- return match ? periodBounds(`${match[1]}-${String(match[2]).padStart(2, '0')}`) : {};
- }
-
- const bodyBuilders = {
- PlatformSaasController_upsertFeature(input) {
- return { id: input.id || undefined, code: input.code, name: input.name, category: input.category, description: input.description || undefined, referencePriceCents: yuanToCents(input.referencePrice), currency: 'CNY', status: input.status || 'active', sortOrder: Number(input.sortOrder || 100) };
- },
- PlatformSaasController_upsertOffering(input) {
- return { id: input.id || undefined, code: input.code, name: input.name, type: input.type || 'base_plan', status: input.status || 'active', description: input.description || undefined, sortOrder: Number(input.sortOrder || 100) };
- },
- PlatformSaasController_upsertFeatureLimit(input) {
- return { id: input.id || undefined, metricCode: input.metricCode, featureCode: input.featureCode, name: input.name, unit: input.unit || 'count', kind: input.kind || 'current', warningPercent: Number(input.warningPercent || 80), isHardLimit: input.isHardLimit !== false };
- },
- PlatformSaasController_upsertVersion(input) {
- return { id: input.id || undefined, offeringId: input.offeringId, billingCycle: input.billingCycle || 'yearly', originalAmountCents: yuanToCents(input.originalAmount), amountCents: yuanToCents(input.amount), currency: 'CNY', effectiveAt: input.effectiveAt ? new Date(input.effectiveAt).toISOString() : undefined, featureCodes: splitList(input.featureCodes), limits: {}, metadata: {} };
- },
- PlatformBackofficeController_upsertRole(input) {
- return { id: input.id || undefined, code: input.code, name: input.name, status: input.status || 'active', description: input.description || undefined };
- },
- PlatformBackofficeController_replaceRoleBindings(input) {
- return { permissionCodes: input.permissionCodes || [], menuCodes: input.menuCodes || [] };
- },
- PlatformSaasController_upsertTenantFeatureOverride(input) {
- return { tenantId: input.tenantId, featureCode: input.featureCode, mode: input.mode, expiresAt: input.expiresAt ? new Date(input.expiresAt).toISOString() : undefined, reason: input.reason };
- },
- PlatformAdminTenantsController_create(input) {
- return {
- slug: input.slug,
- name: input.name,
- legalName: input.legalName || undefined,
- status: mapValue(dictionaries.tenantStatusToApi, input.status, input.status),
- billingStatus: mapValue(dictionaries.billingStatusToApi, input.billingStatus, input.billingStatus),
- metadata: input.metadata || {},
- ownerEmail: input.ownerEmail || undefined,
- ownerPhone: input.ownerPhone || undefined,
- ownerName: input.ownerName,
- temporaryPassword: input.temporaryPassword,
- };
- },
- PlatformAdminTenantsController_status(input) {
- return {
- tenantId: input.tenantId,
- status: mapValue(dictionaries.tenantStatusToApi, input.status, input.status),
- billingStatus: mapValue(dictionaries.billingStatusToApi, input.billingStatus, input.billingStatus),
- reason: input.reason,
- };
- },
- PlatformAdminTenantsController_billingProfile(input) {
- return {
- tenantId: input.tenantId,
- billingName: input.billingName || undefined,
- taxId: input.taxId || undefined,
- contactName: input.contactName || undefined,
- contactPhone: input.phone || input.contactPhone || undefined,
- contactEmail: input.email || input.contactEmail || undefined,
- billingAddress: input.billingAddress || undefined,
- invoiceTitle: input.invoiceTitle || undefined,
- invoiceType: ({ 增值税专用发票: 'special_vat', 增值税普通发票: 'normal_vat', 不开票: 'none' })[input.type || input.invoiceType] || input.invoiceType || 'none',
- bankName: input.bankName || undefined,
- bankAccountMasked: input.bankAccountMasked || undefined,
- };
- },
- PlatformAdminBillingController_createSubscription(input) {
- return {
- tenantId: input.tenantId,
- planCode: input.planCode,
- status: mapValue(dictionaries.subscriptionStatusToApi, input.status, input.status || 'active'),
- billingCycle: ({ 年度: 'yearly', 月度: 'monthly', 试用: 'trial' })[input.cycle] || input.billingCycle,
- amountCents: yuanToCents(input.amount),
- startsAt: isoStartOfDay(input.start || input.startsAt),
- expiresAt: isoStartOfDay(input.expires || input.expiresAt),
- metadata: { autoRenew: Boolean(input.autoRenew), source: 'static-platform-console' },
- };
- },
- PlatformAdminBillingController_createInvoice(input) {
- const bounds = invoicePeriodBounds(input.period);
- return {
- tenantId: input.tenantId,
- invoiceType: mapValue(dictionaries.invoiceTypeToApi, input.type, input.invoiceType || 'manual'),
- status: input.status || 'draft',
- dueDate: input.due || input.dueDate,
- billingPeriodStart: input.billingPeriodStart || bounds.periodStart,
- billingPeriodEnd: input.billingPeriodEnd || bounds.periodEnd,
- items: input.items || [{
- itemType: mapValue(dictionaries.invoiceTypeToApi, input.type, 'manual'),
- description: input.note || input.type || '平台手工账单',
- quantity: 1,
- unitAmountCents: yuanToCents(input.amount),
- metadata: { periodLabel: input.period || '' },
- }],
- note: input.note || undefined,
- };
- },
- PlatformAdminBillingController_fromSubscription(input) {
- return {
- tenantId: input.tenantId,
- subscriptionId: input.subscriptionId || undefined,
- status: input.status || 'issued',
- dueDate: input.dueDate || undefined,
- note: input.note || undefined,
- };
- },
- PlatformAdminBillingController_fromSubscriptionsBatch(input) {
- return {
- tenantIds: input.tenantIds || undefined,
- subscriptionIds: input.subscriptionIds || undefined,
- daysAhead: input.daysAhead ?? 45,
- status: input.status || 'issued',
- dueDate: input.dueDate || undefined,
- note: input.note || undefined,
- dryRun: Boolean(input.dryRun),
- };
- },
- PlatformAdminBillingController_fromUsage(input) {
- const bounds = input.periodStart && input.periodEnd ? input : { ...input, ...periodBounds(input.period) };
- return {
- tenantIds: bounds.tenantIds || undefined,
- periodStart: bounds.periodStart,
- periodEnd: bounds.periodEnd,
- dueDate: bounds.dueDate || undefined,
- note: bounds.note || undefined,
- status: bounds.status || 'issued',
- dryRun: Boolean(bounds.dryRun),
- };
- },
- PlatformAdminBillingController_processOverdue(input) {
- return { dryRun: Boolean(input.dryRun), channel: input.channel || 'internal', limit: Number(input.limit || 100) };
- },
- PlatformAdminBillingController_confirmPayment(input) {
- return {
- paymentId: input.paymentId || input.backendPaymentId || input.invoiceId,
- providerTradeNo: input.tradeNo || input.providerTradeNo || undefined,
- paidAt: input.paidAt ? new Date(input.paidAt).toISOString() : undefined,
- reason: input.reason || input.paymentNo || 'platform_manual_payment_confirm',
- };
- },
- PlatformAdminBillingController_recordUsage(input) {
- const bounds = input.periodStart && input.periodEnd ? input : { ...input, ...periodBounds(input.period) };
- return {
- tenantId: bounds.tenantId,
- metricKey: bounds.metricKey,
- metricValue: Number(bounds.metricValue || 0),
- periodStart: bounds.periodStart,
- periodEnd: bounds.periodEnd,
- metadata: { source: 'platform_console_manual' },
- };
- },
- PlatformAdminOverviewController_upsertStaff(input) {
- return {
- userId: input.userId || undefined,
- email: input.email || undefined,
- phone: input.phone || undefined,
- name: input.name,
- status: input.status === '已停用' ? 'disabled' : 'active',
- roleIds: input.roleIds || [],
- };
- },
- PlatformAdminOverviewController_updateStaffStatus(input) {
- return {
- userId: input.userId || input.staffId,
- status: input.status === '正常' || input.status === 'active' ? 'active' : 'disabled',
- reason: input.reason || undefined,
- };
- },
- PlatformAdminAuditController_updateAlert(input) {
- return {
- alertId: input.alertId,
- status: input.status,
- resolutionNote: input.resolutionNote || input.note || undefined,
- };
- },
- PlatformAdminCrmController_upsertConfig(input) {
- return {
- id: input.backendId || input.id || undefined,
- tenantId: input.tenantId,
- enabled: input.enabled !== false && input.status !== '未启用',
- url: input.endpoint || input.url || undefined,
- secretRef: input.secretRef || undefined,
- formName: input.formName || input.pool || undefined,
- examType: input.examType || input.subject || undefined,
- timeoutSeconds: Number(input.timeout || input.timeoutSeconds || 10),
- delaySeconds: Number(input.delaySeconds || 0),
- assignmentMode: input.assignmentMode || 'round_robin',
- assignmentPool: splitList(input.pool),
- assignmentConfig: { retry: Number(input.retry || 3), source: 'platform_console' },
- };
- },
- PlatformAdminCrmController_retryLead(input) {
- return { queueId: input.backendId || input.queueId || input.id, note: input.note || 'platform_console_retry' };
- },
- PlatformAdminSmsController_upsertChannel(input) {
- return {
- id: input.backendId || input.id || undefined,
- tenantId: input.tenantId,
- provider: input.provider || 'generic',
- name: input.name || `${input.provider || 'generic'} 短信渠道`,
- signature: input.signature || '',
- scene: input.scene || 'login',
- status: mapValue(dictionaries.providerStatusToApi, input.status, input.status || 'active'),
- secretRef: input.secretRef || undefined,
- priority: Number(input.priority || 100),
- monthlyQuota: Number(input.quota || input.monthlyQuota || 0),
- configPublic: input.configPublic || { redacted: true },
- metadata: { source: 'platform_console' },
- };
- },
- PlatformAdminSmsController_upsertTemplate(input) {
- return {
- id: input.backendId || input.id || undefined,
- tenantId: input.tenantId,
- channelId: input.channelId,
- code: input.code,
- name: input.name,
- type: input.type || 'notification',
- auditStatus: input.auditStatus || 'draft',
- status: input.status || 'active',
- providerTemplateCode: input.providerTemplateCode || undefined,
- content: input.content || '',
- remark: input.remark || undefined,
- metadata: { source: 'platform_console' },
- };
- },
- PlatformAdminPaymentSettingsController_upsertApp(input) {
- return {
- id: input.backendId || input.id || undefined,
- appCode: input.appCode || input.code || String(input.appName || '').toLowerCase().replaceAll(' ', '_'),
- appName: input.appName,
- status: mapValue(dictionaries.paymentStatusToApi, input.status, input.status || 'active'),
- settlementMode: input.settlement || input.settlementMode || 'PlatformCollect',
- description: input.description || undefined,
- metadata: { source: 'platform_console' },
- };
- },
- PlatformAdminPaymentSettingsController_upsertChannel(input) {
- return {
- id: input.backendId || input.id || undefined,
- appId: input.appId,
- provider: input.provider || 'manual',
- mode: input.mode || 'PlatformCollect',
- status: mapValue(dictionaries.paymentStatusToApi, input.status, input.status || 'active'),
- displayName: input.displayName || input.appName || input.provider || '支付渠道',
- secretRef: input.secretRef || undefined,
- callbackPath: input.callbackPath || undefined,
- priority: Number(input.priority || 100),
- configPublic: input.configPublic || { redacted: true },
- metadata: { source: 'platform_console' },
- };
- },
- PlatformAdminTenantPaymentSettingsController_upsertApp(input) {
- return {
- tenantId: input.tenantId,
- provider: input.provider || 'manual',
- status: mapValue(dictionaries.providerStatusToApi, input.status, input.status || 'active'),
- displayName: input.appName || input.displayName || undefined,
- secretRef: input.secretRef || undefined,
- priority: Number(input.priority || 100),
- configPublic: input.configPublic || { mode: input.mode || 'TenantCollect', redacted: true },
- metadata: { source: 'platform_console' },
- };
- },
- PlatformQuestionBanksController_upsertBank(input) {
- return {
- id: input.id || undefined,
- name: input.name,
- metadata: input.metadata || {},
- };
- },
- PlatformQuestionBanksController_upsertNode(input) {
- return {
- id: input.id || undefined,
- questionBankId: input.questionBankId,
- parentId: input.parentId || undefined,
- nodeKey: input.nodeKey || undefined,
- name: input.name,
- nodeType: input.nodeType,
- sortOrder: Number(input.sortOrder || 0),
- isSelectable: input.isSelectable !== false,
- metadata: input.metadata || {},
- };
- },
- PlatformQuestionBanksController_batchCreateNodes(input) {
- return {
- questionBankId: input.questionBankId,
- parentId: input.parentId || undefined,
- nodeType: input.nodeType,
- names: Array.isArray(input.names) ? input.names : splitList(input.names),
- };
- },
- PlatformQuestionBanksController_upsertQuestion(input) {
- return {
- id: input.id || undefined,
- questionBankId: input.questionBankId,
- contentNodeId: input.contentNodeId,
- legacyId: input.legacyId || undefined,
- type: input.type,
- typeLabel: input.typeLabel || undefined,
- difficulty: input.difficulty == null ? undefined : Number(input.difficulty),
- tags: input.tags || [],
- content: input.content,
- options: input.options || [],
- correctOptionIndex: input.correctOptionIndex ?? undefined,
- correctOptionIndices: input.correctOptionIndices || [],
- answerText: input.answerText || undefined,
- explanation: input.explanation || undefined,
- subQuestions: input.subQuestions || [],
- codeLang: input.codeLang || undefined,
- codeTemplate: input.codeTemplate || undefined,
- mediaUrl: input.mediaUrl || undefined,
- status: input.status || 'published',
- examMarkers: input.examMarkers || {},
- sourceHash: input.sourceHash || undefined,
- };
- },
- PlatformQuestionBanksController_archiveQuestions(input) {
- return { questionIds: input.questionIds || [] };
- },
- PlatformQuestionBanksController_previewImport(input) {
- return {
- questionBankId: input.questionBankId,
- contentNodeId: input.contentNodeId || undefined,
- format: input.format,
- sourceName: input.sourceName || undefined,
- payload: input.payload,
- };
- },
- PlatformQuestionBanksController_executeImport(input) {
- return bodyBuilders.PlatformQuestionBanksController_previewImport(input);
- },
- };
-
- function notificationBody(input) {
- const maxAttempts = Number(input.maxAttempts || input.retry || 3);
- return {
- id: input.id || undefined,
- channelCode: input.code || input.channelCode,
- name: input.name,
- enabled: input.enabled !== false,
- provider: mapValue(dictionaries.providerToApi, input.provider, input.provider || 'generic'),
- webhookUrl: input.endpoint || input.webhookUrl,
- secret: input.secret || undefined,
- secretRef: input.secretRef || undefined,
- minSeverity: mapValue(dictionaries.severityToApi, input.minSeverity, input.minSeverity || 'medium'),
- statusFilter: splitList(input.statusFilter || 'open,acknowledged'),
- timeoutSec: Number(input.timeout || input.timeoutSec || 10),
- maxAttempts,
- metadata: { ...(input.metadata || {}), maxAttempts },
- };
- }
- bodyBuilders.PlatformAdminAuditController_upsertChannel = notificationBody;
- bodyBuilders.PlatformAdminDunningChannelsController_upsertChannel = input => ({
- channelId: input.id || input.channelId || undefined,
- channelCode: input.code || input.channelCode,
- name: input.name,
- description: input.description || undefined,
- enabled: input.enabled !== false,
- provider: mapValue(dictionaries.providerToApi, input.provider, input.provider || 'generic'),
- webhookUrl: input.endpoint || input.webhookUrl,
- secretRef: input.secretRef || undefined,
- minReminderLevel: Number(input.minReminderLevel || 1),
- reminderTypes: input.reminderTypes || ['overdue', 'final_notice'],
- reminderChannels: input.reminderChannels || ['internal'],
- tenantIds: input.tenantIds || [],
- timeoutSeconds: Number(input.timeout || input.timeoutSeconds || 10),
- metadata: { ...(input.metadata || {}), secretRedacted: Boolean(input.secretRef) },
- });
-
- function buildBody(operationId, input = {}) {
- const builder = bodyBuilders[operationId];
- return builder ? builder(input) : input;
- }
-
- function jsonSummary(value) {
- if (!value) return '';
- if (typeof value === 'string') return value;
- try {
- return JSON.stringify(value);
- } catch {
- return String(value);
- }
- }
-
- function safeEndpoint(item) {
- if (!item?.webhook) return '';
- const protocol = item.webhook.protocol ? `${item.webhook.protocol}://` : '';
- return `${protocol}${item.webhook.host || ''}${item.webhook.pathname || ''}`;
- }
-
- function currentById(items, id) {
- return (items || []).find(item => item.id === id) || {};
- }
-
- function itemOf(payload) {
- return payload?.item || payload || {};
- }
-
- function itemsOf(payload, key = '') {
- if (Array.isArray(payload)) return payload;
- if (Array.isArray(payload?.items)) return payload.items;
- if (key && Array.isArray(payload?.[key])) return payload[key];
- return [];
- }
-
- function lowerEnum(value) {
- return String(value || '').replace(/([a-z0-9])([A-Z])/g, '$1_$2').toLowerCase();
- }
-
- function catalogPlans(payload) {
- const offerings = itemsOf(payload, 'offerings');
- const offeringsById = new Map(offerings.map(item => [item.id, item]));
- return itemsOf(payload, 'versions')
- .map(version => {
- const offering = offeringsById.get(version.offeringId) || {};
- return {
- ...version,
- code: offering.code || version.offeringCode,
- name: offering.name || version.offeringName,
- description: offering.description || version.description,
- status: lowerEnum(version.status),
- billingCycle: lowerEnum(version.billingCycle),
- baseAmountCents: version.amountCents ?? version.baseAmountCents,
- includedQuotas: version.limits,
- offeringType: lowerEnum(offering.type || version.offeringType),
- };
- })
- .filter(item => item.offeringType !== 'add_on' && item.status !== 'retired');
- }
-
- const adapters = {
- plan(item, current = {}) {
- const quotas = item.includedQuotas && typeof item.includedQuotas === 'object'
- ? Object.entries(item.includedQuotas).map(([key, value]) => `${key}: ${value}`)
- : current.quotas || [];
- return {
- ...current,
- code: item.code,
- name: item.name,
- description: item.description || '',
- cycle: ({ yearly: '年度', monthly: '月度' })[item.billingCycle] || item.billingCycle || '-',
- amount: centsToYuan(item.baseAmountCents),
- quotas,
- tenantCount: Number(current.tenantCount || 0),
- status: item.status,
- };
- },
- tenant(item, current = {}, planMap = {}) {
- const plan = planMap[item.planCode];
- return {
- students: 0,
- questions: 0,
- storageGB: 0,
- trafficTB: 0,
- balance: 0,
- host: '-',
- owner: '待配置',
- ownerPhone: '-',
- ...current,
- id: item.id,
- slug: item.slug,
- name: item.name,
- legal: item.legalName || current.legal || item.name,
- brand: item.brandName || current.brand || item.name,
- planCode: item.planCode || '',
- plan: plan?.name || current.plan || item.planCode || '未订阅',
- status: mapValue(dictionaries.tenantStatusFromApi, item.status, item.status || '-'),
- billing: mapValue(dictionaries.billingStatusFromApi, item.billingStatus, item.billingStatus || '-'),
- mode: item.mode === 'saas' ? '正式' : item.mode || current.mode || '-',
- expires: dateOnly(item.subscriptionExpiresAt),
- balance: centsToYuan(item.openBalanceCents),
- createdAt: dateTime(item.createdAt),
- };
- },
- subscription(item) {
- return {
- id: item.subscriptionId || item.id,
- tenantId: item.tenantId,
- planCode: item.planCode || item.baseOfferingVersionId || '',
- status: mapValue(dictionaries.subscriptionStatusFromApi, lowerEnum(item.status), item.status || '-'),
- cycle: ({ yearly: '年度', monthly: '月度', quarterly: '季度', trial: '试用' })[lowerEnum(item.billingCycle)] || item.billingCycle || '-',
- amount: centsToYuan(item.amountCents ?? item.totalAmountCents),
- start: dateOnly(item.startsAt),
- expires: dateOnly(item.expiresAt || item.currentPeriodEnd),
- autoRenew: Boolean(item.metadata?.autoRenew),
- };
- },
- invoice(item) {
- const status = lowerEnum(item.status);
- const totalCents = item.totalCents ?? item.totalAmountCents;
- const paidCents = item.paidCents ?? (status === 'paid' ? totalCents : 0);
- return {
- id: item.invoiceNo || item.id,
- backendId: item.id,
- orderId: item.orderId || '',
- tenantId: item.tenantId,
- type: mapValue(dictionaries.invoiceTypeFromApi, item.invoiceType, item.invoiceType || '-'),
- period: item.billingPeriodStart ? monthOnly(item.billingPeriodStart) : monthOnly(item.issuedAt || item.dueDate),
- total: centsToYuan(totalCents),
- paid: centsToYuan(paidCents),
- balance: centsToYuan(item.balanceCents ?? Math.max(0, Number(totalCents || 0) - Number(paidCents || 0))),
- due: dateOnly(item.dueDate),
- status: mapValue(dictionaries.invoiceStatusFromApi, status, item.status || '-'),
- note: item.note || '',
- };
- },
- billingPayment(item) {
- return {
- id: item.id,
- orderId: item.orderId,
- tenantId: item.tenantId,
- paymentNo: item.paymentNo || '',
- status: lowerEnum(item.status),
- amount: centsToYuan(item.amountCents),
- providerTradeNo: item.providerTradeNo || '',
- paidAt: item.paidAt || '',
- };
- },
- reminder(item) {
- return {
- id: item.id,
- invoiceId: item.invoiceNo || item.invoiceId,
- backendInvoiceId: item.invoiceId,
- tenantId: item.tenantId,
- level: Number(item.reminderLevel || 1),
- channel: item.channel || '-',
- status: mapValue(dictionaries.eventStatusFromApi, item.status, item.status || '-'),
- date: dateTime(item.reminderDate || item.createdAt),
- message: item.message || '',
- };
- },
- bank(item, current = {}) {
- return {
- ...current,
- id: item.id,
- name: item.name,
- contentEntryId: item.contentEntryId || '',
- catalog: '平台公共题库',
- source: '平台自建',
- nodes: Number(item.nodeCount || 0),
- questions: Number(item.questionCount || 0),
- version: item.metadata?.version || item.metadata?.contentVersion || '-',
- status: lowerEnum(item.status) === 'active' ? '正常' : lowerEnum(item.status) === 'archived' ? '已归档' : item.status || '-',
- };
- },
- staff(item) {
- const roleCodes = item.roleCodes || [];
- const permissions = roleCodes.includes('platform_super_admin') ? ['*'] : [];
- return {
- id: item.userId || item.id,
- userId: item.userId || item.id,
- name: item.name || item.email || '平台员工',
- email: item.email || '',
- phone: item.phoneMasked || item.phone || '-',
- roleCodes,
- role: permissions.includes('*') ? '超级管理员' : roleCodes.join('、') || '未分配角色',
- permissions,
- status: item.status === 'active' ? '正常' : '已停用',
- lastActive: dateTime(item.updatedAt),
- };
- },
- audit(item) {
- const details = jsonSummary(item.details);
- return {
- id: item.id,
- time: `${dateTime(item.createdAt)} CST`,
- actor: item.actorName || item.actorUsername || item.actorUserId || 'system',
- role: item.actorUserId ? '平台管理员' : '系统任务',
- action: item.action || '-',
- targetType: item.targetType || '-',
- targetId: item.targetId || '',
- target: item.tenantName || item.targetId || item.targetType || '-',
- severity: mapValue(dictionaries.severityFromApi, item.details?.severity, item.details?.severity || '中'),
- result: item.details?.result === 'failed' ? '失败' : '成功',
- ip: item.ipAddress || '-',
- details,
- };
- },
- alert(item) {
- const evidence = Array.isArray(item.details?.evidence)
- ? item.details.evidence.map(String)
- : Object.entries(item.details || {}).slice(0, 8).map(([key, value]) => `${key}: ${jsonSummary(value)}`);
- return {
- id: item.id,
- title: item.title || item.ruleName || '平台审计告警',
- summary: item.summary || item.action || '',
- severity: mapValue(dictionaries.severityFromApi, item.severity, item.severity || '-'),
- status: item.status || 'open',
- owner: item.acknowledgedByName || item.resolvedByName || item.tenantName || item.ruleName || '待认领',
- targetType: item.targetType || '-',
- targetId: item.targetId || '',
- evidence,
- updatedAt: dateTime(item.updatedAt || item.createdAt),
- note: item.resolutionNote || '',
- };
- },
- rule(item) {
- return {
- id: item.id,
- code: item.code,
- name: item.name,
- severity: mapValue(dictionaries.severityFromApi, item.severity, item.severity || '-'),
- enabled: item.enabled !== false,
- window: item.conditions?.window || item.metadata?.window || '-',
- threshold: item.conditions?.threshold || item.metadata?.threshold || '-',
- target: item.description || (item.targetTypes || []).join('、') || '-',
- };
- },
- channel(item) {
- return {
- id: item.id,
- code: item.channelCode,
- name: item.name,
- provider: mapValue(dictionaries.providerFromApi, item.provider, item.provider || 'Webhook'),
- endpoint: safeEndpoint(item),
- enabled: item.enabled !== false,
- retry: Number(item.maxAttempts || item.metadata?.maxAttempts || 3),
- minSeverity: mapValue(dictionaries.severityFromApi, item.minSeverity, item.minSeverity || '中'),
- statusFilter: (item.statusFilter || []).join(','),
- timeout: Number(item.timeoutSec || 10),
- maxAttempts: Number(item.maxAttempts || item.metadata?.maxAttempts || 3),
- lastStatus: '正常',
- secretRef: item.secretRef || '',
- endpointRedacted: true,
- reminderTypes: item.reminderTypes || [],
- reminderChannels: item.reminderChannels || [],
- minReminderLevel: Number(item.minReminderLevel || 1),
- };
- },
- event(item, type = 'audit') {
- return {
- id: item.id,
- channelId: item.channelId,
- subject: type === 'dunning'
- ? item.reminderMessage || item.invoiceNo || '催缴通知'
- : item.alertTitle || item.alertAction || '审计告警通知',
- status: mapValue(dictionaries.eventStatusFromApi, item.status, item.status || '-'),
- attempts: Number(item.attempts || 0),
- updatedAt: dateTime(item.updatedAt || item.sentAt || item.createdAt),
- error: item.lastError || '',
- };
- },
- crmConfig(item) {
- const assignmentPool = Array.isArray(item.assignmentPool) ? item.assignmentPool.join('、') : jsonSummary(item.assignmentPool);
- return {
- id: item.id,
- backendId: item.id,
- tenantId: item.tenantId,
- provider: item.url ? 'Webhook' : 'generic',
- endpoint: item.url || '',
- assignmentMode: ({ round_robin: '按地区轮转', direct: '手工分配', referrer: '来源归属', none: '不分配' })[lowerEnum(item.assignmentMode)] || item.assignmentMode || '-',
- pool: assignmentPool || item.formName || '-',
- timeout: Number(item.timeoutSeconds || 0),
- retry: Number(item.assignmentConfig?.retry || 0),
- enabled: item.enabled !== false,
- status: item.enabled === false ? '未启用' : '正常',
- secretRef: item.secretRef || '',
- formName: item.formName || '',
- examType: item.examType || '',
- };
- },
- crmLead(item) {
- return {
- id: item.id,
- backendId: item.id,
- tenantId: item.tenantId,
- student: item.payload?.student || item.leadId || item.recordId || 'CRM 线索',
- phone: item.payload?.phoneMasked || '-',
- source: item.source || '-',
- subject: item.payload?.subject || item.provider || '-',
- owner: item.payload?.owner || '-',
- attempts: Number(item.attempts || 0),
- status: mapValue(dictionaries.crmStatusFromApi, lowerEnum(item.status), item.status || '-'),
- lastError: item.lastError || '',
- };
- },
- smsChannel(item) {
- const status = mapValue(dictionaries.providerStatusFromApi, lowerEnum(item.status), item.status || '-');
- return {
- id: item.id,
- backendId: item.id,
- tenantId: item.tenantId,
- provider: item.provider || '-',
- name: item.name || item.displayName || '',
- signature: item.signature || item.name || '-',
- scene: item.scene || '-',
- secretRef: item.secretRef || '',
- quota: Number(item.monthlyQuota || 0),
- used: Number(item.sentThisMonth || 0),
- status,
- enabled: status === '正常',
- priority: Number(item.priority || 100),
- };
- },
- smsTemplate(item) {
- const sent = Number(item.sentCount || 0);
- const failed = Number(item.failedCount || 0);
- return {
- id: item.id,
- backendId: item.id,
- tenantId: item.tenantId,
- channelId: item.channelId,
- name: item.name || '-',
- code: item.code || '-',
- type: lowerEnum(item.type),
- status: mapValue(dictionaries.smsAuditStatusFromApi, lowerEnum(item.auditStatus), item.auditStatus || '-'),
- templateStatus: mapValue(dictionaries.smsTemplateStatusFromApi, lowerEnum(item.status), item.status || '-'),
- lastSend: dateTime(item.updatedAt),
- successRate: sent + failed ? `${Math.round(sent / (sent + failed) * 100)}%` : '-',
- content: item.content || '',
- };
- },
- smsLog(item) {
- return {
- id: item.id,
- tenantId: item.tenantId,
- templateId: item.templateId,
- channelId: item.channelId,
- phone: item.phoneMasked || '-',
- provider: item.provider || '-',
- updatedAt: dateTime(item.sentAt || item.createdAt),
- status: lowerEnum(item.status) === 'sent' ? '发送成功' : lowerEnum(item.status) === 'failed' ? '发送失败' : '待发送',
- };
- },
- platformPaymentApp(item) {
- const status = mapValue(dictionaries.paymentStatusFromApi, lowerEnum(item.status), item.status || '-');
- return {
- id: item.id,
- backendId: item.id,
- tenantId: '',
- appCode: item.appCode || '',
- appName: item.appName || '-',
- provider: 'platform',
- mode: '平台收款',
- settlement: item.settlementMode || 'PlatformCollect',
- secretRef: '',
- status,
- appScope: 'platform',
- };
- },
- tenantPaymentApp(item) {
- const status = mapValue(dictionaries.providerStatusFromApi, lowerEnum(item.status), item.status || '-');
- return {
- id: item.id,
- backendId: item.id,
- tenantId: item.tenantId || '',
- appName: item.displayName || item.provider || '-',
- provider: item.provider || '-',
- mode: item.configPublic?.mode || 'TenantCollect',
- settlement: '租户收款',
- secretRef: item.secretRef || '',
- status,
- appScope: 'tenant',
- };
- },
- platformPaymentEvent(item) {
- return {
- id: item.id,
- appId: item.appId || '',
- orderNo: item.providerEventId || item.eventId || item.paymentId || '-',
- amount: centsToYuan(item.payload?.amountCents || item.amountCents || 0),
- channel: item.provider || '-',
- notified: item.eventType || '-',
- updatedAt: dateTime(item.createdAt || item.processedAt),
- status: item.error ? '回调失败' : '成功',
- };
- },
- };
-
- function aggregateUsage(items) {
- const records = new Map();
- items.forEach(item => {
- const period = monthOnly(item.periodStart || item.periodEnd);
- const key = `${item.tenantId}:${period}`;
- const record = records.get(key) || {
- tenantId: item.tenantId,
- period,
- source: item.metadata?.source === 'platform_usage_worker' ? 'Worker 自动采集' : '人工补录',
- students: 0,
- questions: 0,
- storageGB: 0,
- trafficTB: 0,
- overage: [],
- estimated: 0,
- };
- const metricMap = {
- students: 'students',
- questions: 'questions',
- storage_gb: 'storageGB',
- traffic_tb: 'trafficTB',
- };
- const field = metricMap[item.metricKey || item.metricCode];
- if (field) record[field] = Number(item.metricValue ?? item.usedValue ?? 0);
- records.set(key, record);
- });
- return Array.from(records.values());
- }
-
- function currentPeriod() {
- const parts = new Intl.DateTimeFormat('en-US', {
- timeZone: 'Asia/Shanghai',
- year: 'numeric',
- month: '2-digit',
- }).formatToParts(new Date());
- const values = Object.fromEntries(parts.map(part => [part.type, part.value]));
- return `${values.year}-${values.month}`;
- }
-
- const bootstrapDescriptors = [
- ['backofficeBootstrap', 'PlatformBackofficeController_bootstrap', {}],
- ['overview', 'PlatformAdminOverviewController_overview', {}],
- ['domains', 'PlatformAdminTenantsController_domains', { query: { limit: 200 } }],
- ['plans', 'PlatformAdminOverviewController_plans', {}],
- ['tenants', 'PlatformAdminTenantsController_list', { query: { limit: 200 } }],
- ['subscriptions', 'PlatformAdminBillingController_subscriptions', { query: { limit: 200 } }],
- ['saasOrders', 'PlatformAdminBillingController_orders', { query: { limit: 200 } }],
- ['saasRefunds', 'PlatformAdminBillingController_refunds', { query: { limit: 200 } }],
- ['invoices', 'PlatformAdminBillingController_invoices', { query: { limit: 200 } }],
- ['billingPayments', 'PlatformAdminBillingController_payments', { query: { limit: 200 } }],
- ['usage', 'PlatformAdminBillingController_usage', { query: { limit: 200 } }],
- ['reminders', 'PlatformAdminBillingController_reminders', { query: { limit: 100 } }],
- ['banks', 'PlatformQuestionBanksController_getBanks', { query: { status: 'all' } }],
- ['staff', 'PlatformAdminOverviewController_staff', { query: { limit: 200 } }],
- ['dunningChannels', 'PlatformAdminDunningChannelsController_channels', { query: { limit: 100 } }],
- ['dunningEvents', 'PlatformAdminDunningEventsController_events', { query: { limit: 100 } }],
- ['auditLogs', 'PlatformAdminAuditController_logs', { query: { limit: 200 } }],
- ['alerts', 'PlatformAdminAuditController_alerts', { query: { limit: 100 } }],
- ['crmConfigs', 'PlatformAdminCrmController_configs', { query: { limit: 200 } }],
- ['crmLeads', 'PlatformAdminCrmController_leads', { query: { limit: 200 } }],
- ['crmLogs', 'PlatformAdminCrmController_logs', { query: { limit: 200 } }],
- ['smsChannels', 'PlatformAdminSmsController_channels', { query: { limit: 200 } }],
- ['smsTemplates', 'PlatformAdminSmsController_templates', { query: { limit: 200 } }],
- ['smsLogs', 'PlatformAdminSmsController_logs', { query: { limit: 200 } }],
- ['platformPaymentApps', 'PlatformAdminPaymentSettingsController_apps', { query: { limit: 200 } }],
- ['paymentChannels', 'PlatformAdminPaymentSettingsController_channels', { query: { limit: 200 } }],
- ['rebateSummary', 'PlatformAdminPaymentSettingsController_rebateSummary', {}],
- ['tenantPaymentApps', 'PlatformAdminTenantPaymentSettingsController_apps', { query: { limit: 200 } }],
- ['platformPaymentEvents', 'PlatformAdminPaymentSettingsController_events', { query: { limit: 100 } }],
- ['tenantPaymentEvents', 'PlatformAdminTenantPaymentSettingsController_events', { query: { limit: 100 } }],
- ];
-
- async function bootstrap(options = {}) {
- const descriptors = bootstrapDescriptors.map(([key, operationId, requestOptions]) => {
- const nextOptions = { ...requestOptions, query: { ...(requestOptions.query || {}) } };
- return [key, operationId, nextOptions];
- });
- const results = await Promise.allSettled(
- descriptors.map(([, operationId, requestOptions]) => request(operationId, requestOptions)),
- );
- const payloads = {};
- const errors = {};
- results.forEach((result, index) => {
- const [key] = descriptors[index];
- if (result.status === 'fulfilled') payloads[key] = result.value;
- else errors[key] = result.reason;
- });
- return { payloads, errors, requested: descriptors.length };
- }
-
- function adaptBootstrap(payloads, currentData = {}) {
- const patch = {};
- const backoffice = payloads.backofficeBootstrap || {};
- const permissionItems = Array.isArray(backoffice.permissions) ? backoffice.permissions : [];
- const roleItems = Array.isArray(backoffice.roles) ? backoffice.roles : [];
- if (permissionItems.length) {
- patch.platformPermissions = Object.fromEntries(permissionItems.map(item => [
- item.code,
- platformPermissionLabels[item.code] || item.name || item.code,
- ]));
- }
- if (roleItems.length) {
- patch.platformRoles = roleItems
- .filter(item => String(item.status || '').toLowerCase() === 'active')
- .map(item => {
- const localized = platformRoleLabels[item.code] || {};
- return { id: item.id, code: item.code, name: localized.name || item.name || item.code, description: localized.description || item.description || '', permissionCodes: item.permissionCodes || [], menuCodes: item.menuCodes || [] };
- });
- }
- if (payloads.overview) patch.apiOverview = itemOf(payloads.overview);
- if (payloads.domains) patch.domains = itemsOf(payloads.domains);
- if (payloads.plans) patch.saasCatalog = payloads.plans;
- if (payloads.permissions) patch.apiPermissions = itemOf(payloads.permissions);
- const planPayload = itemsOf(payloads.plans, 'versions').length ? catalogPlans(payloads.plans) : itemsOf(payloads.plans);
- if (planPayload.length) {
- patch.plans = planPayload.map(item => adapters.plan(item, currentById(currentData.plans, item.code)));
- }
- const planItems = patch.plans || currentData.plans || [];
- const planMap = Object.fromEntries(planItems.map(item => [item.code, item]));
- const tenants = itemsOf(payloads.tenants);
- if (tenants.length) {
- patch.tenants = tenants.map(item => adapters.tenant(item, currentById(currentData.tenants, item.id), planMap));
- }
- const staff = itemsOf(payloads.staff);
- if (staff.length) {
- const roles = patch.platformRoles || currentData.platformRoles || [];
- patch.staff = staff.map(item => {
- const adapted = adapters.staff(item);
- const assignedRoles = roles.filter(role => adapted.roleCodes.includes(role.code));
- adapted.roleIds = assignedRoles.map(role => role.id);
- adapted.role = assignedRoles.map(role => role.name).join('、') || adapted.role;
- adapted.permissions = adapted.permissions.includes('*') ? adapted.permissions : [...new Set(assignedRoles.flatMap(role => role.permissionCodes))];
- return adapted;
- });
- }
- const invoices = itemsOf(payloads.invoices);
- if (invoices.length) patch.invoices = invoices.map(adapters.invoice);
- const billingPayments = itemsOf(payloads.billingPayments);
- if (billingPayments.length) patch.billingPayments = billingPayments.map(adapters.billingPayment);
- const subscriptions = itemsOf(payloads.subscriptions);
- if (subscriptions.length) patch.subscriptions = subscriptions.map(adapters.subscription);
- if (payloads.saasOrders) patch.saasOrders = itemsOf(payloads.saasOrders);
- if (payloads.saasRefunds) patch.saasRefunds = itemsOf(payloads.saasRefunds);
- const usage = itemsOf(payloads.usage);
- if (usage.length) patch.usage = aggregateUsage(usage);
- if (Array.isArray(payloads.usageCandidates?.items) && patch.usage) {
- const usageByKey = new Map(patch.usage.map(item => [`${item.tenantId}:${item.period}`, item]));
- payloads.usageCandidates.items.forEach(candidate => {
- const record = usageByKey.get(`${candidate.tenantId}:${monthOnly(candidate.periodStart)}`);
- if (!record) return;
- record.estimated = centsToYuan(candidate.totalCents);
- record.overage = (candidate.items || []).map(item => item.description || item.itemType).filter(Boolean);
- });
- }
- const reminders = itemsOf(payloads.reminders);
- if (reminders.length) patch.reminders = reminders.map(adapters.reminder);
- const dunningChannels = itemsOf(payloads.dunningChannels);
- if (dunningChannels.length) patch.dunningChannels = dunningChannels.map(adapters.channel);
- const dunningEvents = itemsOf(payloads.dunningEvents);
- if (dunningEvents.length) patch.dunningEvents = dunningEvents.map(item => adapters.event(item, 'dunning'));
- const banks = itemsOf(payloads.banks);
- if (banks.length) {
- patch.banks = banks.map(item => adapters.bank(item, currentById(currentData.banks, item.id)));
- }
- const auditLogs = itemsOf(payloads.auditLogs);
- if (auditLogs.length) patch.auditLogs = auditLogs.map(adapters.audit);
- const alertRules = itemsOf(payloads.alertRules);
- if (alertRules.length) patch.alertRules = alertRules.map(adapters.rule);
- const alerts = itemsOf(payloads.alerts);
- if (alerts.length) patch.alerts = alerts.map(adapters.alert);
- const crmConfigs = itemsOf(payloads.crmConfigs);
- if (crmConfigs.length) patch.crmConfigs = crmConfigs.map(adapters.crmConfig);
- const crmLeads = itemsOf(payloads.crmLeads);
- if (crmLeads.length) patch.crmLeads = crmLeads.map(adapters.crmLead);
- if (payloads.crmLogs) patch.crmLogs = itemsOf(payloads.crmLogs);
- const smsChannels = itemsOf(payloads.smsChannels);
- if (smsChannels.length) patch.smsChannels = smsChannels.map(adapters.smsChannel);
- const smsTemplates = itemsOf(payloads.smsTemplates);
- if (smsTemplates.length) patch.smsTemplates = smsTemplates.map(adapters.smsTemplate);
- const smsLogs = itemsOf(payloads.smsLogs);
- if (smsLogs.length) patch.smsLogs = smsLogs.map(adapters.smsLog);
- const platformPaymentApps = itemsOf(payloads.platformPaymentApps).map(adapters.platformPaymentApp);
- const tenantPaymentApps = itemsOf(payloads.tenantPaymentApps).map(adapters.tenantPaymentApp);
- if (platformPaymentApps.length || tenantPaymentApps.length) patch.paymentApps = [...platformPaymentApps, ...tenantPaymentApps];
- if (payloads.paymentChannels) patch.paymentChannels = itemsOf(payloads.paymentChannels);
- if (payloads.rebateSummary) patch.rebateSummary = itemOf(payloads.rebateSummary);
- const paymentEvents = [
- ...itemsOf(payloads.platformPaymentEvents).map(adapters.platformPaymentEvent),
- ...itemsOf(payloads.tenantPaymentEvents).map(adapters.platformPaymentEvent),
- ];
- if (paymentEvents.length) patch.paymentEvents = paymentEvents;
- const auditChannels = itemsOf(payloads.auditChannels);
- if (auditChannels.length) patch.auditChannels = auditChannels.map(adapters.channel);
- const notificationEvents = itemsOf(payloads.notificationEvents);
- if (notificationEvents.length) {
- patch.notificationEvents = notificationEvents.map(item => adapters.event(item, 'audit'));
- }
- return patch;
- }
-
- async function tenantDetail(tenantId) {
- const payload = await request('PlatformAdminTenantsController_detail', { query: { tenantId } });
- const item = payload.item || {};
- return {
- tenant: item.tenant || null,
- domains: item.domains || [],
- subscriptions: (item.subscriptions || []).map(adapters.subscription),
- invoices: (item.invoices || []).map(adapters.invoice),
- usage: aggregateUsage(item.usage || []),
- billingProfile: item.tenant ? {
- billingName: item.tenant.billingName || '',
- taxId: item.tenant.taxId || '',
- contactName: item.tenant.contactName || '',
- phone: item.tenant.contactPhone || '',
- email: item.tenant.contactEmail || '',
- billingAddress: item.tenant.billingAddress || '',
- invoiceTitle: item.tenant.invoiceTitle || '',
- type: ({ special_vat: '增值税专用发票', normal_vat: '增值税普通发票', none: '不开票' })[item.tenant.invoiceType] || item.tenant.invoiceType || '',
- bankName: item.tenant.bankName || '',
- bankAccountMasked: item.tenant.bankAccountMasked || '',
- } : null,
- };
- }
-
- function downloadExport(payload) {
- const item = payload?.item;
- if (!item?.contentBase64) {
- throw new PlatformApiError('审计导出响应缺少文件内容', { code: 'AUDIT_EXPORT_INVALID' });
- }
- const bytes = Uint8Array.from(atob(item.contentBase64), character => character.charCodeAt(0));
- const blob = new Blob([bytes], { type: item.mimeType || 'application/octet-stream' });
- const url = URL.createObjectURL(blob);
- const anchor = document.createElement('a');
- anchor.href = url;
- anchor.download = item.filename || `platform-audit.${item.format || 'csv'}`;
- anchor.click();
- setTimeout(() => URL.revokeObjectURL(url), 1000);
- return item;
- }
-
- window.GongxuePlatformApi = Object.freeze({
- PlatformApiError,
- adapters,
- adaptBootstrap,
- bootstrap,
- buildBody,
- dictionaries,
- downloadExport,
- isEnabled,
- operationCatalog,
- periodBounds,
- publicConfig,
- request,
- tenantDetail,
- trace,
- });
-})();
diff --git a/Tiku.Api/wwwroot/platform-admin/platform-auth.js b/Tiku.Api/wwwroot/platform-admin/platform-auth.js
deleted file mode 100644
index 6697a43..0000000
--- a/Tiku.Api/wwwroot/platform-admin/platform-auth.js
+++ /dev/null
@@ -1,141 +0,0 @@
-(() => {
- const ACCESS_TOKEN_KEY = 'tiku_platform_access_token';
- const REFRESH_TOKEN_KEY = 'tiku_platform_refresh_token';
- const ACCESS_EXPIRES_KEY = 'tiku_platform_access_expires_at';
- const USER_KEY = 'tiku_platform_user';
- const runtime = window.GONGXUE_PLATFORM_RUNTIME_CONFIG || {};
- let challengeToken = '';
- let pendingResolve;
-
- function apiUrl(path) {
- return `${String(runtime.apiBaseUrl || '').replace(/\/+$/, '')}${path}`;
- }
-
- async function post(path, body) {
- const response = await fetch(apiUrl(path), {
- method: 'POST',
- headers: { Accept: 'application/json', 'Content-Type': 'application/json' },
- credentials: 'omit',
- body: JSON.stringify(body),
- });
- const text = await response.text();
- let payload = {};
- if (text) {
- try { payload = JSON.parse(text); } catch { payload = { detail: text.slice(0, 500) }; }
- }
- if (!response.ok) throw new Error(payload.detail || payload.title || payload.message || `请求失败(HTTP ${response.status})`);
- return payload;
- }
-
- function gate() { return document.querySelector('#platformAuthGate'); }
-
- function shell(title, description, content) {
- gate().innerHTML = ``;
- gate().hidden = false;
- document.querySelector('.platform-app')?.setAttribute('inert', '');
- }
-
- function showError(error) {
- const target = document.querySelector('#platformAuthError');
- if (target) target.textContent = error?.message || '操作失败,请重试';
- }
-
- function setBusy(form, busy) {
- form.querySelectorAll('button,input').forEach(control => { control.disabled = busy; });
- }
-
- function storeAuthenticated(result) {
- const user = result?.user;
- const tokens = user?.tokens;
- if (!tokens?.accessToken || !tokens?.refreshToken) throw new Error('登录响应缺少令牌');
- sessionStorage.setItem(ACCESS_TOKEN_KEY, tokens.accessToken);
- sessionStorage.setItem(REFRESH_TOKEN_KEY, tokens.refreshToken);
- sessionStorage.setItem(ACCESS_EXPIRES_KEY, tokens.accessTokenExpiresAt || '');
- sessionStorage.setItem(USER_KEY, JSON.stringify({ userId: user.userId, email: user.email, name: user.name }));
- }
-
- function completeGate() {
- gate().hidden = true;
- gate().innerHTML = '';
- document.querySelector('.platform-app')?.removeAttribute('inert');
- pendingResolve?.(true);
- pendingResolve = null;
- }
-
- function finishAuthentication(result) {
- storeAuthenticated(result);
- completeGate();
- }
-
- async function handleAuthenticationResult(result) {
- challengeToken = result.challengeToken || '';
- if (result.status === 'authenticated') { finishAuthentication(result); return; }
- if (result.status === 'password_change_required') { renderPasswordChange(); return; }
- throw new Error(`不支持的认证状态:${result.status || 'unknown'}`);
- }
-
- function renderLogin() {
- shell('平台管理员登录', '连接真实 PostgreSQL 与 ASP.NET Core API。', ``);
- document.querySelector('#platformLoginForm').addEventListener('submit', async event => {
- event.preventDefault();
- const form = event.currentTarget;
- setBusy(form, true);
- try {
- const result = await post('/api/auth/login/password', { realm: 'platform', identifier: form.elements.identifier.value.trim(), password: form.elements.password.value });
- await handleAuthenticationResult(result);
- } catch (error) { showError(error); setBusy(form, false); }
- });
- }
-
- function renderPasswordChange() {
- shell('设置正式密码', '至少 8 位,且必须同时包含字母和数字。', ``);
- document.querySelector('#platformPasswordForm').addEventListener('submit', async event => {
- event.preventDefault();
- const form = event.currentTarget;
- if (form.elements.newPassword.value !== form.elements.confirmPassword.value) { showError(new Error('两次输入的密码不一致')); return; }
- setBusy(form, true);
- try { await handleAuthenticationResult(await post('/api/auth/password/change-required', { challengeToken, newPassword: form.elements.newPassword.value })); }
- catch (error) { showError(error); setBusy(form, false); }
- });
- }
-
- function clearSession() {
- [ACCESS_TOKEN_KEY, REFRESH_TOKEN_KEY, ACCESS_EXPIRES_KEY, USER_KEY].forEach(key => sessionStorage.removeItem(key));
- }
-
- function hasSession() {
- const token = sessionStorage.getItem(ACCESS_TOKEN_KEY);
- const expiresAt = Date.parse(sessionStorage.getItem(ACCESS_EXPIRES_KEY) || '');
- return Boolean(token) && Number.isFinite(expiresAt) && expiresAt > Date.now() + 15_000;
- }
-
- async function requireSession() {
- if (hasSession()) return true;
- clearSession();
- renderLogin();
- return new Promise(resolve => { pendingResolve = resolve; });
- }
-
- function requireReauthentication() {
- clearSession();
- renderLogin();
- pendingResolve = () => location.reload();
- }
-
- async function logout() {
- const refreshToken = sessionStorage.getItem(REFRESH_TOKEN_KEY);
- try { if (refreshToken) await post('/api/auth/logout', { refreshToken }); } catch { /* Clear the browser session even when revocation cannot be reached. */ }
- clearSession();
- location.reload();
- }
-
- window.GongxuePlatformAuth = Object.freeze({
- getAccessToken: () => sessionStorage.getItem(ACCESS_TOKEN_KEY) || '',
- getUser: () => {
- try { return JSON.parse(sessionStorage.getItem(USER_KEY) || 'null'); } catch { return null; }
- },
- logout,
- requireReauthentication,
- requireSession,
- });
-})();
diff --git a/Tiku.Api/wwwroot/platform-admin/runtime-config.js b/Tiku.Api/wwwroot/platform-admin/runtime-config.js
deleted file mode 100644
index cc4d436..0000000
--- a/Tiku.Api/wwwroot/platform-admin/runtime-config.js
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * 平台端公开运行时配置。
- *
- * 默认连接同源后端。其他部署环境可在本文件之前注入同名对象,
- * 或在部署时替换本文件。不要把 access token、service role key 或任何服务端密钥
- * 写入静态文件;getAccessToken 应从当前平台登录会话中按需读取短期 JWT。
- *
- * window.GONGXUE_PLATFORM_RUNTIME_CONFIG = {
- * mode: 'api',
- * apiBaseUrl: 'https://api.example.com',
- * fallbackToMock: true,
- * timeoutMs: 10000,
- * getAccessToken: async () => {
- * return sessionStorage.getItem('tiku_platform_access_token') || '';
- * },
- * };
- */
-window.GONGXUE_PLATFORM_RUNTIME_CONFIG = window.GONGXUE_PLATFORM_RUNTIME_CONFIG || {
- mode: 'api',
- apiBaseUrl: '',
- fallbackToMock: false,
- timeoutMs: 10000,
- getAccessToken: async () => window.GongxuePlatformAuth?.getAccessToken() || '',
-};
diff --git a/Tiku.Api/wwwroot/platform-admin/spec-contract.js b/Tiku.Api/wwwroot/platform-admin/spec-contract.js
deleted file mode 100644
index b0500d3..0000000
--- a/Tiku.Api/wwwroot/platform-admin/spec-contract.js
+++ /dev/null
@@ -1,313 +0,0 @@
-(() => {
- const actions = [
- ['P-01', 'act.p-01.01', '进入租户/账务/题库/审计', 'command', 'native', 'nav', '[data-nav="tenants"],[data-nav="billing"],[data-nav="bank"],[data-nav="audit"]', 'PlatformAdminOverviewController_overview', 'allow'],
- ['P-01', 'act.p-01.02', '确认/解决告警', 'command', 'native', 'mutation', '[data-alert-detail],[data-action="transition-alert"]', 'PlatformAdminAuditController_alerts', 'allow'],
- ['P-01', 'act.p-01.03', '导出审计', 'async', 'native', 'task', '[data-action="export-audit"]', 'PlatformAdminAuditController_logs', 'allow'],
- ['P-01', 'act.p-01.04', '刷新', 'command', 'native', 'read', '[data-action="refresh"]', 'PlatformAdminOverviewController_overview', 'allow'],
- ['P-02', 'act.p-02.01', '搜索', 'command', 'native', 'read', '#tenantSearch,[data-action="apply-tenant-query"]', 'PlatformAdminTenantsController_list', 'allow'],
- ['P-02', 'act.p-02.02', '创建租户', 'command', 'native', 'mutation', '[data-action="create-tenant"],[form="createTenantForm"]', 'PlatformAdminTenantsController_create', 'block'],
- ['P-02', 'act.p-02.03', '打开详情', 'command', 'native', 'nav', '[data-tenant-detail]', 'PlatformAdminTenantsController_list', 'allow'],
- ['P-02', 'act.p-02.04', '准备暂停/恢复', 'destructive', 'native', 'mutation', '[data-action="prepare-tenant-status"],[form="tenantStatusForm"]', 'PlatformAdminTenantsController_status', 'block'],
- ['P-02', 'act.p-02.05', '去账务', 'command', 'native', 'nav', '[data-action="tenant-to-billing"]', 'PlatformAdminBillingController_invoices', 'allow'],
- ['P-03', 'act.p-03.01', '修改状态', 'command', 'native', 'mutation', '[data-action="prepare-tenant-status"],[form="tenantStatusForm"]', 'PlatformAdminTenantsController_status', 'block'],
- ['P-03', 'act.p-03.02', '编辑账务资料', 'command', 'native', 'nav', '[data-action="edit-billing-profile"]', 'PlatformAdminTenantsController_billingProfile', 'block'],
- ['P-03', 'act.p-03.03', '创建订阅', 'command', 'native', 'mutation', '[data-action="create-subscription-for-tenant"],[form="subscriptionForm"]', 'PlatformAdminBillingController_createSubscription', 'block'],
- ['P-03', 'act.p-03.04', '查看账单/用量', 'command', 'native', 'nav', '[data-action="tenant-to-billing"],[data-action="tenant-to-usage"]', 'PlatformAdminTenantsController_detail', 'allow'],
- ['P-03', 'act.p-03.05', '打开租户门户入口', 'command', 'native', 'nav', '[data-action="open-tenant-portal"]', 'PlatformAdminTenantsController_detail', 'allow'],
- ['P-04', 'act.p-04.01', '编辑', 'command', 'native', 'mutation', '#billingProfileForm', 'PlatformAdminTenantsController_billingProfile', 'block'],
- ['P-04', 'act.p-04.02', '保存', 'command', 'native', 'mutation', '[form="billingProfileForm"]', 'PlatformAdminTenantsController_billingProfile', 'block'],
- ['P-04', 'act.p-04.03', '查看关联账单', 'command', 'native', 'nav', '[data-action="billing-profile-to-invoices"]', 'PlatformAdminTenantsController_billingProfile', 'allow'],
- ['P-05', 'act.p-05.01', '选择套餐', 'command', 'native', 'mutation', '[data-action="select-plan"]', 'PlatformAdminOverviewController_plans', 'block'],
- ['P-05', 'act.p-05.02', '创建订阅', 'command', 'native', 'mutation', '[data-action="create-subscription"],[form="subscriptionForm"]', 'PlatformAdminBillingController_createSubscription', 'block'],
- ['P-05', 'act.p-05.03', '进入账单候选', 'command', 'native', 'nav', '[data-action="subscription-to-billing"]', 'PlatformAdminBillingController_createSubscription', 'allow'],
- ['P-05', 'act.p-05.04', '查看租户详情', 'command', 'native', 'nav', '[data-tenant-detail]', 'PlatformAdminBillingController_createSubscription', 'allow'],
- ['P-06', 'act.p-06.01', '查询', 'command', 'contract', 'read', '[data-action="apply-invoice-query"]', 'PlatformAdminBillingController_invoices', 'allow'],
- ['P-06', 'act.p-06.02', '手工创建', 'command', 'native', 'mutation', '[data-action="create-invoice"],[form="invoiceForm"]', 'PlatformAdminBillingController_createInvoice', 'block'],
- ['P-06', 'act.p-06.03', '预览候选', 'command', 'native', 'read', '[data-action="preview-invoice-candidates"]', 'PlatformAdminBillingController_subscriptionCandidates', 'block'],
- ['P-06', 'act.p-06.04', '单个生成', 'async', 'contract', 'task', '[data-action="generate-subscription-invoice"]', 'PlatformAdminBillingController_fromSubscription', 'block'],
- ['P-06', 'act.p-06.05', '批量 dry-run', 'command', 'native', 'read', '[data-action="run-invoice-dry-run"]', 'PlatformAdminBillingController_fromSubscriptionsBatch', 'block'],
- ['P-06', 'act.p-06.06', '确认生成', 'async', 'native', 'task', '[data-action="confirm-generate-candidates"]', 'PlatformAdminBillingController_fromSubscriptionsBatch', 'block'],
- ['P-06', 'act.p-06.07', '打开租户', 'command', 'native', 'nav', '[data-tenant-detail]', 'PlatformAdminBillingController_invoices', 'allow'],
- ['P-07', 'act.p-07.01', '记录用量', 'command', 'native', 'mutation', '[data-action="record-usage"],[form="usageForm"]', 'PlatformAdminBillingController_recordUsage', 'block'],
- ['P-07', 'act.p-07.02', '查询', 'command', 'native', 'read', '#usagePeriodFilter', 'PlatformAdminBillingController_usage', 'allow'],
- ['P-07', 'act.p-07.03', '预览超额候选', 'command', 'native', 'read', '[data-action="preview-overage"]', 'PlatformAdminBillingController_usageCandidates', 'block'],
- ['P-07', 'act.p-07.04', 'dry-run', 'command', 'native', 'read', '[data-action="run-overage-dry-run"]', 'PlatformAdminBillingController_fromUsage', 'block'],
- ['P-07', 'act.p-07.05', '生成超额账单', 'async', 'native', 'task', '[data-action="confirm-overage-invoices"]', 'PlatformAdminBillingController_fromUsage', 'block'],
- ['P-07', 'act.p-07.06', '跳租户详情', 'command', 'native', 'nav', '[data-tenant-detail]', 'PlatformAdminBillingController_usage', 'allow'],
- ['P-08', 'act.p-08.01', '确认收款', 'command', 'native', 'mutation', '[data-action="confirm-payment"],[form="paymentForm"]', 'PlatformAdminBillingController_confirmPayment', 'block'],
- ['P-08', 'act.p-08.02', '预览逾期', 'command', 'native', 'read', '[data-action="preview-overdue"]', 'PlatformAdminBillingController_processOverdue', 'block'],
- ['P-08', 'act.p-08.03', '生成催缴', 'async', 'native', 'task', '[data-action="confirm-overdue-process"],[data-action="generate-reminder"]', 'PlatformAdminBillingController_processOverdue', 'block'],
- ['P-08', 'act.p-08.04', '查询提醒', 'command', 'native', 'read', '[data-billing-tab="reminders"]', 'PlatformAdminBillingController_reminders', 'allow'],
- ['P-08', 'act.p-08.05', '新增/编辑/启停渠道', 'command', 'native', 'mutation', '[data-action="new-dunning-channel"],[data-action="edit-dunning-channel"],[data-action="toggle-dunning-channel"]', 'PlatformAdminDunningChannelsController_upsertChannel', 'block'],
- ['P-08', 'act.p-08.06', '查看通知事件', 'command', 'contract', 'read', '[data-notification-detail]', 'PlatformAdminDunningEventsController_events', 'allow'],
- ['P-09', 'act.p-09.01', '查询与选择题库', 'command', 'native', 'read', '[data-action="apply-bank-search"],[data-bank-select]', 'PlatformQuestionBanksController_getBanks', 'allow'],
- ['P-09', 'act.p-09.02', '维护题库与内容结构', 'command', 'native', 'mutation', '[data-action="new-bank"],[data-action="edit-bank"],[data-action="new-bank-node"],[data-action="batch-bank-nodes"]', 'PlatformQuestionBanksController_upsertNode', 'block'],
- ['P-09', 'act.p-09.03', '单题录入与题目管理', 'command', 'native', 'mutation', '#bankQuestionForm,[data-action="edit-bank-question"],[data-action="archive-bank-question"]', 'PlatformQuestionBanksController_upsertQuestion', 'block'],
- ['P-09', 'act.p-09.04', '普通题目批量导入', 'async', 'native', 'task', '#bankBatchImportForm', 'PlatformQuestionBanksController_executeImport', 'block'],
- ['P-09', 'act.p-09.05', '结构化题库文件导入', 'async', 'native', 'task', '#bankStructuredImportForm', 'PlatformQuestionBanksController_executeImport', 'block'],
- ['P-10', 'act.p-10.01', '切换 CRM 视图', 'command', 'native', 'read', '[data-crm-tab]', 'PlatformAdminCrmController_configs', 'allow'],
- ['P-10', 'act.p-10.02', '新建/编辑 CRM 接入', 'command', 'native', 'mutation', '[data-action="new-crm-config"],[data-action="edit-crm-config"]', 'PlatformAdminCrmController_upsertConfig', 'block'],
- ['P-10', 'act.p-10.03', '启停 CRM 接入', 'destructive', 'native', 'mutation', '[data-action="toggle-crm-config"]', 'PlatformAdminCrmController_upsertConfig', 'block'],
- ['P-10', 'act.p-10.04', '重试线索推送', 'command', 'native', 'mutation', '[data-action="retry-crm-lead"]', 'PlatformAdminCrmController_retryLead', 'block'],
- ['P-11', 'act.p-11.01', '切换短信视图', 'command', 'native', 'read', '[data-sms-tab]', 'PlatformAdminSmsController_channels', 'allow'],
- ['P-11', 'act.p-11.02', '新建/编辑短信渠道', 'command', 'native', 'mutation', '[data-action="new-sms-channel"],[data-action="edit-sms-channel"]', 'PlatformAdminSmsController_upsertChannel', 'block'],
- ['P-11', 'act.p-11.03', '启停短信渠道', 'destructive', 'native', 'mutation', '[data-action="toggle-sms-channel"]', 'PlatformAdminSmsController_upsertChannel', 'block'],
- ['P-12', 'act.p-12.01', '切换支付设置视图', 'command', 'native', 'read', '[data-payment-tab]', 'PlatformAdminPaymentSettingsController_apps', 'allow'],
- ['P-12', 'act.p-12.02', '新建/编辑支付应用', 'command', 'native', 'mutation', '[data-action="new-payment-app"],[data-action="edit-payment-app"]', 'PlatformAdminPaymentSettingsController_upsertApp', 'block'],
- ['P-12', 'act.p-12.03', '启停支付应用', 'destructive', 'native', 'mutation', '[data-action="toggle-payment-app"]', 'PlatformAdminPaymentSettingsController_upsertApp', 'block'],
- ['P-12', 'act.p-12.04', '查看风控规则', 'command', 'native', 'read', '[data-action="payment-rule-detail"]', 'PlatformAdminPaymentSettingsController_events', 'allow'],
- ['P-13', 'act.p-13.01', '新建/编辑', 'command', 'native', 'mutation', '[data-action="new-staff"],[data-action="edit-staff"]', 'PlatformAdminOverviewController_upsertStaff', 'block'],
- ['P-13', 'act.p-13.02', '全选/分组授权', 'command', 'native', 'mutation', '[data-action="select-permission-group"]', 'PlatformAdminOverviewController_permissions', 'block'],
- ['P-13', 'act.p-13.03', '启用/禁用', 'destructive', 'native', 'mutation', '[data-action="toggle-staff"]', 'PlatformAdminOverviewController_updateStaffStatus', 'block'],
- ['P-13', 'act.p-13.04', '禁用时撤销会话', 'destructive', 'native', 'audit', '[data-action="execute-staff-disable"]', 'PlatformAdminOverviewController_updateStaffStatus', 'block'],
- ['P-13', 'act.p-13.05', '清空表单', 'command', 'contract', 'mutation', '[data-action="clear-staff-form"]', 'PlatformAdminOverviewController_upsertStaff', 'block'],
- ['P-14', 'act.p-14.01', '筛选', 'command', 'native', 'read', '#auditSearch,#auditRangeFilter,[data-audit-severity]', 'PlatformAdminAuditController_logs', 'allow'],
- ['P-14', 'act.p-14.02', '查看详情', 'command', 'native', 'read', '[data-audit-detail]', 'PlatformAdminAuditController_logs', 'allow'],
- ['P-14', 'act.p-14.03', '导出 CSV/JSON', 'async', 'native', 'task', '[data-action="export-audit"]', 'PlatformAdminAuditController_exportLogs', 'allow'],
- ['P-14', 'act.p-14.04', '复制 ID', 'command', 'native', 'read', '[data-copy]', 'PlatformAdminAuditController_logs', 'allow'],
- ['P-14', 'act.p-14.05', '跳目标对象', 'command', 'native', 'nav', '[data-action="jump-audit-target"],[data-action="jump-related-alert"]', 'PlatformAdminAuditController_logs', 'allow'],
- ['P-15', 'act.p-15.01', '确认/解决告警', 'command', 'native', 'mutation', '[data-action="transition-alert"]', 'PlatformAdminAuditController_updateAlert', 'allow'],
- ['P-15', 'act.p-15.02', '查看证据', 'command', 'native', 'read', '[data-alert-detail]', 'PlatformAdminAuditController_alerts', 'allow'],
- ['P-15', 'act.p-15.03', '新建/编辑/启停通知渠道', 'command', 'native', 'mutation', '[data-action="new-audit-channel"],[data-action="edit-audit-channel"],[data-action="toggle-audit-channel"]', 'PlatformAdminAuditController_upsertChannel', 'block'],
- ['P-15', 'act.p-15.04', '查看失败事件', 'command', 'contract', 'read', '[data-notification-detail]', 'PlatformAdminAuditController_events', 'allow'],
- ].map(([pageId, id, label, kind, mode, effect, selector, operationId, mobile]) => ({ pageId, id, label, kind, mode, effect, selector, operationIds: [operationId], mobile, destructive: kind === 'destructive', implemented: true }));
-
- const operationRows = [
- ['P-13', 'PlatformBackofficeController_bootstrap', 'GET', '/api/backoffice/platform/bootstrap'],
- ['P-01', 'PlatformAdminOverviewController_overview', 'GET', '/api/platform-admin/overview'],
- ['P-01', 'PlatformAdminAuditController_alerts', 'GET', '/api/platform-admin/audit-alerts'],
- ['P-01', 'PlatformAdminAuditController_logs', 'GET', '/api/platform-admin/audit-logs'],
- ['P-02', 'PlatformAdminTenantsController_list', 'GET', '/api/platform-admin/tenants'],
- ['P-02', 'PlatformAdminTenantsController_create', 'POST', '/api/platform-admin/tenants'],
- ['P-02A', 'PlatformAdminTenantsController_domains', 'GET', '/api/platform-admin/domains'],
- ['P-02A', 'PlatformAdminTenantsController_recheckDomain', 'POST', '/api/platform-admin/domains/{domainId}/recheck'],
- ['P-03', 'PlatformAdminTenantsController_detail', 'GET', '/api/platform-admin/tenants/detail'],
- ['P-03', 'PlatformAdminTenantsController_status', 'PATCH', '/api/platform-admin/tenants/status'],
- ['P-03', 'PlatformAdminTenantsController_billingProfile', 'PUT', '/api/platform-admin/tenants/billing-profile'],
- ['P-03', 'PlatformAdminBillingController_createSubscription', 'POST', '/api/platform-admin/saas/subscriptions'],
- ['P-04', 'PlatformAdminTenantsController_billingProfile', 'PUT', '/api/platform-admin/tenants/billing-profile'],
- ['P-05', 'PlatformAdminOverviewController_plans', 'GET', '/api/platform-admin/saas/catalog'],
- ['P-05A', 'PlatformSaasController_upsertFeature', 'PUT', '/api/platform-admin/saas/features'],
- ['P-05A', 'PlatformSaasController_upsertFeatureLimit', 'PUT', '/api/platform-admin/saas/feature-limits'],
- ['P-05A', 'PlatformSaasController_upsertOffering', 'PUT', '/api/platform-admin/saas/offerings'],
- ['P-05A', 'PlatformSaasController_upsertVersion', 'PUT', '/api/platform-admin/saas/offering-versions'],
- ['P-05A', 'PlatformSaasController_publishVersion', 'POST', '/api/platform-admin/saas/offering-versions/{versionId}/publish'],
- ['P-05A', 'PlatformSaasController_cloneVersion', 'POST', '/api/platform-admin/saas/offering-versions/{versionId}/clone'],
- ['P-05A', 'PlatformSaasController_retireVersion', 'POST', '/api/platform-admin/saas/offering-versions/{versionId}/retire'],
- ['P-05B', 'PlatformAdminBillingController_orders', 'GET', '/api/platform-admin/saas/orders'],
- ['P-05B', 'PlatformAdminBillingController_refunds', 'GET', '/api/platform-admin/saas/refunds'],
- ['P-05A', 'PlatformSaasController_upsertTenantFeatureOverride', 'PUT', '/api/platform-admin/saas/tenant-feature-overrides'],
- ['P-05', 'PlatformAdminBillingController_subscriptions', 'GET', '/api/platform-admin/saas/subscriptions'],
- ['P-05', 'PlatformAdminBillingController_createSubscription', 'POST', '/api/platform-admin/saas/subscriptions'],
- ['P-06', 'PlatformAdminBillingController_invoices', 'GET', '/api/platform-admin/saas/invoices'],
- ['P-06', 'PlatformAdminBillingController_createInvoice', 'POST', '/api/platform-admin/saas/invoices'],
- ['P-06', 'PlatformAdminBillingController_subscriptionCandidates', 'GET', '/api/platform-admin/saas/invoices/subscription-candidates'],
- ['P-06', 'PlatformAdminBillingController_fromSubscription', 'POST', '/api/platform-admin/saas/invoices/from-subscription'],
- ['P-06', 'PlatformAdminBillingController_fromSubscriptionsBatch', 'POST', '/api/platform-admin/saas/invoices/from-subscriptions-batch'],
- ['P-07', 'PlatformAdminBillingController_usage', 'GET', '/api/platform-admin/saas/usage'],
- ['P-07', 'PlatformAdminBillingController_recordUsage', 'POST', '/api/platform-admin/saas/usage'],
- ['P-07', 'PlatformAdminBillingController_usageCandidates', 'GET', '/api/platform-admin/saas/invoices/usage-overage-candidates'],
- ['P-07', 'PlatformAdminBillingController_fromUsage', 'POST', '/api/platform-admin/saas/invoices/from-usage-overage'],
- ['P-08', 'PlatformAdminBillingController_confirmPayment', 'POST', '/api/platform-admin/saas/payments/manual/confirm'],
- ['P-08', 'PlatformAdminBillingController_payments', 'GET', '/api/platform-admin/saas/payments'],
- ['P-08', 'PlatformAdminBillingController_processOverdue', 'POST', '/api/platform-admin/saas/invoices/process-overdue'],
- ['P-08', 'PlatformAdminBillingController_reminders', 'GET', '/api/platform-admin/saas/invoices/reminders'],
- ['P-08', 'PlatformAdminDunningChannelsController_channels', 'GET', '/api/platform-admin/saas/dunning/channels'],
- ['P-08', 'PlatformAdminDunningChannelsController_upsertChannel', 'PUT', '/api/platform-admin/saas/dunning/channels'],
- ['P-08', 'PlatformAdminDunningChannelsController_disableChannel', 'POST', '/api/platform-admin/saas/dunning/channels/disable'],
- ['P-08', 'PlatformAdminDunningEventsController_events', 'GET', '/api/platform-admin/saas/dunning/events'],
- ['P-08', 'PlatformAdminDunningEventsController_eventDetail', 'GET', '/api/platform-admin/saas/dunning/events/detail'],
- ['P-08', 'PlatformAdminDunningEventsController_retryEvent', 'POST', '/api/platform-admin/saas/dunning/events/retry'],
- ['P-09', 'PlatformQuestionBanksController_getBanks', 'GET', '/api/platform-admin/question-banks'],
- ['P-09', 'PlatformQuestionBanksController_upsertBank', 'PUT', '/api/platform-admin/question-banks'],
- ['P-09', 'PlatformQuestionBanksController_archiveBank', 'POST', '/api/platform-admin/question-banks/{bankId}/archive'],
- ['P-09', 'PlatformQuestionBanksController_getNodes', 'GET', '/api/platform-admin/question-banks/{bankId}/nodes'],
- ['P-09', 'PlatformQuestionBanksController_upsertNode', 'PUT', '/api/platform-admin/question-banks/nodes'],
- ['P-09', 'PlatformQuestionBanksController_batchCreateNodes', 'POST', '/api/platform-admin/question-banks/nodes/batch'],
- ['P-09', 'PlatformQuestionBanksController_archiveNode', 'POST', '/api/platform-admin/question-banks/nodes/{nodeId}/archive'],
- ['P-09', 'PlatformQuestionBanksController_getQuestions', 'GET', '/api/platform-admin/question-banks/questions'],
- ['P-09', 'PlatformQuestionBanksController_upsertQuestion', 'PUT', '/api/platform-admin/question-banks/questions'],
- ['P-09', 'PlatformQuestionBanksController_archiveQuestions', 'POST', '/api/platform-admin/question-banks/questions/archive'],
- ['P-09', 'PlatformQuestionBanksController_previewImport', 'POST', '/api/platform-admin/question-banks/imports/preview'],
- ['P-09', 'PlatformQuestionBanksController_executeImport', 'POST', '/api/platform-admin/question-banks/imports'],
- ['P-09', 'PlatformQuestionBanksController_getImport', 'GET', '/api/platform-admin/question-banks/imports/{jobId}'],
- ['P-09', 'PlatformQuestionBanksController_signAssetUpload', 'POST', '/api/platform-admin/question-banks/assets/upload-sign'],
- ['P-09', 'PlatformQuestionBanksController_confirmAssetUpload', 'POST', '/api/platform-admin/question-banks/assets/upload-confirm'],
- ['P-10', 'PlatformAdminCrmController_configs', 'GET', '/api/platform-admin/tenant-capabilities/crm/configs'],
- ['P-10', 'PlatformAdminCrmController_upsertConfig', 'PUT', '/api/platform-admin/tenant-capabilities/crm/configs'],
- ['P-10', 'PlatformAdminCrmController_leads', 'GET', '/api/platform-admin/tenant-capabilities/crm/leads'],
- ['P-10', 'PlatformAdminCrmController_retryLead', 'POST', '/api/platform-admin/tenant-capabilities/crm/leads/retry'],
- ['P-10', 'PlatformAdminCrmController_logs', 'GET', '/api/platform-admin/tenant-capabilities/crm/logs'],
- ['P-11', 'PlatformAdminSmsController_channels', 'GET', '/api/platform-admin/tenant-capabilities/sms/channels'],
- ['P-11', 'PlatformAdminSmsController_disableChannel', 'POST', '/api/platform-admin/tenant-capabilities/sms/channels/{channelId}/disable'],
- ['P-11', 'PlatformAdminSmsController_templates', 'GET', '/api/platform-admin/tenant-capabilities/sms/templates'],
- ['P-11', 'PlatformAdminSmsController_submitTemplateReview', 'POST', '/api/platform-admin/tenant-capabilities/sms/templates/{templateId}/submit-review'],
- ['P-11', 'PlatformAdminSmsController_disableTemplate', 'POST', '/api/platform-admin/tenant-capabilities/sms/templates/{templateId}/disable'],
- ['P-11', 'PlatformAdminSmsController_logs', 'GET', '/api/platform-admin/tenant-capabilities/sms/logs'],
- ['P-11', 'PlatformAdminSmsController_upsertChannel', 'PUT', '/api/platform-admin/tenant-capabilities/sms/channels'],
- ['P-11', 'PlatformAdminSmsController_upsertTemplate', 'PUT', '/api/platform-admin/tenant-capabilities/sms/templates'],
- ['P-12', 'PlatformAdminPaymentSettingsController_apps', 'GET', '/api/platform-admin/payment-settings/apps'],
- ['P-12', 'PlatformAdminPaymentSettingsController_channels', 'GET', '/api/platform-admin/payment-settings/channels'],
- ['P-12', 'PlatformAdminPaymentSettingsController_upsertChannel', 'PUT', '/api/platform-admin/payment-settings/channels'],
- ['P-12', 'PlatformAdminPaymentSettingsController_disableChannel', 'POST', '/api/platform-admin/payment-settings/channels/{channelId}/disable'],
- ['P-12', 'PlatformAdminPaymentSettingsController_rebateSummary', 'GET', '/api/platform-admin/payment-settings/rebates/summary'],
- ['P-12', 'PlatformAdminPaymentSettingsController_events', 'GET', '/api/platform-admin/payment-settings/events'],
- ['P-12', 'PlatformAdminPaymentSettingsController_rebates', 'GET', '/api/platform-admin/payment-settings/rebates/summary'],
- ['P-12', 'PlatformAdminPaymentSettingsController_upsertApp', 'PUT', '/api/platform-admin/payment-settings/apps'],
- ['P-12', 'PlatformAdminTenantPaymentSettingsController_apps', 'GET', '/api/platform-admin/tenant-capabilities/payments/apps'],
- ['P-12', 'PlatformAdminTenantPaymentSettingsController_events', 'GET', '/api/platform-admin/tenant-capabilities/payments/events'],
- ['P-12', 'PlatformAdminTenantPaymentSettingsController_upsertApp', 'PUT', '/api/platform-admin/tenant-capabilities/payments/apps'],
- ['P-13', 'PlatformAdminOverviewController_permissions', 'GET', '/api/platform-admin/permissions'],
- ['P-13', 'PlatformAdminOverviewController_staff', 'GET', '/api/platform-admin/staff'],
- ['P-13', 'PlatformAdminOverviewController_upsertStaff', 'PUT', '/api/platform-admin/staff'],
- ['P-13', 'PlatformAdminOverviewController_updateStaffStatus', 'PATCH', '/api/platform-admin/staff/status'],
- ['P-13A', 'PlatformBackofficeController_upsertRole', 'POST', '/api/backoffice/platform/roles'],
- ['P-13A', 'PlatformBackofficeController_replaceRoleBindings', 'PUT', '/api/backoffice/platform/roles/{roleId}/bindings'],
- ['P-14', 'PlatformAdminAuditController_logs', 'GET', '/api/platform-admin/audit-logs'],
- ['P-14', 'PlatformAdminAuditController_exportLogs', 'GET', '/api/platform-admin/audit-logs/export'],
- ['P-15', 'PlatformAdminAuditController_rules', 'GET', '/api/platform-admin/audit-alert-rules'],
- ['P-15', 'PlatformAdminAuditController_alerts', 'GET', '/api/platform-admin/audit-alerts'],
- ['P-15', 'PlatformAdminAuditController_updateAlert', 'POST', '/api/platform-admin/audit-alerts/status'],
- ['P-15', 'PlatformAdminAuditController_channels', 'GET', '/api/platform-admin/audit-notification-channels'],
- ['P-15', 'PlatformAdminAuditController_upsertChannel', 'PUT', '/api/platform-admin/audit-notification-channels'],
- ['P-15', 'PlatformAdminAuditController_events', 'GET', '/api/platform-admin/audit-notification-events'],
- ];
- const operations = operationRows.map(([pageId, operationId, method, path]) => ({ pageId, operationId, method, path }));
- const operationById = Object.fromEntries(operations.map(operation => [operation.operationId, operation]));
-
- const navEdges = [
- ['nav.p-01.p-02', 'P-01', 'P-02', '[data-nav="tenants"]'],
- ['nav.p-01.p-06', 'P-01', 'P-06', '[data-nav="billing"]'],
- ['nav.p-01.p-10', 'P-01', 'P-10', '[data-nav="crm"]'],
- ['nav.p-01.p-11', 'P-01', 'P-11', '[data-nav="sms"]'],
- ['nav.p-01.p-12', 'P-01', 'P-12', '[data-nav="paymentSettings"]'],
- ['nav.p-01.p-15', 'P-01', 'P-15', '[data-nav="alerts"],[data-alert-detail]'],
- ['nav.p-02.p-03', 'P-02', 'P-03', '[data-tenant-detail]'],
- ['nav.p-03.p-04', 'P-03', 'P-04', '[data-action="edit-billing-profile"]'],
- ['nav.p-03.p-05', 'P-03', 'P-05', '[data-action="create-subscription-for-tenant"]'],
- ['nav.p-03.p-06', 'P-03', 'P-06', '[data-action="tenant-to-billing"]'],
- ['nav.p-05.p-06', 'P-05', 'P-06', '[data-action="subscription-to-billing"]'],
- ['nav.p-05.p-07', 'P-05', 'P-07', '[data-action="subscriptions-to-usage"]'],
- ['nav.p-06.p-08', 'P-06', 'P-08', '[data-nav="dunning"]'],
- ['nav.p-14.p-15', 'P-14', 'P-15', '[data-action="jump-related-alert"]'],
- ].map(([id, fromPageId, toPageId, selector]) => ({ id, fromPageId, toPageId, selector, implemented: true }));
-
- const supportingReads = [];
-
- const trace = [];
- const decoratedActionIds = new Set();
- const selectorCollisions = new Set();
- const explicitResultActionIds = new Set(['act.p-06.01', 'act.p-06.04', 'act.p-09.01', 'act.p-09.05']);
- function pushTrace(entry) {
- trace.push({ at: new Date().toISOString(), ...entry });
- if (trace.length > 120) trace.splice(0, trace.length - 120);
- document.documentElement.dataset.platformContractEvents = String(trace.length);
- }
-
- function decorate(root = document, pageId = '') {
- const shell = root.querySelector?.('.page-shell');
- if (shell && pageId) {
- const pageOperations = operations.filter(operation => operation.pageId === pageId);
- shell.dataset.specPageId = pageId;
- shell.dataset.operationIds = pageOperations.map(operation => operation.operationId).join(' ');
- shell.dataset.operationContracts = pageOperations.map(operation => `${operation.method} ${operation.path}`).join(' | ');
- }
- actions.filter(action => action.pageId === pageId).forEach(action => {
- root.querySelectorAll?.(action.selector).forEach(element => {
- const existingActionId = element.dataset.specActionId;
- if (existingActionId && existingActionId !== action.id) selectorCollisions.add(`${existingActionId} -> ${action.id}`);
- element.dataset.specActionId = action.id;
- element.dataset.specActionMode = action.mode;
- element.dataset.specEffect = action.effect;
- element.dataset.mobileBoundary = action.mobile;
- const operation = operationById[action.operationIds[0]];
- if (operation) {
- element.dataset.operationId = operation.operationId;
- element.dataset.operationMethod = operation.method;
- element.dataset.operationPath = operation.path;
- }
- decoratedActionIds.add(action.id);
- });
- });
- supportingReads.filter(read => read.pageId === pageId).forEach(read => {
- const operation = operationById[read.operationId];
- root.querySelectorAll?.(read.selector).forEach(element => {
- element.dataset.specSupportingRead = 'true';
- element.dataset.specEffect = 'read';
- if (operation) {
- element.dataset.operationId = operation.operationId;
- element.dataset.operationMethod = operation.method;
- element.dataset.operationPath = operation.path;
- }
- });
- });
- navEdges.filter(edge => edge.fromPageId === pageId).forEach(edge => {
- root.querySelectorAll?.(edge.selector).forEach(element => {
- element.dataset.navEdgeId = edge.id;
- element.dataset.navTargetPage = edge.toPageId;
- });
- });
- window.__PLATFORM_SPEC_COVERAGE__ = coverage();
- }
-
- function eventContract(target) {
- const element = target?.closest?.('[data-spec-action-id]');
- if (!element) return null;
- return { element, actionId: element.dataset.specActionId, operationId: element.dataset.operationId || '', requestId: `req_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 7)}` };
- }
-
- document.addEventListener('click', event => {
- const contract = eventContract(event.target);
- if (!contract) return;
- contract.element.dataset.contractRequestId = contract.requestId;
- pushTrace({ phase: 'before', actionId: contract.actionId, operationId: contract.operationId, requestId: contract.requestId });
- setTimeout(() => pushTrace({ phase: 'after', actionId: contract.actionId, operationId: contract.operationId, requestId: contract.requestId, result: 'handled', pageId: document.querySelector('.page-shell')?.dataset.specPageId || '' }), 0);
- }, true);
-
- document.addEventListener('change', event => {
- const contract = eventContract(event.target);
- if (!contract) return;
- pushTrace({ phase: 'after', actionId: contract.actionId, operationId: contract.operationId, requestId: contract.requestId, result: 'changed' });
- }, true);
-
- const coverage = () => ({
- expected: 70,
- total: actions.length,
- unique: new Set(actions.map(action => action.id)).size,
- catalogued: actions.filter(action => action.label && action.kind).length,
- selectorDeclared: actions.filter(action => action.selector).length,
- nativeMetadata: actions.filter(action => action.mode === 'native').length,
- contractMetadata: actions.filter(action => action.mode === 'contract').length,
- nativeMapped: actions.filter(action => action.mode === 'native' && decoratedActionIds.has(action.id)).length,
- dedicatedExecutor: explicitResultActionIds.size,
- dedicatedExecutorDefinition: 'actions with explicit success/failure result recording',
- reachable: actions.filter(action => action.implemented && action.selector).length,
- mountedThisSession: decoratedActionIds.size,
- decoratedInSession: decoratedActionIds.size,
- notYetDecorated: actions.filter(action => !decoratedActionIds.has(action.id)).map(action => action.id),
- implemented: actions.filter(action => action.implemented && action.selector).length,
- unimplemented: actions.filter(action => !action.implemented || !action.selector).map(action => action.id),
- selectorCollisions: Array.from(selectorCollisions),
- apiExact: operations.filter(operation => operation.operationId && operation.method && operation.path).length,
- uiOnlyExplained: actions.filter(action => action.operationIds.length === 0).length,
- effectDeclared: actions.filter(action => action.effect).length,
- mobileDeclared: actions.filter(action => action.mobile).length,
- actuallyExecuted: new Set(trace.filter(entry => entry.phase === 'result' && entry.result === 'success').map(entry => entry.actionId)).size,
- executionNote: 'catalogue and selector metadata are not counted as successful business execution',
- navigation: { expected: 14, total: navEdges.length, unique: new Set(navEdges.map(edge => edge.id)).size },
- pageBindings: { expected: 63, total: operations.length, unique: new Set(operations.map(operation => `${operation.pageId}:${operation.operationId}`)).size },
- });
- const assertions = {
- pages: new Set(actions.map(action => action.pageId)).size === 15,
- actionIds: actions.every(action => action.id.startsWith(`act.${action.pageId.toLowerCase()}.`)),
- duplicateActions: new Set(actions.map(action => action.id)).size === actions.length,
- operationContracts: operations.every(operation => /^(GET|POST|PUT|PATCH|DELETE)$/.test(operation.method) && operation.path.startsWith('/api/')),
- navTargets: navEdges.every(edge => actions.some(action => action.pageId === edge.fromPageId) && actions.some(action => action.pageId === edge.toPageId)),
- };
- window.GONGXUE_PLATFORM_SPEC = { actions, operations, navEdges, supportingReads };
- window.__GONGXUE_ACTION_CONTRACT__ = { coverage, assertions, trace };
- window.decoratePlatformSpec = decorate;
- window.recordPlatformSpecResult = (actionId, result = {}) => pushTrace({ phase: 'result', actionId, ...result });
- window.__PLATFORM_CONTRACT_EVENTS__ = trace;
- window.__PLATFORM_SPEC_COVERAGE__ = coverage();
-})();
diff --git a/Tiku.Api/wwwroot/platform-admin/styles.css b/Tiku.Api/wwwroot/platform-admin/styles.css
deleted file mode 100644
index 90379ca..0000000
--- a/Tiku.Api/wwwroot/platform-admin/styles.css
+++ /dev/null
@@ -1,49 +0,0 @@
-:root{--navy:#111827;--navy-2:#1d2939;--blue:#1455ff;--blue-50:#f3f6ff;--blue-100:#e7edff;--ink:#101828;--ink-2:#344054;--muted:#667085;--line:#e4e7ec;--canvas:#f5f6f8;--green:#159455;--orange:#ed8b00;--red:#d92d20;--purple:#6941c6;--cyan:#088ab2;--sidebar:230px;font-family:Inter,"PingFang SC","Microsoft YaHei",system-ui,sans-serif;color:var(--ink);background:var(--canvas);font-synthesis:none}*{box-sizing:border-box}html,body{margin:0;min-height:100%;background:var(--canvas)}body{min-width:320px;letter-spacing:0}button,input,select,textarea{font:inherit;letter-spacing:0}button{cursor:pointer;color:inherit}button:focus-visible,input:focus-visible,select:focus-visible{outline:3px solid rgba(20,85,255,.2);outline-offset:2px}svg{width:19px;height:19px}.platform-app{min-height:100vh;display:grid;grid-template-columns:var(--sidebar) minmax(0,1fr)}.platform-sidebar{position:fixed;inset:0 auto 0 0;z-index:30;width:var(--sidebar);display:flex;flex-direction:column;padding:17px 14px;background:var(--navy);color:#d0d5dd;overflow:auto}.platform-brand{height:53px;display:flex;align-items:center;gap:10px;padding:4px 7px;border:0;background:transparent;color:#fff;text-align:left}.platform-brand img{width:37px;height:37px;border-radius:7px}.platform-brand span{display:grid;gap:2px}.platform-brand strong{font-size:15px}.platform-brand small{color:#98a2b3;font-size:8px}.environment{height:34px;display:grid;grid-template-columns:8px 1fr auto;align-items:center;gap:7px;margin:13px 6px 21px;padding:0 9px;border:1px solid #344054;background:#182230;font-size:8px}.environment i{width:7px;height:7px;border-radius:50%;background:#32d583;box-shadow:0 0 0 3px rgba(50,213,131,.1)}.environment b{color:#98a2b3;font-size:7px}#sideNav{display:grid;gap:19px}#sideNav section{display:grid;gap:3px}#sideNav h2{margin:0 10px 5px;color:#667085;font-size:7.5px;text-transform:uppercase}#sideNav button,.platform-foot>button{position:relative;width:100%;height:40px;display:grid;grid-template-columns:20px 1fr auto;align-items:center;gap:8px;padding:0 10px;border:0;border-radius:5px;background:transparent;color:#98a2b3;text-align:left;font-size:10px;font-weight:650}#sideNav button:hover,.platform-foot>button:hover{background:#1d2939;color:#fff}#sideNav button.is-active{background:#23335d;color:#fff}#sideNav button.is-active:before{content:"";position:absolute;left:-14px;width:3px;height:25px;background:#6b8cff}#sideNav svg,.platform-foot svg{width:16px}#sideNav b{min-width:18px;height:18px;display:grid;place-items:center;border-radius:9px;background:#d92d20;color:#fff;font-size:7px}.platform-foot{margin-top:auto;padding-top:14px;border-top:1px solid #344054}.platform-foot>div{height:54px;display:grid;grid-template-columns:31px 1fr 24px;align-items:center;gap:8px;margin:8px 4px 0}.platform-foot>div>span{width:30px;height:30px;display:grid;place-items:center;border-radius:50%;background:#344054;color:#fff;font-size:9px}.platform-foot p{display:grid;gap:3px;margin:0}.platform-foot strong{color:#fff;font-size:9px}.platform-foot small{color:#667085;font-size:7.5px}.platform-foot>div button{border:0;background:transparent;color:#667085}.platform-foot>div svg{width:14px}.platform-workspace{grid-column:2;min-width:0}.platform-topbar{position:sticky;top:0;z-index:20;height:66px;display:flex;align-items:center;gap:22px;padding:0 30px;border-bottom:1px solid var(--line);background:rgba(255,255,255,.96);backdrop-filter:blur(12px)}.page-context{display:grid;gap:3px;min-width:190px}.page-context small{color:#98a2b3;font-size:7px}.page-context strong{font-size:11px}.platform-search{width:min(470px,37vw);height:37px;display:flex;align-items:center;gap:8px;padding:0 10px;border:1px solid transparent;background:#f3f5f7}.platform-search:focus-within{border-color:#a9c0ff;background:#fff}.platform-search svg{width:15px;color:var(--muted)}.platform-search input{min-width:0;width:100%;border:0;outline:0;background:transparent;font-size:9px}.platform-search kbd{padding:2px 5px;border:1px solid var(--line);background:#fff;color:var(--muted);font-size:7px}.top-status{margin-left:auto;display:flex;align-items:center;gap:13px}.top-status>span{display:flex;align-items:center;gap:6px;color:var(--green);font-size:8px}.top-status>span i{width:7px;height:7px;border-radius:50%;background:#32d583}.icon-button{position:relative;width:36px;height:36px;display:grid;place-items:center;border:1px solid var(--line);background:#fff}.icon-button svg{width:16px}.icon-button b{position:absolute;right:-3px;top:-4px;min-width:17px;height:17px;display:grid;place-items:center;border:2px solid #fff;border-radius:9px;background:var(--red);color:#fff;font-size:7px}.mobile-menu{display:none}#mainView{min-height:calc(100vh - 66px);padding:26px 30px 48px}.page-shell{width:min(1540px,100%);margin:0 auto}.page-head{min-height:52px;display:flex;align-items:flex-start;justify-content:space-between;gap:20px;margin-bottom:18px}.page-head h1{margin:0;font-size:21px}.page-head p{margin:5px 0 0;color:var(--muted);font-size:9.5px}.page-head>div:last-child{display:flex;gap:8px}.button{min-height:36px;display:inline-flex;align-items:center;justify-content:center;gap:7px;padding:0 12px;border:1px solid #d0d5dd;background:#fff;font-size:9px;font-weight:650}.button:hover{border-color:#9db9ff;color:var(--blue)}.button.primary{border-color:var(--blue);background:var(--blue);color:#fff}.button.danger{border-color:#ffb4ae;color:var(--red)}.button svg{width:14px}.control{height:36px;border:1px solid var(--line);background:#fff;padding:0 9px;font-size:8px}.link{padding:0;border:0;background:transparent;color:var(--blue);font-size:8px;font-weight:700}.metric-grid{display:grid;grid-template-columns:repeat(5,1fr);gap:11px}.metric{min-height:112px;display:grid;grid-template-columns:40px 1fr;align-items:center;gap:12px;padding:17px;border:1px solid var(--line);background:#fff}.metric-icon{width:38px;height:38px;display:grid;place-items:center;border-radius:6px;background:var(--blue-100);color:var(--blue)}.metric-icon.green{background:#edf9f2;color:var(--green)}.metric-icon.orange{background:#fff5e8;color:var(--orange)}.metric-icon.red{background:#fff0ef;color:var(--red)}.metric-icon.purple{background:#f3f0ff;color:var(--purple)}.metric-icon.cyan{background:#edfafd;color:var(--cyan)}.metric-icon svg{width:17px}.metric div{display:grid;gap:5px}.metric small,.metric p{margin:0;color:var(--muted);font-size:7.5px}.metric strong{font-size:20px}.panel,.table-panel{border:1px solid var(--line);background:#fff}.panel-head{min-height:60px;display:flex;align-items:center;justify-content:space-between;gap:12px;padding:0 17px;border-bottom:1px solid var(--line)}.panel-head h2{margin:0;font-size:11px}.panel-head span{display:block;margin-top:4px;color:var(--muted);font-size:7.5px}.overview-grid{display:grid;grid-template-columns:minmax(0,1.7fr) minmax(310px,.72fr);gap:11px;margin-top:11px}.revenue-panel{min-width:0}.legend{display:flex;gap:12px;color:var(--muted);font-size:7.5px}.legend span{display:flex!important;align-items:center;gap:5px}.legend i{width:7px;height:7px;border-radius:50%}.legend .blue{background:var(--blue)}.legend .green{background:var(--green)}.revenue-chart{height:278px;display:grid;grid-template-columns:38px 1fr;padding:24px 18px 18px}.chart-axis{display:flex;flex-direction:column;justify-content:space-between;color:#98a2b3;font-size:7px}.chart-plot{position:relative}.chart-plot .grid{position:absolute;inset:0 0 20px;background:repeating-linear-gradient(to bottom,var(--line) 0,var(--line) 1px,transparent 1px,transparent 33.333%)}.bars{position:absolute;inset:0;display:flex;align-items:end;gap:8px}.bars>span{height:100%;flex:1;display:flex;align-items:end;justify-content:center;gap:3px;position:relative;padding-bottom:20px}.bars i{width:45%;background:var(--blue);opacity:.78}.bars b{width:18%;background:var(--green)}.bars em{position:absolute;bottom:0;color:#98a2b3;font-size:6.5px;font-style:normal}.alert-row{width:100%;min-height:62px;display:grid;grid-template-columns:34px minmax(0,1fr) 14px;align-items:center;gap:9px;padding:9px 14px;border:0;border-bottom:1px solid var(--line);background:#fff;text-align:left}.alert-row:last-child{border-bottom:0}.alert-row:hover{background:#fafbfc}.alert-row>span{width:32px;height:32px;display:grid;place-items:center;border-radius:6px;background:#fff5e8;color:var(--orange)}.alert-row svg{width:15px}.alert-row div{display:grid;gap:4px}.alert-row strong{font-size:8.5px}.alert-row small{color:var(--muted);font-size:7px}.alert-row>svg{color:#98a2b3}.overview-lower{display:grid;grid-template-columns:.8fr 1fr 1fr;gap:11px;margin-top:11px}.tenant-health{min-height:192px;display:grid;grid-template-columns:140px 1fr;align-items:center;gap:10px;padding:17px}.health-donut{width:118px;height:118px;display:grid;place-items:center;align-content:center;gap:2px;border-radius:50%;background:conic-gradient(var(--blue) 79%,#6b8cff 0 89%,#a9bbff 0 95%,#e4e7ec 0);position:relative}.health-donut:before{content:"";position:absolute;width:82px;height:82px;border-radius:50%;background:#fff}.health-donut strong,.health-donut span{position:relative}.health-donut strong{font-size:19px}.health-donut span{color:var(--muted);font-size:7px}.tenant-health>div:last-child{display:grid;gap:10px}.tenant-health p{display:grid;grid-template-columns:55px 1fr 20px;align-items:center;gap:7px;margin:0;font-size:7.5px}.tenant-health p i{height:4px;background:#edf0f4}.tenant-health p i b{display:block;height:100%;background:var(--blue)}.usage-summary{display:grid;grid-template-columns:repeat(3,1fr);padding:18px}.usage-summary>div{display:grid;gap:6px;padding:0 13px;border-right:1px solid var(--line)}.usage-summary>div:first-child{padding-left:0}.usage-summary>div:last-child{border-right:0}.usage-summary span,.usage-summary small{color:var(--muted);font-size:7px}.usage-summary strong{font-size:15px}.usage-summary i,.usage-kpis i,.usage-cell i,.drawer-usage i{height:4px;background:#edf0f4}.usage-summary i b,.usage-kpis i b,.usage-cell i b,.drawer-usage i b{display:block;height:100%;background:var(--blue)}.platform-activity{display:grid;padding:7px 14px}.platform-activity>div{min-height:51px;display:grid;grid-template-columns:27px 1fr;align-items:center;gap:8px;border-bottom:1px solid var(--line)}.platform-activity>div:last-child{border-bottom:0}.platform-activity>div>span{width:26px;height:26px;display:grid;place-items:center;border-radius:50%;background:#f2f4f7;font-size:7px}.platform-activity p{display:grid;gap:4px;margin:0;font-size:7.5px}.platform-activity small{color:var(--muted);font-size:6.5px}.filter-bar{min-height:59px;display:flex;align-items:center;gap:8px;padding:10px 12px;border:1px solid var(--line);background:#fff}.filter-bar label{min-width:300px;height:36px;display:flex;align-items:center;gap:7px;padding:0 9px;border:1px solid var(--line);background:#f8fafc}.filter-bar label svg{width:14px;color:var(--muted)}.filter-bar input{min-width:0;width:100%;border:0;outline:0;background:transparent;font-size:8px}.filter-bar select{height:36px;border:1px solid var(--line);background:#fff;padding:0 28px 0 9px;font-size:8px}.filter-segment{display:flex;gap:3px;margin-left:auto;padding:3px;background:#f2f4f7}.filter-segment button{height:28px;padding:0 9px;border:0;background:transparent;color:var(--muted);font-size:7px;white-space:nowrap}.filter-segment button.is-active{background:#fff;color:var(--blue);box-shadow:0 1px 4px rgba(16,24,40,.08);font-weight:700}.table-panel{overflow:auto;border-top:0}.platform-table{width:100%;min-width:1040px;border-collapse:collapse}.platform-table th{height:42px;padding:0 12px;background:#f8fafc;color:var(--muted);font-size:7px;font-weight:650;text-align:left}.platform-table td{height:65px;padding:8px 12px;border-top:1px solid var(--line);font-size:8px;vertical-align:middle}.platform-table tr:hover td{background:#fcfcfd}.platform-table td>strong,.platform-table td>small{display:block}.platform-table td>small{margin-top:4px;color:var(--muted);font-size:6.5px}.tenant-cell{display:flex;align-items:center;gap:9px}.tenant-cell>span{width:31px;height:31px;display:grid;place-items:center;border-radius:6px;background:var(--blue-100);color:var(--blue);font-size:8px;font-weight:800}.tenant-cell>div{display:grid;gap:4px}.tenant-cell strong{font-size:8.5px}.tenant-cell small{color:var(--muted);font-size:6.5px}.status{display:inline-flex;align-items:center;justify-content:center;min-height:21px;padding:0 7px;border-radius:4px;font-size:6.5px!important;font-style:normal;font-weight:700;white-space:nowrap}.status.success{background:#edf9f2;color:var(--green)}.status.warning{background:#fff5e8;color:#b96700}.status.danger{background:#fff0ef;color:var(--red)}.status.neutral{background:#f2f4f7;color:var(--muted)}.money-due{color:var(--red)}.row-action{width:28px;height:28px;display:grid;place-items:center;border:0;background:transparent;color:var(--muted)}.row-action:hover{background:var(--blue-100);color:var(--blue)}.row-action svg{width:13px}.table-panel>footer{height:48px;display:flex;align-items:center;justify-content:space-between;padding:0 13px;border-top:1px solid var(--line);color:var(--muted);font-size:7px}.table-panel>footer button{display:flex;align-items:center;gap:5px;border:0;background:transparent;color:var(--blue);font-size:7px}.table-panel>footer svg{width:12px}.drawer-backdrop{position:fixed;z-index:60;inset:0;background:rgba(16,24,40,.28)}.tenant-drawer{position:absolute;right:0;top:0;bottom:0;width:min(620px,100%);display:flex;flex-direction:column;background:#fff;box-shadow:-18px 0 50px rgba(16,24,40,.18);overflow:auto}.tenant-drawer>header{min-height:92px;display:flex;align-items:center;justify-content:space-between;padding:16px 21px;border-bottom:1px solid var(--line)}.tenant-drawer>header>div{display:flex;align-items:center;gap:12px}.tenant-drawer>header>div>span{width:45px;height:45px;display:grid;place-items:center;border-radius:8px;background:var(--blue-100);color:var(--blue);font-size:12px;font-weight:800}.tenant-drawer header small{color:var(--blue);font-size:7px}.tenant-drawer h2{margin:4px 0;font-size:15px}.tenant-drawer header p{margin:0;color:var(--muted);font-size:7px}.tenant-drawer header>button{border:0;background:transparent}.tenant-drawer header svg{width:17px}.drawer-status{display:grid!important;grid-template-columns:repeat(4,1fr);padding:0!important;border-bottom:1px solid var(--line)}.drawer-status>div{min-height:73px;display:grid;align-content:center;gap:6px;padding:13px;border-right:1px solid var(--line)}.drawer-status>div:last-child{border-right:0}.drawer-status span{color:var(--muted);font-size:7px}.drawer-status strong{font-size:8px}.drawer-tabs{height:43px;display:flex;gap:16px;padding:0 20px;border-bottom:1px solid var(--line)}.drawer-tabs button{border:0;background:transparent;color:var(--muted);font-size:7.5px}.drawer-tabs button.is-active{color:var(--blue);border-bottom:2px solid var(--blue);font-weight:700}.tenant-drawer>section{padding:19px 21px;border-bottom:1px solid var(--line)}.tenant-drawer>section h3{margin:0 0 12px;font-size:10px}.tenant-drawer dl{display:grid;grid-template-columns:1fr 1fr;gap:13px;margin:0}.tenant-drawer dl div{display:grid;gap:4px}.tenant-drawer dt{color:var(--muted);font-size:7px}.tenant-drawer dd{margin:0;font-size:8px}.domain-item{min-height:49px;display:grid;grid-template-columns:24px 1fr auto;align-items:center;gap:8px;border-bottom:1px solid var(--line)}.domain-item>svg{width:15px;color:var(--blue)}.domain-item span{display:grid;gap:4px}.domain-item strong{font-size:8px}.domain-item small{color:var(--muted);font-size:6.5px}.drawer-usage{display:grid;gap:13px}.drawer-usage>div{display:grid;grid-template-columns:80px 1fr;align-items:center;gap:6px 12px}.drawer-usage span{color:var(--muted);font-size:7px}.drawer-usage strong{font-size:8px}.drawer-usage i{grid-column:2}.tenant-drawer>footer{position:sticky;bottom:0;display:flex;justify-content:flex-end;gap:7px;margin-top:auto;padding:12px 20px;border-top:1px solid var(--line);background:#fff}.lifecycle-summary{display:grid;grid-template-columns:repeat(4,1fr);gap:10px}.lifecycle-summary article{min-height:92px;display:grid;grid-template-columns:42px 1fr 20px;align-items:center;gap:10px;padding:15px;border:1px solid var(--line);background:#fff}.stage-number{width:40px;height:40px;display:grid;place-items:center;border-radius:50%;background:var(--blue-100);color:var(--blue);font-size:15px;font-weight:800}.stage-number.risk{background:#fff0ef;color:var(--red)}.lifecycle-summary article>div{display:grid;gap:5px}.lifecycle-summary strong{font-size:9px}.lifecycle-summary small{color:var(--muted);font-size:7px}.lifecycle-summary button{border:0;background:transparent;color:#98a2b3}.lifecycle-summary svg{width:13px}.lifecycle-grid{display:grid;grid-template-columns:1.2fr .8fr;gap:11px;margin-top:11px}.lifecycle-row{min-height:64px;display:grid;grid-template-columns:31px minmax(0,1fr) 42px auto;align-items:center;gap:9px;padding:8px 15px;border-bottom:1px solid var(--line)}.lifecycle-row>span{width:29px;height:29px;display:grid;place-items:center;border-radius:6px;background:var(--blue-100);color:var(--blue);font-size:8px}.lifecycle-row>div{display:grid;gap:4px}.lifecycle-row strong{font-size:8px}.lifecycle-row small{color:var(--muted);font-size:6.5px}.lifecycle-row>b{color:var(--orange);font-size:8px}.setup-card{padding:17px}.setup-card header{display:flex;justify-content:space-between;margin-bottom:12px}.setup-card header span{font-size:9px;font-weight:700}.setup-card header b{color:var(--blue);font-size:8px}.setup-card p{display:flex;align-items:center;gap:7px;margin:0;min-height:35px;color:var(--muted);font-size:7.5px}.setup-card p.done{color:var(--green)}.setup-card p svg{width:14px}.setup-card .button{width:100%;margin-top:12px}.plan-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:11px}.plan-card{min-height:330px;padding:20px;border:1px solid var(--line);background:#fff}.plan-card.is-featured{border:2px solid var(--blue);padding:19px}.plan-card header{display:flex;justify-content:space-between;gap:10px}.plan-card header span{font-size:13px;font-weight:800}.plan-card header p{margin:5px 0 0;color:var(--muted);font-size:7.5px}.plan-card header b{height:21px;padding:0 7px;display:flex;align-items:center;background:var(--blue-100);color:var(--blue);font-size:6.5px;white-space:nowrap}.plan-card>strong{display:block;margin:26px 0 22px;color:var(--blue);font-size:31px}.plan-card>strong small{color:var(--muted);font-size:8px}.plan-card ul{display:grid;gap:12px;margin:0 0 25px;padding:18px 0;border-block:1px solid var(--line);list-style:none}.plan-card li{display:flex;align-items:center;gap:7px;font-size:8px}.plan-card li svg{width:13px;color:var(--green)}.plan-card>.button{width:100%}.subscription-table{margin-top:11px;border-top:1px solid var(--line)}.table-head{height:58px;display:flex;align-items:center;justify-content:space-between;padding:0 15px;border-bottom:1px solid var(--line)}.table-head h2{margin:0;font-size:10px}.table-head span{color:var(--muted);font-size:7px}.table-head label{width:220px;height:32px;display:flex;align-items:center;gap:6px;padding:0 8px;border:1px solid var(--line);background:#f8fafc}.table-head svg{width:13px;color:var(--muted)}.table-head input{min-width:0;width:100%;border:0;outline:0;background:transparent;font-size:7.5px}.switch{width:32px;height:18px;padding:2px;border:0;border-radius:9px;background:#d0d5dd}.switch i{display:block;width:14px;height:14px;border-radius:50%;background:#fff}.switch.is-on{background:var(--blue)}.switch.is-on i{transform:translateX(14px)}.billing-metrics{grid-template-columns:repeat(4,1fr)}.billing-tabs{height:47px;display:flex;gap:22px;margin-top:11px;padding:0 15px;border:1px solid var(--line);border-bottom:0;background:#fff}.billing-tabs button{border:0;background:transparent;color:var(--muted);font-size:8px}.billing-tabs button.is-active{color:var(--blue);border-bottom:2px solid var(--blue);font-weight:700}.collection-console{display:grid;grid-template-columns:1.2fr .8fr;gap:11px}.collection-console>.panel{border-top:0}.collection-console article{min-height:70px;display:grid;grid-template-columns:34px minmax(0,1fr) auto auto;align-items:center;gap:9px;padding:9px 15px;border-bottom:1px solid var(--line)}.collection-console article>span{width:32px;height:32px;display:grid;place-items:center;background:#fff0ef;color:var(--red)}.collection-console article svg{width:15px}.collection-console article>div{display:grid;gap:4px}.collection-console article strong{font-size:8.5px}.collection-console article small{color:var(--muted);font-size:7px}.collection-console article>b{color:var(--red);font-size:8px}.policy-timeline{padding:15px}.policy-timeline p{position:relative;display:grid;gap:4px;margin:0;padding:0 0 20px 20px;border-left:1px solid var(--line)}.policy-timeline p:last-child{padding-bottom:0}.policy-timeline p:before{content:"";position:absolute;left:-4px;top:2px;width:7px;height:7px;border-radius:50%;background:var(--blue)}.policy-timeline b{font-size:8px}.policy-timeline span{color:var(--muted);font-size:7px}.usage-kpis{display:grid;grid-template-columns:repeat(4,1fr);margin-bottom:11px;border:1px solid var(--line);background:#fff}.usage-kpis>div{min-height:110px;display:grid;gap:6px;align-content:center;padding:16px 18px;border-right:1px solid var(--line)}.usage-kpis>div:last-child{border-right:0}.usage-kpis span,.usage-kpis small{color:var(--muted);font-size:7px}.usage-kpis strong{font-size:20px}.usage-kpis i.orange b{background:var(--orange)}.usage-cell{min-width:110px;display:grid;gap:6px}.usage-cell span{font-size:7px}.bank-layout{min-height:600px;display:grid;grid-template-columns:280px minmax(0,1fr);border:1px solid var(--line);background:#fff}.bank-tree{border-right:1px solid var(--line)}.bank-tree header{height:51px;display:flex;align-items:center;justify-content:space-between;padding:0 13px;border-bottom:1px solid var(--line)}.bank-tree header strong{font-size:9px}.bank-tree header button{border:0;background:transparent;color:var(--blue)}.bank-tree header svg{width:14px}.bank-tree>button{width:100%;min-height:57px;display:grid;grid-template-columns:28px 1fr 14px;align-items:center;gap:8px;padding:8px 12px;border:0;border-bottom:1px solid var(--line);background:#fff;text-align:left}.bank-tree>button.is-active{background:var(--blue-50);box-shadow:inset 3px 0 var(--blue)}.bank-tree>button>svg:first-child{width:16px;color:var(--blue)}.bank-tree>button>svg:last-child{width:13px;color:#98a2b3}.bank-tree>button span{display:grid;gap:4px}.bank-tree strong{font-size:8px}.bank-tree small{color:var(--muted);font-size:6.5px}.bank-content{min-width:0;padding:22px}.bank-content>header{display:flex;align-items:flex-start;justify-content:space-between}.bank-content header span{color:var(--blue);font-size:7px}.bank-content h2{margin:7px 0 5px;font-size:16px}.bank-content header p{margin:0;color:var(--muted);font-size:7.5px}.bank-stats{display:grid;grid-template-columns:repeat(4,1fr);margin:20px 0;border:1px solid var(--line)}.bank-stats>div{min-height:75px;display:grid;align-content:center;gap:5px;padding:13px;border-right:1px solid var(--line)}.bank-stats>div:last-child{border-right:0}.bank-stats span{color:var(--muted);font-size:7px}.bank-stats strong{font-size:17px}.version-card{min-height:115px;display:flex;align-items:center;justify-content:space-between;gap:15px;padding:17px;border:1px solid var(--line);margin-top:10px}.version-card h3{margin:8px 0 6px;font-size:12px}.version-card p{margin:0;color:var(--ink-2);font-size:8px}.version-card small{display:block;margin-top:8px;color:var(--muted);font-size:6.5px}.version-card>div:last-child{display:flex;gap:7px}.audit-filter label{min-width:320px}.audit-table code{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:6.5px}.severity{display:inline-flex;align-items:center;justify-content:center;min-width:34px;height:20px;border-radius:4px;font-size:6.5px;font-weight:800}.severity.success{background:#edf9f2;color:var(--green)}.severity.warning{background:#fff5e8;color:#b96700}.severity.danger{background:#fff0ef;color:var(--red)}.severity.neutral{background:#f2f4f7;color:var(--muted)}.alert-layout{display:grid;grid-template-columns:minmax(0,1.35fr) minmax(320px,.65fr);gap:11px}.security-alert{min-height:94px;display:grid;grid-template-columns:40px minmax(0,1fr) auto auto;align-items:center;gap:11px;padding:12px 15px;border-bottom:1px solid var(--line)}.alert-level{width:38px;height:38px;display:grid;place-items:center;border-radius:50%;font-size:7px;font-weight:800}.alert-level.danger{background:#fff0ef;color:var(--red)}.alert-level.warning{background:#fff5e8;color:#b96700}.security-alert>div{display:grid;gap:4px}.security-alert small,.security-alert em{color:var(--muted);font-size:6.5px;font-style:normal}.security-alert strong{font-size:8.5px}.security-alert p{margin:0;color:var(--ink-2);font-size:7px}.channel-panel{display:grid;align-content:start;gap:11px}.channel-row{min-height:65px;display:grid;grid-template-columns:32px minmax(0,1fr) auto 22px;align-items:center;gap:8px;padding:9px 13px;border-bottom:1px solid var(--line)}.channel-row>span{width:30px;height:30px;display:grid;place-items:center;background:var(--blue-100);color:var(--blue)}.channel-row svg{width:14px}.channel-row>div{display:grid;gap:4px}.channel-row strong{font-size:8px}.channel-row small{color:var(--muted);font-size:6.5px}.channel-row>button{border:0;background:transparent}.failure-panel>div:last-child{padding:15px}.failure-panel strong{font-size:8px}.failure-panel p{color:var(--muted);font-size:7px;line-height:1.6}.staff-layout{display:grid;grid-template-columns:1.1fr .9fr;gap:11px}.staff-row{min-height:67px;display:grid;grid-template-columns:32px minmax(0,1fr) 82px 90px auto 22px;align-items:center;gap:9px;padding:9px 14px;border-bottom:1px solid var(--line)}.staff-row>span{width:30px;height:30px;display:grid;place-items:center;border-radius:50%;background:var(--blue-100);color:var(--blue);font-size:8px}.staff-row>div{display:grid;gap:4px}.staff-row strong{font-size:8px}.staff-row small{color:var(--muted);font-size:6.5px}.staff-row>b,.staff-row>em{font-size:7px;font-style:normal;font-weight:500}.staff-row>button{border:0;background:transparent}.role-row{min-height:68px;display:grid;grid-template-columns:32px minmax(0,1fr) 30px auto;align-items:center;gap:9px;padding:9px 14px;border-bottom:1px solid var(--line)}.role-row>span{width:30px;height:30px;display:grid;place-items:center;background:#edf9f2;color:var(--green)}.role-row svg{width:14px}.role-row>div{display:grid;gap:4px}.role-row strong{font-size:8px}.role-row small{color:var(--muted);font-size:6.5px}.role-row>b{font-size:7px}.toast{position:fixed;z-index:100;left:50%;bottom:24px;min-height:40px;display:flex;align-items:center;gap:8px;padding:0 13px;background:#101828;color:#fff;box-shadow:0 12px 30px rgba(16,24,40,.24);transform:translate(-50%,16px);opacity:0;pointer-events:none;transition:.2s;font-size:8px}.toast.is-visible{transform:translate(-50%,0);opacity:1}.toast svg{width:14px;color:#78e2a8}
-@media(max-width:1240px){:root{--sidebar:210px}.metric-grid{grid-template-columns:repeat(3,1fr)}.overview-grid{grid-template-columns:1fr}.overview-lower{grid-template-columns:1fr 1fr}.activity-panel{grid-column:1/-1}.lifecycle-grid,.collection-console,.alert-layout{grid-template-columns:1fr}.staff-layout{grid-template-columns:1fr}}
-@media(max-width:900px){.platform-app{display:block}.platform-sidebar{transform:translateX(-100%);transition:.2s;box-shadow:18px 0 48px rgba(16,24,40,.28)}.platform-app.menu-open .platform-sidebar{transform:translateX(0)}.platform-workspace{min-width:0}.platform-topbar{height:58px;padding:0 12px;gap:9px}.mobile-menu{display:grid}.page-context small,.platform-search kbd,.top-status>span{display:none}.page-context{min-width:120px}.platform-search{width:auto;flex:1}#mainView{padding:18px 12px 32px}.page-head{align-items:flex-start;flex-direction:column}.page-head>div:last-child{width:100%;overflow:auto}.metric-grid{grid-template-columns:1fr 1fr}.overview-lower{grid-template-columns:1fr}.activity-panel{grid-column:auto}.filter-bar{align-items:stretch;flex-wrap:wrap}.filter-bar label{min-width:100%}.filter-bar select{flex:1}.filter-segment{width:100%;margin-left:0;overflow:auto}.filter-segment button{flex:1}.table-panel{border-top:1px solid var(--line)}.lifecycle-summary{grid-template-columns:1fr 1fr}.plan-grid{grid-template-columns:1fr}.collection-console{grid-template-columns:1fr}.usage-kpis{grid-template-columns:1fr 1fr}.bank-layout{display:block}.bank-tree{border-right:0;border-bottom:1px solid var(--line)}.bank-tree>button{display:inline-grid;width:260px;border-right:1px solid var(--line)}.bank-tree{overflow:auto;white-space:nowrap}.bank-tree header{position:sticky;left:0;background:#fff}.bank-content{padding:16px}.staff-layout{grid-template-columns:1fr}}
-@media(max-width:560px){.page-context{display:none}.top-status .icon-button{display:none}.metric-grid{grid-template-columns:1fr}.metric{min-height:94px}.revenue-chart{height:230px;padding-inline:8px}.overview-lower{grid-template-columns:1fr}.tenant-health{grid-template-columns:1fr;justify-items:center}.usage-summary{grid-template-columns:1fr}.usage-summary>div{padding:12px 0;border-right:0;border-bottom:1px solid var(--line)}.usage-summary>div:last-child{border-bottom:0}.lifecycle-summary{grid-template-columns:1fr}.drawer-status{grid-template-columns:1fr 1fr}.drawer-status>div:nth-child(2){border-right:0}.drawer-status>div:nth-child(-n+2){border-bottom:1px solid var(--line)}.drawer-tabs{overflow:auto}.drawer-tabs button{min-width:max-content}.tenant-drawer dl{grid-template-columns:1fr}.billing-metrics{grid-template-columns:1fr}.billing-tabs{overflow:auto}.billing-tabs button{min-width:max-content}.usage-kpis{grid-template-columns:1fr}.usage-kpis>div{border-right:0;border-bottom:1px solid var(--line)}.bank-stats{grid-template-columns:1fr 1fr}.bank-stats>div:nth-child(2){border-right:0}.bank-stats>div:nth-child(-n+2){border-bottom:1px solid var(--line)}.version-card{align-items:flex-start;flex-direction:column}.security-alert{grid-template-columns:38px minmax(0,1fr)}.security-alert>b,.security-alert>.button{grid-column:2;width:max-content}.staff-row{grid-template-columns:31px minmax(0,1fr) auto}.staff-row>em,.staff-row>i{display:none}.role-row{grid-template-columns:30px minmax(0,1fr) auto}.role-row>.button{grid-column:2/-1}.tenant-drawer{width:100%}}
-@media(prefers-reduced-motion:reduce){*,*:before,*:after{transition:none!important}}
-
-/* Global productive typography floor: dense, but never miniature. */
-:root{--text-caption:12px;--text-label:13px;--text-body:14px;--text-heading:18px;--text-title:24px;--line-caption:18px;--line-body:22px}
-.platform-brand small,.environment,.environment b,.environment-switch,.environment-switch small,#sideNav section h2,.platform-foot small,.platform-foot>div>span,.platform-foot strong,.page-context small,.platform-search input,.platform-search kbd,.top-status,.top-status>span,.icon-button b,.page-head p,.metric small,.metric p,.panel-head span,.legend,.chart-axis,.bars em,.alert-row small,.health-donut span,.tenant-health p,.usage-summary span,.usage-summary small,.platform-activity>span,.platform-activity small,.filter-bar input,.filter-bar select,.platform-table th,.platform-table td>small,.tenant-cell small,.table-panel>footer,.tenant-drawer header small,.tenant-drawer header p,.drawer-status span,.drawer-tabs button,.tenant-drawer dt,.domain-item small,.drawer-usage span,.setup-card p,.plan-card header p,.plan-card header b,.plan-card>strong small,.table-head span,.table-head input,.billing-tabs button,.collection-console article small,.policy-timeline span,.usage-kpis span,.usage-kpis small,.usage-cell span,.bank-tree small,.bank-content header span,.bank-content header p,.bank-stats span,.version-card small,.audit-table code,.severity,.security-alert small,.security-alert em,.security-alert p,.alert-level,.channel-row small,.failure-panel p,.staff-row small,.staff-row>b,.staff-row>em,.role-row small,.role-row>b{font-size:var(--text-caption)!important;line-height:var(--line-caption)}
-#sideNav button,.platform-foot>button,.page-context strong,.button,.control,.link,.filter-segment button,.platform-table td,.platform-table footer button,.tenant-drawer h3,.tenant-drawer dd,.domain-item strong,.drawer-usage strong,.setup-card header span,.setup-card header b,.plan-card li,.table-head h2,.collection-console article strong,.collection-console article>b,.policy-timeline b,.bank-tree header strong,.bank-tree strong,.version-card p,.security-alert strong,.channel-row strong,.failure-panel strong,.staff-row strong,.role-row strong,.status,.toast{font-size:var(--text-label)!important;line-height:20px}
-.page-head h1{font-size:var(--text-title);line-height:32px}.panel-head h2,.tenant-drawer h2,.bank-content h2{font-size:var(--text-heading);line-height:26px}.metric strong{font-size:28px;line-height:36px}.usage-kpis strong{font-size:24px;line-height:32px}.plan-card>strong{font-size:36px;line-height:44px}.platform-table th{height:46px}.platform-table td{height:68px}.button,.control,.platform-search,.filter-bar label,.filter-bar select{min-height:40px}.icon-button{width:40px;height:40px}.status,.severity{min-height:24px;padding-inline:8px}.tenant-drawer{width:min(640px,100%)}.tenant-drawer>header>button{width:40px;height:40px;display:grid;place-items:center}.drawer-tabs{height:48px}.drawer-tabs button{padding-inline:12px}.tenant-drawer>footer{gap:8px}
-@media(max-width:900px){:root{--text-body:15px;--text-label:14px}.button,.control,.icon-button{min-height:44px}.platform-table td{font-size:14px!important}.platform-table th{font-size:12px!important}}
-
-/* v1.1 specification interaction layer */
-.prototype-controls{display:flex;align-items:center;gap:7px}.prototype-controls label{height:40px;display:flex;align-items:center;gap:6px;padding:0 8px;border:1px solid var(--line);background:#fff}.prototype-controls span{color:var(--muted);font-size:12px;white-space:nowrap}.prototype-controls select{max-width:118px;border:0;outline:0;background:transparent;font-size:12px;color:var(--ink)}
-.page-id{display:block;margin:0 0 5px;color:var(--blue);font-size:12px;font-weight:750}.page-head.is-subpage{padding-bottom:14px;border-bottom:1px solid var(--line)}.subpage-nav{display:flex!important;align-items:center;gap:8px!important;margin-bottom:14px}.subpage-nav .icon-button{min-height:40px}.cell-link{padding:0;border:0;background:transparent;color:inherit;text-align:left;font:inherit}.tenant-cell.cell-link{display:flex}.row-actions,.inline-actions{display:flex;align-items:center;gap:6px}.platform-table tr.is-highlighted td{background:var(--blue-50)}
-.state-panel{min-height:300px;display:grid;place-items:center;align-content:center;gap:12px;padding:36px;border:1px solid var(--line);background:#fff;text-align:center}.state-panel>span{width:52px;height:52px;display:grid;place-items:center;border-radius:50%;background:var(--blue-100);color:var(--blue)}.state-panel>span svg{width:24px}.state-panel h2,.state-panel p{margin:0}.state-panel h2{font-size:20px}.state-panel p{max-width:650px;color:var(--muted);font-size:14px;line-height:22px}.state-panel>div{display:flex;gap:8px}.state-panel.is-error>span{background:#fff0ef;color:var(--red)}.state-panel.is-forbidden>span{background:#fff5e8;color:var(--orange)}.state-panel.is-partial{min-height:180px;margin-top:12px;background:#fffdf7}.skeleton-stack{display:grid;gap:13px;padding:28px;border:1px solid var(--line);background:#fff}.skeleton-stack i{width:var(--w);height:42px;background:linear-gradient(90deg,#f2f4f7,#fafafa,#f2f4f7);background-size:200% 100%;animation:skeleton 1.2s linear infinite}.state-hint{color:var(--muted);font-size:13px}@keyframes skeleton{to{background-position:-200% 0}}
-.detail-summary{display:grid;grid-template-columns:repeat(5,1fr);margin-bottom:12px;border:1px solid var(--line);background:#fff}.detail-summary>div{min-height:84px;display:grid;align-content:center;gap:7px;padding:14px 17px;border-right:1px solid var(--line)}.detail-summary>div:last-child{border-right:0}.detail-summary span{color:var(--muted);font-size:12px}.detail-summary strong{font-size:16px}.detail-grid{display:grid;grid-template-columns:minmax(0,1.25fr) minmax(340px,.75fr);gap:12px}.detail-list{display:grid;grid-template-columns:1fr 1fr;gap:20px;margin:0;padding:22px}.detail-list div{display:grid;gap:6px}.detail-list dt{color:var(--muted);font-size:12px}.detail-list dd{margin:0;font-size:14px;line-height:22px}.action-panel>button{width:100%;min-height:72px;display:grid;grid-template-columns:32px 1fr 20px;align-items:center;gap:10px;padding:12px 16px;border:0;border-bottom:1px solid var(--line);background:#fff;text-align:left}.action-panel>button:hover{background:var(--blue-50)}.action-panel>button>svg:first-child{color:var(--blue)}.action-panel>button>span{display:grid;gap:5px}.action-panel>button strong{font-size:14px}.action-panel>button small{color:var(--muted);font-size:12px}.timeline-panel{margin-top:12px}.timeline{display:grid;grid-template-columns:repeat(4,1fr);padding:22px}.timeline p{position:relative;display:grid;gap:6px;margin:0;padding:0 20px 0 25px;border-top:2px solid var(--line)}.timeline p:before{content:"";position:absolute;left:0;top:-7px;width:12px;height:12px;border-radius:50%;background:#d0d5dd}.timeline p.done{border-color:#98b1ff}.timeline p.done:before{background:var(--blue)}.timeline p.risk{border-color:#ffb4ae}.timeline p.risk:before{background:var(--red)}.timeline b{padding-top:16px;font-size:14px}.timeline span{color:var(--muted);font-size:12px;line-height:18px}
-.form-workspace{display:grid;gap:12px}.form-section{overflow:hidden}.form-grid{display:grid;grid-template-columns:1fr 1fr;gap:18px;padding:22px}.form-grid label,.modal-form>label,.alert-evidence>label{display:grid;align-content:start;gap:7px}.form-grid label.wide,.modal-detail .wide{grid-column:1/-1}.form-grid label>span,.modal-form label>span,.alert-evidence label>span{font-size:13px;font-weight:700}.form-grid input,.form-grid select,.form-grid textarea,.modal-form input,.modal-form select,.modal-form textarea,.alert-evidence textarea{width:100%;min-height:42px;padding:9px 11px;border:1px solid #d0d5dd;background:#fff;color:var(--ink);font-size:14px}.form-grid textarea,.modal-form textarea{resize:vertical}.form-grid input:disabled,.form-grid select:disabled{background:#f2f4f7;color:var(--muted)}.form-actions{position:sticky;bottom:0;z-index:4;display:flex;justify-content:flex-end;align-items:center;gap:8px;padding:14px 18px;border:1px solid var(--line);background:#fff}.form-actions>span{margin-right:auto;color:var(--muted);font-size:12px}.form-error-summary{margin:0;padding:14px 17px;border:1px solid #ffb4ae;background:#fff0ef;color:#b42318;font-size:13px}.form-error-summary strong{font-size:14px}.form-error-summary ul{margin:8px 0 0;padding-left:20px}.field-error{color:#b42318;font-size:12px;line-height:18px}.is-invalid{border-color:var(--red)!important;box-shadow:0 0 0 3px rgba(217,45,32,.08)}
-.toggle-label{display:flex;align-items:center;gap:7px;padding:0 10px;border:1px solid var(--line);background:#fff;font-size:13px}.modal-backdrop{position:fixed;z-index:80;inset:0;display:grid;place-items:center;padding:24px;background:rgba(16,24,40,.42)}.modal{width:min(620px,100%);max-height:min(820px,calc(100vh - 48px));display:flex;flex-direction:column;border:1px solid var(--line);background:#fff;box-shadow:0 24px 80px rgba(16,24,40,.25)}.modal.is-wide{width:min(880px,100%)}.modal>header{display:flex;align-items:flex-start;justify-content:space-between;gap:16px;padding:20px 22px;border-bottom:1px solid var(--line)}.modal>header small{color:var(--blue);font-size:12px;font-weight:750}.modal>header h2{margin:5px 0;font-size:20px}.modal>header p{margin:0;color:var(--muted);font-size:13px;line-height:20px}.modal>header .icon-button{flex:0 0 auto}.modal>footer{display:flex;justify-content:flex-end;gap:8px;padding:14px 20px;border-top:1px solid var(--line);background:#fff}.modal-form{min-height:0;display:grid;gap:16px;padding:20px 22px;overflow:auto}.modal-form .form-grid{padding:0}.check-row{display:flex!important;align-items:center!important;grid-template-columns:20px 1fr;gap:8px!important;min-height:42px}.check-row input{width:18px!important;min-height:18px!important}.danger-notice{display:flex;gap:8px;padding:12px;border:1px solid #ffb4ae;background:#fff0ef;color:#b42318;font-size:13px;line-height:20px}.modal-form fieldset{margin:0;padding:16px;border:1px solid var(--line)}.modal-form legend{padding:0 6px;font-size:14px;font-weight:700}.permission-grid{display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-bottom:12px}.permission-grid label{display:flex;align-items:center;gap:7px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px}.permission-grid input{width:16px;min-height:16px}.modal-detail{display:grid;grid-template-columns:1fr 1fr;gap:18px;margin:0;padding:22px;overflow:auto}.modal-detail div{display:grid;gap:6px}.modal-detail dt{color:var(--muted);font-size:12px}.modal-detail dd{margin:0;font-size:14px;line-height:22px}.candidate-list,.task-list{display:grid;gap:0;min-height:0;overflow:auto}.candidate-list label{min-height:68px;display:grid;grid-template-columns:20px 1fr;align-items:center;gap:10px;padding:12px 22px;border-bottom:1px solid var(--line)}.candidate-list label>span{display:grid;gap:5px}.candidate-list strong{font-size:14px}.candidate-list small{color:var(--muted);font-size:12px}.candidate-list>p{padding:30px;text-align:center;color:var(--muted)}.alert-evidence{display:grid;gap:18px;padding:22px;overflow:auto}.evidence-head{display:grid;grid-template-columns:42px 1fr auto;align-items:center;gap:12px}.evidence-head>div{display:grid;gap:5px}.evidence-head strong{font-size:15px}.evidence-head small{color:var(--muted);font-size:12px}.alert-evidence ul{display:grid;gap:8px;margin:0;padding:0;list-style:none}.alert-evidence li{display:flex;align-items:center;gap:8px;padding:10px 12px;background:#f8fafc;font-size:13px}.alert-evidence li svg{width:15px;color:var(--blue)}.task-list article{min-height:80px;display:grid;grid-template-columns:38px 1fr auto;align-items:center;gap:12px;padding:12px 20px;border-bottom:1px solid var(--line)}.task-state{width:36px;height:36px;display:grid;place-items:center;border-radius:50%;background:#f2f4f7;color:var(--muted)}.task-state.success{background:#edf9f2;color:var(--green)}.task-state.danger{background:#fff0ef;color:var(--red)}.task-state.warning svg{animation:spin 1s linear infinite}.task-list article>div{display:grid;gap:4px}.task-list strong{font-size:14px}.task-list small,.task-list p{margin:0;color:var(--muted);font-size:12px;line-height:18px}@keyframes spin{to{transform:rotate(360deg)}}
-.toast.is-error svg{color:#ffb4ae}.failure-panel article{padding:0}.channel-row .row-actions{justify-content:flex-end}.collection-console article .inline-actions{justify-content:flex-end}.collection-console article .inline-actions .button{white-space:nowrap}
-.confirm-impact{display:grid;grid-template-columns:42px 1fr;align-items:center;gap:12px;padding:22px}.confirm-impact>span{width:40px;height:40px;display:grid;place-items:center;border-radius:50%;background:#fff0ef;color:var(--red)}.confirm-impact p{margin:0;font-size:14px;line-height:22px}.icons-unavailable [data-lucide]{display:none}.icons-unavailable .button:empty,.icons-unavailable .icon-button:empty{display:none}
-.unsaved-leave-guard{position:fixed;z-index:140;inset:0;display:grid;place-items:center;padding:24px;background:rgba(16,24,40,.5)}.leave-guard-card{width:min(520px,100%);box-shadow:0 28px 90px rgba(16,24,40,.28)}
-.alert-row strong,.platform-activity p{font-size:13px;line-height:20px}.platform-activity p strong{font-size:13px}.tenant-health p strong{font-size:13px}.failure-panel article strong{font-size:13px}.failure-panel article p{font-size:12px;line-height:18px}
-.platform-activity>div>span,#sideNav b{font-size:12px!important}.platform-foot>div>span{font-size:13px!important}.mobile-boundary{display:grid;grid-template-columns:48px 1fr;align-items:start;gap:14px;padding:22px}.mobile-boundary>span{width:46px;height:46px;display:grid;place-items:center;background:var(--blue-100);color:var(--blue)}.mobile-boundary strong{font-size:15px}.mobile-boundary p{margin:6px 0 0;color:var(--muted);font-size:13px;line-height:20px}
-.tenant-cell>span,.staff-row>span{font-size:12px!important}.tenant-cell strong{font-size:13px!important;line-height:20px}
-.sidebar-backdrop{display:none;position:fixed;z-index:29;inset:0;border:0;background:rgba(16,24,40,.42)}
-@media(max-width:1320px){.prototype-controls label span{display:none}.prototype-controls select{max-width:105px}.detail-summary{grid-template-columns:repeat(3,1fr)}.detail-summary>div:nth-child(3){border-right:0}.detail-summary>div:nth-child(-n+3){border-bottom:1px solid var(--line)}}
-@media(max-width:1050px){.prototype-controls{display:none}.detail-grid{grid-template-columns:1fr}.timeline{grid-template-columns:1fr}.timeline p{padding-bottom:16px;border-top:0;border-left:2px solid var(--line)}.timeline p:before{top:0;left:-7px}.timeline b{padding-top:0}.detail-summary{grid-template-columns:1fr 1fr}.detail-summary>div:nth-child(3){border-right:1px solid var(--line)}.detail-summary>div:nth-child(even){border-right:0}.detail-summary>div{border-bottom:1px solid var(--line)}}
-@media(max-width:900px){body.menu-locked{overflow:hidden}.platform-app.menu-open+.sidebar-backdrop{display:block}.modal-backdrop{padding:0}.modal,.modal.is-wide{width:100%;height:100%;max-height:none}.modal>header{padding:16px}.modal>footer{padding:12px 14px}.form-grid,.modal-form .form-grid,.modal-detail,.permission-grid{grid-template-columns:1fr}.form-grid label.wide,.modal-detail .wide{grid-column:auto}.form-actions{position:static;bottom:auto;z-index:auto;flex-wrap:wrap}.form-actions>span{width:100%;margin:0}.row-action,.switch{position:relative;width:44px;height:44px;flex:0 0 44px}.row-action{background:transparent}.row-action:before{content:"";position:absolute;inset:8px;background:transparent}.row-action:hover{background:transparent}.row-action:hover:before{background:var(--blue-100)}.row-action svg{position:relative;z-index:1}.switch{display:grid;place-items:center;padding:0;border-radius:0;background:transparent}.switch:before{content:"";position:absolute;left:6px;top:13px;width:32px;height:18px;border-radius:9px;background:#d0d5dd}.switch i{position:relative;z-index:1;transform:translateX(-7px)}.switch.is-on{background:transparent}.switch.is-on:before{background:var(--blue)}.switch.is-on i{transform:translateX(7px)}.detail-summary{grid-template-columns:1fr 1fr}.collection-console article{grid-template-columns:34px minmax(0,1fr)}.collection-console article>b,.collection-console article>.inline-actions{grid-column:2}.platform-topbar{overflow:hidden}.platform-search{min-width:0}}
-@media(max-width:900px){.unsaved-leave-guard{padding:0;align-items:end}.unsaved-leave-guard .modal{width:100%;height:auto;max-height:100vh}.leave-guard-card footer{flex-wrap:wrap}.leave-guard-card footer .button{min-height:44px;flex:1}}
-@media(max-width:560px){.detail-summary{grid-template-columns:1fr}.detail-summary>div{border-right:0!important}.page-head.is-subpage>div:last-child{display:none}.modal>footer{overflow:auto;justify-content:flex-start}.modal>footer .button{white-space:nowrap}.form-actions .button{flex:1;min-width:0;white-space:nowrap}.alert-layout,.channel-panel,.panel{min-width:0}.panel-head{align-items:flex-start;flex-wrap:wrap;padding-block:12px}.panel-head>.filter-segment{max-width:100%;overflow:auto}.security-alert{grid-template-columns:38px minmax(0,1fr)}.security-alert .inline-actions{grid-column:2;flex-wrap:wrap;min-width:0}.security-alert .inline-actions .button{min-width:0;white-space:normal}.task-list article{grid-template-columns:34px 1fr}.task-list article>.button,.task-list article>.status{grid-column:2;width:max-content}.evidence-head{grid-template-columns:40px 1fr}.evidence-head>.status{grid-column:2;width:max-content}.top-status .icon-button:first-of-type{display:grid}.staff-row{grid-template-columns:32px minmax(0,1fr) auto}.staff-row>b,.staff-row>em,.staff-row>i{display:none}.mobile-boundary{grid-template-columns:1fr}.mobile-boundary>span{width:44px;height:44px}}
-.contract-result{display:grid;grid-template-columns:24px minmax(0,1fr);align-items:center;gap:10px;margin:0 0 12px;padding:10px 12px;border:1px solid #b7e4c7;background:#f2fbf5;color:#17663a}.contract-result>svg{width:18px}.contract-result>span{display:grid;gap:3px}.contract-result strong{font-size:13px}.contract-result small{color:#52705f;font-size:12px;line-height:18px}.contract-result.is-loading{border-color:#bfd0ff;background:var(--blue-50);color:var(--blue)}.contract-result.is-loading>svg{animation:spin 1s linear infinite}.contract-result.is-error{border-color:#ffb4ae;background:#fff0ef;color:#b42318}.contract-result.is-error small{color:#8f2d25}.candidate-list label:has(>.button){grid-template-columns:20px minmax(0,1fr) auto}.alert-rules{margin-bottom:12px}.alert-rules .panel-head code{max-width:46%;overflow:hidden;color:var(--muted);font-size:12px;text-overflow:ellipsis;white-space:nowrap}.rule-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr))}.rule-grid article{min-height:106px;display:grid;grid-template-columns:42px minmax(0,1fr) auto;align-items:start;gap:10px;padding:16px;border-right:1px solid var(--line);border-top:1px solid var(--line)}.rule-grid article:last-child{border-right:0}.rule-grid article>div{display:grid;gap:5px}.rule-grid strong{font-size:13px}.rule-grid small,.rule-grid p{margin:0;color:var(--muted);font-size:12px;line-height:18px}.tree-empty{padding:18px;color:var(--muted);font-size:13px;text-align:center}
-@media(max-width:1050px){.rule-grid{grid-template-columns:1fr}.rule-grid article{border-right:0}.candidate-list label:has(>.button){grid-template-columns:20px minmax(0,1fr)}.candidate-list label>.button{grid-column:2;width:max-content}}
-/* Real API authentication gate. Tokens are held in sessionStorage by platform-auth.js. */
-.platform-auth-gate { position: fixed; inset: 0; z-index: 10000; display: grid; place-items: center; padding: 24px; background: radial-gradient(circle at 20% 10%, #17345f 0, #0b1220 42%, #060a12 100%); color: #e5e7eb; }
-.platform-auth-gate[hidden] { display: none; }
-.platform-auth-card { width: min(460px, 100%); padding: 32px; border: 1px solid rgba(148,163,184,.22); border-radius: 18px; background: rgba(15,23,42,.96); box-shadow: 0 24px 80px rgba(0,0,0,.45); }
-.platform-auth-card header { display: flex; gap: 14px; align-items: center; margin-bottom: 26px; }
-.platform-auth-card header img { width: 44px; height: 44px; border-radius: 12px; }
-.platform-auth-card h1 { margin: 0; font-size: 22px; }
-.platform-auth-card header p, .platform-auth-card .auth-help { margin: 5px 0 0; color: #94a3b8; font-size: 13px; line-height: 1.6; }
-.platform-auth-card form { display: grid; gap: 16px; }
-.platform-auth-card label { display: grid; gap: 7px; color: #cbd5e1; font-size: 13px; }
-.platform-auth-card input { width: 100%; box-sizing: border-box; padding: 11px 12px; border: 1px solid #334155; border-radius: 9px; background: #0b1220; color: #f8fafc; font: inherit; }
-.platform-auth-card input:focus { outline: 2px solid #3b82f6; outline-offset: 1px; }
-.platform-auth-card button { width: 100%; min-height: 42px; margin-top: 14px; border: 0; border-radius: 9px; background: #2563eb; color: white; font: inherit; font-weight: 700; cursor: pointer; }
-.platform-auth-card button:disabled { opacity: .55; cursor: wait; }
-.platform-auth-error { min-height: 20px; margin: 14px 0 0; color: #fca5a5; font-size: 13px; }
diff --git a/Tiku.IntegrationTests/Api/PlatformAdminFrontendSeparationTests.cs b/Tiku.IntegrationTests/Api/PlatformAdminFrontendSeparationTests.cs
new file mode 100644
index 0000000..0900e8d
--- /dev/null
+++ b/Tiku.IntegrationTests/Api/PlatformAdminFrontendSeparationTests.cs
@@ -0,0 +1,23 @@
+using System.Net;
+
+namespace Tiku.IntegrationTests.Api;
+
+public sealed class PlatformAdminFrontendSeparationTests
+{
+ [Theory]
+ [InlineData("/platform-admin")]
+ [InlineData("/platform-admin/")]
+ [InlineData("/platform-admin/app.js")]
+ public async Task WebApi_does_not_host_platform_admin_frontend(string path)
+ {
+ await using var factory = new ApiTestFactory();
+ using var client = factory.CreateClient(new()
+ {
+ AllowAutoRedirect = false
+ });
+
+ using var response = await client.GetAsync(path);
+
+ Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
+ }
+}
diff --git a/Tiku.IntegrationTests/Api/PlatformAdminStaticEndpointTests.cs b/Tiku.IntegrationTests/Api/PlatformAdminStaticEndpointTests.cs
deleted file mode 100644
index 0579a4a..0000000
--- a/Tiku.IntegrationTests/Api/PlatformAdminStaticEndpointTests.cs
+++ /dev/null
@@ -1,117 +0,0 @@
-using System.Net;
-
-namespace Tiku.IntegrationTests.Api;
-
-public sealed class PlatformAdminStaticEndpointTests
-{
- [Fact]
- public async Task Platform_admin_static_shell_is_served_without_api_authentication()
- {
- await using var factory = new ApiTestFactory();
- using var client = factory.CreateClient();
-
- var response = await client.GetAsync("/platform-admin/");
- var body = await response.Content.ReadAsStringAsync();
-
- Assert.Equal(HttpStatusCode.OK, response.StatusCode);
- Assert.Contains("恭学题库 SaaS · 平台管理", body, StringComparison.Ordinal);
- Assert.Contains("./platform-api.js", body, StringComparison.Ordinal);
- Assert.Contains("./platform-auth.js", body, StringComparison.Ordinal);
- Assert.Contains("platformAuthGate", body, StringComparison.Ordinal);
- }
-
- [Fact]
- public async Task Platform_admin_short_path_redirects_to_static_shell_directory()
- {
- await using var factory = new ApiTestFactory();
- using var client = factory.CreateClient(new()
- {
- AllowAutoRedirect = false
- });
-
- var response = await client.GetAsync("/platform-admin");
-
- Assert.Equal(HttpStatusCode.MovedPermanently, response.StatusCode);
- Assert.Equal("/platform-admin/", response.Headers.Location?.AbsolutePath);
- }
-
- [Fact]
- public async Task Platform_admin_runtime_uses_real_api_without_mock_fallback()
- {
- await using var factory = new ApiTestFactory();
- using var client = factory.CreateClient();
-
- var runtime = await client.GetStringAsync("/platform-admin/runtime-config.js");
- var authentication = await client.GetStringAsync("/platform-admin/platform-auth.js");
-
- Assert.Contains("mode: 'api'", runtime, StringComparison.Ordinal);
- Assert.Contains("fallbackToMock: false", runtime, StringComparison.Ordinal);
- Assert.Contains("/api/auth/login/password", authentication, StringComparison.Ordinal);
- Assert.Contains("/api/auth/password/change-required", authentication, StringComparison.Ordinal);
- Assert.DoesNotContain("/api/auth/mfa", authentication, StringComparison.Ordinal);
- }
-
- [Fact]
- public async Task Platform_admin_shell_covers_current_platform_capabilities_and_dto_fields()
- {
- await using var factory = new ApiTestFactory();
- using var client = factory.CreateClient();
-
- var application = await client.GetStringAsync("/platform-admin/app.js");
- var api = await client.GetStringAsync("/platform-admin/platform-api.js");
- var contract = await client.GetStringAsync("/platform-admin/spec-contract.js");
-
- Assert.Contains("租户域名与证书", application, StringComparison.Ordinal);
- Assert.Contains("SaaS 商品与版本", application, StringComparison.Ordinal);
- Assert.Contains("SaaS 订单与交易", application, StringComparison.Ordinal);
- Assert.Contains("平台角色与功能", application, StringComparison.Ordinal);
- Assert.Contains("function businessStatusLabel(value)", application, StringComparison.Ordinal);
- Assert.Contains("function backendStatusLabel()", application, StringComparison.Ordinal);
- Assert.DoesNotContain("业务功能名称和中文说明", application, StringComparison.Ordinal);
- Assert.DoesNotContain("中文说明", application, StringComparison.Ordinal);
- Assert.DoesNotContain("API 契约", application, StringComparison.Ordinal);
- Assert.Contains("/api/backoffice/platform/bootstrap", contract, StringComparison.Ordinal);
- Assert.Contains("/api/platform-admin/payment-settings/channels", contract, StringComparison.Ordinal);
- Assert.Contains("/api/platform-admin/tenant-capabilities/crm/logs", contract, StringComparison.Ordinal);
- Assert.Contains("userId: input.userId", api, StringComparison.Ordinal);
- Assert.Contains("roleIds: input.roleIds", api, StringComparison.Ordinal);
- Assert.Contains("resolutionNote: input.resolutionNote", api, StringComparison.Ordinal);
- Assert.Contains("platformPermissionLabels[item.code]", api, StringComparison.Ordinal);
- Assert.Contains("'platform:role:manage': '管理平台角色与权限'", api, StringComparison.Ordinal);
- Assert.DoesNotContain("authUserId: input.authUserId", api, StringComparison.Ordinal);
- Assert.DoesNotContain("platformPermissions:", api, StringComparison.Ordinal);
- Assert.DoesNotContain("staffId: input.staffId", api, StringComparison.Ordinal);
- }
-
- [Fact]
- public async Task Platform_question_bank_workspace_loads_cache_busted_scripts_and_real_api_bindings()
- {
- await using var factory = new ApiTestFactory();
- using var client = factory.CreateClient();
-
- var shell = await client.GetStringAsync("/platform-admin/");
- var application = await client.GetStringAsync("/platform-admin/app.js");
- var api = await client.GetStringAsync("/platform-admin/platform-api.js");
- var contract = await client.GetStringAsync("/platform-admin/spec-contract.js");
-
- Assert.Contains("app.js?v=20260730-question-bank1", shell, StringComparison.Ordinal);
- Assert.Contains("platform-api.js?v=20260730-question-bank1", shell, StringComparison.Ordinal);
- Assert.Contains("spec-contract.js?v=20260730-question-bank1", shell, StringComparison.Ordinal);
- Assert.Contains("operationId: 'PlatformQuestionBanksController_upsertBank'", application, StringComparison.Ordinal);
- Assert.Contains("operationId: 'PlatformQuestionBanksController_upsertNode'", application, StringComparison.Ordinal);
- Assert.Contains("operationId: 'PlatformQuestionBanksController_upsertQuestion'", application, StringComparison.Ordinal);
- Assert.Contains("PlatformQuestionBanksController_archiveQuestions", application, StringComparison.Ordinal);
- Assert.Contains("PlatformQuestionBanksController_archiveNode", application, StringComparison.Ordinal);
- Assert.Contains("PlatformQuestionBanksController_archiveBank", application, StringComparison.Ordinal);
- Assert.Contains("data-action=\"shift-bank-node\"", application, StringComparison.Ordinal);
- Assert.Contains("PlatformQuestionBanksController_signAssetUpload", application, StringComparison.Ordinal);
- Assert.Contains("PlatformQuestionBanksController_confirmAssetUpload", application, StringComparison.Ordinal);
- Assert.Contains("PlatformQuestionBanksController_upsertBank(input)", api, StringComparison.Ordinal);
- Assert.Contains("PlatformQuestionBanksController_upsertQuestion(input)", api, StringComparison.Ordinal);
- Assert.Contains("PlatformQuestionBanksController_executeImport(input)", api, StringComparison.Ordinal);
- Assert.Contains("['P-09', 'PlatformQuestionBanksController_upsertBank', 'PUT', '/api/platform-admin/question-banks']", contract, StringComparison.Ordinal);
- Assert.Contains("['P-09', 'PlatformQuestionBanksController_executeImport', 'POST', '/api/platform-admin/question-banks/imports']", contract, StringComparison.Ordinal);
- Assert.DoesNotContain("question_bank:grant", application, StringComparison.Ordinal);
- Assert.DoesNotContain("question_bank:ops", application, StringComparison.Ordinal);
- }
-}
diff --git a/Tiku.PlatformAdmin.Web/.env.example b/Tiku.PlatformAdmin.Web/.env.example
new file mode 100644
index 0000000..0458ce6
--- /dev/null
+++ b/Tiku.PlatformAdmin.Web/.env.example
@@ -0,0 +1,2 @@
+VITE_API_BASE_URL=http://localhost:5090
+OPENAPI_URL=http://localhost:5090/openapi/v1.json
diff --git a/Tiku.PlatformAdmin.Web/.gitignore b/Tiku.PlatformAdmin.Web/.gitignore
new file mode 100644
index 0000000..b813019
--- /dev/null
+++ b/Tiku.PlatformAdmin.Web/.gitignore
@@ -0,0 +1,5 @@
+node_modules/
+dist/
+.generated/
+.env.local
+*.log
diff --git a/Tiku.PlatformAdmin.Web/README.md b/Tiku.PlatformAdmin.Web/README.md
new file mode 100644
index 0000000..5c93c53
--- /dev/null
+++ b/Tiku.PlatformAdmin.Web/README.md
@@ -0,0 +1,25 @@
+# Tiku 平台管理前端
+
+独立部署的 React + TypeScript 平台管理端。业务接口契约只从 `Tiku.Api` 实时 OpenAPI 文档生成,不依赖旧静态前端的接口适配代码。
+
+## 本地开发
+
+首次使用先安装前端依赖:
+
+```bash
+npm install
+```
+
+之后从仓库根目录运行 `dotnet run --project Tiku.Api`,ASP.NET Core 的开发代理会自动启动本工程的 Vite 服务。访问 。开发服务器默认代理 `/api` 到 `http://localhost:5090`;需要修改目标时设置 `VITE_DEV_API_TARGET`。
+
+也可以在本目录单独执行 `npm run dev`,便于只调试前端。Production 环境不会由 API 启动 Node 进程,前端仍应独立构建和部署。
+
+## 接口契约
+
+```bash
+OPENAPI_URL=http://localhost:5090/openapi/v1.json npm run generate:api
+```
+
+生成结果包括完整 OpenAPI TypeScript 类型,以及全部 `/api/platform-admin/**`、`/api/backoffice/platform/**` 接口的页面操作元数据。`npm test` 会验证每个后端平台接口都已归入且只归入一个页面组。
+
+生产部署通过 `VITE_API_BASE_URL` 指定 API 地址;同域反向代理时可以留空。
diff --git a/Tiku.PlatformAdmin.Web/index.html b/Tiku.PlatformAdmin.Web/index.html
new file mode 100644
index 0000000..c2eed97
--- /dev/null
+++ b/Tiku.PlatformAdmin.Web/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ 恭学题库 SaaS · 平台管理
+
+
+
+
+
+
diff --git a/Tiku.PlatformAdmin.Web/package-lock.json b/Tiku.PlatformAdmin.Web/package-lock.json
new file mode 100644
index 0000000..3d0644f
--- /dev/null
+++ b/Tiku.PlatformAdmin.Web/package-lock.json
@@ -0,0 +1,3534 @@
+{
+ "name": "@tiku/platform-admin",
+ "version": "0.1.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "@tiku/platform-admin",
+ "version": "0.1.0",
+ "dependencies": {
+ "@ant-design/icons": "^6.0.1",
+ "antd": "6.5.0",
+ "react": "^19.2.0",
+ "react-dom": "^19.2.0",
+ "react-router": "^8.3.0"
+ },
+ "devDependencies": {
+ "@types/node": "^24.10.0",
+ "@types/react": "^19.2.2",
+ "@types/react-dom": "^19.2.2",
+ "@vitejs/plugin-react": "^5.1.1",
+ "openapi-typescript": "^7.10.1",
+ "typescript": "^5.9.3",
+ "vite": "^7.2.2",
+ "vitest": "^4.0.8"
+ }
+ },
+ "node_modules/@ant-design/colors": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/@ant-design/colors/-/colors-8.0.1.tgz",
+ "integrity": "sha512-foPVl0+SWIslGUtD/xBr1p9U4AKzPhNYEseXYRRo5QSzGACYZrQbe11AYJbYfAWnWSpGBx6JjBmSeugUsD9vqQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@ant-design/fast-color": "^3.0.0"
+ }
+ },
+ "node_modules/@ant-design/cssinjs": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/@ant-design/cssinjs/-/cssinjs-2.1.2.tgz",
+ "integrity": "sha512-2Hy8BnCEH31xPeSLbhhB2ctCPXE2ZnASdi+KbSeS79BNbUhL9hAEe20SkUk+BR8aKTmqb6+FKFruk7w8z0VoRQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.11.1",
+ "@emotion/hash": "^0.8.0",
+ "@emotion/unitless": "^0.7.5",
+ "@rc-component/util": "^1.4.0",
+ "clsx": "^2.1.1",
+ "csstype": "^3.1.3",
+ "stylis": "^4.3.4"
+ },
+ "peerDependencies": {
+ "react": ">=16.0.0",
+ "react-dom": ">=16.0.0"
+ }
+ },
+ "node_modules/@ant-design/cssinjs-utils": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/@ant-design/cssinjs-utils/-/cssinjs-utils-2.1.2.tgz",
+ "integrity": "sha512-5fTHQ158jJJ5dC/ECeyIdZUzKxE/mpEMRZxthyG1sw/AKRHKgJBg00Yi6ACVXgycdje7KahRNvNET/uBccwCnA==",
+ "license": "MIT",
+ "dependencies": {
+ "@ant-design/cssinjs": "^2.1.2",
+ "@babel/runtime": "^7.23.2",
+ "@rc-component/util": "^1.4.0"
+ },
+ "peerDependencies": {
+ "react": ">=18",
+ "react-dom": ">=18"
+ }
+ },
+ "node_modules/@ant-design/fast-color": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@ant-design/fast-color/-/fast-color-3.0.1.tgz",
+ "integrity": "sha512-esKJegpW4nckh0o6kV3Tkb7NPIZYbPnnFxmQDUmL08ukXZAvV85TZBr70eGuke/CIArLaP6aw8lt9KILjnWuOw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.x"
+ }
+ },
+ "node_modules/@ant-design/icons": {
+ "version": "6.3.2",
+ "resolved": "https://registry.npmjs.org/@ant-design/icons/-/icons-6.3.2.tgz",
+ "integrity": "sha512-B6O5a5XJ4wjtNOfZejXYwHW5zvKV5gYkjGf11dHGLEbKn0ABDGndo41+gfIiXyTFhvESj4XTotuud33mUFid0g==",
+ "license": "MIT",
+ "dependencies": {
+ "@ant-design/colors": "^8.0.1",
+ "@ant-design/icons-svg": "^4.5.0",
+ "@rc-component/util": "^1.11.0",
+ "clsx": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "peerDependencies": {
+ "react": ">=16.0.0",
+ "react-dom": ">=16.0.0"
+ }
+ },
+ "node_modules/@ant-design/icons-svg": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/@ant-design/icons-svg/-/icons-svg-4.5.0.tgz",
+ "integrity": "sha512-1BTUFyKPTBZ53MuTP8s0k5SFEXL7o3VHEOwLgzaoWKwnBeqIcqUtVshc4SKzhI6uACfqhJqBwBUE9FsWR3uULA==",
+ "license": "MIT"
+ },
+ "node_modules/@ant-design/react-slick": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@ant-design/react-slick/-/react-slick-2.0.0.tgz",
+ "integrity": "sha512-HMS9sRoEmZey8LsE/Yo6+klhlzU12PisjrVcydW3So7RdklyEd2qehyU6a7Yp+OYN72mgsYs3NFCyP2lCPFVqg==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.28.4",
+ "clsx": "^2.1.1",
+ "json2mq": "^0.2.0",
+ "throttle-debounce": "^5.0.0"
+ },
+ "peerDependencies": {
+ "react": "^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
+ "react-dom": "^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
+ }
+ },
+ "node_modules/@babel/code-frame": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz",
+ "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.29.7",
+ "js-tokens": "^4.0.0",
+ "picocolors": "^1.1.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/compat-data": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.7.tgz",
+ "integrity": "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/core": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz",
+ "integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.29.7",
+ "@babel/generator": "^7.29.7",
+ "@babel/helper-compilation-targets": "^7.29.7",
+ "@babel/helper-module-transforms": "^7.29.7",
+ "@babel/helpers": "^7.29.7",
+ "@babel/parser": "^7.29.7",
+ "@babel/template": "^7.29.7",
+ "@babel/traverse": "^7.29.7",
+ "@babel/types": "^7.29.7",
+ "@jridgewell/remapping": "^2.3.5",
+ "convert-source-map": "^2.0.0",
+ "debug": "^4.1.0",
+ "gensync": "^1.0.0-beta.2",
+ "json5": "^2.2.3",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/babel"
+ }
+ },
+ "node_modules/@babel/generator": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.7.tgz",
+ "integrity": "sha512-DkXD5OJQaAQIdZ1bt3UZdEnHAn9Imd3IVBdX03UFe+ony9Ojw5pzr9YVKGDY1jt+Gcn/FnGkNf8r+Vj5NOJWtQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.29.7",
+ "@babel/types": "^7.29.7",
+ "@jridgewell/gen-mapping": "^0.3.12",
+ "@jridgewell/trace-mapping": "^0.3.28",
+ "jsesc": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-compilation-targets": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz",
+ "integrity": "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/compat-data": "^7.29.7",
+ "@babel/helper-validator-option": "^7.29.7",
+ "browserslist": "^4.24.0",
+ "lru-cache": "^5.1.1",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-globals": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz",
+ "integrity": "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-imports": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz",
+ "integrity": "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/traverse": "^7.29.7",
+ "@babel/types": "^7.29.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-transforms": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz",
+ "integrity": "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-module-imports": "^7.29.7",
+ "@babel/helper-validator-identifier": "^7.29.7",
+ "@babel/traverse": "^7.29.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-plugin-utils": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.29.7.tgz",
+ "integrity": "sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-string-parser": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz",
+ "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-identifier": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz",
+ "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-option": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz",
+ "integrity": "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helpers": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.7.tgz",
+ "integrity": "sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/template": "^7.29.7",
+ "@babel/types": "^7.29.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/parser": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.7.tgz",
+ "integrity": "sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.29.7"
+ },
+ "bin": {
+ "parser": "bin/babel-parser.js"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-react-jsx-self": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.29.7.tgz",
+ "integrity": "sha512-TL0hMc9xzy86VD31nUiwzd5otRAcyEPcsegCxolO0PvcXuH1v0kECe/UIznYFihpkvU5wg/jk4v0TTEFfm53fw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.29.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-react-jsx-source": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.29.7.tgz",
+ "integrity": "sha512-06IyK09H3wi4cGbhDBwp5gUGo0IKtnYa8tyTiephirPCK6fbobVGiXMMI5zLQ4aKEYP3wZ3ArU44o+8KMrSG/Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.29.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/runtime": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.7.tgz",
+ "integrity": "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/template": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz",
+ "integrity": "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.29.7",
+ "@babel/parser": "^7.29.7",
+ "@babel/types": "^7.29.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/traverse": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.7.tgz",
+ "integrity": "sha512-EhlfNQtZ+NK22w5BM61ciuiq1m58ed33Wr1Xan//ZRTy6hgjnwyCffRYwzsGXdASJSUJ1guZILsErh1eQcl+zw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.29.7",
+ "@babel/generator": "^7.29.7",
+ "@babel/helper-globals": "^7.29.7",
+ "@babel/parser": "^7.29.7",
+ "@babel/template": "^7.29.7",
+ "@babel/types": "^7.29.7",
+ "debug": "^4.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/types": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.7.tgz",
+ "integrity": "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-string-parser": "^7.29.7",
+ "@babel/helper-validator-identifier": "^7.29.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@emotion/hash": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.8.0.tgz",
+ "integrity": "sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==",
+ "license": "MIT"
+ },
+ "node_modules/@emotion/unitless": {
+ "version": "0.7.5",
+ "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz",
+ "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==",
+ "license": "MIT"
+ },
+ "node_modules/@esbuild/aix-ppc64": {
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.1.tgz",
+ "integrity": "sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "aix"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-arm": {
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.1.tgz",
+ "integrity": "sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-arm64": {
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.1.tgz",
+ "integrity": "sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-x64": {
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.1.tgz",
+ "integrity": "sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/darwin-arm64": {
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.1.tgz",
+ "integrity": "sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/darwin-x64": {
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.1.tgz",
+ "integrity": "sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.1.tgz",
+ "integrity": "sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/freebsd-x64": {
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.1.tgz",
+ "integrity": "sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-arm": {
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.1.tgz",
+ "integrity": "sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-arm64": {
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.1.tgz",
+ "integrity": "sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-ia32": {
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.1.tgz",
+ "integrity": "sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-loong64": {
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.1.tgz",
+ "integrity": "sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-mips64el": {
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.1.tgz",
+ "integrity": "sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==",
+ "cpu": [
+ "mips64el"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-ppc64": {
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.1.tgz",
+ "integrity": "sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-riscv64": {
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.1.tgz",
+ "integrity": "sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-s390x": {
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.1.tgz",
+ "integrity": "sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-x64": {
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.1.tgz",
+ "integrity": "sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/netbsd-arm64": {
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.1.tgz",
+ "integrity": "sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/netbsd-x64": {
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.1.tgz",
+ "integrity": "sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openbsd-arm64": {
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.1.tgz",
+ "integrity": "sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openbsd-x64": {
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.1.tgz",
+ "integrity": "sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openharmony-arm64": {
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.1.tgz",
+ "integrity": "sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openharmony"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/sunos-x64": {
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.1.tgz",
+ "integrity": "sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-arm64": {
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.1.tgz",
+ "integrity": "sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-ia32": {
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.1.tgz",
+ "integrity": "sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-x64": {
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.1.tgz",
+ "integrity": "sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@jridgewell/gen-mapping": {
+ "version": "0.3.13",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
+ "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.5.0",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ }
+ },
+ "node_modules/@jridgewell/remapping": {
+ "version": "2.3.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz",
+ "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ }
+ },
+ "node_modules/@jridgewell/resolve-uri": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
+ "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.5.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
+ "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.31",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
+ "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/resolve-uri": "^3.1.0",
+ "@jridgewell/sourcemap-codec": "^1.4.14"
+ }
+ },
+ "node_modules/@rc-component/async-validator": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/@rc-component/async-validator/-/async-validator-6.0.0.tgz",
+ "integrity": "sha512-D3AGQwdyE58gmvx6waVSXJ80JGO+IY5L2O8HDnSOex7JNlzB3GuN/4hyHNTdhy2qtOhkpbIjmeAN3tL993wKbA==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.24.4"
+ },
+ "engines": {
+ "node": ">=14.x"
+ }
+ },
+ "node_modules/@rc-component/cascader": {
+ "version": "1.17.0",
+ "resolved": "https://registry.npmjs.org/@rc-component/cascader/-/cascader-1.17.0.tgz",
+ "integrity": "sha512-3cVNG0zrQF1PoXq262L3wGCU+/YLEC1mGSVHDl577dQmA0ZKkXFbY6nwyXo+beCcM7buo49t24jkr+QZdL7O8w==",
+ "license": "MIT",
+ "dependencies": {
+ "@rc-component/select": "~1.8.0",
+ "@rc-component/tree": "~1.3.2",
+ "@rc-component/util": "^1.11.1",
+ "clsx": "^2.1.1"
+ },
+ "peerDependencies": {
+ "react": ">=18.0.0",
+ "react-dom": ">=18.0.0"
+ }
+ },
+ "node_modules/@rc-component/checkbox": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@rc-component/checkbox/-/checkbox-2.0.0.tgz",
+ "integrity": "sha512-3CXGPpAR9gsPKeO2N78HAPOzU30UdemD6HGJoWVJOpa6WleaGB5kzZj3v6bdTZab31YuWgY/RxV3VKPctn0DwQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@rc-component/util": "^1.3.0",
+ "clsx": "^2.1.1"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/@rc-component/collapse": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@rc-component/collapse/-/collapse-1.2.0.tgz",
+ "integrity": "sha512-ZRYSKSS39qsFx93p26bde7JUZJshsUBEQRlRXPuJYlAiNX0vyYlF5TsAm8JZN3LcF8XvKikdzPbgAtXSbkLUkw==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.10.1",
+ "@rc-component/motion": "^1.1.4",
+ "@rc-component/util": "^1.3.0",
+ "clsx": "^2.1.1"
+ },
+ "peerDependencies": {
+ "react": ">=18.0.0",
+ "react-dom": ">=18.0.0"
+ }
+ },
+ "node_modules/@rc-component/color-picker": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/@rc-component/color-picker/-/color-picker-3.1.1.tgz",
+ "integrity": "sha512-OHaCHLHszCegdXmIq2ZRIZBN/EtpT6Wm8SG/gpzLATHbVKc/avvuKi+zlOuk05FTWvgaMmpxAko44uRJ3M+2pg==",
+ "license": "MIT",
+ "dependencies": {
+ "@ant-design/fast-color": "^3.0.1",
+ "@rc-component/util": "^1.3.0",
+ "clsx": "^2.1.1"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/@rc-component/context": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/@rc-component/context/-/context-2.0.2.tgz",
+ "integrity": "sha512-uiGpAlblCNlziHPwj4S4Iy/oemeuz/hR03mbiEjTCXwsqOIN3BOzsRMyDwpyO5Fm0vIEEJRUf9ZtbRLbhksuTA==",
+ "license": "MIT",
+ "dependencies": {
+ "@rc-component/util": "^1.11.0"
+ },
+ "peerDependencies": {
+ "react": ">=18.0.0",
+ "react-dom": ">=18.0.0"
+ }
+ },
+ "node_modules/@rc-component/dialog": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/@rc-component/dialog/-/dialog-1.10.0.tgz",
+ "integrity": "sha512-eDukNlz9vNszAGv7i3zKXdxEd3wgVmNxuJijYt8zvTh17QwTu8KK/bdURRd/lU4qaMzhO1HKKmMrwOnkaw0BvQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@rc-component/motion": "^1.3.3",
+ "@rc-component/portal": "^2.1.0",
+ "@rc-component/util": "^1.9.0",
+ "clsx": "^2.1.1"
+ },
+ "peerDependencies": {
+ "react": ">=18.0.0",
+ "react-dom": ">=18.0.0"
+ }
+ },
+ "node_modules/@rc-component/drawer": {
+ "version": "1.4.2",
+ "resolved": "https://registry.npmjs.org/@rc-component/drawer/-/drawer-1.4.2.tgz",
+ "integrity": "sha512-1ib+fZEp6FBu+YvcIktm+nCQ+Q+qIpwpoaJH6opGr4ofh2QMq+qdr5DLC4oCf5qf3pcWX9lUWPYX652k4ini8Q==",
+ "license": "MIT",
+ "dependencies": {
+ "@rc-component/motion": "^1.1.4",
+ "@rc-component/portal": "^2.1.3",
+ "@rc-component/util": "^1.9.0",
+ "clsx": "^2.1.1"
+ },
+ "peerDependencies": {
+ "react": ">=18.0.0",
+ "react-dom": ">=18.0.0"
+ }
+ },
+ "node_modules/@rc-component/dropdown": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@rc-component/dropdown/-/dropdown-1.0.3.tgz",
+ "integrity": "sha512-YTST/N6kpqpDz3IMuM/PSSZnrDpSOA6dgHv12gPA90ZTSLv2CoqkZ0+9NtwTY6BeO7dstPblSic2QJg7dSFy/g==",
+ "license": "MIT",
+ "dependencies": {
+ "@rc-component/trigger": "^3.0.0",
+ "@rc-component/util": "^1.11.1",
+ "clsx": "^2.1.1"
+ },
+ "peerDependencies": {
+ "react": ">=16.11.0",
+ "react-dom": ">=16.11.0"
+ }
+ },
+ "node_modules/@rc-component/form": {
+ "version": "1.8.6",
+ "resolved": "https://registry.npmjs.org/@rc-component/form/-/form-1.8.6.tgz",
+ "integrity": "sha512-1EXVsSKPZC6kGrIqxVck7kAWM6T65b6et/n5wIcyiaIa41VrDshD0nVLHoBDEIZr2ATQsOP6icb4XQkNFMLBAw==",
+ "license": "MIT",
+ "dependencies": {
+ "@rc-component/async-validator": "^6.0.0",
+ "@rc-component/util": "^1.11.1",
+ "clsx": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=8.x"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/@rc-component/image": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@rc-component/image/-/image-1.9.0.tgz",
+ "integrity": "sha512-khF7w7xkBH5B1bsBcI1FSUZdkyd1aqpl2eYyILCqCzzQH3XdfehGUaZTnptyaJJfs09/R5hv9jXWyazOMFIClQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@rc-component/motion": "^1.0.0",
+ "@rc-component/portal": "^2.1.2",
+ "@rc-component/util": "^1.10.1",
+ "clsx": "^2.1.1"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/@rc-component/input": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/@rc-component/input/-/input-1.3.1.tgz",
+ "integrity": "sha512-iFvTUT9W+JC/MSin2aGAk8NqsVlTzcExNC9DZariON1IWirju9NoNeEk47an4Q8iHazkoVI/y1LnDi88+CPcig==",
+ "license": "MIT",
+ "dependencies": {
+ "@rc-component/resize-observer": "^1.1.1",
+ "@rc-component/util": "^1.11.1",
+ "clsx": "^2.1.1"
+ },
+ "peerDependencies": {
+ "react": ">=16.0.0",
+ "react-dom": ">=16.0.0"
+ }
+ },
+ "node_modules/@rc-component/input-number": {
+ "version": "1.6.2",
+ "resolved": "https://registry.npmjs.org/@rc-component/input-number/-/input-number-1.6.2.tgz",
+ "integrity": "sha512-Gjcq7meZlCOiWN1t1xCC+7/s85humHVokTBI7PJgTfoyw5OWF74y3e6P8PHX104g9+b54jsodFIzyaj6p8LI9w==",
+ "license": "MIT",
+ "dependencies": {
+ "@rc-component/mini-decimal": "^1.0.1",
+ "@rc-component/util": "^1.4.0",
+ "clsx": "^2.1.1"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/@rc-component/mentions": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/@rc-component/mentions/-/mentions-1.10.0.tgz",
+ "integrity": "sha512-CI1njYUVY0NjHtLhNoVmXlJyy568Sfep9Wsak6vmGjtT6uazx98djGYlCXz2xkHhEm73g91Y3MTvzUyE5avI7w==",
+ "license": "MIT",
+ "dependencies": {
+ "@rc-component/input": "~1.3.0",
+ "@rc-component/menu": "~1.4.0",
+ "@rc-component/trigger": "^3.0.0",
+ "@rc-component/util": "^1.3.0",
+ "clsx": "^2.1.1"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/@rc-component/menu": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/@rc-component/menu/-/menu-1.4.1.tgz",
+ "integrity": "sha512-3GsVRoQ4cnF/AoIQ4P+Z1haBfgfBPQfLT1RJY3Nu4DzOnheTslfCiGSPj7bv/cLj5sW5pHqN25dDXGP3JELAlQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@rc-component/motion": "^1.1.4",
+ "@rc-component/overflow": "^1.0.0",
+ "@rc-component/trigger": "^3.0.0",
+ "@rc-component/util": "^1.11.1",
+ "clsx": "^2.1.1"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/@rc-component/mini-decimal": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/@rc-component/mini-decimal/-/mini-decimal-1.1.4.tgz",
+ "integrity": "sha512-xiuXcaCwyOWpD8a8scdExFl+bntNphAW8XeenL1ig2en0AAZY0Pcp4pC0dI22qJ+NvxKn9RoNIoRdqYU3BLH4w==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.18.0"
+ },
+ "engines": {
+ "node": ">=8.x"
+ }
+ },
+ "node_modules/@rc-component/motion": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/@rc-component/motion/-/motion-1.3.3.tgz",
+ "integrity": "sha512-Xh3IszxvlSv3/PLYFyC2UZi9LNB83yOnkB/LNmRzaypZLvkhqUIPS7MQpGZcCMWrNsXV2p6YTSWbSGvFpEle9A==",
+ "license": "MIT",
+ "dependencies": {
+ "@rc-component/util": "^1.11.0",
+ "clsx": "^2.1.1"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/@rc-component/mutate-observer": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/@rc-component/mutate-observer/-/mutate-observer-2.0.1.tgz",
+ "integrity": "sha512-AyarjoLU5YlxuValRi+w8JRH2Z84TBbFO2RoGWz9d8bSu0FqT8DtugH3xC3BV7mUwlmROFauyWuXFuq4IFbH+w==",
+ "license": "MIT",
+ "dependencies": {
+ "@rc-component/util": "^1.2.0"
+ },
+ "engines": {
+ "node": ">=8.x"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/@rc-component/notification": {
+ "version": "2.0.7",
+ "resolved": "https://registry.npmjs.org/@rc-component/notification/-/notification-2.0.7.tgz",
+ "integrity": "sha512-nqZzpf6BPdaj+3ILx7si79LLmqPKyUmQoXa+/9gg0SkH0v1DbD66oJgRMSBEVnd/zUT3D4gwxWIHUKebYf2ZXQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@rc-component/motion": "^1.1.4",
+ "@rc-component/util": "^1.11.0",
+ "clsx": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=8.x"
+ },
+ "peerDependencies": {
+ "react": ">=18.0.0",
+ "react-dom": ">=18.0.0"
+ }
+ },
+ "node_modules/@rc-component/overflow": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@rc-component/overflow/-/overflow-1.0.1.tgz",
+ "integrity": "sha512-syfmgAABaHCnCDzPwHZ/2tuvIcpOO3jefYZMmfkN+pmo8HKTzsfhS57vxo4ksPdN0By+uWVJhJWNFozNBxi2eA==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.11.1",
+ "@rc-component/resize-observer": "^1.0.1",
+ "@rc-component/util": "^1.4.0",
+ "clsx": "^2.1.1"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/@rc-component/pagination": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/@rc-component/pagination/-/pagination-1.4.0.tgz",
+ "integrity": "sha512-CW1g7P9V8u+e8JQdUsl2RWg+GCsoee0mtJjZUCCxn/vb3jzOwDKm6hAdwddHCVBfWJ58eGUBZz3IvnU8rRktjw==",
+ "license": "MIT",
+ "dependencies": {
+ "@rc-component/util": "^1.11.1",
+ "clsx": "^2.1.1"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/@rc-component/picker": {
+ "version": "1.11.0",
+ "resolved": "https://registry.npmjs.org/@rc-component/picker/-/picker-1.11.0.tgz",
+ "integrity": "sha512-6qXGKtoJvO8sUd17m5cyNEbEJub0zflCHnaZTBBmj63DPRZYc0WEHN8rp6hFSl+yMCJS/dJY5G+1fQ8bLCuD7A==",
+ "license": "MIT",
+ "dependencies": {
+ "@rc-component/overflow": "^1.0.0",
+ "@rc-component/resize-observer": "^1.0.0",
+ "@rc-component/trigger": "^3.6.15",
+ "@rc-component/util": "^1.11.1",
+ "clsx": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=12.x"
+ },
+ "peerDependencies": {
+ "date-fns": ">= 2.x",
+ "dayjs": ">= 1.x",
+ "luxon": ">= 3.x",
+ "moment": ">= 2.x",
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ },
+ "peerDependenciesMeta": {
+ "date-fns": {
+ "optional": true
+ },
+ "dayjs": {
+ "optional": true
+ },
+ "luxon": {
+ "optional": true
+ },
+ "moment": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@rc-component/portal": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/@rc-component/portal/-/portal-2.2.1.tgz",
+ "integrity": "sha512-ck+r1kW/JSv0wxPji3KN2ss9K6Z0qqwusw/mf/0JobXhZ8hC2ejZwCJObW/SvDi0uhA0VzmCnx0CaCci95tcmA==",
+ "license": "MIT",
+ "dependencies": {
+ "@rc-component/util": "^1.11.0",
+ "clsx": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=12.x"
+ },
+ "peerDependencies": {
+ "react": ">=18.0.0",
+ "react-dom": ">=18.0.0"
+ }
+ },
+ "node_modules/@rc-component/progress": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@rc-component/progress/-/progress-1.0.2.tgz",
+ "integrity": "sha512-WZUnH9eGxH1+xodZKqdrHke59uyGZSWgj5HBM5Kwk5BrTMuAORO7VJ2IP5Qbm9aH3n9x3IcesqHHR0NWPBC7fQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@rc-component/util": "^1.2.1",
+ "clsx": "^2.1.1"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/@rc-component/qrcode": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@rc-component/qrcode/-/qrcode-2.0.0.tgz",
+ "integrity": "sha512-aAv3QhPP1xyafuTZOxub6a54pCeBnN3IwQkpETrBtthq4BL5IgxnCbuoBWPDpdLw1y1j6BgBUCAKV92+yX06Dw==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.24.7"
+ },
+ "engines": {
+ "node": ">=8.x"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/@rc-component/rate": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@rc-component/rate/-/rate-1.0.1.tgz",
+ "integrity": "sha512-bkXxeBqDpl5IOC7yL7GcSYjQx9G8H+6kLYQnNZWeBYq2OYIv1MONd6mqKTjnnJYpV0cQIU2z3atdW0j1kttpTw==",
+ "license": "MIT",
+ "dependencies": {
+ "@rc-component/util": "^1.3.0",
+ "clsx": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=8.x"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/@rc-component/resize-observer": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@rc-component/resize-observer/-/resize-observer-1.1.2.tgz",
+ "integrity": "sha512-t/Bb0W8uvL4PYKAB3YcChC+DlHh0Wt5kM7q/J+0qpVEUMLe7Hk5zuvc9km0hMnTFPSx5Z7Wu/fzCLN6erVLE8Q==",
+ "license": "MIT",
+ "dependencies": {
+ "@rc-component/util": "^1.2.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/@rc-component/segmented": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/@rc-component/segmented/-/segmented-1.3.0.tgz",
+ "integrity": "sha512-5J/bJ01mbDnoA6P/FW8SxUvKn+OgUSTZJPzCNnTBntG50tzoP7DydGhqxp7ggZXZls7me3mc2EQDXakU3iTVFg==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.11.1",
+ "@rc-component/motion": "^1.1.4",
+ "@rc-component/util": "^1.3.0",
+ "clsx": "^2.1.1"
+ },
+ "peerDependencies": {
+ "react": ">=16.0.0",
+ "react-dom": ">=16.0.0"
+ }
+ },
+ "node_modules/@rc-component/select": {
+ "version": "1.8.2",
+ "resolved": "https://registry.npmjs.org/@rc-component/select/-/select-1.8.2.tgz",
+ "integrity": "sha512-HQ9zuYqjfZTlcEMWlU1GAPBajd2OHIMVHyjZSGVTCVARwkfCgvXZMTEn0cduy3L+ejAKkaZluOQvxovZoaJaQw==",
+ "license": "MIT",
+ "dependencies": {
+ "@rc-component/overflow": "^1.0.0",
+ "@rc-component/trigger": "^3.0.0",
+ "@rc-component/util": "^1.11.1",
+ "@rc-component/virtual-list": "^1.2.0",
+ "clsx": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=8.x"
+ },
+ "peerDependencies": {
+ "react": "*",
+ "react-dom": "*"
+ }
+ },
+ "node_modules/@rc-component/slider": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@rc-component/slider/-/slider-1.1.1.tgz",
+ "integrity": "sha512-LSzgWGYDgeCDgR4r1XlU29gbYws6HpLnvJd/uMhLeW/vQgxldeR+Wb4uzHDCHiYEbr1bnEHWdjkPxjJRHxuiig==",
+ "license": "MIT",
+ "dependencies": {
+ "@rc-component/util": "^1.3.0",
+ "clsx": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=8.x"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/@rc-component/steps": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/@rc-component/steps/-/steps-1.2.2.tgz",
+ "integrity": "sha512-/yVIZ00gDYYPHSY0JP+M+s3ZvuXLu2f9rEjQqiUDs7EcYsUYrpJ/1bLj9aI9R7MBR3fu/NGh6RM9u2qGfqp+Nw==",
+ "license": "MIT",
+ "dependencies": {
+ "@rc-component/util": "^1.2.1",
+ "clsx": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=8.x"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/@rc-component/switch": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@rc-component/switch/-/switch-1.0.3.tgz",
+ "integrity": "sha512-Jgi+EbOBquje/XNdofr7xbJQZPYJP+BlPfR0h+WN4zFkdtB2EWqEfvkXJWeipflwjWip0/17rNbxEAqs8hVHfw==",
+ "license": "MIT",
+ "dependencies": {
+ "@rc-component/util": "^1.3.0",
+ "clsx": "^2.1.1"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/@rc-component/table": {
+ "version": "1.10.4",
+ "resolved": "https://registry.npmjs.org/@rc-component/table/-/table-1.10.4.tgz",
+ "integrity": "sha512-HwoTnrwc29zeoXkXGhWqzJh8FIibGUxi1jM4LtoSzmR9d5Vv5osUQpZxnXKBP8iOCvyD6BQzZm1nXJRcnrxpAg==",
+ "license": "MIT",
+ "dependencies": {
+ "@rc-component/context": "^2.0.1",
+ "@rc-component/resize-observer": "^1.0.0",
+ "@rc-component/util": "^1.11.1",
+ "@rc-component/virtual-list": "^1.0.1",
+ "clsx": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=8.x"
+ },
+ "peerDependencies": {
+ "react": ">=18.0.0",
+ "react-dom": ">=18.0.0"
+ }
+ },
+ "node_modules/@rc-component/tabs": {
+ "version": "1.11.0",
+ "resolved": "https://registry.npmjs.org/@rc-component/tabs/-/tabs-1.11.0.tgz",
+ "integrity": "sha512-hA/drZYOVa/MMIb4M2fWf3yaTyTG4qVuIABmghvEhyfw2nBob5VTH69lMCDjSVKmgODjO6nWlCV+gVn3xBrj5Q==",
+ "license": "MIT",
+ "dependencies": {
+ "@rc-component/dropdown": "~1.0.0",
+ "@rc-component/menu": "~1.4.0",
+ "@rc-component/motion": "^1.1.3",
+ "@rc-component/resize-observer": "^1.0.0",
+ "@rc-component/util": "^1.11.1",
+ "clsx": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=8.x"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/@rc-component/tooltip": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/@rc-component/tooltip/-/tooltip-1.4.0.tgz",
+ "integrity": "sha512-8Rx5DCctIlLI4raR0I0xHjVTf1aF48+gKCNeAAo5bmF5VoR5YED+A/XEqzXv9KKqrJDRcd3Wndpxh2hyzrTtSg==",
+ "license": "MIT",
+ "dependencies": {
+ "@rc-component/trigger": "^3.7.1",
+ "@rc-component/util": "^1.3.0",
+ "clsx": "^2.1.1"
+ },
+ "peerDependencies": {
+ "react": ">=18.0.0",
+ "react-dom": ">=18.0.0"
+ }
+ },
+ "node_modules/@rc-component/tour": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/@rc-component/tour/-/tour-2.4.0.tgz",
+ "integrity": "sha512-aui4r4TqmTzwaBgcQxHYep8kM8PTjZFufjokObpy35KfFeZ0k9ArquWFZqegQlH24P14t+F0qO0mGTgzlav1yg==",
+ "license": "MIT",
+ "dependencies": {
+ "@rc-component/portal": "^2.2.0",
+ "@rc-component/trigger": "^3.0.0",
+ "@rc-component/util": "^1.7.0",
+ "clsx": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=8.x"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/@rc-component/tree": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/@rc-component/tree/-/tree-1.3.2.tgz",
+ "integrity": "sha512-bJFj46wEkpBPnWyTm18XmgAgNQ/4YvprxMOPPY2a6rmhGJYxLuNKEFiL5Qej4Qctu9wHJm8WW+v2SYskafE0kA==",
+ "license": "MIT",
+ "dependencies": {
+ "@rc-component/motion": "^1.0.0",
+ "@rc-component/util": "^1.11.1",
+ "@rc-component/virtual-list": "^1.2.0",
+ "clsx": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=10.x"
+ },
+ "peerDependencies": {
+ "react": "*",
+ "react-dom": "*"
+ }
+ },
+ "node_modules/@rc-component/tree-select": {
+ "version": "1.11.0",
+ "resolved": "https://registry.npmjs.org/@rc-component/tree-select/-/tree-select-1.11.0.tgz",
+ "integrity": "sha512-EhS0X0wtUhBfK4S5TlpSY3MR9ndPMGgujtt1PJW3Ej+ToAlnS/6ohYURtCoXBYGqazUwHmgQGVUDsfpVwhWPkg==",
+ "license": "MIT",
+ "dependencies": {
+ "@rc-component/select": "~1.8.0",
+ "@rc-component/tree": "~1.3.2",
+ "@rc-component/util": "^1.11.1",
+ "clsx": "^2.1.1"
+ },
+ "peerDependencies": {
+ "react": "*",
+ "react-dom": "*"
+ }
+ },
+ "node_modules/@rc-component/trigger": {
+ "version": "3.10.1",
+ "resolved": "https://registry.npmjs.org/@rc-component/trigger/-/trigger-3.10.1.tgz",
+ "integrity": "sha512-mXlDN0IXdtV8Yqqm8195ECCyrbmfvvfKvwVvSlH0+qvKD6BUF8gRhEjSy0FOcD1+CcDRHgTiX99LoxfQrmh3Cw==",
+ "license": "MIT",
+ "dependencies": {
+ "@rc-component/motion": "^1.3.3",
+ "@rc-component/portal": "^2.2.1",
+ "@rc-component/resize-observer": "^1.1.2",
+ "@rc-component/util": "^1.11.1",
+ "clsx": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=8.x"
+ },
+ "peerDependencies": {
+ "react": ">=18.0.0",
+ "react-dom": ">=18.0.0"
+ }
+ },
+ "node_modules/@rc-component/upload": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@rc-component/upload/-/upload-1.1.1.tgz",
+ "integrity": "sha512-GvYWSKeaJTOxxC5p6+nOSadzfvXA1h8C/iHFPFZX+szH3JUXrvs+DLiW8YUTBgvMh8m63mJeHrlYlJzAlg+pDA==",
+ "license": "MIT",
+ "dependencies": {
+ "@rc-component/util": "^1.11.1",
+ "clsx": "^2.1.1"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/@rc-component/util": {
+ "version": "1.12.0",
+ "resolved": "https://registry.npmjs.org/@rc-component/util/-/util-1.12.0.tgz",
+ "integrity": "sha512-AEjPL8JVdohIITaiXokyjL9WQ6tKWWjAYK9QU16tGNE9JaQABBQy+hA4H2Lup5MgXy9yY3iLrbZJheuU13hTdQ==",
+ "license": "MIT",
+ "dependencies": {
+ "is-mobile": "^5.0.0",
+ "react-is": "^19.2.7"
+ },
+ "peerDependencies": {
+ "react": ">=18.0.0",
+ "react-dom": ">=18.0.0"
+ }
+ },
+ "node_modules/@rc-component/virtual-list": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/@rc-component/virtual-list/-/virtual-list-1.4.0.tgz",
+ "integrity": "sha512-qoyNStkTJQDezPjBibGA5HNxS9NiKJvemD1bLp7qfyxDlwy7ofPLUP0ZqJ47hR8AKcFaizd0AP/7QWLTLpudKQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^8.0.0",
+ "@rc-component/resize-observer": "^1.0.1",
+ "@rc-component/util": "^1.4.0",
+ "clsx": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=8.x"
+ },
+ "peerDependencies": {
+ "react": ">=18.0.0",
+ "react-dom": ">=18.0.0"
+ }
+ },
+ "node_modules/@rc-component/virtual-list/node_modules/@babel/runtime": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-8.0.0.tgz",
+ "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/pluginutils": {
+ "version": "1.0.0-rc.3",
+ "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.3.tgz",
+ "integrity": "sha512-eybk3TjzzzV97Dlj5c+XrBFW57eTNhzod66y9HrBlzJ6NsCrWCp/2kaPS3K9wJmurBC0Tdw4yPjXKZqlznim3Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@rollup/rollup-android-arm-eabi": {
+ "version": "4.62.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.62.3.tgz",
+ "integrity": "sha512-c0wdcekXtQvvn5Tsrk/+op/gUArrbWaFduBnTLP2l1cKLSQs4diMWjJw3m6A0DdzT8dAAX95KpkJ3qynCePbmw==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-android-arm64": {
+ "version": "4.62.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.62.3.tgz",
+ "integrity": "sha512-3YjElDdWN+qXAFbJ/CzPV+0wspLqh54k/I6GfdYtEJRqg7buSgc1yPM3B+93j1M4neobtkATHZTmxK2AMVGfnA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-arm64": {
+ "version": "4.62.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.62.3.tgz",
+ "integrity": "sha512-Pch2pFNOxxz1hTjypIdPyRTR6riiwRl84+VcN9djS680fw+Co1nAJINrdpqp7KV0NvyuU8ilZXZCjd7ykJl1GQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-x64": {
+ "version": "4.62.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.62.3.tgz",
+ "integrity": "sha512-LEuncFUHFiF8t4yZVZvvZA1wk0pjAscRnsrn1EfTEmN4HXotBi2YtcnLRyaK6UbuczW7xZS5ES+81Rdz8Z0T6g==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-freebsd-arm64": {
+ "version": "4.62.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.62.3.tgz",
+ "integrity": "sha512-zvBUvsQUpOWALdDsk6qbS8bXf2VxmPisuudNDrY7x0p0jBdsoZl8HsHczIOgkQiZldmcacMKtBzpoGVNeIe2bQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-freebsd-x64": {
+ "version": "4.62.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.62.3.tgz",
+ "integrity": "sha512-C2KmNrcSem/AMg984H/dev+si0lieQGdXdR/lYGJnuumXnFb9Y7QdiI62obFdLlxRYLBv4P0eUVIDbD4c1vVvw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
+ "version": "4.62.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.62.3.tgz",
+ "integrity": "sha512-ggXnsTAEzNQx74XpunRsiZ9aBZDsI7XIa0hm2nzR9f4WzH5/f/d73ZSDaC5ejJ8YLY4NW+V3wr0tjOaeCq8hqA==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-musleabihf": {
+ "version": "4.62.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.62.3.tgz",
+ "integrity": "sha512-2vng+FlzNUhKZxtej3IUqJgbZoQk2M/dwQM20+ULV0R/E/8tr9/P6uEf2iiGIk4HL0zMKh5Jry7mUHdUOvyGgA==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-gnu": {
+ "version": "4.62.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.62.3.tgz",
+ "integrity": "sha512-LLLFZKt4/Nraf9rxDkhiU8QVgLF4WmCkfr0L4fj0fPfIZFBib0DeiFk1hhaYKd03LFAFJcxHslhDFlNJLylf5Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-musl": {
+ "version": "4.62.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.62.3.tgz",
+ "integrity": "sha512-WJkdQCvS9sWNOUBJZfQRKpZGFBztRzcowI+nndmflKgU4XY+3a420FgTOSKTsVqJbnzSxeT4vaJalpOaPo2YCQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-loong64-gnu": {
+ "version": "4.62.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.62.3.tgz",
+ "integrity": "sha512-PwHXCCS2n64/1Ot6rP1YEYA02MGYBcQlr8CSZZyrUG2O7NH6NklYmvr9v3Jy+5e/eDeNchc/ukmKJi9LuflMIQ==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-loong64-musl": {
+ "version": "4.62.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.62.3.tgz",
+ "integrity": "sha512-vUjxINQu3RC8NZS3ykk1gN65gIz8pAopOq2HXuZhiIxHdx7TFvDG+jgrdSgInu1Eza4/Rfi2VzZgyIgEH4WOaw==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-ppc64-gnu": {
+ "version": "4.62.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.62.3.tgz",
+ "integrity": "sha512-wzko4aJ13+0G3kGnviCg5gnXFKd40izKsrf2uOw12US4XqprkDrmwOpeW14aSNa37V8bfPcz5Fkob6LZ3BAPmA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-ppc64-musl": {
+ "version": "4.62.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.62.3.tgz",
+ "integrity": "sha512-8120ue0JUMSwy11stlwnfdX3pPd+WZYGCDBwEHWtIHi6pOpZmsEF5QKB7a/UN+XFdqvobxz98kv8RTqikyCEBw==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-gnu": {
+ "version": "4.62.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.62.3.tgz",
+ "integrity": "sha512-XLFHnR3tXMjbOCh2vtVJHmxt+995uJsTERQyseFDRA0xxMxyTZPLa3OIUlyFaO4mF/Lu0FjmWHCuPXJT1n/IOg==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-musl": {
+ "version": "4.62.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.62.3.tgz",
+ "integrity": "sha512-se6yXvNGMIl0f+RQzyh7XAmia8/9kplQx424wnG2w0C1oi6XgO6Y8otKhdXFHbHs88Ihavzmvh1NWjuovE76BQ==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-s390x-gnu": {
+ "version": "4.62.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.62.3.tgz",
+ "integrity": "sha512-gNoxRefktVIiGflpONuxWWXZAzIQG++z9qHO3xKwk4WdDMuQja3JHGfE1u0i3PfPDyvhypdk+WrgIJqLhGG7sg==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-gnu": {
+ "version": "4.62.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.62.3.tgz",
+ "integrity": "sha512-V4KtWtQfAFMU7+9/A/VDps/VI8CHd3cYz0L8sgJzz8qK7eY7wI4ruFD82UYIYvW9Z4DtlTfhQcsl4XyPHW5uSg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-musl": {
+ "version": "4.62.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.62.3.tgz",
+ "integrity": "sha512-LBx9LYXvj2CBkMkjLdNAWLwH0MLMin7do2VcVo9kVPibGLkY0BQQut2fv7NVqkXqZ/CrAu9LqDHVV1xHCMpCPw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-openbsd-x64": {
+ "version": "4.62.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.62.3.tgz",
+ "integrity": "sha512-ABVf3Q0RCu7NcyCCOZQI0pJ3GuSdfSl8EXcy88QtdceIMIoCUdfhsJChZ64L9zVM2aJHjde1Bhn5uqSRcX9ySA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-openharmony-arm64": {
+ "version": "4.62.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.62.3.tgz",
+ "integrity": "sha512-+2Cy/ldweGBLlPIKsQLF8U5N44a0KDdbrk1rAjHOM9M2K+kGdIVjHLmmrZIcx+9Ny3ke/1JomCsDI1ocb11+sg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openharmony"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-arm64-msvc": {
+ "version": "4.62.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.62.3.tgz",
+ "integrity": "sha512-dtZvzc8BedpSaFNy75x6uiWwAGTH+aZHDtdrqP6qk+WcLJrfti6sGje1ZJ9UxyzDLF23d/mV+PaMwuC0hL7UVA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-ia32-msvc": {
+ "version": "4.62.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.62.3.tgz",
+ "integrity": "sha512-Rj8Ra4noo+aYy7sKBggCx0407mws34kAb1ySyWuq5DAtFBQdkSwnsjCgPrhPe9cvgBKZIukpE+CVHvORCS93kQ==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-x64-gnu": {
+ "version": "4.62.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.62.3.tgz",
+ "integrity": "sha512-vp7N084ew/odXn2gi/mzm9mUkQu9l6AiN6dt4IeUM2Uvm9o+cVmP+YkqbMOteLbiGgqBBlJZjIMYVCfOOIVbVQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-x64-msvc": {
+ "version": "4.62.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.62.3.tgz",
+ "integrity": "sha512-MOG/3gTOn4Fwf574RVOaY61I5o6P90legkFADiTyn1hyjNydT+cerU2rLUwPdZkKKyJ+iT+K9p7WXK4LM1Ka6g==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@standard-schema/spec": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz",
+ "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/babel__core": {
+ "version": "7.20.5",
+ "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
+ "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.20.7",
+ "@babel/types": "^7.20.7",
+ "@types/babel__generator": "*",
+ "@types/babel__template": "*",
+ "@types/babel__traverse": "*"
+ }
+ },
+ "node_modules/@types/babel__generator": {
+ "version": "7.27.0",
+ "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz",
+ "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.0.0"
+ }
+ },
+ "node_modules/@types/babel__template": {
+ "version": "7.4.4",
+ "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz",
+ "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.1.0",
+ "@babel/types": "^7.0.0"
+ }
+ },
+ "node_modules/@types/babel__traverse": {
+ "version": "7.28.0",
+ "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz",
+ "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.28.2"
+ }
+ },
+ "node_modules/@types/chai": {
+ "version": "5.2.3",
+ "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz",
+ "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/deep-eql": "*",
+ "assertion-error": "^2.0.1"
+ }
+ },
+ "node_modules/@types/deep-eql": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz",
+ "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/estree": {
+ "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/node": {
+ "version": "24.13.3",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-24.13.3.tgz",
+ "integrity": "sha512-Dh8vAsV36ig5wa9OX4pXvMc9D3Veibfw2wix0CUwYODLD8nkj9UsLjASr49nPg+2eKzxhBV+v7L8pXvT4e639Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "undici-types": "~7.18.0"
+ }
+ },
+ "node_modules/@types/react": {
+ "version": "19.2.17",
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.17.tgz",
+ "integrity": "sha512-MXfmqaVPEVgkBT/aY0aGCkRWWtByiYQXo3xdQ8r5RzuFrPiRn8Gar2tQdXSUQ2GKV3bkXckek89V8wQBY2Q/Aw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "csstype": "^3.2.2"
+ }
+ },
+ "node_modules/@types/react-dom": {
+ "version": "19.2.3",
+ "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz",
+ "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "^19.2.0"
+ }
+ },
+ "node_modules/@vitejs/plugin-react": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-5.2.0.tgz",
+ "integrity": "sha512-YmKkfhOAi3wsB1PhJq5Scj3GXMn3WvtQ/JC0xoopuHoXSdmtdStOpFrYaT1kie2YgFBcIe64ROzMYRjCrYOdYw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/core": "^7.29.0",
+ "@babel/plugin-transform-react-jsx-self": "^7.27.1",
+ "@babel/plugin-transform-react-jsx-source": "^7.27.1",
+ "@rolldown/pluginutils": "1.0.0-rc.3",
+ "@types/babel__core": "^7.20.5",
+ "react-refresh": "^0.18.0"
+ },
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ },
+ "peerDependencies": {
+ "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0"
+ }
+ },
+ "node_modules/@vitest/expect": {
+ "version": "4.1.10",
+ "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.10.tgz",
+ "integrity": "sha512-YsCn+qAk1GWjQOWFEsEcL2gNQ0zmVmQu3T03qP6UyjhtmdtwtbuI+DASn/7iQB3HGTXkdBwGddzxPlmiql5vlA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@standard-schema/spec": "^1.1.0",
+ "@types/chai": "^5.2.2",
+ "@vitest/spy": "4.1.10",
+ "@vitest/utils": "4.1.10",
+ "chai": "^6.2.2",
+ "tinyrainbow": "^3.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vitest/mocker": {
+ "version": "4.1.10",
+ "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.10.tgz",
+ "integrity": "sha512-v0xaezt+DKEmKfaxg133ldzADrwLGd7Ze1MfQQTYfvs8OqZIwbxyxaYURivwV7sWy5fqn3rH5uOrSp07bp44Ow==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vitest/spy": "4.1.10",
+ "estree-walker": "^3.0.3",
+ "magic-string": "^0.30.21"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ },
+ "peerDependencies": {
+ "msw": "^2.4.9",
+ "vite": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ },
+ "peerDependenciesMeta": {
+ "msw": {
+ "optional": true
+ },
+ "vite": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@vitest/pretty-format": {
+ "version": "4.1.10",
+ "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.10.tgz",
+ "integrity": "sha512-W1HsjSH4MXQ9YfmmhLAoIYf1HRfekQCGngeIgcei6MP5QQGWUe0gkopdZQaVCFO+JDJMrAJGwa5pRpNpvy4P8Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "tinyrainbow": "^3.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vitest/runner": {
+ "version": "4.1.10",
+ "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.10.tgz",
+ "integrity": "sha512-IKI6kpIH+LmpROplyLwBBaCfMgOZOMsygVa6BARD6ahA04VRuJSa6OaVG7kRvSEMD870Vd91rSSw0eegtWyLGg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vitest/utils": "4.1.10",
+ "pathe": "^2.0.3"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vitest/snapshot": {
+ "version": "4.1.10",
+ "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.10.tgz",
+ "integrity": "sha512-xRkfOT1qpTAi/Ti4Y1LtfRc3kEuqxGw59eN2jN9pRWMtS/XDevekhcFSqvQqjUNGksfjMJu3Y+oJ+4Ypn2OaJw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vitest/pretty-format": "4.1.10",
+ "@vitest/utils": "4.1.10",
+ "magic-string": "^0.30.21",
+ "pathe": "^2.0.3"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vitest/spy": {
+ "version": "4.1.10",
+ "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.10.tgz",
+ "integrity": "sha512-PLf/Ugvoq5wO/b4rwYCR1h2PSIdXz7wnkQFMiUpLdtM7l6pqVFcQIBEHyT1+l+cj7mNwAfZHzqXqDyjvOuwbDw==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vitest/utils": {
+ "version": "4.1.10",
+ "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.10.tgz",
+ "integrity": "sha512-fy9am/HWxbaGt/Sawrp90vt6Y6jQwf1RX77cz3uwoJwJVMli/e1IEwRPnMNJ7vKfPTwo0diXifkpPvwH9v7nGA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vitest/pretty-format": "4.1.10",
+ "convert-source-map": "^2.0.0",
+ "tinyrainbow": "^3.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/agent-base": {
+ "version": "7.1.4",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz",
+ "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "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/antd": {
+ "version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/antd/-/antd-6.5.0.tgz",
+ "integrity": "sha512-9zbVc9UukfGuqCvIAov01nlpDQWfARNmZQyt21ZhqLX7ilXmi4cdkp12xA48WEmXRXwZvno8A03qQuGE9JG8fg==",
+ "license": "MIT",
+ "dependencies": {
+ "@ant-design/colors": "^8.0.1",
+ "@ant-design/cssinjs": "^2.1.2",
+ "@ant-design/cssinjs-utils": "^2.1.2",
+ "@ant-design/fast-color": "^3.0.1",
+ "@ant-design/icons": "^6.3.1",
+ "@ant-design/react-slick": "~2.0.0",
+ "@babel/runtime": "^7.29.2",
+ "@rc-component/cascader": "~1.17.0",
+ "@rc-component/checkbox": "~2.0.0",
+ "@rc-component/collapse": "~1.2.0",
+ "@rc-component/color-picker": "~3.1.1",
+ "@rc-component/dialog": "~1.10.0",
+ "@rc-component/drawer": "~1.4.2",
+ "@rc-component/dropdown": "~1.0.2",
+ "@rc-component/form": "~1.8.5",
+ "@rc-component/image": "~1.9.0",
+ "@rc-component/input": "~1.3.1",
+ "@rc-component/input-number": "~1.6.2",
+ "@rc-component/mentions": "~1.10.0",
+ "@rc-component/menu": "~1.4.1",
+ "@rc-component/motion": "^1.3.3",
+ "@rc-component/mutate-observer": "^2.0.1",
+ "@rc-component/notification": "~2.0.7",
+ "@rc-component/pagination": "~1.4.0",
+ "@rc-component/picker": "~1.11.0",
+ "@rc-component/progress": "~1.0.2",
+ "@rc-component/qrcode": "~2.0.0",
+ "@rc-component/rate": "~1.0.1",
+ "@rc-component/resize-observer": "^1.1.2",
+ "@rc-component/segmented": "~1.3.0",
+ "@rc-component/select": "~1.8.2",
+ "@rc-component/slider": "~1.1.1",
+ "@rc-component/steps": "~1.2.2",
+ "@rc-component/switch": "~1.0.3",
+ "@rc-component/table": "~1.10.2",
+ "@rc-component/tabs": "~1.11.0",
+ "@rc-component/tooltip": "~1.4.0",
+ "@rc-component/tour": "~2.4.0",
+ "@rc-component/tree": "~1.3.2",
+ "@rc-component/tree-select": "~1.11.0",
+ "@rc-component/trigger": "^3.9.1",
+ "@rc-component/upload": "~1.1.1",
+ "@rc-component/util": "^1.11.1",
+ "clsx": "^2.1.1",
+ "dayjs": "^1.11.11",
+ "scroll-into-view-if-needed": "^3.1.0",
+ "throttle-debounce": "^5.0.2"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/ant-design"
+ },
+ "peerDependencies": {
+ "react": ">=18.0.0",
+ "react-dom": ">=18.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/assertion-error": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz",
+ "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "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/baseline-browser-mapping": {
+ "version": "2.11.7",
+ "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.7.tgz",
+ "integrity": "sha512-APw5YuIQAg6L9w4sHDI6j26DGFJI6RpYOhnkMPdC9lWbkKvsyPHzDsve1yd73lk21yz7Y09Kci8B2Pp9FonzWA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "baseline-browser-mapping": "dist/cli.cjs"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/brace-expansion": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.3.tgz",
+ "integrity": "sha512-DRdx5neNsG/QXbniLFWi2YmC/68oeOOmKz6zOjVk6ZS1ZLXgLIKqVEc6hWsmkjBbgii0SwaBTcJ5XKj5gzY/4A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/browserslist": {
+ "version": "4.28.7",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.7.tgz",
+ "integrity": "sha512-JxV13hNrFxqjOc8alRbq9dK1MM79NEXYpma2B2J4wAtpWS5zIEIKqWPGCl7N4o7Uc7B7itylh7SuDujATRyyTw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "baseline-browser-mapping": "^2.10.44",
+ "caniuse-lite": "^1.0.30001806",
+ "electron-to-chromium": "^1.5.393",
+ "node-releases": "^2.0.51",
+ "update-browserslist-db": "^1.2.3"
+ },
+ "bin": {
+ "browserslist": "cli.js"
+ },
+ "engines": {
+ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+ }
+ },
+ "node_modules/caniuse-lite": {
+ "version": "1.0.30001806",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001806.tgz",
+ "integrity": "sha512-72Cuvd95zbSYPKq6Fhg8eDJRlzgWDf7/mtoZv6Qe/DYNCEBdNxoA3+rZAU2ZhGCpZlns3EssFavaZomckT5Uuw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "CC-BY-4.0"
+ },
+ "node_modules/chai": {
+ "version": "6.2.2",
+ "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz",
+ "integrity": "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "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/clsx": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz",
+ "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "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/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",
+ "integrity": "sha512-VRhuHOLoKYOy4UbilLbUzbYg93XLjv2PncJC50EuTWPA3gaja1UjBsUP/D/9/juV3vQFr6XBEzn9KCAHdUvOHw==",
+ "license": "MIT"
+ },
+ "node_modules/convert-source-map": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
+ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/cookie-es": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/cookie-es/-/cookie-es-3.1.1.tgz",
+ "integrity": "sha512-UaXxwISYJPTr9hwQxMFYZ7kNhSXboMXP+Z3TRX6f1/NyaGPfuNUZOWP1pUEb75B2HjfklIYLVRfWiFZJyC6Npg==",
+ "license": "MIT"
+ },
+ "node_modules/csstype": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
+ "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
+ "license": "MIT"
+ },
+ "node_modules/dayjs": {
+ "version": "1.11.21",
+ "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.21.tgz",
+ "integrity": "sha512-98IT+HOahAisibz/yjKbzuOBwYcjJ7BCLPzARyHiyEBmRz4fatF+KPJszEHXsGYjUG234aH/cOjW1wwTbKUZlA==",
+ "license": "MIT"
+ },
+ "node_modules/debug": {
+ "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"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/electron-to-chromium": {
+ "version": "1.5.398",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.398.tgz",
+ "integrity": "sha512-AsvhAxopJGh6museTDMIjn6JpDYOfgu4RLlygomt87MUwBUqTfd/1EiPtx10/LZE8xpTvkP2E9Gafq7lkLtodQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/es-module-lexer": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.3.1.tgz",
+ "integrity": "sha512-shc1dbU90Yl/xq1QrC7QRtfcwURZuVRfPhZbDoldJ1cn1gzDvBaBWlv0eFolj5+0znnPJz5TXLxsN77X/12KTA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/esbuild": {
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.1.tgz",
+ "integrity": "sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "optionalDependencies": {
+ "@esbuild/aix-ppc64": "0.28.1",
+ "@esbuild/android-arm": "0.28.1",
+ "@esbuild/android-arm64": "0.28.1",
+ "@esbuild/android-x64": "0.28.1",
+ "@esbuild/darwin-arm64": "0.28.1",
+ "@esbuild/darwin-x64": "0.28.1",
+ "@esbuild/freebsd-arm64": "0.28.1",
+ "@esbuild/freebsd-x64": "0.28.1",
+ "@esbuild/linux-arm": "0.28.1",
+ "@esbuild/linux-arm64": "0.28.1",
+ "@esbuild/linux-ia32": "0.28.1",
+ "@esbuild/linux-loong64": "0.28.1",
+ "@esbuild/linux-mips64el": "0.28.1",
+ "@esbuild/linux-ppc64": "0.28.1",
+ "@esbuild/linux-riscv64": "0.28.1",
+ "@esbuild/linux-s390x": "0.28.1",
+ "@esbuild/linux-x64": "0.28.1",
+ "@esbuild/netbsd-arm64": "0.28.1",
+ "@esbuild/netbsd-x64": "0.28.1",
+ "@esbuild/openbsd-arm64": "0.28.1",
+ "@esbuild/openbsd-x64": "0.28.1",
+ "@esbuild/openharmony-arm64": "0.28.1",
+ "@esbuild/sunos-x64": "0.28.1",
+ "@esbuild/win32-arm64": "0.28.1",
+ "@esbuild/win32-ia32": "0.28.1",
+ "@esbuild/win32-x64": "0.28.1"
+ }
+ },
+ "node_modules/escalade": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
+ "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/estree-walker": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz",
+ "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "^1.0.0"
+ }
+ },
+ "node_modules/expect-type": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.4.0.tgz",
+ "integrity": "sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
+ "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/fdir": {
+ "version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
+ "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "peerDependencies": {
+ "picomatch": "^3 || ^4"
+ },
+ "peerDependenciesMeta": {
+ "picomatch": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/gensync": {
+ "version": "1.0.0-beta.2",
+ "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
+ "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/https-proxy-agent": {
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz",
+ "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "agent-base": "^7.1.2",
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "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/is-mobile": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/is-mobile/-/is-mobile-5.0.0.tgz",
+ "integrity": "sha512-Tz/yndySvLAEXh+Uk8liFCxOwVH6YutuR74utvOcu7I9Di+DwM0mtdPVZNaVvvBUM2OXxne/NhOs1zAO7riusQ==",
+ "license": "MIT"
+ },
+ "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",
+ "dependencies": {
+ "argparse": "^2.0.1"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/jsesc": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
+ "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "jsesc": "bin/jsesc"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "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",
+ "integrity": "sha512-SzoRg7ux5DWTII9J2qkrZrqV1gt+rTaoufMxEzXbS26Uid0NwaJd123HcoB80TgubEppxxIGdNxCx50fEoEWQA==",
+ "license": "MIT",
+ "dependencies": {
+ "string-convert": "^0.2.0"
+ }
+ },
+ "node_modules/json5": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+ "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "json5": "lib/cli.js"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/lru-cache": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
+ "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "yallist": "^3.0.2"
+ }
+ },
+ "node_modules/magic-string": {
+ "version": "0.30.21",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz",
+ "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.5.5"
+ }
+ },
+ "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/nanoid": {
+ "version": "3.3.16",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.16.tgz",
+ "integrity": "sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
+ },
+ "engines": {
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ }
+ },
+ "node_modules/node-releases": {
+ "version": "2.0.51",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.51.tgz",
+ "integrity": "sha512-wRNIrw4DmVLKQlbgOMdkMx27Wrpzes2hh5Jtbi2bjPd+4wJstWIqP5A+lscnqbm0xxmT5Bpg8Lec5ItEBwx6BQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/obug": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.4.tgz",
+ "integrity": "sha512-4a+OsYv9UktOJKE+l1A4OufDgdRF9PifWj+tJnHURo/P+WOxpG4GzUFL9qCalmWauao6ogiG+QvnCovwPoyAWA==",
+ "dev": true,
+ "funding": [
+ "https://github.com/sponsors/sxzz",
+ "https://opencollective.com/debug"
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.20.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/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/pathe": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz",
+ "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/picocolors": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/picomatch": {
+ "version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz",
+ "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "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",
+ "integrity": "sha512-DTPx3RWSSnWyzLxQnlH0rJP+EW5ekl16ZU4/psbIhA0e53kJfdgaN5vKM+xP7yJtXVu+nfdVFmlgFDEKAe4Pyw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "nanoid": "^3.3.16",
+ "picocolors": "^1.1.1",
+ "source-map-js": "^1.2.1"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
+ "node_modules/react": {
+ "version": "19.2.8",
+ "resolved": "https://registry.npmjs.org/react/-/react-19.2.8.tgz",
+ "integrity": "sha512-PWaYA1L/q9u2u7xYQi+Y3L3Yfnie7XyLeaJICV1MGD6LprsBxcAqGjYyr0eY3p+QdsA+x/Irkt4Qif8D63+Sbw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/react-dom": {
+ "version": "19.2.8",
+ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.8.tgz",
+ "integrity": "sha512-rVprimfGBG3DR+Tq0IQG2DT5PxKth1WIGDmj5yPmlzr4YBe7uyE+Du4oVqTDXZSHGGGXRtTJEGSSePyQCMBglQ==",
+ "license": "MIT",
+ "dependencies": {
+ "scheduler": "^0.27.0"
+ },
+ "peerDependencies": {
+ "react": "^19.2.8"
+ }
+ },
+ "node_modules/react-is": {
+ "version": "19.2.8",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.8.tgz",
+ "integrity": "sha512-s5un28nYxKJw5gvUHyW5PCC28CvBqLu9r3cWgzHT4Vo/5fqqkFcdRYsGcKf50WMPpjjFZS5d76fn3YCo2njKwQ==",
+ "license": "MIT"
+ },
+ "node_modules/react-refresh": {
+ "version": "0.18.0",
+ "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.18.0.tgz",
+ "integrity": "sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/react-router": {
+ "version": "8.3.0",
+ "resolved": "https://registry.npmjs.org/react-router/-/react-router-8.3.0.tgz",
+ "integrity": "sha512-qyPMvW83jGIct3yiieisxdk9M745anqhpIMKN5m1t6yBMfgVPpt77aHOqs5fUlEJRMCGffg9BaQLH9oPVOL7xQ==",
+ "license": "MIT",
+ "dependencies": {
+ "cookie-es": "^3.1.1"
+ },
+ "engines": {
+ "node": ">=22.22.0"
+ },
+ "peerDependencies": {
+ "react": ">=19.2.7",
+ "react-dom": ">=19.2.7"
+ },
+ "peerDependenciesMeta": {
+ "react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/require-from-string": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
+ "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/rollup": {
+ "version": "4.62.3",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.62.3.tgz",
+ "integrity": "sha512-Gu0c0iH9FzgX1L1t7ByIbbS3Vmdz+6KHm/EsqmmC71gUQ82yvZRkTK6XzrFObSka91WUVdynqp6nsfilzr5k6Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "1.0.9"
+ },
+ "bin": {
+ "rollup": "dist/bin/rollup"
+ },
+ "engines": {
+ "node": ">=18.0.0",
+ "npm": ">=8.0.0"
+ },
+ "optionalDependencies": {
+ "@rollup/rollup-android-arm-eabi": "4.62.3",
+ "@rollup/rollup-android-arm64": "4.62.3",
+ "@rollup/rollup-darwin-arm64": "4.62.3",
+ "@rollup/rollup-darwin-x64": "4.62.3",
+ "@rollup/rollup-freebsd-arm64": "4.62.3",
+ "@rollup/rollup-freebsd-x64": "4.62.3",
+ "@rollup/rollup-linux-arm-gnueabihf": "4.62.3",
+ "@rollup/rollup-linux-arm-musleabihf": "4.62.3",
+ "@rollup/rollup-linux-arm64-gnu": "4.62.3",
+ "@rollup/rollup-linux-arm64-musl": "4.62.3",
+ "@rollup/rollup-linux-loong64-gnu": "4.62.3",
+ "@rollup/rollup-linux-loong64-musl": "4.62.3",
+ "@rollup/rollup-linux-ppc64-gnu": "4.62.3",
+ "@rollup/rollup-linux-ppc64-musl": "4.62.3",
+ "@rollup/rollup-linux-riscv64-gnu": "4.62.3",
+ "@rollup/rollup-linux-riscv64-musl": "4.62.3",
+ "@rollup/rollup-linux-s390x-gnu": "4.62.3",
+ "@rollup/rollup-linux-x64-gnu": "4.62.3",
+ "@rollup/rollup-linux-x64-musl": "4.62.3",
+ "@rollup/rollup-openbsd-x64": "4.62.3",
+ "@rollup/rollup-openharmony-arm64": "4.62.3",
+ "@rollup/rollup-win32-arm64-msvc": "4.62.3",
+ "@rollup/rollup-win32-ia32-msvc": "4.62.3",
+ "@rollup/rollup-win32-x64-gnu": "4.62.3",
+ "@rollup/rollup-win32-x64-msvc": "4.62.3",
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/scheduler": {
+ "version": "0.27.0",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz",
+ "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==",
+ "license": "MIT"
+ },
+ "node_modules/scroll-into-view-if-needed": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/scroll-into-view-if-needed/-/scroll-into-view-if-needed-3.1.0.tgz",
+ "integrity": "sha512-49oNpRjWRvnU8NyGVmUaYG4jtTkNonFZI86MmGRDqBphEK2EXT9gdEUoQPZhuBM8yWHxCWbobltqYO5M4XrUvQ==",
+ "license": "MIT",
+ "dependencies": {
+ "compute-scroll-into-view": "^3.0.2"
+ }
+ },
+ "node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/siginfo": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz",
+ "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/source-map-js": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
+ "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/stackback": {
+ "version": "0.0.2",
+ "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz",
+ "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/std-env": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/std-env/-/std-env-4.2.0.tgz",
+ "integrity": "sha512-oCUKSupKTHX53EyjDtuZQ64pjLJ6yYCtpmEw0goYxtjG9KpbRe8KAsl2tBUGU9DyMcJ0RwJ8GqJAFzMXcXW1Rw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/string-convert": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/string-convert/-/string-convert-0.2.1.tgz",
+ "integrity": "sha512-u/1tdPl4yQnPBjnVrmdLo9gtuLvELKsAoRapekWggdiQNvvvum+jYF329d84NAa660KQw7pB2n36KrIKVoXa3A==",
+ "license": "MIT"
+ },
+ "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/throttle-debounce": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-5.0.2.tgz",
+ "integrity": "sha512-B71/4oyj61iNH0KeCamLuE2rmKuTO5byTOSVwECM5FA7TiAiAW+UqTKZ9ERueC4qvgSttUhdmq1mXC3kJqGX7A==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.22"
+ }
+ },
+ "node_modules/tinybench": {
+ "version": "2.9.0",
+ "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz",
+ "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/tinyexec": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.2.4.tgz",
+ "integrity": "sha512-SHf/r48b7vOrjve9PxJo3MN5v5yuyjHvdUcrQffT3WXMUfnGmHDVbC4k3sHJaJTgZCwpUplIaAo5ANtMyp3YHg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/tinyglobby": {
+ "version": "0.2.17",
+ "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz",
+ "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fdir": "^6.5.0",
+ "picomatch": "^4.0.4"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/SuperchupuDev"
+ }
+ },
+ "node_modules/tinyrainbow": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.1.1.tgz",
+ "integrity": "sha512-yau8yJdTt989Mm0Bd/236QnzEiPf2xLLTqUZRUJOo/3CB078LSwzei343DgtJVmfJKJE3TMINY1u42SQsP6mXw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "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/typescript": {
+ "version": "5.9.3",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
+ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=14.17"
+ }
+ },
+ "node_modules/undici-types": {
+ "version": "7.18.2",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz",
+ "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/update-browserslist-db": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz",
+ "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "escalade": "^3.2.0",
+ "picocolors": "^1.1.1"
+ },
+ "bin": {
+ "update-browserslist-db": "cli.js"
+ },
+ "peerDependencies": {
+ "browserslist": ">= 4.21.0"
+ }
+ },
+ "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/vite": {
+ "version": "7.3.6",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.6.tgz",
+ "integrity": "sha512-4XP60spRGjSZFf1qYH+dJIkK2znL3zQfl9KkOV9MkkRR/3Dls0dxaBsQPTloEc5BLXWPL9vsOxopxyKoMmDueg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "esbuild": "^0.27.0 || ^0.28.0",
+ "fdir": "^6.5.0",
+ "picomatch": "^4.0.3",
+ "postcss": "^8.5.6",
+ "rollup": "^4.43.0",
+ "tinyglobby": "^0.2.15"
+ },
+ "bin": {
+ "vite": "bin/vite.js"
+ },
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ },
+ "funding": {
+ "url": "https://github.com/vitejs/vite?sponsor=1"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.3"
+ },
+ "peerDependencies": {
+ "@types/node": "^20.19.0 || >=22.12.0",
+ "jiti": ">=1.21.0",
+ "less": "^4.0.0",
+ "lightningcss": "^1.21.0",
+ "sass": "^1.70.0",
+ "sass-embedded": "^1.70.0",
+ "stylus": ">=0.54.8",
+ "sugarss": "^5.0.0",
+ "terser": "^5.16.0",
+ "tsx": "^4.8.1",
+ "yaml": "^2.4.2"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ },
+ "jiti": {
+ "optional": true
+ },
+ "less": {
+ "optional": true
+ },
+ "lightningcss": {
+ "optional": true
+ },
+ "sass": {
+ "optional": true
+ },
+ "sass-embedded": {
+ "optional": true
+ },
+ "stylus": {
+ "optional": true
+ },
+ "sugarss": {
+ "optional": true
+ },
+ "terser": {
+ "optional": true
+ },
+ "tsx": {
+ "optional": true
+ },
+ "yaml": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vitest": {
+ "version": "4.1.10",
+ "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.10.tgz",
+ "integrity": "sha512-R9jUTe5S4Qb0HCd4TNqpC7oGcrMssMRGXLW80ubjWsW9VH5GF8y1Y0SFLY9AbqSk6nt0PnOx4H4WNJYZ13GUPw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vitest/expect": "4.1.10",
+ "@vitest/mocker": "4.1.10",
+ "@vitest/pretty-format": "4.1.10",
+ "@vitest/runner": "4.1.10",
+ "@vitest/snapshot": "4.1.10",
+ "@vitest/spy": "4.1.10",
+ "@vitest/utils": "4.1.10",
+ "es-module-lexer": "^2.0.0",
+ "expect-type": "^1.3.0",
+ "magic-string": "^0.30.21",
+ "obug": "^2.1.1",
+ "pathe": "^2.0.3",
+ "picomatch": "^4.0.3",
+ "std-env": "^4.0.0-rc.1",
+ "tinybench": "^2.9.0",
+ "tinyexec": "^1.0.2",
+ "tinyglobby": "^0.2.15",
+ "tinyrainbow": "^3.1.0",
+ "vite": "^6.0.0 || ^7.0.0 || ^8.0.0",
+ "why-is-node-running": "^2.3.0"
+ },
+ "bin": {
+ "vitest": "vitest.mjs"
+ },
+ "engines": {
+ "node": "^20.0.0 || ^22.0.0 || >=24.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ },
+ "peerDependencies": {
+ "@edge-runtime/vm": "*",
+ "@opentelemetry/api": "^1.9.0",
+ "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0",
+ "@vitest/browser-playwright": "4.1.10",
+ "@vitest/browser-preview": "4.1.10",
+ "@vitest/browser-webdriverio": "4.1.10",
+ "@vitest/coverage-istanbul": "4.1.10",
+ "@vitest/coverage-v8": "4.1.10",
+ "@vitest/ui": "4.1.10",
+ "happy-dom": "*",
+ "jsdom": "*",
+ "vite": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@edge-runtime/vm": {
+ "optional": true
+ },
+ "@opentelemetry/api": {
+ "optional": true
+ },
+ "@types/node": {
+ "optional": true
+ },
+ "@vitest/browser-playwright": {
+ "optional": true
+ },
+ "@vitest/browser-preview": {
+ "optional": true
+ },
+ "@vitest/browser-webdriverio": {
+ "optional": true
+ },
+ "@vitest/coverage-istanbul": {
+ "optional": true
+ },
+ "@vitest/coverage-v8": {
+ "optional": true
+ },
+ "@vitest/ui": {
+ "optional": true
+ },
+ "happy-dom": {
+ "optional": true
+ },
+ "jsdom": {
+ "optional": true
+ },
+ "vite": {
+ "optional": false
+ }
+ }
+ },
+ "node_modules/why-is-node-running": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz",
+ "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "siginfo": "^2.0.0",
+ "stackback": "0.0.2"
+ },
+ "bin": {
+ "why-is-node-running": "cli.js"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/yallist": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "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-parser": {
+ "version": "21.1.1",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
+ "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=12"
+ }
+ }
+ }
+}
diff --git a/Tiku.PlatformAdmin.Web/package.json b/Tiku.PlatformAdmin.Web/package.json
new file mode 100644
index 0000000..74ef37e
--- /dev/null
+++ b/Tiku.PlatformAdmin.Web/package.json
@@ -0,0 +1,31 @@
+{
+ "name": "@tiku/platform-admin",
+ "private": true,
+ "version": "0.1.0",
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "tsc -b && vite build",
+ "preview": "vite preview",
+ "generate:api": "node scripts/generate-platform-operations.mjs",
+ "test": "vitest run",
+ "check": "npm run build && npm run test"
+ },
+ "dependencies": {
+ "@ant-design/icons": "^6.0.1",
+ "antd": "6.5.0",
+ "react": "^19.2.0",
+ "react-dom": "^19.2.0",
+ "react-router": "^8.3.0"
+ },
+ "devDependencies": {
+ "@types/node": "^24.10.0",
+ "@types/react": "^19.2.2",
+ "@types/react-dom": "^19.2.2",
+ "@vitejs/plugin-react": "^5.1.1",
+ "openapi-typescript": "^7.10.1",
+ "typescript": "^5.9.3",
+ "vite": "^7.2.2",
+ "vitest": "^4.0.8"
+ }
+}
diff --git a/Tiku.Api/wwwroot/platform-admin/assets/logo.png b/Tiku.PlatformAdmin.Web/public/logo.png
similarity index 100%
rename from Tiku.Api/wwwroot/platform-admin/assets/logo.png
rename to Tiku.PlatformAdmin.Web/public/logo.png
diff --git a/Tiku.PlatformAdmin.Web/scripts/generate-platform-operations.mjs b/Tiku.PlatformAdmin.Web/scripts/generate-platform-operations.mjs
new file mode 100644
index 0000000..4134a2d
--- /dev/null
+++ b/Tiku.PlatformAdmin.Web/scripts/generate-platform-operations.mjs
@@ -0,0 +1,51 @@
+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' });
+
+const methods = new Set(['get', 'post', 'put', 'patch', 'delete']);
+const operations = [];
+for (const [route, pathItem] of Object.entries(document.paths || {})) {
+ for (const [method, operation] of Object.entries(pathItem || {})) {
+ if (!methods.has(method)) continue;
+ const tags = operation.tags || [];
+ const isPlatform = route.startsWith('/api/platform-admin/') || route === '/api/platform-admin' || route.startsWith('/api/backoffice/platform/');
+ if (!isPlatform) continue;
+ const requestSchema = operation.requestBody?.content?.['application/json']?.schema || null;
+ const responseEntry = Object.entries(operation.responses || {}).find(([status]) => /^2/.test(status));
+ const responseSchema = responseEntry?.[1]?.content?.['application/json']?.schema || null;
+ operations.push({
+ id: `${method.toUpperCase()} ${route}`,
+ method: method.toUpperCase(),
+ path: route,
+ tag: tags[0] || '平台端',
+ summary: operation.summary || `${method.toUpperCase()} ${route}`,
+ description: operation.description || '',
+ parameters: [...(pathItem.parameters || []), ...(operation.parameters || [])],
+ requestSchema,
+ responseSchema,
+ });
+ }
+}
+
+operations.sort((a, b) => a.path.localeCompare(b.path) || a.method.localeCompare(b.method));
+const schemas = document.components?.schemas || {};
+const source = `/* eslint-disable */\n// 由 scripts/generate-platform-operations.mjs 根据后端 OpenAPI 自动生成,请勿手改。\nimport type { PlatformOperation } from './types';\n\nexport const generatedAt = ${JSON.stringify(new Date().toISOString())};\nexport const platformOperations = ${JSON.stringify(operations, null, 2)} as const satisfies readonly PlatformOperation[];\nexport const openApiSchemas = ${JSON.stringify(schemas, null, 2)} as const;\n`;
+writeFileSync(path.join(apiDir, 'platform-operations.generated.ts'), source);
+console.log(`已生成 ${operations.length} 个平台接口契约,来源:${openApiUrl}`);
diff --git a/Tiku.PlatformAdmin.Web/src/api/groups.test.ts b/Tiku.PlatformAdmin.Web/src/api/groups.test.ts
new file mode 100644
index 0000000..8ef1262
--- /dev/null
+++ b/Tiku.PlatformAdmin.Web/src/api/groups.test.ts
@@ -0,0 +1,18 @@
+import { describe, expect, it } from 'vitest';
+import { platformOperations } from './platform-operations.generated';
+import { groupForOperation, platformGroups } from './groups';
+
+describe('平台 OpenAPI 页面覆盖', () => {
+ it('每个后端平台接口恰好归入一个页面组', () => {
+ const knownGroups = new Set(platformGroups.map((group) => group.key));
+ const grouped = platformOperations.map((operation) => ({ id: operation.id, group: groupForOperation(operation) }));
+ expect(grouped).toHaveLength(platformOperations.length);
+ expect(new Set(grouped.map((item) => item.id)).size).toBe(platformOperations.length);
+ expect(grouped.every((item) => knownGroups.has(item.group))).toBe(true);
+ });
+
+ it('契约只包含平台权限域接口', () => {
+ expect(platformOperations.length).toBeGreaterThan(0);
+ expect(platformOperations.every((operation) => operation.path.startsWith('/api/platform-admin/') || operation.path.startsWith('/api/backoffice/platform/'))).toBe(true);
+ });
+});
diff --git a/Tiku.PlatformAdmin.Web/src/api/groups.ts b/Tiku.PlatformAdmin.Web/src/api/groups.ts
new file mode 100644
index 0000000..e49b578
--- /dev/null
+++ b/Tiku.PlatformAdmin.Web/src/api/groups.ts
@@ -0,0 +1,31 @@
+import type { PlatformOperation } from './types';
+
+export const platformGroups = [
+ { key: 'overview', label: '经营概览', description: '平台经营指标与实时概览' },
+ { key: 'tenants', label: '租户管理', description: '租户、详情、域名与账务资料' },
+ { key: 'catalog', label: 'SaaS 商品', description: '功能、限额、套餐与版本生命周期' },
+ { key: 'billing', label: '订阅与账务', description: '订单、订阅、支付、退款、发票、用量与催缴' },
+ { key: 'question-banks', label: '公共题库', description: '题库结构、题目、导入与资源上传' },
+ { key: 'crm', label: 'CRM 能力', description: '租户 CRM 配置、线索队列与推送日志' },
+ { key: 'sms', label: '短信能力', description: '租户短信渠道、模板与发送日志' },
+ { key: 'payments', label: '支付设置', description: '平台支付与租户支付应用托管' },
+ { key: 'staff', label: '平台权限', description: '平台员工、角色与权限绑定' },
+ { key: 'audit', label: '审计与告警', description: '平台审计日志、告警与通知' },
+] as const;
+
+export type PlatformGroupKey = (typeof platformGroups)[number]['key'];
+
+export function groupForOperation(operation: PlatformOperation): PlatformGroupKey {
+ const route = operation.path;
+ if (route === '/api/platform-admin/overview') return 'overview';
+ if (route.startsWith('/api/platform-admin/tenants') || route.startsWith('/api/platform-admin/domains')) return 'tenants';
+ if (route.startsWith('/api/platform-admin/question-banks')) return 'question-banks';
+ if (route.startsWith('/api/platform-admin/tenant-capabilities/crm')) return 'crm';
+ if (route.startsWith('/api/platform-admin/tenant-capabilities/sms')) return 'sms';
+ if (route.startsWith('/api/platform-admin/payment-settings') || route.startsWith('/api/platform-admin/tenant-capabilities/payments')) return 'payments';
+ if (route.startsWith('/api/backoffice/platform') || route.startsWith('/api/platform-admin/staff')) return 'staff';
+ if (route.startsWith('/api/platform-admin/audit-')) return 'audit';
+ if (route.startsWith('/api/platform-admin/saas/features') || route.startsWith('/api/platform-admin/saas/feature-limits') || route.startsWith('/api/platform-admin/saas/offerings') || route.startsWith('/api/platform-admin/saas/offering-versions') || route.startsWith('/api/platform-admin/saas/catalog') || route.startsWith('/api/platform-admin/saas/tenant-feature-overrides')) return 'catalog';
+ if (route.startsWith('/api/platform-admin/saas/')) return 'billing';
+ throw new Error(`平台接口尚未归入页面:${operation.id}`);
+}
diff --git a/Tiku.PlatformAdmin.Web/src/api/http.ts b/Tiku.PlatformAdmin.Web/src/api/http.ts
new file mode 100644
index 0000000..93c572e
--- /dev/null
+++ b/Tiku.PlatformAdmin.Web/src/api/http.ts
@@ -0,0 +1,105 @@
+import type { OperationInput, PlatformOperation } from './types';
+import { tokenStore, type TokenPair } from './token-store';
+
+const apiBaseUrl = (import.meta.env.VITE_API_BASE_URL || '').replace(/\/$/, '');
+let refreshPromise: Promise | null = null;
+
+export class ApiError extends Error {
+ constructor(
+ message: string,
+ readonly status: number,
+ readonly details?: unknown,
+ ) {
+ super(message);
+ }
+}
+
+async function parseResponse(response: Response): Promise {
+ if (response.status === 204) return null;
+ const contentType = response.headers.get('content-type') || '';
+ if (contentType.includes('json')) return response.json();
+ const text = await response.text();
+ return text || null;
+}
+
+async function refreshTokens(): Promise {
+ const tokens = tokenStore.get();
+ if (!tokens?.refreshToken) return null;
+ const response = await fetch(`${apiBaseUrl}/api/auth/refresh`, {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify({ refreshToken: tokens.refreshToken }),
+ });
+ if (!response.ok) {
+ tokenStore.set(null);
+ return null;
+ }
+ const next = (await response.json()) as TokenPair;
+ tokenStore.set(next);
+ return next;
+}
+
+async function authorizedFetch(url: string, init: RequestInit, retry = true): Promise {
+ const accessToken = tokenStore.get()?.accessToken;
+ const headers = new Headers(init.headers);
+ if (accessToken) headers.set('Authorization', `Bearer ${accessToken}`);
+ const response = await fetch(`${apiBaseUrl}${url}`, { ...init, headers });
+ if (response.status !== 401 || !retry) return response;
+ refreshPromise ??= refreshTokens().finally(() => { refreshPromise = null; });
+ const refreshed = await refreshPromise;
+ return refreshed ? authorizedFetch(url, init, false) : response;
+}
+
+function appendQuery(url: URL, query: Record) {
+ for (const [key, value] of Object.entries(query)) {
+ if (value === undefined || value === null || value === '') continue;
+ if (Array.isArray(value)) value.forEach((item) => url.searchParams.append(key, String(item)));
+ else url.searchParams.set(key, String(value));
+ }
+}
+
+export async function apiRequest(
+ operation: PlatformOperation,
+ input: OperationInput = {},
+ signal?: AbortSignal,
+): Promise {
+ const pathValues = (input.path || {}) as Record;
+ let route = operation.path.replace(/\{([^}]+)\}/g, (_, name: string) => encodeURIComponent(String(pathValues[name] ?? '')));
+ const url = new URL(route, window.location.origin);
+ appendQuery(url, ((input.query || {}) as Record));
+ route = `${url.pathname}${url.search}`;
+ const headers: Record = {};
+ const init: RequestInit = { method: operation.method, headers, signal };
+ if (input.body !== undefined && operation.method !== 'GET') {
+ headers['Content-Type'] = 'application/json';
+ init.body = JSON.stringify(input.body);
+ }
+ const response = await authorizedFetch(route, init);
+ const payload = await parseResponse(response);
+ if (!response.ok) {
+ const problem = payload as { detail?: string; title?: string } | null;
+ throw new ApiError(problem?.detail || problem?.title || `请求失败(HTTP ${response.status})`, response.status, payload);
+ }
+ return payload as T;
+}
+
+export async function authRequest(path: string, body?: unknown): Promise {
+ const response = await fetch(`${apiBaseUrl}${path}`, {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/json' },
+ body: body === undefined ? undefined : JSON.stringify(body),
+ });
+ const payload = await parseResponse(response);
+ if (!response.ok) {
+ const problem = payload as { detail?: string; title?: string } | null;
+ throw new ApiError(problem?.detail || problem?.title || `请求失败(HTTP ${response.status})`, response.status, payload);
+ }
+ return payload as T;
+}
+
+export async function getCurrentUser(): Promise {
+ const response = await authorizedFetch('/api/me', { method: 'GET' });
+ const payload = await parseResponse(response);
+ if (!response.ok) throw new ApiError('登录会话已失效', response.status, payload);
+ return payload as T;
+}
diff --git a/Tiku.PlatformAdmin.Web/src/api/platform-operations.generated.ts b/Tiku.PlatformAdmin.Web/src/api/platform-operations.generated.ts
new file mode 100644
index 0000000..2828593
--- /dev/null
+++ b/Tiku.PlatformAdmin.Web/src/api/platform-operations.generated.ts
@@ -0,0 +1,31952 @@
+/* eslint-disable */
+// 由 scripts/generate-platform-operations.mjs 根据后端 OpenAPI 自动生成,请勿手改。
+import type { PlatformOperation } from './types';
+
+export const generatedAt = "2026-07-30T05:41:34.952Z";
+export const platformOperations = [
+ {
+ "id": "GET /api/backoffice/platform/bootstrap",
+ "method": "GET",
+ "path": "/api/backoffice/platform/bootstrap",
+ "tag": "平台端-后台权限",
+ "summary": "查询平台角色管理初始化数据",
+ "description": "",
+ "parameters": [],
+ "requestSchema": null,
+ "responseSchema": {
+ "$ref": "#/components/schemas/BackofficeBootstrap"
+ }
+ },
+ {
+ "id": "POST /api/backoffice/platform/roles",
+ "method": "POST",
+ "path": "/api/backoffice/platform/roles",
+ "tag": "平台端-后台权限",
+ "summary": "创建或更新平台后台角色",
+ "description": "",
+ "parameters": [],
+ "requestSchema": {
+ "$ref": "#/components/schemas/UpsertBackofficeRoleDto"
+ },
+ "responseSchema": {
+ "$ref": "#/components/schemas/BackofficeRoleItem"
+ }
+ },
+ {
+ "id": "PUT /api/backoffice/platform/roles/{roleId}/bindings",
+ "method": "PUT",
+ "path": "/api/backoffice/platform/roles/{roleId}/bindings",
+ "tag": "平台端-后台权限",
+ "summary": "替换平台后台角色权限绑定",
+ "description": "",
+ "parameters": [
+ {
+ "name": "roleId",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ ],
+ "requestSchema": {
+ "$ref": "#/components/schemas/ReplaceRoleBindingsDto"
+ },
+ "responseSchema": {
+ "$ref": "#/components/schemas/BackofficeRoleItem"
+ }
+ },
+ {
+ "id": "GET /api/backoffice/platform/ui-bootstrap",
+ "method": "GET",
+ "path": "/api/backoffice/platform/ui-bootstrap",
+ "tag": "平台端-后台权限",
+ "summary": "查询平台后台菜单与权限",
+ "description": "返回当前平台管理员可见的后台菜单、权限和模块启用状态。",
+ "parameters": [],
+ "requestSchema": null,
+ "responseSchema": {
+ "$ref": "#/components/schemas/BackofficeUiBootstrap"
+ }
+ },
+ {
+ "id": "PUT /api/backoffice/platform/users/{userId}/roles",
+ "method": "PUT",
+ "path": "/api/backoffice/platform/users/{userId}/roles",
+ "tag": "平台端-后台权限",
+ "summary": "替换平台用户后台角色",
+ "description": "",
+ "parameters": [
+ {
+ "name": "userId",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ ],
+ "requestSchema": {
+ "$ref": "#/components/schemas/ReplaceUserRolesDto"
+ },
+ "responseSchema": null
+ },
+ {
+ "id": "GET /api/platform-admin/audit-alerts",
+ "method": "GET",
+ "path": "/api/platform-admin/audit-alerts",
+ "tag": "平台端-平台管理",
+ "summary": "查询平台审计告警",
+ "description": "",
+ "parameters": [
+ {
+ "name": "Status",
+ "in": "query",
+ "description": "状态。",
+ "schema": {
+ "maxLength": 32,
+ "minLength": 0,
+ "type": "string"
+ }
+ },
+ {
+ "name": "Search",
+ "in": "query",
+ "description": "搜索关键字。",
+ "schema": {
+ "maxLength": 200,
+ "minLength": 0,
+ "type": "string"
+ }
+ },
+ {
+ "name": "Limit",
+ "in": "query",
+ "description": "返回数量上限。",
+ "schema": {
+ "maximum": 200,
+ "minimum": 1,
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ }
+ }
+ ],
+ "requestSchema": null,
+ "responseSchema": {
+ "$ref": "#/components/schemas/PlatformAuditAlertList"
+ }
+ },
+ {
+ "id": "POST /api/platform-admin/audit-alerts/status",
+ "method": "POST",
+ "path": "/api/platform-admin/audit-alerts/status",
+ "tag": "平台端-平台管理",
+ "summary": "更新平台审计告警状态",
+ "description": "",
+ "parameters": [],
+ "requestSchema": {
+ "$ref": "#/components/schemas/UpdatePlatformAuditAlertStatusDto"
+ },
+ "responseSchema": {
+ "$ref": "#/components/schemas/PlatformAuditAlert"
+ }
+ },
+ {
+ "id": "GET /api/platform-admin/audit-logs",
+ "method": "GET",
+ "path": "/api/platform-admin/audit-logs",
+ "tag": "平台端-平台管理",
+ "summary": "查询平台审计日志",
+ "description": "",
+ "parameters": [
+ {
+ "name": "Status",
+ "in": "query",
+ "description": "状态。",
+ "schema": {
+ "maxLength": 32,
+ "minLength": 0,
+ "type": "string"
+ }
+ },
+ {
+ "name": "Search",
+ "in": "query",
+ "description": "搜索关键字。",
+ "schema": {
+ "maxLength": 200,
+ "minLength": 0,
+ "type": "string"
+ }
+ },
+ {
+ "name": "Limit",
+ "in": "query",
+ "description": "返回数量上限。",
+ "schema": {
+ "maximum": 200,
+ "minimum": 1,
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ }
+ }
+ ],
+ "requestSchema": null,
+ "responseSchema": {
+ "$ref": "#/components/schemas/PlatformAuditLogList"
+ }
+ },
+ {
+ "id": "GET /api/platform-admin/domains",
+ "method": "GET",
+ "path": "/api/platform-admin/domains",
+ "tag": "平台端-平台管理",
+ "summary": "查询租户域名状态",
+ "description": "",
+ "parameters": [
+ {
+ "name": "Status",
+ "in": "query",
+ "description": "状态。",
+ "schema": {
+ "maxLength": 32,
+ "minLength": 0,
+ "type": "string"
+ }
+ },
+ {
+ "name": "Search",
+ "in": "query",
+ "description": "搜索关键字。",
+ "schema": {
+ "maxLength": 200,
+ "minLength": 0,
+ "type": "string"
+ }
+ },
+ {
+ "name": "Limit",
+ "in": "query",
+ "description": "返回数量上限。",
+ "schema": {
+ "maximum": 200,
+ "minimum": 1,
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ }
+ }
+ ],
+ "requestSchema": null,
+ "responseSchema": {
+ "$ref": "#/components/schemas/PlatformDomainList"
+ }
+ },
+ {
+ "id": "POST /api/platform-admin/domains/{domainId}/recheck",
+ "method": "POST",
+ "path": "/api/platform-admin/domains/{domainId}/recheck",
+ "tag": "平台端-平台管理",
+ "summary": "重新触发租户域名 DNS/TLS 验证",
+ "description": "",
+ "parameters": [
+ {
+ "name": "domainId",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ ],
+ "requestSchema": null,
+ "responseSchema": {
+ "$ref": "#/components/schemas/PlatformDomainRecheckResult"
+ }
+ },
+ {
+ "id": "GET /api/platform-admin/overview",
+ "method": "GET",
+ "path": "/api/platform-admin/overview",
+ "tag": "平台端-平台管理",
+ "summary": "查询平台经营概览",
+ "description": "",
+ "parameters": [],
+ "requestSchema": null,
+ "responseSchema": {
+ "$ref": "#/components/schemas/PlatformOverview"
+ }
+ },
+ {
+ "id": "GET /api/platform-admin/payment-settings/apps",
+ "method": "GET",
+ "path": "/api/platform-admin/payment-settings/apps",
+ "tag": "平台端-支付设置",
+ "summary": "查询平台支付应用",
+ "description": "",
+ "parameters": [
+ {
+ "name": "status",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "limit",
+ "in": "query",
+ "schema": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32",
+ "default": 100
+ }
+ }
+ ],
+ "requestSchema": null,
+ "responseSchema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/PlatformPaymentApp"
+ }
+ }
+ },
+ {
+ "id": "PUT /api/platform-admin/payment-settings/apps",
+ "method": "PUT",
+ "path": "/api/platform-admin/payment-settings/apps",
+ "tag": "平台端-支付设置",
+ "summary": "新增或更新平台支付应用",
+ "description": "",
+ "parameters": [],
+ "requestSchema": {
+ "$ref": "#/components/schemas/UpsertPlatformPaymentAppDto"
+ },
+ "responseSchema": {
+ "$ref": "#/components/schemas/PlatformPaymentApp"
+ }
+ },
+ {
+ "id": "GET /api/platform-admin/payment-settings/channels",
+ "method": "GET",
+ "path": "/api/platform-admin/payment-settings/channels",
+ "tag": "平台端-支付设置",
+ "summary": "查询平台支付渠道",
+ "description": "",
+ "parameters": [
+ {
+ "name": "appId",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "format": "uuid"
+ }
+ },
+ {
+ "name": "status",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "limit",
+ "in": "query",
+ "schema": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32",
+ "default": 100
+ }
+ }
+ ],
+ "requestSchema": null,
+ "responseSchema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/PlatformPaymentChannel"
+ }
+ }
+ },
+ {
+ "id": "PUT /api/platform-admin/payment-settings/channels",
+ "method": "PUT",
+ "path": "/api/platform-admin/payment-settings/channels",
+ "tag": "平台端-支付设置",
+ "summary": "新增或更新平台支付渠道",
+ "description": "",
+ "parameters": [],
+ "requestSchema": {
+ "$ref": "#/components/schemas/UpsertPlatformPaymentChannelDto"
+ },
+ "responseSchema": {
+ "$ref": "#/components/schemas/PlatformPaymentChannel"
+ }
+ },
+ {
+ "id": "POST /api/platform-admin/payment-settings/channels/{id}/disable",
+ "method": "POST",
+ "path": "/api/platform-admin/payment-settings/channels/{id}/disable",
+ "tag": "平台端-支付设置",
+ "summary": "禁用平台支付渠道",
+ "description": "",
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ ],
+ "requestSchema": null,
+ "responseSchema": {
+ "$ref": "#/components/schemas/PlatformPaymentChannel"
+ }
+ },
+ {
+ "id": "GET /api/platform-admin/payment-settings/events",
+ "method": "GET",
+ "path": "/api/platform-admin/payment-settings/events",
+ "tag": "平台端-支付设置",
+ "summary": "查询平台支付事件",
+ "description": "",
+ "parameters": [
+ {
+ "name": "status",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "limit",
+ "in": "query",
+ "schema": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32",
+ "default": 100
+ }
+ }
+ ],
+ "requestSchema": null,
+ "responseSchema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/PlatformBillingPaymentEvent"
+ }
+ }
+ },
+ {
+ "id": "GET /api/platform-admin/payment-settings/rebates/summary",
+ "method": "GET",
+ "path": "/api/platform-admin/payment-settings/rebates/summary",
+ "tag": "平台端-支付设置",
+ "summary": "查询平台返佣汇总",
+ "description": "",
+ "parameters": [],
+ "requestSchema": null,
+ "responseSchema": {
+ "$ref": "#/components/schemas/PlatformRebateSummary"
+ }
+ },
+ {
+ "id": "GET /api/platform-admin/question-banks",
+ "method": "GET",
+ "path": "/api/platform-admin/question-banks",
+ "tag": "平台端-公共题库",
+ "summary": "查询平台公共题库",
+ "description": "",
+ "parameters": [
+ {
+ "name": "keyword",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "status",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "requestSchema": null,
+ "responseSchema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/PlatformQuestionBankItem"
+ }
+ }
+ },
+ {
+ "id": "PUT /api/platform-admin/question-banks",
+ "method": "PUT",
+ "path": "/api/platform-admin/question-banks",
+ "tag": "平台端-公共题库",
+ "summary": "新增或更新平台公共题库",
+ "description": "",
+ "parameters": [],
+ "requestSchema": {
+ "$ref": "#/components/schemas/UpsertPlatformQuestionBankCommand"
+ },
+ "responseSchema": {
+ "$ref": "#/components/schemas/PlatformQuestionBankItem"
+ }
+ },
+ {
+ "id": "POST /api/platform-admin/question-banks/{bankId}/archive",
+ "method": "POST",
+ "path": "/api/platform-admin/question-banks/{bankId}/archive",
+ "tag": "平台端-公共题库",
+ "summary": "归档平台公共题库",
+ "description": "",
+ "parameters": [
+ {
+ "name": "bankId",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ ],
+ "requestSchema": null,
+ "responseSchema": {
+ "$ref": "#/components/schemas/PlatformQuestionBankItem"
+ }
+ },
+ {
+ "id": "GET /api/platform-admin/question-banks/{bankId}/nodes",
+ "method": "GET",
+ "path": "/api/platform-admin/question-banks/{bankId}/nodes",
+ "tag": "平台端-公共题库",
+ "summary": "查询公共题库内容结构",
+ "description": "",
+ "parameters": [
+ {
+ "name": "bankId",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ ],
+ "requestSchema": null,
+ "responseSchema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/PlatformQuestionBankNodeItem"
+ }
+ }
+ },
+ {
+ "id": "POST /api/platform-admin/question-banks/assets/upload-confirm",
+ "method": "POST",
+ "path": "/api/platform-admin/question-banks/assets/upload-confirm",
+ "tag": "平台端-公共题库",
+ "summary": "确认公共题库图片上传结果",
+ "description": "",
+ "parameters": [],
+ "requestSchema": {
+ "$ref": "#/components/schemas/AssetUploadConfirmDto"
+ },
+ "responseSchema": {
+ "$ref": "#/components/schemas/AssetUploadConfirmResult"
+ }
+ },
+ {
+ "id": "POST /api/platform-admin/question-banks/assets/upload-sign",
+ "method": "POST",
+ "path": "/api/platform-admin/question-banks/assets/upload-sign",
+ "tag": "平台端-公共题库",
+ "summary": "签发公共题库图片上传地址",
+ "description": "",
+ "parameters": [],
+ "requestSchema": {
+ "$ref": "#/components/schemas/AssetUploadSignDto"
+ },
+ "responseSchema": {
+ "$ref": "#/components/schemas/AssetUploadSignResult"
+ }
+ },
+ {
+ "id": "POST /api/platform-admin/question-banks/imports",
+ "method": "POST",
+ "path": "/api/platform-admin/question-banks/imports",
+ "tag": "平台端-公共题库",
+ "summary": "执行公共题库 JSON 导入",
+ "description": "",
+ "parameters": [],
+ "requestSchema": {
+ "$ref": "#/components/schemas/PlatformQuestionImportCommand"
+ },
+ "responseSchema": {
+ "$ref": "#/components/schemas/PlatformQuestionImportResult"
+ }
+ },
+ {
+ "id": "GET /api/platform-admin/question-banks/imports/{jobId}",
+ "method": "GET",
+ "path": "/api/platform-admin/question-banks/imports/{jobId}",
+ "tag": "平台端-公共题库",
+ "summary": "查询公共题库导入结果",
+ "description": "",
+ "parameters": [
+ {
+ "name": "jobId",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ ],
+ "requestSchema": null,
+ "responseSchema": {
+ "$ref": "#/components/schemas/ContentImportJobDetail"
+ }
+ },
+ {
+ "id": "POST /api/platform-admin/question-banks/imports/preview",
+ "method": "POST",
+ "path": "/api/platform-admin/question-banks/imports/preview",
+ "tag": "平台端-公共题库",
+ "summary": "预检公共题库 JSON 导入",
+ "description": "",
+ "parameters": [],
+ "requestSchema": {
+ "$ref": "#/components/schemas/PlatformQuestionImportCommand"
+ },
+ "responseSchema": {
+ "$ref": "#/components/schemas/PlatformQuestionImportResult"
+ }
+ },
+ {
+ "id": "PUT /api/platform-admin/question-banks/nodes",
+ "method": "PUT",
+ "path": "/api/platform-admin/question-banks/nodes",
+ "tag": "平台端-公共题库",
+ "summary": "新增或更新公共题库内容节点",
+ "description": "",
+ "parameters": [],
+ "requestSchema": {
+ "$ref": "#/components/schemas/UpsertPlatformQuestionBankNodeCommand"
+ },
+ "responseSchema": {
+ "$ref": "#/components/schemas/PlatformQuestionBankNodeItem"
+ }
+ },
+ {
+ "id": "POST /api/platform-admin/question-banks/nodes/{nodeId}/archive",
+ "method": "POST",
+ "path": "/api/platform-admin/question-banks/nodes/{nodeId}/archive",
+ "tag": "平台端-公共题库",
+ "summary": "归档公共题库内容节点",
+ "description": "",
+ "parameters": [
+ {
+ "name": "nodeId",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ ],
+ "requestSchema": null,
+ "responseSchema": {
+ "$ref": "#/components/schemas/PlatformQuestionBankNodeItem"
+ }
+ },
+ {
+ "id": "POST /api/platform-admin/question-banks/nodes/batch",
+ "method": "POST",
+ "path": "/api/platform-admin/question-banks/nodes/batch",
+ "tag": "平台端-公共题库",
+ "summary": "批量创建公共题库章节或试卷",
+ "description": "",
+ "parameters": [],
+ "requestSchema": {
+ "$ref": "#/components/schemas/BatchCreatePlatformQuestionBankNodesCommand"
+ },
+ "responseSchema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/PlatformQuestionBankNodeItem"
+ }
+ }
+ },
+ {
+ "id": "GET /api/platform-admin/question-banks/questions",
+ "method": "GET",
+ "path": "/api/platform-admin/question-banks/questions",
+ "tag": "平台端-公共题库",
+ "summary": "分页查询公共题库题目",
+ "description": "",
+ "parameters": [
+ {
+ "name": "questionBankId",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "format": "uuid"
+ }
+ },
+ {
+ "name": "contentNodeId",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "format": "uuid"
+ }
+ },
+ {
+ "name": "keyword",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "type",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "difficulty",
+ "in": "query",
+ "schema": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ }
+ },
+ {
+ "name": "status",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "page",
+ "in": "query",
+ "schema": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32",
+ "default": 1
+ }
+ },
+ {
+ "name": "pageSize",
+ "in": "query",
+ "schema": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32",
+ "default": 20
+ }
+ }
+ ],
+ "requestSchema": null,
+ "responseSchema": {
+ "$ref": "#/components/schemas/PlatformQuestionPage"
+ }
+ },
+ {
+ "id": "PUT /api/platform-admin/question-banks/questions",
+ "method": "PUT",
+ "path": "/api/platform-admin/question-banks/questions",
+ "tag": "平台端-公共题库",
+ "summary": "新增或更新公共题库题目并保留版本",
+ "description": "",
+ "parameters": [],
+ "requestSchema": {
+ "$ref": "#/components/schemas/UpsertPlatformQuestionCommand"
+ },
+ "responseSchema": {
+ "$ref": "#/components/schemas/PlatformQuestionItem"
+ }
+ },
+ {
+ "id": "POST /api/platform-admin/question-banks/questions/archive",
+ "method": "POST",
+ "path": "/api/platform-admin/question-banks/questions/archive",
+ "tag": "平台端-公共题库",
+ "summary": "批量归档公共题库题目",
+ "description": "",
+ "parameters": [],
+ "requestSchema": {
+ "$ref": "#/components/schemas/ArchivePlatformQuestionsCommand"
+ },
+ "responseSchema": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ }
+ },
+ {
+ "id": "GET /api/platform-admin/saas/catalog",
+ "method": "GET",
+ "path": "/api/platform-admin/saas/catalog",
+ "tag": "平台端-SaaS 套餐",
+ "summary": "查询平台 SaaS 商品目录",
+ "description": "",
+ "parameters": [],
+ "requestSchema": null,
+ "responseSchema": {
+ "$ref": "#/components/schemas/SaasCatalogSnapshot"
+ }
+ },
+ {
+ "id": "GET /api/platform-admin/saas/dunning/channels",
+ "method": "GET",
+ "path": "/api/platform-admin/saas/dunning/channels",
+ "tag": "平台端-平台管理",
+ "summary": "查询平台催缴通知渠道",
+ "description": "",
+ "parameters": [
+ {
+ "name": "Status",
+ "in": "query",
+ "description": "状态。",
+ "schema": {
+ "maxLength": 32,
+ "minLength": 0,
+ "type": "string"
+ }
+ },
+ {
+ "name": "Search",
+ "in": "query",
+ "description": "搜索关键字。",
+ "schema": {
+ "maxLength": 200,
+ "minLength": 0,
+ "type": "string"
+ }
+ },
+ {
+ "name": "Limit",
+ "in": "query",
+ "description": "返回数量上限。",
+ "schema": {
+ "maximum": 200,
+ "minimum": 1,
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ }
+ }
+ ],
+ "requestSchema": null,
+ "responseSchema": {
+ "$ref": "#/components/schemas/PlatformBillingDunningChannelList"
+ }
+ },
+ {
+ "id": "PUT /api/platform-admin/saas/dunning/channels",
+ "method": "PUT",
+ "path": "/api/platform-admin/saas/dunning/channels",
+ "tag": "平台端-平台管理",
+ "summary": "创建或更新平台催缴通知渠道",
+ "description": "",
+ "parameters": [],
+ "requestSchema": {
+ "$ref": "#/components/schemas/UpsertPlatformBillingDunningChannelDto"
+ },
+ "responseSchema": {
+ "$ref": "#/components/schemas/PlatformBillingDunningChannelItem"
+ }
+ },
+ {
+ "id": "POST /api/platform-admin/saas/dunning/channels/disable",
+ "method": "POST",
+ "path": "/api/platform-admin/saas/dunning/channels/disable",
+ "tag": "平台端-平台管理",
+ "summary": "禁用平台催缴通知渠道",
+ "description": "",
+ "parameters": [],
+ "requestSchema": {
+ "$ref": "#/components/schemas/DisablePlatformBillingDunningChannelDto"
+ },
+ "responseSchema": {
+ "$ref": "#/components/schemas/PlatformBillingDunningChannelItem"
+ }
+ },
+ {
+ "id": "GET /api/platform-admin/saas/dunning/events",
+ "method": "GET",
+ "path": "/api/platform-admin/saas/dunning/events",
+ "tag": "平台端-平台管理",
+ "summary": "查询平台催缴通知事件",
+ "description": "",
+ "parameters": [
+ {
+ "name": "Status",
+ "in": "query",
+ "description": "状态。",
+ "schema": {
+ "maxLength": 32,
+ "minLength": 0,
+ "type": "string"
+ }
+ },
+ {
+ "name": "Search",
+ "in": "query",
+ "description": "搜索关键字。",
+ "schema": {
+ "maxLength": 200,
+ "minLength": 0,
+ "type": "string"
+ }
+ },
+ {
+ "name": "Limit",
+ "in": "query",
+ "description": "返回数量上限。",
+ "schema": {
+ "maximum": 200,
+ "minimum": 1,
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ }
+ }
+ ],
+ "requestSchema": null,
+ "responseSchema": {
+ "$ref": "#/components/schemas/PlatformBillingDunningEventList"
+ }
+ },
+ {
+ "id": "GET /api/platform-admin/saas/dunning/events/detail",
+ "method": "GET",
+ "path": "/api/platform-admin/saas/dunning/events/detail",
+ "tag": "平台端-平台管理",
+ "summary": "查询平台催缴通知事件详情",
+ "description": "",
+ "parameters": [
+ {
+ "name": "eventId",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ ],
+ "requestSchema": null,
+ "responseSchema": {
+ "$ref": "#/components/schemas/PlatformBillingDunningEventItem"
+ }
+ },
+ {
+ "id": "POST /api/platform-admin/saas/dunning/events/retry",
+ "method": "POST",
+ "path": "/api/platform-admin/saas/dunning/events/retry",
+ "tag": "平台端-平台管理",
+ "summary": "重新标记平台催缴通知事件待发送",
+ "description": "",
+ "parameters": [],
+ "requestSchema": {
+ "$ref": "#/components/schemas/RetryPlatformBillingDunningEventDto"
+ },
+ "responseSchema": {
+ "$ref": "#/components/schemas/PlatformBillingDunningEventItem"
+ }
+ },
+ {
+ "id": "PUT /api/platform-admin/saas/feature-limits",
+ "method": "PUT",
+ "path": "/api/platform-admin/saas/feature-limits",
+ "tag": "平台端-SaaS 套餐",
+ "summary": "新增或更新 SaaS 功能限额",
+ "description": "",
+ "parameters": [],
+ "requestSchema": {
+ "$ref": "#/components/schemas/UpsertSaasFeatureLimitDto"
+ },
+ "responseSchema": {
+ "$ref": "#/components/schemas/SaasFeatureLimitDefinition"
+ }
+ },
+ {
+ "id": "PUT /api/platform-admin/saas/features",
+ "method": "PUT",
+ "path": "/api/platform-admin/saas/features",
+ "tag": "平台端-SaaS 套餐",
+ "summary": "新增或更新 SaaS 功能",
+ "description": "",
+ "parameters": [],
+ "requestSchema": {
+ "$ref": "#/components/schemas/UpsertSaasFeatureDto"
+ },
+ "responseSchema": {
+ "$ref": "#/components/schemas/SaasFeature"
+ }
+ },
+ {
+ "id": "GET /api/platform-admin/saas/invoices",
+ "method": "GET",
+ "path": "/api/platform-admin/saas/invoices",
+ "tag": "平台端-SaaS 套餐",
+ "summary": "查询平台 SaaS 发票",
+ "description": "",
+ "parameters": [
+ {
+ "name": "tenantId",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "format": "uuid"
+ }
+ },
+ {
+ "name": "status",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "limit",
+ "in": "query",
+ "schema": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32",
+ "default": 100
+ }
+ }
+ ],
+ "requestSchema": null,
+ "responseSchema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/PlatformBillingInvoice"
+ }
+ }
+ },
+ {
+ "id": "GET /api/platform-admin/saas/invoices/reminders",
+ "method": "GET",
+ "path": "/api/platform-admin/saas/invoices/reminders",
+ "tag": "平台端-SaaS 套餐",
+ "summary": "查询平台 SaaS 账单提醒",
+ "description": "",
+ "parameters": [
+ {
+ "name": "tenantId",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "format": "uuid"
+ }
+ },
+ {
+ "name": "status",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "limit",
+ "in": "query",
+ "schema": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32",
+ "default": 100
+ }
+ }
+ ],
+ "requestSchema": null,
+ "responseSchema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/PlatformBillingInvoiceReminder"
+ }
+ }
+ },
+ {
+ "id": "PUT /api/platform-admin/saas/offering-versions",
+ "method": "PUT",
+ "path": "/api/platform-admin/saas/offering-versions",
+ "tag": "平台端-SaaS 套餐",
+ "summary": "新增或更新 SaaS 套餐版本草稿",
+ "description": "",
+ "parameters": [],
+ "requestSchema": {
+ "$ref": "#/components/schemas/UpsertSaasOfferingVersionDto"
+ },
+ "responseSchema": {
+ "$ref": "#/components/schemas/SaasOfferingVersionItem"
+ }
+ },
+ {
+ "id": "POST /api/platform-admin/saas/offering-versions/{versionId}/clone",
+ "method": "POST",
+ "path": "/api/platform-admin/saas/offering-versions/{versionId}/clone",
+ "tag": "平台端-SaaS 套餐",
+ "summary": "克隆 SaaS 套餐版本",
+ "description": "",
+ "parameters": [
+ {
+ "name": "versionId",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ ],
+ "requestSchema": null,
+ "responseSchema": {
+ "$ref": "#/components/schemas/SaasOfferingVersionItem"
+ }
+ },
+ {
+ "id": "POST /api/platform-admin/saas/offering-versions/{versionId}/publish",
+ "method": "POST",
+ "path": "/api/platform-admin/saas/offering-versions/{versionId}/publish",
+ "tag": "平台端-SaaS 套餐",
+ "summary": "发布 SaaS 套餐版本",
+ "description": "",
+ "parameters": [
+ {
+ "name": "versionId",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ ],
+ "requestSchema": null,
+ "responseSchema": {
+ "$ref": "#/components/schemas/SaasOfferingVersionItem"
+ }
+ },
+ {
+ "id": "POST /api/platform-admin/saas/offering-versions/{versionId}/retire",
+ "method": "POST",
+ "path": "/api/platform-admin/saas/offering-versions/{versionId}/retire",
+ "tag": "平台端-SaaS 套餐",
+ "summary": "下架 SaaS 套餐版本",
+ "description": "",
+ "parameters": [
+ {
+ "name": "versionId",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ ],
+ "requestSchema": null,
+ "responseSchema": {
+ "$ref": "#/components/schemas/SaasOfferingVersionItem"
+ }
+ },
+ {
+ "id": "PUT /api/platform-admin/saas/offerings",
+ "method": "PUT",
+ "path": "/api/platform-admin/saas/offerings",
+ "tag": "平台端-SaaS 套餐",
+ "summary": "新增或更新 SaaS 套餐",
+ "description": "",
+ "parameters": [],
+ "requestSchema": {
+ "$ref": "#/components/schemas/UpsertSaasOfferingDto"
+ },
+ "responseSchema": {
+ "$ref": "#/components/schemas/SaasOffering"
+ }
+ },
+ {
+ "id": "GET /api/platform-admin/saas/orders",
+ "method": "GET",
+ "path": "/api/platform-admin/saas/orders",
+ "tag": "平台端-SaaS 套餐",
+ "summary": "查询平台 SaaS 订单",
+ "description": "",
+ "parameters": [
+ {
+ "name": "tenantId",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "format": "uuid"
+ }
+ },
+ {
+ "name": "status",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "limit",
+ "in": "query",
+ "schema": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32",
+ "default": 100
+ }
+ }
+ ],
+ "requestSchema": null,
+ "responseSchema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/PlatformBillingOrder"
+ }
+ }
+ },
+ {
+ "id": "GET /api/platform-admin/saas/payments",
+ "method": "GET",
+ "path": "/api/platform-admin/saas/payments",
+ "tag": "平台端-SaaS 套餐",
+ "summary": "查询平台 SaaS 支付记录",
+ "description": "",
+ "parameters": [
+ {
+ "name": "tenantId",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "format": "uuid"
+ }
+ },
+ {
+ "name": "status",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "limit",
+ "in": "query",
+ "schema": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32",
+ "default": 100
+ }
+ }
+ ],
+ "requestSchema": null,
+ "responseSchema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/PlatformBillingPayment"
+ }
+ }
+ },
+ {
+ "id": "POST /api/platform-admin/saas/payments/manual/confirm",
+ "method": "POST",
+ "path": "/api/platform-admin/saas/payments/manual/confirm",
+ "tag": "平台端-SaaS 套餐",
+ "summary": "确认平台手工支付",
+ "description": "",
+ "parameters": [],
+ "requestSchema": {
+ "$ref": "#/components/schemas/ConfirmManualPlatformPaymentDto"
+ },
+ "responseSchema": {
+ "$ref": "#/components/schemas/PlatformBillingPayment"
+ }
+ },
+ {
+ "id": "GET /api/platform-admin/saas/refunds",
+ "method": "GET",
+ "path": "/api/platform-admin/saas/refunds",
+ "tag": "平台端-SaaS 套餐",
+ "summary": "查询平台 SaaS 退款记录",
+ "description": "",
+ "parameters": [
+ {
+ "name": "tenantId",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "format": "uuid"
+ }
+ },
+ {
+ "name": "status",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "limit",
+ "in": "query",
+ "schema": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32",
+ "default": 100
+ }
+ }
+ ],
+ "requestSchema": null,
+ "responseSchema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/PlatformBillingRefund"
+ }
+ }
+ },
+ {
+ "id": "GET /api/platform-admin/saas/subscriptions",
+ "method": "GET",
+ "path": "/api/platform-admin/saas/subscriptions",
+ "tag": "平台端-SaaS 套餐",
+ "summary": "查询租户 SaaS 订阅",
+ "description": "",
+ "parameters": [
+ {
+ "name": "tenantId",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "format": "uuid"
+ }
+ },
+ {
+ "name": "status",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "limit",
+ "in": "query",
+ "schema": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32",
+ "default": 100
+ }
+ }
+ ],
+ "requestSchema": null,
+ "responseSchema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/TenantSaasSubscription"
+ }
+ }
+ },
+ {
+ "id": "PUT /api/platform-admin/saas/tenant-feature-overrides",
+ "method": "PUT",
+ "path": "/api/platform-admin/saas/tenant-feature-overrides",
+ "tag": "平台端-SaaS 套餐",
+ "summary": "新增或更新租户功能覆盖规则",
+ "description": "",
+ "parameters": [],
+ "requestSchema": {
+ "$ref": "#/components/schemas/UpsertTenantFeatureOverrideDto"
+ },
+ "responseSchema": {
+ "$ref": "#/components/schemas/TenantFeatureOverride"
+ }
+ },
+ {
+ "id": "GET /api/platform-admin/saas/usage",
+ "method": "GET",
+ "path": "/api/platform-admin/saas/usage",
+ "tag": "平台端-SaaS 套餐",
+ "summary": "查询租户 SaaS 用量",
+ "description": "",
+ "parameters": [
+ {
+ "name": "tenantId",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "format": "uuid"
+ }
+ },
+ {
+ "name": "limit",
+ "in": "query",
+ "schema": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32",
+ "default": 100
+ }
+ }
+ ],
+ "requestSchema": null,
+ "responseSchema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/TenantFeatureUsage"
+ }
+ }
+ },
+ {
+ "id": "GET /api/platform-admin/staff",
+ "method": "GET",
+ "path": "/api/platform-admin/staff",
+ "tag": "平台端-平台管理",
+ "summary": "查询平台员工列表",
+ "description": "",
+ "parameters": [
+ {
+ "name": "Status",
+ "in": "query",
+ "description": "状态。",
+ "schema": {
+ "maxLength": 32,
+ "minLength": 0,
+ "type": "string"
+ }
+ },
+ {
+ "name": "Search",
+ "in": "query",
+ "description": "搜索关键字。",
+ "schema": {
+ "maxLength": 200,
+ "minLength": 0,
+ "type": "string"
+ }
+ },
+ {
+ "name": "Limit",
+ "in": "query",
+ "description": "返回数量上限。",
+ "schema": {
+ "maximum": 200,
+ "minimum": 1,
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ }
+ }
+ ],
+ "requestSchema": null,
+ "responseSchema": {
+ "$ref": "#/components/schemas/PlatformStaffList"
+ }
+ },
+ {
+ "id": "PUT /api/platform-admin/staff",
+ "method": "PUT",
+ "path": "/api/platform-admin/staff",
+ "tag": "平台端-平台管理",
+ "summary": "创建或更新平台员工",
+ "description": "",
+ "parameters": [],
+ "requestSchema": {
+ "$ref": "#/components/schemas/UpsertPlatformStaffDto"
+ },
+ "responseSchema": {
+ "$ref": "#/components/schemas/PlatformStaffItem"
+ }
+ },
+ {
+ "id": "PATCH /api/platform-admin/staff/status",
+ "method": "PATCH",
+ "path": "/api/platform-admin/staff/status",
+ "tag": "平台端-平台管理",
+ "summary": "启用或禁用平台员工",
+ "description": "",
+ "parameters": [],
+ "requestSchema": {
+ "$ref": "#/components/schemas/UpdatePlatformStaffStatusDto"
+ },
+ "responseSchema": {
+ "$ref": "#/components/schemas/PlatformStaffItem"
+ }
+ },
+ {
+ "id": "GET /api/platform-admin/tenant-capabilities/crm/configs",
+ "method": "GET",
+ "path": "/api/platform-admin/tenant-capabilities/crm/configs",
+ "tag": "平台端-租户 CRM 能力",
+ "summary": "查询租户 CRM 配置",
+ "description": "",
+ "parameters": [
+ {
+ "name": "TenantId",
+ "in": "query",
+ "description": "租户 ID。",
+ "schema": {
+ "type": "string",
+ "format": "uuid"
+ }
+ },
+ {
+ "name": "Status",
+ "in": "query",
+ "description": "状态。",
+ "schema": {
+ "maxLength": 50,
+ "minLength": 0,
+ "type": "string"
+ }
+ },
+ {
+ "name": "Limit",
+ "in": "query",
+ "description": "返回数量上限。",
+ "schema": {
+ "maximum": 500,
+ "minimum": 1,
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ }
+ }
+ ],
+ "requestSchema": null,
+ "responseSchema": {
+ "$ref": "#/components/schemas/PlatformTenantCapabilityListOfPlatformCrmConfigItem"
+ }
+ },
+ {
+ "id": "PUT /api/platform-admin/tenant-capabilities/crm/configs",
+ "method": "PUT",
+ "path": "/api/platform-admin/tenant-capabilities/crm/configs",
+ "tag": "平台端-租户 CRM 能力",
+ "summary": "新增或更新租户 CRM 配置",
+ "description": "",
+ "parameters": [],
+ "requestSchema": {
+ "$ref": "#/components/schemas/UpsertPlatformCrmConfigDto"
+ },
+ "responseSchema": {
+ "$ref": "#/components/schemas/PlatformCrmConfigItem"
+ }
+ },
+ {
+ "id": "GET /api/platform-admin/tenant-capabilities/crm/leads",
+ "method": "GET",
+ "path": "/api/platform-admin/tenant-capabilities/crm/leads",
+ "tag": "平台端-租户 CRM 能力",
+ "summary": "查询租户 CRM 线索队列",
+ "description": "",
+ "parameters": [
+ {
+ "name": "TenantId",
+ "in": "query",
+ "description": "租户 ID。",
+ "schema": {
+ "type": "string",
+ "format": "uuid"
+ }
+ },
+ {
+ "name": "Status",
+ "in": "query",
+ "description": "状态。",
+ "schema": {
+ "maxLength": 50,
+ "minLength": 0,
+ "type": "string"
+ }
+ },
+ {
+ "name": "Limit",
+ "in": "query",
+ "description": "返回数量上限。",
+ "schema": {
+ "maximum": 500,
+ "minimum": 1,
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ }
+ }
+ ],
+ "requestSchema": null,
+ "responseSchema": {
+ "$ref": "#/components/schemas/PlatformTenantCapabilityListOfCrmWebhookQueueItem"
+ }
+ },
+ {
+ "id": "POST /api/platform-admin/tenant-capabilities/crm/leads/retry",
+ "method": "POST",
+ "path": "/api/platform-admin/tenant-capabilities/crm/leads/retry",
+ "tag": "平台端-租户 CRM 能力",
+ "summary": "重试租户 CRM 线索推送",
+ "description": "",
+ "parameters": [],
+ "requestSchema": {
+ "$ref": "#/components/schemas/RetryPlatformCrmLeadDto"
+ },
+ "responseSchema": {
+ "$ref": "#/components/schemas/CrmWebhookQueueItem"
+ }
+ },
+ {
+ "id": "GET /api/platform-admin/tenant-capabilities/crm/logs",
+ "method": "GET",
+ "path": "/api/platform-admin/tenant-capabilities/crm/logs",
+ "tag": "平台端-租户 CRM 能力",
+ "summary": "查询租户 CRM 推送日志",
+ "description": "",
+ "parameters": [
+ {
+ "name": "QueueId",
+ "in": "query",
+ "description": "队列任务 ID。",
+ "schema": {
+ "type": "string",
+ "format": "uuid"
+ }
+ },
+ {
+ "name": "TenantId",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "format": "uuid"
+ }
+ },
+ {
+ "name": "Status",
+ "in": "query",
+ "schema": {
+ "maxLength": 50,
+ "minLength": 0,
+ "type": "string"
+ }
+ },
+ {
+ "name": "Limit",
+ "in": "query",
+ "schema": {
+ "maximum": 500,
+ "minimum": 1,
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ }
+ }
+ ],
+ "requestSchema": null,
+ "responseSchema": {
+ "$ref": "#/components/schemas/PlatformTenantCapabilityListOfCrmWebhookLog"
+ }
+ },
+ {
+ "id": "GET /api/platform-admin/tenant-capabilities/payments/apps",
+ "method": "GET",
+ "path": "/api/platform-admin/tenant-capabilities/payments/apps",
+ "tag": "平台端-租户支付能力",
+ "summary": "查询租户支付应用",
+ "description": "",
+ "parameters": [
+ {
+ "name": "TenantId",
+ "in": "query",
+ "description": "租户 ID。",
+ "schema": {
+ "type": "string",
+ "format": "uuid"
+ }
+ },
+ {
+ "name": "Status",
+ "in": "query",
+ "description": "状态。",
+ "schema": {
+ "maxLength": 50,
+ "minLength": 0,
+ "type": "string"
+ }
+ },
+ {
+ "name": "Limit",
+ "in": "query",
+ "description": "返回数量上限。",
+ "schema": {
+ "maximum": 500,
+ "minimum": 1,
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ }
+ }
+ ],
+ "requestSchema": null,
+ "responseSchema": {
+ "$ref": "#/components/schemas/PlatformTenantCapabilityListOfTenantExternalProviderItem"
+ }
+ },
+ {
+ "id": "PUT /api/platform-admin/tenant-capabilities/payments/apps",
+ "method": "PUT",
+ "path": "/api/platform-admin/tenant-capabilities/payments/apps",
+ "tag": "平台端-租户支付能力",
+ "summary": "新增或更新租户支付应用",
+ "description": "",
+ "parameters": [],
+ "requestSchema": {
+ "$ref": "#/components/schemas/UpsertPlatformTenantPaymentAppDto"
+ },
+ "responseSchema": {
+ "$ref": "#/components/schemas/TenantExternalProviderItem"
+ }
+ },
+ {
+ "id": "GET /api/platform-admin/tenant-capabilities/payments/events",
+ "method": "GET",
+ "path": "/api/platform-admin/tenant-capabilities/payments/events",
+ "tag": "平台端-租户支付能力",
+ "summary": "查询租户支付事件",
+ "description": "",
+ "parameters": [
+ {
+ "name": "TenantId",
+ "in": "query",
+ "description": "租户 ID。",
+ "schema": {
+ "type": "string",
+ "format": "uuid"
+ }
+ },
+ {
+ "name": "Status",
+ "in": "query",
+ "description": "状态。",
+ "schema": {
+ "maxLength": 50,
+ "minLength": 0,
+ "type": "string"
+ }
+ },
+ {
+ "name": "Limit",
+ "in": "query",
+ "description": "返回数量上限。",
+ "schema": {
+ "maximum": 500,
+ "minimum": 1,
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ }
+ }
+ ],
+ "requestSchema": null,
+ "responseSchema": {
+ "$ref": "#/components/schemas/PlatformTenantCapabilityListOfObject"
+ }
+ },
+ {
+ "id": "GET /api/platform-admin/tenant-capabilities/sms/channels",
+ "method": "GET",
+ "path": "/api/platform-admin/tenant-capabilities/sms/channels",
+ "tag": "平台端-租户短信能力",
+ "summary": "查询租户短信渠道",
+ "description": "",
+ "parameters": [
+ {
+ "name": "TenantId",
+ "in": "query",
+ "description": "租户 ID。",
+ "schema": {
+ "type": "string",
+ "format": "uuid"
+ }
+ },
+ {
+ "name": "Status",
+ "in": "query",
+ "description": "状态。",
+ "schema": {
+ "maxLength": 50,
+ "minLength": 0,
+ "type": "string"
+ }
+ },
+ {
+ "name": "Limit",
+ "in": "query",
+ "description": "返回数量上限。",
+ "schema": {
+ "maximum": 500,
+ "minimum": 1,
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ }
+ }
+ ],
+ "requestSchema": null,
+ "responseSchema": {
+ "$ref": "#/components/schemas/PlatformTenantCapabilityListOfPlatformSmsChannelItem"
+ }
+ },
+ {
+ "id": "PUT /api/platform-admin/tenant-capabilities/sms/channels",
+ "method": "PUT",
+ "path": "/api/platform-admin/tenant-capabilities/sms/channels",
+ "tag": "平台端-租户短信能力",
+ "summary": "新增或更新租户短信渠道",
+ "description": "",
+ "parameters": [],
+ "requestSchema": {
+ "$ref": "#/components/schemas/UpsertPlatformSmsChannelDto"
+ },
+ "responseSchema": {
+ "$ref": "#/components/schemas/PlatformSmsChannelItem"
+ }
+ },
+ {
+ "id": "POST /api/platform-admin/tenant-capabilities/sms/channels/{id}/disable",
+ "method": "POST",
+ "path": "/api/platform-admin/tenant-capabilities/sms/channels/{id}/disable",
+ "tag": "平台端-租户短信能力",
+ "summary": "禁用租户短信渠道",
+ "description": "",
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ ],
+ "requestSchema": null,
+ "responseSchema": {
+ "$ref": "#/components/schemas/PlatformSmsChannelItem"
+ }
+ },
+ {
+ "id": "GET /api/platform-admin/tenant-capabilities/sms/logs",
+ "method": "GET",
+ "path": "/api/platform-admin/tenant-capabilities/sms/logs",
+ "tag": "平台端-租户短信能力",
+ "summary": "查询租户短信发送日志",
+ "description": "",
+ "parameters": [
+ {
+ "name": "TenantId",
+ "in": "query",
+ "description": "租户 ID。",
+ "schema": {
+ "type": "string",
+ "format": "uuid"
+ }
+ },
+ {
+ "name": "Status",
+ "in": "query",
+ "description": "状态。",
+ "schema": {
+ "maxLength": 50,
+ "minLength": 0,
+ "type": "string"
+ }
+ },
+ {
+ "name": "Limit",
+ "in": "query",
+ "description": "返回数量上限。",
+ "schema": {
+ "maximum": 500,
+ "minimum": 1,
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ }
+ }
+ ],
+ "requestSchema": null,
+ "responseSchema": {
+ "$ref": "#/components/schemas/PlatformTenantCapabilityListOfSmsSendLog"
+ }
+ },
+ {
+ "id": "GET /api/platform-admin/tenant-capabilities/sms/templates",
+ "method": "GET",
+ "path": "/api/platform-admin/tenant-capabilities/sms/templates",
+ "tag": "平台端-租户短信能力",
+ "summary": "查询租户短信模板",
+ "description": "",
+ "parameters": [
+ {
+ "name": "TenantId",
+ "in": "query",
+ "description": "租户 ID。",
+ "schema": {
+ "type": "string",
+ "format": "uuid"
+ }
+ },
+ {
+ "name": "Status",
+ "in": "query",
+ "description": "状态。",
+ "schema": {
+ "maxLength": 50,
+ "minLength": 0,
+ "type": "string"
+ }
+ },
+ {
+ "name": "Limit",
+ "in": "query",
+ "description": "返回数量上限。",
+ "schema": {
+ "maximum": 500,
+ "minimum": 1,
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ }
+ }
+ ],
+ "requestSchema": null,
+ "responseSchema": {
+ "$ref": "#/components/schemas/PlatformTenantCapabilityListOfPlatformSmsTemplateItem"
+ }
+ },
+ {
+ "id": "PUT /api/platform-admin/tenant-capabilities/sms/templates",
+ "method": "PUT",
+ "path": "/api/platform-admin/tenant-capabilities/sms/templates",
+ "tag": "平台端-租户短信能力",
+ "summary": "新增或更新租户短信模板",
+ "description": "",
+ "parameters": [],
+ "requestSchema": {
+ "$ref": "#/components/schemas/UpsertPlatformSmsTemplateDto"
+ },
+ "responseSchema": {
+ "$ref": "#/components/schemas/PlatformSmsTemplateItem"
+ }
+ },
+ {
+ "id": "POST /api/platform-admin/tenant-capabilities/sms/templates/{id}/disable",
+ "method": "POST",
+ "path": "/api/platform-admin/tenant-capabilities/sms/templates/{id}/disable",
+ "tag": "平台端-租户短信能力",
+ "summary": "禁用租户短信模板",
+ "description": "",
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ ],
+ "requestSchema": null,
+ "responseSchema": {
+ "$ref": "#/components/schemas/PlatformSmsTemplateItem"
+ }
+ },
+ {
+ "id": "POST /api/platform-admin/tenant-capabilities/sms/templates/{id}/submit-review",
+ "method": "POST",
+ "path": "/api/platform-admin/tenant-capabilities/sms/templates/{id}/submit-review",
+ "tag": "平台端-租户短信能力",
+ "summary": "提交租户短信模板审核",
+ "description": "",
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ ],
+ "requestSchema": null,
+ "responseSchema": {
+ "$ref": "#/components/schemas/PlatformSmsTemplateItem"
+ }
+ },
+ {
+ "id": "GET /api/platform-admin/tenants",
+ "method": "GET",
+ "path": "/api/platform-admin/tenants",
+ "tag": "平台端-平台管理",
+ "summary": "查询平台租户列表",
+ "description": "",
+ "parameters": [
+ {
+ "name": "Status",
+ "in": "query",
+ "description": "状态。",
+ "schema": {
+ "maxLength": 32,
+ "minLength": 0,
+ "type": "string"
+ }
+ },
+ {
+ "name": "Search",
+ "in": "query",
+ "description": "搜索关键字。",
+ "schema": {
+ "maxLength": 200,
+ "minLength": 0,
+ "type": "string"
+ }
+ },
+ {
+ "name": "Limit",
+ "in": "query",
+ "description": "返回数量上限。",
+ "schema": {
+ "maximum": 200,
+ "minimum": 1,
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ }
+ }
+ ],
+ "requestSchema": null,
+ "responseSchema": {
+ "$ref": "#/components/schemas/PlatformTenantList"
+ }
+ },
+ {
+ "id": "POST /api/platform-admin/tenants",
+ "method": "POST",
+ "path": "/api/platform-admin/tenants",
+ "tag": "平台端-平台管理",
+ "summary": "创建平台租户",
+ "description": "",
+ "parameters": [],
+ "requestSchema": {
+ "$ref": "#/components/schemas/CreatePlatformTenantDto"
+ },
+ "responseSchema": {
+ "$ref": "#/components/schemas/PlatformTenantProvisioningResult"
+ }
+ },
+ {
+ "id": "PUT /api/platform-admin/tenants/billing-profile",
+ "method": "PUT",
+ "path": "/api/platform-admin/tenants/billing-profile",
+ "tag": "平台端-平台管理",
+ "summary": "保存租户账务与开票资料",
+ "description": "",
+ "parameters": [],
+ "requestSchema": {
+ "$ref": "#/components/schemas/UpsertPlatformTenantBillingProfileDto"
+ },
+ "responseSchema": {
+ "$ref": "#/components/schemas/TenantBillingProfileItem"
+ }
+ },
+ {
+ "id": "GET /api/platform-admin/tenants/detail",
+ "method": "GET",
+ "path": "/api/platform-admin/tenants/detail",
+ "tag": "平台端-平台管理",
+ "summary": "查询平台租户详情",
+ "description": "",
+ "parameters": [
+ {
+ "name": "tenantId",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ ],
+ "requestSchema": null,
+ "responseSchema": {
+ "$ref": "#/components/schemas/PlatformTenantDetail"
+ }
+ },
+ {
+ "id": "PATCH /api/platform-admin/tenants/status",
+ "method": "PATCH",
+ "path": "/api/platform-admin/tenants/status",
+ "tag": "平台端-平台管理",
+ "summary": "更新租户业务与账务状态",
+ "description": "",
+ "parameters": [],
+ "requestSchema": {
+ "$ref": "#/components/schemas/UpdatePlatformTenantStatusDto"
+ },
+ "responseSchema": {
+ "$ref": "#/components/schemas/PlatformTenantItem"
+ }
+ }
+] as const satisfies readonly PlatformOperation[];
+export const openApiSchemas = {
+ "ActivationCodeItem": {
+ "required": [
+ "id",
+ "batchId",
+ "code",
+ "days",
+ "isUsed",
+ "usedBy",
+ "usedAt",
+ "saleType",
+ "soldTo",
+ "remark",
+ "createdAt"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "batchId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "code": {
+ "type": "string"
+ },
+ "days": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "isUsed": {
+ "type": "boolean"
+ },
+ "usedBy": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "usedAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "saleType": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "soldTo": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "remark": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+ },
+ "ActivationCodeList": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ActivationCodeItem"
+ }
+ }
+ }
+ },
+ "AdminOrderList": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/CommerceOrderItem"
+ }
+ }
+ }
+ },
+ "AdminPaymentList": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/CommercePaymentItem"
+ }
+ }
+ }
+ },
+ "AnnouncementCatalogItem": {
+ "required": [
+ "id",
+ "legacyId",
+ "content",
+ "link",
+ "backgroundColor",
+ "order",
+ "isActive"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "content": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "link": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "backgroundColor": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "order": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "isActive": {
+ "type": "boolean"
+ }
+ }
+ },
+ "AnswerRecordItem": {
+ "required": [
+ "id",
+ "sessionQuestionId",
+ "practiceSessionId",
+ "selectedOptions",
+ "answerText",
+ "isCorrect",
+ "answeredAt"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "sessionQuestionId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "practiceSessionId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "selectedOptions": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "answerText": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "isCorrect": {
+ "type": [
+ "null",
+ "boolean"
+ ]
+ },
+ "answeredAt": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+ },
+ "AppAssetCatalogItem": {
+ "required": [
+ "id",
+ "legacyId",
+ "assetKey",
+ "fileName",
+ "description",
+ "metadata"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "assetKey": {
+ "type": "string"
+ },
+ "fileName": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "description": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ }
+ },
+ "ArchivePlatformQuestionsCommand": {
+ "required": [
+ "questionIds"
+ ],
+ "type": "object",
+ "properties": {
+ "questionIds": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ }
+ },
+ "AssetAccessActorRole": {
+ "type": "integer"
+ },
+ "AssetAccessDisposition": {
+ "type": "integer"
+ },
+ "AssetAccessPrincipalDto": {
+ "required": [
+ "userId",
+ "isMember",
+ "hasSvip"
+ ],
+ "type": "object",
+ "properties": {
+ "userId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "isMember": {
+ "type": "boolean"
+ },
+ "hasSvip": {
+ "type": "boolean"
+ }
+ },
+ "description": "资产访问Principal请求 DTO。"
+ },
+ "AssetAccessResponseDto": {
+ "required": [
+ "item",
+ "access",
+ "url",
+ "watermark"
+ ],
+ "type": "object",
+ "properties": {
+ "item": {
+ "$ref": "#/components/schemas/ContentAssetAccessSummaryDto"
+ },
+ "access": {
+ "$ref": "#/components/schemas/AssetAccessPrincipalDto"
+ },
+ "url": {
+ "$ref": "#/components/schemas/SignedStorageUrlDto"
+ },
+ "watermark": {
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ },
+ "description": "资产访问签名响应。"
+ },
+ "AssetAccessResult": {
+ "type": "integer"
+ },
+ "AssetAccessSignDto": {
+ "required": [
+ "assetId"
+ ],
+ "type": "object",
+ "properties": {
+ "assetId": {
+ "type": "string",
+ "description": "资产 ID。",
+ "format": "uuid"
+ },
+ "expiresInSeconds": {
+ "maximum": 3600,
+ "minimum": 60,
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "description": "有效期秒数。",
+ "format": "int32"
+ }
+ },
+ "description": "创建资产访问签名请求。"
+ },
+ "AssetAccessType": {
+ "type": "integer"
+ },
+ "AssetManagementSignedAccessResult": {
+ "required": [
+ "item",
+ "url"
+ ],
+ "type": "object",
+ "properties": {
+ "item": {
+ "$ref": "#/components/schemas/ContentAssetManagementItem"
+ },
+ "url": {
+ "$ref": "#/components/schemas/ObjectStorageSignedUrl"
+ }
+ }
+ },
+ "AssetPreviewStatus": {
+ "type": "integer"
+ },
+ "AssetSecurityRiskLevel": {
+ "type": "integer"
+ },
+ "AssetSecurityScanStatus": {
+ "type": "integer"
+ },
+ "AssetStorageProvider": {
+ "type": "integer"
+ },
+ "AssetUploadConfirmDto": {
+ "required": [
+ "assetId"
+ ],
+ "type": "object",
+ "properties": {
+ "assetId": {
+ "type": "string",
+ "description": "资产 ID。",
+ "format": "uuid"
+ },
+ "mimeType": {
+ "maxLength": 200,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "MIME 类型。"
+ },
+ "fileSizeBytes": {
+ "maximum": 9223372036854776000,
+ "minimum": 0,
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "description": "文件大小,单位为字节。",
+ "format": "int64"
+ },
+ "checksumSha256": {
+ "pattern": "^[A-Fa-f0-9]{64}$",
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "SHA-256 校验值。"
+ }
+ },
+ "description": "确认资产上传请求。"
+ },
+ "AssetUploadConfirmResult": {
+ "required": [
+ "item",
+ "metadata"
+ ],
+ "type": "object",
+ "properties": {
+ "item": {
+ "$ref": "#/components/schemas/ContentAssetManagementItem"
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/ObjectStorageMetadata"
+ }
+ }
+ },
+ "AssetUploadSignDto": {
+ "required": [
+ "fileName",
+ "mimeType"
+ ],
+ "type": "object",
+ "properties": {
+ "assetId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "资产 ID。",
+ "format": "uuid"
+ },
+ "regionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "地区 ID。",
+ "format": "uuid"
+ },
+ "subjectId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "科目 ID。",
+ "format": "uuid"
+ },
+ "categoryId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "分类 ID。",
+ "format": "uuid"
+ },
+ "contentNodeId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "内容节点 ID。",
+ "format": "uuid"
+ },
+ "assetKey": {
+ "maxLength": 200,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "资产键。"
+ },
+ "title": {
+ "maxLength": 300,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "标题。"
+ },
+ "category": {
+ "maxLength": 100,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "分类。"
+ },
+ "description": {
+ "maxLength": 1000,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "说明。"
+ },
+ "fileName": {
+ "maxLength": 500,
+ "minLength": 0,
+ "type": "string",
+ "description": "文件名。"
+ },
+ "mimeType": {
+ "maxLength": 200,
+ "minLength": 0,
+ "type": "string",
+ "description": "MIME 类型。"
+ },
+ "fileSizeBytes": {
+ "maximum": 9223372036854776000,
+ "minimum": 0,
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "description": "文件大小,单位为字节。",
+ "format": "int64"
+ },
+ "checksumSha256": {
+ "pattern": "^[A-Fa-f0-9]{64}$",
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "SHA-256 校验值。"
+ },
+ "assetType": {
+ "maxLength": 50,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "资产类型。"
+ },
+ "visibility": {
+ "maxLength": 50,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "可见性。"
+ },
+ "isPublic": {
+ "type": [
+ "null",
+ "boolean"
+ ],
+ "description": "是否公开。"
+ },
+ "provider": {
+ "maxLength": 50,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "服务提供方。"
+ },
+ "bucket": {
+ "maxLength": 200,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "存储桶。"
+ },
+ "objectKey": {
+ "maxLength": 1000,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "对象存储键。"
+ },
+ "expiresInSeconds": {
+ "maximum": 3600,
+ "minimum": 1,
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "description": "有效期秒数。",
+ "format": "int32"
+ },
+ "metadata": {
+ "description": "扩展元数据。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ },
+ "description": "创建资产上传签名请求。"
+ },
+ "AssetUploadSignResult": {
+ "required": [
+ "item",
+ "upload"
+ ],
+ "type": "object",
+ "properties": {
+ "item": {
+ "$ref": "#/components/schemas/ContentAssetManagementItem"
+ },
+ "upload": {
+ "$ref": "#/components/schemas/ObjectStorageSignedUrl"
+ }
+ }
+ },
+ "AssetUploadStatus": {
+ "type": "integer"
+ },
+ "AuthenticatedUserDto": {
+ "type": "object",
+ "properties": {
+ "userId": {
+ "type": "string",
+ "description": "用户 ID。",
+ "format": "uuid"
+ },
+ "phone": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "手机号。"
+ },
+ "email": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "邮箱。"
+ },
+ "name": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "名称。"
+ },
+ "realm": {
+ "description": "认证域。",
+ "$ref": "#/components/schemas/AuthRealm"
+ },
+ "tenant": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "description": "租户成员摘要。",
+ "$ref": "#/components/schemas/TenantMembershipSummary"
+ }
+ ]
+ },
+ "tokens": {
+ "description": "访问令牌和刷新令牌。",
+ "$ref": "#/components/schemas/AuthTokenPair"
+ }
+ },
+ "description": "Authenticated用户请求 DTO。"
+ },
+ "AuthenticationResultDto": {
+ "type": "object",
+ "properties": {
+ "status": {
+ "description": "状态。",
+ "$ref": "#/components/schemas/AuthenticationStatus"
+ },
+ "user": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "description": "用户信息。",
+ "$ref": "#/components/schemas/AuthenticatedUserDto"
+ }
+ ]
+ },
+ "challengeToken": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "挑战令牌。"
+ },
+ "challengeExpiresAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "挑战令牌过期时间。",
+ "format": "date-time"
+ }
+ },
+ "description": "登录认证结果。"
+ },
+ "AuthenticationStatus": {
+ "type": "integer"
+ },
+ "AuthRealm": {
+ "type": "integer"
+ },
+ "AuthTokenPair": {
+ "required": [
+ "accessToken",
+ "refreshToken",
+ "accessTokenExpiresAt",
+ "refreshTokenExpiresAt"
+ ],
+ "type": "object",
+ "properties": {
+ "accessToken": {
+ "type": "string",
+ "description": "用于访问 API 的 JWT access token。"
+ },
+ "refreshToken": {
+ "type": "string",
+ "description": "用于刷新会话的 refresh token,服务端只保存哈希。"
+ },
+ "accessTokenExpiresAt": {
+ "type": "string",
+ "description": "access token 过期时间。",
+ "format": "date-time"
+ },
+ "refreshTokenExpiresAt": {
+ "type": "string",
+ "description": "refresh token 过期时间。",
+ "format": "date-time"
+ }
+ },
+ "description": "认证令牌对。"
+ },
+ "BackendPermissionArea": {
+ "type": "integer"
+ },
+ "BackendRoleStatus": {
+ "type": "integer"
+ },
+ "BackgroundJobItem": {
+ "required": [
+ "id",
+ "tenantId",
+ "jobType",
+ "status",
+ "retryCount",
+ "maxRetries",
+ "runAfter",
+ "startedAt",
+ "completedAt",
+ "lastError",
+ "outputAssetId",
+ "result"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "tenantId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "jobType": {
+ "type": "string"
+ },
+ "status": {
+ "$ref": "#/components/schemas/BackgroundJobStatus"
+ },
+ "retryCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "maxRetries": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "runAfter": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "startedAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "completedAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "lastError": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "outputAssetId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "result": {
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ }
+ },
+ "BackgroundJobStatus": {
+ "type": "integer"
+ },
+ "BackofficeBootstrap": {
+ "required": [
+ "permissions",
+ "menus",
+ "roles"
+ ],
+ "type": "object",
+ "properties": {
+ "permissions": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/BackofficePermissionItem"
+ }
+ },
+ "menus": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/BackofficeMenuItem"
+ }
+ },
+ "roles": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/BackofficeRoleItem"
+ }
+ }
+ }
+ },
+ "BackofficeMenuItem": {
+ "required": [
+ "id",
+ "code",
+ "parentCode",
+ "title",
+ "area",
+ "path",
+ "icon",
+ "permissionCode",
+ "sortOrder",
+ "isActive"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "code": {
+ "type": "string"
+ },
+ "parentCode": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "title": {
+ "type": "string"
+ },
+ "area": {
+ "$ref": "#/components/schemas/BackendPermissionArea"
+ },
+ "path": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "icon": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "permissionCode": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "sortOrder": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "isActive": {
+ "type": "boolean"
+ }
+ }
+ },
+ "BackofficePermissionItem": {
+ "required": [
+ "id",
+ "code",
+ "name",
+ "area",
+ "permissionModuleCode",
+ "description",
+ "sortOrder"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "code": {
+ "type": "string"
+ },
+ "name": {
+ "type": "string"
+ },
+ "area": {
+ "$ref": "#/components/schemas/BackendPermissionArea"
+ },
+ "permissionModuleCode": {
+ "type": "string"
+ },
+ "description": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "sortOrder": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ }
+ }
+ },
+ "BackofficeRoleItem": {
+ "required": [
+ "id",
+ "code",
+ "name",
+ "status",
+ "isSystem",
+ "description",
+ "permissionCodes",
+ "menuCodes"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "code": {
+ "type": "string"
+ },
+ "name": {
+ "type": "string"
+ },
+ "status": {
+ "$ref": "#/components/schemas/BackendRoleStatus"
+ },
+ "isSystem": {
+ "type": "boolean"
+ },
+ "description": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "permissionCodes": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "menuCodes": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "dataScope": {}
+ }
+ },
+ "BackofficeUiBootstrap": {
+ "required": [
+ "permissionCodes",
+ "menus",
+ "enabledFeatures",
+ "quotas"
+ ],
+ "type": "object",
+ "properties": {
+ "permissionCodes": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "menus": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/BackofficeMenuItem"
+ }
+ },
+ "enabledFeatures": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "quotas": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/FeatureQuotaSnapshot"
+ }
+ }
+ }
+ },
+ "BadgeItem": {
+ "required": [
+ "id",
+ "name",
+ "description",
+ "category",
+ "iconUrl",
+ "level",
+ "unlockType",
+ "conditionExtra",
+ "isUnlocked",
+ "grantedAt",
+ "note",
+ "order"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "name": {
+ "type": "string"
+ },
+ "description": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "category": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "iconUrl": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "level": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "unlockType": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "conditionExtra": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "isUnlocked": {
+ "type": "boolean"
+ },
+ "grantedAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "note": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "order": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ }
+ }
+ },
+ "BadgeList": {
+ "required": [
+ "items",
+ "total",
+ "unlocked",
+ "includeLocked"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/BadgeItem"
+ }
+ },
+ "total": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "unlocked": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "includeLocked": {
+ "type": "boolean"
+ }
+ }
+ },
+ "BannerCatalogItem": {
+ "required": [
+ "id",
+ "legacyId",
+ "regionId",
+ "title",
+ "subtitle",
+ "content",
+ "buttonText",
+ "buttonLink",
+ "backgroundColor",
+ "borderColor",
+ "order",
+ "isActive"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "regionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "title": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "subtitle": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "content": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "buttonText": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "buttonLink": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "backgroundColor": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "borderColor": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "order": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "isActive": {
+ "type": "boolean"
+ }
+ }
+ },
+ "BatchCreatePlatformQuestionBankNodesCommand": {
+ "required": [
+ "questionBankId",
+ "parentId",
+ "nodeType",
+ "names"
+ ],
+ "type": "object",
+ "properties": {
+ "questionBankId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "parentId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "nodeType": {
+ "$ref": "#/components/schemas/ContentNodeType"
+ },
+ "names": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "BillingStatus": {
+ "type": "integer"
+ },
+ "BindReferralDto": {
+ "required": [
+ "refCode"
+ ],
+ "type": "object",
+ "properties": {
+ "refCode": {
+ "maxLength": 100,
+ "minLength": 0,
+ "type": "string",
+ "description": "推荐码。"
+ },
+ "source": {
+ "maxLength": 100,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "来源。"
+ },
+ "metadata": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "description": "扩展元数据。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ ]
+ }
+ },
+ "description": "绑定推荐请求 DTO。"
+ },
+ "CatalogListOfAnnouncementCatalogItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/AnnouncementCatalogItem"
+ }
+ }
+ }
+ },
+ "CatalogListOfAppAssetCatalogItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/AppAssetCatalogItem"
+ }
+ }
+ }
+ },
+ "CatalogListOfBannerCatalogItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/BannerCatalogItem"
+ }
+ }
+ }
+ },
+ "CatalogListOfCategoryCatalogItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/CategoryCatalogItem"
+ }
+ }
+ }
+ },
+ "CatalogListOfCollectionQuestionCatalogItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/CollectionQuestionCatalogItem"
+ }
+ }
+ }
+ },
+ "CatalogListOfContentAssetAccessEventItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ContentAssetAccessEventItem"
+ }
+ }
+ }
+ },
+ "CatalogListOfContentAssetCatalogItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ContentAssetCatalogItem"
+ }
+ }
+ }
+ },
+ "CatalogListOfContentAssetManagementItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ContentAssetManagementItem"
+ }
+ }
+ }
+ },
+ "CatalogListOfContentAssetSecurityScanEventItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ContentAssetSecurityScanEventItem"
+ }
+ }
+ }
+ },
+ "CatalogListOfContentEntryCatalogItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ContentEntryCatalogItem"
+ }
+ }
+ }
+ },
+ "CatalogListOfContentEntryManagementItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ContentEntryManagementItem"
+ }
+ }
+ }
+ },
+ "CatalogListOfContentImportIssueModel": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ContentImportIssueModel"
+ }
+ }
+ }
+ },
+ "CatalogListOfContentImportJobItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ContentImportJobItem"
+ }
+ }
+ }
+ },
+ "CatalogListOfContentNodeCatalogItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ContentNodeCatalogItem"
+ }
+ }
+ }
+ },
+ "CatalogListOfContentNodeManagementItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ContentNodeManagementItem"
+ }
+ }
+ }
+ },
+ "CatalogListOfExamDateCatalogItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ExamDateCatalogItem"
+ }
+ }
+ }
+ },
+ "CatalogListOfFaqCatalogItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/FaqCatalogItem"
+ }
+ }
+ }
+ },
+ "CatalogListOfHandbookChapter": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/HandbookChapter"
+ }
+ }
+ }
+ },
+ "CatalogListOfHandbookChapterCatalogItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/HandbookChapterCatalogItem"
+ }
+ }
+ }
+ },
+ "CatalogListOfHandbookEntry": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/HandbookEntry"
+ }
+ }
+ }
+ },
+ "CatalogListOfHandbookEntryCatalogItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/HandbookEntryCatalogItem"
+ }
+ }
+ }
+ },
+ "CatalogListOfHandbookSubject": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/HandbookSubject"
+ }
+ }
+ }
+ },
+ "CatalogListOfHandbookSubjectCatalogItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/HandbookSubjectCatalogItem"
+ }
+ }
+ }
+ },
+ "CatalogListOfImageAssetCatalogItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ImageAssetCatalogItem"
+ }
+ }
+ }
+ },
+ "CatalogListOfint": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ }
+ }
+ }
+ },
+ "CatalogListOfMajor": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/Major"
+ }
+ }
+ }
+ },
+ "CatalogListOfMajorCatalogItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/MajorCatalogItem"
+ }
+ }
+ }
+ },
+ "CatalogListOfModuleNodeCatalogItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ModuleNodeCatalogItem"
+ }
+ }
+ }
+ },
+ "CatalogListOfOperationContentItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/OperationContentItem"
+ }
+ }
+ }
+ },
+ "CatalogListOfPracticeBlueprintCatalogItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/PracticeBlueprintCatalogItem"
+ }
+ }
+ }
+ },
+ "CatalogListOfPracticeBlueprintManagementItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/PracticeBlueprintManagementItem"
+ }
+ }
+ }
+ },
+ "CatalogListOfProductCatalogItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ProductCatalogItem"
+ }
+ }
+ }
+ },
+ "CatalogListOfQuestionBankCatalogItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/QuestionBankCatalogItem"
+ }
+ }
+ }
+ },
+ "CatalogListOfQuestionCatalogItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/QuestionCatalogItem"
+ }
+ }
+ }
+ },
+ "CatalogListOfQuestionCollectionCatalogItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/QuestionCollectionCatalogItem"
+ }
+ }
+ }
+ },
+ "CatalogListOfQuestionCollectionManagementItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/QuestionCollectionManagementItem"
+ }
+ }
+ }
+ },
+ "CatalogListOfQuestionVersionCatalogItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/QuestionVersionCatalogItem"
+ }
+ }
+ }
+ },
+ "CatalogListOfQuestionVideoCatalogItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/QuestionVideoCatalogItem"
+ }
+ }
+ }
+ },
+ "CatalogListOfRegionCatalogItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/RegionCatalogItem"
+ }
+ }
+ }
+ },
+ "CatalogListOfRegionModuleCatalogItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/RegionModuleCatalogItem"
+ }
+ }
+ }
+ },
+ "CatalogListOfSchool": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/School"
+ }
+ }
+ }
+ },
+ "CatalogListOfSchoolCatalogItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/SchoolCatalogItem"
+ }
+ }
+ }
+ },
+ "CatalogListOfScorelineField": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ScorelineField"
+ }
+ }
+ }
+ },
+ "CatalogListOfScorelineFieldItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ScorelineFieldItem"
+ }
+ }
+ }
+ },
+ "CatalogListOfScorelineRecord": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ScorelineRecord"
+ }
+ }
+ }
+ },
+ "CatalogListOfScorelineRecordItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ScorelineRecordItem"
+ }
+ }
+ }
+ },
+ "CatalogListOfScorelineTrendItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ScorelineTrendItem"
+ }
+ }
+ }
+ },
+ "CatalogListOfSubjectCatalogItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/SubjectCatalogItem"
+ }
+ }
+ }
+ },
+ "CatalogListOfSvipPlanCatalogItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/SvipPlanCatalogItem"
+ }
+ }
+ }
+ },
+ "CatalogListOfTenantAdminAuditLogItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/TenantAdminAuditLogItem"
+ }
+ }
+ }
+ },
+ "CatalogListOfTenantAdminBadgeGrantItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/TenantAdminBadgeGrantItem"
+ }
+ }
+ }
+ },
+ "CatalogListOfTenantAdminBadgeItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/TenantAdminBadgeItem"
+ }
+ }
+ }
+ },
+ "CatalogListOfTenantAdminClassMemberItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/TenantAdminClassMemberItem"
+ }
+ }
+ }
+ },
+ "CatalogListOfTenantAdminFeedbackItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/TenantAdminFeedbackItem"
+ }
+ }
+ }
+ },
+ "CatalogListOfTenantAdminMemberItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/TenantAdminMemberItem"
+ }
+ }
+ }
+ },
+ "CatalogListOfTenantAdminNotificationItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/TenantAdminNotificationItem"
+ }
+ }
+ }
+ },
+ "CatalogListOfTenantAdminStudentFollowupItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/TenantAdminStudentFollowupItem"
+ }
+ }
+ }
+ },
+ "CatalogListOfTenantAdminStudentNoteItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/TenantAdminStudentNoteItem"
+ }
+ }
+ }
+ },
+ "CatalogListOfTenantDomainItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/TenantDomainItem"
+ }
+ }
+ }
+ },
+ "CatalogListOfTenantIdentityProviderItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/TenantIdentityProviderItem"
+ }
+ }
+ }
+ },
+ "CatalogListOfTenantSupervisionRuleItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/TenantSupervisionRuleItem"
+ }
+ }
+ }
+ },
+ "CatalogListOfTenantThemeTemplateItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/TenantThemeTemplateItem"
+ }
+ }
+ }
+ },
+ "CatalogListOfVideoExplanationCatalogItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/VideoExplanationCatalogItem"
+ }
+ }
+ }
+ },
+ "CatalogListOfVideoManagementItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/VideoManagementItem"
+ }
+ }
+ }
+ },
+ "CatalogListOfVocabularyUnit": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/VocabularyUnit"
+ }
+ }
+ }
+ },
+ "CatalogListOfVocabularyUnitCatalogItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/VocabularyUnitCatalogItem"
+ }
+ }
+ }
+ },
+ "CatalogListOfVocabularyWord": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/VocabularyWord"
+ }
+ }
+ }
+ },
+ "CatalogListOfVocabularyWordCatalogItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/VocabularyWordCatalogItem"
+ }
+ }
+ }
+ },
+ "CategoryCatalogItem": {
+ "required": [
+ "id",
+ "legacyId",
+ "subjectId",
+ "nodeId",
+ "name",
+ "categoryType",
+ "order",
+ "svipQuestionLimit"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "subjectId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "nodeId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "name": {
+ "type": "string"
+ },
+ "categoryType": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "$ref": "#/components/schemas/CategoryType"
+ }
+ ]
+ },
+ "order": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "svipQuestionLimit": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ }
+ }
+ },
+ "CategoryType": {
+ "type": "integer"
+ },
+ "ChangeTenantSubscriptionDto": {
+ "required": [
+ "baseOfferingVersionId",
+ "addOnOfferingVersionIds",
+ "idempotencyKey"
+ ],
+ "type": "object",
+ "properties": {
+ "baseOfferingVersionId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "addOnOfferingVersionIds": {
+ "type": [
+ "null",
+ "array"
+ ],
+ "items": {
+ "type": "string",
+ "format": "uuid"
+ }
+ },
+ "idempotencyKey": {
+ "type": "string"
+ }
+ },
+ "description": "变更租户订阅请求 DTO。"
+ },
+ "CheckCommerceCouponDto": {
+ "required": [
+ "planId"
+ ],
+ "type": "object",
+ "properties": {
+ "couponCode": {
+ "maxLength": 100,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "优惠券码。"
+ },
+ "couponRedemptionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "优惠券领取记录 ID。",
+ "format": "uuid"
+ },
+ "planId": {
+ "type": "string",
+ "description": "套餐 ID。",
+ "format": "uuid"
+ },
+ "quantity": {
+ "maximum": 99,
+ "minimum": 1,
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "description": "数量。",
+ "format": "int32"
+ },
+ "regionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "地区 ID。",
+ "format": "uuid"
+ }
+ },
+ "description": "校验交易优惠券请求 DTO。"
+ },
+ "CheckInResult": {
+ "required": [
+ "checkInDate",
+ "alreadyCheckedIn",
+ "points",
+ "balanceAfter",
+ "claimId",
+ "scoreEventId"
+ ],
+ "type": "object",
+ "properties": {
+ "checkInDate": {
+ "type": "string",
+ "format": "date"
+ },
+ "alreadyCheckedIn": {
+ "type": "boolean"
+ },
+ "points": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "balanceAfter": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "claimId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "scoreEventId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ }
+ }
+ },
+ "ClaimCommerceCouponDto": {
+ "required": [
+ "couponCode"
+ ],
+ "type": "object",
+ "properties": {
+ "couponCode": {
+ "maxLength": 100,
+ "minLength": 0,
+ "type": "string",
+ "description": "优惠券码。"
+ }
+ },
+ "description": "领取交易优惠券请求 DTO。"
+ },
+ "ClaimPointTaskDto": {
+ "required": [
+ "taskKey"
+ ],
+ "type": "object",
+ "properties": {
+ "taskKey": {
+ "maxLength": 100,
+ "minLength": 0,
+ "type": "string",
+ "description": "任务键。"
+ },
+ "sourceType": {
+ "maxLength": 100,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "来源类型。"
+ },
+ "sourceId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "来源 ID。",
+ "format": "uuid"
+ }
+ },
+ "description": "领取积分任务请求 DTO。"
+ },
+ "CodeBatchItem": {
+ "required": [
+ "id",
+ "name",
+ "totalCount",
+ "days",
+ "regionId",
+ "saleType",
+ "channel",
+ "defaultUnitPriceCents",
+ "costPriceCents",
+ "issuedAt",
+ "remark",
+ "createdAt"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "name": {
+ "type": "string"
+ },
+ "totalCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "days": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "regionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "saleType": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "channel": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "defaultUnitPriceCents": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "costPriceCents": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "issuedAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "remark": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+ },
+ "CollectionItemsReplaceResult": {
+ "required": [
+ "collectionId",
+ "questionCount",
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "collectionId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "questionCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/QuestionCollectionItemManagementItem"
+ }
+ }
+ }
+ },
+ "CollectionQuestionCatalogItem": {
+ "required": [
+ "id",
+ "legacyId",
+ "entryId",
+ "contentNodeId",
+ "primaryCollectionId",
+ "subjectId",
+ "categoryId",
+ "nodeId",
+ "type",
+ "typeLabel",
+ "difficulty",
+ "tags",
+ "examMarkers",
+ "mediaUrl",
+ "hasVideoExplanation",
+ "sectionKey",
+ "score",
+ "order",
+ "versionId",
+ "content",
+ "options",
+ "correctOptionIndex",
+ "correctOptionIndices",
+ "answerText",
+ "explanation",
+ "subQuestions",
+ "codeLang",
+ "codeTemplate"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "entryId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "contentNodeId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "primaryCollectionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "subjectId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "categoryId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "nodeId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "type": {
+ "type": "string"
+ },
+ "typeLabel": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "difficulty": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "tags": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "examMarkers": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "mediaUrl": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "hasVideoExplanation": {
+ "type": "boolean"
+ },
+ "sectionKey": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "score": {
+ "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
+ "type": [
+ "null",
+ "number",
+ "string"
+ ],
+ "format": "double"
+ },
+ "order": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "versionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "content": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "options": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "correctOptionIndex": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "correctOptionIndices": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "answerText": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "explanation": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "subQuestions": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "codeLang": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "codeTemplate": {
+ "type": [
+ "null",
+ "string"
+ ]
+ }
+ }
+ },
+ "CollectionQuestionDto": {
+ "required": [
+ "questionId",
+ "source"
+ ],
+ "type": "object",
+ "properties": {
+ "questionId": {
+ "type": "string",
+ "description": "题目 ID。",
+ "format": "uuid"
+ },
+ "source": {
+ "description": "来源。",
+ "$ref": "#/components/schemas/QuestionSource"
+ },
+ "sectionKey": {
+ "maxLength": 100,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "分段键。"
+ },
+ "order": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "description": "显示顺序。",
+ "format": "int32"
+ },
+ "score": {
+ "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
+ "type": [
+ "null",
+ "number",
+ "string"
+ ],
+ "description": "分数。",
+ "format": "double"
+ },
+ "required": {
+ "type": [
+ "null",
+ "boolean"
+ ],
+ "description": "是否必填。"
+ },
+ "metadata": {
+ "description": "扩展元数据。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ },
+ "description": "题集题目请求 DTO。"
+ },
+ "CommerceAdjustmentDirection": {
+ "type": "integer"
+ },
+ "CommerceAdjustmentVoucher": {
+ "type": "object",
+ "properties": {
+ "issueId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "batchId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "itemId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "orderId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "paymentId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "refundRequestId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "createdBy": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "reviewedBy": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "voucherNo": {
+ "type": "string"
+ },
+ "status": {
+ "$ref": "#/components/schemas/CommerceAdjustmentVoucherStatus"
+ },
+ "direction": {
+ "$ref": "#/components/schemas/CommerceAdjustmentDirection"
+ },
+ "amountCents": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "currency": {
+ "type": "string"
+ },
+ "reason": {
+ "type": "string"
+ },
+ "proofAssetKey": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "reviewedAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "closedAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updatedAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "tenantId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ },
+ "CommerceAdjustmentVoucherEvent": {
+ "type": "object",
+ "properties": {
+ "tenantId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "voucherId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "fromStatus": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "$ref": "#/components/schemas/CommerceAdjustmentVoucherStatus"
+ }
+ ]
+ },
+ "toStatus": {
+ "$ref": "#/components/schemas/CommerceAdjustmentVoucherStatus"
+ },
+ "actorUserId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "note": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "details": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ },
+ "CommerceAdjustmentVoucherStatus": {
+ "type": "integer"
+ },
+ "CommerceCouponCheckResult": {
+ "required": [
+ "valid",
+ "reasonCode",
+ "couponId",
+ "couponRedemptionId",
+ "couponCode",
+ "originalAmountCents",
+ "discountCents",
+ "payableAmountCents",
+ "payablePrice"
+ ],
+ "type": "object",
+ "properties": {
+ "valid": {
+ "type": "boolean"
+ },
+ "reasonCode": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "couponId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "couponRedemptionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "couponCode": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "originalAmountCents": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "discountCents": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "payableAmountCents": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "payablePrice": {
+ "type": "string"
+ }
+ }
+ },
+ "CommerceCouponItem": {
+ "required": [
+ "id",
+ "couponId",
+ "couponCode",
+ "status",
+ "planId",
+ "regionId",
+ "discountType",
+ "discountValue",
+ "discountPreviewCents",
+ "discountPreview",
+ "validFrom",
+ "validTo",
+ "claimedAt",
+ "usedAt"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "couponId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "couponCode": {
+ "type": "string"
+ },
+ "status": {
+ "type": "string"
+ },
+ "planId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "regionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "discountType": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "discountValue": {
+ "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
+ "type": [
+ "null",
+ "number",
+ "string"
+ ],
+ "format": "double"
+ },
+ "discountPreviewCents": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "discountPreview": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "validFrom": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "validTo": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "claimedAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "usedAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ }
+ }
+ },
+ "CommerceCouponList": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/CommerceCouponItem"
+ }
+ }
+ }
+ },
+ "CommerceOrderItem": {
+ "required": [
+ "id",
+ "orderNo",
+ "status",
+ "planId",
+ "regionId",
+ "productType",
+ "productName",
+ "amountCents",
+ "price",
+ "payMethod",
+ "payProvider",
+ "tradeNo",
+ "days",
+ "paidAt",
+ "createdAt",
+ "rawPayload"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "orderNo": {
+ "type": "string"
+ },
+ "status": {
+ "type": "string"
+ },
+ "planId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "regionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "productType": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "productName": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "amountCents": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "price": {
+ "type": "string"
+ },
+ "payMethod": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "payProvider": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "tradeNo": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "days": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "paidAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "rawPayload": {
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ }
+ },
+ "CommerceOrderList": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/CommerceOrderItem"
+ }
+ }
+ }
+ },
+ "CommercePaymentItem": {
+ "required": [
+ "id",
+ "orderId",
+ "orderNo",
+ "provider",
+ "method",
+ "status",
+ "amountCents",
+ "price",
+ "providerTradeNo",
+ "paidAt",
+ "clientPayload",
+ "rawPayload"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "orderId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "orderNo": {
+ "type": "string"
+ },
+ "provider": {
+ "type": "string"
+ },
+ "method": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "status": {
+ "type": "string"
+ },
+ "amountCents": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "price": {
+ "type": "string"
+ },
+ "providerTradeNo": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "paidAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "clientPayload": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "rawPayload": {
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ }
+ },
+ "CommerceReconciliationBatch": {
+ "type": "object",
+ "properties": {
+ "createdBy": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "provider": {
+ "type": "string"
+ },
+ "billDate": {
+ "type": "string",
+ "format": "date"
+ },
+ "billType": {
+ "$ref": "#/components/schemas/ReconciliationBillType"
+ },
+ "source": {
+ "$ref": "#/components/schemas/ReconciliationSource"
+ },
+ "sourceName": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "sourceHash": {
+ "type": "string"
+ },
+ "status": {
+ "$ref": "#/components/schemas/ReconciliationBatchStatus"
+ },
+ "totalCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "matchedCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "mismatchCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "missingLocalCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "missingProviderCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "duplicateCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "ignoredCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "amountCents": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "refundAmountCents": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "feeCents": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "completedAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "error": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updatedAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "tenantId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ },
+ "CommerceReconciliationIssue": {
+ "type": "object",
+ "properties": {
+ "batchId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "itemId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "orderId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "paymentId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "refundRequestId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "assignedTo": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "createdBy": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "resolvedBy": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "issueNo": {
+ "type": "string"
+ },
+ "provider": {
+ "type": "string"
+ },
+ "transactionType": {
+ "$ref": "#/components/schemas/ReconciliationTransactionType"
+ },
+ "issueCode": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "matchStatus": {
+ "$ref": "#/components/schemas/ReconciliationIssueMatchStatus"
+ },
+ "severity": {
+ "$ref": "#/components/schemas/NotificationSeverity"
+ },
+ "status": {
+ "$ref": "#/components/schemas/ReconciliationIssueStatus"
+ },
+ "resolutionType": {
+ "$ref": "#/components/schemas/ReconciliationResolutionType"
+ },
+ "orderNo": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "refundNo": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "providerTradeNo": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "providerRefundNo": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "amountCents": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "refundAmountCents": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "resolvedAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "dueAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "summary": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "resolutionNote": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updatedAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "tenantId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ },
+ "CommerceReconciliationIssueEvent": {
+ "type": "object",
+ "properties": {
+ "tenantId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "issueId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "fromStatus": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "$ref": "#/components/schemas/ReconciliationIssueStatus"
+ }
+ ]
+ },
+ "toStatus": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "$ref": "#/components/schemas/ReconciliationIssueStatus"
+ }
+ ]
+ },
+ "eventType": {
+ "type": "string"
+ },
+ "actorUserId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "note": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "details": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ },
+ "CommerceReconciliationItem": {
+ "type": "object",
+ "properties": {
+ "tenantId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "batchId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "orderId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "paymentId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "refundRequestId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "rowNo": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "provider": {
+ "type": "string"
+ },
+ "transactionType": {
+ "$ref": "#/components/schemas/ReconciliationTransactionType"
+ },
+ "providerTradeNo": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "providerRefundNo": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "orderNo": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "refundNo": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "amountCents": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "refundAmountCents": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "feeCents": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "paidAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "refundedAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "providerStatus": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "localStatus": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "matchStatus": {
+ "$ref": "#/components/schemas/ReconciliationMatchStatus"
+ },
+ "severity": {
+ "$ref": "#/components/schemas/NotificationSeverity"
+ },
+ "issueCode": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "details": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ },
+ "CommerceRefundEvent": {
+ "type": "object",
+ "properties": {
+ "tenantId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "refundRequestId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "fromStatus": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "$ref": "#/components/schemas/CommerceRefundStatus"
+ }
+ ]
+ },
+ "toStatus": {
+ "$ref": "#/components/schemas/CommerceRefundStatus"
+ },
+ "eventType": {
+ "type": "string"
+ },
+ "actorUserId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "details": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ },
+ "CommerceRefundRequest": {
+ "type": "object",
+ "properties": {
+ "orderId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "paymentId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "requestedBy": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "reviewedBy": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "processedBy": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "refundNo": {
+ "type": "string"
+ },
+ "provider": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "providerRefundNo": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "status": {
+ "$ref": "#/components/schemas/CommerceRefundStatus"
+ },
+ "amountCents": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "reason": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "entitlementAction": {
+ "$ref": "#/components/schemas/RefundEntitlementAction"
+ },
+ "requestedAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "reviewedAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "processedAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "succeededAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "failedAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "cancelledAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "failureReason": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updatedAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "tenantId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ },
+ "CommerceRefundStatus": {
+ "type": "integer"
+ },
+ "CommissionExportItem": {
+ "required": [
+ "settlementId",
+ "filename",
+ "format",
+ "mimeType",
+ "rowCount",
+ "contentBase64",
+ "sha256",
+ "sizeBytes"
+ ],
+ "type": "object",
+ "properties": {
+ "settlementId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "filename": {
+ "type": "string"
+ },
+ "format": {
+ "type": "string"
+ },
+ "mimeType": {
+ "type": "string"
+ },
+ "rowCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "contentBase64": {
+ "type": "string"
+ },
+ "sha256": {
+ "type": "string"
+ },
+ "sizeBytes": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ }
+ }
+ },
+ "CommissionListOfCommissionProofItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/CommissionProofItem"
+ }
+ }
+ }
+ },
+ "CommissionListOfCommissionSettlementItemDto": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/CommissionSettlementItemDto"
+ }
+ }
+ }
+ },
+ "CommissionListOfCommissionSourceItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/CommissionSourceItem"
+ }
+ }
+ }
+ },
+ "CommissionProofItem": {
+ "required": [
+ "id",
+ "settlementId",
+ "proofType",
+ "status",
+ "title",
+ "assetId",
+ "externalUrl",
+ "amountCents",
+ "paymentMethod",
+ "paymentAccount",
+ "paidAt",
+ "reviewedAt"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "settlementId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "proofType": {
+ "type": "string"
+ },
+ "status": {
+ "type": "string"
+ },
+ "title": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "assetId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "externalUrl": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "amountCents": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "paymentMethod": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "paymentAccount": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "paidAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "reviewedAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ }
+ }
+ },
+ "CommissionSettingsItem": {
+ "required": [
+ "defaultRate",
+ "minSettlementCents",
+ "settlementCycle",
+ "config"
+ ],
+ "type": "object",
+ "properties": {
+ "defaultRate": {
+ "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
+ "type": [
+ "number",
+ "string"
+ ],
+ "format": "double"
+ },
+ "minSettlementCents": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "settlementCycle": {
+ "type": "string"
+ },
+ "config": {
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ }
+ },
+ "CommissionSettlementItemDto": {
+ "required": [
+ "id",
+ "settlementNo",
+ "referrerUserId",
+ "status",
+ "periodStart",
+ "periodEnd",
+ "sourceCount",
+ "paidUserCount",
+ "grossAmountCents",
+ "commissionAmountCents",
+ "reviewedAt",
+ "paidAt"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "settlementNo": {
+ "type": "string"
+ },
+ "referrerUserId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "status": {
+ "type": "string"
+ },
+ "periodStart": {
+ "type": "string",
+ "format": "date"
+ },
+ "periodEnd": {
+ "type": "string",
+ "format": "date"
+ },
+ "sourceCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "paidUserCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "grossAmountCents": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "commissionAmountCents": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "reviewedAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "paidAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ }
+ }
+ },
+ "CommissionSourceItem": {
+ "required": [
+ "sourceType",
+ "sourceId",
+ "sourceNo",
+ "referrerUserId",
+ "studentUserId",
+ "grossAmountCents",
+ "commissionRate",
+ "commissionAmountCents",
+ "rateSource",
+ "settlementId"
+ ],
+ "type": "object",
+ "properties": {
+ "sourceType": {
+ "type": "string"
+ },
+ "sourceId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "sourceNo": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "referrerUserId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "studentUserId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "grossAmountCents": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "commissionRate": {
+ "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
+ "type": [
+ "number",
+ "string"
+ ],
+ "format": "double"
+ },
+ "commissionAmountCents": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "rateSource": {
+ "type": "string"
+ },
+ "settlementId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ }
+ }
+ },
+ "CommissionSummaryItem": {
+ "required": [
+ "sourceCount",
+ "paidUserCount",
+ "grossAmountCents",
+ "commissionAmountCents"
+ ],
+ "type": "object",
+ "properties": {
+ "sourceCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "paidUserCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "grossAmountCents": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "commissionAmountCents": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ }
+ }
+ },
+ "ConfirmManualPlatformPaymentDto": {
+ "required": [
+ "paymentId",
+ "providerTradeNo",
+ "paidAt",
+ "reason"
+ ],
+ "type": "object",
+ "properties": {
+ "paymentId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "providerTradeNo": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "paidAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "reason": {
+ "type": "string"
+ }
+ },
+ "description": "确认人工平台支付请求 DTO。"
+ },
+ "ContentAssetAccessEventItem": {
+ "required": [
+ "id",
+ "assetId",
+ "userId",
+ "actorRole",
+ "accessType",
+ "visibility",
+ "assetType",
+ "storageProvider",
+ "disposition",
+ "expiresInSeconds",
+ "signatureMode",
+ "result",
+ "denyCode",
+ "ipAddress",
+ "userAgent",
+ "metadata",
+ "createdAt"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "assetId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "userId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "actorRole": {
+ "$ref": "#/components/schemas/AssetAccessActorRole"
+ },
+ "accessType": {
+ "$ref": "#/components/schemas/AssetAccessType"
+ },
+ "visibility": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "assetType": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "storageProvider": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "disposition": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "$ref": "#/components/schemas/AssetAccessDisposition"
+ }
+ ]
+ },
+ "expiresInSeconds": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "signatureMode": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "result": {
+ "$ref": "#/components/schemas/AssetAccessResult"
+ },
+ "denyCode": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "ipAddress": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "userAgent": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+ },
+ "ContentAssetAccessSummaryDto": {
+ "required": [
+ "id",
+ "assetType",
+ "title",
+ "fileName",
+ "previewUrl",
+ "uploadStatus",
+ "securityScanStatus",
+ "previewStatus",
+ "visibility"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "assetType": {
+ "$ref": "#/components/schemas/ContentAssetType"
+ },
+ "title": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "fileName": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "previewUrl": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "uploadStatus": {
+ "$ref": "#/components/schemas/AssetUploadStatus"
+ },
+ "securityScanStatus": {
+ "$ref": "#/components/schemas/AssetSecurityScanStatus"
+ },
+ "previewStatus": {
+ "$ref": "#/components/schemas/AssetPreviewStatus"
+ },
+ "visibility": {
+ "$ref": "#/components/schemas/ContentVisibility"
+ }
+ },
+ "description": "内容资产访问摘要。"
+ },
+ "ContentAssetCatalogItem": {
+ "required": [
+ "id",
+ "legacyId",
+ "regionId",
+ "subjectId",
+ "categoryId",
+ "contentNodeId",
+ "assetKey",
+ "title",
+ "category",
+ "description",
+ "fileName",
+ "cdnUrl",
+ "isPublic",
+ "assetType",
+ "storageProvider",
+ "bucket",
+ "objectKey",
+ "mimeType",
+ "fileSizeBytes",
+ "checksumSha256",
+ "visibility",
+ "previewUrl",
+ "status",
+ "order",
+ "uploadStatus",
+ "verifiedAt",
+ "previewStatus",
+ "securityScanStatus",
+ "metadata"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "regionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "subjectId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "categoryId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "contentNodeId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "assetKey": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "title": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "category": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "description": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "fileName": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "cdnUrl": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "isPublic": {
+ "type": "boolean"
+ },
+ "assetType": {
+ "$ref": "#/components/schemas/ContentAssetType"
+ },
+ "storageProvider": {
+ "$ref": "#/components/schemas/AssetStorageProvider"
+ },
+ "bucket": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "objectKey": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "mimeType": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "fileSizeBytes": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "format": "int64"
+ },
+ "checksumSha256": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "visibility": {
+ "$ref": "#/components/schemas/ContentVisibility"
+ },
+ "previewUrl": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "status": {
+ "$ref": "#/components/schemas/ContentStatus"
+ },
+ "order": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "uploadStatus": {
+ "$ref": "#/components/schemas/AssetUploadStatus"
+ },
+ "verifiedAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "previewStatus": {
+ "$ref": "#/components/schemas/AssetPreviewStatus"
+ },
+ "securityScanStatus": {
+ "$ref": "#/components/schemas/AssetSecurityScanStatus"
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ }
+ },
+ "ContentAssetManagementItem": {
+ "required": [
+ "id",
+ "legacyId",
+ "regionId",
+ "subjectId",
+ "categoryId",
+ "contentNodeId",
+ "assetKey",
+ "title",
+ "category",
+ "description",
+ "fileName",
+ "cdnUrl",
+ "isPublic",
+ "assetType",
+ "storageProvider",
+ "bucket",
+ "objectKey",
+ "mimeType",
+ "fileSizeBytes",
+ "checksumSha256",
+ "visibility",
+ "status",
+ "order",
+ "uploadStatus",
+ "verifiedAt",
+ "verifiedSizeBytes",
+ "verifiedChecksumSha256",
+ "previewStatus",
+ "securityScanStatus",
+ "metadata",
+ "createdAt",
+ "updatedAt"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "regionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "subjectId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "categoryId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "contentNodeId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "assetKey": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "title": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "category": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "description": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "fileName": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "cdnUrl": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "isPublic": {
+ "type": "boolean"
+ },
+ "assetType": {
+ "$ref": "#/components/schemas/ContentAssetType"
+ },
+ "storageProvider": {
+ "$ref": "#/components/schemas/AssetStorageProvider"
+ },
+ "bucket": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "objectKey": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "mimeType": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "fileSizeBytes": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "format": "int64"
+ },
+ "checksumSha256": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "visibility": {
+ "$ref": "#/components/schemas/ContentVisibility"
+ },
+ "status": {
+ "$ref": "#/components/schemas/ContentStatus"
+ },
+ "order": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "uploadStatus": {
+ "$ref": "#/components/schemas/AssetUploadStatus"
+ },
+ "verifiedAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "verifiedSizeBytes": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "format": "int64"
+ },
+ "verifiedChecksumSha256": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "previewStatus": {
+ "$ref": "#/components/schemas/AssetPreviewStatus"
+ },
+ "securityScanStatus": {
+ "$ref": "#/components/schemas/AssetSecurityScanStatus"
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updatedAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ }
+ }
+ },
+ "ContentAssetSecurityScanEventItem": {
+ "required": [
+ "id",
+ "assetId",
+ "provider",
+ "scanStatus",
+ "riskLevel",
+ "issueCodes",
+ "details",
+ "createdAt"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "assetId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "provider": {
+ "type": "string"
+ },
+ "scanStatus": {
+ "$ref": "#/components/schemas/AssetSecurityScanStatus"
+ },
+ "riskLevel": {
+ "$ref": "#/components/schemas/AssetSecurityRiskLevel"
+ },
+ "issueCodes": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "details": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+ },
+ "ContentAssetType": {
+ "type": "integer"
+ },
+ "ContentEntryCatalogItem": {
+ "required": [
+ "id",
+ "regionId",
+ "legacyId",
+ "entryKey",
+ "name",
+ "entryType",
+ "icon",
+ "route",
+ "description",
+ "visibility",
+ "accessRules",
+ "layoutConfig",
+ "order"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "regionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "entryKey": {
+ "type": "string"
+ },
+ "name": {
+ "type": "string"
+ },
+ "entryType": {
+ "$ref": "#/components/schemas/ContentEntryType"
+ },
+ "icon": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "route": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "description": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "visibility": {
+ "$ref": "#/components/schemas/ContentVisibility"
+ },
+ "accessRules": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "layoutConfig": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "order": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ }
+ }
+ },
+ "ContentEntryManagementItem": {
+ "required": [
+ "id",
+ "regionId",
+ "legacyId",
+ "entryKey",
+ "name",
+ "entryType",
+ "icon",
+ "route",
+ "description",
+ "visibility",
+ "accessRules",
+ "layoutConfig",
+ "order",
+ "isActive",
+ "createdAt",
+ "updatedAt"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "regionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "entryKey": {
+ "type": "string"
+ },
+ "name": {
+ "type": "string"
+ },
+ "entryType": {
+ "$ref": "#/components/schemas/ContentEntryType"
+ },
+ "icon": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "route": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "description": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "visibility": {
+ "$ref": "#/components/schemas/ContentVisibility"
+ },
+ "accessRules": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "layoutConfig": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "order": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "isActive": {
+ "type": "boolean"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updatedAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ }
+ }
+ },
+ "ContentEntryType": {
+ "type": "integer"
+ },
+ "ContentImportIssueModel": {
+ "required": [
+ "id",
+ "jobId",
+ "itemId",
+ "rowNo",
+ "severity",
+ "code",
+ "fieldPath",
+ "message",
+ "details"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "jobId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "itemId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "rowNo": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "severity": {
+ "$ref": "#/components/schemas/ImportIssueSeverity"
+ },
+ "code": {
+ "type": "string"
+ },
+ "fieldPath": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "message": {
+ "type": "string"
+ },
+ "details": {
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ }
+ },
+ "ContentImportItemModel": {
+ "required": [
+ "id",
+ "jobId",
+ "rowNo",
+ "externalId",
+ "status",
+ "targetType",
+ "targetId",
+ "sourcePayload",
+ "normalizedPayload",
+ "contentHash",
+ "issuesCount"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "jobId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "rowNo": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "externalId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "status": {
+ "$ref": "#/components/schemas/ContentImportItemStatus"
+ },
+ "targetType": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "targetId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "sourcePayload": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "normalizedPayload": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "contentHash": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "issuesCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ }
+ }
+ },
+ "ContentImportItemStatus": {
+ "type": "integer"
+ },
+ "ContentImportJobDetail": {
+ "required": [
+ "job",
+ "items",
+ "issues"
+ ],
+ "type": "object",
+ "properties": {
+ "job": {
+ "$ref": "#/components/schemas/ContentImportJobItem"
+ },
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ContentImportItemModel"
+ }
+ },
+ "issues": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ContentImportIssueModel"
+ }
+ }
+ }
+ },
+ "ContentImportJobItem": {
+ "required": [
+ "id",
+ "targetRegionId",
+ "targetSubjectId",
+ "targetCategoryId",
+ "targetContentNodeId",
+ "targetQuestionBankId",
+ "importType",
+ "sourceFormat",
+ "status",
+ "sourceName",
+ "sourceHash",
+ "dryRun",
+ "totalCount",
+ "validCount",
+ "errorCount",
+ "warningCount",
+ "insertedCount",
+ "updatedCount",
+ "skippedCount",
+ "summary",
+ "errorMessage",
+ "startedAt",
+ "finishedAt",
+ "createdAt",
+ "updatedAt"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "targetRegionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "targetSubjectId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "targetCategoryId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "targetContentNodeId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "targetQuestionBankId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "importType": {
+ "$ref": "#/components/schemas/ContentImportType"
+ },
+ "sourceFormat": {
+ "$ref": "#/components/schemas/ImportSourceFormat"
+ },
+ "status": {
+ "$ref": "#/components/schemas/ContentImportStatus"
+ },
+ "sourceName": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "sourceHash": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "dryRun": {
+ "type": "boolean"
+ },
+ "totalCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "validCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "errorCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "warningCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "insertedCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "updatedCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "skippedCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "summary": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "errorMessage": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "startedAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "finishedAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updatedAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ }
+ }
+ },
+ "ContentImportStatus": {
+ "type": "integer"
+ },
+ "ContentImportType": {
+ "type": "integer"
+ },
+ "ContentManagementResultOfContentAssetManagementItem": {
+ "required": [
+ "item"
+ ],
+ "type": "object",
+ "properties": {
+ "item": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "$ref": "#/components/schemas/ContentAssetManagementItem"
+ }
+ ]
+ }
+ }
+ },
+ "ContentManagementResultOfContentEntryManagementItem": {
+ "required": [
+ "item"
+ ],
+ "type": "object",
+ "properties": {
+ "item": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "$ref": "#/components/schemas/ContentEntryManagementItem"
+ }
+ ]
+ }
+ }
+ },
+ "ContentManagementResultOfContentNodeManagementItem": {
+ "required": [
+ "item"
+ ],
+ "type": "object",
+ "properties": {
+ "item": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "$ref": "#/components/schemas/ContentNodeManagementItem"
+ }
+ ]
+ }
+ }
+ },
+ "ContentManagementResultOfHandbookChapter": {
+ "required": [
+ "item"
+ ],
+ "type": "object",
+ "properties": {
+ "item": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "$ref": "#/components/schemas/HandbookChapter"
+ }
+ ]
+ }
+ }
+ },
+ "ContentManagementResultOfHandbookEntry": {
+ "required": [
+ "item"
+ ],
+ "type": "object",
+ "properties": {
+ "item": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "$ref": "#/components/schemas/HandbookEntry"
+ }
+ ]
+ }
+ }
+ },
+ "ContentManagementResultOfHandbookSubject": {
+ "required": [
+ "item"
+ ],
+ "type": "object",
+ "properties": {
+ "item": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "$ref": "#/components/schemas/HandbookSubject"
+ }
+ ]
+ }
+ }
+ },
+ "ContentManagementResultOfMajor": {
+ "required": [
+ "item"
+ ],
+ "type": "object",
+ "properties": {
+ "item": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "$ref": "#/components/schemas/Major"
+ }
+ ]
+ }
+ }
+ },
+ "ContentManagementResultOfOperationContentItem": {
+ "required": [
+ "item"
+ ],
+ "type": "object",
+ "properties": {
+ "item": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "$ref": "#/components/schemas/OperationContentItem"
+ }
+ ]
+ }
+ }
+ },
+ "ContentManagementResultOfPracticeBlueprintManagementItem": {
+ "required": [
+ "item"
+ ],
+ "type": "object",
+ "properties": {
+ "item": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "$ref": "#/components/schemas/PracticeBlueprintManagementItem"
+ }
+ ]
+ }
+ }
+ },
+ "ContentManagementResultOfQuestionCollectionManagementItem": {
+ "required": [
+ "item"
+ ],
+ "type": "object",
+ "properties": {
+ "item": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "$ref": "#/components/schemas/QuestionCollectionManagementItem"
+ }
+ ]
+ }
+ }
+ },
+ "ContentManagementResultOfQuestionManagementItem": {
+ "required": [
+ "item"
+ ],
+ "type": "object",
+ "properties": {
+ "item": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "$ref": "#/components/schemas/QuestionManagementItem"
+ }
+ ]
+ }
+ }
+ },
+ "ContentManagementResultOfQuestionVideoManagementItem": {
+ "required": [
+ "item"
+ ],
+ "type": "object",
+ "properties": {
+ "item": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "$ref": "#/components/schemas/QuestionVideoManagementItem"
+ }
+ ]
+ }
+ }
+ },
+ "ContentManagementResultOfSchool": {
+ "required": [
+ "item"
+ ],
+ "type": "object",
+ "properties": {
+ "item": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "$ref": "#/components/schemas/School"
+ }
+ ]
+ }
+ }
+ },
+ "ContentManagementResultOfScorelineField": {
+ "required": [
+ "item"
+ ],
+ "type": "object",
+ "properties": {
+ "item": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "$ref": "#/components/schemas/ScorelineField"
+ }
+ ]
+ }
+ }
+ },
+ "ContentManagementResultOfScorelineRecord": {
+ "required": [
+ "item"
+ ],
+ "type": "object",
+ "properties": {
+ "item": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "$ref": "#/components/schemas/ScorelineRecord"
+ }
+ ]
+ }
+ }
+ },
+ "ContentManagementResultOfTenantAdminBadgeGrantItem": {
+ "required": [
+ "item"
+ ],
+ "type": "object",
+ "properties": {
+ "item": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "$ref": "#/components/schemas/TenantAdminBadgeGrantItem"
+ }
+ ]
+ }
+ }
+ },
+ "ContentManagementResultOfTenantAdminBadgeItem": {
+ "required": [
+ "item"
+ ],
+ "type": "object",
+ "properties": {
+ "item": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "$ref": "#/components/schemas/TenantAdminBadgeItem"
+ }
+ ]
+ }
+ }
+ },
+ "ContentManagementResultOfTenantAdminClassItem": {
+ "required": [
+ "item"
+ ],
+ "type": "object",
+ "properties": {
+ "item": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "$ref": "#/components/schemas/TenantAdminClassItem"
+ }
+ ]
+ }
+ }
+ },
+ "ContentManagementResultOfTenantAdminClassMemberItem": {
+ "required": [
+ "item"
+ ],
+ "type": "object",
+ "properties": {
+ "item": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "$ref": "#/components/schemas/TenantAdminClassMemberItem"
+ }
+ ]
+ }
+ }
+ },
+ "ContentManagementResultOfTenantAdminFeedbackItem": {
+ "required": [
+ "item"
+ ],
+ "type": "object",
+ "properties": {
+ "item": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "$ref": "#/components/schemas/TenantAdminFeedbackItem"
+ }
+ ]
+ }
+ }
+ },
+ "ContentManagementResultOfTenantAdminMemberItem": {
+ "required": [
+ "item"
+ ],
+ "type": "object",
+ "properties": {
+ "item": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "$ref": "#/components/schemas/TenantAdminMemberItem"
+ }
+ ]
+ }
+ }
+ },
+ "ContentManagementResultOfTenantAdminNotificationItem": {
+ "required": [
+ "item"
+ ],
+ "type": "object",
+ "properties": {
+ "item": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "$ref": "#/components/schemas/TenantAdminNotificationItem"
+ }
+ ]
+ }
+ }
+ },
+ "ContentManagementResultOfTenantAdminStudentFollowupItem": {
+ "required": [
+ "item"
+ ],
+ "type": "object",
+ "properties": {
+ "item": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "$ref": "#/components/schemas/TenantAdminStudentFollowupItem"
+ }
+ ]
+ }
+ }
+ },
+ "ContentManagementResultOfTenantAdminStudentItem": {
+ "required": [
+ "item"
+ ],
+ "type": "object",
+ "properties": {
+ "item": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "$ref": "#/components/schemas/TenantAdminStudentItem"
+ }
+ ]
+ }
+ }
+ },
+ "ContentManagementResultOfTenantAdminStudentNoteItem": {
+ "required": [
+ "item"
+ ],
+ "type": "object",
+ "properties": {
+ "item": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "$ref": "#/components/schemas/TenantAdminStudentNoteItem"
+ }
+ ]
+ }
+ }
+ },
+ "ContentManagementResultOfTenantAdminStudentStatusItem": {
+ "required": [
+ "item"
+ ],
+ "type": "object",
+ "properties": {
+ "item": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "$ref": "#/components/schemas/TenantAdminStudentStatusItem"
+ }
+ ]
+ }
+ }
+ },
+ "ContentManagementResultOfTenantBrandingItem": {
+ "required": [
+ "item"
+ ],
+ "type": "object",
+ "properties": {
+ "item": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "$ref": "#/components/schemas/TenantBrandingItem"
+ }
+ ]
+ }
+ }
+ },
+ "ContentManagementResultOfTenantDomainItem": {
+ "required": [
+ "item"
+ ],
+ "type": "object",
+ "properties": {
+ "item": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "$ref": "#/components/schemas/TenantDomainItem"
+ }
+ ]
+ }
+ }
+ },
+ "ContentManagementResultOfTenantIdentityProviderItem": {
+ "required": [
+ "item"
+ ],
+ "type": "object",
+ "properties": {
+ "item": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "$ref": "#/components/schemas/TenantIdentityProviderItem"
+ }
+ ]
+ }
+ }
+ },
+ "ContentManagementResultOfTenantSettingsItem": {
+ "required": [
+ "item"
+ ],
+ "type": "object",
+ "properties": {
+ "item": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "$ref": "#/components/schemas/TenantSettingsItem"
+ }
+ ]
+ }
+ }
+ },
+ "ContentManagementResultOfTenantSupervisionRuleItem": {
+ "required": [
+ "item"
+ ],
+ "type": "object",
+ "properties": {
+ "item": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "$ref": "#/components/schemas/TenantSupervisionRuleItem"
+ }
+ ]
+ }
+ }
+ },
+ "ContentManagementResultOfTenantThemeItem": {
+ "required": [
+ "item"
+ ],
+ "type": "object",
+ "properties": {
+ "item": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "$ref": "#/components/schemas/TenantThemeItem"
+ }
+ ]
+ }
+ }
+ },
+ "ContentManagementResultOfVideoManagementItem": {
+ "required": [
+ "item"
+ ],
+ "type": "object",
+ "properties": {
+ "item": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "$ref": "#/components/schemas/VideoManagementItem"
+ }
+ ]
+ }
+ }
+ },
+ "ContentManagementResultOfVocabularyUnit": {
+ "required": [
+ "item"
+ ],
+ "type": "object",
+ "properties": {
+ "item": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "$ref": "#/components/schemas/VocabularyUnit"
+ }
+ ]
+ }
+ }
+ },
+ "ContentManagementResultOfVocabularyWord": {
+ "required": [
+ "item"
+ ],
+ "type": "object",
+ "properties": {
+ "item": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "$ref": "#/components/schemas/VocabularyWord"
+ }
+ ]
+ }
+ }
+ },
+ "ContentMarkerType": {
+ "type": "integer"
+ },
+ "ContentNodeCatalogItem": {
+ "required": [
+ "id",
+ "entryId",
+ "regionId",
+ "parentId",
+ "legacyId",
+ "nodeKey",
+ "name",
+ "nodeType",
+ "markerType",
+ "markerConfig",
+ "path",
+ "depth",
+ "order",
+ "isSelectable",
+ "isLeaf",
+ "accessRules",
+ "metadata"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "entryId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "regionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "parentId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "nodeKey": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "name": {
+ "type": "string"
+ },
+ "nodeType": {
+ "$ref": "#/components/schemas/ContentNodeType"
+ },
+ "markerType": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "$ref": "#/components/schemas/ContentMarkerType"
+ }
+ ]
+ },
+ "markerConfig": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "path": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "depth": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "order": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "isSelectable": {
+ "type": "boolean"
+ },
+ "isLeaf": {
+ "type": "boolean"
+ },
+ "accessRules": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ }
+ },
+ "ContentNodeManagementItem": {
+ "required": [
+ "id",
+ "entryId",
+ "regionId",
+ "parentId",
+ "legacyId",
+ "nodeKey",
+ "name",
+ "nodeType",
+ "markerType",
+ "markerConfig",
+ "path",
+ "depth",
+ "order",
+ "isActive",
+ "isSelectable",
+ "isLeaf",
+ "accessRules",
+ "metadata",
+ "createdAt",
+ "updatedAt"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "entryId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "regionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "parentId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "nodeKey": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "name": {
+ "type": "string"
+ },
+ "nodeType": {
+ "$ref": "#/components/schemas/ContentNodeType"
+ },
+ "markerType": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "$ref": "#/components/schemas/ContentMarkerType"
+ }
+ ]
+ },
+ "markerConfig": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "path": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "depth": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "order": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "isActive": {
+ "type": "boolean"
+ },
+ "isSelectable": {
+ "type": "boolean"
+ },
+ "isLeaf": {
+ "type": "boolean"
+ },
+ "accessRules": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updatedAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ }
+ }
+ },
+ "ContentNodeType": {
+ "type": "integer"
+ },
+ "ContentStatus": {
+ "type": "integer"
+ },
+ "ContentVisibility": {
+ "type": "integer"
+ },
+ "Coupon": {
+ "type": "object",
+ "properties": {
+ "planId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "code": {
+ "type": "string"
+ },
+ "discountType": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "$ref": "#/components/schemas/DiscountType"
+ }
+ ]
+ },
+ "discountValue": {
+ "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
+ "type": [
+ "null",
+ "number",
+ "string"
+ ],
+ "format": "double"
+ },
+ "validFrom": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "validTo": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "maxUses": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "usedCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "source": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "remark": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updatedAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "tenantId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ },
+ "CouponRedemption": {
+ "type": "object",
+ "properties": {
+ "couponId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "userId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "planId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "orderId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "regionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "couponCode": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "status": {
+ "$ref": "#/components/schemas/CouponRedemptionStatus"
+ },
+ "discountAppliedCents": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "source": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "remark": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "claimedAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "usedAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updatedAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "tenantId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ },
+ "CouponRedemptionStatus": {
+ "type": "integer"
+ },
+ "CreateAdjustmentVoucherDto": {
+ "required": [
+ "reason"
+ ],
+ "type": "object",
+ "properties": {
+ "issueId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "工单 ID。",
+ "format": "uuid"
+ },
+ "batchId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "批次 ID。",
+ "format": "uuid"
+ },
+ "itemId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "兑换项 ID。",
+ "format": "uuid"
+ },
+ "orderId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "订单 ID。",
+ "format": "uuid"
+ },
+ "paymentId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "支付记录 ID。",
+ "format": "uuid"
+ },
+ "refundRequestId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "退款申请 ID。",
+ "format": "uuid"
+ },
+ "direction": {
+ "description": "方向。",
+ "$ref": "#/components/schemas/CommerceAdjustmentDirection"
+ },
+ "amountCents": {
+ "maximum": 2147483647,
+ "minimum": 1,
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "description": "金额,单位为分。",
+ "format": "int32"
+ },
+ "currency": {
+ "maxLength": 10,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "币种。"
+ },
+ "reason": {
+ "maxLength": 1000,
+ "minLength": 0,
+ "type": "string",
+ "description": "原因。"
+ },
+ "proofAssetKey": {
+ "maxLength": 500,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "证明资产键。"
+ },
+ "metadata": {
+ "description": "扩展元数据。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ },
+ "description": "创建调账凭证请求 DTO。"
+ },
+ "CreateBackgroundJobDto": {
+ "type": "object",
+ "properties": {
+ "jobType": {
+ "type": "string",
+ "description": "任务类型。"
+ },
+ "payload": {
+ "description": "任务载荷。",
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "runAfter": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "计划运行时间。",
+ "format": "date-time"
+ },
+ "maxRetries": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "description": "最大重试次数。",
+ "format": "int32"
+ }
+ },
+ "description": "创建租户后台任务请求。"
+ },
+ "CreateCodeBatchDto": {
+ "required": [
+ "name"
+ ],
+ "type": "object",
+ "properties": {
+ "name": {
+ "maxLength": 200,
+ "minLength": 0,
+ "type": "string",
+ "description": "名称。"
+ },
+ "totalCount": {
+ "maximum": 1000,
+ "minimum": 1,
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "description": "总数量。",
+ "format": "int32"
+ },
+ "days": {
+ "maximum": 3650,
+ "minimum": 1,
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "description": "天数。",
+ "format": "int32"
+ },
+ "regionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "地区 ID。",
+ "format": "uuid"
+ },
+ "saleType": {
+ "maxLength": 50,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "售卖类型。"
+ },
+ "channel": {
+ "maxLength": 100,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "渠道。"
+ },
+ "defaultUnitPriceCents": {
+ "maximum": 2147483647,
+ "minimum": 0,
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "description": "默认单价,单位为分。",
+ "format": "int32"
+ },
+ "costPriceCents": {
+ "maximum": 2147483647,
+ "minimum": 0,
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "description": "成本价,单位为分。",
+ "format": "int32"
+ },
+ "remark": {
+ "maxLength": 1000,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "备注。"
+ }
+ },
+ "description": "创建编码批次请求 DTO。"
+ },
+ "CreateCommerceOrderDto": {
+ "required": [
+ "planId"
+ ],
+ "type": "object",
+ "properties": {
+ "planId": {
+ "type": "string",
+ "description": "套餐 ID。",
+ "format": "uuid"
+ },
+ "quantity": {
+ "maximum": 99,
+ "minimum": 1,
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "description": "数量。",
+ "format": "int32"
+ },
+ "payMethod": {
+ "maxLength": 50,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "支付方式。"
+ },
+ "payProvider": {
+ "maxLength": 50,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "支付渠道。"
+ },
+ "regionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "地区 ID。",
+ "format": "uuid"
+ },
+ "couponCode": {
+ "maxLength": 100,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "优惠券码。"
+ },
+ "couponRedemptionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "优惠券领取记录 ID。",
+ "format": "uuid"
+ }
+ },
+ "description": "创建交易订单请求 DTO。"
+ },
+ "CreateCommercePaymentDto": {
+ "required": [
+ "orderNo",
+ "provider",
+ "method"
+ ],
+ "type": "object",
+ "properties": {
+ "orderNo": {
+ "maxLength": 100,
+ "minLength": 0,
+ "type": "string",
+ "description": "订单号。"
+ },
+ "provider": {
+ "maxLength": 50,
+ "minLength": 0,
+ "type": "string",
+ "description": "服务提供方。"
+ },
+ "method": {
+ "maxLength": 50,
+ "minLength": 0,
+ "type": "string",
+ "description": "方式。"
+ },
+ "openId": {
+ "maxLength": 255,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "微信或支付渠道 openid。"
+ },
+ "returnUrl": {
+ "maxLength": 2048,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "支付完成返回地址。"
+ },
+ "quitUrl": {
+ "maxLength": 2048,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "支付取消返回地址。"
+ }
+ },
+ "description": "创建交易支付请求 DTO。"
+ },
+ "CreateCommissionProofDto": {
+ "required": [
+ "settlementId"
+ ],
+ "type": "object",
+ "properties": {
+ "settlementId": {
+ "type": "string",
+ "description": "结算单 ID。",
+ "format": "uuid"
+ },
+ "proofType": {
+ "maxLength": 50,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "凭证类型。"
+ },
+ "title": {
+ "maxLength": 200,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "标题。"
+ },
+ "description": {
+ "maxLength": 2000,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "说明。"
+ },
+ "assetId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "资产 ID。",
+ "format": "uuid"
+ },
+ "externalUrl": {
+ "maxLength": 2048,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "外部链接。"
+ },
+ "amountCents": {
+ "maximum": 2147483647,
+ "minimum": 0,
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "description": "金额,单位为分。",
+ "format": "int32"
+ },
+ "paymentMethod": {
+ "maxLength": 100,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "支付方式。"
+ },
+ "paymentAccount": {
+ "maxLength": 200,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "收款账号。"
+ },
+ "paidAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "支付时间。",
+ "format": "date-time"
+ },
+ "metadata": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "description": "扩展元数据。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ ]
+ }
+ },
+ "description": "创建佣金结算凭证请求。"
+ },
+ "CreatePlatformBillingOrderDto": {
+ "required": [
+ "quoteId",
+ "idempotencyKey"
+ ],
+ "type": "object",
+ "properties": {
+ "quoteId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "idempotencyKey": {
+ "type": "string"
+ }
+ },
+ "description": "创建平台账务订单请求 DTO。"
+ },
+ "CreatePlatformBillingPaymentDto": {
+ "required": [
+ "provider",
+ "method",
+ "idempotencyKey",
+ "openId",
+ "returnUrl",
+ "quitUrl"
+ ],
+ "type": "object",
+ "properties": {
+ "provider": {
+ "type": "string"
+ },
+ "method": {
+ "type": "string"
+ },
+ "idempotencyKey": {
+ "type": "string"
+ },
+ "openId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "returnUrl": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "quitUrl": {
+ "type": [
+ "null",
+ "string"
+ ]
+ }
+ },
+ "description": "创建平台账务支付请求 DTO。"
+ },
+ "CreatePlatformBillingQuoteDto": {
+ "required": [
+ "baseOfferingVersionId",
+ "addOnOfferingVersionIds",
+ "purpose",
+ "idempotencyKey"
+ ],
+ "type": "object",
+ "properties": {
+ "baseOfferingVersionId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "addOnOfferingVersionIds": {
+ "type": [
+ "null",
+ "array"
+ ],
+ "items": {
+ "type": "string",
+ "format": "uuid"
+ }
+ },
+ "purpose": {
+ "$ref": "#/components/schemas/PlatformBillingOrderPurpose"
+ },
+ "idempotencyKey": {
+ "type": "string"
+ }
+ },
+ "description": "创建平台账务报价请求 DTO。"
+ },
+ "CreatePlatformTenantDto": {
+ "required": [
+ "slug",
+ "name",
+ "ownerName",
+ "temporaryPassword"
+ ],
+ "type": "object",
+ "properties": {
+ "slug": {
+ "maxLength": 100,
+ "minLength": 0,
+ "type": "string",
+ "description": "短编码。"
+ },
+ "name": {
+ "maxLength": 200,
+ "minLength": 0,
+ "type": "string",
+ "description": "名称。"
+ },
+ "legalName": {
+ "maxLength": 300,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "法定名称。"
+ },
+ "status": {
+ "description": "状态。",
+ "$ref": "#/components/schemas/TenantStatus"
+ },
+ "billingStatus": {
+ "description": "账务状态。",
+ "$ref": "#/components/schemas/BillingStatus"
+ },
+ "metadata": {
+ "description": "扩展元数据。",
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "ownerEmail": {
+ "maxLength": 320,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "租户负责人邮箱。"
+ },
+ "ownerPhone": {
+ "maxLength": 32,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "租户负责人手机号。"
+ },
+ "ownerName": {
+ "maxLength": 100,
+ "minLength": 0,
+ "type": "string",
+ "description": "租户负责人姓名。"
+ },
+ "temporaryPassword": {
+ "maxLength": 200,
+ "minLength": 12,
+ "type": "string",
+ "description": "临时密码。"
+ }
+ },
+ "description": "创建平台租户请求 DTO。"
+ },
+ "CreatePointExchangeOrderDto": {
+ "required": [
+ "itemId"
+ ],
+ "type": "object",
+ "properties": {
+ "itemId": {
+ "type": "string",
+ "description": "兑换项 ID。",
+ "format": "uuid"
+ }
+ },
+ "description": "创建积分兑换订单请求 DTO。"
+ },
+ "CreatePracticeSessionDto": {
+ "type": "object",
+ "properties": {
+ "mode": {
+ "maxLength": 50,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "模式。"
+ },
+ "targetType": {
+ "maxLength": 50,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "目标类型。"
+ },
+ "targetId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "目标 ID。",
+ "format": "uuid"
+ },
+ "blueprintId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "练习蓝图 ID。",
+ "format": "uuid"
+ },
+ "collectionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "题集 ID。",
+ "format": "uuid"
+ },
+ "entryId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "内容入口 ID。",
+ "format": "uuid"
+ },
+ "contentNodeId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "内容节点 ID。",
+ "format": "uuid"
+ },
+ "questionLimit": {
+ "maximum": 500,
+ "minimum": 1,
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "description": "题目数量上限。",
+ "format": "int32"
+ },
+ "durationMinutes": {
+ "maximum": 1440,
+ "minimum": 1,
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "description": "时长,单位为分钟。",
+ "format": "int32"
+ },
+ "totalScore": {
+ "maximum": 99999,
+ "minimum": 0,
+ "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
+ "type": [
+ "null",
+ "number",
+ "string"
+ ],
+ "description": "总分。",
+ "format": "double"
+ },
+ "metadata": {
+ "description": "扩展元数据。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ },
+ "description": "创建练习会话请求 DTO。"
+ },
+ "CreateReconciliationBatchDto": {
+ "required": [
+ "provider",
+ "sourceHash"
+ ],
+ "type": "object",
+ "properties": {
+ "provider": {
+ "maxLength": 50,
+ "minLength": 0,
+ "type": "string",
+ "description": "服务提供方。"
+ },
+ "billDate": {
+ "type": "string",
+ "description": "账单日期。",
+ "format": "date"
+ },
+ "billType": {
+ "description": "账单类型。",
+ "$ref": "#/components/schemas/ReconciliationBillType"
+ },
+ "source": {
+ "description": "来源。",
+ "$ref": "#/components/schemas/ReconciliationSource"
+ },
+ "sourceName": {
+ "maxLength": 200,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "来源名称。"
+ },
+ "sourceHash": {
+ "maxLength": 200,
+ "minLength": 0,
+ "type": "string",
+ "description": "来源哈希。"
+ },
+ "metadata": {
+ "description": "扩展元数据。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ },
+ "description": "创建对账批次请求 DTO。"
+ },
+ "CreateRefundRequestDto": {
+ "required": [
+ "orderId"
+ ],
+ "type": "object",
+ "properties": {
+ "orderId": {
+ "type": "string",
+ "description": "订单 ID。",
+ "format": "uuid"
+ },
+ "paymentId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "支付记录 ID。",
+ "format": "uuid"
+ },
+ "amountCents": {
+ "maximum": 2147483647,
+ "minimum": 1,
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "description": "金额,单位为分。",
+ "format": "int32"
+ },
+ "reason": {
+ "maxLength": 1000,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "原因。"
+ },
+ "entitlementAction": {
+ "description": "权益动作。",
+ "$ref": "#/components/schemas/RefundEntitlementAction"
+ },
+ "metadata": {
+ "description": "扩展元数据。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ },
+ "description": "创建退款Request请求 DTO。"
+ },
+ "CreateTaxonomyNodeDto": {
+ "required": [
+ "nodeType",
+ "code",
+ "name"
+ ],
+ "type": "object",
+ "properties": {
+ "parentId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "父节点 ID。",
+ "format": "uuid"
+ },
+ "parentSource": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "description": "父级来源。",
+ "$ref": "#/components/schemas/QuestionSource"
+ }
+ ]
+ },
+ "nodeType": {
+ "description": "节点Type。",
+ "$ref": "#/components/schemas/TaxonomyNodeType"
+ },
+ "code": {
+ "maxLength": 100,
+ "minLength": 0,
+ "type": "string",
+ "description": "编码。"
+ },
+ "name": {
+ "maxLength": 300,
+ "minLength": 0,
+ "type": "string",
+ "description": "名称。"
+ },
+ "sortOrder": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "description": "排序值。",
+ "format": "int32"
+ },
+ "metadata": {
+ "description": "扩展元数据。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ },
+ "description": "创建分类节点请求 DTO。"
+ },
+ "CreateTenantDomainDto": {
+ "required": [
+ "host"
+ ],
+ "type": "object",
+ "properties": {
+ "host": {
+ "type": "string",
+ "description": "访问域名。"
+ },
+ "domainType": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "域名类型。"
+ },
+ "isPrimary": {
+ "type": "boolean",
+ "description": "是否主域名。"
+ }
+ },
+ "description": "创建租户域名请求 DTO。"
+ },
+ "CrmConfigItem": {
+ "required": [
+ "id",
+ "enabled",
+ "url",
+ "secretRef",
+ "assignmentMode",
+ "assignmentPool",
+ "formName",
+ "examType",
+ "timeoutSeconds",
+ "delaySeconds",
+ "updatedAt"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "enabled": {
+ "type": "boolean"
+ },
+ "url": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "secretRef": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "assignmentMode": {
+ "type": "string"
+ },
+ "assignmentPool": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "formName": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "examType": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "timeoutSeconds": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "delaySeconds": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "updatedAt": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+ },
+ "CrmDeadLetterResult": {
+ "required": [
+ "summary",
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "summary": {
+ "$ref": "#/components/schemas/CrmDeadLetterSummary"
+ },
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/CrmQueueItem"
+ }
+ }
+ }
+ },
+ "CrmDeadLetterSummary": {
+ "required": [
+ "failed",
+ "discarded",
+ "total",
+ "oldestOpenAt"
+ ],
+ "type": "object",
+ "properties": {
+ "failed": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "discarded": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "total": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "oldestOpenAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ }
+ }
+ },
+ "CrmListOfCrmQueueItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/CrmQueueItem"
+ }
+ }
+ }
+ },
+ "CrmListOfCrmQueueLogItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/CrmQueueLogItem"
+ }
+ }
+ }
+ },
+ "CrmQueueActionDto": {
+ "required": [
+ "queueId"
+ ],
+ "type": "object",
+ "properties": {
+ "queueId": {
+ "type": "string",
+ "description": "队列任务 ID。",
+ "format": "uuid"
+ },
+ "action": {
+ "maxLength": 50,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "操作。"
+ },
+ "note": {
+ "maxLength": 500,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "备注。"
+ },
+ "metadata": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "description": "扩展元数据。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ ]
+ }
+ },
+ "description": "CRM队列Action请求 DTO。"
+ },
+ "CrmQueueItem": {
+ "required": [
+ "id",
+ "status",
+ "attempts",
+ "leadId",
+ "recordId",
+ "source",
+ "provider",
+ "lastError",
+ "scheduledAt",
+ "nextAttemptAt",
+ "payload"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "status": {
+ "type": "string"
+ },
+ "attempts": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "leadId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "recordId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "source": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "provider": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "lastError": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "scheduledAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "nextAttemptAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "payload": {
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ }
+ },
+ "CrmQueueLogItem": {
+ "required": [
+ "id",
+ "queueId",
+ "recordId",
+ "leadId",
+ "httpCode",
+ "outcome",
+ "errorMessage",
+ "operation",
+ "requestPayload",
+ "responseSummary",
+ "createdAt"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "queueId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "recordId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "leadId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "httpCode": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "outcome": {
+ "type": "string"
+ },
+ "errorMessage": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "operation": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "requestPayload": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "responseSummary": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+ },
+ "CrmQueuePreviewItem": {
+ "required": [
+ "id",
+ "status",
+ "source"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "status": {
+ "type": "string"
+ },
+ "source": {
+ "type": [
+ "null",
+ "string"
+ ]
+ }
+ }
+ },
+ "CrmWebhookLog": {
+ "type": "object",
+ "properties": {
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "recordId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "leadId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "httpCode": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "outcome": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "errorMessage": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "requestBody": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "requestPayload": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "responseSummary": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "signedAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "attempt": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updatedAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "tenantId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ },
+ "CrmWebhookQueueItem": {
+ "type": "object",
+ "properties": {
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "recordId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "leadId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "source": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "provider": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "status": {
+ "$ref": "#/components/schemas/CrmWebhookQueueStatus"
+ },
+ "scheduledAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "attempts": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "nextAttemptAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "lastAttemptAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "lastError": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "lastHttpCode": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "lastResponseSummary": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "sentAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "idempotencyKey": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "targetUrl": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "payload": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updatedAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "tenantId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ },
+ "CrmWebhookQueueStatus": {
+ "type": "integer"
+ },
+ "CurrentEntitlementItem": {
+ "required": [
+ "isActive",
+ "entitlementType",
+ "startsAt",
+ "expiresAt",
+ "status",
+ "daysLeft"
+ ],
+ "type": "object",
+ "properties": {
+ "isActive": {
+ "type": "boolean"
+ },
+ "entitlementType": {
+ "type": "string"
+ },
+ "startsAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "expiresAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "status": {
+ "type": "string"
+ },
+ "daysLeft": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ }
+ }
+ },
+ "CurrentTenantResponse": {
+ "required": [
+ "tenantId",
+ "tenantName",
+ "tenantSlug",
+ "status",
+ "role"
+ ],
+ "type": "object",
+ "properties": {
+ "tenantId": {
+ "type": "string",
+ "description": "租户 ID。",
+ "format": "uuid"
+ },
+ "tenantName": {
+ "type": "string",
+ "description": "租户名称。"
+ },
+ "tenantSlug": {
+ "type": "string",
+ "description": "租户编码。"
+ },
+ "status": {
+ "description": "租户状态。",
+ "$ref": "#/components/schemas/TenantStatus"
+ },
+ "role": {
+ "description": "当前用户在租户内的角色。",
+ "$ref": "#/components/schemas/TenantRole"
+ }
+ },
+ "description": "当前请求租户和当前用户在该租户内的权限摘要。"
+ },
+ "DirectHandbookChapterDto": {
+ "required": [
+ "name"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "ID。",
+ "format": "uuid"
+ },
+ "subjectId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "科目 ID。",
+ "format": "uuid"
+ },
+ "entryId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "内容入口 ID。",
+ "format": "uuid"
+ },
+ "contentNodeId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "内容节点 ID。",
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "历史系统 ID。"
+ },
+ "name": {
+ "type": "string",
+ "description": "名称。"
+ },
+ "description": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "说明。"
+ },
+ "order": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "description": "显示顺序。",
+ "format": "int32"
+ },
+ "isActive": {
+ "type": [
+ "null",
+ "boolean"
+ ],
+ "description": "是否启用。"
+ },
+ "metadata": {
+ "description": "扩展元数据。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ },
+ "description": "管理侧知识手册章节写入请求。"
+ },
+ "DirectHandbookEntryDto": {
+ "required": [
+ "title"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "ID。",
+ "format": "uuid"
+ },
+ "chapterId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "章节 ID。",
+ "format": "uuid"
+ },
+ "entryId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "内容入口 ID。",
+ "format": "uuid"
+ },
+ "contentNodeId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "内容节点 ID。",
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "历史系统 ID。"
+ },
+ "title": {
+ "type": "string",
+ "description": "标题。"
+ },
+ "summary": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "摘要。"
+ },
+ "content": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "内容。"
+ },
+ "tags": {
+ "description": "标签列表。",
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "order": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "description": "显示顺序。",
+ "format": "int32"
+ },
+ "isActive": {
+ "type": [
+ "null",
+ "boolean"
+ ],
+ "description": "是否启用。"
+ },
+ "metadata": {
+ "description": "扩展元数据。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ },
+ "description": "管理侧知识手册条目写入请求。"
+ },
+ "DirectHandbookSubjectDto": {
+ "required": [
+ "name"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "ID。",
+ "format": "uuid"
+ },
+ "regionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "地区 ID。",
+ "format": "uuid"
+ },
+ "schoolId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "院校 ID。",
+ "format": "uuid"
+ },
+ "majorId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "专业 ID。",
+ "format": "uuid"
+ },
+ "entryId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "内容入口 ID。",
+ "format": "uuid"
+ },
+ "contentNodeId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "内容节点 ID。",
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "历史系统 ID。"
+ },
+ "name": {
+ "type": "string",
+ "description": "名称。"
+ },
+ "type": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "类型。"
+ },
+ "icon": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "图标。"
+ },
+ "color": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "颜色。"
+ },
+ "description": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "说明。"
+ },
+ "order": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "description": "显示顺序。",
+ "format": "int32"
+ },
+ "isActive": {
+ "type": [
+ "null",
+ "boolean"
+ ],
+ "description": "是否启用。"
+ },
+ "metadata": {
+ "description": "扩展元数据。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ },
+ "description": "管理侧知识手册科目写入请求。"
+ },
+ "DirectImportDto": {
+ "type": "object",
+ "properties": {
+ "sourceFormat": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "来源格式。"
+ },
+ "sourceName": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "来源名称。"
+ },
+ "regionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "地区 ID。",
+ "format": "uuid"
+ },
+ "entryId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "内容入口 ID。",
+ "format": "uuid"
+ },
+ "contentNodeId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "内容节点 ID。",
+ "format": "uuid"
+ },
+ "subjectId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "科目 ID。",
+ "format": "uuid"
+ },
+ "categoryId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "分类 ID。",
+ "format": "uuid"
+ },
+ "questionBankId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "题库 ID。",
+ "format": "uuid"
+ },
+ "collectionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "题集 ID。",
+ "format": "uuid"
+ },
+ "async": {
+ "type": [
+ "null",
+ "boolean"
+ ],
+ "description": "是否异步执行。"
+ },
+ "items": {
+ "type": [
+ "null",
+ "array"
+ ],
+ "description": "数据项列表。"
+ },
+ "units": {
+ "type": [
+ "null",
+ "array"
+ ],
+ "description": "单元数据列表。"
+ },
+ "words": {
+ "type": [
+ "null",
+ "array"
+ ],
+ "description": "单词数据列表。"
+ },
+ "subjects": {
+ "type": [
+ "null",
+ "array"
+ ],
+ "description": "科目数据列表。"
+ },
+ "entries": {
+ "type": [
+ "null",
+ "array"
+ ],
+ "description": "条目数据列表。"
+ },
+ "fields": {
+ "type": [
+ "null",
+ "array"
+ ],
+ "description": "字段数据列表。"
+ },
+ "schools": {
+ "type": [
+ "null",
+ "array"
+ ],
+ "description": "院校数据列表。"
+ },
+ "majors": {
+ "type": [
+ "null",
+ "array"
+ ],
+ "description": "专业数据列表。"
+ },
+ "records": {
+ "type": [
+ "null",
+ "array"
+ ],
+ "description": "记录数据列表。"
+ },
+ "videos": {
+ "type": [
+ "null",
+ "array"
+ ],
+ "description": "视频数据列表。"
+ }
+ },
+ "description": "管理侧内容导入请求。"
+ },
+ "DirectImportJobDto": {
+ "type": "object",
+ "properties": {
+ "jobId": {
+ "type": "string",
+ "description": "任务 ID。",
+ "format": "uuid"
+ }
+ },
+ "description": "管理侧内容导入任务查询请求。"
+ },
+ "DirectMajorDto": {
+ "required": [
+ "name"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "ID。",
+ "format": "uuid"
+ },
+ "regionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "地区 ID。",
+ "format": "uuid"
+ },
+ "schoolId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "院校 ID。",
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "历史系统 ID。"
+ },
+ "name": {
+ "type": "string",
+ "description": "名称。"
+ },
+ "description": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "说明。"
+ },
+ "studyTips": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "备考建议。"
+ },
+ "order": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "description": "显示顺序。",
+ "format": "int32"
+ },
+ "isActive": {
+ "type": [
+ "null",
+ "boolean"
+ ],
+ "description": "是否启用。"
+ }
+ },
+ "description": "管理侧专业写入请求。"
+ },
+ "DirectOperationContentDto": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "ID。",
+ "format": "uuid"
+ },
+ "regionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "地区 ID。",
+ "format": "uuid"
+ },
+ "schoolId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "院校 ID。",
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "历史系统 ID。"
+ },
+ "title": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "标题。"
+ },
+ "subtitle": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "副标题。"
+ },
+ "content": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "内容。"
+ },
+ "question": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "问题。"
+ },
+ "answer": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "答案。"
+ },
+ "link": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "链接地址。"
+ },
+ "buttonText": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "按钮文案。"
+ },
+ "buttonLink": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "按钮链接。"
+ },
+ "backgroundColor": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "背景颜色。"
+ },
+ "borderColor": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "边框颜色。"
+ },
+ "examName": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "考试名称。"
+ },
+ "examAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "考试时间。",
+ "format": "date-time"
+ },
+ "examType": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "考试类型。"
+ },
+ "description": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "说明。"
+ },
+ "order": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "description": "显示顺序。",
+ "format": "int32"
+ },
+ "isActive": {
+ "type": [
+ "null",
+ "boolean"
+ ],
+ "description": "是否启用。"
+ },
+ "metadata": {
+ "description": "扩展元数据。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ },
+ "description": "管理侧运营内容写入请求。"
+ },
+ "DirectQuestionVideoDto": {
+ "type": "object",
+ "properties": {
+ "questionId": {
+ "type": "string",
+ "description": "题目 ID。",
+ "format": "uuid"
+ },
+ "videoId": {
+ "type": "string",
+ "description": "视频 ID。",
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "历史系统 ID。"
+ },
+ "videoType": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "视频类型。"
+ },
+ "order": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "description": "显示顺序。",
+ "format": "int32"
+ },
+ "metadata": {
+ "description": "扩展元数据。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ },
+ "description": "管理侧题目视频绑定请求。"
+ },
+ "DirectQuestionWriteDto": {
+ "type": "object",
+ "properties": {
+ "questionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "题目 ID。",
+ "format": "uuid"
+ },
+ "questionBankId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "题库 ID。",
+ "format": "uuid"
+ },
+ "subjectId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "科目 ID。",
+ "format": "uuid"
+ },
+ "categoryId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "分类 ID。",
+ "format": "uuid"
+ },
+ "nodeId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "节点 ID。",
+ "format": "uuid"
+ },
+ "entryId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "内容入口 ID。",
+ "format": "uuid"
+ },
+ "contentNodeId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "内容节点 ID。",
+ "format": "uuid"
+ },
+ "primaryCollectionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "主题集 ID。",
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "历史系统 ID。"
+ },
+ "type": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "类型。"
+ },
+ "typeLabel": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "类型显示名。"
+ },
+ "difficulty": {
+ "maximum": 5,
+ "minimum": 1,
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "description": "难度。",
+ "format": "int32"
+ },
+ "tags": {
+ "description": "标签列表。",
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "content": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "内容。"
+ },
+ "options": {
+ "description": "选项配置。",
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "correctOptionIndex": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "description": "正确选项索引。",
+ "format": "int32"
+ },
+ "correctOptionIndices": {
+ "description": "正确选项索引列表。",
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "answerText": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "文字答案。"
+ },
+ "explanation": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "解析。"
+ },
+ "subQuestions": {
+ "description": "子题列表。",
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "codeLang": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "代码语言。"
+ },
+ "codeTemplate": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "代码模板。"
+ },
+ "mediaUrl": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "媒体地址。"
+ },
+ "status": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "状态。"
+ },
+ "examMarkers": {
+ "description": "考试标记配置。",
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "sourceHash": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "来源哈希。"
+ },
+ "createVersion": {
+ "type": [
+ "null",
+ "boolean"
+ ],
+ "description": "是否创建题目版本。"
+ }
+ },
+ "description": "管理侧题目写入请求。"
+ },
+ "DirectSchoolDto": {
+ "required": [
+ "name"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "ID。",
+ "format": "uuid"
+ },
+ "regionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "地区 ID。",
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "历史系统 ID。"
+ },
+ "name": {
+ "type": "string",
+ "description": "名称。"
+ },
+ "professionalExamDate": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "专业考试日期。"
+ },
+ "metadata": {
+ "description": "扩展元数据。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ },
+ "description": "管理侧院校写入请求。"
+ },
+ "DirectScorelineFieldDto": {
+ "required": [
+ "fieldKey",
+ "fieldName"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "ID。",
+ "format": "uuid"
+ },
+ "regionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "地区 ID。",
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "历史系统 ID。"
+ },
+ "fieldKey": {
+ "type": "string",
+ "description": "字段键。"
+ },
+ "fieldName": {
+ "type": "string",
+ "description": "字段名称。"
+ },
+ "fieldType": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "字段类型。"
+ },
+ "unit": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "单位。"
+ },
+ "isFilter": {
+ "type": [
+ "null",
+ "boolean"
+ ],
+ "description": "是否可筛选。"
+ },
+ "isRequired": {
+ "type": [
+ "null",
+ "boolean"
+ ],
+ "description": "是否必填。"
+ },
+ "isVisible": {
+ "type": [
+ "null",
+ "boolean"
+ ],
+ "description": "是否可见。"
+ },
+ "isTrend": {
+ "type": [
+ "null",
+ "boolean"
+ ],
+ "description": "是否参与趋势展示。"
+ },
+ "options": {
+ "description": "选项配置。",
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "placeholder": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "占位提示。"
+ },
+ "description": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "说明。"
+ },
+ "order": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "description": "显示顺序。",
+ "format": "int32"
+ }
+ },
+ "description": "管理侧分数线字段写入请求。"
+ },
+ "DirectScorelineRecordDto": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "ID。",
+ "format": "uuid"
+ },
+ "regionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "地区 ID。",
+ "format": "uuid"
+ },
+ "schoolId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "院校 ID。",
+ "format": "uuid"
+ },
+ "majorId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "专业 ID。",
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "历史系统 ID。"
+ },
+ "year": {
+ "maximum": 3000,
+ "minimum": 1900,
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "description": "年份。",
+ "format": "int32"
+ },
+ "schoolName": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "院校名称。"
+ },
+ "majorName": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "专业名称。"
+ },
+ "fieldValues": {
+ "description": "动态字段值。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ },
+ "description": "管理侧分数线记录写入请求。"
+ },
+ "DirectVideoDto": {
+ "required": [
+ "title"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "ID。",
+ "format": "uuid"
+ },
+ "subjectId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "科目 ID。",
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "历史系统 ID。"
+ },
+ "title": {
+ "type": "string",
+ "description": "标题。"
+ },
+ "description": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "说明。"
+ },
+ "videoUrl": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "视频地址。"
+ },
+ "thumbnailUrl": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "缩略图地址。"
+ },
+ "durationSeconds": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "description": "时长,单位为秒。",
+ "format": "int32"
+ },
+ "knowledgeTags": {
+ "description": "知识标签。",
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "isGeneral": {
+ "type": [
+ "null",
+ "boolean"
+ ],
+ "description": "是否通用视频。"
+ },
+ "difficulty": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "description": "难度。",
+ "format": "int32"
+ },
+ "order": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "description": "显示顺序。",
+ "format": "int32"
+ },
+ "isActive": {
+ "type": [
+ "null",
+ "boolean"
+ ],
+ "description": "是否启用。"
+ },
+ "metadata": {
+ "description": "扩展元数据。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ },
+ "description": "管理侧视频写入请求。"
+ },
+ "DirectVocabularyUnitDto": {
+ "required": [
+ "name"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "ID。",
+ "format": "uuid"
+ },
+ "regionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "地区 ID。",
+ "format": "uuid"
+ },
+ "entryId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "内容入口 ID。",
+ "format": "uuid"
+ },
+ "contentNodeId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "内容节点 ID。",
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "历史系统 ID。"
+ },
+ "name": {
+ "type": "string",
+ "description": "名称。"
+ },
+ "description": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "说明。"
+ },
+ "wordCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "description": "单词数量。",
+ "format": "int32"
+ },
+ "order": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "description": "显示顺序。",
+ "format": "int32"
+ },
+ "isActive": {
+ "type": [
+ "null",
+ "boolean"
+ ],
+ "description": "是否启用。"
+ },
+ "metadata": {
+ "description": "扩展元数据。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ },
+ "description": "管理侧词汇单元写入请求。"
+ },
+ "DirectVocabularyWordDto": {
+ "required": [
+ "word"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "ID。",
+ "format": "uuid"
+ },
+ "unitId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "单元 ID。",
+ "format": "uuid"
+ },
+ "entryId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "内容入口 ID。",
+ "format": "uuid"
+ },
+ "contentNodeId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "内容节点 ID。",
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "历史系统 ID。"
+ },
+ "word": {
+ "type": "string",
+ "description": "单词。"
+ },
+ "phonetic": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "音标。"
+ },
+ "meaning": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "释义。"
+ },
+ "example": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "例句。"
+ },
+ "exampleTranslation": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "例句翻译。"
+ },
+ "difficulty": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "description": "难度。",
+ "format": "int32"
+ },
+ "tags": {
+ "description": "标签列表。",
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "order": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "description": "显示顺序。",
+ "format": "int32"
+ },
+ "isActive": {
+ "type": [
+ "null",
+ "boolean"
+ ],
+ "description": "是否启用。"
+ },
+ "metadata": {
+ "description": "扩展元数据。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ },
+ "description": "管理侧词汇单词写入请求。"
+ },
+ "DisablePlatformBillingDunningChannelDto": {
+ "required": [
+ "channelId"
+ ],
+ "type": "object",
+ "properties": {
+ "channelId": {
+ "type": "string",
+ "description": "通知渠道 ID。",
+ "format": "uuid"
+ },
+ "reason": {
+ "maxLength": 1000,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "原因。"
+ }
+ },
+ "description": "禁用平台DunningChannel请求 DTO。"
+ },
+ "DisableTenantAdminMemberDto": {
+ "required": [
+ "membershipId"
+ ],
+ "type": "object",
+ "properties": {
+ "membershipId": {
+ "type": "string",
+ "description": "成员关系 ID。",
+ "format": "uuid"
+ }
+ },
+ "description": "禁用租户管理端成员请求 DTO。"
+ },
+ "DiscountType": {
+ "type": "integer"
+ },
+ "ExamCountdownItem": {
+ "required": [
+ "id",
+ "legacyId",
+ "regionId",
+ "schoolId",
+ "examName",
+ "examAt",
+ "examType",
+ "description",
+ "metadata",
+ "order",
+ "isActive",
+ "daysLeft"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "regionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "schoolId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "examName": {
+ "type": "string"
+ },
+ "examAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "examType": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "description": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "order": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "isActive": {
+ "type": "boolean"
+ },
+ "daysLeft": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ }
+ }
+ },
+ "ExamCountdownList": {
+ "required": [
+ "items",
+ "regionId",
+ "schoolId"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ExamCountdownItem"
+ }
+ },
+ "regionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "schoolId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ }
+ }
+ },
+ "ExamDateCatalogItem": {
+ "required": [
+ "id",
+ "legacyId",
+ "regionId",
+ "schoolId",
+ "examName",
+ "examAt",
+ "examType",
+ "description",
+ "metadata",
+ "order",
+ "isActive",
+ "daysLeft"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "regionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "schoolId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "examName": {
+ "type": "string"
+ },
+ "examAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "examType": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "description": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "order": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "isActive": {
+ "type": "boolean"
+ },
+ "daysLeft": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ }
+ }
+ },
+ "FaqCatalogItem": {
+ "required": [
+ "id",
+ "legacyId",
+ "regionId",
+ "question",
+ "answer",
+ "order",
+ "isActive"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "regionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "question": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "answer": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "order": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "isActive": {
+ "type": "boolean"
+ }
+ }
+ },
+ "FavoriteQuestionItem": {
+ "required": [
+ "questionReferenceId",
+ "locator",
+ "createdAt"
+ ],
+ "type": "object",
+ "properties": {
+ "questionReferenceId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "locator": {
+ "$ref": "#/components/schemas/QuestionLocator"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+ },
+ "FavoriteWordDto": {
+ "required": [
+ "wordId"
+ ],
+ "type": "object",
+ "properties": {
+ "wordId": {
+ "type": "string",
+ "description": "单词 ID。",
+ "format": "uuid"
+ },
+ "favorite": {
+ "type": [
+ "null",
+ "boolean"
+ ],
+ "description": "是否收藏。"
+ },
+ "note": {
+ "maxLength": 1000,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "备注。"
+ }
+ },
+ "description": "收藏单词请求 DTO。"
+ },
+ "FavoriteWordItem": {
+ "required": [
+ "wordId",
+ "note",
+ "favoritedAt"
+ ],
+ "type": "object",
+ "properties": {
+ "wordId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "note": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "favoritedAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ }
+ }
+ },
+ "FeatureQuotaSnapshot": {
+ "required": [
+ "metricCode",
+ "usedValue",
+ "limitValue",
+ "usedPercent",
+ "warning",
+ "exceeded",
+ "periodStart",
+ "periodEnd"
+ ],
+ "type": "object",
+ "properties": {
+ "metricCode": {
+ "type": "string"
+ },
+ "usedValue": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int64"
+ },
+ "limitValue": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int64"
+ },
+ "usedPercent": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "warning": {
+ "type": "boolean"
+ },
+ "exceeded": {
+ "type": "boolean"
+ },
+ "periodStart": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "periodEnd": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+ },
+ "FeedbackItem": {
+ "required": [
+ "id",
+ "questionId",
+ "type",
+ "title",
+ "category",
+ "description",
+ "status",
+ "priority",
+ "contact",
+ "attachments",
+ "metadata",
+ "createdAt",
+ "updatedAt"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "questionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "type": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "title": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "category": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "description": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "status": {
+ "type": "string"
+ },
+ "priority": {
+ "type": "string"
+ },
+ "contact": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "attachments": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updatedAt": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+ },
+ "GenerateCommissionSettlementDto": {
+ "required": [
+ "startDate",
+ "endDate",
+ "referrerUserId"
+ ],
+ "type": "object",
+ "properties": {
+ "startDate": {
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
+ "type": "string",
+ "description": "开始日期,格式为 yyyy-MM-dd。"
+ },
+ "endDate": {
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
+ "type": "string",
+ "description": "结束日期,格式为 yyyy-MM-dd。"
+ },
+ "referrerUserId": {
+ "type": "string",
+ "description": "推荐人用户 ID。",
+ "format": "uuid"
+ },
+ "status": {
+ "maxLength": 50,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "状态。"
+ },
+ "remark": {
+ "maxLength": 1000,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "备注。"
+ },
+ "metadata": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "description": "扩展元数据。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ ]
+ }
+ },
+ "description": "生成佣金结算单请求 DTO。"
+ },
+ "GrantTenantAdminBadgeDto": {
+ "required": [
+ "userId",
+ "badgeId"
+ ],
+ "type": "object",
+ "properties": {
+ "userId": {
+ "type": "string",
+ "description": "用户 ID。",
+ "format": "uuid"
+ },
+ "badgeId": {
+ "type": "string",
+ "description": "徽章 ID。",
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "历史系统 ID。"
+ },
+ "note": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "备注。"
+ },
+ "grantedAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "授予时间。",
+ "format": "date-time"
+ },
+ "metadata": {
+ "description": "扩展元数据。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ },
+ "description": "授予租户管理端徽章请求 DTO。"
+ },
+ "HandbookChapter": {
+ "type": "object",
+ "properties": {
+ "subjectId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "entryId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "contentNodeId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "name": {
+ "type": "string"
+ },
+ "description": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "sortOrder": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "isActive": {
+ "type": "boolean"
+ },
+ "sourceHash": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updatedAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "tenantId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ },
+ "HandbookChapterCatalogItem": {
+ "required": [
+ "id",
+ "legacyId",
+ "subjectId",
+ "entryId",
+ "contentNodeId",
+ "name",
+ "description",
+ "order",
+ "metadata"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "subjectId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "entryId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "contentNodeId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "name": {
+ "type": "string"
+ },
+ "description": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "order": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ }
+ },
+ "HandbookEntry": {
+ "type": "object",
+ "properties": {
+ "chapterId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "entryId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "contentNodeId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "title": {
+ "type": "string"
+ },
+ "summary": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "content": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "tags": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "sortOrder": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "isActive": {
+ "type": "boolean"
+ },
+ "sourceHash": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updatedAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "tenantId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ },
+ "HandbookEntryCatalogItem": {
+ "required": [
+ "id",
+ "legacyId",
+ "chapterId",
+ "entryId",
+ "contentNodeId",
+ "title",
+ "summary",
+ "content",
+ "tags",
+ "order",
+ "metadata"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "chapterId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "entryId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "contentNodeId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "title": {
+ "type": "string"
+ },
+ "summary": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "content": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "tags": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "order": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ }
+ },
+ "HandbookSubject": {
+ "type": "object",
+ "properties": {
+ "regionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "schoolId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "majorId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "entryId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "contentNodeId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "name": {
+ "type": "string"
+ },
+ "type": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "$ref": "#/components/schemas/HandbookSubjectType"
+ }
+ ]
+ },
+ "icon": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "color": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "description": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "majorLegacyIds": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "sortOrder": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "isActive": {
+ "type": "boolean"
+ },
+ "sourceHash": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updatedAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "tenantId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ },
+ "HandbookSubjectCatalogItem": {
+ "required": [
+ "id",
+ "legacyId",
+ "regionId",
+ "schoolId",
+ "majorId",
+ "entryId",
+ "contentNodeId",
+ "name",
+ "type",
+ "icon",
+ "color",
+ "description",
+ "order",
+ "metadata"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "regionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "schoolId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "majorId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "entryId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "contentNodeId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "name": {
+ "type": "string"
+ },
+ "type": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "$ref": "#/components/schemas/HandbookSubjectType"
+ }
+ ]
+ },
+ "icon": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "color": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "description": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "order": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ }
+ },
+ "HandbookSubjectType": {
+ "type": "integer"
+ },
+ "HealthResponseDto": {
+ "required": [
+ "status",
+ "service",
+ "checkedAt"
+ ],
+ "type": "object",
+ "properties": {
+ "status": {
+ "type": "string",
+ "description": "服务状态,例如 ok。"
+ },
+ "service": {
+ "type": "string",
+ "description": "服务名称。"
+ },
+ "checkedAt": {
+ "type": "string",
+ "description": "检查时间。",
+ "format": "date-time"
+ }
+ },
+ "description": "健康检查响应。"
+ },
+ "IdempotentTenantBillingDto": {
+ "required": [
+ "idempotencyKey"
+ ],
+ "type": "object",
+ "properties": {
+ "idempotencyKey": {
+ "type": "string"
+ }
+ },
+ "description": "Idempotent租户账务请求 DTO。"
+ },
+ "ImageAssetCatalogItem": {
+ "required": [
+ "id",
+ "legacyId",
+ "title",
+ "category",
+ "fileName",
+ "isPublic",
+ "cdnUrl",
+ "metadata"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "title": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "category": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "fileName": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "isPublic": {
+ "type": "boolean"
+ },
+ "cdnUrl": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ }
+ },
+ "ImportFieldMappingItem": {
+ "required": [
+ "importType",
+ "title",
+ "description",
+ "fields",
+ "requiredFields"
+ ],
+ "type": "object",
+ "properties": {
+ "importType": {
+ "type": "string"
+ },
+ "title": {
+ "type": "string"
+ },
+ "description": {
+ "type": "string"
+ },
+ "fields": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ImportFieldSpec"
+ }
+ },
+ "requiredFields": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "ImportFieldSpec": {
+ "required": [
+ "field",
+ "label",
+ "required",
+ "aliases",
+ "description",
+ "example"
+ ],
+ "type": "object",
+ "properties": {
+ "field": {
+ "type": "string"
+ },
+ "label": {
+ "type": "string"
+ },
+ "required": {
+ "type": "boolean"
+ },
+ "aliases": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "description": {
+ "type": "string"
+ },
+ "example": {
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ }
+ },
+ "ImportIssueSeverity": {
+ "type": "integer"
+ },
+ "ImportPostCheckResult": {
+ "required": [
+ "jobId",
+ "status",
+ "counts",
+ "issues"
+ ],
+ "type": "object",
+ "properties": {
+ "jobId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "status": {
+ "type": "string"
+ },
+ "counts": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "issues": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ContentImportIssueModel"
+ }
+ }
+ }
+ },
+ "ImportSourceFormat": {
+ "type": "integer"
+ },
+ "ImportTemplateItem": {
+ "required": [
+ "importType",
+ "format",
+ "fileName",
+ "mimeType",
+ "contentBase64",
+ "contentPreview",
+ "fields"
+ ],
+ "type": "object",
+ "properties": {
+ "importType": {
+ "type": "string"
+ },
+ "format": {
+ "type": "string"
+ },
+ "fileName": {
+ "type": "string"
+ },
+ "mimeType": {
+ "type": "string"
+ },
+ "contentBase64": {
+ "type": "string"
+ },
+ "contentPreview": {
+ "type": "string"
+ },
+ "fields": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ImportFieldSpec"
+ }
+ }
+ }
+ },
+ "JsonElement": {},
+ "LearningActionResult": {
+ "required": [
+ "ok"
+ ],
+ "type": "object",
+ "properties": {
+ "ok": {
+ "type": "boolean"
+ },
+ "isFavorite": {
+ "type": [
+ "null",
+ "boolean"
+ ]
+ }
+ }
+ },
+ "LearningLeaderboardItem": {
+ "required": [
+ "userId",
+ "displayName",
+ "answerCount",
+ "correctCount",
+ "wrongCount",
+ "accuracy"
+ ],
+ "type": "object",
+ "properties": {
+ "userId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "displayName": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "answerCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "correctCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "wrongCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "accuracy": {
+ "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
+ "type": [
+ "number",
+ "string"
+ ],
+ "format": "double"
+ }
+ }
+ },
+ "LearningLeaderboardResult": {
+ "required": [
+ "metric",
+ "period",
+ "items",
+ "currentUser",
+ "generatedAt"
+ ],
+ "type": "object",
+ "properties": {
+ "metric": {
+ "type": "string"
+ },
+ "period": {
+ "type": "string"
+ },
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/LearningLeaderboardItem"
+ }
+ },
+ "currentUser": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "$ref": "#/components/schemas/LearningLeaderboardItem"
+ }
+ ]
+ },
+ "generatedAt": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+ },
+ "LearningListOfFavoriteQuestionItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/FavoriteQuestionItem"
+ }
+ }
+ }
+ },
+ "LearningListOfFavoriteWordItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/FavoriteWordItem"
+ }
+ }
+ }
+ },
+ "LearningListOfLearningTrendItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/LearningTrendItem"
+ }
+ }
+ }
+ },
+ "LearningListOfPracticeHistoryItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/PracticeHistoryItem"
+ }
+ }
+ }
+ },
+ "LearningListOfPracticeSessionReportItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/PracticeSessionReportItem"
+ }
+ }
+ }
+ },
+ "LearningListOfWordProgressItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/WordProgressItem"
+ }
+ }
+ }
+ },
+ "LearningListOfWrongQuestionItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/WrongQuestionItem"
+ }
+ }
+ }
+ },
+ "LearningStatsItem": {
+ "required": [
+ "answerCount",
+ "correctCount",
+ "wrongCount",
+ "favoriteQuestionCount",
+ "favoriteWordCount",
+ "wordProgressCount",
+ "practiceSessionCount",
+ "practiceReportCount"
+ ],
+ "type": "object",
+ "properties": {
+ "answerCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "correctCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "wrongCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "favoriteQuestionCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "favoriteWordCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "wordProgressCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "practiceSessionCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "practiceReportCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ }
+ }
+ },
+ "LearningTrendItem": {
+ "required": [
+ "date",
+ "answerCount",
+ "correctCount",
+ "wrongCount"
+ ],
+ "type": "object",
+ "properties": {
+ "date": {
+ "type": "string",
+ "format": "date"
+ },
+ "answerCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "correctCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "wrongCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ }
+ }
+ },
+ "Major": {
+ "type": "object",
+ "properties": {
+ "regionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "schoolId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "name": {
+ "type": "string"
+ },
+ "description": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "studyTips": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "sortOrder": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "isActive": {
+ "type": "boolean"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updatedAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "tenantId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ },
+ "MajorCatalogItem": {
+ "required": [
+ "id",
+ "legacyId",
+ "regionId",
+ "schoolId",
+ "name",
+ "description",
+ "studyTips",
+ "order"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "regionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "schoolId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "name": {
+ "type": "string"
+ },
+ "description": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "studyTips": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "order": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ }
+ }
+ },
+ "ManualBindReferralDto": {
+ "required": [
+ "studentUserId",
+ "referrerUserId"
+ ],
+ "type": "object",
+ "properties": {
+ "studentUserId": {
+ "type": "string",
+ "description": "学生用户 ID。",
+ "format": "uuid"
+ },
+ "referrerUserId": {
+ "type": "string",
+ "description": "推荐人用户 ID。",
+ "format": "uuid"
+ },
+ "source": {
+ "maxLength": 100,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "来源。"
+ },
+ "force": {
+ "type": "boolean",
+ "description": "是否强制执行。"
+ },
+ "metadata": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "description": "扩展元数据。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ ]
+ }
+ },
+ "description": "人工绑定推荐请求 DTO。"
+ },
+ "MembershipStatus": {
+ "type": "integer"
+ },
+ "MeResponse": {
+ "required": [
+ "userId",
+ "phone",
+ "email",
+ "name",
+ "tenants"
+ ],
+ "type": "object",
+ "properties": {
+ "userId": {
+ "type": "string",
+ "description": "用户 ID。",
+ "format": "uuid"
+ },
+ "phone": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "手机号。"
+ },
+ "email": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "邮箱。"
+ },
+ "name": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "用户显示名称。"
+ },
+ "tenants": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/TenantMembershipResponse"
+ },
+ "description": "当前用户拥有的活跃租户成员列表。"
+ }
+ },
+ "description": "当前用户基础信息和租户成员摘要。"
+ },
+ "ModuleNodeCatalogItem": {
+ "required": [
+ "id",
+ "legacyId",
+ "regionId",
+ "moduleId",
+ "parentId",
+ "legacyParentId",
+ "type",
+ "name",
+ "path",
+ "order",
+ "metadata"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "regionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "moduleId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "parentId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "legacyParentId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "type": {
+ "$ref": "#/components/schemas/ModuleNodeType"
+ },
+ "name": {
+ "type": "string"
+ },
+ "path": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "order": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ }
+ },
+ "ModuleNodeType": {
+ "type": "integer"
+ },
+ "NotificationSeverity": {
+ "type": "integer"
+ },
+ "NotificationStatus": {
+ "type": "integer"
+ },
+ "NotificationStatusDto": {
+ "required": [
+ "notificationIds"
+ ],
+ "type": "object",
+ "properties": {
+ "notificationIds": {
+ "maxItems": 100,
+ "minItems": 1,
+ "type": "array",
+ "items": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "description": "通知 ID 列表。"
+ },
+ "status": {
+ "maxLength": 32,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "状态。"
+ }
+ },
+ "description": "通知状态请求 DTO。"
+ },
+ "OAuthCodeDto": {
+ "required": [
+ "realm",
+ "code"
+ ],
+ "type": "object",
+ "properties": {
+ "realm": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "description": "认证域。",
+ "$ref": "#/components/schemas/AuthRealm"
+ }
+ ]
+ },
+ "tenantCode": {
+ "maxLength": 100,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "租户编码。"
+ },
+ "code": {
+ "maxLength": 512,
+ "minLength": 0,
+ "type": "string",
+ "description": "编码。"
+ },
+ "profile": {
+ "type": [
+ "null",
+ "object"
+ ],
+ "description": "公开用户资料。"
+ },
+ "lang": {
+ "maxLength": 20,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "语言。"
+ }
+ },
+ "description": "O认证编码请求 DTO。"
+ },
+ "ObjectStorageMetadata": {
+ "required": [
+ "provider",
+ "bucket",
+ "objectKey",
+ "exists",
+ "sizeBytes",
+ "mimeType",
+ "checksumSha256",
+ "eTag",
+ "lastModified",
+ "rawHeaders",
+ "verificationSource"
+ ],
+ "type": "object",
+ "properties": {
+ "provider": {
+ "type": "string"
+ },
+ "bucket": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "objectKey": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "exists": {
+ "type": "boolean"
+ },
+ "sizeBytes": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "format": "int64"
+ },
+ "mimeType": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "checksumSha256": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "eTag": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "lastModified": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "rawHeaders": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ }
+ },
+ "verificationSource": {
+ "type": "string"
+ }
+ }
+ },
+ "ObjectStorageSignedUrl": {
+ "required": [
+ "provider",
+ "bucket",
+ "objectKey",
+ "method",
+ "url",
+ "headers",
+ "expiresAt",
+ "expiresIn",
+ "signatureMode"
+ ],
+ "type": "object",
+ "properties": {
+ "provider": {
+ "type": "string"
+ },
+ "bucket": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "objectKey": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "method": {
+ "type": "string"
+ },
+ "url": {
+ "type": "string",
+ "format": "uri"
+ },
+ "headers": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ }
+ },
+ "expiresAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "expiresIn": {
+ "pattern": "^-?(\\d+\\.)?\\d{2}:\\d{2}:\\d{2}(\\.\\d{1,7})?$",
+ "type": "string"
+ },
+ "signatureMode": {
+ "type": "string"
+ }
+ }
+ },
+ "OperationContentItem": {
+ "required": [
+ "id",
+ "kind",
+ "regionId",
+ "schoolId",
+ "legacyId",
+ "title",
+ "content",
+ "question",
+ "answer",
+ "examAt",
+ "examType",
+ "order",
+ "isActive",
+ "metadata"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "kind": {
+ "type": "string"
+ },
+ "regionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "schoolId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "title": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "content": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "question": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "answer": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "examAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "examType": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "order": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "isActive": {
+ "type": "boolean"
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ }
+ },
+ "PasswordLoginDto": {
+ "required": [
+ "realm",
+ "password"
+ ],
+ "type": "object",
+ "properties": {
+ "realm": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "description": "认证域。",
+ "$ref": "#/components/schemas/AuthRealm"
+ }
+ ]
+ },
+ "tenantCode": {
+ "maxLength": 100,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "租户编码。"
+ },
+ "identifier": {
+ "maxLength": 320,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "账号标识。"
+ },
+ "phone": {
+ "maxLength": 32,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "兼容手机号字段;新客户端应使用 identifier。"
+ },
+ "password": {
+ "maxLength": 128,
+ "minLength": 8,
+ "type": "string",
+ "description": "密码。"
+ }
+ },
+ "description": "PasswordLogin请求 DTO。"
+ },
+ "PaymentNotificationProcessResult": {
+ "required": [
+ "provider",
+ "eventId",
+ "orderNo",
+ "status",
+ "idempotent"
+ ],
+ "type": "object",
+ "properties": {
+ "provider": {
+ "type": "string"
+ },
+ "eventId": {
+ "type": "string"
+ },
+ "orderNo": {
+ "type": "string"
+ },
+ "status": {
+ "type": "string"
+ },
+ "idempotent": {
+ "type": "boolean"
+ }
+ }
+ },
+ "PlatformAlertSeverity": {
+ "type": "integer"
+ },
+ "PlatformAuditAlert": {
+ "type": "object",
+ "properties": {
+ "ruleId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "auditLogId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "tenantId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "acknowledgedBy": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "resolvedBy": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "severity": {
+ "$ref": "#/components/schemas/PlatformAlertSeverity"
+ },
+ "status": {
+ "$ref": "#/components/schemas/PlatformAuditAlertStatus"
+ },
+ "action": {
+ "type": "string"
+ },
+ "targetType": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "targetId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "title": {
+ "type": "string"
+ },
+ "summary": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "details": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "firstSeenAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "lastSeenAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "acknowledgedAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "resolvedAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "resolutionNote": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updatedAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ },
+ "PlatformAuditAlertList": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/PlatformAuditAlert"
+ }
+ }
+ }
+ },
+ "PlatformAuditAlertStatus": {
+ "type": "integer"
+ },
+ "PlatformAuditLogItem": {
+ "required": [
+ "id",
+ "tenantId",
+ "actorUserId",
+ "action",
+ "targetType",
+ "targetId",
+ "details",
+ "ipAddress",
+ "userAgent",
+ "createdAt"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "tenantId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "actorUserId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "action": {
+ "type": "string"
+ },
+ "targetType": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "targetId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "details": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "ipAddress": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "userAgent": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+ },
+ "PlatformAuditLogList": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/PlatformAuditLogItem"
+ }
+ }
+ }
+ },
+ "PlatformBillingCycle": {
+ "type": "integer"
+ },
+ "PlatformBillingDunningChannelItem": {
+ "required": [
+ "id",
+ "channelCode",
+ "name",
+ "description",
+ "enabled",
+ "provider",
+ "webhookUrlMasked",
+ "secretRef",
+ "reminderTypes",
+ "reminderChannels",
+ "minReminderLevel",
+ "tenantIds",
+ "timeoutSeconds",
+ "metadata",
+ "createdAt",
+ "updatedAt"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "channelCode": {
+ "type": "string"
+ },
+ "name": {
+ "type": "string"
+ },
+ "description": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "enabled": {
+ "type": "boolean"
+ },
+ "provider": {
+ "$ref": "#/components/schemas/PlatformBillingDunningProvider"
+ },
+ "webhookUrlMasked": {
+ "type": "string"
+ },
+ "secretRef": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "reminderTypes": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "reminderChannels": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "minReminderLevel": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "tenantIds": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "format": "uuid"
+ }
+ },
+ "timeoutSeconds": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updatedAt": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+ },
+ "PlatformBillingDunningChannelList": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/PlatformBillingDunningChannelItem"
+ }
+ }
+ }
+ },
+ "PlatformBillingDunningEventItem": {
+ "required": [
+ "id",
+ "tenantId",
+ "channelId",
+ "reminderId",
+ "invoiceId",
+ "provider",
+ "status",
+ "attempts",
+ "scheduledAt",
+ "nextAttemptAt",
+ "lastAttemptAt",
+ "sentAt",
+ "lastError",
+ "lastHttpCode",
+ "lastResponseSummary",
+ "requestPayload",
+ "metadata",
+ "createdAt",
+ "updatedAt"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "tenantId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "channelId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "reminderId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "invoiceId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "provider": {
+ "$ref": "#/components/schemas/PlatformBillingDunningProvider"
+ },
+ "status": {
+ "$ref": "#/components/schemas/PlatformBillingDunningNotificationStatus"
+ },
+ "attempts": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "scheduledAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "nextAttemptAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "lastAttemptAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "sentAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "lastError": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "lastHttpCode": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "lastResponseSummary": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "requestPayload": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updatedAt": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+ },
+ "PlatformBillingDunningEventList": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/PlatformBillingDunningEventItem"
+ }
+ }
+ }
+ },
+ "PlatformBillingDunningNotificationStatus": {
+ "type": "integer"
+ },
+ "PlatformBillingDunningProvider": {
+ "type": "integer"
+ },
+ "PlatformBillingInvoice": {
+ "type": "object",
+ "properties": {
+ "orderId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "invoiceNo": {
+ "type": "string"
+ },
+ "status": {
+ "$ref": "#/components/schemas/PlatformBillingInvoiceStatus"
+ },
+ "totalAmountCents": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "currency": {
+ "type": "string"
+ },
+ "dueDate": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date"
+ },
+ "issuedAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "paidAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "billingProfileSnapshot": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updatedAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "tenantId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ },
+ "PlatformBillingInvoiceReminder": {
+ "type": "object",
+ "properties": {
+ "invoiceId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "createdBy": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "reminderType": {
+ "$ref": "#/components/schemas/PlatformBillingInvoiceReminderType"
+ },
+ "channel": {
+ "$ref": "#/components/schemas/PlatformBillingInvoiceReminderChannel"
+ },
+ "status": {
+ "$ref": "#/components/schemas/PlatformBillingInvoiceReminderStatus"
+ },
+ "reminderDate": {
+ "type": "string",
+ "format": "date"
+ },
+ "reminderLevel": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "dueDate": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date"
+ },
+ "balanceCentsSnapshot": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "message": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "sentAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "acknowledgedAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updatedAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "tenantId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ },
+ "PlatformBillingInvoiceReminderChannel": {
+ "type": "integer"
+ },
+ "PlatformBillingInvoiceReminderStatus": {
+ "type": "integer"
+ },
+ "PlatformBillingInvoiceReminderType": {
+ "type": "integer"
+ },
+ "PlatformBillingInvoiceStatus": {
+ "type": "integer"
+ },
+ "PlatformBillingItemType": {
+ "type": "integer"
+ },
+ "PlatformBillingOrder": {
+ "type": "object",
+ "properties": {
+ "quoteId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "orderNo": {
+ "type": "string"
+ },
+ "idempotencyKey": {
+ "type": "string"
+ },
+ "purpose": {
+ "$ref": "#/components/schemas/PlatformBillingOrderPurpose"
+ },
+ "status": {
+ "$ref": "#/components/schemas/PlatformBillingOrderStatus"
+ },
+ "originalAmountCents": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "discountAmountCents": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "totalAmountCents": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "currency": {
+ "type": "string"
+ },
+ "expiresAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "paidAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "cancelledAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "snapshot": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updatedAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "tenantId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ },
+ "PlatformBillingOrderPurpose": {
+ "type": "integer"
+ },
+ "PlatformBillingOrderStatus": {
+ "type": "integer"
+ },
+ "PlatformBillingOrderView": {
+ "required": [
+ "id",
+ "orderNo",
+ "purpose",
+ "status",
+ "totalAmountCents",
+ "currency",
+ "expiresAt",
+ "paidAt",
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "orderNo": {
+ "type": "string"
+ },
+ "purpose": {
+ "$ref": "#/components/schemas/PlatformBillingOrderPurpose"
+ },
+ "status": {
+ "$ref": "#/components/schemas/PlatformBillingOrderStatus"
+ },
+ "totalAmountCents": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "currency": {
+ "type": "string"
+ },
+ "expiresAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "paidAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/PlatformBillingQuoteItemView"
+ }
+ }
+ }
+ },
+ "PlatformBillingPayment": {
+ "type": "object",
+ "properties": {
+ "orderId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "paymentNo": {
+ "type": "string"
+ },
+ "idempotencyKey": {
+ "type": "string"
+ },
+ "provider": {
+ "type": "string"
+ },
+ "method": {
+ "type": "string"
+ },
+ "status": {
+ "$ref": "#/components/schemas/PlatformBillingPaymentStatus"
+ },
+ "amountCents": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "providerTradeNo": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "paidAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "clientPayload": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updatedAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "tenantId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ },
+ "PlatformBillingPaymentEvent": {
+ "type": "object",
+ "properties": {
+ "tenantId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "paymentId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "provider": {
+ "type": "string"
+ },
+ "providerEventId": {
+ "type": "string"
+ },
+ "eventType": {
+ "type": "string"
+ },
+ "payload": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ },
+ "PlatformBillingPaymentStatus": {
+ "type": "integer"
+ },
+ "PlatformBillingPaymentView": {
+ "required": [
+ "id",
+ "paymentNo",
+ "provider",
+ "method",
+ "status",
+ "amountCents",
+ "clientPayload"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "paymentNo": {
+ "type": "string"
+ },
+ "provider": {
+ "type": "string"
+ },
+ "method": {
+ "type": "string"
+ },
+ "status": {
+ "$ref": "#/components/schemas/PlatformBillingPaymentStatus"
+ },
+ "amountCents": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "clientPayload": {
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ }
+ },
+ "PlatformBillingQuoteItemView": {
+ "required": [
+ "offeringVersionId",
+ "offeringCode",
+ "offeringName",
+ "itemType",
+ "unitAmountCents",
+ "amountCents"
+ ],
+ "type": "object",
+ "properties": {
+ "offeringVersionId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "offeringCode": {
+ "type": "string"
+ },
+ "offeringName": {
+ "type": "string"
+ },
+ "itemType": {
+ "$ref": "#/components/schemas/PlatformBillingItemType"
+ },
+ "unitAmountCents": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "amountCents": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ }
+ }
+ },
+ "PlatformBillingQuoteStatus": {
+ "type": "integer"
+ },
+ "PlatformBillingQuoteView": {
+ "required": [
+ "id",
+ "quoteNo",
+ "status",
+ "purpose",
+ "originalAmountCents",
+ "discountAmountCents",
+ "totalAmountCents",
+ "currency",
+ "expiresAt",
+ "items",
+ "featureCodes",
+ "limits"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "quoteNo": {
+ "type": "string"
+ },
+ "status": {
+ "$ref": "#/components/schemas/PlatformBillingQuoteStatus"
+ },
+ "purpose": {
+ "$ref": "#/components/schemas/PlatformBillingOrderPurpose"
+ },
+ "originalAmountCents": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "discountAmountCents": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "totalAmountCents": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "currency": {
+ "type": "string"
+ },
+ "expiresAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/PlatformBillingQuoteItemView"
+ }
+ },
+ "featureCodes": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "limits": {
+ "type": "object",
+ "additionalProperties": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int64"
+ }
+ }
+ }
+ },
+ "PlatformBillingRefund": {
+ "type": "object",
+ "properties": {
+ "orderId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "paymentId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "refundNo": {
+ "type": "string"
+ },
+ "status": {
+ "$ref": "#/components/schemas/PlatformBillingRefundStatus"
+ },
+ "amountCents": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "reason": {
+ "type": "string"
+ },
+ "providerRefundNo": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "completedAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updatedAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "tenantId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ },
+ "PlatformBillingRefundStatus": {
+ "type": "integer"
+ },
+ "PlatformCrmConfigItem": {
+ "required": [
+ "id",
+ "tenantId",
+ "tenantName",
+ "enabled",
+ "url",
+ "secretRef",
+ "formName",
+ "examType",
+ "timeoutSeconds",
+ "delaySeconds",
+ "assignmentMode",
+ "assignmentPool",
+ "assignmentConfig",
+ "updatedAt"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "tenantId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "tenantName": {
+ "type": "string"
+ },
+ "enabled": {
+ "type": "boolean"
+ },
+ "url": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "secretRef": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "formName": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "examType": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "timeoutSeconds": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "delaySeconds": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "assignmentMode": {
+ "$ref": "#/components/schemas/ReferralAssignmentMode"
+ },
+ "assignmentPool": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "assignmentConfig": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "updatedAt": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+ },
+ "PlatformDomainList": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/PlatformTenantDomainItem"
+ }
+ }
+ }
+ },
+ "PlatformDomainRecheckResult": {
+ "required": [
+ "domainId",
+ "status",
+ "lastCheckedAt"
+ ],
+ "type": "object",
+ "properties": {
+ "domainId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "status": {
+ "$ref": "#/components/schemas/TenantDomainStatus"
+ },
+ "lastCheckedAt": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+ },
+ "PlatformOverview": {
+ "required": [
+ "tenantCount",
+ "activeTenantCount",
+ "suspendedTenantCount",
+ "orderCount",
+ "paidOrderCount",
+ "revenueCents",
+ "questionBankCount",
+ "questionCount",
+ "learningActiveUserCount"
+ ],
+ "type": "object",
+ "properties": {
+ "tenantCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "activeTenantCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "suspendedTenantCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "orderCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "paidOrderCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "revenueCents": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "questionBankCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "questionCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "learningActiveUserCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ }
+ }
+ },
+ "PlatformPaymentApp": {
+ "type": "object",
+ "properties": {
+ "appCode": {
+ "type": "string"
+ },
+ "appName": {
+ "type": "string"
+ },
+ "status": {
+ "$ref": "#/components/schemas/PlatformPaymentAppStatus"
+ },
+ "settlementMode": {
+ "type": "string"
+ },
+ "description": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updatedAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ },
+ "PlatformPaymentAppStatus": {
+ "type": "integer"
+ },
+ "PlatformPaymentChannel": {
+ "type": "object",
+ "properties": {
+ "appId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "provider": {
+ "type": "string"
+ },
+ "mode": {
+ "type": "string"
+ },
+ "status": {
+ "$ref": "#/components/schemas/PlatformPaymentChannelStatus"
+ },
+ "displayName": {
+ "type": "string"
+ },
+ "secretRef": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "callbackPath": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "priority": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "configPublic": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updatedAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ },
+ "PlatformPaymentChannelStatus": {
+ "type": "integer"
+ },
+ "PlatformQuestionBankItem": {
+ "required": [
+ "id",
+ "contentEntryId",
+ "name",
+ "status",
+ "nodeCount",
+ "questionCount",
+ "metadata",
+ "createdAt",
+ "updatedAt"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "contentEntryId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "name": {
+ "type": "string"
+ },
+ "status": {
+ "$ref": "#/components/schemas/QuestionBankStatus"
+ },
+ "nodeCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "questionCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updatedAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ }
+ }
+ },
+ "PlatformQuestionBankNodeItem": {
+ "required": [
+ "id",
+ "questionBankId",
+ "entryId",
+ "parentId",
+ "nodeKey",
+ "name",
+ "nodeType",
+ "depth",
+ "sortOrder",
+ "isActive",
+ "isSelectable",
+ "isLeaf",
+ "questionCount",
+ "metadata"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "questionBankId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "entryId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "parentId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "nodeKey": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "name": {
+ "type": "string"
+ },
+ "nodeType": {
+ "$ref": "#/components/schemas/ContentNodeType"
+ },
+ "depth": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "sortOrder": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "isActive": {
+ "type": "boolean"
+ },
+ "isSelectable": {
+ "type": "boolean"
+ },
+ "isLeaf": {
+ "type": "boolean"
+ },
+ "questionCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ }
+ },
+ "PlatformQuestionImportCommand": {
+ "required": [
+ "questionBankId",
+ "contentNodeId",
+ "format",
+ "sourceName",
+ "payload"
+ ],
+ "type": "object",
+ "properties": {
+ "questionBankId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "contentNodeId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "format": {
+ "type": "string"
+ },
+ "sourceName": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "payload": {
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ }
+ },
+ "PlatformQuestionImportResult": {
+ "required": [
+ "detail",
+ "createdNodeCount",
+ "insertedQuestionCount",
+ "updatedQuestionCount",
+ "skippedQuestionCount"
+ ],
+ "type": "object",
+ "properties": {
+ "detail": {
+ "$ref": "#/components/schemas/ContentImportJobDetail"
+ },
+ "createdNodeCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "insertedQuestionCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "updatedQuestionCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "skippedQuestionCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ }
+ }
+ },
+ "PlatformQuestionItem": {
+ "required": [
+ "id",
+ "versionId",
+ "questionBankId",
+ "entryId",
+ "contentNodeId",
+ "legacyId",
+ "type",
+ "typeLabel",
+ "difficulty",
+ "tags",
+ "content",
+ "options",
+ "correctOptionIndex",
+ "correctOptionIndices",
+ "answerText",
+ "explanation",
+ "subQuestions",
+ "codeLang",
+ "codeTemplate",
+ "mediaUrl",
+ "status",
+ "versionNo",
+ "createdAt",
+ "updatedAt"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "versionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "questionBankId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "entryId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "contentNodeId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "type": {
+ "type": "string"
+ },
+ "typeLabel": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "difficulty": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "tags": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "content": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "options": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "correctOptionIndex": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "correctOptionIndices": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "answerText": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "explanation": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "subQuestions": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "codeLang": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "codeTemplate": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "mediaUrl": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "status": {
+ "$ref": "#/components/schemas/QuestionStatus"
+ },
+ "versionNo": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updatedAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ }
+ }
+ },
+ "PlatformQuestionPage": {
+ "required": [
+ "items",
+ "total",
+ "page",
+ "pageSize"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/PlatformQuestionItem"
+ }
+ },
+ "total": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "page": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "pageSize": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ }
+ }
+ },
+ "PlatformRebateSummary": {
+ "required": [
+ "grossAmountCents",
+ "commissionAmountCents",
+ "pendingSettlementCents",
+ "paidSettlementCents",
+ "exceptionCount"
+ ],
+ "type": "object",
+ "properties": {
+ "grossAmountCents": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "commissionAmountCents": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "pendingSettlementCents": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "paidSettlementCents": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "exceptionCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ }
+ }
+ },
+ "PlatformSmsChannelItem": {
+ "required": [
+ "id",
+ "tenantId",
+ "tenantName",
+ "provider",
+ "name",
+ "signature",
+ "scene",
+ "status",
+ "secretRef",
+ "priority",
+ "monthlyQuota",
+ "sentThisMonth",
+ "configPublic",
+ "metadata",
+ "updatedAt"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "tenantId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "tenantName": {
+ "type": "string"
+ },
+ "provider": {
+ "type": "string"
+ },
+ "name": {
+ "type": "string"
+ },
+ "signature": {
+ "type": "string"
+ },
+ "scene": {
+ "type": "string"
+ },
+ "status": {
+ "$ref": "#/components/schemas/TenantExternalProviderStatus"
+ },
+ "secretRef": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "priority": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "monthlyQuota": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "sentThisMonth": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "configPublic": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "updatedAt": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+ },
+ "PlatformSmsTemplateItem": {
+ "required": [
+ "id",
+ "tenantId",
+ "tenantName",
+ "channelId",
+ "channelName",
+ "code",
+ "name",
+ "type",
+ "auditStatus",
+ "status",
+ "providerTemplateCode",
+ "content",
+ "remark",
+ "sentCount",
+ "failedCount",
+ "updatedAt"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "tenantId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "tenantName": {
+ "type": "string"
+ },
+ "channelId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "channelName": {
+ "type": "string"
+ },
+ "code": {
+ "type": "string"
+ },
+ "name": {
+ "type": "string"
+ },
+ "type": {
+ "$ref": "#/components/schemas/SmsTemplateType"
+ },
+ "auditStatus": {
+ "$ref": "#/components/schemas/SmsTemplateAuditStatus"
+ },
+ "status": {
+ "$ref": "#/components/schemas/SmsTemplateStatus"
+ },
+ "providerTemplateCode": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "content": {
+ "type": "string"
+ },
+ "remark": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "sentCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "failedCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "updatedAt": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+ },
+ "PlatformStaffItem": {
+ "required": [
+ "userId",
+ "name",
+ "phoneMasked",
+ "email",
+ "status",
+ "roleCodes",
+ "createdAt",
+ "updatedAt"
+ ],
+ "type": "object",
+ "properties": {
+ "userId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "name": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "phoneMasked": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "email": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "status": {
+ "$ref": "#/components/schemas/UserStatus"
+ },
+ "roleCodes": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updatedAt": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+ },
+ "PlatformStaffList": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/PlatformStaffItem"
+ }
+ }
+ }
+ },
+ "PlatformTenantCapabilityListOfCrmWebhookLog": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/CrmWebhookLog"
+ }
+ }
+ }
+ },
+ "PlatformTenantCapabilityListOfCrmWebhookQueueItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/CrmWebhookQueueItem"
+ }
+ }
+ }
+ },
+ "PlatformTenantCapabilityListOfObject": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array"
+ }
+ }
+ },
+ "PlatformTenantCapabilityListOfPlatformCrmConfigItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/PlatformCrmConfigItem"
+ }
+ }
+ }
+ },
+ "PlatformTenantCapabilityListOfPlatformSmsChannelItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/PlatformSmsChannelItem"
+ }
+ }
+ }
+ },
+ "PlatformTenantCapabilityListOfPlatformSmsTemplateItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/PlatformSmsTemplateItem"
+ }
+ }
+ }
+ },
+ "PlatformTenantCapabilityListOfSmsSendLog": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/SmsSendLog"
+ }
+ }
+ }
+ },
+ "PlatformTenantCapabilityListOfTenantExternalProviderItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/TenantExternalProviderItem"
+ }
+ }
+ }
+ },
+ "PlatformTenantDetail": {
+ "required": [
+ "tenant",
+ "domains",
+ "subscriptions",
+ "billingProfile"
+ ],
+ "type": "object",
+ "properties": {
+ "tenant": {
+ "$ref": "#/components/schemas/PlatformTenantItem"
+ },
+ "domains": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/PlatformTenantDomainItem"
+ }
+ },
+ "subscriptions": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/PlatformTenantSubscriptionItem"
+ }
+ },
+ "billingProfile": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "$ref": "#/components/schemas/TenantBillingProfileItem"
+ }
+ ]
+ }
+ }
+ },
+ "PlatformTenantDomainItem": {
+ "required": [
+ "id",
+ "tenantId",
+ "host",
+ "domainType",
+ "status",
+ "isPrimary",
+ "verifiedAt",
+ "dnsVerifiedAt",
+ "tlsReadyAt",
+ "lastCheckedAt",
+ "lastFailureReason"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "tenantId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "host": {
+ "type": "string"
+ },
+ "domainType": {
+ "$ref": "#/components/schemas/TenantDomainType"
+ },
+ "status": {
+ "$ref": "#/components/schemas/TenantDomainStatus"
+ },
+ "isPrimary": {
+ "type": "boolean"
+ },
+ "verifiedAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "dnsVerifiedAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "tlsReadyAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "lastCheckedAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "lastFailureReason": {
+ "type": [
+ "null",
+ "string"
+ ]
+ }
+ }
+ },
+ "PlatformTenantItem": {
+ "required": [
+ "id",
+ "slug",
+ "name",
+ "legalName",
+ "status",
+ "mode",
+ "billingStatus",
+ "subscriptionExpiresAt",
+ "domainCount",
+ "createdAt",
+ "updatedAt"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "slug": {
+ "type": "string"
+ },
+ "name": {
+ "type": "string"
+ },
+ "legalName": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "status": {
+ "$ref": "#/components/schemas/TenantStatus"
+ },
+ "mode": {
+ "$ref": "#/components/schemas/TenantMode"
+ },
+ "billingStatus": {
+ "$ref": "#/components/schemas/BillingStatus"
+ },
+ "subscriptionExpiresAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "domainCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updatedAt": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+ },
+ "PlatformTenantList": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/PlatformTenantItem"
+ }
+ }
+ }
+ },
+ "PlatformTenantProvisioningResult": {
+ "required": [
+ "tenant",
+ "ownerUserId",
+ "ownerIdentifier",
+ "mustChangePassword"
+ ],
+ "type": "object",
+ "properties": {
+ "tenant": {
+ "$ref": "#/components/schemas/PlatformTenantItem"
+ },
+ "ownerUserId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "ownerIdentifier": {
+ "type": "string"
+ },
+ "mustChangePassword": {
+ "type": "boolean"
+ }
+ }
+ },
+ "PlatformTenantSubscriptionItem": {
+ "required": [
+ "id",
+ "tenantId",
+ "baseOfferingVersionId",
+ "status",
+ "startsAt",
+ "currentPeriodStart",
+ "currentPeriodEnd",
+ "cancelAtPeriodEnd",
+ "metadata"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "tenantId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "baseOfferingVersionId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "status": {
+ "$ref": "#/components/schemas/TenantSaasSubscriptionStatus"
+ },
+ "startsAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "currentPeriodStart": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "currentPeriodEnd": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "cancelAtPeriodEnd": {
+ "type": "boolean"
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ }
+ },
+ "PointActivityClaim": {
+ "type": "object",
+ "properties": {
+ "taskId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "userId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "taskKey": {
+ "type": "string"
+ },
+ "points": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "status": {
+ "$ref": "#/components/schemas/PointActivityClaimStatus"
+ },
+ "sourceType": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "sourceId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "claimedAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updatedAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "tenantId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ },
+ "PointActivityClaimStatus": {
+ "type": "integer"
+ },
+ "PointActivityTask": {
+ "type": "object",
+ "properties": {
+ "taskKey": {
+ "type": "string"
+ },
+ "title": {
+ "type": "string"
+ },
+ "description": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "taskType": {
+ "$ref": "#/components/schemas/PointActivityTaskType"
+ },
+ "status": {
+ "$ref": "#/components/schemas/PointActivityTaskStatus"
+ },
+ "points": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "maxClaimsPerUser": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "startsAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "endsAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "sortOrder": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "rules": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updatedAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "tenantId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ },
+ "PointActivityTaskStatus": {
+ "type": "integer"
+ },
+ "PointActivityTaskType": {
+ "type": "integer"
+ },
+ "PointClaimItem": {
+ "required": [
+ "id",
+ "taskId",
+ "taskKey",
+ "points",
+ "status",
+ "sourceType",
+ "sourceId",
+ "claimedAt",
+ "metadata"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "taskId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "taskKey": {
+ "type": "string"
+ },
+ "points": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "status": {
+ "type": "string"
+ },
+ "sourceType": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "sourceId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "claimedAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ }
+ },
+ "PointExchangeItem": {
+ "type": "object",
+ "properties": {
+ "regionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "itemKey": {
+ "type": "string"
+ },
+ "name": {
+ "type": "string"
+ },
+ "description": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "itemType": {
+ "$ref": "#/components/schemas/PointExchangeItemType"
+ },
+ "status": {
+ "$ref": "#/components/schemas/PointExchangeItemStatus"
+ },
+ "pointsCost": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "stock": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "days": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "sortOrder": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "startsAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "endsAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "fulfillmentPayload": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updatedAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "tenantId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ },
+ "PointExchangeItemDto": {
+ "required": [
+ "id",
+ "regionId",
+ "itemKey",
+ "name",
+ "description",
+ "itemType",
+ "status",
+ "pointsCost",
+ "stock",
+ "days",
+ "canExchange",
+ "sortOrder",
+ "fulfillmentPayload",
+ "metadata"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "regionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "itemKey": {
+ "type": "string"
+ },
+ "name": {
+ "type": "string"
+ },
+ "description": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "itemType": {
+ "type": "string"
+ },
+ "status": {
+ "type": "string"
+ },
+ "pointsCost": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "stock": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "days": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "canExchange": {
+ "type": "boolean"
+ },
+ "sortOrder": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "fulfillmentPayload": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ }
+ },
+ "PointExchangeItemStatus": {
+ "type": "integer"
+ },
+ "PointExchangeItemType": {
+ "type": "integer"
+ },
+ "PointExchangeOrder": {
+ "type": "object",
+ "properties": {
+ "itemId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "userId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "orderNo": {
+ "type": "string"
+ },
+ "itemName": {
+ "type": "string"
+ },
+ "itemType": {
+ "$ref": "#/components/schemas/PointExchangeItemType"
+ },
+ "status": {
+ "$ref": "#/components/schemas/PointExchangeOrderStatus"
+ },
+ "pointsCost": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "orderedAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "completedAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "cancelledAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "fulfillmentSnapshot": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updatedAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "tenantId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ },
+ "PointExchangeOrderItem": {
+ "required": [
+ "id",
+ "itemId",
+ "orderNo",
+ "itemName",
+ "itemType",
+ "status",
+ "pointsCost",
+ "orderedAt",
+ "completedAt",
+ "fulfillmentSnapshot",
+ "metadata"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "itemId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "orderNo": {
+ "type": "string"
+ },
+ "itemName": {
+ "type": "string"
+ },
+ "itemType": {
+ "type": "string"
+ },
+ "status": {
+ "type": "string"
+ },
+ "pointsCost": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "orderedAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "completedAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "fulfillmentSnapshot": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ }
+ },
+ "PointExchangeOrderStatus": {
+ "type": "integer"
+ },
+ "PointListOfPointExchangeItemDto": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/PointExchangeItemDto"
+ }
+ }
+ }
+ },
+ "PointListOfPointExchangeOrderItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/PointExchangeOrderItem"
+ }
+ }
+ }
+ },
+ "PointListOfPointTaskItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/PointTaskItem"
+ }
+ }
+ }
+ },
+ "PointSummaryItem": {
+ "required": [
+ "earnedPoints",
+ "spentPoints",
+ "balancePoints"
+ ],
+ "type": "object",
+ "properties": {
+ "earnedPoints": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "spentPoints": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "balancePoints": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ }
+ }
+ },
+ "PointTaskItem": {
+ "required": [
+ "id",
+ "taskKey",
+ "title",
+ "description",
+ "taskType",
+ "status",
+ "points",
+ "maxClaimsPerUser",
+ "claimedCount",
+ "canClaim",
+ "startsAt",
+ "endsAt",
+ "sortOrder",
+ "rules",
+ "metadata"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "taskKey": {
+ "type": "string"
+ },
+ "title": {
+ "type": "string"
+ },
+ "description": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "taskType": {
+ "type": "string"
+ },
+ "status": {
+ "type": "string"
+ },
+ "points": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "maxClaimsPerUser": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "claimedCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "canClaim": {
+ "type": "boolean"
+ },
+ "startsAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "endsAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "sortOrder": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "rules": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ }
+ },
+ "PracticeAccessMode": {
+ "type": "integer"
+ },
+ "PracticeAssemblyType": {
+ "type": "integer"
+ },
+ "PracticeBlueprintCatalogItem": {
+ "required": [
+ "id",
+ "regionId",
+ "entryId",
+ "nodeId",
+ "collectionId",
+ "legacyId",
+ "name",
+ "mode",
+ "assemblyType",
+ "questionLimit",
+ "durationMinutes",
+ "totalScore",
+ "passScore",
+ "sections",
+ "rules",
+ "accessRules",
+ "status",
+ "order"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "regionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "entryId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "nodeId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "collectionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "name": {
+ "type": "string"
+ },
+ "mode": {
+ "$ref": "#/components/schemas/PracticeMode"
+ },
+ "assemblyType": {
+ "$ref": "#/components/schemas/PracticeAssemblyType"
+ },
+ "questionLimit": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "durationMinutes": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "totalScore": {
+ "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
+ "type": [
+ "null",
+ "number",
+ "string"
+ ],
+ "format": "double"
+ },
+ "passScore": {
+ "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
+ "type": [
+ "null",
+ "number",
+ "string"
+ ],
+ "format": "double"
+ },
+ "sections": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "rules": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "accessRules": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "status": {
+ "$ref": "#/components/schemas/ContentStatus"
+ },
+ "order": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ }
+ }
+ },
+ "PracticeBlueprintManagementItem": {
+ "required": [
+ "id",
+ "regionId",
+ "entryId",
+ "nodeId",
+ "collectionId",
+ "legacyId",
+ "name",
+ "mode",
+ "assemblyType",
+ "questionLimit",
+ "durationMinutes",
+ "totalScore",
+ "passScore",
+ "sections",
+ "rules",
+ "accessRules",
+ "status",
+ "order",
+ "createdAt",
+ "updatedAt"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "regionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "entryId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "nodeId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "collectionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "name": {
+ "type": "string"
+ },
+ "mode": {
+ "$ref": "#/components/schemas/PracticeMode"
+ },
+ "assemblyType": {
+ "$ref": "#/components/schemas/PracticeAssemblyType"
+ },
+ "questionLimit": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "durationMinutes": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "totalScore": {
+ "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
+ "type": [
+ "null",
+ "number",
+ "string"
+ ],
+ "format": "double"
+ },
+ "passScore": {
+ "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
+ "type": [
+ "null",
+ "number",
+ "string"
+ ],
+ "format": "double"
+ },
+ "sections": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "rules": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "accessRules": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "status": {
+ "$ref": "#/components/schemas/ContentStatus"
+ },
+ "order": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updatedAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ }
+ }
+ },
+ "PracticeHistoryItem": {
+ "required": [
+ "id",
+ "mode",
+ "targetType",
+ "targetId",
+ "blueprintId",
+ "collectionId",
+ "entryId",
+ "contentNodeId",
+ "questionCount",
+ "answeredCount",
+ "correctCount",
+ "wrongCount",
+ "startedAt",
+ "finishedAt",
+ "expiresAt",
+ "status",
+ "reportId",
+ "score",
+ "reportTotalScore",
+ "accuracy"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "mode": {
+ "type": "string"
+ },
+ "targetType": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "targetId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "blueprintId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "collectionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "entryId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "contentNodeId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "questionCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "answeredCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "correctCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "wrongCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "startedAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "finishedAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "expiresAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "status": {
+ "type": "string"
+ },
+ "reportId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "score": {
+ "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
+ "type": [
+ "null",
+ "number",
+ "string"
+ ],
+ "format": "double"
+ },
+ "reportTotalScore": {
+ "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
+ "type": [
+ "null",
+ "number",
+ "string"
+ ],
+ "format": "double"
+ },
+ "accuracy": {
+ "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
+ "type": [
+ "null",
+ "number",
+ "string"
+ ],
+ "format": "double"
+ }
+ }
+ },
+ "PracticeMode": {
+ "type": "integer"
+ },
+ "PracticeSessionDetailItem": {
+ "required": [
+ "session",
+ "questions",
+ "answersBySessionQuestion"
+ ],
+ "type": "object",
+ "properties": {
+ "session": {
+ "$ref": "#/components/schemas/PracticeSessionItem"
+ },
+ "questions": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/PracticeSessionQuestionItem"
+ }
+ },
+ "answersBySessionQuestion": {
+ "type": "object",
+ "additionalProperties": {
+ "$ref": "#/components/schemas/AnswerRecordItem"
+ }
+ }
+ }
+ },
+ "PracticeSessionItem": {
+ "required": [
+ "id",
+ "mode",
+ "targetType",
+ "targetId",
+ "blueprintId",
+ "collectionId",
+ "entryId",
+ "contentNodeId",
+ "questionCount",
+ "durationMinutes",
+ "totalScore",
+ "accessMode",
+ "accessEntitlementId",
+ "consumedFreeQuota",
+ "accessSnapshot",
+ "startedAt",
+ "finishedAt",
+ "expiresAt",
+ "metadata",
+ "status"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "mode": {
+ "type": "string"
+ },
+ "targetType": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "targetId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "blueprintId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "collectionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "entryId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "contentNodeId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "questionCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "durationMinutes": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "totalScore": {
+ "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
+ "type": [
+ "null",
+ "number",
+ "string"
+ ],
+ "format": "double"
+ },
+ "accessMode": {
+ "$ref": "#/components/schemas/PracticeAccessMode"
+ },
+ "accessEntitlementId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "consumedFreeQuota": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "accessSnapshot": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "startedAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "finishedAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "expiresAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "status": {
+ "type": "string"
+ }
+ }
+ },
+ "PracticeSessionQuestionItem": {
+ "required": [
+ "sessionQuestionId",
+ "questionReferenceId",
+ "locator",
+ "questionId",
+ "type",
+ "typeLabel",
+ "difficulty",
+ "tags",
+ "versionId",
+ "content",
+ "options",
+ "explanation"
+ ],
+ "type": "object",
+ "properties": {
+ "sessionQuestionId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "questionReferenceId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "locator": {
+ "$ref": "#/components/schemas/QuestionLocator"
+ },
+ "questionId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "type": {
+ "type": "string"
+ },
+ "typeLabel": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "difficulty": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "tags": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "versionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "content": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "options": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "explanation": {
+ "type": [
+ "null",
+ "string"
+ ]
+ }
+ }
+ },
+ "PracticeSessionReportItem": {
+ "required": [
+ "id",
+ "practiceSessionId",
+ "blueprintId",
+ "collectionId",
+ "mode",
+ "totalQuestions",
+ "answeredCount",
+ "correctCount",
+ "wrongCount",
+ "unansweredCount",
+ "score",
+ "totalScore",
+ "accuracy",
+ "durationSeconds",
+ "startedAt",
+ "submittedAt",
+ "sectionStats",
+ "questionResults",
+ "wrongQuestionIds",
+ "metadata"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "practiceSessionId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "blueprintId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "collectionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "mode": {
+ "type": "string"
+ },
+ "totalQuestions": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "answeredCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "correctCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "wrongCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "unansweredCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "score": {
+ "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
+ "type": [
+ "number",
+ "string"
+ ],
+ "format": "double"
+ },
+ "totalScore": {
+ "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
+ "type": [
+ "number",
+ "string"
+ ],
+ "format": "double"
+ },
+ "accuracy": {
+ "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
+ "type": [
+ "number",
+ "string"
+ ],
+ "format": "double"
+ },
+ "durationSeconds": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "startedAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "submittedAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "sectionStats": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "questionResults": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "wrongQuestionIds": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ }
+ },
+ "PreviewReconciliationImportDto": {
+ "required": [
+ "provider",
+ "sourceName"
+ ],
+ "type": "object",
+ "properties": {
+ "provider": {
+ "maxLength": 50,
+ "minLength": 0,
+ "type": "string",
+ "description": "服务提供方。"
+ },
+ "billDate": {
+ "type": "string",
+ "description": "账单日期。",
+ "format": "date"
+ },
+ "billType": {
+ "description": "账单类型。",
+ "$ref": "#/components/schemas/ReconciliationBillType"
+ },
+ "sourceName": {
+ "maxLength": 300,
+ "minLength": 0,
+ "type": "string",
+ "description": "来源名称。"
+ },
+ "rows": {
+ "description": "数据行列表。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ },
+ "description": "预览对账导入请求 DTO。"
+ },
+ "PreviewTenantThemeDto": {
+ "required": [
+ "templateCode"
+ ],
+ "type": "object",
+ "properties": {
+ "templateCode": {
+ "type": "string",
+ "description": "模板编码。"
+ },
+ "theme": {
+ "description": "主题配置。",
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "publicAssets": {
+ "description": "公开资源配置。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ },
+ "description": "预览租户主题请求 DTO。"
+ },
+ "ProblemDetails": {
+ "type": "object",
+ "properties": {
+ "type": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "title": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "status": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "detail": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "instance": {
+ "type": [
+ "null",
+ "string"
+ ]
+ }
+ }
+ },
+ "ProductCatalogItem": {
+ "required": [
+ "id",
+ "legacyId",
+ "regionId",
+ "title",
+ "price",
+ "priceLabel",
+ "link",
+ "type",
+ "tags",
+ "cover",
+ "previewIframe",
+ "detailImages",
+ "order",
+ "isActive"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "regionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "title": {
+ "type": "string"
+ },
+ "price": {
+ "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
+ "type": [
+ "null",
+ "number",
+ "string"
+ ],
+ "format": "double"
+ },
+ "priceLabel": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "link": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "type": {
+ "$ref": "#/components/schemas/ProductType"
+ },
+ "tags": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "cover": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "previewIframe": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "detailImages": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "order": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "isActive": {
+ "type": "boolean"
+ }
+ }
+ },
+ "ProductType": {
+ "type": "integer"
+ },
+ "ProfileNotificationItem": {
+ "required": [
+ "id",
+ "notificationType",
+ "status",
+ "severity",
+ "title",
+ "message",
+ "actionLabel",
+ "actionPath",
+ "sourceType",
+ "sourceId",
+ "metadata",
+ "readAt",
+ "createdAt"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "notificationType": {
+ "type": "string"
+ },
+ "status": {
+ "type": "string"
+ },
+ "severity": {
+ "type": "string"
+ },
+ "title": {
+ "type": "string"
+ },
+ "message": {
+ "type": "string"
+ },
+ "actionLabel": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "actionPath": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "sourceType": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "sourceId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "readAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+ },
+ "ProfileNotificationList": {
+ "required": [
+ "items",
+ "summary"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ProfileNotificationItem"
+ }
+ },
+ "summary": {
+ "type": "object",
+ "additionalProperties": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ }
+ }
+ }
+ },
+ "ProfileScoreEventItem": {
+ "required": [
+ "id",
+ "eventType",
+ "points",
+ "balanceAfter",
+ "sourceType",
+ "sourceId",
+ "metadata",
+ "createdAt"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "eventType": {
+ "type": "string"
+ },
+ "points": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "balanceAfter": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "sourceType": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "sourceId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+ },
+ "ProfileScoreEventList": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ProfileScoreEventItem"
+ }
+ }
+ }
+ },
+ "PublicTenantBrandingDto": {
+ "required": [
+ "brandName",
+ "shortName",
+ "slogan",
+ "logoUrl",
+ "faviconUrl",
+ "serviceWechat",
+ "serviceAccountName",
+ "theme",
+ "publicAssets"
+ ],
+ "type": "object",
+ "properties": {
+ "brandName": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "品牌名称。"
+ },
+ "shortName": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "品牌短名称。"
+ },
+ "slogan": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "品牌标语。"
+ },
+ "logoUrl": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "Logo 地址。"
+ },
+ "faviconUrl": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "Favicon 地址。"
+ },
+ "serviceWechat": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "客服微信。"
+ },
+ "serviceAccountName": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "公众号或服务号名称。"
+ },
+ "theme": {
+ "description": "公开主题配置。",
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "publicAssets": {
+ "description": "公开资源配置。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ },
+ "description": "可公开给客户端的租户品牌信息。"
+ },
+ "PublicTenantDto": {
+ "required": [
+ "id",
+ "slug",
+ "name",
+ "status",
+ "mode",
+ "host"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "租户 ID。",
+ "format": "uuid"
+ },
+ "slug": {
+ "type": "string",
+ "description": "租户编码。"
+ },
+ "name": {
+ "type": "string",
+ "description": "租户名称。"
+ },
+ "status": {
+ "description": "租户状态。",
+ "$ref": "#/components/schemas/TenantStatus"
+ },
+ "mode": {
+ "description": "租户模式。",
+ "$ref": "#/components/schemas/TenantMode"
+ },
+ "host": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "当前匹配到的访问域名。"
+ }
+ },
+ "description": "可公开给客户端的租户基础信息。"
+ },
+ "PublishTenantFrontendConfigDto": {
+ "type": "object",
+ "properties": {
+ "expectedVersion": {
+ "maximum": 2147483647,
+ "minimum": 1,
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "description": "期望配置版本。",
+ "format": "int32"
+ }
+ },
+ "description": "发布租户前端配置请求。"
+ },
+ "PublishTenantThemeDto": {
+ "type": "object",
+ "properties": {
+ "useDraft": {
+ "type": [
+ "null",
+ "boolean"
+ ],
+ "description": "是否使用草稿配置。"
+ },
+ "templateCode": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "模板编码。"
+ },
+ "theme": {
+ "description": "主题配置。",
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "publicAssets": {
+ "description": "公开资源配置。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ },
+ "description": "发布租户主题请求 DTO。"
+ },
+ "QuestionActionDto": {
+ "required": [
+ "questionId",
+ "source"
+ ],
+ "type": "object",
+ "properties": {
+ "questionId": {
+ "type": "string",
+ "description": "题目 ID。",
+ "format": "uuid"
+ },
+ "source": {
+ "description": "来源。",
+ "$ref": "#/components/schemas/QuestionSource"
+ },
+ "favorite": {
+ "type": [
+ "null",
+ "boolean"
+ ],
+ "description": "是否收藏。"
+ }
+ },
+ "description": "题目Action请求 DTO。"
+ },
+ "QuestionBankCatalogItem": {
+ "required": [
+ "id",
+ "regionId",
+ "name",
+ "source",
+ "status",
+ "metadata"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "regionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "name": {
+ "type": "string"
+ },
+ "source": {
+ "$ref": "#/components/schemas/QuestionSource"
+ },
+ "status": {
+ "$ref": "#/components/schemas/QuestionBankStatus"
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ }
+ },
+ "QuestionBankStatus": {
+ "type": "integer"
+ },
+ "QuestionCatalogItem": {
+ "required": [
+ "id",
+ "questionBankId",
+ "subjectId",
+ "categoryId",
+ "nodeId",
+ "entryId",
+ "contentNodeId",
+ "primaryCollectionId",
+ "legacyId",
+ "legacySubjectId",
+ "legacyCategoryId",
+ "legacyNodeId",
+ "type",
+ "typeLabel",
+ "difficulty",
+ "tags",
+ "examMarkers",
+ "mediaUrl",
+ "hasVideoExplanation",
+ "status",
+ "versionId",
+ "versionNo",
+ "content",
+ "options",
+ "correctOptionIndex",
+ "correctOptionIndices",
+ "answerText",
+ "explanation",
+ "subQuestions",
+ "codeLang",
+ "codeTemplate",
+ "locator"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "questionBankId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "subjectId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "categoryId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "nodeId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "entryId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "contentNodeId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "primaryCollectionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "legacySubjectId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "legacyCategoryId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "legacyNodeId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "type": {
+ "type": "string"
+ },
+ "typeLabel": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "difficulty": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "tags": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "examMarkers": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "mediaUrl": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "hasVideoExplanation": {
+ "type": "boolean"
+ },
+ "status": {
+ "$ref": "#/components/schemas/QuestionStatus"
+ },
+ "versionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "versionNo": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "content": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "options": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "correctOptionIndex": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "correctOptionIndices": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "answerText": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "explanation": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "subQuestions": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "codeLang": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "codeTemplate": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "locator": {
+ "$ref": "#/components/schemas/QuestionLocator"
+ }
+ }
+ },
+ "QuestionCollectionCatalogItem": {
+ "required": [
+ "id",
+ "regionId",
+ "entryId",
+ "nodeId",
+ "subjectId",
+ "categoryId",
+ "questionBankId",
+ "legacyId",
+ "name",
+ "collectionType",
+ "sourceType",
+ "filters",
+ "questionCount",
+ "totalScore",
+ "durationMinutes",
+ "status",
+ "order",
+ "accessRules",
+ "metadata"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "regionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "entryId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "nodeId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "subjectId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "categoryId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "questionBankId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "name": {
+ "type": "string"
+ },
+ "collectionType": {
+ "$ref": "#/components/schemas/QuestionCollectionType"
+ },
+ "sourceType": {
+ "$ref": "#/components/schemas/QuestionCollectionSourceType"
+ },
+ "filters": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "questionCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "totalScore": {
+ "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
+ "type": [
+ "null",
+ "number",
+ "string"
+ ],
+ "format": "double"
+ },
+ "durationMinutes": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "status": {
+ "$ref": "#/components/schemas/ContentStatus"
+ },
+ "order": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "accessRules": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ }
+ },
+ "QuestionCollectionItemManagementItem": {
+ "required": [
+ "id",
+ "collectionId",
+ "questionId",
+ "locator",
+ "sectionKey",
+ "order",
+ "score",
+ "required",
+ "metadata"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "collectionId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "questionId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "locator": {
+ "$ref": "#/components/schemas/QuestionLocator"
+ },
+ "sectionKey": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "order": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "score": {
+ "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
+ "type": [
+ "null",
+ "number",
+ "string"
+ ],
+ "format": "double"
+ },
+ "required": {
+ "type": "boolean"
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ }
+ },
+ "QuestionCollectionManagementItem": {
+ "required": [
+ "id",
+ "regionId",
+ "entryId",
+ "nodeId",
+ "subjectId",
+ "categoryId",
+ "questionBankId",
+ "legacyId",
+ "name",
+ "collectionType",
+ "sourceType",
+ "filters",
+ "questionCount",
+ "totalScore",
+ "durationMinutes",
+ "status",
+ "order",
+ "accessRules",
+ "metadata",
+ "createdAt",
+ "updatedAt"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "regionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "entryId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "nodeId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "subjectId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "categoryId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "questionBankId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "name": {
+ "type": "string"
+ },
+ "collectionType": {
+ "$ref": "#/components/schemas/QuestionCollectionType"
+ },
+ "sourceType": {
+ "$ref": "#/components/schemas/QuestionCollectionSourceType"
+ },
+ "filters": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "questionCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "totalScore": {
+ "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
+ "type": [
+ "null",
+ "number",
+ "string"
+ ],
+ "format": "double"
+ },
+ "durationMinutes": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "status": {
+ "$ref": "#/components/schemas/ContentStatus"
+ },
+ "order": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "accessRules": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updatedAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ }
+ }
+ },
+ "QuestionCollectionSourceType": {
+ "type": "integer"
+ },
+ "QuestionCollectionType": {
+ "type": "integer"
+ },
+ "QuestionLocator": {
+ "required": [
+ "source",
+ "questionId"
+ ],
+ "type": "object",
+ "properties": {
+ "source": {
+ "$ref": "#/components/schemas/QuestionSource"
+ },
+ "questionId": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ },
+ "QuestionManagementItem": {
+ "required": [
+ "id",
+ "versionId",
+ "questionBankId",
+ "subjectId",
+ "categoryId",
+ "nodeId",
+ "entryId",
+ "contentNodeId",
+ "primaryCollectionId",
+ "legacyId",
+ "type",
+ "typeLabel",
+ "difficulty",
+ "tags",
+ "content",
+ "options",
+ "correctOptionIndex",
+ "correctOptionIndices",
+ "answerText",
+ "explanation",
+ "subQuestions",
+ "codeLang",
+ "codeTemplate",
+ "mediaUrl",
+ "hasVideoExplanation",
+ "status"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "versionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "questionBankId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "subjectId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "categoryId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "nodeId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "entryId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "contentNodeId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "primaryCollectionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "type": {
+ "type": "string"
+ },
+ "typeLabel": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "difficulty": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "tags": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "content": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "options": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "correctOptionIndex": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "correctOptionIndices": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "answerText": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "explanation": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "subQuestions": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "codeLang": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "codeTemplate": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "mediaUrl": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "hasVideoExplanation": {
+ "type": "boolean"
+ },
+ "status": {
+ "$ref": "#/components/schemas/QuestionStatus"
+ }
+ }
+ },
+ "QuestionSource": {
+ "type": "integer"
+ },
+ "QuestionStatus": {
+ "type": "integer"
+ },
+ "QuestionVersionCatalogItem": {
+ "required": [
+ "id",
+ "questionId",
+ "versionNo",
+ "content",
+ "options",
+ "correctOptionIndex",
+ "correctOptionIndices",
+ "answerText",
+ "explanation",
+ "subQuestions",
+ "codeLang",
+ "codeTemplate",
+ "createdAt"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "questionId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "versionNo": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "content": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "options": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "correctOptionIndex": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "correctOptionIndices": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "answerText": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "explanation": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "subQuestions": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "codeLang": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "codeTemplate": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+ },
+ "QuestionVideoCatalogItem": {
+ "required": [
+ "id",
+ "legacyId",
+ "questionId",
+ "videoId",
+ "videoType",
+ "order",
+ "metadata",
+ "video"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "questionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "videoId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "videoType": {
+ "$ref": "#/components/schemas/QuestionVideoType"
+ },
+ "order": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "video": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "$ref": "#/components/schemas/VideoExplanationCatalogItem"
+ }
+ ]
+ }
+ }
+ },
+ "QuestionVideoManagementItem": {
+ "required": [
+ "id",
+ "questionId",
+ "videoId",
+ "legacyId",
+ "videoType",
+ "order",
+ "metadata"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "questionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "videoId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "videoType": {
+ "$ref": "#/components/schemas/QuestionVideoType"
+ },
+ "order": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ }
+ },
+ "QuestionVideoQueryDto": {
+ "type": "object",
+ "properties": {
+ "questionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "题目 ID。",
+ "format": "uuid"
+ },
+ "questionIds": {
+ "maxItems": 100,
+ "type": [
+ "null",
+ "array"
+ ],
+ "items": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "description": "题目 ID 列表。"
+ },
+ "limit": {
+ "maximum": 500,
+ "minimum": 1,
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "description": "返回数量上限。",
+ "format": "int32"
+ }
+ },
+ "description": "题目视频查询参数。"
+ },
+ "QuestionVideoType": {
+ "type": "integer"
+ },
+ "RecentPracticeItem": {
+ "required": [
+ "id",
+ "practiceType",
+ "targetName",
+ "progress",
+ "lastAccessAt",
+ "lastPracticeAt"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "practiceType": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "targetName": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "progress": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "lastAccessAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "lastPracticeAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ }
+ }
+ },
+ "ReconciliationBatchStatus": {
+ "type": "integer"
+ },
+ "ReconciliationBillType": {
+ "type": "integer"
+ },
+ "ReconciliationImportPreview": {
+ "required": [
+ "totalCount",
+ "paymentCount",
+ "refundCount",
+ "invalidCount",
+ "amountCents",
+ "refundAmountCents",
+ "sourceHash"
+ ],
+ "type": "object",
+ "properties": {
+ "totalCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "paymentCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "refundCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "invalidCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "amountCents": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "refundAmountCents": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "sourceHash": {
+ "type": "string"
+ }
+ }
+ },
+ "ReconciliationIssueMatchStatus": {
+ "type": "integer"
+ },
+ "ReconciliationIssueStatus": {
+ "type": "integer"
+ },
+ "ReconciliationMatchStatus": {
+ "type": "integer"
+ },
+ "ReconciliationResolutionType": {
+ "type": "integer"
+ },
+ "ReconciliationSource": {
+ "type": "integer"
+ },
+ "ReconciliationTransactionType": {
+ "type": "integer"
+ },
+ "RedeemActivationCodeDto": {
+ "required": [
+ "code",
+ "userId"
+ ],
+ "type": "object",
+ "properties": {
+ "code": {
+ "maxLength": 100,
+ "minLength": 0,
+ "type": "string",
+ "description": "编码。"
+ },
+ "userId": {
+ "type": "string",
+ "description": "用户 ID。",
+ "format": "uuid"
+ },
+ "regionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "地区 ID。",
+ "format": "uuid"
+ }
+ },
+ "description": "核销激活码编码请求 DTO。"
+ },
+ "ReferralAssignmentMode": {
+ "type": "integer"
+ },
+ "ReferralBindResult": {
+ "required": [
+ "lead",
+ "crmQueue"
+ ],
+ "type": "object",
+ "properties": {
+ "lead": {
+ "$ref": "#/components/schemas/ReferralLeadItem"
+ },
+ "crmQueue": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "$ref": "#/components/schemas/CrmQueuePreviewItem"
+ }
+ ]
+ }
+ }
+ },
+ "ReferralConversionReport": {
+ "required": [
+ "startDate",
+ "endDate",
+ "leadCount",
+ "paidLeadCount",
+ "paidAmountCents",
+ "conversionRate",
+ "topReferrers",
+ "recentUnconvertedLeads"
+ ],
+ "type": "object",
+ "properties": {
+ "startDate": {
+ "type": "string",
+ "format": "date"
+ },
+ "endDate": {
+ "type": "string",
+ "format": "date"
+ },
+ "leadCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "paidLeadCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "paidAmountCents": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "conversionRate": {
+ "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
+ "type": [
+ "number",
+ "string"
+ ],
+ "format": "double"
+ },
+ "topReferrers": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ReferralStatsItem"
+ }
+ },
+ "recentUnconvertedLeads": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ReferralLeadItem"
+ }
+ }
+ }
+ },
+ "ReferralInviteDto": {
+ "type": "object",
+ "properties": {
+ "channel": {
+ "maxLength": 100,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "渠道。"
+ },
+ "landingPath": {
+ "maxLength": 2048,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "落地页路径。"
+ }
+ },
+ "description": "推荐邀请码请求 DTO。"
+ },
+ "ReferralInviteItem": {
+ "required": [
+ "inviteCode"
+ ],
+ "type": "object",
+ "properties": {
+ "inviteCode": {
+ "type": "string"
+ }
+ }
+ },
+ "ReferralLeadItem": {
+ "required": [
+ "id",
+ "studentUserId",
+ "referrerUserId",
+ "refCode",
+ "status",
+ "boundAt",
+ "changed"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "studentUserId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "referrerUserId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "refCode": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "status": {
+ "type": "string"
+ },
+ "boundAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "changed": {
+ "type": "boolean"
+ }
+ }
+ },
+ "ReferralListOfReferralLeadItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ReferralLeadItem"
+ }
+ }
+ }
+ },
+ "ReferralListOfReferralStatsItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ReferralStatsItem"
+ }
+ }
+ }
+ },
+ "ReferralListOfReferralTeamItem": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ReferralTeamItem"
+ }
+ }
+ }
+ },
+ "ReferralQrcodeDto": {
+ "type": "object",
+ "properties": {
+ "page": {
+ "maxLength": 500,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "页码。"
+ },
+ "scene": {
+ "maxLength": 128,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "场景参数。"
+ },
+ "provider": {
+ "maxLength": 100,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "服务提供方。"
+ },
+ "qrcodeUrl": {
+ "maxLength": 2048,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "二维码地址。"
+ },
+ "metadata": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "description": "扩展元数据。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ ]
+ }
+ },
+ "description": "推荐二维码请求 DTO。"
+ },
+ "ReferralQrcodeItem": {
+ "required": [
+ "id",
+ "refCode",
+ "scene",
+ "page",
+ "provider",
+ "qrcodeUrl",
+ "status",
+ "metadata"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "refCode": {
+ "type": "string"
+ },
+ "scene": {
+ "type": "string"
+ },
+ "page": {
+ "type": "string"
+ },
+ "provider": {
+ "type": "string"
+ },
+ "qrcodeUrl": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "status": {
+ "type": "string"
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ }
+ },
+ "ReferralResolutionItem": {
+ "required": [
+ "valid",
+ "inviterId",
+ "inviteCode",
+ "role",
+ "name"
+ ],
+ "type": "object",
+ "properties": {
+ "valid": {
+ "type": "boolean"
+ },
+ "inviterId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "inviteCode": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "role": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "name": {
+ "type": [
+ "null",
+ "string"
+ ]
+ }
+ }
+ },
+ "ReferralStatsItem": {
+ "required": [
+ "referrerUserId",
+ "name",
+ "role",
+ "inviteCode",
+ "leadCount",
+ "paidLeadCount",
+ "paidAmountCents",
+ "trackCount",
+ "conversionRate"
+ ],
+ "type": "object",
+ "properties": {
+ "referrerUserId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "name": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "role": {
+ "type": "string"
+ },
+ "inviteCode": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "leadCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "paidLeadCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "paidAmountCents": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "trackCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "conversionRate": {
+ "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
+ "type": [
+ "number",
+ "string"
+ ],
+ "format": "double"
+ }
+ }
+ },
+ "ReferralTeamItem": {
+ "required": [
+ "id",
+ "memberUserId",
+ "leaderUserId",
+ "relationType",
+ "status",
+ "metadata"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "memberUserId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "leaderUserId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "relationType": {
+ "type": "string"
+ },
+ "status": {
+ "type": "string"
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ }
+ },
+ "ReferralTrackItem": {
+ "required": [
+ "id",
+ "eventType",
+ "refCode",
+ "referrerUserId",
+ "targetUserId",
+ "source",
+ "createdAt"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "eventType": {
+ "type": "string"
+ },
+ "refCode": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "referrerUserId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "targetUserId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "source": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+ },
+ "ReferralTrackResult": {
+ "required": [
+ "item",
+ "lead",
+ "crmQueue"
+ ],
+ "type": "object",
+ "properties": {
+ "item": {
+ "$ref": "#/components/schemas/ReferralTrackItem"
+ },
+ "lead": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "$ref": "#/components/schemas/ReferralLeadItem"
+ }
+ ]
+ },
+ "crmQueue": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "$ref": "#/components/schemas/CrmQueuePreviewItem"
+ }
+ ]
+ }
+ }
+ },
+ "RefreshSessionDto": {
+ "required": [
+ "refreshToken"
+ ],
+ "type": "object",
+ "properties": {
+ "refreshToken": {
+ "maxLength": 2048,
+ "minLength": 0,
+ "type": "string",
+ "description": "刷新令牌。"
+ }
+ },
+ "description": "刷新会话请求 DTO。"
+ },
+ "RefundEntitlementAction": {
+ "type": "integer"
+ },
+ "RefundNotificationDto": {
+ "required": [
+ "refundNo"
+ ],
+ "type": "object",
+ "properties": {
+ "refundNo": {
+ "maxLength": 100,
+ "minLength": 0,
+ "type": "string",
+ "description": "退款单号。"
+ },
+ "providerRefundNo": {
+ "maxLength": 200,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "渠道退款单号。"
+ },
+ "status": {
+ "description": "状态。",
+ "$ref": "#/components/schemas/CommerceRefundStatus"
+ },
+ "eventId": {
+ "maxLength": 200,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "事件 ID。"
+ },
+ "payload": {
+ "description": "任务载荷。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ },
+ "description": "退款通知请求 DTO。"
+ },
+ "RegionCatalogItem": {
+ "required": [
+ "id",
+ "legacyId",
+ "name",
+ "code",
+ "shortName",
+ "fullName",
+ "icon",
+ "pinyin",
+ "order",
+ "isHot"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "name": {
+ "type": "string"
+ },
+ "code": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "shortName": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "fullName": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "icon": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "pinyin": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "order": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "isHot": {
+ "type": "boolean"
+ }
+ }
+ },
+ "RegionModuleCatalogItem": {
+ "required": [
+ "id",
+ "legacyId",
+ "regionId",
+ "name",
+ "type",
+ "icon",
+ "color",
+ "textColor",
+ "description",
+ "route",
+ "order",
+ "isPrimarySchoolModule"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "regionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "name": {
+ "type": "string"
+ },
+ "type": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "icon": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "color": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "textColor": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "description": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "route": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "order": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "isPrimarySchoolModule": {
+ "type": "boolean"
+ }
+ }
+ },
+ "RemoveTenantAdminClassMemberDto": {
+ "required": [
+ "classMemberId"
+ ],
+ "type": "object",
+ "properties": {
+ "classMemberId": {
+ "type": "string",
+ "description": "班级成员 ID。",
+ "format": "uuid"
+ }
+ },
+ "description": "移除租户管理端班级成员请求 DTO。"
+ },
+ "ReplaceCollectionItemsDto": {
+ "required": [
+ "collectionId"
+ ],
+ "type": "object",
+ "properties": {
+ "collectionId": {
+ "type": "string",
+ "description": "题集 ID。",
+ "format": "uuid"
+ },
+ "questions": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/CollectionQuestionDto"
+ },
+ "description": "题目列表。"
+ }
+ },
+ "description": "替换题集Items请求 DTO。"
+ },
+ "ReplaceRoleBindingsDto": {
+ "type": "object",
+ "properties": {
+ "permissionCodes": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "description": "权限编码列表。"
+ },
+ "menuCodes": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "description": "菜单编码列表。"
+ }
+ },
+ "description": "替换角色权限绑定请求。"
+ },
+ "ReplaceUserRolesDto": {
+ "type": "object",
+ "properties": {
+ "roleIds": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "description": "角色 ID 列表。"
+ }
+ },
+ "description": "替换用户角色请求。"
+ },
+ "ReportPriority": {
+ "type": "integer"
+ },
+ "ReportStatus": {
+ "type": "integer"
+ },
+ "ReportType": {
+ "type": "integer"
+ },
+ "RequestProviderBillJobDto": {
+ "required": [
+ "provider"
+ ],
+ "type": "object",
+ "properties": {
+ "provider": {
+ "maxLength": 50,
+ "minLength": 0,
+ "type": "string",
+ "description": "服务提供方。"
+ },
+ "billDate": {
+ "type": "string",
+ "description": "账单日期。",
+ "format": "date"
+ },
+ "billType": {
+ "description": "账单类型。",
+ "$ref": "#/components/schemas/ReconciliationBillType"
+ },
+ "runAfter": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "计划运行时间。",
+ "format": "date-time"
+ }
+ },
+ "description": "RequestProviderBill任务请求 DTO。"
+ },
+ "RequiredPasswordChangeDto": {
+ "required": [
+ "challengeToken",
+ "newPassword"
+ ],
+ "type": "object",
+ "properties": {
+ "challengeToken": {
+ "maxLength": 2048,
+ "minLength": 0,
+ "type": "string",
+ "description": "挑战令牌。"
+ },
+ "newPassword": {
+ "maxLength": 128,
+ "minLength": 8,
+ "type": "string",
+ "description": "新密码。"
+ }
+ },
+ "description": "首次登录必改密码请求。"
+ },
+ "ResolveReferralDto": {
+ "type": "object",
+ "properties": {
+ "code": {
+ "maxLength": 100,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "编码。"
+ },
+ "tenantCode": {
+ "maxLength": 100,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "租户编码。"
+ }
+ },
+ "description": "解析推荐请求 DTO。"
+ },
+ "RetryPlatformBillingDunningEventDto": {
+ "required": [
+ "eventId"
+ ],
+ "type": "object",
+ "properties": {
+ "eventId": {
+ "type": "string",
+ "description": "事件 ID。",
+ "format": "uuid"
+ },
+ "reason": {
+ "maxLength": 1000,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "原因。"
+ }
+ },
+ "description": "重试平台Dunning事件请求 DTO。"
+ },
+ "RetryPlatformCrmLeadDto": {
+ "required": [
+ "queueId"
+ ],
+ "type": "object",
+ "properties": {
+ "queueId": {
+ "type": "string",
+ "description": "队列任务 ID。",
+ "format": "uuid"
+ },
+ "note": {
+ "maxLength": 500,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "备注。"
+ }
+ },
+ "description": "重试租户 CRM 线索推送请求。"
+ },
+ "SaasCatalogSnapshot": {
+ "required": [
+ "features",
+ "limitDefinitions",
+ "offerings",
+ "versions"
+ ],
+ "type": "object",
+ "properties": {
+ "features": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/SaasFeature"
+ }
+ },
+ "limitDefinitions": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/SaasFeatureLimitDefinition"
+ }
+ },
+ "offerings": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/SaasOffering"
+ }
+ },
+ "versions": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/SaasOfferingVersionItem"
+ }
+ }
+ }
+ },
+ "SaasFeature": {
+ "type": "object",
+ "properties": {
+ "code": {
+ "type": "string"
+ },
+ "name": {
+ "type": "string"
+ },
+ "category": {
+ "type": "string"
+ },
+ "description": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "referencePriceCents": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "currency": {
+ "type": "string"
+ },
+ "status": {
+ "$ref": "#/components/schemas/SaasFeatureStatus"
+ },
+ "isCore": {
+ "type": "boolean"
+ },
+ "sortOrder": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updatedAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ },
+ "SaasFeatureLimitDefinition": {
+ "type": "object",
+ "properties": {
+ "metricCode": {
+ "type": "string"
+ },
+ "featureCode": {
+ "type": "string"
+ },
+ "name": {
+ "type": "string"
+ },
+ "unit": {
+ "type": "string"
+ },
+ "kind": {
+ "$ref": "#/components/schemas/SaasFeatureLimitKind"
+ },
+ "warningPercent": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "isHardLimit": {
+ "type": "boolean"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updatedAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ },
+ "SaasFeatureLimitKind": {
+ "type": "integer"
+ },
+ "SaasFeatureStatus": {
+ "type": "integer"
+ },
+ "SaasOffering": {
+ "type": "object",
+ "properties": {
+ "code": {
+ "type": "string"
+ },
+ "name": {
+ "type": "string"
+ },
+ "type": {
+ "$ref": "#/components/schemas/SaasOfferingType"
+ },
+ "status": {
+ "$ref": "#/components/schemas/SaasOfferingStatus"
+ },
+ "description": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "sortOrder": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updatedAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ },
+ "SaasOfferingStatus": {
+ "type": "integer"
+ },
+ "SaasOfferingType": {
+ "type": "integer"
+ },
+ "SaasOfferingVersionItem": {
+ "required": [
+ "id",
+ "offeringId",
+ "offeringCode",
+ "offeringName",
+ "offeringType",
+ "version",
+ "status",
+ "billingCycle",
+ "originalAmountCents",
+ "amountCents",
+ "currency",
+ "effectiveAt",
+ "publishedAt",
+ "featureCodes",
+ "limits"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "offeringId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "offeringCode": {
+ "type": "string"
+ },
+ "offeringName": {
+ "type": "string"
+ },
+ "offeringType": {
+ "$ref": "#/components/schemas/SaasOfferingType"
+ },
+ "version": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "status": {
+ "$ref": "#/components/schemas/SaasOfferingVersionStatus"
+ },
+ "billingCycle": {
+ "$ref": "#/components/schemas/PlatformBillingCycle"
+ },
+ "originalAmountCents": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "amountCents": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "currency": {
+ "type": "string"
+ },
+ "effectiveAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "publishedAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "featureCodes": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "limits": {
+ "type": "object",
+ "additionalProperties": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int64"
+ }
+ }
+ }
+ },
+ "SaasOfferingVersionStatus": {
+ "type": "integer"
+ },
+ "SaveTenantFrontendConfigDraftDto": {
+ "type": "object",
+ "properties": {
+ "branding": {
+ "description": "品牌配置。",
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "theme": {
+ "description": "主题配置。",
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "features": {
+ "description": "功能配置。",
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "navigation": {
+ "description": "导航配置。",
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "homeModules": {
+ "description": "首页模块配置。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ },
+ "description": "保存租户前端配置草稿请求。"
+ },
+ "School": {
+ "type": "object",
+ "properties": {
+ "regionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "moduleId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "name": {
+ "type": "string"
+ },
+ "professionalExamDate": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updatedAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "tenantId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ },
+ "SchoolCatalogItem": {
+ "required": [
+ "id",
+ "legacyId",
+ "regionId",
+ "moduleId",
+ "name",
+ "professionalExamDate",
+ "metadata"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "regionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "moduleId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "name": {
+ "type": "string"
+ },
+ "professionalExamDate": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ }
+ },
+ "ScorelineField": {
+ "type": "object",
+ "properties": {
+ "regionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "fieldKey": {
+ "type": "string"
+ },
+ "fieldName": {
+ "type": "string"
+ },
+ "fieldType": {
+ "type": "string"
+ },
+ "unit": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "isFilter": {
+ "type": "boolean"
+ },
+ "isRequired": {
+ "type": "boolean"
+ },
+ "isVisible": {
+ "type": "boolean"
+ },
+ "isTrend": {
+ "type": "boolean"
+ },
+ "options": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "placeholder": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "description": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "sortOrder": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updatedAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "tenantId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ },
+ "ScorelineFieldItem": {
+ "required": [
+ "id",
+ "legacyId",
+ "regionId",
+ "fieldKey",
+ "fieldName",
+ "fieldType",
+ "unit",
+ "isFilter",
+ "isRequired",
+ "isVisible",
+ "isTrend",
+ "options",
+ "placeholder",
+ "description",
+ "sortOrder"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "regionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "fieldKey": {
+ "type": "string"
+ },
+ "fieldName": {
+ "type": "string"
+ },
+ "fieldType": {
+ "type": "string"
+ },
+ "unit": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "isFilter": {
+ "type": "boolean"
+ },
+ "isRequired": {
+ "type": "boolean"
+ },
+ "isVisible": {
+ "type": "boolean"
+ },
+ "isTrend": {
+ "type": "boolean"
+ },
+ "options": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "placeholder": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "description": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "sortOrder": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ }
+ }
+ },
+ "ScorelineRecord": {
+ "type": "object",
+ "properties": {
+ "regionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "schoolId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "majorId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "year": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "schoolName": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "majorName": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "fieldValues": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updatedAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "tenantId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ },
+ "ScorelineRecordCursorPage": {
+ "required": [
+ "pageSize",
+ "hasMore",
+ "nextCursor",
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "pageSize": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "hasMore": {
+ "type": "boolean"
+ },
+ "nextCursor": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ScorelineRecordItem"
+ }
+ }
+ }
+ },
+ "ScorelineRecordItem": {
+ "required": [
+ "id",
+ "legacyId",
+ "regionId",
+ "schoolId",
+ "majorId",
+ "year",
+ "schoolName",
+ "majorName",
+ "fieldValues"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "regionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "schoolId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "majorId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "year": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "schoolName": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "majorName": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "fieldValues": {
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ }
+ },
+ "ScorelineRecordPage": {
+ "required": [
+ "page",
+ "pageSize",
+ "total",
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "page": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "pageSize": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "total": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ScorelineRecordItem"
+ }
+ }
+ }
+ },
+ "ScorelineTrendItem": {
+ "required": [
+ "year",
+ "schoolCount",
+ "majorCount"
+ ],
+ "type": "object",
+ "properties": {
+ "year": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "schoolCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "majorCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ }
+ }
+ },
+ "SendSmsCodeDto": {
+ "required": [
+ "realm",
+ "phone"
+ ],
+ "type": "object",
+ "properties": {
+ "realm": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "description": "认证域。",
+ "$ref": "#/components/schemas/AuthRealm"
+ }
+ ]
+ },
+ "tenantCode": {
+ "maxLength": 100,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "租户编码。"
+ },
+ "phone": {
+ "maxLength": 32,
+ "minLength": 0,
+ "type": "string",
+ "description": "手机号。"
+ },
+ "deviceId": {
+ "maxLength": 256,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "设备 ID。"
+ }
+ },
+ "description": "发送短信验证码请求。"
+ },
+ "SignedStorageUrlDto": {
+ "required": [
+ "provider",
+ "bucket",
+ "objectKey",
+ "method",
+ "url",
+ "headers",
+ "expiresAt",
+ "expiresInSeconds",
+ "signatureMode"
+ ],
+ "type": "object",
+ "properties": {
+ "provider": {
+ "type": "string"
+ },
+ "bucket": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "objectKey": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "method": {
+ "type": "string"
+ },
+ "url": {
+ "type": "string"
+ },
+ "headers": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ }
+ },
+ "expiresAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "expiresInSeconds": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "signatureMode": {
+ "type": "string"
+ }
+ },
+ "description": "SignedStorageUrl请求 DTO。"
+ },
+ "SimpleImportResult": {
+ "required": [
+ "job",
+ "items",
+ "issues"
+ ],
+ "type": "object",
+ "properties": {
+ "job": {
+ "$ref": "#/components/schemas/ContentImportJobItem"
+ },
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ContentImportItemModel"
+ }
+ },
+ "issues": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ContentImportIssueModel"
+ }
+ }
+ }
+ },
+ "SmsLoginDto": {
+ "required": [
+ "realm",
+ "phone",
+ "code"
+ ],
+ "type": "object",
+ "properties": {
+ "realm": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "description": "认证域。",
+ "$ref": "#/components/schemas/AuthRealm"
+ }
+ ]
+ },
+ "tenantCode": {
+ "maxLength": 100,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "租户编码。"
+ },
+ "phone": {
+ "maxLength": 32,
+ "minLength": 0,
+ "type": "string",
+ "description": "手机号。"
+ },
+ "code": {
+ "maxLength": 12,
+ "minLength": 4,
+ "type": "string",
+ "description": "编码。"
+ }
+ },
+ "description": "SmsLogin请求 DTO。"
+ },
+ "SmsSendLog": {
+ "type": "object",
+ "properties": {
+ "tenantId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "channelId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "templateId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "provider": {
+ "type": "string"
+ },
+ "scene": {
+ "type": "string"
+ },
+ "phoneMasked": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "status": {
+ "$ref": "#/components/schemas/SmsSendLogStatus"
+ },
+ "providerMessageId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "errorCode": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "errorMessage": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "sentAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ },
+ "SmsSendLogStatus": {
+ "type": "integer"
+ },
+ "SmsSendResult": {
+ "required": [
+ "verificationId",
+ "expiresAt"
+ ],
+ "type": "object",
+ "properties": {
+ "verificationId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "expiresAt": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+ },
+ "SmsTemplateAuditStatus": {
+ "type": "integer"
+ },
+ "SmsTemplateStatus": {
+ "type": "integer"
+ },
+ "SmsTemplateType": {
+ "type": "integer"
+ },
+ "StudentFollowupPriority": {
+ "type": "integer"
+ },
+ "StudentFollowupStatus": {
+ "type": "integer"
+ },
+ "StudentFollowupType": {
+ "type": "integer"
+ },
+ "StudentMembershipItem": {
+ "required": [
+ "isSvip",
+ "expiresAt"
+ ],
+ "type": "object",
+ "properties": {
+ "isSvip": {
+ "type": "boolean"
+ },
+ "expiresAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ }
+ }
+ },
+ "StudentNoteType": {
+ "type": "integer"
+ },
+ "StudentNoteVisibility": {
+ "type": "integer"
+ },
+ "StudentProfileItem": {
+ "required": [
+ "profileId",
+ "userId",
+ "username",
+ "phone",
+ "email",
+ "name",
+ "avatarPreset",
+ "avatarDisplayUrl",
+ "primaryRole",
+ "score",
+ "regionId",
+ "regionName",
+ "selectedSchoolId",
+ "selectedSchoolName",
+ "selectedMajorId",
+ "selectedMajorName",
+ "questionsAnsweredToday",
+ "masteredWordsCount",
+ "lastCheckInDate",
+ "stats",
+ "progress",
+ "moduleSelections",
+ "recentActivities",
+ "recentPractices",
+ "membership"
+ ],
+ "type": "object",
+ "properties": {
+ "profileId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "userId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "username": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "phone": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "email": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "name": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "avatarPreset": {
+ "type": "string"
+ },
+ "avatarDisplayUrl": {
+ "type": "string"
+ },
+ "primaryRole": {
+ "type": "string"
+ },
+ "score": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "regionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "regionName": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "selectedSchoolId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "selectedSchoolName": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "selectedMajorId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "selectedMajorName": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "questionsAnsweredToday": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "masteredWordsCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "lastCheckInDate": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date"
+ },
+ "stats": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "progress": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "moduleSelections": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "recentActivities": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "recentPractices": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/RecentPracticeItem"
+ }
+ },
+ "membership": {
+ "$ref": "#/components/schemas/StudentMembershipItem"
+ }
+ }
+ },
+ "SubjectCatalogItem": {
+ "required": [
+ "id",
+ "legacyId",
+ "regionId",
+ "moduleId",
+ "schoolId",
+ "majorId",
+ "nodeId",
+ "name",
+ "type",
+ "icon",
+ "description",
+ "stats",
+ "order"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "regionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "moduleId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "schoolId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "majorId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "nodeId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "name": {
+ "type": "string"
+ },
+ "type": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "$ref": "#/components/schemas/SubjectType"
+ }
+ ]
+ },
+ "icon": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "description": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "stats": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "order": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ }
+ }
+ },
+ "SubjectType": {
+ "type": "integer"
+ },
+ "SubmitAnswerDto": {
+ "required": [
+ "sessionQuestionId"
+ ],
+ "type": "object",
+ "properties": {
+ "sessionQuestionId": {
+ "type": "string",
+ "description": "会话题目 ID。",
+ "format": "uuid"
+ },
+ "selectedOptions": {
+ "type": [
+ "null",
+ "array"
+ ],
+ "items": {
+ "type": "string"
+ },
+ "description": "已选选项。"
+ },
+ "answerText": {
+ "maxLength": 10000,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "文字答案。"
+ },
+ "selfJudgedCorrect": {
+ "type": [
+ "null",
+ "boolean"
+ ],
+ "description": "主观题自评是否正确。"
+ }
+ },
+ "description": "提交答案请求 DTO。"
+ },
+ "SubmitFeedbackDto": {
+ "required": [
+ "description"
+ ],
+ "type": "object",
+ "properties": {
+ "questionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "题目 ID。",
+ "format": "uuid"
+ },
+ "type": {
+ "maxLength": 50,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "类型。"
+ },
+ "category": {
+ "maxLength": 100,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "分类。"
+ },
+ "title": {
+ "maxLength": 200,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "标题。"
+ },
+ "description": {
+ "maxLength": 5000,
+ "minLength": 0,
+ "type": "string",
+ "description": "说明。"
+ },
+ "priority": {
+ "maxLength": 32,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "优先级。"
+ },
+ "contact": {
+ "maxLength": 200,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "联系方式。"
+ },
+ "attachments": {
+ "description": "附件列表。",
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "metadata": {
+ "description": "扩展元数据。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ },
+ "description": "提交反馈请求 DTO。"
+ },
+ "SubmitPracticeSessionDto": {
+ "required": [
+ "practiceSessionId"
+ ],
+ "type": "object",
+ "properties": {
+ "practiceSessionId": {
+ "type": "string",
+ "description": "练习会话 ID。",
+ "format": "uuid"
+ }
+ },
+ "description": "提交练习会话请求 DTO。"
+ },
+ "SvipPlanCatalogItem": {
+ "required": [
+ "id",
+ "legacyId",
+ "regionId",
+ "name",
+ "priceCents",
+ "price",
+ "originalPriceCents",
+ "originalPrice",
+ "days",
+ "description",
+ "perDayLabel",
+ "badge",
+ "recommended",
+ "couponOnly",
+ "vpProductId",
+ "vpEnabled",
+ "order",
+ "isActive"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "regionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "name": {
+ "type": "string"
+ },
+ "priceCents": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "price": {
+ "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
+ "type": [
+ "number",
+ "string"
+ ],
+ "format": "double"
+ },
+ "originalPriceCents": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "originalPrice": {
+ "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
+ "type": [
+ "null",
+ "number",
+ "string"
+ ],
+ "format": "double"
+ },
+ "days": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "description": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "perDayLabel": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "badge": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "recommended": {
+ "type": "boolean"
+ },
+ "couponOnly": {
+ "type": "boolean"
+ },
+ "vpProductId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "vpEnabled": {
+ "type": "boolean"
+ },
+ "order": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "isActive": {
+ "type": "boolean"
+ }
+ }
+ },
+ "TaxonomyNodeItem": {
+ "required": [
+ "id",
+ "source",
+ "parentId",
+ "parentSource",
+ "nodeType",
+ "code",
+ "name",
+ "path",
+ "depth",
+ "sortOrder",
+ "metadata"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "source": {
+ "$ref": "#/components/schemas/QuestionSource"
+ },
+ "parentId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "parentSource": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "$ref": "#/components/schemas/QuestionSource"
+ }
+ ]
+ },
+ "nodeType": {
+ "$ref": "#/components/schemas/TaxonomyNodeType"
+ },
+ "code": {
+ "type": "string"
+ },
+ "name": {
+ "type": "string"
+ },
+ "path": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "depth": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "sortOrder": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ }
+ },
+ "TaxonomyNodeType": {
+ "type": "integer"
+ },
+ "TenantAdjustmentReport": {
+ "required": [
+ "draftCount",
+ "pendingReviewCount",
+ "approvedCount",
+ "closedCount",
+ "increaseRevenueCents",
+ "decreaseRevenueCents"
+ ],
+ "type": "object",
+ "properties": {
+ "draftCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "pendingReviewCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "approvedCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "closedCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "increaseRevenueCents": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "decreaseRevenueCents": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ }
+ }
+ },
+ "TenantAdjustmentVoucherEventList": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/CommerceAdjustmentVoucherEvent"
+ }
+ }
+ }
+ },
+ "TenantAdjustmentVoucherList": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/CommerceAdjustmentVoucher"
+ }
+ }
+ }
+ },
+ "TenantAdminAuditLogItem": {
+ "required": [
+ "id",
+ "actorUserId",
+ "action",
+ "targetType",
+ "targetId",
+ "details",
+ "ipAddress",
+ "userAgent",
+ "actorName",
+ "actorPhone",
+ "createdAt"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "actorUserId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "action": {
+ "type": "string"
+ },
+ "targetType": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "targetId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "details": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "ipAddress": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "userAgent": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "actorName": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "actorPhone": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+ },
+ "TenantAdminBadgeGrantItem": {
+ "required": [
+ "id",
+ "legacyId",
+ "userId",
+ "userName",
+ "userPhone",
+ "badgeId",
+ "badgeName",
+ "badgeCategory",
+ "iconUrl",
+ "level",
+ "grantedBy",
+ "grantedByName",
+ "note",
+ "grantedAt",
+ "createdAt",
+ "updatedAt"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "userId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "userName": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "userPhone": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "badgeId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "badgeName": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "badgeCategory": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "iconUrl": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "level": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "grantedBy": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "grantedByName": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "note": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "grantedAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updatedAt": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+ },
+ "TenantAdminBadgeItem": {
+ "required": [
+ "id",
+ "legacyId",
+ "name",
+ "description",
+ "category",
+ "iconUrl",
+ "level",
+ "unlockType",
+ "conditionField",
+ "conditionOperator",
+ "conditionValue",
+ "conditionExtra",
+ "order",
+ "isActive",
+ "createdAt",
+ "updatedAt"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "name": {
+ "type": "string"
+ },
+ "description": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "category": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "iconUrl": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "level": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "unlockType": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "conditionField": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "conditionOperator": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "conditionValue": {
+ "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
+ "type": [
+ "null",
+ "number",
+ "string"
+ ],
+ "format": "double"
+ },
+ "conditionExtra": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "order": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "isActive": {
+ "type": "boolean"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updatedAt": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+ },
+ "TenantAdminBulkAssignClassDto": {
+ "required": [
+ "classId",
+ "userIds"
+ ],
+ "type": "object",
+ "properties": {
+ "classId": {
+ "type": "string",
+ "description": "班级 ID。",
+ "format": "uuid"
+ },
+ "userIds": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "description": "用户 ID 列表。"
+ }
+ },
+ "description": "租户管理端批量分配班级请求 DTO。"
+ },
+ "TenantAdminBulkOperationResult": {
+ "required": [
+ "requestedCount",
+ "succeededCount",
+ "failedCount",
+ "failedUserIds"
+ ],
+ "type": "object",
+ "properties": {
+ "requestedCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "succeededCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "failedCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "failedUserIds": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ }
+ },
+ "TenantAdminBulkStatusDto": {
+ "required": [
+ "userIds"
+ ],
+ "type": "object",
+ "properties": {
+ "userIds": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "description": "用户 ID 列表。"
+ },
+ "status": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "状态。"
+ },
+ "reason": {
+ "maxLength": 1000,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "原因。"
+ }
+ },
+ "description": "租户管理端批量状态请求 DTO。"
+ },
+ "TenantAdminClassItem": {
+ "required": [
+ "id",
+ "regionId",
+ "regionName",
+ "legacyId",
+ "code",
+ "name",
+ "description",
+ "status",
+ "order",
+ "metadata",
+ "studentCount",
+ "staffCount",
+ "createdAt",
+ "updatedAt"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "regionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "regionName": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "code": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "name": {
+ "type": "string"
+ },
+ "description": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "status": {
+ "$ref": "#/components/schemas/TenantRecordStatus"
+ },
+ "order": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "studentCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "staffCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updatedAt": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+ },
+ "TenantAdminClassList": {
+ "required": [
+ "items",
+ "scoped"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/TenantAdminClassItem"
+ }
+ },
+ "scoped": {
+ "type": "boolean"
+ }
+ }
+ },
+ "TenantAdminClassMemberItem": {
+ "required": [
+ "id",
+ "classId",
+ "userId",
+ "memberType",
+ "status",
+ "joinedAt",
+ "leftAt",
+ "metadata",
+ "user"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "classId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "userId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "memberType": {
+ "$ref": "#/components/schemas/TenantClassMemberType"
+ },
+ "status": {
+ "$ref": "#/components/schemas/TenantClassMemberStatus"
+ },
+ "joinedAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "leftAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "user": {
+ "$ref": "#/components/schemas/TenantAdminUserSummary"
+ }
+ }
+ },
+ "TenantAdminFeedbackItem": {
+ "required": [
+ "id",
+ "userId",
+ "userName",
+ "userPhone",
+ "questionId",
+ "type",
+ "title",
+ "category",
+ "description",
+ "status",
+ "priority",
+ "handledBy",
+ "handledAt",
+ "resolution",
+ "contact",
+ "attachments",
+ "metadata",
+ "createdAt",
+ "updatedAt"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "userId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "userName": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "userPhone": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "questionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "type": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "$ref": "#/components/schemas/ReportType"
+ }
+ ]
+ },
+ "title": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "category": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "description": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "status": {
+ "$ref": "#/components/schemas/ReportStatus"
+ },
+ "priority": {
+ "$ref": "#/components/schemas/ReportPriority"
+ },
+ "handledBy": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "handledAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "resolution": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "contact": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "attachments": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updatedAt": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+ },
+ "TenantAdminMemberItem": {
+ "required": [
+ "membershipId",
+ "userId",
+ "role",
+ "status",
+ "legacyRole",
+ "user",
+ "createdAt",
+ "updatedAt"
+ ],
+ "type": "object",
+ "properties": {
+ "membershipId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "userId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "role": {
+ "$ref": "#/components/schemas/TenantRole"
+ },
+ "status": {
+ "$ref": "#/components/schemas/MembershipStatus"
+ },
+ "legacyRole": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "user": {
+ "$ref": "#/components/schemas/TenantAdminUserSummary"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updatedAt": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+ },
+ "TenantAdminNotificationItem": {
+ "required": [
+ "id",
+ "userId",
+ "notificationType",
+ "status",
+ "severity",
+ "title",
+ "message",
+ "actionLabel",
+ "actionPath",
+ "sourceType",
+ "sourceId",
+ "dedupeKey",
+ "metadata",
+ "createdBy",
+ "readAt",
+ "createdAt",
+ "updatedAt"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "userId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "notificationType": {
+ "type": "string"
+ },
+ "status": {
+ "$ref": "#/components/schemas/NotificationStatus"
+ },
+ "severity": {
+ "$ref": "#/components/schemas/NotificationSeverity"
+ },
+ "title": {
+ "type": "string"
+ },
+ "message": {
+ "type": "string"
+ },
+ "actionLabel": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "actionPath": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "sourceType": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "sourceId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "dedupeKey": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "createdBy": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "readAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updatedAt": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+ },
+ "TenantAdminOverviewItem": {
+ "required": [
+ "studentCount",
+ "classCount",
+ "staffCount",
+ "activePracticeCount",
+ "todayPracticeCount",
+ "pendingFollowupCount",
+ "unreadNotificationCount",
+ "paidOrderCount",
+ "revenueCents",
+ "pendingRefundCount",
+ "openReconciliationIssueCount",
+ "generatedAt"
+ ],
+ "type": "object",
+ "properties": {
+ "studentCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "classCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "staffCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "activePracticeCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "todayPracticeCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "pendingFollowupCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "unreadNotificationCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "paidOrderCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "revenueCents": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "pendingRefundCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "openReconciliationIssueCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "generatedAt": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+ },
+ "TenantAdminStudentClassSummary": {
+ "required": [
+ "classId",
+ "className",
+ "classCode",
+ "memberType",
+ "joinedAt"
+ ],
+ "type": "object",
+ "properties": {
+ "classId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "className": {
+ "type": "string"
+ },
+ "classCode": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "memberType": {
+ "$ref": "#/components/schemas/TenantClassMemberType"
+ },
+ "joinedAt": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+ },
+ "TenantAdminStudentFollowupItem": {
+ "required": [
+ "id",
+ "studentUserId",
+ "assignedToUserId",
+ "classId",
+ "title",
+ "description",
+ "followupType",
+ "priority",
+ "status",
+ "dueAt",
+ "completedAt",
+ "completedBy",
+ "metadata",
+ "createdBy",
+ "updatedBy",
+ "createdAt",
+ "updatedAt"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "studentUserId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "assignedToUserId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "classId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "title": {
+ "type": "string"
+ },
+ "description": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "followupType": {
+ "$ref": "#/components/schemas/StudentFollowupType"
+ },
+ "priority": {
+ "$ref": "#/components/schemas/StudentFollowupPriority"
+ },
+ "status": {
+ "$ref": "#/components/schemas/StudentFollowupStatus"
+ },
+ "dueAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "completedAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "completedBy": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "createdBy": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "updatedBy": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updatedAt": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+ },
+ "TenantAdminStudentImportDto": {
+ "required": [
+ "rows"
+ ],
+ "type": "object",
+ "properties": {
+ "rows": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/TenantAdminStudentImportRowDto"
+ },
+ "description": "数据行列表。"
+ }
+ },
+ "description": "租户管理端学生导入请求 DTO。"
+ },
+ "TenantAdminStudentImportPreview": {
+ "required": [
+ "totalCount",
+ "validCount",
+ "invalidCount",
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "totalCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "validCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "invalidCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/TenantAdminStudentImportPreviewItem"
+ }
+ }
+ }
+ },
+ "TenantAdminStudentImportPreviewItem": {
+ "required": [
+ "rowNo",
+ "valid",
+ "reason",
+ "phone",
+ "email",
+ "name",
+ "regionId",
+ "classId"
+ ],
+ "type": "object",
+ "properties": {
+ "rowNo": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "valid": {
+ "type": "boolean"
+ },
+ "reason": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "phone": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "email": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "name": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "regionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "classId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ }
+ }
+ },
+ "TenantAdminStudentImportResult": {
+ "required": [
+ "totalCount",
+ "createdOrUpdatedCount",
+ "classAssignedCount",
+ "invalidItems"
+ ],
+ "type": "object",
+ "properties": {
+ "totalCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "createdOrUpdatedCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "classAssignedCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "invalidItems": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/TenantAdminStudentImportPreviewItem"
+ }
+ }
+ }
+ },
+ "TenantAdminStudentImportRowDto": {
+ "type": "object",
+ "properties": {
+ "user": {
+ "description": "用户信息。",
+ "$ref": "#/components/schemas/TenantAdminUserLookupDto"
+ },
+ "regionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "地区 ID。",
+ "format": "uuid"
+ },
+ "classId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "班级 ID。",
+ "format": "uuid"
+ },
+ "avatarPreset": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "头像预设。"
+ },
+ "rawProfile": {
+ "description": "原始用户资料。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ },
+ "description": "租户管理端学生导入行请求 DTO。"
+ },
+ "TenantAdminStudentItem": {
+ "required": [
+ "membershipId",
+ "userId",
+ "status",
+ "user",
+ "profileId",
+ "avatarPreset",
+ "regionId",
+ "regionName",
+ "selectedSchoolId",
+ "selectedSchoolName",
+ "selectedMajorId",
+ "selectedMajorName",
+ "stats",
+ "progress",
+ "moduleSelections",
+ "classes",
+ "createdAt",
+ "updatedAt"
+ ],
+ "type": "object",
+ "properties": {
+ "membershipId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "userId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "status": {
+ "$ref": "#/components/schemas/MembershipStatus"
+ },
+ "user": {
+ "$ref": "#/components/schemas/TenantAdminUserSummary"
+ },
+ "profileId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "avatarPreset": {
+ "type": "string"
+ },
+ "regionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "regionName": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "selectedSchoolId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "selectedSchoolName": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "selectedMajorId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "selectedMajorName": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "stats": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "progress": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "moduleSelections": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "classes": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/TenantAdminStudentClassSummary"
+ }
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updatedAt": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+ },
+ "TenantAdminStudentList": {
+ "required": [
+ "items",
+ "scoped"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/TenantAdminStudentItem"
+ }
+ },
+ "scoped": {
+ "type": "boolean"
+ }
+ }
+ },
+ "TenantAdminStudentNoteItem": {
+ "required": [
+ "id",
+ "studentUserId",
+ "noteType",
+ "content",
+ "visibility",
+ "isPinned",
+ "metadata",
+ "createdBy",
+ "updatedBy",
+ "createdAt",
+ "updatedAt"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "studentUserId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "noteType": {
+ "$ref": "#/components/schemas/StudentNoteType"
+ },
+ "content": {
+ "type": "string"
+ },
+ "visibility": {
+ "$ref": "#/components/schemas/StudentNoteVisibility"
+ },
+ "isPinned": {
+ "type": "boolean"
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "createdBy": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "updatedBy": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updatedAt": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+ },
+ "TenantAdminStudentStatusItem": {
+ "required": [
+ "membershipId",
+ "userId",
+ "role",
+ "status",
+ "updatedAt"
+ ],
+ "type": "object",
+ "properties": {
+ "membershipId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "userId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "role": {
+ "$ref": "#/components/schemas/TenantRole"
+ },
+ "status": {
+ "$ref": "#/components/schemas/MembershipStatus"
+ },
+ "updatedAt": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+ },
+ "TenantAdminUserLookupDto": {
+ "type": "object",
+ "properties": {
+ "userId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "用户 ID。",
+ "format": "uuid"
+ },
+ "username": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "用户名。"
+ },
+ "email": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "邮箱。"
+ },
+ "phone": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "手机号。"
+ },
+ "name": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "名称。"
+ },
+ "avatarUrl": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "头像地址。"
+ }
+ },
+ "description": "租户管理端用户查找请求 DTO。"
+ },
+ "TenantAdminUserSummary": {
+ "required": [
+ "id",
+ "username",
+ "email",
+ "phone",
+ "name",
+ "avatarUrl",
+ "primaryRole"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "username": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "email": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "phone": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "name": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "avatarUrl": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "primaryRole": {
+ "type": "string"
+ }
+ }
+ },
+ "TenantBillingCatalog": {
+ "required": [
+ "features",
+ "basePlans",
+ "addOns"
+ ],
+ "type": "object",
+ "properties": {
+ "features": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/SaasFeature"
+ }
+ },
+ "basePlans": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/SaasOfferingVersionItem"
+ }
+ },
+ "addOns": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/SaasOfferingVersionItem"
+ }
+ }
+ }
+ },
+ "TenantBillingInvoiceTitleType": {
+ "type": "integer"
+ },
+ "TenantBillingProfileItem": {
+ "required": [
+ "tenantId",
+ "billingName",
+ "taxId",
+ "contactName",
+ "contactPhoneMasked",
+ "contactEmail",
+ "billingAddress",
+ "invoiceTitle",
+ "invoiceType",
+ "bankName",
+ "bankAccountMasked",
+ "metadata"
+ ],
+ "type": "object",
+ "properties": {
+ "tenantId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "billingName": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "taxId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "contactName": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "contactPhoneMasked": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "contactEmail": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "billingAddress": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "invoiceTitle": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "invoiceType": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "$ref": "#/components/schemas/TenantBillingInvoiceTitleType"
+ }
+ ]
+ },
+ "bankName": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "bankAccountMasked": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ }
+ },
+ "TenantBrandingItem": {
+ "required": [
+ "tenantId",
+ "brandName",
+ "shortName",
+ "slogan",
+ "organizationName",
+ "logoUrl",
+ "faviconUrl",
+ "serviceWechat",
+ "serviceAccountName",
+ "theme",
+ "publicAssets",
+ "updatedAt"
+ ],
+ "type": "object",
+ "properties": {
+ "tenantId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "brandName": {
+ "type": "string"
+ },
+ "shortName": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "slogan": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "organizationName": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "logoUrl": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "faviconUrl": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "serviceWechat": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "serviceAccountName": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "theme": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "publicAssets": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "updatedAt": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+ },
+ "TenantClassMemberStatus": {
+ "type": "integer"
+ },
+ "TenantClassMemberType": {
+ "type": "integer"
+ },
+ "TenantCommerceAnomalySummary": {
+ "required": [
+ "openRefundCount",
+ "processingRefundCount",
+ "openReconciliationIssueCount",
+ "failedReconciliationBatchCount",
+ "pendingPaymentCount",
+ "paymentMismatchCount"
+ ],
+ "type": "object",
+ "properties": {
+ "openRefundCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "processingRefundCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "openReconciliationIssueCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "failedReconciliationBatchCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "pendingPaymentCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "paymentMismatchCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ }
+ }
+ },
+ "TenantCouponList": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/Coupon"
+ }
+ }
+ }
+ },
+ "TenantCouponRedemptionList": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/CouponRedemption"
+ }
+ }
+ }
+ },
+ "TenantCouponReport": {
+ "required": [
+ "couponCount",
+ "claimedCount",
+ "usedCount",
+ "discountAppliedCents"
+ ],
+ "type": "object",
+ "properties": {
+ "couponCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "claimedCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "usedCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "discountAppliedCents": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ }
+ }
+ },
+ "TenantDomainItem": {
+ "required": [
+ "id",
+ "host",
+ "domainType",
+ "status",
+ "isPrimary",
+ "verificationToken",
+ "verifiedAt",
+ "lastCheckedAt",
+ "dnsVerifiedAt",
+ "tlsReadyAt",
+ "lastFailureReason",
+ "createdAt",
+ "updatedAt"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "host": {
+ "type": "string"
+ },
+ "domainType": {
+ "$ref": "#/components/schemas/TenantDomainType"
+ },
+ "status": {
+ "$ref": "#/components/schemas/TenantDomainStatus"
+ },
+ "isPrimary": {
+ "type": "boolean"
+ },
+ "verificationToken": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "verifiedAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "lastCheckedAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "dnsVerifiedAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "tlsReadyAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "lastFailureReason": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updatedAt": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+ },
+ "TenantDomainStatus": {
+ "type": "integer"
+ },
+ "TenantDomainType": {
+ "type": "integer"
+ },
+ "TenantExternalProviderCapability": {
+ "type": "integer"
+ },
+ "TenantExternalProviderItem": {
+ "required": [
+ "id",
+ "capability",
+ "provider",
+ "status",
+ "displayName",
+ "secretRef",
+ "priority",
+ "configPublic",
+ "metadata",
+ "createdAt",
+ "updatedAt"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "capability": {
+ "$ref": "#/components/schemas/TenantExternalProviderCapability"
+ },
+ "provider": {
+ "type": "string"
+ },
+ "status": {
+ "$ref": "#/components/schemas/TenantExternalProviderStatus"
+ },
+ "displayName": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "secretRef": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "priority": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "configPublic": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updatedAt": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+ },
+ "TenantExternalProviderStatus": {
+ "type": "integer"
+ },
+ "TenantFeatureOverride": {
+ "type": "object",
+ "properties": {
+ "featureCode": {
+ "type": "string"
+ },
+ "mode": {
+ "$ref": "#/components/schemas/TenantFeatureOverrideMode"
+ },
+ "expiresAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "reason": {
+ "type": "string"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updatedAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "tenantId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ },
+ "TenantFeatureOverrideMode": {
+ "type": "integer"
+ },
+ "TenantFeatureUsage": {
+ "type": "object",
+ "properties": {
+ "metricCode": {
+ "type": "string"
+ },
+ "periodStart": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "periodEnd": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "usedValue": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int64"
+ },
+ "limitValueSnapshot": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int64"
+ },
+ "warningIssued": {
+ "type": "boolean"
+ },
+ "version": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int64"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updatedAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "tenantId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ },
+ "TenantFeedbackReport": {
+ "required": [
+ "pendingCount",
+ "acceptedCount",
+ "rejectedCount",
+ "resolvedCount",
+ "closedCount"
+ ],
+ "type": "object",
+ "properties": {
+ "pendingCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "acceptedCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "rejectedCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "resolvedCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "closedCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ }
+ }
+ },
+ "TenantFollowupReport": {
+ "required": [
+ "openCount",
+ "inProgressCount",
+ "doneCount",
+ "overdueCount"
+ ],
+ "type": "object",
+ "properties": {
+ "openCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "inProgressCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "doneCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "overdueCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ }
+ }
+ },
+ "TenantFrontendConfigDraft": {
+ "required": [
+ "branding",
+ "theme",
+ "features",
+ "navigation",
+ "homeModules"
+ ],
+ "type": "object",
+ "properties": {
+ "branding": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "theme": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "features": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "navigation": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "homeModules": {
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ }
+ },
+ "TenantFrontendConfigItem": {
+ "required": [
+ "schemaVersion",
+ "configVersion",
+ "published",
+ "draft",
+ "publishedAt"
+ ],
+ "type": "object",
+ "properties": {
+ "schemaVersion": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "configVersion": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "published": {
+ "$ref": "#/components/schemas/TenantFrontendConfigDraft"
+ },
+ "draft": {
+ "$ref": "#/components/schemas/TenantFrontendConfigDraft"
+ },
+ "publishedAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ }
+ }
+ },
+ "TenantIdentityProviderItem": {
+ "required": [
+ "id",
+ "provider",
+ "status",
+ "displayName",
+ "secretRef",
+ "priority",
+ "configPublic",
+ "createdAt",
+ "updatedAt"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "provider": {
+ "type": "string"
+ },
+ "status": {
+ "$ref": "#/components/schemas/TenantExternalProviderStatus"
+ },
+ "displayName": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "secretRef": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "priority": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "configPublic": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updatedAt": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+ },
+ "TenantMembershipResponse": {
+ "required": [
+ "tenantId",
+ "tenantName",
+ "tenantSlug",
+ "role",
+ "status"
+ ],
+ "type": "object",
+ "properties": {
+ "tenantId": {
+ "type": "string",
+ "description": "租户 ID。",
+ "format": "uuid"
+ },
+ "tenantName": {
+ "type": "string",
+ "description": "租户名称。"
+ },
+ "tenantSlug": {
+ "type": "string",
+ "description": "租户编码。"
+ },
+ "role": {
+ "description": "当前用户在该租户内的角色。",
+ "$ref": "#/components/schemas/TenantRole"
+ },
+ "status": {
+ "description": "租户成员状态。",
+ "$ref": "#/components/schemas/MembershipStatus"
+ }
+ },
+ "description": "用户在某个租户内的成员摘要。"
+ },
+ "TenantMembershipSummary": {
+ "required": [
+ "tenantId",
+ "tenantName",
+ "role",
+ "status"
+ ],
+ "type": "object",
+ "properties": {
+ "tenantId": {
+ "type": "string",
+ "description": "租户 ID。",
+ "format": "uuid"
+ },
+ "tenantName": {
+ "type": "string",
+ "description": "租户名称。"
+ },
+ "role": {
+ "description": "当前用户在租户内的角色。",
+ "$ref": "#/components/schemas/TenantRole"
+ },
+ "status": {
+ "description": "租户成员状态。",
+ "$ref": "#/components/schemas/MembershipStatus"
+ }
+ },
+ "description": "当前登录租户成员摘要。"
+ },
+ "TenantMode": {
+ "type": "integer"
+ },
+ "TenantOnboardingStatus": {
+ "required": [
+ "tenantId",
+ "readyForStudentTraffic",
+ "completedRequiredSteps",
+ "requiredSteps",
+ "steps"
+ ],
+ "type": "object",
+ "properties": {
+ "tenantId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "readyForStudentTraffic": {
+ "type": "boolean"
+ },
+ "completedRequiredSteps": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "requiredSteps": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "steps": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/TenantOnboardingStep"
+ }
+ }
+ }
+ },
+ "TenantOnboardingStep": {
+ "required": [
+ "code",
+ "required",
+ "completed",
+ "detail"
+ ],
+ "type": "object",
+ "properties": {
+ "code": {
+ "type": "string"
+ },
+ "required": {
+ "type": "boolean"
+ },
+ "completed": {
+ "type": "boolean"
+ },
+ "detail": {
+ "type": [
+ "null",
+ "string"
+ ]
+ }
+ }
+ },
+ "TenantPaymentProviderItem": {
+ "required": [
+ "id",
+ "provider",
+ "mode",
+ "displayName",
+ "status",
+ "secretRef",
+ "priority",
+ "configPublic",
+ "createdAt",
+ "updatedAt"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "provider": {
+ "type": "string"
+ },
+ "mode": {
+ "type": "string"
+ },
+ "displayName": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "status": {
+ "$ref": "#/components/schemas/TenantExternalProviderStatus"
+ },
+ "secretRef": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "priority": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "configPublic": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updatedAt": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+ },
+ "TenantPointClaimList": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/PointActivityClaim"
+ }
+ }
+ }
+ },
+ "TenantPointExchangeItemList": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/PointExchangeItem"
+ }
+ }
+ }
+ },
+ "TenantPointExchangeOrderList": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/PointExchangeOrder"
+ }
+ }
+ }
+ },
+ "TenantPointRiskReport": {
+ "required": [
+ "negativeScoreUserCount",
+ "highPointClaimUserCount",
+ "cancelledExchangeOrderCount"
+ ],
+ "type": "object",
+ "properties": {
+ "negativeScoreUserCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "highPointClaimUserCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "cancelledExchangeOrderCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ }
+ }
+ },
+ "TenantPointTaskList": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/PointActivityTask"
+ }
+ }
+ }
+ },
+ "TenantReconciliationBatchList": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/CommerceReconciliationBatch"
+ }
+ }
+ }
+ },
+ "TenantReconciliationIssueEventList": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/CommerceReconciliationIssueEvent"
+ }
+ }
+ }
+ },
+ "TenantReconciliationIssueList": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/CommerceReconciliationIssue"
+ }
+ }
+ }
+ },
+ "TenantReconciliationItemList": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/CommerceReconciliationItem"
+ }
+ }
+ }
+ },
+ "TenantRecordStatus": {
+ "type": "integer"
+ },
+ "TenantRefundEventList": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/CommerceRefundEvent"
+ }
+ }
+ }
+ },
+ "TenantRefundList": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/CommerceRefundRequest"
+ }
+ }
+ }
+ },
+ "TenantResolveResponseDto": {
+ "required": [
+ "tenant",
+ "branding",
+ "features",
+ "adminFeatures",
+ "publicConfig"
+ ],
+ "type": "object",
+ "properties": {
+ "tenant": {
+ "description": "公开租户基础信息。",
+ "$ref": "#/components/schemas/PublicTenantDto"
+ },
+ "branding": {
+ "description": "公开品牌配置。",
+ "$ref": "#/components/schemas/PublicTenantBrandingDto"
+ },
+ "features": {
+ "description": "面向前端公开的功能开关。",
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "adminFeatures": {
+ "description": "面向管理端公开的功能开关。",
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "publicConfig": {
+ "description": "可公开的租户配置,不包含密钥或内部配置。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ },
+ "description": "租户解析响应。"
+ },
+ "TenantRole": {
+ "type": "integer"
+ },
+ "TenantRuntimeBootstrap": {
+ "required": [
+ "schemaVersion",
+ "configVersion",
+ "tenantCode",
+ "tenantName",
+ "branding",
+ "theme",
+ "features",
+ "navigation",
+ "homeModules",
+ "enabledFeatures",
+ "loginMethods"
+ ],
+ "type": "object",
+ "properties": {
+ "schemaVersion": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "configVersion": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "tenantCode": {
+ "type": "string"
+ },
+ "tenantName": {
+ "type": "string"
+ },
+ "branding": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "theme": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "features": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "navigation": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "homeModules": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "enabledFeatures": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "loginMethods": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "TenantSaasSubscription": {
+ "type": "object",
+ "properties": {
+ "baseOfferingVersionId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "scheduledBaseOfferingVersionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "status": {
+ "$ref": "#/components/schemas/TenantSaasSubscriptionStatus"
+ },
+ "startsAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "currentPeriodStart": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "currentPeriodEnd": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "cancelAtPeriodEnd": {
+ "type": "boolean"
+ },
+ "cancelledAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "lifecycleVersion": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int64"
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updatedAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "tenantId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ },
+ "TenantSaasSubscriptionStatus": {
+ "type": "integer"
+ },
+ "TenantSecretItem": {
+ "required": [
+ "id",
+ "purpose",
+ "provider",
+ "secretKey",
+ "secretRef",
+ "status",
+ "rotatedAt",
+ "expiresAt",
+ "updatedAt"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "purpose": {
+ "type": "string"
+ },
+ "provider": {
+ "type": "string"
+ },
+ "secretKey": {
+ "type": "string"
+ },
+ "secretRef": {
+ "type": "string"
+ },
+ "status": {
+ "type": "string"
+ },
+ "rotatedAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "expiresAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "updatedAt": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+ },
+ "TenantSecretStatus": {
+ "type": "integer"
+ },
+ "TenantSettingsItem": {
+ "required": [
+ "tenantId",
+ "featureFlags",
+ "adminFeatureFlags",
+ "publicConfig",
+ "updatedAt"
+ ],
+ "type": "object",
+ "properties": {
+ "tenantId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "featureFlags": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "adminFeatureFlags": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "publicConfig": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "updatedAt": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+ },
+ "TenantStatus": {
+ "type": "integer"
+ },
+ "TenantSubscriptionView": {
+ "required": [
+ "id",
+ "status",
+ "startsAt",
+ "currentPeriodStart",
+ "currentPeriodEnd",
+ "cancelAtPeriodEnd",
+ "baseOfferingVersionId",
+ "scheduledBaseOfferingVersionId",
+ "featureCodes"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "status": {
+ "$ref": "#/components/schemas/TenantSaasSubscriptionStatus"
+ },
+ "startsAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "currentPeriodStart": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "currentPeriodEnd": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "cancelAtPeriodEnd": {
+ "type": "boolean"
+ },
+ "baseOfferingVersionId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "scheduledBaseOfferingVersionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "featureCodes": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "TenantSupervisionGenerateDto": {
+ "type": "object",
+ "properties": {
+ "userIds": {
+ "type": [
+ "null",
+ "array"
+ ],
+ "items": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "description": "用户 ID 列表。"
+ },
+ "assignedToUserId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "分配处理人用户 ID。",
+ "format": "uuid"
+ },
+ "dueAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "到期时间。",
+ "format": "date-time"
+ }
+ },
+ "description": "租户督导生成请求 DTO。"
+ },
+ "TenantSupervisionGenerateResult": {
+ "required": [
+ "createdCount"
+ ],
+ "type": "object",
+ "properties": {
+ "createdCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ }
+ }
+ },
+ "TenantSupervisionPreview": {
+ "required": [
+ "items"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/TenantSupervisionRiskStudentItem"
+ }
+ }
+ }
+ },
+ "TenantSupervisionRiskStudentItem": {
+ "required": [
+ "userId",
+ "name",
+ "phoneMasked",
+ "regionId",
+ "ruleCodes",
+ "reasons"
+ ],
+ "type": "object",
+ "properties": {
+ "userId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "name": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "phoneMasked": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "regionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "ruleCodes": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "reasons": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "TenantSupervisionRuleItem": {
+ "required": [
+ "code",
+ "title",
+ "enabled",
+ "daysWithoutCheckIn",
+ "maxQuestionsAnsweredToday",
+ "followupType",
+ "priority",
+ "metadata"
+ ],
+ "type": "object",
+ "properties": {
+ "code": {
+ "type": "string"
+ },
+ "title": {
+ "type": "string"
+ },
+ "enabled": {
+ "type": "boolean"
+ },
+ "daysWithoutCheckIn": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "maxQuestionsAnsweredToday": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "followupType": {
+ "type": "string"
+ },
+ "priority": {
+ "type": "string"
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ }
+ },
+ "TenantThemeConfigStatus": {
+ "type": "integer"
+ },
+ "TenantThemeItem": {
+ "required": [
+ "tenantId",
+ "activeTemplateCode",
+ "activeTheme",
+ "activePublicAssets",
+ "draftTemplateCode",
+ "draftTheme",
+ "draftPublicAssets",
+ "status",
+ "publishedAt",
+ "publishedBy",
+ "draftUpdatedBy",
+ "updatedAt"
+ ],
+ "type": "object",
+ "properties": {
+ "tenantId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "activeTemplateCode": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "activeTheme": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "activePublicAssets": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "draftTemplateCode": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "draftTheme": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "draftPublicAssets": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "status": {
+ "$ref": "#/components/schemas/TenantThemeConfigStatus"
+ },
+ "publishedAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "publishedBy": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "draftUpdatedBy": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "updatedAt": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+ },
+ "TenantThemeTemplateItem": {
+ "required": [
+ "code",
+ "name",
+ "description",
+ "previewImageUrl",
+ "theme",
+ "publicAssets",
+ "order"
+ ],
+ "type": "object",
+ "properties": {
+ "code": {
+ "type": "string"
+ },
+ "name": {
+ "type": "string"
+ },
+ "description": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "previewImageUrl": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "theme": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "publicAssets": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "order": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ }
+ }
+ },
+ "TrackReferralEventDto": {
+ "required": [
+ "refCode"
+ ],
+ "type": "object",
+ "properties": {
+ "refCode": {
+ "maxLength": 100,
+ "minLength": 0,
+ "type": "string",
+ "description": "推荐码。"
+ },
+ "eventType": {
+ "maxLength": 100,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "事件类型。"
+ },
+ "source": {
+ "maxLength": 100,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "来源。"
+ },
+ "targetUserId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "目标用户 ID。",
+ "format": "uuid"
+ },
+ "metadata": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "description": "扩展元数据。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ ]
+ },
+ "tenantCode": {
+ "maxLength": 100,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "租户编码。"
+ }
+ },
+ "description": "记录推荐事件请求 DTO。"
+ },
+ "UpdateAdjustmentVoucherStatusDto": {
+ "required": [
+ "voucherId"
+ ],
+ "type": "object",
+ "properties": {
+ "voucherId": {
+ "type": "string",
+ "description": "凭证 ID。",
+ "format": "uuid"
+ },
+ "status": {
+ "description": "状态。",
+ "$ref": "#/components/schemas/CommerceAdjustmentVoucherStatus"
+ },
+ "note": {
+ "maxLength": 1000,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "备注。"
+ }
+ },
+ "description": "更新调账凭证状态请求 DTO。"
+ },
+ "UpdateCommissionProofStatusDto": {
+ "required": [
+ "proofId"
+ ],
+ "type": "object",
+ "properties": {
+ "proofId": {
+ "type": "string",
+ "description": "凭证 ID。",
+ "format": "uuid"
+ },
+ "status": {
+ "maxLength": 50,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "状态。"
+ },
+ "reviewNote": {
+ "maxLength": 1000,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "审核备注。"
+ },
+ "metadata": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "description": "扩展元数据。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ ]
+ }
+ },
+ "description": "更新佣金结算凭证状态请求。"
+ },
+ "UpdateCommissionSettingsDto": {
+ "type": "object",
+ "properties": {
+ "defaultRate": {
+ "maximum": 1,
+ "minimum": 0,
+ "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
+ "type": [
+ "null",
+ "number",
+ "string"
+ ],
+ "description": "默认佣金比例。",
+ "format": "double"
+ },
+ "minSettlementCents": {
+ "maximum": 2147483647,
+ "minimum": 0,
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "description": "最低结算金额,单位为分。",
+ "format": "int32"
+ },
+ "settlementCycle": {
+ "maxLength": 50,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "结算周期。"
+ },
+ "config": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "description": "配置内容。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ ]
+ }
+ },
+ "description": "保存佣金配置请求。"
+ },
+ "UpdateCommissionSettlementStatusDto": {
+ "required": [
+ "settlementId"
+ ],
+ "type": "object",
+ "properties": {
+ "settlementId": {
+ "type": "string",
+ "description": "结算单 ID。",
+ "format": "uuid"
+ },
+ "status": {
+ "maxLength": 50,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "状态。"
+ },
+ "reviewNote": {
+ "maxLength": 1000,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "审核备注。"
+ },
+ "paymentMethod": {
+ "maxLength": 100,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "支付方式。"
+ },
+ "paymentAccount": {
+ "maxLength": 200,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "收款账号。"
+ },
+ "metadata": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "description": "扩展元数据。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ ]
+ }
+ },
+ "description": "更新佣金结算单状态请求 DTO。"
+ },
+ "UpdateMemberCommissionRateDto": {
+ "required": [
+ "userId"
+ ],
+ "type": "object",
+ "properties": {
+ "userId": {
+ "type": "string",
+ "description": "用户 ID。",
+ "format": "uuid"
+ },
+ "commissionRate": {
+ "maximum": 1,
+ "minimum": 0,
+ "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
+ "type": [
+ "null",
+ "number",
+ "string"
+ ],
+ "description": "成员佣金比例。",
+ "format": "double"
+ },
+ "commissionConfig": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "description": "佣金扩展配置。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ ]
+ }
+ },
+ "description": "调整成员佣金比例请求。"
+ },
+ "UpdatePlatformAuditAlertStatusDto": {
+ "required": [
+ "alertId"
+ ],
+ "type": "object",
+ "properties": {
+ "alertId": {
+ "type": "string",
+ "description": "告警 ID。",
+ "format": "uuid"
+ },
+ "status": {
+ "description": "状态。",
+ "$ref": "#/components/schemas/PlatformAuditAlertStatus"
+ },
+ "resolutionNote": {
+ "maxLength": 1000,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "处理备注。"
+ }
+ },
+ "description": "更新平台审计Alert状态请求 DTO。"
+ },
+ "UpdatePlatformStaffStatusDto": {
+ "required": [
+ "userId"
+ ],
+ "type": "object",
+ "properties": {
+ "userId": {
+ "type": "string",
+ "description": "用户 ID。",
+ "format": "uuid"
+ },
+ "status": {
+ "description": "状态。",
+ "$ref": "#/components/schemas/UserStatus"
+ },
+ "reason": {
+ "maxLength": 1000,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "原因。"
+ }
+ },
+ "description": "更新平台Staff状态请求 DTO。"
+ },
+ "UpdatePlatformTenantStatusDto": {
+ "required": [
+ "tenantId"
+ ],
+ "type": "object",
+ "properties": {
+ "tenantId": {
+ "type": "string",
+ "description": "租户 ID。",
+ "format": "uuid"
+ },
+ "status": {
+ "description": "状态。",
+ "$ref": "#/components/schemas/TenantStatus"
+ },
+ "billingStatus": {
+ "description": "账务状态。",
+ "$ref": "#/components/schemas/BillingStatus"
+ },
+ "reason": {
+ "maxLength": 1000,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "原因。"
+ }
+ },
+ "description": "更新平台租户状态请求 DTO。"
+ },
+ "UpdatePointExchangeOrderStatusDto": {
+ "required": [
+ "orderId"
+ ],
+ "type": "object",
+ "properties": {
+ "orderId": {
+ "type": "string",
+ "description": "订单 ID。",
+ "format": "uuid"
+ },
+ "status": {
+ "description": "状态。",
+ "$ref": "#/components/schemas/PointExchangeOrderStatus"
+ }
+ },
+ "description": "更新积分兑换订单状态请求 DTO。"
+ },
+ "UpdateProfileDto": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "maxLength": 100,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "名称。"
+ },
+ "avatarPreset": {
+ "maxLength": 32,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "头像预设。"
+ },
+ "regionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "地区 ID。",
+ "format": "uuid"
+ },
+ "selectedSchoolId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "已选择院校 ID。",
+ "format": "uuid"
+ },
+ "selectedMajorId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "已选择专业 ID。",
+ "format": "uuid"
+ },
+ "stats": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "description": "统计数据。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ ]
+ },
+ "progress": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "description": "进度数据。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ ]
+ },
+ "moduleSelections": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "description": "模块选择数据。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ ]
+ },
+ "recentActivities": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "description": "最近活动数据。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ ]
+ }
+ },
+ "description": "更新资料请求 DTO。"
+ },
+ "UpdateReconciliationIssueDto": {
+ "required": [
+ "issueId"
+ ],
+ "type": "object",
+ "properties": {
+ "issueId": {
+ "type": "string",
+ "description": "工单 ID。",
+ "format": "uuid"
+ },
+ "status": {
+ "description": "状态。",
+ "$ref": "#/components/schemas/ReconciliationIssueStatus"
+ },
+ "resolutionType": {
+ "description": "处理类型。",
+ "$ref": "#/components/schemas/ReconciliationResolutionType"
+ },
+ "note": {
+ "maxLength": 1000,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "备注。"
+ },
+ "assignedTo": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "分配处理人。",
+ "format": "uuid"
+ }
+ },
+ "description": "更新对账Issue请求 DTO。"
+ },
+ "UpdateRefundStatusDto": {
+ "required": [
+ "refundRequestId"
+ ],
+ "type": "object",
+ "properties": {
+ "refundRequestId": {
+ "type": "string",
+ "description": "退款申请 ID。",
+ "format": "uuid"
+ },
+ "status": {
+ "description": "状态。",
+ "$ref": "#/components/schemas/CommerceRefundStatus"
+ },
+ "reason": {
+ "maxLength": 1000,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "原因。"
+ },
+ "providerRefundNo": {
+ "maxLength": 200,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "渠道退款单号。"
+ }
+ },
+ "description": "更新退款状态请求 DTO。"
+ },
+ "UpdateTenantAdminFeedbackDto": {
+ "required": [
+ "feedbackId"
+ ],
+ "type": "object",
+ "properties": {
+ "feedbackId": {
+ "type": "string",
+ "description": "反馈 ID。",
+ "format": "uuid"
+ },
+ "status": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "状态。"
+ },
+ "priority": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "优先级。"
+ },
+ "resolution": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "处理结果。"
+ },
+ "note": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "备注。"
+ },
+ "metadata": {
+ "description": "扩展元数据。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ },
+ "description": "更新租户管理端反馈请求 DTO。"
+ },
+ "UpdateTenantAdminStudentStatusDto": {
+ "required": [
+ "userId"
+ ],
+ "type": "object",
+ "properties": {
+ "userId": {
+ "type": "string",
+ "description": "用户 ID。",
+ "format": "uuid"
+ },
+ "status": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "状态。"
+ },
+ "reason": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "原因。"
+ }
+ },
+ "description": "更新租户管理端学生状态请求 DTO。"
+ },
+ "UpsertAssetDto": {
+ "type": "object",
+ "properties": {
+ "assetId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "资产 ID。",
+ "format": "uuid"
+ },
+ "regionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "地区 ID。",
+ "format": "uuid"
+ },
+ "subjectId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "科目 ID。",
+ "format": "uuid"
+ },
+ "categoryId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "分类 ID。",
+ "format": "uuid"
+ },
+ "contentNodeId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "内容节点 ID。",
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "历史系统 ID。"
+ },
+ "assetKey": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "资产键。"
+ },
+ "title": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "标题。"
+ },
+ "category": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "分类。"
+ },
+ "description": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "说明。"
+ },
+ "fileName": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "文件名。"
+ },
+ "cdnUrl": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "CDN 地址。"
+ },
+ "isPublic": {
+ "type": [
+ "null",
+ "boolean"
+ ],
+ "description": "是否公开。"
+ },
+ "assetType": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "资产类型。"
+ },
+ "visibility": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "可见性。"
+ },
+ "status": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "状态。"
+ },
+ "provider": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "服务提供方。"
+ },
+ "bucket": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "存储桶。"
+ },
+ "objectKey": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "对象存储键。"
+ },
+ "mimeType": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "MIME 类型。"
+ },
+ "fileSizeBytes": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "description": "文件大小,单位为字节。",
+ "format": "int64"
+ },
+ "checksumSha256": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "SHA-256 校验值。"
+ },
+ "previewUrl": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "预览地址。"
+ },
+ "previewObjectKey": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "预览对象存储键。"
+ },
+ "order": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "description": "显示顺序。",
+ "format": "int32"
+ },
+ "accessRules": {
+ "description": "访问规则。",
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "metadata": {
+ "description": "扩展元数据。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ },
+ "description": "新增或更新内容资产请求。"
+ },
+ "UpsertBackofficeRoleDto": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "ID。",
+ "format": "uuid"
+ },
+ "code": {
+ "type": "string",
+ "description": "编码。"
+ },
+ "name": {
+ "type": "string",
+ "description": "名称。"
+ },
+ "status": {
+ "description": "状态。",
+ "$ref": "#/components/schemas/BackendRoleStatus"
+ },
+ "description": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "说明。"
+ },
+ "dataScope": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "description": "数据范围配置。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ ]
+ }
+ },
+ "description": "创建或更新后台角色请求。"
+ },
+ "UpsertContentEntryDto": {
+ "required": [
+ "name"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "ID。",
+ "format": "uuid"
+ },
+ "regionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "地区 ID。",
+ "format": "uuid"
+ },
+ "legacyId": {
+ "maxLength": 64,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "历史系统 ID。"
+ },
+ "entryKey": {
+ "maxLength": 100,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "入口键。"
+ },
+ "name": {
+ "maxLength": 300,
+ "minLength": 0,
+ "type": "string",
+ "description": "名称。"
+ },
+ "entryType": {
+ "maxLength": 50,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "入口类型。"
+ },
+ "icon": {
+ "maxLength": 100,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "图标。"
+ },
+ "route": {
+ "maxLength": 500,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "路由地址。"
+ },
+ "description": {
+ "maxLength": 2000,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "说明。"
+ },
+ "visibility": {
+ "maxLength": 50,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "可见性。"
+ },
+ "accessRules": {
+ "description": "访问规则。",
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "layoutConfig": {
+ "description": "布局配置。",
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "order": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "description": "显示顺序。",
+ "format": "int32"
+ },
+ "isActive": {
+ "type": [
+ "null",
+ "boolean"
+ ],
+ "description": "是否启用。"
+ }
+ },
+ "description": "新增或更新内容条目请求 DTO。"
+ },
+ "UpsertContentNodeDto": {
+ "required": [
+ "entryId",
+ "name"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "ID。",
+ "format": "uuid"
+ },
+ "entryId": {
+ "type": "string",
+ "description": "内容入口 ID。",
+ "format": "uuid"
+ },
+ "regionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "地区 ID。",
+ "format": "uuid"
+ },
+ "parentId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "父节点 ID。",
+ "format": "uuid"
+ },
+ "legacyId": {
+ "maxLength": 64,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "历史系统 ID。"
+ },
+ "nodeKey": {
+ "maxLength": 100,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "节点键。"
+ },
+ "name": {
+ "maxLength": 300,
+ "minLength": 0,
+ "type": "string",
+ "description": "名称。"
+ },
+ "nodeType": {
+ "maxLength": 50,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "节点Type。"
+ },
+ "markerType": {
+ "maxLength": 50,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "标记类型。"
+ },
+ "markerConfig": {
+ "description": "标记配置。",
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "order": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "description": "显示顺序。",
+ "format": "int32"
+ },
+ "isActive": {
+ "type": [
+ "null",
+ "boolean"
+ ],
+ "description": "是否启用。"
+ },
+ "isSelectable": {
+ "type": [
+ "null",
+ "boolean"
+ ],
+ "description": "是否可选择。"
+ },
+ "isLeaf": {
+ "type": [
+ "null",
+ "boolean"
+ ],
+ "description": "是否叶子节点。"
+ },
+ "accessRules": {
+ "description": "访问规则。",
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "metadata": {
+ "description": "扩展元数据。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ },
+ "description": "新增或更新内容节点请求 DTO。"
+ },
+ "UpsertCrmConfigDto": {
+ "type": "object",
+ "properties": {
+ "enabled": {
+ "type": "boolean",
+ "description": "是否启用。"
+ },
+ "url": {
+ "maxLength": 2048,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "访问地址。"
+ },
+ "secretRef": {
+ "maxLength": 300,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "密钥引用。"
+ },
+ "secret": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "密钥内容。"
+ },
+ "formName": {
+ "maxLength": 200,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "表单名称。"
+ },
+ "examType": {
+ "maxLength": 100,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "考试类型。"
+ },
+ "timeoutSeconds": {
+ "maximum": 120,
+ "minimum": 1,
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "description": "超时时长,单位为秒。",
+ "format": "int32"
+ },
+ "delaySeconds": {
+ "maximum": 86400,
+ "minimum": 0,
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "description": "延迟秒数。",
+ "format": "int32"
+ },
+ "assignmentMode": {
+ "maxLength": 50,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "分配模式。"
+ },
+ "assignmentPool": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "description": "分配池。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ ]
+ },
+ "assignmentConfig": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "description": "分配配置。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ ]
+ }
+ },
+ "description": "新增或更新CRM配置请求 DTO。"
+ },
+ "UpsertPaymentAccountDto": {
+ "required": [
+ "provider"
+ ],
+ "type": "object",
+ "properties": {
+ "provider": {
+ "maxLength": 50,
+ "minLength": 0,
+ "type": "string",
+ "description": "服务提供方。"
+ },
+ "mode": {
+ "maxLength": 50,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "模式。"
+ },
+ "displayName": {
+ "maxLength": 200,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "显示名称。"
+ },
+ "status": {
+ "description": "状态。",
+ "$ref": "#/components/schemas/TenantExternalProviderStatus"
+ },
+ "secretRef": {
+ "maxLength": 300,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "密钥引用。"
+ },
+ "priority": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "description": "优先级。",
+ "format": "int32"
+ },
+ "configPublic": {
+ "description": "公开配置内容。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ },
+ "description": "新增或更新支付账号请求 DTO。"
+ },
+ "UpsertPlatformBillingDunningChannelDto": {
+ "required": [
+ "channelCode",
+ "name",
+ "webhookUrl"
+ ],
+ "type": "object",
+ "properties": {
+ "channelId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "通知渠道 ID。",
+ "format": "uuid"
+ },
+ "channelCode": {
+ "maxLength": 100,
+ "minLength": 0,
+ "type": "string",
+ "description": "渠道编码。"
+ },
+ "name": {
+ "maxLength": 200,
+ "minLength": 0,
+ "type": "string",
+ "description": "名称。"
+ },
+ "description": {
+ "maxLength": 1000,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "说明。"
+ },
+ "enabled": {
+ "type": "boolean",
+ "description": "是否启用。"
+ },
+ "provider": {
+ "description": "服务提供方。",
+ "$ref": "#/components/schemas/PlatformBillingDunningProvider"
+ },
+ "webhookUrl": {
+ "maxLength": 2048,
+ "minLength": 0,
+ "type": "string",
+ "description": "Webhook 地址。"
+ },
+ "secretRef": {
+ "maxLength": 300,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "密钥引用。"
+ },
+ "reminderTypes": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "description": "提醒类型列表。"
+ },
+ "reminderChannels": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "description": "提醒渠道列表。"
+ },
+ "minReminderLevel": {
+ "maximum": 20,
+ "minimum": 1,
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "description": "最低提醒级别。",
+ "format": "int32"
+ },
+ "tenantIds": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "description": "租户 ID 列表。"
+ },
+ "timeoutSeconds": {
+ "maximum": 60,
+ "minimum": 1,
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "description": "超时时长,单位为秒。",
+ "format": "int32"
+ },
+ "metadata": {
+ "description": "扩展元数据。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ },
+ "description": "新增或更新平台DunningChannel请求 DTO。"
+ },
+ "UpsertPlatformCrmConfigDto": {
+ "required": [
+ "tenantId"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "ID。",
+ "format": "uuid"
+ },
+ "tenantId": {
+ "type": "string",
+ "description": "租户 ID。",
+ "format": "uuid"
+ },
+ "enabled": {
+ "type": "boolean",
+ "description": "是否启用。"
+ },
+ "url": {
+ "maxLength": 2048,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "回调地址。"
+ },
+ "secretRef": {
+ "maxLength": 300,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "密钥引用。"
+ },
+ "formName": {
+ "maxLength": 200,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "表单名称。"
+ },
+ "examType": {
+ "maxLength": 100,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "考试类型。"
+ },
+ "timeoutSeconds": {
+ "maximum": 120,
+ "minimum": 1,
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "description": "超时时长,单位为秒。",
+ "format": "int32"
+ },
+ "delaySeconds": {
+ "maximum": 86400,
+ "minimum": 0,
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "description": "延迟秒数。",
+ "format": "int32"
+ },
+ "assignmentMode": {
+ "maxLength": 50,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "分配模式。"
+ },
+ "assignmentPool": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "description": "分配池。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ ]
+ },
+ "assignmentConfig": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "description": "分配配置。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ ]
+ }
+ },
+ "description": "新增或更新租户 CRM 配置请求。"
+ },
+ "UpsertPlatformPaymentAppDto": {
+ "required": [
+ "appCode",
+ "appName"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "ID。",
+ "format": "uuid"
+ },
+ "appCode": {
+ "maxLength": 100,
+ "minLength": 0,
+ "type": "string",
+ "description": "支付应用编码。"
+ },
+ "appName": {
+ "maxLength": 200,
+ "minLength": 0,
+ "type": "string",
+ "description": "支付应用名称。"
+ },
+ "status": {
+ "description": "状态。",
+ "$ref": "#/components/schemas/PlatformPaymentAppStatus"
+ },
+ "settlementMode": {
+ "maxLength": 100,
+ "minLength": 0,
+ "type": "string",
+ "description": "结算模式。"
+ },
+ "description": {
+ "maxLength": 500,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "说明。"
+ },
+ "metadata": {
+ "description": "扩展元数据。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ },
+ "description": "新增或更新平台支付应用请求。"
+ },
+ "UpsertPlatformPaymentChannelDto": {
+ "required": [
+ "appId",
+ "provider",
+ "displayName"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "ID。",
+ "format": "uuid"
+ },
+ "appId": {
+ "type": "string",
+ "description": "支付应用 ID。",
+ "format": "uuid"
+ },
+ "provider": {
+ "maxLength": 80,
+ "minLength": 0,
+ "type": "string",
+ "description": "服务提供方。"
+ },
+ "mode": {
+ "maxLength": 100,
+ "minLength": 0,
+ "type": "string",
+ "description": "模式。"
+ },
+ "status": {
+ "description": "状态。",
+ "$ref": "#/components/schemas/PlatformPaymentChannelStatus"
+ },
+ "displayName": {
+ "maxLength": 200,
+ "minLength": 0,
+ "type": "string",
+ "description": "显示名称。"
+ },
+ "secretRef": {
+ "maxLength": 300,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "密钥引用。"
+ },
+ "callbackPath": {
+ "maxLength": 500,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "回调路径。"
+ },
+ "priority": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "description": "优先级。",
+ "format": "int32"
+ },
+ "configPublic": {
+ "description": "公开配置内容。",
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "metadata": {
+ "description": "扩展元数据。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ },
+ "description": "新增或更新平台支付渠道请求。"
+ },
+ "UpsertPlatformQuestionBankCommand": {
+ "required": [
+ "id",
+ "name",
+ "metadata"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "name": {
+ "type": "string"
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ }
+ },
+ "UpsertPlatformQuestionBankNodeCommand": {
+ "required": [
+ "id",
+ "questionBankId",
+ "parentId",
+ "nodeKey",
+ "name",
+ "nodeType",
+ "sortOrder",
+ "isSelectable",
+ "metadata"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "questionBankId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "parentId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "nodeKey": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "name": {
+ "type": "string"
+ },
+ "nodeType": {
+ "$ref": "#/components/schemas/ContentNodeType"
+ },
+ "sortOrder": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "isSelectable": {
+ "type": "boolean"
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ }
+ },
+ "UpsertPlatformQuestionCommand": {
+ "required": [
+ "id",
+ "questionBankId",
+ "contentNodeId",
+ "legacyId",
+ "type",
+ "typeLabel",
+ "difficulty",
+ "tags",
+ "content",
+ "options",
+ "correctOptionIndex",
+ "correctOptionIndices",
+ "answerText",
+ "explanation",
+ "subQuestions",
+ "codeLang",
+ "codeTemplate",
+ "mediaUrl",
+ "status",
+ "examMarkers",
+ "sourceHash"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "questionBankId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "contentNodeId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "type": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "typeLabel": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "difficulty": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "tags": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "content": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "options": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "correctOptionIndex": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "correctOptionIndices": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "answerText": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "explanation": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "subQuestions": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "codeLang": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "codeTemplate": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "mediaUrl": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "status": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "examMarkers": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "sourceHash": {
+ "type": [
+ "null",
+ "string"
+ ]
+ }
+ }
+ },
+ "UpsertPlatformSmsChannelDto": {
+ "required": [
+ "tenantId",
+ "provider",
+ "name",
+ "signature",
+ "scene"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "ID。",
+ "format": "uuid"
+ },
+ "tenantId": {
+ "type": "string",
+ "description": "租户 ID。",
+ "format": "uuid"
+ },
+ "provider": {
+ "maxLength": 80,
+ "minLength": 0,
+ "type": "string",
+ "description": "服务提供方。"
+ },
+ "name": {
+ "maxLength": 200,
+ "minLength": 0,
+ "type": "string",
+ "description": "名称。"
+ },
+ "signature": {
+ "maxLength": 100,
+ "minLength": 0,
+ "type": "string",
+ "description": "短信签名。"
+ },
+ "scene": {
+ "maxLength": 100,
+ "minLength": 0,
+ "type": "string",
+ "description": "使用场景。"
+ },
+ "status": {
+ "description": "状态。",
+ "$ref": "#/components/schemas/TenantExternalProviderStatus"
+ },
+ "secretRef": {
+ "maxLength": 300,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "密钥引用。"
+ },
+ "priority": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "description": "优先级。",
+ "format": "int32"
+ },
+ "monthlyQuota": {
+ "maximum": 2147483647,
+ "minimum": 0,
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "description": "月度配额。",
+ "format": "int32"
+ },
+ "configPublic": {
+ "description": "公开配置内容。",
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "metadata": {
+ "description": "扩展元数据。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ },
+ "description": "新增或更新租户短信渠道请求。"
+ },
+ "UpsertPlatformSmsTemplateDto": {
+ "required": [
+ "tenantId",
+ "channelId",
+ "code",
+ "name",
+ "content"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "ID。",
+ "format": "uuid"
+ },
+ "tenantId": {
+ "type": "string",
+ "description": "租户 ID。",
+ "format": "uuid"
+ },
+ "channelId": {
+ "type": "string",
+ "description": "短信渠道 ID。",
+ "format": "uuid"
+ },
+ "code": {
+ "maxLength": 120,
+ "minLength": 0,
+ "type": "string",
+ "description": "编码。"
+ },
+ "name": {
+ "maxLength": 200,
+ "minLength": 0,
+ "type": "string",
+ "description": "名称。"
+ },
+ "type": {
+ "description": "类型。",
+ "$ref": "#/components/schemas/SmsTemplateType"
+ },
+ "auditStatus": {
+ "description": "审核状态。",
+ "$ref": "#/components/schemas/SmsTemplateAuditStatus"
+ },
+ "status": {
+ "description": "状态。",
+ "$ref": "#/components/schemas/SmsTemplateStatus"
+ },
+ "providerTemplateCode": {
+ "maxLength": 120,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "渠道模板编码。"
+ },
+ "content": {
+ "maxLength": 1000,
+ "minLength": 0,
+ "type": "string",
+ "description": "模板内容。"
+ },
+ "remark": {
+ "maxLength": 500,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "Remark。"
+ },
+ "metadata": {
+ "description": "扩展元数据。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ },
+ "description": "新增或更新租户短信模板请求。"
+ },
+ "UpsertPlatformStaffDto": {
+ "type": "object",
+ "properties": {
+ "userId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "用户 ID。",
+ "format": "uuid"
+ },
+ "email": {
+ "maxLength": 320,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "邮箱。"
+ },
+ "phone": {
+ "maxLength": 32,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "手机号。"
+ },
+ "name": {
+ "maxLength": 200,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "名称。"
+ },
+ "status": {
+ "description": "状态。",
+ "$ref": "#/components/schemas/UserStatus"
+ },
+ "roleIds": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "description": "角色 ID 列表。"
+ }
+ },
+ "description": "新增或更新平台Staff请求 DTO。"
+ },
+ "UpsertPlatformTenantBillingProfileDto": {
+ "required": [
+ "tenantId"
+ ],
+ "type": "object",
+ "properties": {
+ "tenantId": {
+ "type": "string",
+ "description": "租户 ID。",
+ "format": "uuid"
+ },
+ "billingName": {
+ "maxLength": 300,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "账务名称。"
+ },
+ "taxId": {
+ "maxLength": 100,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "税号。"
+ },
+ "contactName": {
+ "maxLength": 100,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "联系人姓名。"
+ },
+ "contactPhone": {
+ "maxLength": 32,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "联系人手机号。"
+ },
+ "contactEmail": {
+ "maxLength": 320,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "联系人邮箱。"
+ },
+ "billingAddress": {
+ "maxLength": 1000,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "账务地址。"
+ },
+ "invoiceTitle": {
+ "maxLength": 300,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "发票抬头。"
+ },
+ "invoiceType": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "description": "发票类型。",
+ "$ref": "#/components/schemas/TenantBillingInvoiceTitleType"
+ }
+ ]
+ },
+ "bankName": {
+ "maxLength": 300,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "开户银行。"
+ },
+ "bankAccountMasked": {
+ "maxLength": 100,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "脱敏银行账号。"
+ },
+ "metadata": {
+ "description": "扩展元数据。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ },
+ "description": "新增或更新平台租户账务资料请求 DTO。"
+ },
+ "UpsertPlatformTenantPaymentAppDto": {
+ "required": [
+ "tenantId",
+ "provider"
+ ],
+ "type": "object",
+ "properties": {
+ "tenantId": {
+ "type": "string",
+ "description": "租户 ID。",
+ "format": "uuid"
+ },
+ "provider": {
+ "maxLength": 80,
+ "minLength": 0,
+ "type": "string",
+ "description": "服务提供方。"
+ },
+ "status": {
+ "description": "状态。",
+ "$ref": "#/components/schemas/TenantExternalProviderStatus"
+ },
+ "displayName": {
+ "maxLength": 200,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "显示名称。"
+ },
+ "secretRef": {
+ "maxLength": 300,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "密钥引用。"
+ },
+ "priority": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "description": "优先级。",
+ "format": "int32"
+ },
+ "configPublic": {
+ "description": "公开配置内容。",
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "metadata": {
+ "description": "扩展元数据。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ },
+ "description": "新增或更新租户支付应用请求。"
+ },
+ "UpsertPointExchangeItemDto": {
+ "required": [
+ "itemKey",
+ "name"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "ID。",
+ "format": "uuid"
+ },
+ "regionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "地区 ID。",
+ "format": "uuid"
+ },
+ "itemKey": {
+ "maxLength": 100,
+ "minLength": 0,
+ "type": "string",
+ "description": "兑换项键。"
+ },
+ "name": {
+ "maxLength": 200,
+ "minLength": 0,
+ "type": "string",
+ "description": "名称。"
+ },
+ "description": {
+ "maxLength": 1000,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "说明。"
+ },
+ "itemType": {
+ "description": "兑换项类型。",
+ "$ref": "#/components/schemas/PointExchangeItemType"
+ },
+ "status": {
+ "description": "状态。",
+ "$ref": "#/components/schemas/PointExchangeItemStatus"
+ },
+ "pointsCost": {
+ "maximum": 2147483647,
+ "minimum": 1,
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "description": "所需积分。",
+ "format": "int32"
+ },
+ "stock": {
+ "maximum": 2147483647,
+ "minimum": 0,
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "description": "库存数量。",
+ "format": "int32"
+ },
+ "days": {
+ "maximum": 3650,
+ "minimum": 0,
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "description": "天数。",
+ "format": "int32"
+ },
+ "sortOrder": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "description": "排序值。",
+ "format": "int32"
+ },
+ "startsAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "开始时间。",
+ "format": "date-time"
+ },
+ "endsAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "结束时间。",
+ "format": "date-time"
+ },
+ "fulfillmentPayload": {
+ "description": "履约载荷。",
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "metadata": {
+ "description": "扩展元数据。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ },
+ "description": "新增或更新积分兑换Item请求 DTO。"
+ },
+ "UpsertPointTaskDto": {
+ "required": [
+ "taskKey",
+ "title"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "ID。",
+ "format": "uuid"
+ },
+ "taskKey": {
+ "maxLength": 100,
+ "minLength": 0,
+ "type": "string",
+ "description": "任务键。"
+ },
+ "title": {
+ "maxLength": 200,
+ "minLength": 0,
+ "type": "string",
+ "description": "标题。"
+ },
+ "description": {
+ "maxLength": 1000,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "说明。"
+ },
+ "taskType": {
+ "description": "任务类型。",
+ "$ref": "#/components/schemas/PointActivityTaskType"
+ },
+ "status": {
+ "description": "状态。",
+ "$ref": "#/components/schemas/PointActivityTaskStatus"
+ },
+ "points": {
+ "maximum": 2147483647,
+ "minimum": 1,
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "description": "积分数量。",
+ "format": "int32"
+ },
+ "maxClaimsPerUser": {
+ "maximum": 1000,
+ "minimum": 1,
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "description": "每用户最多领取次数。",
+ "format": "int32"
+ },
+ "startsAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "开始时间。",
+ "format": "date-time"
+ },
+ "endsAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "结束时间。",
+ "format": "date-time"
+ },
+ "sortOrder": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "description": "排序值。",
+ "format": "int32"
+ },
+ "rules": {
+ "description": "规则配置。",
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "metadata": {
+ "description": "扩展元数据。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ },
+ "description": "新增或更新积分任务请求 DTO。"
+ },
+ "UpsertPracticeBlueprintDto": {
+ "required": [
+ "name"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "ID。",
+ "format": "uuid"
+ },
+ "regionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "地区 ID。",
+ "format": "uuid"
+ },
+ "entryId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "内容入口 ID。",
+ "format": "uuid"
+ },
+ "nodeId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "节点 ID。",
+ "format": "uuid"
+ },
+ "collectionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "题集 ID。",
+ "format": "uuid"
+ },
+ "legacyId": {
+ "maxLength": 64,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "历史系统 ID。"
+ },
+ "name": {
+ "maxLength": 300,
+ "minLength": 0,
+ "type": "string",
+ "description": "名称。"
+ },
+ "mode": {
+ "maxLength": 50,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "模式。"
+ },
+ "assemblyType": {
+ "maxLength": 50,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "组卷方式。"
+ },
+ "questionLimit": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "description": "题目数量上限。",
+ "format": "int32"
+ },
+ "durationMinutes": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "description": "时长,单位为分钟。",
+ "format": "int32"
+ },
+ "totalScore": {
+ "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
+ "type": [
+ "null",
+ "number",
+ "string"
+ ],
+ "description": "总分。",
+ "format": "double"
+ },
+ "passScore": {
+ "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
+ "type": [
+ "null",
+ "number",
+ "string"
+ ],
+ "description": "及格分。",
+ "format": "double"
+ },
+ "sections": {
+ "description": "分段配置。",
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "rules": {
+ "description": "规则配置。",
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "accessRules": {
+ "description": "访问规则。",
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "status": {
+ "maxLength": 50,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "状态。"
+ },
+ "order": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "description": "显示顺序。",
+ "format": "int32"
+ }
+ },
+ "description": "新增或更新练习Blueprint请求 DTO。"
+ },
+ "UpsertQuestionCollectionDto": {
+ "required": [
+ "name"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "ID。",
+ "format": "uuid"
+ },
+ "regionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "地区 ID。",
+ "format": "uuid"
+ },
+ "entryId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "内容入口 ID。",
+ "format": "uuid"
+ },
+ "nodeId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "节点 ID。",
+ "format": "uuid"
+ },
+ "subjectId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "科目 ID。",
+ "format": "uuid"
+ },
+ "categoryId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "分类 ID。",
+ "format": "uuid"
+ },
+ "questionBankId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "题库 ID。",
+ "format": "uuid"
+ },
+ "legacyId": {
+ "maxLength": 64,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "历史系统 ID。"
+ },
+ "name": {
+ "maxLength": 300,
+ "minLength": 0,
+ "type": "string",
+ "description": "名称。"
+ },
+ "collectionType": {
+ "maxLength": 50,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "题集类型。"
+ },
+ "sourceType": {
+ "maxLength": 50,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "来源类型。"
+ },
+ "filters": {
+ "description": "筛选条件。",
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "totalScore": {
+ "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
+ "type": [
+ "null",
+ "number",
+ "string"
+ ],
+ "description": "总分。",
+ "format": "double"
+ },
+ "durationMinutes": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "description": "时长,单位为分钟。",
+ "format": "int32"
+ },
+ "status": {
+ "maxLength": 50,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "状态。"
+ },
+ "order": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "description": "显示顺序。",
+ "format": "int32"
+ },
+ "accessRules": {
+ "description": "访问规则。",
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "metadata": {
+ "description": "扩展元数据。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ },
+ "description": "新增或更新题目题集请求 DTO。"
+ },
+ "UpsertReferralTeamDto": {
+ "required": [
+ "memberUserId"
+ ],
+ "type": "object",
+ "properties": {
+ "memberUserId": {
+ "type": "string",
+ "description": "成员用户 ID。",
+ "format": "uuid"
+ },
+ "leaderUserId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "上级成员用户 ID。",
+ "format": "uuid"
+ },
+ "relationType": {
+ "maxLength": 50,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "关系类型。"
+ },
+ "status": {
+ "maxLength": 50,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "状态。"
+ },
+ "metadata": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "description": "扩展元数据。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ ]
+ }
+ },
+ "description": "新增或更新推荐团队请求 DTO。"
+ },
+ "UpsertSaasFeatureDto": {
+ "required": [
+ "id",
+ "code",
+ "name",
+ "category",
+ "description",
+ "referencePriceCents",
+ "currency",
+ "status",
+ "sortOrder"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "code": {
+ "type": "string"
+ },
+ "name": {
+ "type": "string"
+ },
+ "category": {
+ "type": "string"
+ },
+ "description": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "referencePriceCents": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "currency": {
+ "type": "string"
+ },
+ "status": {
+ "$ref": "#/components/schemas/SaasFeatureStatus"
+ },
+ "sortOrder": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ }
+ },
+ "description": "新增或更新SaaS功能请求 DTO。"
+ },
+ "UpsertSaasFeatureLimitDto": {
+ "required": [
+ "id",
+ "metricCode",
+ "featureCode",
+ "name",
+ "unit",
+ "kind",
+ "warningPercent",
+ "isHardLimit"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "metricCode": {
+ "type": "string"
+ },
+ "featureCode": {
+ "type": "string"
+ },
+ "name": {
+ "type": "string"
+ },
+ "unit": {
+ "type": "string"
+ },
+ "kind": {
+ "$ref": "#/components/schemas/SaasFeatureLimitKind"
+ },
+ "warningPercent": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "isHardLimit": {
+ "type": "boolean"
+ }
+ },
+ "description": "新增或更新 SaaS 功能额度定义。"
+ },
+ "UpsertSaasOfferingDto": {
+ "required": [
+ "id",
+ "code",
+ "name",
+ "type",
+ "status",
+ "description",
+ "sortOrder"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "code": {
+ "type": "string"
+ },
+ "name": {
+ "type": "string"
+ },
+ "type": {
+ "$ref": "#/components/schemas/SaasOfferingType"
+ },
+ "status": {
+ "$ref": "#/components/schemas/SaasOfferingStatus"
+ },
+ "description": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "sortOrder": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ }
+ },
+ "description": "新增或更新SaaS套餐请求 DTO。"
+ },
+ "UpsertSaasOfferingVersionDto": {
+ "required": [
+ "id",
+ "offeringId",
+ "billingCycle",
+ "originalAmountCents",
+ "amountCents",
+ "currency",
+ "effectiveAt",
+ "featureCodes",
+ "limits",
+ "metadata"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "offeringId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "billingCycle": {
+ "$ref": "#/components/schemas/PlatformBillingCycle"
+ },
+ "originalAmountCents": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "amountCents": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "currency": {
+ "type": "string"
+ },
+ "effectiveAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "featureCodes": {
+ "type": [
+ "null",
+ "array"
+ ],
+ "items": {
+ "type": "string"
+ }
+ },
+ "limits": {
+ "type": [
+ "null",
+ "object"
+ ],
+ "additionalProperties": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int64"
+ }
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ },
+ "description": "新增或更新SaaS套餐版本请求 DTO。"
+ },
+ "UpsertTenantAdminBadgeDto": {
+ "required": [
+ "name"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "ID。",
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "历史系统 ID。"
+ },
+ "name": {
+ "type": "string",
+ "description": "名称。"
+ },
+ "description": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "说明。"
+ },
+ "category": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "分类。"
+ },
+ "iconUrl": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "图标地址。"
+ },
+ "level": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "description": "级别。",
+ "format": "int32"
+ },
+ "unlockType": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "解锁类型。"
+ },
+ "conditionField": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "条件字段。"
+ },
+ "conditionOperator": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "条件运算符。"
+ },
+ "conditionValue": {
+ "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
+ "type": [
+ "null",
+ "number",
+ "string"
+ ],
+ "description": "条件值。",
+ "format": "double"
+ },
+ "conditionExtra": {
+ "description": "条件扩展配置。",
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "order": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "description": "显示顺序。",
+ "format": "int32"
+ },
+ "isActive": {
+ "type": [
+ "null",
+ "boolean"
+ ],
+ "description": "是否启用。"
+ }
+ },
+ "description": "新增或更新租户管理端徽章请求 DTO。"
+ },
+ "UpsertTenantAdminClassDto": {
+ "required": [
+ "name"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "ID。",
+ "format": "uuid"
+ },
+ "regionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "地区 ID。",
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "历史系统 ID。"
+ },
+ "code": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "编码。"
+ },
+ "name": {
+ "type": "string",
+ "description": "名称。"
+ },
+ "description": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "说明。"
+ },
+ "status": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "状态。"
+ },
+ "order": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "description": "显示顺序。",
+ "format": "int32"
+ },
+ "metadata": {
+ "description": "扩展元数据。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ },
+ "description": "新增或更新租户管理端班级请求 DTO。"
+ },
+ "UpsertTenantAdminClassMemberDto": {
+ "required": [
+ "classId"
+ ],
+ "type": "object",
+ "properties": {
+ "classId": {
+ "type": "string",
+ "description": "班级 ID。",
+ "format": "uuid"
+ },
+ "user": {
+ "description": "用户信息。",
+ "$ref": "#/components/schemas/TenantAdminUserLookupDto"
+ },
+ "memberType": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "成员类型。"
+ },
+ "status": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "状态。"
+ },
+ "metadata": {
+ "description": "扩展元数据。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ },
+ "description": "新增或更新租户管理端班级成员请求 DTO。"
+ },
+ "UpsertTenantAdminMemberDto": {
+ "type": "object",
+ "properties": {
+ "membershipId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "成员关系 ID。",
+ "format": "uuid"
+ },
+ "user": {
+ "description": "用户信息。",
+ "$ref": "#/components/schemas/TenantAdminUserLookupDto"
+ },
+ "role": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "角色。"
+ },
+ "status": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "状态。"
+ },
+ "primaryRole": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "主要角色。"
+ }
+ },
+ "description": "新增或更新租户管理端成员请求 DTO。"
+ },
+ "UpsertTenantAdminNotificationDto": {
+ "required": [
+ "userId",
+ "notificationType",
+ "title",
+ "message"
+ ],
+ "type": "object",
+ "properties": {
+ "userId": {
+ "type": "string",
+ "description": "用户 ID。",
+ "format": "uuid"
+ },
+ "notificationType": {
+ "type": "string",
+ "description": "通知类型。"
+ },
+ "severity": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "严重级别。"
+ },
+ "title": {
+ "type": "string",
+ "description": "标题。"
+ },
+ "message": {
+ "type": "string",
+ "description": "消息内容。"
+ },
+ "actionLabel": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "操作按钮文案。"
+ },
+ "actionPath": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "操作路径。"
+ },
+ "sourceType": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "来源类型。"
+ },
+ "sourceId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "来源 ID。",
+ "format": "uuid"
+ },
+ "dedupeKey": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "去重键。"
+ },
+ "metadata": {
+ "description": "扩展元数据。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ },
+ "description": "新增或更新租户管理端通知请求 DTO。"
+ },
+ "UpsertTenantAdminStudentDto": {
+ "type": "object",
+ "properties": {
+ "user": {
+ "description": "用户信息。",
+ "$ref": "#/components/schemas/TenantAdminUserLookupDto"
+ },
+ "regionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "地区 ID。",
+ "format": "uuid"
+ },
+ "selectedSchoolId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "已选择院校 ID。",
+ "format": "uuid"
+ },
+ "selectedMajorId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "已选择专业 ID。",
+ "format": "uuid"
+ },
+ "avatarPreset": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "头像预设。"
+ },
+ "stats": {
+ "description": "统计数据。",
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "progress": {
+ "description": "进度数据。",
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "moduleSelections": {
+ "description": "模块选择数据。",
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "rawProfile": {
+ "description": "原始用户资料。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ },
+ "description": "新增或更新租户管理端学生请求 DTO。"
+ },
+ "UpsertTenantAdminStudentFollowupDto": {
+ "required": [
+ "studentUserId",
+ "title"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "ID。",
+ "format": "uuid"
+ },
+ "studentUserId": {
+ "type": "string",
+ "description": "学生用户 ID。",
+ "format": "uuid"
+ },
+ "assignedToUserId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "分配处理人用户 ID。",
+ "format": "uuid"
+ },
+ "classId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "班级 ID。",
+ "format": "uuid"
+ },
+ "title": {
+ "type": "string",
+ "description": "标题。"
+ },
+ "description": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "说明。"
+ },
+ "followupType": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "跟进类型。"
+ },
+ "priority": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "优先级。"
+ },
+ "status": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "状态。"
+ },
+ "dueAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "到期时间。",
+ "format": "date-time"
+ },
+ "metadata": {
+ "description": "扩展元数据。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ },
+ "description": "新增或更新租户管理端学生跟进请求 DTO。"
+ },
+ "UpsertTenantAdminStudentNoteDto": {
+ "required": [
+ "studentUserId",
+ "content"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "ID。",
+ "format": "uuid"
+ },
+ "studentUserId": {
+ "type": "string",
+ "description": "学生用户 ID。",
+ "format": "uuid"
+ },
+ "noteType": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "备注类型。"
+ },
+ "content": {
+ "type": "string",
+ "description": "内容。"
+ },
+ "visibility": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "可见性。"
+ },
+ "isPinned": {
+ "type": [
+ "null",
+ "boolean"
+ ],
+ "description": "是否置顶。"
+ },
+ "metadata": {
+ "description": "扩展元数据。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ },
+ "description": "新增或更新租户管理端学生Note请求 DTO。"
+ },
+ "UpsertTenantBrandingDto": {
+ "required": [
+ "brandName"
+ ],
+ "type": "object",
+ "properties": {
+ "brandName": {
+ "type": "string",
+ "description": "品牌名称。"
+ },
+ "shortName": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "品牌简称。"
+ },
+ "slogan": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "品牌标语。"
+ },
+ "organizationName": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "机构名称。"
+ },
+ "logoUrl": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "Logo 地址。"
+ },
+ "faviconUrl": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "站点图标地址。"
+ },
+ "serviceWechat": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "客服微信。"
+ },
+ "serviceAccountName": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "客服账号名称。"
+ }
+ },
+ "description": "新增或更新租户品牌请求 DTO。"
+ },
+ "UpsertTenantCouponDto": {
+ "required": [
+ "code"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "ID。",
+ "format": "uuid"
+ },
+ "code": {
+ "maxLength": 100,
+ "minLength": 0,
+ "type": "string",
+ "description": "编码。"
+ },
+ "planId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "套餐 ID。",
+ "format": "uuid"
+ },
+ "discountType": {
+ "description": "优惠类型。",
+ "$ref": "#/components/schemas/DiscountType"
+ },
+ "discountValue": {
+ "maximum": 999999,
+ "minimum": 0.01,
+ "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
+ "type": [
+ "number",
+ "string"
+ ],
+ "description": "优惠值。",
+ "format": "double"
+ },
+ "validFrom": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "有效期开始时间。",
+ "format": "date-time"
+ },
+ "validTo": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "有效期结束时间。",
+ "format": "date-time"
+ },
+ "maxUses": {
+ "maximum": 2147483647,
+ "minimum": 1,
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "description": "最大使用次数。",
+ "format": "int32"
+ },
+ "source": {
+ "maxLength": 50,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "来源。"
+ },
+ "remark": {
+ "maxLength": 1000,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "备注。"
+ }
+ },
+ "description": "新增或更新租户优惠券请求 DTO。"
+ },
+ "UpsertTenantFeatureOverrideDto": {
+ "required": [
+ "tenantId",
+ "featureCode",
+ "mode",
+ "expiresAt",
+ "reason"
+ ],
+ "type": "object",
+ "properties": {
+ "tenantId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "featureCode": {
+ "type": "string"
+ },
+ "mode": {
+ "$ref": "#/components/schemas/TenantFeatureOverrideMode"
+ },
+ "expiresAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "reason": {
+ "type": "string"
+ }
+ },
+ "description": "新增或更新租户功能覆盖规则请求 DTO。"
+ },
+ "UpsertTenantIdentityProviderDto": {
+ "required": [
+ "provider"
+ ],
+ "type": "object",
+ "properties": {
+ "provider": {
+ "type": "string",
+ "description": "服务提供方。"
+ },
+ "status": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "状态。"
+ },
+ "displayName": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "显示名称。"
+ },
+ "secretRef": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "密钥引用。"
+ },
+ "priority": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "description": "优先级。",
+ "format": "int32"
+ },
+ "configPublic": {
+ "description": "公开配置内容。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ },
+ "description": "新增或更新租户身份源Provider请求 DTO。"
+ },
+ "UpsertTenantSecretDto": {
+ "required": [
+ "purpose",
+ "provider",
+ "secretKey"
+ ],
+ "type": "object",
+ "properties": {
+ "purpose": {
+ "maxLength": 80,
+ "minLength": 0,
+ "type": "string",
+ "description": "用途。"
+ },
+ "provider": {
+ "maxLength": 50,
+ "minLength": 0,
+ "type": "string",
+ "description": "服务提供方。"
+ },
+ "secretKey": {
+ "maxLength": 120,
+ "minLength": 0,
+ "type": "string",
+ "description": "密钥键。"
+ },
+ "secretRef": {
+ "maxLength": 300,
+ "minLength": 0,
+ "type": "string",
+ "description": "密钥引用。"
+ },
+ "status": {
+ "description": "状态。",
+ "$ref": "#/components/schemas/TenantSecretStatus"
+ },
+ "secretPayload": {
+ "description": "密钥载荷。",
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "expiresAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "过期时间。",
+ "format": "date-time"
+ }
+ },
+ "description": "新增或更新租户Secret请求 DTO。"
+ },
+ "UpsertTenantSettingsDto": {
+ "type": "object",
+ "properties": {
+ "featureFlags": {
+ "description": "前端功能开关。",
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "adminFeatureFlags": {
+ "description": "管理端功能开关。",
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "publicConfig": {
+ "description": "公开配置。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ },
+ "description": "新增或更新租户设置请求 DTO。"
+ },
+ "UpsertTenantSupervisionRuleDto": {
+ "required": [
+ "code",
+ "title"
+ ],
+ "type": "object",
+ "properties": {
+ "code": {
+ "maxLength": 100,
+ "minLength": 0,
+ "type": "string",
+ "description": "编码。"
+ },
+ "title": {
+ "maxLength": 200,
+ "minLength": 0,
+ "type": "string",
+ "description": "标题。"
+ },
+ "enabled": {
+ "type": "boolean",
+ "description": "是否启用。"
+ },
+ "daysWithoutCheckIn": {
+ "maximum": 3650,
+ "minimum": 0,
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "description": "未签到天数。",
+ "format": "int32"
+ },
+ "maxQuestionsAnsweredToday": {
+ "maximum": 2147483647,
+ "minimum": 0,
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "description": "当天最大答题数。",
+ "format": "int32"
+ },
+ "followupType": {
+ "maxLength": 50,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "跟进类型。"
+ },
+ "priority": {
+ "maxLength": 50,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "优先级。"
+ },
+ "metadata": {
+ "description": "扩展元数据。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ },
+ "description": "新增或更新租户督导规则请求 DTO。"
+ },
+ "UserStatus": {
+ "type": "integer"
+ },
+ "VideoExplanationCatalogItem": {
+ "required": [
+ "id",
+ "legacyId",
+ "subjectId",
+ "title",
+ "description",
+ "videoUrl",
+ "thumbnailUrl",
+ "durationSeconds",
+ "knowledgeTags",
+ "isGeneral",
+ "difficulty",
+ "order",
+ "isActive",
+ "metadata"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "subjectId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "title": {
+ "type": "string"
+ },
+ "description": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "videoUrl": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "thumbnailUrl": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "durationSeconds": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "knowledgeTags": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "isGeneral": {
+ "type": "boolean"
+ },
+ "difficulty": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "order": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "isActive": {
+ "type": "boolean"
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ }
+ },
+ "VideoManagementItem": {
+ "required": [
+ "id",
+ "subjectId",
+ "legacyId",
+ "title",
+ "description",
+ "videoUrl",
+ "thumbnailUrl",
+ "durationSeconds",
+ "knowledgeTags",
+ "isGeneral",
+ "difficulty",
+ "order",
+ "isActive",
+ "metadata"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "subjectId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "title": {
+ "type": "string"
+ },
+ "description": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "videoUrl": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "thumbnailUrl": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "durationSeconds": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "knowledgeTags": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "isGeneral": {
+ "type": "boolean"
+ },
+ "difficulty": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "order": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "isActive": {
+ "type": "boolean"
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ }
+ },
+ "VideoPlaybackItem": {
+ "required": [
+ "videoId",
+ "questionId",
+ "title",
+ "description",
+ "playUrl",
+ "thumbnailUrl",
+ "durationSeconds",
+ "progress",
+ "metadata"
+ ],
+ "type": "object",
+ "properties": {
+ "videoId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "questionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "title": {
+ "type": "string"
+ },
+ "description": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "playUrl": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "thumbnailUrl": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "durationSeconds": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "progress": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "$ref": "#/components/schemas/VideoProgressItem"
+ }
+ ]
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ }
+ },
+ "VideoPlayDto": {
+ "required": [
+ "videoId"
+ ],
+ "type": "object",
+ "properties": {
+ "videoId": {
+ "type": "string",
+ "description": "视频 ID。",
+ "format": "uuid"
+ },
+ "questionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "题目 ID。",
+ "format": "uuid"
+ }
+ },
+ "description": "视频Play请求 DTO。"
+ },
+ "VideoProgressDto": {
+ "required": [
+ "videoId"
+ ],
+ "type": "object",
+ "properties": {
+ "videoId": {
+ "type": "string",
+ "description": "视频 ID。",
+ "format": "uuid"
+ },
+ "questionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "题目 ID。",
+ "format": "uuid"
+ },
+ "positionSeconds": {
+ "maximum": 2147483647,
+ "minimum": 0,
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "description": "播放位置,单位为秒。",
+ "format": "int32"
+ },
+ "durationSeconds": {
+ "maximum": 2147483647,
+ "minimum": 0,
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "description": "时长,单位为秒。",
+ "format": "int32"
+ },
+ "watchedSeconds": {
+ "maximum": 2147483647,
+ "minimum": 0,
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "description": "已观看时长,单位为秒。",
+ "format": "int32"
+ },
+ "isCompleted": {
+ "type": [
+ "null",
+ "boolean"
+ ],
+ "description": "是否已完成。"
+ },
+ "metadata": {
+ "description": "扩展元数据。",
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ },
+ "description": "视频Progress请求 DTO。"
+ },
+ "VideoProgressItem": {
+ "required": [
+ "id",
+ "videoId",
+ "questionId",
+ "positionSeconds",
+ "durationSeconds",
+ "watchedSeconds",
+ "isCompleted",
+ "completedAt",
+ "lastPlayedAt",
+ "playCount",
+ "metadata"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "videoId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "questionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "positionSeconds": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "durationSeconds": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "watchedSeconds": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "isCompleted": {
+ "type": "boolean"
+ },
+ "completedAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "lastPlayedAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "playCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ }
+ },
+ "VocabularyUnit": {
+ "type": "object",
+ "properties": {
+ "regionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "entryId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "contentNodeId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "name": {
+ "type": "string"
+ },
+ "description": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "wordCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "sortOrder": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "isActive": {
+ "type": "boolean"
+ },
+ "sourceHash": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updatedAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "tenantId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ },
+ "VocabularyUnitCatalogItem": {
+ "required": [
+ "id",
+ "legacyId",
+ "regionId",
+ "entryId",
+ "contentNodeId",
+ "name",
+ "description",
+ "wordCount",
+ "order",
+ "metadata"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "regionId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "entryId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "contentNodeId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "name": {
+ "type": "string"
+ },
+ "description": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "wordCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "order": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ }
+ },
+ "VocabularyWord": {
+ "type": "object",
+ "properties": {
+ "unitId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "entryId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "contentNodeId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "word": {
+ "type": "string"
+ },
+ "phonetic": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "meaning": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "example": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "exampleTranslation": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "difficulty": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "tags": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "sortOrder": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "isActive": {
+ "type": "boolean"
+ },
+ "sourceHash": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updatedAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "tenantId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ },
+ "VocabularyWordCatalogItem": {
+ "required": [
+ "id",
+ "legacyId",
+ "unitId",
+ "entryId",
+ "contentNodeId",
+ "word",
+ "phonetic",
+ "meaning",
+ "example",
+ "exampleTranslation",
+ "difficulty",
+ "tags",
+ "order",
+ "metadata"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "legacyId": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "unitId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "entryId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "contentNodeId": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "uuid"
+ },
+ "word": {
+ "type": "string"
+ },
+ "phonetic": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "meaning": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "example": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "exampleTranslation": {
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ "difficulty": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "tags": {
+ "$ref": "#/components/schemas/JsonElement"
+ },
+ "order": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ }
+ },
+ "WordDueLevel": {
+ "type": "integer"
+ },
+ "WordProgressDto": {
+ "required": [
+ "wordId"
+ ],
+ "type": "object",
+ "properties": {
+ "wordId": {
+ "type": "string",
+ "description": "单词 ID。",
+ "format": "uuid"
+ },
+ "status": {
+ "maxLength": 50,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "状态。"
+ },
+ "correctDelta": {
+ "maximum": 100,
+ "minimum": 0,
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "description": "答对数量变化。",
+ "format": "int32"
+ },
+ "wrongDelta": {
+ "maximum": 100,
+ "minimum": 0,
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "null",
+ "integer",
+ "string"
+ ],
+ "description": "答错数量变化。",
+ "format": "int32"
+ },
+ "nextReviewAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "下次复习时间。",
+ "format": "date-time"
+ }
+ },
+ "description": "单词Progress请求 DTO。"
+ },
+ "WordProgressItem": {
+ "required": [
+ "wordId",
+ "status",
+ "correctCount",
+ "wrongCount",
+ "lastReviewAt",
+ "nextReviewAt",
+ "reviewCount",
+ "correctStreak",
+ "lastResult",
+ "dueLevel",
+ "metadata"
+ ],
+ "type": "object",
+ "properties": {
+ "wordId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "status": {
+ "$ref": "#/components/schemas/WordProgressStatus"
+ },
+ "correctCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "wrongCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "lastReviewAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "nextReviewAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "reviewCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "correctStreak": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "lastResult": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "$ref": "#/components/schemas/WordReviewResult"
+ }
+ ]
+ },
+ "dueLevel": {
+ "$ref": "#/components/schemas/WordDueLevel"
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ }
+ },
+ "WordProgressStatus": {
+ "type": "integer"
+ },
+ "WordReviewDto": {
+ "required": [
+ "wordId"
+ ],
+ "type": "object",
+ "properties": {
+ "wordId": {
+ "type": "string",
+ "description": "单词 ID。",
+ "format": "uuid"
+ },
+ "result": {
+ "maxLength": 50,
+ "minLength": 0,
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "结果。"
+ },
+ "nextReviewAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "description": "下次复习时间。",
+ "format": "date-time"
+ }
+ },
+ "description": "单词Review请求 DTO。"
+ },
+ "WordReviewPlan": {
+ "required": [
+ "items",
+ "nextAction"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/WordReviewPlanItem"
+ }
+ },
+ "nextAction": {
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ }
+ },
+ "WordReviewPlanItem": {
+ "required": [
+ "wordId",
+ "status",
+ "nextReviewAt",
+ "correctCount",
+ "wrongCount",
+ "dueLevel"
+ ],
+ "type": "object",
+ "properties": {
+ "wordId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "status": {
+ "$ref": "#/components/schemas/WordProgressStatus"
+ },
+ "nextReviewAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ },
+ "correctCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "wrongCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "dueLevel": {
+ "$ref": "#/components/schemas/WordDueLevel"
+ }
+ }
+ },
+ "WordReviewResult": {
+ "type": "integer"
+ },
+ "WordStatsItem": {
+ "required": [
+ "total",
+ "newCount",
+ "learningCount",
+ "reviewingCount",
+ "masteredCount",
+ "dueCount",
+ "favoriteCount"
+ ],
+ "type": "object",
+ "properties": {
+ "total": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "newCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "learningCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "reviewingCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "masteredCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "dueCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "favoriteCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ }
+ }
+ },
+ "WrongQuestionItem": {
+ "required": [
+ "questionReferenceId",
+ "locator",
+ "wrongCount",
+ "lastWrongAt",
+ "resolvedAt"
+ ],
+ "type": "object",
+ "properties": {
+ "questionReferenceId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "locator": {
+ "$ref": "#/components/schemas/QuestionLocator"
+ },
+ "wrongCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "lastWrongAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "resolvedAt": {
+ "type": [
+ "null",
+ "string"
+ ],
+ "format": "date-time"
+ }
+ }
+ },
+ "WrongQuestionReviewPlan": {
+ "required": [
+ "items",
+ "nextAction"
+ ],
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/WrongQuestionReviewPlanItem"
+ }
+ },
+ "nextAction": {
+ "$ref": "#/components/schemas/JsonElement"
+ }
+ }
+ },
+ "WrongQuestionReviewPlanItem": {
+ "required": [
+ "questionReferenceId",
+ "locator",
+ "wrongCount",
+ "lastWrongAt"
+ ],
+ "type": "object",
+ "properties": {
+ "questionReferenceId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "locator": {
+ "$ref": "#/components/schemas/QuestionLocator"
+ },
+ "wrongCount": {
+ "pattern": "^-?(?:0|[1-9]\\d*)$",
+ "type": [
+ "integer",
+ "string"
+ ],
+ "format": "int32"
+ },
+ "lastWrongAt": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+ }
+} as const;
diff --git a/Tiku.PlatformAdmin.Web/src/api/platform.ts b/Tiku.PlatformAdmin.Web/src/api/platform.ts
new file mode 100644
index 0000000..53fb214
--- /dev/null
+++ b/Tiku.PlatformAdmin.Web/src/api/platform.ts
@@ -0,0 +1,13 @@
+import { apiRequest } from './http';
+import { platformOperations } from './platform-operations.generated';
+import type { HttpMethod, OperationInput, PlatformOperation } from './types';
+
+export function platformOperation(method: HttpMethod, path: string): PlatformOperation {
+ const operation = platformOperations.find((item) => item.method === method && item.path === path);
+ if (!operation) throw new Error(`平台接口契约缺失:${method} ${path}`);
+ return operation;
+}
+
+export function platformRequest(method: HttpMethod, path: string, input: OperationInput = {}, signal?: AbortSignal) {
+ return apiRequest(platformOperation(method, path), input, signal);
+}
diff --git a/Tiku.PlatformAdmin.Web/src/api/schema-utils.ts b/Tiku.PlatformAdmin.Web/src/api/schema-utils.ts
new file mode 100644
index 0000000..d00df49
--- /dev/null
+++ b/Tiku.PlatformAdmin.Web/src/api/schema-utils.ts
@@ -0,0 +1,37 @@
+import { openApiSchemas } from './platform-operations.generated';
+import type { JsonSchema } from './types';
+
+const schemas = openApiSchemas as unknown as Record;
+
+export function resolveSchema(schema: JsonSchema | null | undefined, seen = new Set()): JsonSchema {
+ if (!schema) return {};
+ if (schema.$ref) {
+ const name = schema.$ref.split('/').at(-1) || '';
+ if (seen.has(name)) return { type: 'object', description: schema.description };
+ const nextSeen = new Set(seen).add(name);
+ return { ...resolveSchema(schemas[name], nextSeen), description: schema.description || schemas[name]?.description };
+ }
+ const alternatives = schema.oneOf || schema.anyOf;
+ if (alternatives?.length) {
+ const meaningful = alternatives.find((item) => item.type !== 'null') || alternatives[0];
+ return { ...schema, ...resolveSchema(meaningful, seen), oneOf: undefined, anyOf: undefined };
+ }
+ return schema;
+}
+
+export function schemaType(schema: JsonSchema): string {
+ const type = resolveSchema(schema).type;
+ if (Array.isArray(type)) return type.find((item) => item !== 'null') || 'string';
+ return typeof type === 'string' ? type : 'string';
+}
+
+export function defaultForSchema(schema: JsonSchema): unknown {
+ const resolved = resolveSchema(schema);
+ if (resolved.default !== undefined) return resolved.default;
+ switch (schemaType(resolved)) {
+ case 'boolean': return false;
+ case 'array': return [];
+ case 'object': return {};
+ default: return undefined;
+ }
+}
diff --git a/Tiku.PlatformAdmin.Web/src/api/schema.generated.d.ts b/Tiku.PlatformAdmin.Web/src/api/schema.generated.d.ts
new file mode 100644
index 0000000..ca8f388
--- /dev/null
+++ b/Tiku.PlatformAdmin.Web/src/api/schema.generated.d.ts
@@ -0,0 +1,26144 @@
+/**
+ * This file was auto-generated by openapi-typescript.
+ * Do not make direct changes to the file.
+ */
+
+export interface paths {
+ "/api/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/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/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/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/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/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/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/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/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/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/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/backoffice/tenant/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/browser-auth/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/browser-auth/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/browser-auth/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/browser-auth/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/browser-auth/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/browser-auth/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/browser-auth/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/browser-auth/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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;
+ };
+ "/api/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/platform-admin/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-admin/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?: never;
+ 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-admin/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-admin/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?: never;
+ 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"]["PlatformTenantItem"];
+ };
+ };
+ };
+ };
+ trace?: never;
+ };
+ "/api/platform-admin/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/platform-admin/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-admin/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-admin/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-admin/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-admin/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-admin/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-admin/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-admin/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-admin/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-admin/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-admin/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-admin/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/backoffice/platform/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/backoffice/platform/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/backoffice/platform/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/backoffice/platform/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/backoffice/platform/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/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-admin/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-admin/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?: never;
+ 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"]["PlatformPaymentChannel"];
+ };
+ };
+ };
+ };
+ post?: never;
+ delete?: never;
+ options?: never;
+ head?: never;
+ patch?: never;
+ trace?: never;
+ };
+ "/api/platform-admin/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-admin/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-admin/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-admin/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-admin/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-admin/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-admin/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-admin/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-admin/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-admin/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-admin/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-admin/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-admin/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-admin/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-admin/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-admin/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-admin/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-admin/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-admin/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-admin/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-admin/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-admin/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-admin/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-admin/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-admin/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-admin/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-admin/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;
+ post?: never;
+ delete?: never;
+ options?: never;
+ head?: never;
+ patch?: never;
+ trace?: never;
+ };
+ "/api/platform-admin/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-admin/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-admin/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-admin/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-admin/saas/payments/manual/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"]["ConfirmManualPlatformPaymentDto"];
+ "text/json": components["schemas"]["ConfirmManualPlatformPaymentDto"];
+ "application/*+json": components["schemas"]["ConfirmManualPlatformPaymentDto"];
+ };
+ };
+ responses: {
+ /** @description OK */
+ 200: {
+ headers: {
+ [name: string]: unknown;
+ };
+ content: {
+ "text/plain": components["schemas"]["PlatformBillingPayment"];
+ "application/json": components["schemas"]["PlatformBillingPayment"];
+ "text/json": components["schemas"]["PlatformBillingPayment"];
+ };
+ };
+ };
+ };
+ delete?: never;
+ options?: never;
+ head?: never;
+ patch?: never;
+ trace?: never;
+ };
+ "/api/platform-admin/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-admin/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-admin/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-admin/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-admin/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-admin/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-admin/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-admin/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-admin/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-admin/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-admin/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-admin/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-admin/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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-admin/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-admin/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-admin/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-admin/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-admin/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-admin/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-admin/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-admin/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-admin/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-admin/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-admin/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-admin/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-admin/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-admin/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-admin/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-admin/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-admin/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-admin/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-admin/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-admin/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-admin/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-admin/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-admin/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-admin/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-admin/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-admin/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-admin/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-admin/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-admin/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-admin/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-admin/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-admin/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-admin/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-admin/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-admin/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/backoffice/tenant/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/backoffice/tenant/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/backoffice/tenant/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/backoffice/tenant/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/backoffice/tenant/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}": {
+ 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-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/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-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/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/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-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/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/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/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/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-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/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/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/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/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-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/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-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-admin/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-admin/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-admin/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-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/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/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/tenants/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/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/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/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;
+ };
+}
+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"][];
+ };
+ 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;
+ selectedOptions: components["schemas"]["JsonElement"];
+ answerText: null | string;
+ isCorrect: null | boolean;
+ /** Format: date-time */
+ answeredAt: 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 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;
+ /** @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;
+ 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;
+ 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"];
+ };
+ 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 变更租户订阅请求 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 */
+ tenantId?: string;
+ /** 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 */
+ 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 */
+ tenantId?: string;
+ /** 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 */
+ id?: string;
+ };
+ CommerceReconciliationItem: {
+ /** Format: uuid */
+ tenantId?: string;
+ /** 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 */
+ id?: string;
+ };
+ CommerceRefundEvent: {
+ /** Format: uuid */
+ tenantId?: string;
+ /** 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 */
+ 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;
+ 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 确认人工平台支付请求 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 创建编码批次请求 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 租户负责人邮箱。 */
+ ownerEmail?: null | string;
+ /** @description 租户负责人手机号。 */
+ ownerPhone?: null | string;
+ /** @description 租户负责人姓名。 */
+ ownerName: string;
+ /** @description 临时密码。 */
+ temporaryPassword: 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"];
+ };
+ 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"][];
+ };
+ 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"];
+ };
+ /** @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;
+ };
+ PaymentNotificationProcessResult: {
+ provider: string;
+ eventId: string;
+ orderNo: string;
+ status: string;
+ idempotent: boolean;
+ };
+ PlatformAlertSeverity: 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 */
+ tenantId?: string;
+ /** Format: uuid */
+ paymentId?: string;
+ provider?: string;
+ providerEventId?: string;
+ eventType?: string;
+ payload?: components["schemas"]["JsonElement"];
+ /** Format: date-time */
+ createdAt?: 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;
+ /** Format: date-time */
+ createdAt?: string;
+ /** Format: date-time */
+ updatedAt?: string;
+ /** Format: uuid */
+ tenantId?: string;
+ /** Format: uuid */
+ id?: string;
+ };
+ PlatformBillingRefundStatus: 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;
+ };
+ 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;
+ };
+ 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;
+ };
+ 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"];
+ };
+ 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;
+ };
+ 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;
+ };
+ 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;
+ 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: 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"];
+ explanation: null | string;
+ };
+ 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;
+ sectionStats: components["schemas"]["JsonElement"];
+ questionResults: components["schemas"]["JsonElement"];
+ wrongQuestionIds: components["schemas"]["JsonElement"];
+ metadata: components["schemas"]["JsonElement"];
+ };
+ /** @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"][];
+ };
+ /** @description 替换角色权限绑定请求。 */
+ ReplaceRoleBindingsDto: {
+ /** @description 权限编码列表。 */
+ permissionCodes?: string[];
+ /** @description 菜单编码列表。 */
+ menuCodes?: string[];
+ };
+ /** @description 替换用户角色请求。 */
+ ReplaceUserRolesDto: {
+ /** @description 角色 ID 列表。 */
+ roleIds?: string[];
+ };
+ ReportPriority: number;
+ ReportStatus: number;
+ ReportType: number;
+ /** @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 解析推荐请求 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;
+ };
+ 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;
+ /** @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;
+ };
+ /** @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 */
+ tenantId?: string;
+ /** 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 */
+ 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;
+ /** @description 已选选项。 */
+ selectedOptions?: null | string[];
+ /** @description 文字答案。 */
+ answerText?: null | string;
+ /** @description 主观题自评是否正确。 */
+ selfJudgedCorrect?: null | boolean;
+ };
+ /** @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;
+ };
+ 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;
+ };
+ TenantBillingCatalog: {
+ features: components["schemas"]["SaasFeature"][];
+ basePlans: components["schemas"]["SaasOfferingVersionItem"][];
+ addOns: components["schemas"]["SaasOfferingVersionItem"][];
+ };
+ TenantBillingInvoiceTitleType: number;
+ 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;
+ };
+ /** @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;
+ };
+ 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"][];
+ };
+ 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;
+ 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"];
+ };
+ /** @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 账务状态。 */
+ billingStatus?: components["schemas"]["BillingStatus"];
+ /** @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"];
+ };
+ /** @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 新增或更新租户品牌请求 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/Tiku.PlatformAdmin.Web/src/api/token-store.ts b/Tiku.PlatformAdmin.Web/src/api/token-store.ts
new file mode 100644
index 0000000..4d85e9c
--- /dev/null
+++ b/Tiku.PlatformAdmin.Web/src/api/token-store.ts
@@ -0,0 +1,28 @@
+export interface TokenPair {
+ accessToken: string;
+ refreshToken: string;
+ accessTokenExpiresAt: string;
+ refreshTokenExpiresAt: string;
+}
+
+const storageKey = 'tiku.platform-admin.tokens';
+let currentTokens: TokenPair | null = readTokens();
+
+function readTokens(): TokenPair | null {
+ try {
+ const raw = localStorage.getItem(storageKey);
+ return raw ? (JSON.parse(raw) as TokenPair) : null;
+ } catch {
+ return null;
+ }
+}
+
+export const tokenStore = {
+ get: () => currentTokens,
+ set(tokens: TokenPair | null) {
+ currentTokens = tokens;
+ if (tokens) localStorage.setItem(storageKey, JSON.stringify(tokens));
+ else localStorage.removeItem(storageKey);
+ window.dispatchEvent(new CustomEvent('platform-auth-change'));
+ },
+};
diff --git a/Tiku.PlatformAdmin.Web/src/api/types.ts b/Tiku.PlatformAdmin.Web/src/api/types.ts
new file mode 100644
index 0000000..d7240bd
--- /dev/null
+++ b/Tiku.PlatformAdmin.Web/src/api/types.ts
@@ -0,0 +1,43 @@
+export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
+
+export interface JsonSchema {
+ [key: string]: unknown;
+ $ref?: string;
+ type?: string | readonly string[];
+ format?: string;
+ description?: string;
+ default?: unknown;
+ enum?: readonly unknown[];
+ oneOf?: readonly JsonSchema[];
+ anyOf?: readonly JsonSchema[];
+ items?: JsonSchema;
+ properties?: Readonly>;
+ required?: readonly string[];
+ minimum?: number;
+ maximum?: number;
+ minLength?: number;
+ maxLength?: number;
+ pattern?: string;
+}
+
+export interface OpenApiParameter {
+ name: string;
+ in: 'path' | 'query' | 'header';
+ required?: boolean;
+ description?: string;
+ schema?: JsonSchema;
+}
+
+export interface PlatformOperation {
+ id: string;
+ method: HttpMethod;
+ path: string;
+ tag: string;
+ summary: string;
+ description: string;
+ parameters: readonly OpenApiParameter[];
+ requestSchema: JsonSchema | null;
+ responseSchema: JsonSchema | null;
+}
+
+export type OperationInput = Record;
diff --git a/Tiku.PlatformAdmin.Web/src/auth/AuthProvider.tsx b/Tiku.PlatformAdmin.Web/src/auth/AuthProvider.tsx
new file mode 100644
index 0000000..e5a2acb
--- /dev/null
+++ b/Tiku.PlatformAdmin.Web/src/auth/AuthProvider.tsx
@@ -0,0 +1,106 @@
+import { createContext, useCallback, useContext, useEffect, useMemo, useState, type PropsWithChildren } from 'react';
+import { authRequest, getCurrentUser } from '../api/http';
+import { tokenStore, type TokenPair } from '../api/token-store';
+import type { components } from '../api/schema.generated';
+
+type AuthenticationResult = components['schemas']['AuthenticationResultDto'];
+type CurrentUser = components['schemas']['MeResponse'];
+const platformRealm = 1;
+
+interface AuthContextValue {
+ loading: boolean;
+ user: CurrentUser | null;
+ challengeToken: string | null;
+ login(identifier: string, password: string): Promise;
+ completePasswordChange(password: string): Promise;
+ logout(): Promise;
+}
+
+const AuthContext = createContext(null);
+
+function tokensFrom(result: AuthenticationResult): TokenPair | null {
+ const tokens = result.user?.tokens;
+ return tokens?.accessToken && tokens.refreshToken ? (tokens as TokenPair) : null;
+}
+
+export function AuthProvider({ children }: PropsWithChildren) {
+ const [loading, setLoading] = useState(Boolean(tokenStore.get()));
+ const [user, setUser] = useState(null);
+ const [challengeToken, setChallengeToken] = useState(null);
+
+ const loadUser = useCallback(async () => {
+ if (!tokenStore.get()) {
+ setUser(null);
+ setLoading(false);
+ return;
+ }
+ try {
+ setUser(await getCurrentUser());
+ } catch {
+ tokenStore.set(null);
+ setUser(null);
+ } finally {
+ setLoading(false);
+ }
+ }, []);
+
+ useEffect(() => { void loadUser(); }, [loadUser]);
+
+ const applyAuthentication = useCallback(async (result: AuthenticationResult) => {
+ const tokens = tokensFrom(result);
+ if (tokens) {
+ tokenStore.set(tokens);
+ setChallengeToken(null);
+ setLoading(true);
+ await loadUser();
+ return;
+ }
+ if (result.challengeToken) {
+ setChallengeToken(result.challengeToken);
+ return;
+ }
+ throw new Error('认证响应中没有登录令牌或密码变更挑战');
+ }, [loadUser]);
+
+ const value = useMemo(() => ({
+ loading,
+ user,
+ challengeToken,
+ async login(identifier, password) {
+ const result = await authRequest('/api/auth/login/password', {
+ realm: platformRealm,
+ tenantCode: null,
+ identifier,
+ phone: null,
+ password,
+ });
+ await applyAuthentication(result);
+ },
+ async completePasswordChange(password) {
+ if (!challengeToken) throw new Error('密码变更挑战已失效,请重新登录');
+ const result = await authRequest('/api/auth/password/change-required', {
+ challengeToken,
+ newPassword: password,
+ });
+ await applyAuthentication(result);
+ },
+ async logout() {
+ const refreshToken = tokenStore.get()?.refreshToken;
+ try {
+ if (refreshToken) await authRequest('/api/auth/logout', { refreshToken });
+ } finally {
+ tokenStore.set(null);
+ setUser(null);
+ setChallengeToken(null);
+ }
+ },
+ }), [applyAuthentication, challengeToken, loading, user]);
+
+ return {children};
+}
+
+export function useAuth() {
+ const value = useContext(AuthContext);
+ if (!value) throw new Error('useAuth 必须在 AuthProvider 内使用');
+ return value;
+}
diff --git a/Tiku.PlatformAdmin.Web/src/components/BusinessTable.tsx b/Tiku.PlatformAdmin.Web/src/components/BusinessTable.tsx
new file mode 100644
index 0000000..3660823
--- /dev/null
+++ b/Tiku.PlatformAdmin.Web/src/components/BusinessTable.tsx
@@ -0,0 +1,45 @@
+import { Table, Tag, Typography } from 'antd';
+
+const labels: Record = {
+ id: '编号', tenantId: '租户', name: '名称', code: '编码', slug: '短编码', host: '域名', status: '状态', billingStatus: '账务状态',
+ createdAt: '创建时间', updatedAt: '更新时间', expiresAt: '到期时间', dueAt: '到期时间', amountCents: '金额', totalAmountCents: '金额',
+ balanceCents: '余额', phone: '手机号', email: '邮箱', ownerName: '负责人', provider: '服务商', enabled: '启用', appName: '应用名称',
+ appCode: '应用代码', title: '标题', summary: '摘要', action: '动作', targetType: '目标类型', targetId: '目标编号', severity: '级别',
+ version: '版本', billingCycle: '计费周期', effectiveAt: '生效时间', questionCount: '题目数', nodeType: '节点类型', sortOrder: '排序',
+};
+
+function isScalar(value: unknown) { return value == null || ['string', 'number', 'boolean'].includes(typeof value); }
+function cell(value: unknown, key: string) {
+ if (value === null || value === undefined || value === '') return '-';
+ if (typeof value === 'boolean') return {value ? '是' : '否'};
+ if (/status|severity/i.test(key)) return {String(value)};
+ if (/Cents$/.test(key) && typeof value === 'number') return `¥${(value / 100).toLocaleString('zh-CN', { minimumFractionDigits: 2 })}`;
+ return {String(value)};
+}
+
+export function rowsFromPayload(payload: unknown): Record[] {
+ if (Array.isArray(payload)) return payload.filter((item) => item && typeof item === 'object') as Record[];
+ if (!payload || typeof payload !== 'object') return [];
+ const object = payload as Record;
+ for (const key of ['items', 'data', 'results', 'tenants', 'domains', 'staff', 'alerts', 'logs']) {
+ if (Array.isArray(object[key])) return object[key] as Record[];
+ }
+ return [object];
+}
+
+export function BusinessTable({ payload, loading, onSelect }: { payload: unknown; loading: boolean; onSelect(record: Record | null): void }) {
+ const rows = rowsFromPayload(payload);
+ const keys = [...new Set(rows.flatMap((row) => Object.keys(row).filter((key) => isScalar(row[key]))))].slice(0, 9);
+ return (
+ String(row.id || row.tenantId || row.code || index)}
+ rowSelection={{ type: 'radio', onChange: (_, selected) => onSelect(selected[0] || null) }}
+ scroll={{ x: 'max-content' }}
+ pagination={{ pageSize: 20, showSizeChanger: true, showTotal: (total) => `共 ${total} 条` }}
+ locale={{ emptyText: '暂无业务数据' }}
+ columns={keys.map((key) => ({ title: labels[key] || key, dataIndex: key, key, ellipsis: true, render: (value) => cell(value, key) }))}
+ />
+ );
+}
diff --git a/Tiku.PlatformAdmin.Web/src/components/OperationForm.tsx b/Tiku.PlatformAdmin.Web/src/components/OperationForm.tsx
new file mode 100644
index 0000000..4fe0252
--- /dev/null
+++ b/Tiku.PlatformAdmin.Web/src/components/OperationForm.tsx
@@ -0,0 +1,61 @@
+import { Form, Input } from 'antd';
+import { SchemaFields } from './SchemaFields';
+import { resolveSchema, schemaType } from '../api/schema-utils';
+import type { JsonSchema, OperationInput, PlatformOperation } from '../api/types';
+
+function parseJsonFields(target: Record, schema: JsonSchema) {
+ const resolved = resolveSchema(schema);
+ for (const [name, propertySchema] of Object.entries(resolved.properties || {})) {
+ const value = target[name];
+ const type = schemaType(propertySchema);
+ if ((type === 'object' || type === 'array') && typeof value === 'string' && value.trim()) {
+ try {
+ target[name] = JSON.parse(value);
+ } catch {
+ throw new Error(`${propertySchema.description || name} 必须是有效 JSON`);
+ }
+ }
+ }
+}
+
+export function normalizeOperationInput(operation: PlatformOperation, values: OperationInput): OperationInput {
+ const input = structuredClone(values);
+ if (input.body && typeof input.body === 'object' && operation.requestSchema) {
+ parseJsonFields(input.body as Record, operation.requestSchema);
+ }
+ return input;
+}
+
+export function OperationForm({ operation }: { operation: PlatformOperation }) {
+ const pathParameters = operation.parameters.filter((item) => item.in === 'path');
+ const queryParameters = operation.parameters.filter((item) => item.in === 'query');
+ const bodySchema = resolveSchema(operation.requestSchema);
+ return (
+ <>
+ {pathParameters.map((parameter) => (
+
+
+
+ ))}
+ {queryParameters.length > 0 && (
+ item.required).map((item) => item.name)}
+ schema={{
+ type: 'object',
+ properties: Object.fromEntries(queryParameters.map((item) => [item.name, { ...item.schema, description: item.description || item.name }])),
+ }}
+ />
+ )}
+ {operation.requestSchema && schemaType(bodySchema) === 'object' && (
+
+ )}
+ >
+ );
+}
diff --git a/Tiku.PlatformAdmin.Web/src/components/ResponseView.tsx b/Tiku.PlatformAdmin.Web/src/components/ResponseView.tsx
new file mode 100644
index 0000000..e45baed
--- /dev/null
+++ b/Tiku.PlatformAdmin.Web/src/components/ResponseView.tsx
@@ -0,0 +1,54 @@
+import { Descriptions, Empty, Table, Tag, Typography } from 'antd';
+
+function scalar(value: unknown) {
+ if (value === null || value === undefined) return '-';
+ if (typeof value === 'boolean') return value ? 是 : 否;
+ if (typeof value === 'object') return {JSON.stringify(value)};
+ return String(value);
+}
+
+function rowsFrom(payload: unknown): Record[] | null {
+ if (Array.isArray(payload)) return payload.filter((item) => item && typeof item === 'object') as Record[];
+ if (!payload || typeof payload !== 'object') return null;
+ const object = payload as Record;
+ for (const key of ['items', 'data', 'results']) {
+ if (Array.isArray(object[key])) return object[key] as Record[];
+ }
+ return null;
+}
+
+export function ResponseView({ payload }: { payload: unknown }) {
+ if (payload === undefined) return ;
+ if (payload === null) return ;
+ const rows = rowsFrom(payload);
+ if (rows) {
+ if (!rows.length) return ;
+ const keys = [...new Set(rows.flatMap((row) => Object.keys(row)))].slice(0, 8);
+ return (
+ String(row.id || row.code || row.userId || index)}
+ dataSource={rows}
+ scroll={{ x: 'max-content' }}
+ pagination={{ pageSize: 20, showSizeChanger: true }}
+ columns={keys.map((key) => ({
+ title: key,
+ dataIndex: key,
+ key,
+ ellipsis: true,
+ render: scalar,
+ }))}
+ />
+ );
+ }
+ if (typeof payload === 'object') {
+ return (
+
+ {Object.entries(payload as Record).map(([key, value]) => (
+ {scalar(value)}
+ ))}
+
+ );
+ }
+ return {String(payload)};
+}
diff --git a/Tiku.PlatformAdmin.Web/src/components/SchemaFields.tsx b/Tiku.PlatformAdmin.Web/src/components/SchemaFields.tsx
new file mode 100644
index 0000000..c2c63b1
--- /dev/null
+++ b/Tiku.PlatformAdmin.Web/src/components/SchemaFields.tsx
@@ -0,0 +1,55 @@
+import { Form, Input, InputNumber, Select, Switch } from 'antd';
+import type { NamePath } from 'antd/es/form/interface';
+import { defaultForSchema, resolveSchema, schemaType } from '../api/schema-utils';
+import type { JsonSchema } from '../api/types';
+
+interface SchemaFieldsProps {
+ schema: JsonSchema;
+ prefix: NamePath;
+ required?: readonly string[];
+}
+
+function fieldName(prefix: NamePath, name: string): NamePath {
+ return [...(Array.isArray(prefix) ? prefix : [prefix]), name];
+}
+
+export function SchemaFields({ schema, prefix, required = [] }: SchemaFieldsProps) {
+ const resolved = resolveSchema(schema);
+ const properties = resolved.properties || {};
+ return Object.entries(properties).map(([name, propertySchema]) => {
+ const property = resolveSchema(propertySchema);
+ const type = schemaType(property);
+ const label = property.description || name;
+ const isRequired = required.includes(name);
+ const rules = isRequired ? [{ required: true, message: `请填写${label}` }] : undefined;
+ let control = ;
+
+ if (property.enum?.length) {
+ control =