问题原因: - 租户管理页面调用 /api/v1/admin/packages/all 获取课程包 - 但 CoursePackage 实体没有 price 和 discountPrice 字段 - 这些字段在 CourseCollection(课程套餐)实体中 后端修改: - AdminCourseCollectionController 新增 GET /all 接口 - 返回已发布的课程套餐列表(含价格信息) - 添加 @Slf4j 注解和必要导入 前端修改: - src/api/admin.ts 修改 API 调用路径为 /collections/all - 修改返回类型为 CourseCollectionResponse[] - TenantListView.vue 修改 packageList 类型 - 修复 formatPackagePrice 处理 undefined 值 - 修复 handlePackageTypeChange 类型检查 数据库迁移: - 添加 V38 脚本为 course_collection 表添加自增主键 其他修改: - .gitignore 移除 *.sql 排除规则(允许迁移脚本) - CourseCollectionRejectRequest 和 CourseRejectRequest 用于审核驳回 修复的 TypeScript 错误: - formatPackagePrice 参数改为可选类型 - selectedPackage.name 添加可选链操作符
68 lines
2.1 KiB
TypeScript
68 lines
2.1 KiB
TypeScript
import { defineConfig } from 'orval';
|
||
|
||
/** 内联 schema,避免 ResultObject[] 的 $ref 导致 oneOf 验证错误 */
|
||
const RESULT_OBJECT_ARRAY_SCHEMA = {
|
||
type: 'object',
|
||
properties: {
|
||
code: { type: 'integer', format: 'int32' },
|
||
message: { type: 'string' },
|
||
data: { type: 'array', items: { type: 'object', additionalProperties: true } },
|
||
},
|
||
};
|
||
|
||
export default defineConfig({
|
||
readingPlatform: {
|
||
output: {
|
||
mode: 'split',
|
||
target: 'src/api/generated/index.ts',
|
||
schemas: 'src/api/generated/model',
|
||
client: 'axios',
|
||
override: {
|
||
mutator: {
|
||
path: 'src/api/generated/mutator.ts',
|
||
name: 'customMutator',
|
||
},
|
||
// 自定义类型名称
|
||
name: (type) => {
|
||
// 移除命名空间前缀,简化类型名称
|
||
return type.replace(/^(Result|ResultPageResult)/, '');
|
||
},
|
||
},
|
||
// 导入优化
|
||
imports: {
|
||
axios: true,
|
||
},
|
||
},
|
||
input: {
|
||
// 使用 api:fetch 生成的 openapi.json(api:update 会自动先执行 api:fetch)
|
||
target: './openapi.json',
|
||
// 路径重写:确保 OpenAPI 文档中的路径正确
|
||
override: {
|
||
// 使用转换器修复路径 - 将 `/api/v1/xxx` 转换为 `/v1/xxx`(因为 baseURL 已经是 `/api`)
|
||
transformer: (spec) => {
|
||
const paths = spec.paths || {};
|
||
for (const path of Object.keys(paths)) {
|
||
let newKey = path.replace(/^\/api\/v1\//, '/v1/');
|
||
if (newKey !== path) {
|
||
paths[newKey] = paths[path];
|
||
delete paths[path];
|
||
}
|
||
}
|
||
for (const pathObj of Object.values(paths)) {
|
||
for (const op of Object.values(pathObj)) {
|
||
const content = op?.responses?.['200']?.content;
|
||
if (!content) continue;
|
||
for (const media of Object.values(content)) {
|
||
if (media?.schema?.['$ref']?.endsWith('ResultObject[]')) {
|
||
media.schema = { ...RESULT_OBJECT_ARRAY_SCHEMA };
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return spec;
|
||
},
|
||
},
|
||
},
|
||
},
|
||
});
|