feat: swag.

This commit is contained in:
2026-05-04 16:20:46 +08:00
parent 3fbbbbc6a8
commit b7843641ca
24 changed files with 9376 additions and 19 deletions
+17
View File
@@ -283,6 +283,23 @@ func callAIForAnalysis(prompt string) (*aiAnalysisResult, error) {
}, nil
}
// @Summary AI分析
// @Description 上传心率CSV和教案文件通过AI生成课堂分析报告支持流式和非流式输出
// @Tags AI分析
// @Accept multipart/form-data
// @Produce json
// @Param heart_rate_data formData file true "心率数据CSV文件"
// @Param step_data formData file false "步数数据CSV文件(analysis_type为heart_rate_with_steps时必填)"
// @Param teaching_plan formData file false "教案DOCX文件(teaching_plan_source为upload/wechat时必填)"
// @Param analysis_type formData string false "分析类型: heart_rate_only(默认) | heart_rate_with_steps"
// @Param teaching_plan_source formData string false "教案来源: upload(默认) | cloud | wechat"
// @Param regionid formData string false "区域ID"
// @Param trainid formData string false "训练ID"
// @Param lesson_plan_id formData string false "云端教案ID(teaching_plan_source=cloud时必填)"
// @Param stream formData string false "是否流式输出: true | false"
// @Success 200 {object} SwagAPIResponse "分析成功"
// @Failure 400 {object} SwagAPIResponse "请求参数错误"
// @Router /train-records/analysis-by-ai [post]
func (tc *TrainingController) AnalyzeByAI(c *gin.Context) {
form, err := c.MultipartForm()
if err != nil {
+54 -11
View File
@@ -36,9 +36,17 @@ func NewGatewayAdminController() *GatewayAdminController {
return &GatewayAdminController{DB: config.DB}
}
// List 获取网关列表
// GET /api/v1/gateways?keyword=&isSold=&projectType=&regionId=
// 超级管理员可查询全部;操作员/区域管理员仅能查询所属 regionIDs 网关
// @Summary 获取网关列表
// @Description 查询网关列表,支持关键词/售出状态/项目类型/区域筛选。超级管理员可查全部,操作员只能查所属区域
// @Tags 网关管理
// @Produce json
// @Param keyword query string false "关键词(名称/MAC模糊搜索)"
// @Param isSold query bool false "售出状态"
// @Param projectType query string false "项目类型"
// @Param regionId query int false "区域ID"
// @Security BearerAuth
// @Success 200 {object} SwagAPIResponse "查询成功"
// @Router /admin/gateways [get]
func (gc *GatewayAdminController) List(c *gin.Context) {
var items []models.Gateway
query := gc.DB.Model(&models.Gateway{}).Order("region_id ASC, created_at DESC")
@@ -91,8 +99,16 @@ func (gc *GatewayAdminController) List(c *gin.Context) {
writeSuccess(c, http.StatusOK, "查询成功", items)
}
// GetByMACForUser MAC 查询网关信息
// GET /api/v1/gateways/by-mac?mac=
// @Summary 按MAC查询网关
// @Description 根据MAC地址查询网关信息支持格式兼容带冒号/横线/纯数字)
// @Tags 网关管理
// @Produce json
// @Param mac query string true "MAC地址"
// @Security BearerAuth
// @Success 200 {object} SwagAPIResponse "查询成功"
// @Failure 400 {object} SwagAPIResponse "MAC参数为空"
// @Failure 404 {object} SwagAPIResponse "未找到该网关"
// @Router /gateways/by-mac [get]
func (gc *GatewayAdminController) GetByMACForUser(c *gin.Context) {
macInput := strings.ToUpper(strings.TrimSpace(c.Query("mac")))
if macInput == "" {
@@ -132,8 +148,17 @@ func (gc *GatewayAdminController) GetByMACForUser(c *gin.Context) {
writeSuccess(c, http.StatusOK, "查询成功", item)
}
// Create 创建网关
// POST /api/gateways
// @Summary 创建网关
// @Description 创建新的网关记录,自动同步到产品库存
// @Tags 网关管理
// @Accept json
// @Produce json
// @Param gateway body gatewayPayload true "网关信息"
// @Security BearerAuth
// @Success 201 {object} SwagAPIResponse "创建成功"
// @Failure 400 {object} SwagAPIResponse "请求参数错误"
// @Failure 409 {object} SwagAPIResponse "MAC地址已存在"
// @Router /admin/gateways [post]
func (gc *GatewayAdminController) Create(c *gin.Context) {
var payload gatewayPayload
if err := c.ShouldBindJSON(&payload); err != nil {
@@ -188,8 +213,18 @@ func (gc *GatewayAdminController) Create(c *gin.Context) {
writeSuccess(c, http.StatusCreated, "创建成功", record)
}
// Update 更新网关信息
// PUT /api/gateways/:id
// @Summary 更新网关信息
// @Description 更新指定网关的详细信息,自动同步到产品库存
// @Tags 网关管理
// @Accept json
// @Produce json
// @Param id path int true "网关ID"
// @Param gateway body gatewayPayload true "更新信息"
// @Security BearerAuth
// @Success 200 {object} SwagAPIResponse "更新成功"
// @Failure 400 {object} SwagAPIResponse "请求参数错误"
// @Failure 404 {object} SwagAPIResponse "网关不存在"
// @Router /admin/gateways/{id} [put]
func (gc *GatewayAdminController) Update(c *gin.Context) {
record, err := gc.findByID(c.Param("id"))
if err != nil {
@@ -246,8 +281,16 @@ func (gc *GatewayAdminController) Update(c *gin.Context) {
writeSuccess(c, http.StatusOK, "更新成功", record)
}
// Delete 删除网关
// DELETE /api/gateways/:id
// @Summary 删除网关
// @Description 删除指定网关(已售出的网关禁止删除),自动同步删除产品库存
// @Tags 网关管理
// @Produce json
// @Param id path int true "网关ID"
// @Security BearerAuth
// @Success 200 {object} SwagAPIResponse "删除成功"
// @Failure 403 {object} SwagAPIResponse "已售出无法删除"
// @Failure 404 {object} SwagAPIResponse "网关不存在"
// @Router /admin/gateways/{id} [delete]
func (gc *GatewayAdminController) Delete(c *gin.Context) {
record, err := gc.findByID(c.Param("id"))
if err != nil {
+40
View File
@@ -26,6 +26,14 @@ func NewKindergartenAdminController() *KindergartenAdminController {
return &KindergartenAdminController{DB: config.DB}
}
// @Summary 获取幼儿园列表
// @Description 查询幼儿园列表,支持按名称/地址模糊搜索
// @Tags 幼儿园管理
// @Produce json
// @Param keyword query string false "关键词(名称/地址模糊搜索)"
// @Security BearerAuth
// @Success 200 {object} SwagAPIResponse "查询成功"
// @Router /admin/kindergartens [get]
func (kc *KindergartenAdminController) List(c *gin.Context) {
var items []models.Kindergarten
query := kc.DB.Model(&models.Kindergarten{}).Order("region_id ASC, id ASC")
@@ -42,6 +50,16 @@ func (kc *KindergartenAdminController) List(c *gin.Context) {
writeSuccess(c, http.StatusOK, "query success", items)
}
// @Summary 创建幼儿园
// @Description 创建新的幼儿园记录
// @Tags 幼儿园管理
// @Accept json
// @Produce json
// @Param kindergarten body kindergartenPayload true "幼儿园信息"
// @Security BearerAuth
// @Success 201 {object} SwagAPIResponse "创建成功"
// @Failure 400 {object} SwagAPIResponse "请求参数错误"
// @Router /admin/kindergartens [post]
func (kc *KindergartenAdminController) Create(c *gin.Context) {
var payload kindergartenPayload
if err := c.ShouldBindJSON(&payload); err != nil {
@@ -65,6 +83,18 @@ func (kc *KindergartenAdminController) Create(c *gin.Context) {
writeSuccess(c, http.StatusCreated, "create success", record)
}
// @Summary 更新幼儿园信息
// @Description 更新指定幼儿园的名称、地址和区域
// @Tags 幼儿园管理
// @Accept json
// @Produce json
// @Param id path int true "幼儿园ID"
// @Param kindergarten body kindergartenPayload true "更新信息"
// @Security BearerAuth
// @Success 200 {object} SwagAPIResponse "更新成功"
// @Failure 400 {object} SwagAPIResponse "请求参数错误"
// @Failure 404 {object} SwagAPIResponse "幼儿园不存在"
// @Router /admin/kindergartens/{id} [put]
func (kc *KindergartenAdminController) Update(c *gin.Context) {
record, err := kc.findByID(c.Param("id"))
if err != nil {
@@ -93,6 +123,16 @@ func (kc *KindergartenAdminController) Update(c *gin.Context) {
writeSuccess(c, http.StatusOK, "update success", record)
}
// @Summary 删除幼儿园
// @Description 删除指定幼儿园,如果被用户绑定则无法删除
// @Tags 幼儿园管理
// @Produce json
// @Param id path int true "幼儿园ID"
// @Security BearerAuth
// @Success 200 {object} SwagAPIResponse "删除成功"
// @Failure 404 {object} SwagAPIResponse "幼儿园不存在"
// @Failure 409 {object} SwagAPIResponse "已绑定用户无法删除"
// @Router /admin/kindergartens/{id} [delete]
func (kc *KindergartenAdminController) Delete(c *gin.Context) {
record, err := kc.findByID(c.Param("id"))
if err != nil {
+78
View File
@@ -53,6 +53,18 @@ func NewLessonPlanController() *LessonPlanController {
return &LessonPlanController{DB: config.DB}
}
// @Summary 上传教案文件
// @Description 上传 .docx 格式的教案文件支持MD5去重最大10MB
// @Tags 教案管理
// @Accept multipart/form-data
// @Produce json
// @Param file formData file true "教案文件(.docx)"
// @Security BearerAuth
// @Success 201 {object} SwagAPIResponse "上传成功"
// @Failure 400 {object} SwagAPIResponse "请求参数错误"
// @Failure 401 {object} SwagAPIResponse "未认证"
// @Failure 409 {object} SwagAPIResponse "文件已存在"
// @Router /lesson-plans/upload [post]
func (lc *LessonPlanController) Upload(c *gin.Context) {
fileHeader, err := c.FormFile(lessonPlanFieldName)
if err != nil {
@@ -152,6 +164,14 @@ func (lc *LessonPlanController) Upload(c *gin.Context) {
writeSuccess(c, http.StatusCreated, "upload success", record)
}
// @Summary 获取教案列表
// @Description 获取教案文件列表(非分页),按创建时间倒序
// @Tags 教案管理
// @Produce json
// @Security BearerAuth
// @Success 200 {object} SwagAPIResponse "查询成功"
// @Failure 401 {object} SwagAPIResponse "未认证"
// @Router /lesson-plans [get]
func (lc *LessonPlanController) List(c *gin.Context) {
userID, _, ok := currentUser(c)
if !ok {
@@ -173,6 +193,22 @@ func (lc *LessonPlanController) List(c *gin.Context) {
writeSuccess(c, http.StatusOK, "query success", records)
}
// @Summary 分页查询教案
// @Description 分页获取教案文件列表,支持文件名模糊搜索、上传者搜索、区域筛选、排序
// @Tags 教案管理
// @Produce json
// @Param pageNum query int false "页码(默认1)"
// @Param pageSize query int false "每页数量(默认10,最大100)"
// @Param keyword query string false "文件名模糊搜索"
// @Param uploaderName query string false "上传者名模糊搜索"
// @Param regionId query int false "区域ID"
// @Param sortBy query string false "排序字段: file_size | created_at"
// @Param sortOrder query string false "排序方向: asc | desc"
// @Security BearerAuth
// @Success 200 {object} SwagAPIResponse "查询成功"
// @Failure 400 {object} SwagAPIResponse "请求参数错误"
// @Failure 401 {object} SwagAPIResponse "未认证"
// @Router /lesson-plans/page [get]
func (lc *LessonPlanController) Page(c *gin.Context) {
userID, _, ok := currentUser(c)
if !ok {
@@ -312,6 +348,17 @@ func (lc *LessonPlanController) Page(c *gin.Context) {
})
}
// @Summary 下载教案文件
// @Description 通过ID下载教案文件自动更新下载计数和最后下载时间
// @Tags 教案管理
// @Produce application/octet-stream
// @Param id path int true "教案ID"
// @Security BearerAuth
// @Success 200 {file} binary "教案文件"
// @Failure 401 {object} SwagAPIResponse "未认证"
// @Failure 403 {object} SwagAPIResponse "无权限"
// @Failure 404 {object} SwagAPIResponse "文件不存在"
// @Router /lesson-plans/{id}/download [get]
func (lc *LessonPlanController) Download(c *gin.Context) {
record, err := lc.findLessonPlan(c.Param("id"))
if err != nil {
@@ -344,6 +391,17 @@ func (lc *LessonPlanController) Download(c *gin.Context) {
c.FileAttachment(record.FilePath, record.OriginalFilename)
}
// @Summary 生成分享码
// @Description 为教案文件生成6位数字分享码有效期5分钟每次生成会失效之前的分享码
// @Tags 教案管理
// @Produce json
// @Param id path int true "教案ID"
// @Security BearerAuth
// @Success 200 {object} SwagAPIResponse "生成成功"
// @Failure 401 {object} SwagAPIResponse "未认证"
// @Failure 403 {object} SwagAPIResponse "无权限"
// @Failure 404 {object} SwagAPIResponse "文件不存在"
// @Router /lesson-plans/{id}/share-code [post]
func (lc *LessonPlanController) GenerateShareCode(c *gin.Context) {
record, err := lc.findLessonPlan(c.Param("id"))
if err != nil {
@@ -399,6 +457,15 @@ func (lc *LessonPlanController) GenerateShareCode(c *gin.Context) {
})
}
// @Summary 通过分享码下载教案
// @Description 通过6位分享码下载教案文件无需认证
// @Tags 教案管理
// @Produce application/octet-stream
// @Param code path string true "6位分享码"
// @Success 200 {file} binary "教案文件"
// @Failure 400 {object} SwagAPIResponse "分享码无效"
// @Failure 404 {object} SwagAPIResponse "分享码过期或不存在"
// @Router /lesson-plans/share/{code}/download [get]
func (lc *LessonPlanController) DownloadByShareCode(c *gin.Context) {
shareCode := strings.TrimSpace(c.Param("code"))
if len(shareCode) != shareCodeDigits {
@@ -439,6 +506,17 @@ func (lc *LessonPlanController) DownloadByShareCode(c *gin.Context) {
c.FileAttachment(record.FilePath, record.OriginalFilename)
}
// @Summary 删除教案文件
// @Description 删除教案文件及其关联的分享码
// @Tags 教案管理
// @Produce json
// @Param id path int true "教案ID"
// @Security BearerAuth
// @Success 200 {object} SwagAPIResponse "删除成功"
// @Failure 401 {object} SwagAPIResponse "未认证"
// @Failure 403 {object} SwagAPIResponse "无权限"
// @Failure 404 {object} SwagAPIResponse "文件不存在"
// @Router /lesson-plans/{id} [delete]
func (lc *LessonPlanController) Delete(c *gin.Context) {
record, err := lc.findLessonPlan(c.Param("id"))
if err != nil {
+21 -2
View File
@@ -29,7 +29,16 @@ type AuthResponse struct {
User models.User `json:"user"`
}
// Register 用户注册
// @Summary 用户注册
// @Description 注册新用户返回JWT Token
// @Tags 认证
// @Accept json
// @Produce json
// @Param request body SwagRegisterRequest true "注册信息"
// @Success 201 {object} SwagAPIResponse "注册成功"
// @Failure 400 {object} SwagAPIResponse "请求参数错误"
// @Failure 409 {object} SwagAPIResponse "用户名已存在"
// @Router /register [post]
func Register(c *gin.Context) {
var req RegisterRequest
if err := c.ShouldBindJSON(&req); err != nil {
@@ -73,7 +82,17 @@ func Register(c *gin.Context) {
})
}
// Login 用户登录
// @Summary 用户登录
// @Description 用户名密码登录返回JWT Token和用户信息
// @Tags 认证
// @Accept json
// @Produce json
// @Param request body SwagLoginRequest true "登录信息"
// @Success 200 {object} SwagAPIResponse "登录成功"
// @Failure 400 {object} SwagAPIResponse "请求参数错误"
// @Failure 401 {object} SwagAPIResponse "用户名或密码错误"
// @Failure 403 {object} SwagAPIResponse "用户已禁用"
// @Router /login [post]
func Login(c *gin.Context) {
var req LoginRequest
if err := c.ShouldBindJSON(&req); err != nil {
+42
View File
@@ -32,6 +32,16 @@ func NewProductDefinitionAdminController() *ProductDefinitionAdminController {
return &ProductDefinitionAdminController{DB: config.DB}
}
// @Summary 获取产品定义列表
// @Description 查询产品定义列表,支持按关键词/分类/启用状态筛选
// @Tags 产品定义管理
// @Produce json
// @Param keyword query string false "关键词(代码/名称/描述模糊搜索)"
// @Param category query string false "分类筛选"
// @Param isActive query bool false "是否启用"
// @Security BearerAuth
// @Success 200 {object} SwagAPIResponse "查询成功"
// @Router /admin/product-definitions [get]
func (pc *ProductDefinitionAdminController) List(c *gin.Context) {
var items []models.ProductDefinition
query := pc.DB.Model(&models.ProductDefinition{}).Order("sort ASC, id ASC")
@@ -59,6 +69,16 @@ func (pc *ProductDefinitionAdminController) List(c *gin.Context) {
writeSuccess(c, http.StatusOK, "query success", items)
}
// @Summary 创建产品定义
// @Description 创建新的产品定义
// @Tags 产品定义管理
// @Accept json
// @Produce json
// @Param productDefinition body productDefinitionPayload true "产品定义信息"
// @Security BearerAuth
// @Success 201 {object} SwagAPIResponse "创建成功"
// @Failure 400 {object} SwagAPIResponse "请求参数错误"
// @Router /admin/product-definitions [post]
func (pc *ProductDefinitionAdminController) Create(c *gin.Context) {
var payload productDefinitionPayload
if err := c.ShouldBindJSON(&payload); err != nil {
@@ -87,6 +107,18 @@ func (pc *ProductDefinitionAdminController) Create(c *gin.Context) {
writeSuccess(c, http.StatusCreated, "create success", record)
}
// @Summary 更新产品定义
// @Description 更新指定产品定义的信息
// @Tags 产品定义管理
// @Accept json
// @Produce json
// @Param id path int true "产品定义ID"
// @Param productDefinition body productDefinitionPayload true "更新信息"
// @Security BearerAuth
// @Success 200 {object} SwagAPIResponse "更新成功"
// @Failure 400 {object} SwagAPIResponse "请求参数错误"
// @Failure 404 {object} SwagAPIResponse "产品定义不存在"
// @Router /admin/product-definitions/{id} [put]
func (pc *ProductDefinitionAdminController) Update(c *gin.Context) {
record, err := pc.findByID(c.Param("id"))
if err != nil {
@@ -120,6 +152,16 @@ func (pc *ProductDefinitionAdminController) Update(c *gin.Context) {
writeSuccess(c, http.StatusOK, "update success", record)
}
// @Summary 删除产品定义
// @Description 删除指定产品定义(被库存或模板引用的无法删除)
// @Tags 产品定义管理
// @Produce json
// @Param id path int true "产品定义ID"
// @Security BearerAuth
// @Success 200 {object} SwagAPIResponse "删除成功"
// @Failure 404 {object} SwagAPIResponse "产品定义不存在"
// @Failure 409 {object} SwagAPIResponse "已被引用无法删除"
// @Router /admin/product-definitions/{id} [delete]
func (pc *ProductDefinitionAdminController) Delete(c *gin.Context) {
record, err := pc.findByID(c.Param("id"))
if err != nil {
+46
View File
@@ -40,6 +40,20 @@ func NewProductInventoryAdminController() *ProductInventoryAdminController {
return &ProductInventoryAdminController{DB: config.DB}
}
// @Summary 获取产品库存列表
// @Description 查询产品库存列表,支持多条件筛选
// @Tags 产品库存管理
// @Produce json
// @Param keyword query string false "关键词(资产名称/序列号/购买方等模糊搜索)"
// @Param productCode query string false "产品代码筛选"
// @Param projectTypeCode query string false "项目类型代码筛选"
// @Param suiteCode query string false "套件代码筛选"
// @Param status query string false "状态筛选"
// @Param soldTargetType query string false "购买方类型筛选"
// @Param regionId query int false "区域ID"
// @Security BearerAuth
// @Success 200 {object} SwagAPIResponse "查询成功"
// @Router /admin/product-inventories [get]
func (pc *ProductInventoryAdminController) List(c *gin.Context) {
var items []models.ProductInventory
query := pc.DB.Model(&models.ProductInventory{}).Order("updated_at DESC, id DESC")
@@ -79,6 +93,16 @@ func (pc *ProductInventoryAdminController) List(c *gin.Context) {
writeSuccess(c, http.StatusOK, "query success", items)
}
// @Summary 创建产品库存记录
// @Description 创建新的产品库存记录
// @Tags 产品库存管理
// @Accept json
// @Produce json
// @Param inventory body productInventoryPayload true "库存信息"
// @Security BearerAuth
// @Success 201 {object} SwagAPIResponse "创建成功"
// @Failure 400 {object} SwagAPIResponse "请求参数错误"
// @Router /admin/product-inventories [post]
func (pc *ProductInventoryAdminController) Create(c *gin.Context) {
var payload productInventoryPayload
if err := c.ShouldBindJSON(&payload); err != nil {
@@ -121,6 +145,18 @@ func (pc *ProductInventoryAdminController) Create(c *gin.Context) {
writeSuccess(c, http.StatusCreated, "create success", record)
}
// @Summary 更新产品库存
// @Description 更新指定产品库存记录
// @Tags 产品库存管理
// @Accept json
// @Produce json
// @Param id path int true "库存ID"
// @Param inventory body productInventoryPayload true "更新信息"
// @Security BearerAuth
// @Success 200 {object} SwagAPIResponse "更新成功"
// @Failure 400 {object} SwagAPIResponse "请求参数错误"
// @Failure 404 {object} SwagAPIResponse "库存记录不存在"
// @Router /admin/product-inventories/{id} [put]
func (pc *ProductInventoryAdminController) Update(c *gin.Context) {
record, err := pc.findByID(c.Param("id"))
if err != nil {
@@ -167,6 +203,16 @@ func (pc *ProductInventoryAdminController) Update(c *gin.Context) {
writeSuccess(c, http.StatusOK, "update success", record)
}
// @Summary 删除产品库存
// @Description 删除指定产品库存记录(已售出的无法删除)
// @Tags 产品库存管理
// @Produce json
// @Param id path int true "库存ID"
// @Security BearerAuth
// @Success 200 {object} SwagAPIResponse "删除成功"
// @Failure 404 {object} SwagAPIResponse "库存记录不存在"
// @Failure 409 {object} SwagAPIResponse "已售出无法删除"
// @Router /admin/product-inventories/{id} [delete]
func (pc *ProductInventoryAdminController) Delete(c *gin.Context) {
record, err := pc.findByID(c.Param("id"))
if err != nil {
+41
View File
@@ -33,6 +33,16 @@ func NewProductPrototypeAdminController() *ProductPrototypeAdminController {
return &ProductPrototypeAdminController{DB: config.DB}
}
// @Summary 获取产品原型列表
// @Description 查询产品原型列表,支持按关键词/产品代码/项目类型筛选
// @Tags 产品原型管理
// @Produce json
// @Param keyword query string false "关键词(名称/备注模糊搜索)"
// @Param productCode query string false "产品代码筛选"
// @Param projectTypeCode query string false "项目类型代码筛选"
// @Security BearerAuth
// @Success 200 {object} SwagAPIResponse "查询成功"
// @Router /admin/product-prototypes [get]
func (pc *ProductPrototypeAdminController) List(c *gin.Context) {
var items []models.ProductPrototype
query := pc.DB.Model(&models.ProductPrototype{}).Order("updated_at DESC, id DESC")
@@ -55,6 +65,16 @@ func (pc *ProductPrototypeAdminController) List(c *gin.Context) {
writeSuccess(c, http.StatusOK, "query success", items)
}
// @Summary 创建产品原型
// @Description 创建新的产品原型
// @Tags 产品原型管理
// @Accept json
// @Produce json
// @Param productPrototype body productPrototypePayload true "产品原型信息"
// @Security BearerAuth
// @Success 201 {object} SwagAPIResponse "创建成功"
// @Failure 400 {object} SwagAPIResponse "请求参数错误"
// @Router /admin/product-prototypes [post]
func (pc *ProductPrototypeAdminController) Create(c *gin.Context) {
var payload productPrototypePayload
if err := c.ShouldBindJSON(&payload); err != nil {
@@ -88,6 +108,18 @@ func (pc *ProductPrototypeAdminController) Create(c *gin.Context) {
writeSuccess(c, http.StatusCreated, "create success", record)
}
// @Summary 更新产品原型
// @Description 更新指定产品原型的信息
// @Tags 产品原型管理
// @Accept json
// @Produce json
// @Param id path int true "产品原型ID"
// @Param productPrototype body productPrototypePayload true "更新信息"
// @Security BearerAuth
// @Success 200 {object} SwagAPIResponse "更新成功"
// @Failure 400 {object} SwagAPIResponse "请求参数错误"
// @Failure 404 {object} SwagAPIResponse "产品原型不存在"
// @Router /admin/product-prototypes/{id} [put]
func (pc *ProductPrototypeAdminController) Update(c *gin.Context) {
record, err := pc.findByID(c.Param("id"))
if err != nil {
@@ -122,6 +154,15 @@ func (pc *ProductPrototypeAdminController) Update(c *gin.Context) {
writeSuccess(c, http.StatusOK, "update success", record)
}
// @Summary 删除产品原型
// @Description 删除指定产品原型
// @Tags 产品原型管理
// @Produce json
// @Param id path int true "产品原型ID"
// @Security BearerAuth
// @Success 200 {object} SwagAPIResponse "删除成功"
// @Failure 404 {object} SwagAPIResponse "产品原型不存在"
// @Router /admin/product-prototypes/{id} [delete]
func (pc *ProductPrototypeAdminController) Delete(c *gin.Context) {
record, err := pc.findByID(c.Param("id"))
if err != nil {
+40
View File
@@ -36,6 +36,15 @@ func NewProductSuiteAdminController() *ProductSuiteAdminController {
return &ProductSuiteAdminController{DB: config.DB}
}
// @Summary 获取产品套件列表
// @Description 查询产品套件列表,含套件下的库存明细
// @Tags 产品套件管理
// @Produce json
// @Param keyword query string false "关键词(代码/名称/备注模糊搜索)"
// @Param projectTypeCode query string false "项目类型代码筛选"
// @Security BearerAuth
// @Success 200 {object} SwagAPIResponse "查询成功"
// @Router /admin/product-suites [get]
func (pc *ProductSuiteAdminController) List(c *gin.Context) {
var suites []models.ProductSuite
query := pc.DB.Model(&models.ProductSuite{}).Order("updated_at DESC, id DESC")
@@ -69,6 +78,16 @@ func (pc *ProductSuiteAdminController) List(c *gin.Context) {
writeSuccess(c, http.StatusOK, "query success", result)
}
// @Summary 创建产品套件
// @Description 创建新的产品套件,可选关联库存记录
// @Tags 产品套件管理
// @Accept json
// @Produce json
// @Param suite body productSuitePayload true "套件信息"
// @Security BearerAuth
// @Success 201 {object} SwagAPIResponse "创建成功"
// @Failure 400 {object} SwagAPIResponse "请求参数错误"
// @Router /admin/product-suites [post]
func (pc *ProductSuiteAdminController) Create(c *gin.Context) {
var payload productSuitePayload
if err := c.ShouldBindJSON(&payload); err != nil {
@@ -107,6 +126,18 @@ func (pc *ProductSuiteAdminController) Create(c *gin.Context) {
writeSuccess(c, http.StatusCreated, "create success", record)
}
// @Summary 更新产品套件
// @Description 更新指定产品套件的信息和关联库存
// @Tags 产品套件管理
// @Accept json
// @Produce json
// @Param id path int true "套件ID"
// @Param suite body productSuitePayload true "更新信息"
// @Security BearerAuth
// @Success 200 {object} SwagAPIResponse "更新成功"
// @Failure 400 {object} SwagAPIResponse "请求参数错误"
// @Failure 404 {object} SwagAPIResponse "套件不存在"
// @Router /admin/product-suites/{id} [put]
func (pc *ProductSuiteAdminController) Update(c *gin.Context) {
record, err := pc.findByID(c.Param("id"))
if err != nil {
@@ -149,6 +180,15 @@ func (pc *ProductSuiteAdminController) Update(c *gin.Context) {
writeSuccess(c, http.StatusOK, "update success", record)
}
// @Summary 删除产品套件
// @Description 删除指定产品套件,自动解除关联库存的绑定
// @Tags 产品套件管理
// @Produce json
// @Param id path int true "套件ID"
// @Security BearerAuth
// @Success 200 {object} SwagAPIResponse "删除成功"
// @Failure 404 {object} SwagAPIResponse "套件不存在"
// @Router /admin/product-suites/{id} [delete]
func (pc *ProductSuiteAdminController) Delete(c *gin.Context) {
record, err := pc.findByID(c.Param("id"))
if err != nil {
@@ -31,6 +31,14 @@ func NewProjectProductTemplateAdminController() *ProjectProductTemplateAdminCont
return &ProjectProductTemplateAdminController{DB: config.DB}
}
// @Summary 获取项目产品模板列表
// @Description 查询项目产品模板列表,含项目类型和产品名称
// @Tags 项目产品模板管理
// @Produce json
// @Param projectTypeCode query string false "项目类型代码筛选"
// @Security BearerAuth
// @Success 200 {object} SwagAPIResponse "查询成功"
// @Router /admin/project-product-templates [get]
func (pc *ProjectProductTemplateAdminController) List(c *gin.Context) {
var items []models.ProjectProductTemplate
query := pc.DB.Model(&models.ProjectProductTemplate{}).Order("project_type_code ASC, sort ASC, id ASC")
+42
View File
@@ -29,6 +29,16 @@ func NewProjectTypeAdminController() *ProjectTypeAdminController {
return &ProjectTypeAdminController{DB: config.DB}
}
// @Summary 获取项目类型列表
// @Description 查询项目类型列表,支持按关键词/是否支持网关/是否启用筛选
// @Tags 项目类型管理
// @Produce json
// @Param keyword query string false "关键词(代码/名称/描述模糊搜索)"
// @Param supportsGateway query bool false "是否支持网关"
// @Param isActive query bool false "是否启用"
// @Security BearerAuth
// @Success 200 {object} SwagAPIResponse "查询成功"
// @Router /admin/project-types [get]
func (pc *ProjectTypeAdminController) List(c *gin.Context) {
var items []models.ProjectType
query := pc.DB.Model(&models.ProjectType{}).Order("sort ASC, id ASC")
@@ -61,6 +71,16 @@ func (pc *ProjectTypeAdminController) List(c *gin.Context) {
writeSuccess(c, http.StatusOK, "query success", items)
}
// @Summary 创建项目类型
// @Description 创建新的项目类型
// @Tags 项目类型管理
// @Accept json
// @Produce json
// @Param projectType body projectTypePayload true "项目类型信息"
// @Security BearerAuth
// @Success 201 {object} SwagAPIResponse "创建成功"
// @Failure 400 {object} SwagAPIResponse "请求参数错误"
// @Router /admin/project-types [post]
func (pc *ProjectTypeAdminController) Create(c *gin.Context) {
var payload projectTypePayload
if err := c.ShouldBindJSON(&payload); err != nil {
@@ -87,6 +107,18 @@ func (pc *ProjectTypeAdminController) Create(c *gin.Context) {
writeSuccess(c, http.StatusCreated, "create success", record)
}
// @Summary 更新项目类型
// @Description 更新指定项目类型的信息
// @Tags 项目类型管理
// @Accept json
// @Produce json
// @Param id path int true "项目类型ID"
// @Param projectType body projectTypePayload true "更新信息"
// @Security BearerAuth
// @Success 200 {object} SwagAPIResponse "更新成功"
// @Failure 400 {object} SwagAPIResponse "请求参数错误"
// @Failure 404 {object} SwagAPIResponse "项目类型不存在"
// @Router /admin/project-types/{id} [put]
func (pc *ProjectTypeAdminController) Update(c *gin.Context) {
record, err := pc.findByID(c.Param("id"))
if err != nil {
@@ -118,6 +150,16 @@ func (pc *ProjectTypeAdminController) Update(c *gin.Context) {
writeSuccess(c, http.StatusOK, "update success", record)
}
// @Summary 删除项目类型
// @Description 删除指定项目类型(被网关引用的无法删除)
// @Tags 项目类型管理
// @Produce json
// @Param id path int true "项目类型ID"
// @Security BearerAuth
// @Success 200 {object} SwagAPIResponse "删除成功"
// @Failure 404 {object} SwagAPIResponse "项目类型不存在"
// @Failure 409 {object} SwagAPIResponse "已被网关引用无法删除"
// @Router /admin/project-types/{id} [delete]
func (pc *ProjectTypeAdminController) Delete(c *gin.Context) {
record, err := pc.findByID(c.Param("id"))
if err != nil {
+38
View File
@@ -15,3 +15,41 @@ func writeSuccess(c *gin.Context, httpStatus int, msg string, data interface{})
func writeError(c *gin.Context, httpStatus int, msg string) {
c.JSON(httpStatus, APIResponse{Data: nil, Msg: msg, Code: httpStatus})
}
// Swagger response model types
// SwagAPIResponse 通用API响应
type SwagAPIResponse struct {
Data interface{} `json:"data"` // 响应数据
Msg string `json:"msg"` // 响应消息
Code int `json:"code"` // HTTP状态码
}
// SwagPagination 分页信息
type SwagPagination struct {
CurrentPage int `json:"currentPage"` // 当前页码
PageSize int `json:"pageSize"` // 每页数量
TotalList int64 `json:"totalList"` // 总记录数
TotalPage int `json:"totalPage"` // 总页数
}
// SwagPaginationData 分页响应数据
type SwagPaginationData struct {
List interface{} `json:"list"`
Pagination SwagPagination `json:"pagination"`
}
// SwagLoginRequest 登录请求
type SwagLoginRequest struct {
Username string `json:"username"` // 用户名
Password string `json:"password"` // 密码
}
// SwagRegisterRequest 注册请求
type SwagRegisterRequest struct {
Username string `json:"username"` // 用户名
Password string `json:"password"` // 密码
Role string `json:"role"` // 角色
FlavorType string `json:"flavorType"` // 类型
RegionIDs []uint32 `json:"regionIds"` // 区域ID列表
}
+52
View File
@@ -34,6 +34,18 @@ type analysisRecordListParams struct {
// --- 查询接口 ---
// @Summary 获取AI分析记录列表
// @Description 分页查询AI分析记录支持按区域和时间范围筛选
// @Tags 统计管理
// @Produce json
// @Param pageNum query int false "页码(默认1)"
// @Param pageSize query int false "每页数量(默认10,最大100)"
// @Param regionId query int false "区域ID"
// @Param startTime query int false "开始时间(毫秒时间戳)"
// @Param endTime query int false "结束时间(毫秒时间戳)"
// @Security BearerAuth
// @Success 200 {object} SwagAPIResponse "查询成功"
// @Router /admin/statistics/ai-analysis-records [get]
func (sc *StatisticsController) ListAIAnalysisRecords(c *gin.Context) {
var params analysisRecordListParams
if err := c.ShouldBindQuery(&params); err != nil {
@@ -84,6 +96,15 @@ func (sc *StatisticsController) ListAIAnalysisRecords(c *gin.Context) {
// --- 删除接口 ---
// @Summary 删除AI分析记录
// @Description 删除指定的AI分析记录
// @Tags 统计管理
// @Produce json
// @Param id path int true "记录ID"
// @Security BearerAuth
// @Success 200 {object} SwagAPIResponse "删除成功"
// @Failure 404 {object} SwagAPIResponse "记录不存在"
// @Router /admin/statistics/ai-analysis-records/{id} [delete]
func (sc *StatisticsController) DeleteAIAnalysisRecord(c *gin.Context) {
id := strings.TrimSpace(c.Param("id"))
if id == "" {
@@ -137,6 +158,16 @@ type regionStatisticsItem struct {
LastUsedAt *time.Time `json:"lastUsedAt"`
}
// @Summary AI分析区域统计
// @Description 按区域统计AI分析的使用情况包括调用次数、Token消耗、费用等
// @Tags 统计管理
// @Produce json
// @Param regionId query int false "区域ID"
// @Param startTime query int false "开始时间(毫秒时间戳)"
// @Param endTime query int false "结束时间(毫秒时间戳)"
// @Security BearerAuth
// @Success 200 {object} SwagAPIResponse "查询成功"
// @Router /admin/statistics/ai-analysis [get]
func (sc *StatisticsController) StatisticsByRegion(c *gin.Context) {
regionIDStr := c.Query("regionId")
startTimeStr := c.Query("startTime")
@@ -395,6 +426,17 @@ type trainingSessionRegionStatisticsItem struct {
LastPublishedAt *time.Time `json:"lastPublishedAt"`
}
// @Summary 训练会话区域统计
// @Description 按区域统计MQTT训练会话情况包括开始、结束、完成、进行中的会话数
// @Tags 统计管理
// @Produce json
// @Param regionId query int false "区域ID"
// @Param flavorType query string false "类型筛选"
// @Param startTime query int false "开始时间(毫秒时间戳)"
// @Param endTime query int false "结束时间(毫秒时间戳)"
// @Security BearerAuth
// @Success 200 {object} SwagAPIResponse "查询成功"
// @Router /admin/statistics/mqtt-training-sessions [get]
func (sc *StatisticsController) TrainingSessionStatisticsByRegion(c *gin.Context) {
regionIDStr := c.Query("regionId")
flavorType := strings.TrimSpace(c.Query("flavorType"))
@@ -624,6 +666,16 @@ func (sc *StatisticsController) TrainingSessionStatisticsByRegion(c *gin.Context
})
}
// @Summary AI分析时间线统计
// @Description 按日期统计AI分析的使用情况趋势含总体和分区域数据
// @Tags 统计管理
// @Produce json
// @Param regionId query int false "区域ID"
// @Param startTime query int false "开始时间(毫秒时间戳)"
// @Param endTime query int false "结束时间(毫秒时间戳)"
// @Security BearerAuth
// @Success 200 {object} SwagAPIResponse "查询成功"
// @Router /admin/statistics/ai-analysis-timeline [get]
func (sc *StatisticsController) TimelineStatistics(c *gin.Context) {
regionIDStr := c.Query("regionId")
startTimeStr := c.Query("startTime")
+45 -1
View File
@@ -24,7 +24,17 @@ func NewStepTrainingController() *StepTrainingController {
return &StepTrainingController{DB: config.DB}
}
// 接收训练记录
// @Summary 创建踏步训练记录
// @Description 接收并保存踏步训练记录,包含心率和步频数据,异步计算回归结果
// @Tags 踏步训练
// @Accept json
// @Produce json
// @Param record body SwagAPIResponse true "踏步训练记录"
// @Security BearerAuth
// @Success 201 {object} SwagAPIResponse "保存成功"
// @Failure 400 {object} SwagAPIResponse "请求参数错误"
// @Failure 401 {object} SwagAPIResponse "未认证"
// @Router /step [post]
func (tc *StepTrainingController) CreateTrainingRecord(c *gin.Context) {
var record models.StepTrainRecord
@@ -123,6 +133,17 @@ func (tc *StepTrainingController) CreateTrainingRecord(c *gin.Context) {
})
}
// @Summary 获取踏步训练记录列表
// @Description 分页获取当前用户的踏步训练记录,按开始时间倒序
// @Tags 踏步训练
// @Produce json
// @Param pageNum query int false "页码(默认1)"
// @Param pageSize query int false "每页数量(默认10,最大100)"
// @Security BearerAuth
// @Success 200 {object} SwagAPIResponse "查询成功"
// @Failure 400 {object} SwagAPIResponse "请求参数错误"
// @Failure 401 {object} SwagAPIResponse "未认证"
// @Router /step/train-records [get]
func (tc *StepTrainingController) GetTrainingRecords(c *gin.Context) {
// 定义分页参数结构
type PaginationParams struct {
@@ -191,6 +212,18 @@ func (tc *StepTrainingController) GetTrainingRecords(c *gin.Context) {
},
})
}
// @Summary 获取踏步训练详情
// @Description 根据训练ID获取踏步训练的详细信息包含心率和步频数据
// @Tags 踏步训练
// @Produce json
// @Param trainId path int true "训练ID"
// @Security BearerAuth
// @Success 200 {object} SwagAPIResponse "查询成功"
// @Failure 400 {object} SwagAPIResponse "请求参数错误"
// @Failure 401 {object} SwagAPIResponse "未认证"
// @Failure 404 {object} SwagAPIResponse "训练记录不存在"
// @Router /step/train-data/{trainId} [get]
func (tc *StepTrainingController) GetTrainingRecordByTrainId(c *gin.Context) {
// 从URL路径参数获取trainId
trainId := c.Param("trainId")
@@ -748,6 +781,17 @@ func (tc *StepTrainingController) GetRegressionResult(c *gin.Context) {
})
}
// @Summary 获取训练排名
// @Description 根据训练ID和回归类型获取训练排名
// @Tags 踏步训练
// @Produce json
// @Param trainId path int true "训练ID"
// @Param type query int true "回归类型: 1=线性回归 | 3=二次回归"
// @Security BearerAuth
// @Success 200 {object} SwagAPIResponse "查询成功"
// @Failure 400 {object} SwagAPIResponse "请求参数错误"
// @Failure 401 {object} SwagAPIResponse "未认证"
// @Router /step/train-rank/{trainId} [get]
func (tc *StepTrainingController) GetTrainingRank(c *gin.Context) {
// 参数解析
trainIdStr := c.Param("trainId")
+29
View File
@@ -29,6 +29,13 @@ func NewSystemDebugController() *SystemDebugController {
return &SystemDebugController{}
}
// @Summary 获取MQTT调试状态
// @Description 获取MQTT调试服务的当前运行状态
// @Tags 系统调试
// @Produce json
// @Security BearerAuth
// @Success 200 {object} SwagAPIResponse "查询成功"
// @Router /admin/system-debug/mqtt/status [get]
func (sc *SystemDebugController) MqttStatus(c *gin.Context) {
service := mqtt.GetDebugService()
if service == nil {
@@ -38,6 +45,15 @@ func (sc *SystemDebugController) MqttStatus(c *gin.Context) {
writeSuccess(c, http.StatusOK, "query success", service.Status())
}
// @Summary 启动MQTT调试
// @Description 启动MQTT调试服务
// @Tags 系统调试
// @Accept json
// @Produce json
// @Param persist body mqttDebugStartRequest false "是否持久化到数据库"
// @Security BearerAuth
// @Success 200 {object} SwagAPIResponse "启动成功"
// @Router /admin/system-debug/mqtt/start [post]
func (sc *SystemDebugController) StartMqtt(c *gin.Context) {
service := mqtt.GetDebugService()
if service == nil {
@@ -56,6 +72,13 @@ func (sc *SystemDebugController) StartMqtt(c *gin.Context) {
writeSuccess(c, http.StatusOK, "start success", service.Status())
}
// @Summary 停止MQTT调试
// @Description 停止MQTT调试服务
// @Tags 系统调试
// @Produce json
// @Security BearerAuth
// @Success 200 {object} SwagAPIResponse "停止成功"
// @Router /admin/system-debug/mqtt/stop [post]
func (sc *SystemDebugController) StopMqtt(c *gin.Context) {
service := mqtt.GetDebugService()
if service == nil {
@@ -66,6 +89,12 @@ func (sc *SystemDebugController) StopMqtt(c *gin.Context) {
writeSuccess(c, http.StatusOK, "stop success", service.Status())
}
// @Summary MQTT WebSocket连接
// @Description 通过WebSocket实时监听MQTT消息需要SuperAdmin权限
// @Tags 系统调试
// @Param token query string true "JWT Token"
// @Success 101 "切换为WebSocket协议"
// @Router /admin/system-debug/mqtt/ws [get]
func (sc *SystemDebugController) MqttWebSocket(c *gin.Context) {
service := mqtt.GetDebugService()
if service == nil {
+31 -2
View File
@@ -41,7 +41,15 @@ func NewTrainingController() *TrainingController {
return &TrainingController{DB: config.DB}
}
// 接收训练记录
// @Summary 创建训练记录
// @Description 接收并保存训练记录及心率数据支持重复上传按train_id去重更新
// @Tags 训练管理
// @Accept json
// @Produce json
// @Param record body SwagAPIResponse true "训练记录数据"
// @Success 201 {object} SwagAPIResponse "保存成功"
// @Failure 400 {object} SwagAPIResponse "请求参数错误"
// @Router /train-records [post]
func (tc *TrainingController) CreateTrainingRecord(c *gin.Context) {
var record models.TrainRecord
@@ -121,6 +129,15 @@ type trainingSessionRequest struct {
AppName string `json:"appName"`
}
// @Summary 上传训练会话
// @Description 上传训练开始/结束会话用于MQTT训练会话追踪
// @Tags 训练管理
// @Accept json
// @Produce json
// @Param session body trainingSessionRequest true "训练会话数据"
// @Success 200 {object} SwagAPIResponse "操作成功"
// @Failure 400 {object} SwagAPIResponse "请求参数错误"
// @Router /train-records/session [post]
func (tc *TrainingController) UploadTrainingSession(c *gin.Context) {
var req trainingSessionRequest
if err := c.ShouldBindJSON(&req); err != nil {
@@ -225,6 +242,12 @@ type cloudLessonPlanItem struct {
UploaderName string `json:"uploaderName"`
}
// @Summary 获取云端教案列表
// @Description 获取所有云端教案文件列表
// @Tags 训练管理
// @Produce json
// @Success 200 {object} SwagAPIResponse "查询成功"
// @Router /train-records/cloud-files [get]
func (tc *TrainingController) ListCloudLessonPlans(c *gin.Context) {
var records []models.AppFile
if err := tc.DB.Where("file_type = ?", models.AppFileTypeLessonPlan).Order("created_at DESC").Find(&records).Error; err != nil {
@@ -266,7 +289,13 @@ type CurvePoint struct {
Y float64 `json:"y"` // Y坐标
}
// analysis_handler.go
// @Summary 心率曲线分析
// @Description 对历史心率数据进行统计分析和正态分布曲线拟合
// @Tags 训练管理
// @Produce json
// @Success 200 {object} SwagAPIResponse "分析成功"
// @Failure 400 {object} SwagAPIResponse "数据量不足"
// @Router /train-records/analysis [get]
func (tc *TrainingController) HandleCurveAnalysis(c *gin.Context) {
// 获取数据库连接(根据实际项目配置调整)
+42
View File
@@ -49,6 +49,16 @@ func NewUserAdminController() *UserAdminController {
return &UserAdminController{DB: config.DB}
}
// @Summary 获取用户列表
// @Description 查询系统用户列表,支持按关键词/角色/类型筛选
// @Tags 用户管理
// @Produce json
// @Param keyword query string false "关键词(用户名/邮箱/手机号模糊搜索)"
// @Param role query string false "角色筛选"
// @Param flavorType query string false "类型筛选"
// @Security BearerAuth
// @Success 200 {object} SwagAPIResponse "查询成功"
// @Router /admin/users [get]
func (uc *UserAdminController) List(c *gin.Context) {
var users []models.User
query := uc.DB.Preload("Regions").Order("id ASC")
@@ -76,6 +86,16 @@ func (uc *UserAdminController) List(c *gin.Context) {
writeSuccess(c, http.StatusOK, "query success", items)
}
// @Summary 创建用户
// @Description 创建新的系统用户
// @Tags 用户管理
// @Accept json
// @Produce json
// @Param user body userAdminPayload true "用户信息"
// @Security BearerAuth
// @Success 201 {object} SwagAPIResponse "创建成功"
// @Failure 400 {object} SwagAPIResponse "请求参数错误"
// @Router /admin/users [post]
func (uc *UserAdminController) Create(c *gin.Context) {
var payload userAdminPayload
if err := c.ShouldBindJSON(&payload); err != nil {
@@ -127,6 +147,18 @@ func (uc *UserAdminController) Create(c *gin.Context) {
writeSuccess(c, http.StatusCreated, "create success", items[0])
}
// @Summary 更新用户信息
// @Description 更新指定用户的详细信息支持重置密码和吊销Token
// @Tags 用户管理
// @Accept json
// @Produce json
// @Param id path int true "用户ID"
// @Param user body userAdminPayload true "更新信息"
// @Security BearerAuth
// @Success 200 {object} SwagAPIResponse "更新成功"
// @Failure 400 {object} SwagAPIResponse "请求参数错误"
// @Failure 404 {object} SwagAPIResponse "用户不存在"
// @Router /admin/users/{id} [put]
func (uc *UserAdminController) Update(c *gin.Context) {
user, err := uc.findUserByID(c.Param("id"))
if err != nil {
@@ -212,6 +244,16 @@ func (uc *UserAdminController) Update(c *gin.Context) {
writeSuccess(c, http.StatusOK, "update success", items[0])
}
// @Summary 删除用户
// @Description 删除指定用户不能删除admin账号和当前登录用户
// @Tags 用户管理
// @Produce json
// @Param id path int true "用户ID"
// @Security BearerAuth
// @Success 200 {object} SwagAPIResponse "删除成功"
// @Failure 400 {object} SwagAPIResponse "无法删除受保护账号"
// @Failure 404 {object} SwagAPIResponse "用户不存在"
// @Router /admin/users/{id} [delete]
func (uc *UserAdminController) Delete(c *gin.Context) {
user, err := uc.findUserByID(c.Param("id"))
if err != nil {