From c3b1056c2931f6ef342f31728582ea4952a527e6 Mon Sep 17 00:00:00 2001 From: En Date: Thu, 19 Mar 2026 23:28:40 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E7=A7=9F=E6=88=B7=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E4=B8=8E=E8=AF=BE=E7=A8=8B=E5=A5=97=E9=A4=90=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 优化租户管理相关接口与实体类 - 更新课程套餐服务层实现 - 新增数据库迁移脚本 V42 - 同步更新前端 API 类型与页面组件 --- .claude/CLAUDE.md | 35 +++- reading-platform-frontend/openapi.json | 40 +++- reading-platform-frontend/src/api/admin.ts | 9 +- reading-platform-frontend/src/api/course.ts | 2 + .../src/api/generated/index.ts | 2 +- .../generated/model/getSchoolCoursesParams.ts | 4 + reading-platform-frontend/src/api/package.ts | 1 + .../src/api/school-course.ts | 13 +- reading-platform-frontend/src/api/school.ts | 11 + .../collections/CollectionDetailView.vue | 15 +- .../admin/collections/CollectionEditView.vue | 98 ++++++++- .../admin/collections/CollectionListView.vue | 13 ++ .../views/admin/courses/CourseListView.vue | 18 +- .../admin/packages/PackageDetailView.vue | 13 ++ .../views/admin/packages/PackageEditView.vue | 86 +++++++- .../views/admin/packages/PackageListView.vue | 61 ++++-- .../views/admin/tenants/TenantListView.vue | 167 ++++++++------- .../views/school/courses/CourseListView.vue | 64 +++++- .../platform/common/enums/ErrorCode.java | 1 + .../platform/common/enums/TenantStatus.java | 8 +- .../security/JwtAuthenticationFilter.java | 4 +- .../AdminCourseCollectionController.java | 3 +- .../admin/AdminCourseController.java | 6 +- .../admin/AdminTenantController.java | 33 ++- .../school/SchoolCourseController.java | 23 +- .../CourseCollectionPageQueryRequest.java | 3 + .../dto/request/CoursePageQueryRequest.java | 3 + .../dto/request/TenantCreateRequest.java | 7 +- .../dto/request/TenantUpdateRequest.java | 5 +- .../platform/dto/response/TenantResponse.java | 5 +- .../com/reading/platform/entity/Tenant.java | 3 - .../service/CourseCollectionService.java | 2 +- .../service/CoursePackageService.java | 2 +- .../platform/service/TenantService.java | 5 + .../service/impl/AuthServiceImpl.java | 15 +- .../impl/CourseCollectionServiceImpl.java | 66 +++++- .../impl/CoursePackageServiceImpl.java | 20 +- .../service/impl/TenantServiceImpl.java | 196 +++++++++++------- .../V42__drop_tenant_package_type.sql | 11 + 39 files changed, 827 insertions(+), 246 deletions(-) create mode 100644 reading-platform-java/src/main/resources/db/migration/V42__drop_tenant_package_type.sql diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md index e478ebb..c30293e 100644 --- a/.claude/CLAUDE.md +++ b/.claude/CLAUDE.md @@ -8,14 +8,35 @@ ### 服务端口配置 -| 服务 | 端口 | 说明 | -|------|------|------| -| 后端 API | **8480** | Spring Boot 服务(已修改) | -| 前端 Dev Server | 5173 | Vite 开发服务器 | -| 数据库 MySQL | 3306 | 开发环境数据库 | -| Redis | 6379 | 缓存服务 | +| 服务 | 默认端口 | 测试验证端口 | 说明 | +|------|---------|------------|------| +| 后端 API | **8480** | **8481** | Spring Boot 服务 | +| 前端 Dev Server | 5173 | 5174 | Vite 开发服务器 | +| 数据库 MySQL | 3306 | 3306 | 开发环境数据库 | +| Redis | 6379 | 6379 | 缓存服务 | -**重要**: 后端服务已从默认的 8080 端口改为 **8480 端口**。 +**重要**: +- 日常开发使用默认端口 **8480** 和 **5173** +- **每次测试验证时启动通过变量启动后端 8481 和前端 5174 (重要),不要占用 8480 和 5173 端口** + +### 测试验证环境启动方式 + +```bash +# 启动测试验证环境(后端 8481 + 前端 5174) +# 方式一:使用环境变量 +export SERVER_PORT=8481 +export VITE_APP_PORT=5174 +./start-all.sh + +# 方式二:分别启动 +# 后端(端口 8481) +export SERVER_PORT=8481 +cd reading-platform-java && mvn spring-boot:run + +# 前端(端口 5174,新终端) +export PORT=5174 +cd reading-platform-frontend && npm run dev +``` ### 启动服务 diff --git a/reading-platform-frontend/openapi.json b/reading-platform-frontend/openapi.json index d94f130..a442865 100644 --- a/reading-platform-frontend/openapi.json +++ b/reading-platform-frontend/openapi.json @@ -22283,9 +22283,29 @@ "tags": [ "学校端 - 课程管理" ], - "summary": "获取学校课程包列表", + "summary": "获取学校课程包列表(分页)", "operationId": "getSchoolCourses", "parameters": [ + { + "name": "pageNum", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "format": "int32", + "default": 1 + } + }, + { + "name": "pageSize", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "format": "int32", + "default": 10 + } + }, { "name": "keyword", "in": "query", @@ -22301,6 +22321,22 @@ "schema": { "type": "string" } + }, + { + "name": "domain", + "in": "query", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "lessonType", + "in": "query", + "required": false, + "schema": { + "type": "string" + } } ], "responses": { @@ -22309,7 +22345,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/ResultListCoursePackage" + "$ref": "#/components/schemas/ResultPageResultCourseResponse" } } } diff --git a/reading-platform-frontend/src/api/admin.ts b/reading-platform-frontend/src/api/admin.ts index 932dde2..db1eaf0 100644 --- a/reading-platform-frontend/src/api/admin.ts +++ b/reading-platform-frontend/src/api/admin.ts @@ -10,7 +10,7 @@ export interface TenantQueryParams { pageSize?: number; keyword?: string; status?: string; - packageType?: string; + collectionId?: number; } export interface Tenant { @@ -22,7 +22,7 @@ export interface Tenant { contactPerson?: string; contactPhone?: string; logoUrl?: string; - packageType: string; + packageNames?: string[]; teacherQuota: number; studentQuota: number; storageQuota?: number; @@ -73,8 +73,7 @@ export interface CreateTenantDto { address?: string; contactPerson?: string; contactPhone?: string; - packageType?: string; - packageId?: number; + collectionIds?: number[]; teacherQuota?: number; studentQuota?: number; startDate?: string; @@ -86,7 +85,7 @@ export interface UpdateTenantDto { address?: string; contactPerson?: string; contactPhone?: string; - packageType?: string; + collectionIds?: number[]; teacherQuota?: number; studentQuota?: number; startDate?: string; diff --git a/reading-platform-frontend/src/api/course.ts b/reading-platform-frontend/src/api/course.ts index 707e9c2..b80e386 100644 --- a/reading-platform-frontend/src/api/course.ts +++ b/reading-platform-frontend/src/api/course.ts @@ -18,6 +18,7 @@ export interface CourseQueryParams { pageNum?: number; pageSize?: number; grade?: string; + gradeTags?: string; // 年级筛选(逗号分隔,如 "小班,中班,大班") status?: string; keyword?: string; /** 审核管理页专用:仅返回待审核和已驳回,排除已通过 */ @@ -125,6 +126,7 @@ const toFindAllParams = (params: CourseQueryParams): any => ({ pageSize: params.pageSize ?? 10, keyword: params.keyword, category: params.grade, + gradeTags: params.gradeTags, // 年级筛选(逗号分隔) status: params.status || undefined, reviewOnly: params.reviewOnly, }); diff --git a/reading-platform-frontend/src/api/generated/index.ts b/reading-platform-frontend/src/api/generated/index.ts index 0eb2dc6..921d6e7 100644 --- a/reading-platform-frontend/src/api/generated/index.ts +++ b/reading-platform-frontend/src/api/generated/index.ts @@ -3391,7 +3391,7 @@ const exportGrowthRecords = ( } /** - * @summary 获取学校课程包列表 + * @summary 获取学校课程包列表(分页) */ const getSchoolCourses = ( params?: GetSchoolCoursesParams, diff --git a/reading-platform-frontend/src/api/generated/model/getSchoolCoursesParams.ts b/reading-platform-frontend/src/api/generated/model/getSchoolCoursesParams.ts index 5810a23..7287e3b 100644 --- a/reading-platform-frontend/src/api/generated/model/getSchoolCoursesParams.ts +++ b/reading-platform-frontend/src/api/generated/model/getSchoolCoursesParams.ts @@ -7,6 +7,10 @@ */ export type GetSchoolCoursesParams = { +pageNum?: number; +pageSize?: number; keyword?: string; grade?: string; +domain?: string; +lessonType?: string; }; diff --git a/reading-platform-frontend/src/api/package.ts b/reading-platform-frontend/src/api/package.ts index 575a0e4..394f774 100644 --- a/reading-platform-frontend/src/api/package.ts +++ b/reading-platform-frontend/src/api/package.ts @@ -89,6 +89,7 @@ export interface CourseLesson { export interface PackageListParams { status?: string; + gradeLevels?: string; // 逗号分隔的年级列表,如 "小班,中班,大班" pageNum?: number; pageSize?: number; } diff --git a/reading-platform-frontend/src/api/school-course.ts b/reading-platform-frontend/src/api/school-course.ts index e68f9a6..bd28d0c 100644 --- a/reading-platform-frontend/src/api/school-course.ts +++ b/reading-platform-frontend/src/api/school-course.ts @@ -111,9 +111,16 @@ const api = getReadingPlatformAPI(); // ==================== 学校端 API ==================== -// 获取校本课程包列表 -export function getSchoolCourseList() { - return api.getSchoolCourses() as any; +// 获取校本课程包列表(分页) +export function getSchoolCourseList(params?: { + pageNum?: number; + pageSize?: number; + keyword?: string; + grade?: string; + domain?: string; + lessonType?: string; +}) { + return api.getSchoolCourses(params) as any; } // 获取校本课程包详情 diff --git a/reading-platform-frontend/src/api/school.ts b/reading-platform-frontend/src/api/school.ts index dcff2c8..ae54440 100644 --- a/reading-platform-frontend/src/api/school.ts +++ b/reading-platform-frontend/src/api/school.ts @@ -412,6 +412,17 @@ export interface SchoolCourseQueryParams { export const getSchoolCourses = (params?: SchoolCourseQueryParams) => http.get('/v1/school/courses', { params }); +// 分页版本(用于课程管理页面) +export const getSchoolCourseList = (params?: { + pageNum?: number; + pageSize?: number; + keyword?: string; + grade?: string; + domain?: string; + lessonType?: string; +}) => + http.get<{ list: Course[]; total: number; pageNum: number; pageSize: number; pages: number }>('/v1/school/courses', { params }); + export const getSchoolCourse = (id: number) => http.get(`/v1/school/courses/${id}`); diff --git a/reading-platform-frontend/src/views/admin/collections/CollectionDetailView.vue b/reading-platform-frontend/src/views/admin/collections/CollectionDetailView.vue index 68e56c8..1515906 100644 --- a/reading-platform-frontend/src/views/admin/collections/CollectionDetailView.vue +++ b/reading-platform-frontend/src/views/admin/collections/CollectionDetailView.vue @@ -57,8 +57,10 @@ {{ getStatusText(collection.status) }} {{ formatPrice(collection.price) }} - {{ formatPrice(collection.discountPrice) }} - {{ collection.discountType || '-' }} + + {{ formatPrice(collection.discountPrice) }} + + {{ getDiscountTypeText(collection.discountType) }} {{ grade }} - @@ -206,6 +208,15 @@ const getStatusText = (status: string) => { return collectionsApi.getCollectionStatusInfo(status).label; }; +const getDiscountTypeText = (type?: string) => { + if (!type) return '-'; + const typeMap: Record = { + PERCENTAGE: '折扣', + FIXED: '立减', + }; + return typeMap[type] || type; +}; + // 删除套餐 const handleDelete = async () => { try { diff --git a/reading-platform-frontend/src/views/admin/collections/CollectionEditView.vue b/reading-platform-frontend/src/views/admin/collections/CollectionEditView.vue index 6d2f96f..941a864 100644 --- a/reading-platform-frontend/src/views/admin/collections/CollectionEditView.vue +++ b/reading-platform-frontend/src/views/admin/collections/CollectionEditView.vue @@ -16,18 +16,29 @@ - - + + - - + + + + + {{ getDiscountPriceHint() }} + + - - - 百分比 - 固定金额 + + + 折扣 + 立减 @@ -176,6 +187,54 @@ const parseGradeTags = (tags: string | string[]) => { } }; +// 获取折扣价格输入框的 placeholder +const getDiscountPricePlaceholder = () => { + if (!formState.value.discountType) return '请先选择优惠类型'; + if (formState.value.discountType === 'PERCENTAGE') return '请输入折扣率(0-100)'; + if (formState.value.discountType === 'FIXED') return '请输入立减金额'; + return ''; +}; + +// 获取折扣价格提示文本 +const getDiscountPriceHint = () => { + if (!formState.value.discountType || !formState.value.price) return ''; + if (formState.value.discountType === 'PERCENTAGE') { + if (formState.value.discountPrice !== undefined && formState.value.discountPrice !== null) { + const finalPrice = formState.value.price * (1 - (formState.value.discountPrice / 100)); + if (finalPrice < 0) { + return '折后价不能小于 0'; + } + return `折后价:¥${finalPrice.toFixed(2)}`; + } + return '按百分比减免'; + } + if (formState.value.discountType === 'FIXED') { + if (formState.value.discountPrice !== undefined && formState.value.discountPrice !== null) { + const finalPrice = formState.value.price - formState.value.discountPrice; + if (finalPrice < 0) { + return '立减金额超过原价'; + } + return `折后价:¥${finalPrice.toFixed(2)}`; + } + return '按固定金额减免'; + } + return ''; +}; + +// 获取折扣价格提示文本的颜色 +const getDiscountPriceHintColor = () => { + if (!formState.value.discountType || !formState.value.price || !formState.value.discountPrice) return '#666'; + if (formState.value.discountType === 'PERCENTAGE') { + const finalPrice = formState.value.price * (1 - (formState.value.discountPrice / 100)); + return finalPrice < 0 ? 'red' : '#666'; + } + if (formState.value.discountType === 'FIXED') { + const finalPrice = formState.value.price - formState.value.discountPrice; + return finalPrice < 0 ? 'red' : '#666'; + } + return '#666'; +}; + const fetchCollectionDetail = async () => { if (!isEdit.value) return; @@ -246,6 +305,23 @@ const handleSubmit = async () => { // 手动触发表单校验 await formRef.value.validate(); + // 校验折扣价格逻辑:折扣减免后价格不能小于 0 + if (formState.value.discountPrice !== undefined && formState.value.discountPrice !== null) { + if (formState.value.discountType === 'PERCENTAGE') { + // 折扣类型:折扣率应该是 0-100 之间的数值 + if (formState.value.discountPrice < 0 || formState.value.discountPrice > 100) { + message.error('折扣率应该在 0-100 之间'); + return; + } + } else if (formState.value.discountType === 'FIXED') { + // 立减类型:立减金额不能超过原价 + if (formState.value.discountPrice > formState.value.price) { + message.error('立减金额不能超过原价'); + return; + } + } + } + loading.value = true; const data = { name: formState.value.name, @@ -310,4 +386,10 @@ onMounted(() => { .package-list { width: 100%; } + +.discount-hint { + color: #666; + font-size: 12px; + margin-left: 8px; +} diff --git a/reading-platform-frontend/src/views/admin/collections/CollectionListView.vue b/reading-platform-frontend/src/views/admin/collections/CollectionListView.vue index c5e1a0a..88625ac 100644 --- a/reading-platform-frontend/src/views/admin/collections/CollectionListView.vue +++ b/reading-platform-frontend/src/views/admin/collections/CollectionListView.vue @@ -32,6 +32,9 @@ + @@ -135,6 +138,7 @@ const columns = [ { title: '套餐名称', dataIndex: 'name', key: 'name' }, { title: '价格', dataIndex: 'price', key: 'price', width: 100 }, { title: '优惠价', dataIndex: 'discountPrice', key: 'discountPrice', width: 100 }, + { title: '折扣类型', dataIndex: 'discountType', key: 'discountType', width: 100 }, { title: '适用年级', dataIndex: 'gradeLevels', key: 'gradeLevels', width: 150 }, { title: '课程包数量', dataIndex: 'packageCount', key: 'packageCount', width: 100 }, { title: '状态', dataIndex: 'status', key: 'status', width: 100 }, @@ -145,6 +149,15 @@ const getStatusColor = (status: string) => collectionsApi.getCollectionStatusInf const getStatusText = (status: string) => collectionsApi.getCollectionStatusInfo(status).label; const formatPrice = (price: number | null | undefined) => collectionsApi.formatPrice(price); +const getDiscountTypeText = (type?: string) => { + if (!type) return '-'; + const typeMap: Record = { + PERCENTAGE: '折扣', + FIXED: '立减', + }; + return typeMap[type] || type; +}; + const parseGradeLevels = (gradeLevels: string | string[]) => { return collectionsApi.parseGradeLevels(gradeLevels); }; diff --git a/reading-platform-frontend/src/views/admin/courses/CourseListView.vue b/reading-platform-frontend/src/views/admin/courses/CourseListView.vue index 95567c2..10bef41 100644 --- a/reading-platform-frontend/src/views/admin/courses/CourseListView.vue +++ b/reading-platform-frontend/src/views/admin/courses/CourseListView.vue @@ -4,11 +4,11 @@ - - 小班 - 中班 - 大班 + + 小班 + 中班 + 大班 ([]); const pendingCount = ref(0); const filters = reactive({ - grade: undefined, - status: undefined, + gradeTags: undefined as string[] | undefined, + status: undefined as string | undefined, keyword: '', }); @@ -244,7 +244,9 @@ const fetchCourses = async () => { const data = await courseApi.getCourses({ pageNum: pagination.current, pageSize: pagination.pageSize, - ...filters, + gradeTags: filters.gradeTags?.join(','), // 转为逗号分隔字符串 + status: filters.status, + keyword: filters.keyword, }); console.log('📡 课程列表 API 响应:', data); diff --git a/reading-platform-frontend/src/views/admin/packages/PackageDetailView.vue b/reading-platform-frontend/src/views/admin/packages/PackageDetailView.vue index de66ec4..56c2bde 100644 --- a/reading-platform-frontend/src/views/admin/packages/PackageDetailView.vue +++ b/reading-platform-frontend/src/views/admin/packages/PackageDetailView.vue @@ -49,6 +49,9 @@ {{ pkg?.discountPrice ? '¥' + (pkg.discountPrice / 100).toFixed(2) : '-' }} + + {{ getDiscountTypeText(pkg?.discountType) }} + {{ grade }} @@ -125,6 +128,16 @@ const statusTexts: Record = { const getStatusColor = (status: string) => statusColors[status] || 'default'; const getStatusText = (status: string) => statusTexts[status] || status; +const discountTypeTexts: Record = { + PERCENTAGE: '折扣', + FIXED: '立减', +}; + +const getDiscountTypeText = (type?: string) => { + if (!type) return '-'; + return discountTypeTexts[type] || type; +}; + const formatDate = (date?: string) => { if (!date) return '-'; return new Date(date).toLocaleString(); diff --git a/reading-platform-frontend/src/views/admin/packages/PackageEditView.vue b/reading-platform-frontend/src/views/admin/packages/PackageEditView.vue index 275219b..e424ac6 100644 --- a/reading-platform-frontend/src/views/admin/packages/PackageEditView.vue +++ b/reading-platform-frontend/src/views/admin/packages/PackageEditView.vue @@ -28,12 +28,23 @@ - + + + + {{ getDiscountPriceHint() }} + + - 折扣 + 折扣 立减 @@ -186,6 +197,54 @@ const parseGradeTags = (tags: string | string[]) => { } }; +// 获取折扣价格输入框的 placeholder +const getDiscountPricePlaceholder = () => { + if (!form.discountType) return '请先选择优惠类型'; + if (form.discountType === 'PERCENTAGE') return '请输入折扣率(0-100)'; + if (form.discountType === 'FIXED') return '请输入立减金额'; + return ''; +}; + +// 获取折扣价格提示文本 +const getDiscountPriceHint = () => { + if (!form.discountType || !form.price) return ''; + if (form.discountType === 'PERCENTAGE') { + if (form.discountPrice !== undefined && form.discountPrice !== null) { + const finalPrice = form.price * (1 - (form.discountPrice / 100)); + if (finalPrice < 0) { + return '折后价不能小于 0'; + } + return `折后价:¥${finalPrice.toFixed(2)}`; + } + return '按百分比减免'; + } + if (form.discountType === 'FIXED') { + if (form.discountPrice !== undefined && form.discountPrice !== null) { + const finalPrice = form.price - form.discountPrice; + if (finalPrice < 0) { + return '立减金额超过原价'; + } + return `折后价:¥${finalPrice.toFixed(2)}`; + } + return '按固定金额减免'; + } + return ''; +}; + +// 获取折扣价格提示文本的颜色 +const getDiscountPriceHintColor = () => { + if (!form.discountType || !form.price || !form.discountPrice) return '#666'; + if (form.discountType === 'PERCENTAGE') { + const finalPrice = form.price * (1 - (form.discountPrice / 100)); + return finalPrice < 0 ? 'red' : '#666'; + } + if (form.discountType === 'FIXED') { + const finalPrice = form.price - form.discountPrice; + return finalPrice < 0 ? 'red' : '#666'; + } + return '#666'; +}; + // 从已选课程包同步适用年级到表单(年级列只读,从课程包数据读取) const syncGradeLevelsFromPackages = () => { const grades = [...new Set(selectedPackages.value.flatMap((p) => p.gradeLevels || []).filter(Boolean))]; @@ -261,6 +320,23 @@ const handleSave = async () => { // 手动触发表单校验 await formRef.value.validate(); + // 校验折扣价格逻辑:折扣减免后价格不能小于 0 + if (form.discountPrice !== undefined && form.discountPrice !== null) { + if (form.discountType === 'PERCENTAGE') { + // 折扣类型:折扣率应该是 0-100 之间的数值 + if (form.discountPrice < 0 || form.discountPrice > 100) { + message.error('折扣率应该在 0-100 之间'); + return; + } + } else if (form.discountType === 'FIXED') { + // 立减类型:立减金额不能超过原价 + if (form.discountPrice > form.price) { + message.error('立减金额不能超过原价'); + return; + } + } + } + saving.value = true; const data = { name: form.name, @@ -326,4 +402,10 @@ onMounted(() => { font-size: 12px; margin-top: 4px; } + +.discount-hint { + color: #666; + font-size: 12px; + margin-left: 8px; +} diff --git a/reading-platform-frontend/src/views/admin/packages/PackageListView.vue b/reading-platform-frontend/src/views/admin/packages/PackageListView.vue index 8ed0dc6..462d19b 100644 --- a/reading-platform-frontend/src/views/admin/packages/PackageListView.vue +++ b/reading-platform-frontend/src/views/admin/packages/PackageListView.vue @@ -19,20 +19,34 @@
- - 草稿 - 待审核 - 已通过 - 已拒绝 - 已发布 - 已下架 - + + + 草稿 + 待审核 + 已通过 + 已拒绝 + 已发布 + 已下架 + + + 小班 + 中班 + 大班 + +
@@ -48,6 +62,12 @@ + + @@ -131,6 +151,7 @@ const dataSource = ref([]); const pendingCount = ref(0); const filters = reactive({ status: undefined as string | undefined, + gradeLevels: undefined as string[] | undefined, }); const pagination = reactive({ current: 1, @@ -142,6 +163,8 @@ const columns = [ { title: 'ID', dataIndex: 'id', key: 'id', width: 80 }, { title: '套餐名称', dataIndex: 'name', key: 'name' }, { title: '价格', dataIndex: 'price', key: 'price', width: 100 }, + { title: '优惠价', dataIndex: 'discountPrice', key: 'discountPrice', width: 100 }, + { title: '折扣类型', dataIndex: 'discountType', key: 'discountType', width: 100 }, { title: '适用年级', dataIndex: 'gradeLevels', key: 'gradeLevels', width: 150 }, { title: '课程包数', dataIndex: 'packageCount', key: 'packageCount', width: 80 }, { title: '状态', dataIndex: 'status', key: 'status', width: 100 }, @@ -169,6 +192,15 @@ const statusTexts: Record = { const getStatusColor = (status: string) => statusColors[status] || 'default'; const getStatusText = (status: string) => statusTexts[status] || status; +const getDiscountTypeText = (type?: string) => { + if (!type) return '-'; + const typeMap: Record = { + PERCENTAGE: '折扣', + FIXED: '立减', + }; + return typeMap[type] || type; +}; + const parseGradeLevels = (gradeLevels: string | string[] | undefined): string[] => { if (!gradeLevels) return []; if (Array.isArray(gradeLevels)) { @@ -194,6 +226,7 @@ const fetchData = async () => { try { const res = await getCollectionList({ status: filters.status, + gradeLevels: filters.gradeLevels?.join(','), pageNum: pagination.current, pageSize: pagination.pageSize, }) as any; diff --git a/reading-platform-frontend/src/views/admin/tenants/TenantListView.vue b/reading-platform-frontend/src/views/admin/tenants/TenantListView.vue index b340865..dddcde0 100644 --- a/reading-platform-frontend/src/views/admin/tenants/TenantListView.vue +++ b/reading-platform-frontend/src/views/admin/tenants/TenantListView.vue @@ -16,11 +16,19 @@
- - 基础版 - 标准版 - 高级版 - 定制版 + + + {{ pkg.name }} + @@ -54,9 +62,16 @@