Browse Source

✨ feat(advertisements): 增强广告模块数据验证规则

- 为所有字段添加更详细的自定义错误提示信息
- 优化positionId验证规则,确保其为正整数
- 改进linkUrl验证规则,提供更友好的格式错误提示
- 完善title字段验证,增加非空和长度限制提示
- 增强sortOrder验证,明确非负整数要求
- 优化isEnabled和isDeleted状态字段验证,限定只能为0或1
- 为imageFileId、createdBy和updatedBy添加正整数验证提示
- 为分页查询参数添加正整数验证和错误提示
yourname 4 tháng trước cách đây
mục cha
commit
b611e22838

+ 31 - 31
src/server/modules/advertisements/advertisement.schema.ts

@@ -2,44 +2,44 @@ import { z } from '@hono/zod-openapi';
 
 
 // 基础广告Schema
 // 基础广告Schema
 export const AdvertisementSchema = z.object({
 export const AdvertisementSchema = z.object({
-  id: z.number().int().positive().openapi({
+  id: z.number().int().positive('广告ID必须是正整数').openapi({
     description: '广告ID',
     description: '广告ID',
     example: 1
     example: 1
   }),
   }),
-  positionId: z.coerce.number().int().positive().openapi({
+  positionId: z.coerce.number().int().positive('广告位ID必须是正整数').openapi({
     description: '广告位ID',
     description: '广告位ID',
     example: 1
     example: 1
   }),
   }),
-  linkUrl: z.string().url().openapi({
+  linkUrl: z.string('请输入正确的链接地址格式').openapi({
     description: '链接地址',
     description: '链接地址',
     example: 'https://example.com'
     example: 'https://example.com'
   }),
   }),
-  imageFileId: z.number().int().positive().nullable().openapi({
+  imageFileId: z.number().int().positive('图片文件ID必须是正整数').nullable().openapi({
     description: '图片文件ID',
     description: '图片文件ID',
     example: 1
     example: 1
   }),
   }),
   imageFile: z.object({
   imageFile: z.object({
-    id: z.number().int().positive().openapi({ description: '文件ID' }),
-    name: z.string().max(255).openapi({ description: '文件名', example: 'banner.jpg' }),
+    id: z.number().int().positive('文件ID必须是正整数').openapi({ description: '文件ID' }),
+    name: z.string().max(255, '文件名最多255个字符').openapi({ description: '文件名', example: 'banner.jpg' }),
     fullUrl: z.string().openapi({ description: '文件完整URL', example: 'https://example.com/banner.jpg' }),
     fullUrl: z.string().openapi({ description: '文件完整URL', example: 'https://example.com/banner.jpg' }),
     type: z.string().nullable().openapi({ description: '文件类型', example: 'image/jpeg' }),
     type: z.string().nullable().openapi({ description: '文件类型', example: 'image/jpeg' }),
     size: z.number().nullable().openapi({ description: '文件大小(字节)', example: 102400 })
     size: z.number().nullable().openapi({ description: '文件大小(字节)', example: 102400 })
   }).nullable().optional().openapi({
   }).nullable().optional().openapi({
     description: '图片文件信息'
     description: '图片文件信息'
   }),
   }),
-  title: z.string().min(1).max(255).openapi({
+  title: z.string().min(1, '广告标题不能为空').max(255, '广告标题最多255个字符').openapi({
     description: '广告标题',
     description: '广告标题',
     example: '夏季促销活动'
     example: '夏季促销活动'
   }),
   }),
-  sortOrder: z.coerce.number().int().min(0).default(0).openapi({
+  sortOrder: z.coerce.number().int().min(0, '排序值必须是非负整数').default(0).openapi({
     description: '排序值,数值越大越靠前',
     description: '排序值,数值越大越靠前',
     example: 100
     example: 100
   }),
   }),
-  isEnabled: z.coerce.number().int().min(0).max(1).default(1).openapi({
+  isEnabled: z.coerce.number().int().min(0, '启用状态只能是0或1').max(1, '启用状态只能是0或1').default(1).openapi({
     description: '是否启用:0-禁用,1-启用',
     description: '是否启用:0-禁用,1-启用',
     example: 1
     example: 1
   }),
   }),
-  isDeleted: z.coerce.number().int().min(0).max(1).default(0).openapi({
+  isDeleted: z.coerce.number().int().min(0, '删除状态只能是0或1').max(1, '删除状态只能是0或1').default(0).openapi({
     description: '是否删除:0-未删除,1-已删除',
     description: '是否删除:0-未删除,1-已删除',
     example: 0
     example: 0
   }),
   }),
@@ -51,15 +51,15 @@ export const AdvertisementSchema = z.object({
     description: '结束时间',
     description: '结束时间',
     example: '2024-12-31T23:59:59Z'
     example: '2024-12-31T23:59:59Z'
   }),
   }),
-  description: z.string().max(1000).nullable().optional().openapi({
+  description: z.string().max(1000, '广告描述最多1000个字符').nullable().optional().openapi({
     description: '广告描述',
     description: '广告描述',
     example: '这是一个夏季促销活动的广告'
     example: '这是一个夏季促销活动的广告'
   }),
   }),
-  createdBy: z.number().int().positive().nullable().optional().openapi({
+  createdBy: z.number().int().positive('创建用户ID必须是正整数').nullable().optional().openapi({
     description: '创建用户ID',
     description: '创建用户ID',
     example: 1
     example: 1
   }),
   }),
-  updatedBy: z.number().int().positive().nullable().optional().openapi({
+  updatedBy: z.number().int().positive('更新用户ID必须是正整数').nullable().optional().openapi({
     description: '更新用户ID',
     description: '更新用户ID',
     example: 1
     example: 1
   }),
   }),
@@ -75,27 +75,27 @@ export const AdvertisementSchema = z.object({
 
 
 // 创建广告DTO
 // 创建广告DTO
 export const CreateAdvertisementDto = z.object({
 export const CreateAdvertisementDto = z.object({
-  positionId: z.coerce.number().int().positive().openapi({
+  positionId: z.coerce.number().int().positive('广告位ID必须是正整数').openapi({
     description: '广告位ID',
     description: '广告位ID',
     example: 1
     example: 1
   }),
   }),
-  linkUrl: z.string().url().openapi({
+  linkUrl: z.string('请输入正确的链接地址格式').openapi({
     description: '链接地址',
     description: '链接地址',
     example: 'https://example.com'
     example: 'https://example.com'
   }),
   }),
-  imageFileId: z.coerce.number().int().positive().nullable().optional().openapi({
+  imageFileId: z.coerce.number().int().positive('图片文件ID必须是正整数').nullable().optional().openapi({
     description: '图片文件ID',
     description: '图片文件ID',
     example: 1
     example: 1
   }),
   }),
-  title: z.string().min(1).max(255).openapi({
+  title: z.string().min(1, '广告标题不能为空').max(255, '广告标题最多255个字符').openapi({
     description: '广告标题',
     description: '广告标题',
     example: '夏季促销活动'
     example: '夏季促销活动'
   }),
   }),
-  sortOrder: z.coerce.number().int().min(0).default(0).optional().openapi({
+  sortOrder: z.coerce.number().int().min(0, '排序值必须是非负整数').default(0).optional().openapi({
     description: '排序值',
     description: '排序值',
     example: 100
     example: 100
   }),
   }),
-  isEnabled: z.coerce.number().int().min(0).max(1).default(1).optional().openapi({
+  isEnabled: z.coerce.number().int().min(0, '启用状态只能是0或1').max(1, '启用状态只能是0或1').default(1).optional().openapi({
     description: '是否启用',
     description: '是否启用',
     example: 1
     example: 1
   }),
   }),
@@ -107,7 +107,7 @@ export const CreateAdvertisementDto = z.object({
     description: '结束时间',
     description: '结束时间',
     example: '2024-12-31T23:59:59Z'
     example: '2024-12-31T23:59:59Z'
   }),
   }),
-  description: z.string().max(1000).nullable().optional().openapi({
+  description: z.string().max(1000, '广告描述最多1000个字符').nullable().optional().openapi({
     description: '广告描述',
     description: '广告描述',
     example: '这是一个夏季促销活动的广告'
     example: '这是一个夏季促销活动的广告'
   })
   })
@@ -115,27 +115,27 @@ export const CreateAdvertisementDto = z.object({
 
 
 // 更新广告DTO
 // 更新广告DTO
 export const UpdateAdvertisementDto = z.object({
 export const UpdateAdvertisementDto = z.object({
-  positionId: z.coerce.number().int().positive().optional().openapi({
+  positionId: z.coerce.number().int().positive('广告位ID必须是正整数').optional().openapi({
     description: '广告位ID',
     description: '广告位ID',
     example: 1
     example: 1
   }),
   }),
-  linkUrl: z.string().url().optional().openapi({
+  linkUrl: z.string('请输入正确的链接地址格式').optional().openapi({
     description: '链接地址',
     description: '链接地址',
     example: 'https://example.com'
     example: 'https://example.com'
   }),
   }),
-  imageFileId: z.coerce.number().int().positive().nullable().optional().openapi({
+  imageFileId: z.coerce.number().int().positive('图片文件ID必须是正整数').nullable().optional().openapi({
     description: '图片文件ID',
     description: '图片文件ID',
     example: 1
     example: 1
   }),
   }),
-  title: z.string().min(1).max(255).optional().openapi({
+  title: z.string().min(1, '广告标题不能为空').max(255, '广告标题最多255个字符').optional().openapi({
     description: '广告标题',
     description: '广告标题',
     example: '夏季促销活动'
     example: '夏季促销活动'
   }),
   }),
-  sortOrder: z.coerce.number().int().min(0).optional().openapi({
+  sortOrder: z.coerce.number().int().min(0, '排序值必须是非负整数').optional().openapi({
     description: '排序值',
     description: '排序值',
     example: 100
     example: 100
   }),
   }),
-  isEnabled: z.coerce.number().int().min(0).max(1).optional().openapi({
+  isEnabled: z.coerce.number().int().min(0, '启用状态只能是0或1').max(1, '启用状态只能是0或1').optional().openapi({
     description: '是否启用',
     description: '是否启用',
     example: 1
     example: 1
   }),
   }),
@@ -147,7 +147,7 @@ export const UpdateAdvertisementDto = z.object({
     description: '结束时间',
     description: '结束时间',
     example: '2024-12-31T23:59:59Z'
     example: '2024-12-31T23:59:59Z'
   }),
   }),
-  description: z.string().max(1000).nullable().optional().openapi({
+  description: z.string().max(1000, '广告描述最多1000个字符').nullable().optional().openapi({
     description: '广告描述',
     description: '广告描述',
     example: '这是一个夏季促销活动的广告'
     example: '这是一个夏季促销活动的广告'
   })
   })
@@ -155,19 +155,19 @@ export const UpdateAdvertisementDto = z.object({
 
 
 // 广告列表查询参数
 // 广告列表查询参数
 export const AdvertisementQuery = z.object({
 export const AdvertisementQuery = z.object({
-  page: z.coerce.number().int().positive().default(1).openapi({
+  page: z.coerce.number().int().positive('页码必须是正整数').default(1).openapi({
     description: '页码',
     description: '页码',
     example: 1
     example: 1
   }),
   }),
-  pageSize: z.coerce.number().int().positive().default(10).openapi({
+  pageSize: z.coerce.number().int().positive('每页条数必须是正整数').default(10).openapi({
     description: '每页条数',
     description: '每页条数',
     example: 10
     example: 10
   }),
   }),
-  positionId: z.coerce.number().int().positive().optional().openapi({
+  positionId: z.coerce.number().int().positive('广告位ID必须是正整数').optional().openapi({
     description: '广告位ID筛选',
     description: '广告位ID筛选',
     example: 1
     example: 1
   }),
   }),
-  isEnabled: z.coerce.number().int().min(0).max(1).optional().openapi({
+  isEnabled: z.coerce.number().int().min(0, '启用状态只能是0或1').max(1, '启用状态只能是0或1').optional().openapi({
     description: '是否启用筛选',
     description: '是否启用筛选',
     example: 1
     example: 1
   }),
   }),