From b7843641cadd7b7aa269817f6a69827fe485262b Mon Sep 17 00:00:00 2001 From: laoboli <1293528695@qq.com> Date: Mon, 4 May 2026 16:20:46 +0800 Subject: [PATCH] feat: swag. --- controllers/ai.go | 17 + controllers/gateway.go | 65 +- controllers/kindergarten_admin.go | 40 + controllers/lesson_plan.go | 78 + controllers/login.go | 23 +- controllers/product_definition_admin.go | 42 + controllers/product_inventory_admin.go | 46 + controllers/product_prototype_admin.go | 41 + controllers/product_suite_admin.go | 40 + controllers/project_product_template_admin.go | 8 + controllers/project_type_admin.go | 42 + controllers/response.go | 38 + controllers/statistics.go | 52 + controllers/step_train.go | 46 +- controllers/system_debug.go | 29 + controllers/train.go | 33 +- controllers/user_admin.go | 42 + docs/docs.go | 3273 +++++++++++++++++ docs/swagger.json | 3251 ++++++++++++++++ docs/swagger.yaml | 2078 +++++++++++ go.mod | 20 +- go.sum | 77 + main.go | 8 + routes/routes.go | 6 + 24 files changed, 9376 insertions(+), 19 deletions(-) create mode 100644 docs/docs.go create mode 100644 docs/swagger.json create mode 100644 docs/swagger.yaml diff --git a/controllers/ai.go b/controllers/ai.go index da660a4..7c4d3b9 100644 --- a/controllers/ai.go +++ b/controllers/ai.go @@ -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 { diff --git a/controllers/gateway.go b/controllers/gateway.go index cb4cedb..a9a5ba2 100644 --- a/controllers/gateway.go +++ b/controllers/gateway.go @@ -36,9 +36,17 @@ func NewGatewayAdminController() *GatewayAdminController { return &GatewayAdminController{DB: config.DB} } -// List 获取网关列表 -// GET /api/v1/gateways?keyword=&isSold=&projectType=®ionId= -// 超级管理员可查询全部;操作员/区域管理员仅能查询所属 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 { diff --git a/controllers/kindergarten_admin.go b/controllers/kindergarten_admin.go index 4965532..055d630 100644 --- a/controllers/kindergarten_admin.go +++ b/controllers/kindergarten_admin.go @@ -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 { diff --git a/controllers/lesson_plan.go b/controllers/lesson_plan.go index c1f3fdc..001d249 100644 --- a/controllers/lesson_plan.go +++ b/controllers/lesson_plan.go @@ -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 { diff --git a/controllers/login.go b/controllers/login.go index cfcfb81..a49a36d 100644 --- a/controllers/login.go +++ b/controllers/login.go @@ -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 { diff --git a/controllers/product_definition_admin.go b/controllers/product_definition_admin.go index 708da87..4d1387f 100644 --- a/controllers/product_definition_admin.go +++ b/controllers/product_definition_admin.go @@ -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 { diff --git a/controllers/product_inventory_admin.go b/controllers/product_inventory_admin.go index 3c12469..4be5345 100644 --- a/controllers/product_inventory_admin.go +++ b/controllers/product_inventory_admin.go @@ -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 { diff --git a/controllers/product_prototype_admin.go b/controllers/product_prototype_admin.go index 0d56fb3..59cae09 100644 --- a/controllers/product_prototype_admin.go +++ b/controllers/product_prototype_admin.go @@ -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 { diff --git a/controllers/product_suite_admin.go b/controllers/product_suite_admin.go index defeb10..76bc66a 100644 --- a/controllers/product_suite_admin.go +++ b/controllers/product_suite_admin.go @@ -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 { diff --git a/controllers/project_product_template_admin.go b/controllers/project_product_template_admin.go index f7a62de..f1c1a9a 100644 --- a/controllers/project_product_template_admin.go +++ b/controllers/project_product_template_admin.go @@ -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") diff --git a/controllers/project_type_admin.go b/controllers/project_type_admin.go index 1d2fc0c..5dd2cb1 100644 --- a/controllers/project_type_admin.go +++ b/controllers/project_type_admin.go @@ -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 { diff --git a/controllers/response.go b/controllers/response.go index d958608..a08a7b0 100644 --- a/controllers/response.go +++ b/controllers/response.go @@ -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列表 +} diff --git a/controllers/statistics.go b/controllers/statistics.go index 7d8feca..d035cad 100644 --- a/controllers/statistics.go +++ b/controllers/statistics.go @@ -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(¶ms); 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") diff --git a/controllers/step_train.go b/controllers/step_train.go index 411abea..7c3d661 100644 --- a/controllers/step_train.go +++ b/controllers/step_train.go @@ -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") diff --git a/controllers/system_debug.go b/controllers/system_debug.go index 22be359..5415ca4 100644 --- a/controllers/system_debug.go +++ b/controllers/system_debug.go @@ -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 { diff --git a/controllers/train.go b/controllers/train.go index 011df80..68790de 100644 --- a/controllers/train.go +++ b/controllers/train.go @@ -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) { // 获取数据库连接(根据实际项目配置调整) diff --git a/controllers/user_admin.go b/controllers/user_admin.go index d536f89..3cac0b2 100644 --- a/controllers/user_admin.go +++ b/controllers/user_admin.go @@ -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 { diff --git a/docs/docs.go b/docs/docs.go new file mode 100644 index 0000000..99e4337 --- /dev/null +++ b/docs/docs.go @@ -0,0 +1,3273 @@ +// Package docs Code generated by swaggo/swag. DO NOT EDIT +package docs + +import "github.com/swaggo/swag" + +const docTemplate = `{ + "schemes": {{ marshal .Schemes }}, + "swagger": "2.0", + "info": { + "description": "{{escape .Description}}", + "title": "{{.Title}}", + "contact": {}, + "version": "{{.Version}}" + }, + "host": "{{.Host}}", + "basePath": "{{.BasePath}}", + "paths": { + "/admin/gateways": { + "get": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "查询网关列表,支持关键词/售出状态/项目类型/区域筛选。超级管理员可查全部,操作员只能查所属区域", + "produces": [ + "application/json" + ], + "tags": [ + "网关管理" + ], + "summary": "获取网关列表", + "parameters": [ + { + "type": "string", + "description": "关键词(名称/MAC模糊搜索)", + "name": "keyword", + "in": "query" + }, + { + "type": "boolean", + "description": "售出状态", + "name": "isSold", + "in": "query" + }, + { + "type": "string", + "description": "项目类型", + "name": "projectType", + "in": "query" + }, + { + "type": "integer", + "description": "区域ID", + "name": "regionId", + "in": "query" + } + ], + "responses": { + "200": { + "description": "查询成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + }, + "post": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "创建新的网关记录,自动同步到产品库存", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "网关管理" + ], + "summary": "创建网关", + "parameters": [ + { + "description": "网关信息", + "name": "gateway", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/controllers.gatewayPayload" + } + } + ], + "responses": { + "201": { + "description": "创建成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "400": { + "description": "请求参数错误", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "409": { + "description": "MAC地址已存在", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/admin/gateways/{id}": { + "put": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "更新指定网关的详细信息,自动同步到产品库存", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "网关管理" + ], + "summary": "更新网关信息", + "parameters": [ + { + "type": "integer", + "description": "网关ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "更新信息", + "name": "gateway", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/controllers.gatewayPayload" + } + } + ], + "responses": { + "200": { + "description": "更新成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "400": { + "description": "请求参数错误", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "404": { + "description": "网关不存在", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + }, + "delete": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "删除指定网关(已售出的网关禁止删除),自动同步删除产品库存", + "produces": [ + "application/json" + ], + "tags": [ + "网关管理" + ], + "summary": "删除网关", + "parameters": [ + { + "type": "integer", + "description": "网关ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "删除成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "403": { + "description": "已售出无法删除", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "404": { + "description": "网关不存在", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/admin/kindergartens": { + "get": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "查询幼儿园列表,支持按名称/地址模糊搜索", + "produces": [ + "application/json" + ], + "tags": [ + "幼儿园管理" + ], + "summary": "获取幼儿园列表", + "parameters": [ + { + "type": "string", + "description": "关键词(名称/地址模糊搜索)", + "name": "keyword", + "in": "query" + } + ], + "responses": { + "200": { + "description": "查询成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + }, + "post": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "创建新的幼儿园记录", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "幼儿园管理" + ], + "summary": "创建幼儿园", + "parameters": [ + { + "description": "幼儿园信息", + "name": "kindergarten", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/controllers.kindergartenPayload" + } + } + ], + "responses": { + "201": { + "description": "创建成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "400": { + "description": "请求参数错误", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/admin/kindergartens/{id}": { + "put": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "更新指定幼儿园的名称、地址和区域", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "幼儿园管理" + ], + "summary": "更新幼儿园信息", + "parameters": [ + { + "type": "integer", + "description": "幼儿园ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "更新信息", + "name": "kindergarten", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/controllers.kindergartenPayload" + } + } + ], + "responses": { + "200": { + "description": "更新成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "400": { + "description": "请求参数错误", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "404": { + "description": "幼儿园不存在", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + }, + "delete": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "删除指定幼儿园,如果被用户绑定则无法删除", + "produces": [ + "application/json" + ], + "tags": [ + "幼儿园管理" + ], + "summary": "删除幼儿园", + "parameters": [ + { + "type": "integer", + "description": "幼儿园ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "删除成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "404": { + "description": "幼儿园不存在", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "409": { + "description": "已绑定用户无法删除", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/admin/product-definitions": { + "get": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "查询产品定义列表,支持按关键词/分类/启用状态筛选", + "produces": [ + "application/json" + ], + "tags": [ + "产品定义管理" + ], + "summary": "获取产品定义列表", + "parameters": [ + { + "type": "string", + "description": "关键词(代码/名称/描述模糊搜索)", + "name": "keyword", + "in": "query" + }, + { + "type": "string", + "description": "分类筛选", + "name": "category", + "in": "query" + }, + { + "type": "boolean", + "description": "是否启用", + "name": "isActive", + "in": "query" + } + ], + "responses": { + "200": { + "description": "查询成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + }, + "post": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "创建新的产品定义", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "产品定义管理" + ], + "summary": "创建产品定义", + "parameters": [ + { + "description": "产品定义信息", + "name": "productDefinition", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/controllers.productDefinitionPayload" + } + } + ], + "responses": { + "201": { + "description": "创建成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "400": { + "description": "请求参数错误", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/admin/product-definitions/{id}": { + "put": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "更新指定产品定义的信息", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "产品定义管理" + ], + "summary": "更新产品定义", + "parameters": [ + { + "type": "integer", + "description": "产品定义ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "更新信息", + "name": "productDefinition", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/controllers.productDefinitionPayload" + } + } + ], + "responses": { + "200": { + "description": "更新成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "400": { + "description": "请求参数错误", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "404": { + "description": "产品定义不存在", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + }, + "delete": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "删除指定产品定义(被库存或模板引用的无法删除)", + "produces": [ + "application/json" + ], + "tags": [ + "产品定义管理" + ], + "summary": "删除产品定义", + "parameters": [ + { + "type": "integer", + "description": "产品定义ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "删除成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "404": { + "description": "产品定义不存在", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "409": { + "description": "已被引用无法删除", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/admin/product-inventories": { + "get": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "查询产品库存列表,支持多条件筛选", + "produces": [ + "application/json" + ], + "tags": [ + "产品库存管理" + ], + "summary": "获取产品库存列表", + "parameters": [ + { + "type": "string", + "description": "关键词(资产名称/序列号/购买方等模糊搜索)", + "name": "keyword", + "in": "query" + }, + { + "type": "string", + "description": "产品代码筛选", + "name": "productCode", + "in": "query" + }, + { + "type": "string", + "description": "项目类型代码筛选", + "name": "projectTypeCode", + "in": "query" + }, + { + "type": "string", + "description": "套件代码筛选", + "name": "suiteCode", + "in": "query" + }, + { + "type": "string", + "description": "状态筛选", + "name": "status", + "in": "query" + }, + { + "type": "string", + "description": "购买方类型筛选", + "name": "soldTargetType", + "in": "query" + }, + { + "type": "integer", + "description": "区域ID", + "name": "regionId", + "in": "query" + } + ], + "responses": { + "200": { + "description": "查询成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + }, + "post": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "创建新的产品库存记录", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "产品库存管理" + ], + "summary": "创建产品库存记录", + "parameters": [ + { + "description": "库存信息", + "name": "inventory", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/controllers.productInventoryPayload" + } + } + ], + "responses": { + "201": { + "description": "创建成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "400": { + "description": "请求参数错误", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/admin/product-inventories/{id}": { + "put": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "更新指定产品库存记录", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "产品库存管理" + ], + "summary": "更新产品库存", + "parameters": [ + { + "type": "integer", + "description": "库存ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "更新信息", + "name": "inventory", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/controllers.productInventoryPayload" + } + } + ], + "responses": { + "200": { + "description": "更新成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "400": { + "description": "请求参数错误", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "404": { + "description": "库存记录不存在", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + }, + "delete": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "删除指定产品库存记录(已售出的无法删除)", + "produces": [ + "application/json" + ], + "tags": [ + "产品库存管理" + ], + "summary": "删除产品库存", + "parameters": [ + { + "type": "integer", + "description": "库存ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "删除成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "404": { + "description": "库存记录不存在", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "409": { + "description": "已售出无法删除", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/admin/product-prototypes": { + "get": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "查询产品原型列表,支持按关键词/产品代码/项目类型筛选", + "produces": [ + "application/json" + ], + "tags": [ + "产品原型管理" + ], + "summary": "获取产品原型列表", + "parameters": [ + { + "type": "string", + "description": "关键词(名称/备注模糊搜索)", + "name": "keyword", + "in": "query" + }, + { + "type": "string", + "description": "产品代码筛选", + "name": "productCode", + "in": "query" + }, + { + "type": "string", + "description": "项目类型代码筛选", + "name": "projectTypeCode", + "in": "query" + } + ], + "responses": { + "200": { + "description": "查询成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + }, + "post": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "创建新的产品原型", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "产品原型管理" + ], + "summary": "创建产品原型", + "parameters": [ + { + "description": "产品原型信息", + "name": "productPrototype", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/controllers.productPrototypePayload" + } + } + ], + "responses": { + "201": { + "description": "创建成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "400": { + "description": "请求参数错误", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/admin/product-prototypes/{id}": { + "put": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "更新指定产品原型的信息", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "产品原型管理" + ], + "summary": "更新产品原型", + "parameters": [ + { + "type": "integer", + "description": "产品原型ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "更新信息", + "name": "productPrototype", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/controllers.productPrototypePayload" + } + } + ], + "responses": { + "200": { + "description": "更新成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "400": { + "description": "请求参数错误", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "404": { + "description": "产品原型不存在", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + }, + "delete": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "删除指定产品原型", + "produces": [ + "application/json" + ], + "tags": [ + "产品原型管理" + ], + "summary": "删除产品原型", + "parameters": [ + { + "type": "integer", + "description": "产品原型ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "删除成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "404": { + "description": "产品原型不存在", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/admin/product-suites": { + "get": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "查询产品套件列表,含套件下的库存明细", + "produces": [ + "application/json" + ], + "tags": [ + "产品套件管理" + ], + "summary": "获取产品套件列表", + "parameters": [ + { + "type": "string", + "description": "关键词(代码/名称/备注模糊搜索)", + "name": "keyword", + "in": "query" + }, + { + "type": "string", + "description": "项目类型代码筛选", + "name": "projectTypeCode", + "in": "query" + } + ], + "responses": { + "200": { + "description": "查询成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + }, + "post": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "创建新的产品套件,可选关联库存记录", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "产品套件管理" + ], + "summary": "创建产品套件", + "parameters": [ + { + "description": "套件信息", + "name": "suite", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/controllers.productSuitePayload" + } + } + ], + "responses": { + "201": { + "description": "创建成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "400": { + "description": "请求参数错误", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/admin/product-suites/{id}": { + "put": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "更新指定产品套件的信息和关联库存", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "产品套件管理" + ], + "summary": "更新产品套件", + "parameters": [ + { + "type": "integer", + "description": "套件ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "更新信息", + "name": "suite", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/controllers.productSuitePayload" + } + } + ], + "responses": { + "200": { + "description": "更新成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "400": { + "description": "请求参数错误", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "404": { + "description": "套件不存在", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + }, + "delete": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "删除指定产品套件,自动解除关联库存的绑定", + "produces": [ + "application/json" + ], + "tags": [ + "产品套件管理" + ], + "summary": "删除产品套件", + "parameters": [ + { + "type": "integer", + "description": "套件ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "删除成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "404": { + "description": "套件不存在", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/admin/project-product-templates": { + "get": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "查询项目产品模板列表,含项目类型和产品名称", + "produces": [ + "application/json" + ], + "tags": [ + "项目产品模板管理" + ], + "summary": "获取项目产品模板列表", + "parameters": [ + { + "type": "string", + "description": "项目类型代码筛选", + "name": "projectTypeCode", + "in": "query" + } + ], + "responses": { + "200": { + "description": "查询成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/admin/project-types": { + "get": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "查询项目类型列表,支持按关键词/是否支持网关/是否启用筛选", + "produces": [ + "application/json" + ], + "tags": [ + "项目类型管理" + ], + "summary": "获取项目类型列表", + "parameters": [ + { + "type": "string", + "description": "关键词(代码/名称/描述模糊搜索)", + "name": "keyword", + "in": "query" + }, + { + "type": "boolean", + "description": "是否支持网关", + "name": "supportsGateway", + "in": "query" + }, + { + "type": "boolean", + "description": "是否启用", + "name": "isActive", + "in": "query" + } + ], + "responses": { + "200": { + "description": "查询成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + }, + "post": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "创建新的项目类型", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "项目类型管理" + ], + "summary": "创建项目类型", + "parameters": [ + { + "description": "项目类型信息", + "name": "projectType", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/controllers.projectTypePayload" + } + } + ], + "responses": { + "201": { + "description": "创建成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "400": { + "description": "请求参数错误", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/admin/project-types/{id}": { + "put": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "更新指定项目类型的信息", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "项目类型管理" + ], + "summary": "更新项目类型", + "parameters": [ + { + "type": "integer", + "description": "项目类型ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "更新信息", + "name": "projectType", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/controllers.projectTypePayload" + } + } + ], + "responses": { + "200": { + "description": "更新成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "400": { + "description": "请求参数错误", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "404": { + "description": "项目类型不存在", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + }, + "delete": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "删除指定项目类型(被网关引用的无法删除)", + "produces": [ + "application/json" + ], + "tags": [ + "项目类型管理" + ], + "summary": "删除项目类型", + "parameters": [ + { + "type": "integer", + "description": "项目类型ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "删除成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "404": { + "description": "项目类型不存在", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "409": { + "description": "已被网关引用无法删除", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/admin/statistics/ai-analysis": { + "get": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "按区域统计AI分析的使用情况,包括调用次数、Token消耗、费用等", + "produces": [ + "application/json" + ], + "tags": [ + "统计管理" + ], + "summary": "AI分析区域统计", + "parameters": [ + { + "type": "integer", + "description": "区域ID", + "name": "regionId", + "in": "query" + }, + { + "type": "integer", + "description": "开始时间(毫秒时间戳)", + "name": "startTime", + "in": "query" + }, + { + "type": "integer", + "description": "结束时间(毫秒时间戳)", + "name": "endTime", + "in": "query" + } + ], + "responses": { + "200": { + "description": "查询成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/admin/statistics/ai-analysis-records": { + "get": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "分页查询AI分析记录,支持按区域和时间范围筛选", + "produces": [ + "application/json" + ], + "tags": [ + "统计管理" + ], + "summary": "获取AI分析记录列表", + "parameters": [ + { + "type": "integer", + "description": "页码(默认1)", + "name": "pageNum", + "in": "query" + }, + { + "type": "integer", + "description": "每页数量(默认10,最大100)", + "name": "pageSize", + "in": "query" + }, + { + "type": "integer", + "description": "区域ID", + "name": "regionId", + "in": "query" + }, + { + "type": "integer", + "description": "开始时间(毫秒时间戳)", + "name": "startTime", + "in": "query" + }, + { + "type": "integer", + "description": "结束时间(毫秒时间戳)", + "name": "endTime", + "in": "query" + } + ], + "responses": { + "200": { + "description": "查询成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/admin/statistics/ai-analysis-records/{id}": { + "delete": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "删除指定的AI分析记录", + "produces": [ + "application/json" + ], + "tags": [ + "统计管理" + ], + "summary": "删除AI分析记录", + "parameters": [ + { + "type": "integer", + "description": "记录ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "删除成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "404": { + "description": "记录不存在", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/admin/statistics/ai-analysis-timeline": { + "get": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "按日期统计AI分析的使用情况趋势,含总体和分区域数据", + "produces": [ + "application/json" + ], + "tags": [ + "统计管理" + ], + "summary": "AI分析时间线统计", + "parameters": [ + { + "type": "integer", + "description": "区域ID", + "name": "regionId", + "in": "query" + }, + { + "type": "integer", + "description": "开始时间(毫秒时间戳)", + "name": "startTime", + "in": "query" + }, + { + "type": "integer", + "description": "结束时间(毫秒时间戳)", + "name": "endTime", + "in": "query" + } + ], + "responses": { + "200": { + "description": "查询成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/admin/statistics/mqtt-training-sessions": { + "get": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "按区域统计MQTT训练会话情况,包括开始、结束、完成、进行中的会话数", + "produces": [ + "application/json" + ], + "tags": [ + "统计管理" + ], + "summary": "训练会话区域统计", + "parameters": [ + { + "type": "integer", + "description": "区域ID", + "name": "regionId", + "in": "query" + }, + { + "type": "string", + "description": "类型筛选", + "name": "flavorType", + "in": "query" + }, + { + "type": "integer", + "description": "开始时间(毫秒时间戳)", + "name": "startTime", + "in": "query" + }, + { + "type": "integer", + "description": "结束时间(毫秒时间戳)", + "name": "endTime", + "in": "query" + } + ], + "responses": { + "200": { + "description": "查询成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/admin/system-debug/mqtt/start": { + "post": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "启动MQTT调试服务", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "系统调试" + ], + "summary": "启动MQTT调试", + "parameters": [ + { + "description": "是否持久化到数据库", + "name": "persist", + "in": "body", + "schema": { + "$ref": "#/definitions/controllers.mqttDebugStartRequest" + } + } + ], + "responses": { + "200": { + "description": "启动成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/admin/system-debug/mqtt/status": { + "get": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "获取MQTT调试服务的当前运行状态", + "produces": [ + "application/json" + ], + "tags": [ + "系统调试" + ], + "summary": "获取MQTT调试状态", + "responses": { + "200": { + "description": "查询成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/admin/system-debug/mqtt/stop": { + "post": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "停止MQTT调试服务", + "produces": [ + "application/json" + ], + "tags": [ + "系统调试" + ], + "summary": "停止MQTT调试", + "responses": { + "200": { + "description": "停止成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/admin/system-debug/mqtt/ws": { + "get": { + "description": "通过WebSocket实时监听MQTT消息(需要SuperAdmin权限)", + "tags": [ + "系统调试" + ], + "summary": "MQTT WebSocket连接", + "parameters": [ + { + "type": "string", + "description": "JWT Token", + "name": "token", + "in": "query", + "required": true + } + ], + "responses": { + "101": { + "description": "切换为WebSocket协议" + } + } + } + }, + "/admin/users": { + "get": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "查询系统用户列表,支持按关键词/角色/类型筛选", + "produces": [ + "application/json" + ], + "tags": [ + "用户管理" + ], + "summary": "获取用户列表", + "parameters": [ + { + "type": "string", + "description": "关键词(用户名/邮箱/手机号模糊搜索)", + "name": "keyword", + "in": "query" + }, + { + "type": "string", + "description": "角色筛选", + "name": "role", + "in": "query" + }, + { + "type": "string", + "description": "类型筛选", + "name": "flavorType", + "in": "query" + } + ], + "responses": { + "200": { + "description": "查询成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + }, + "post": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "创建新的系统用户", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "用户管理" + ], + "summary": "创建用户", + "parameters": [ + { + "description": "用户信息", + "name": "user", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/controllers.userAdminPayload" + } + } + ], + "responses": { + "201": { + "description": "创建成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "400": { + "description": "请求参数错误", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/admin/users/{id}": { + "put": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "更新指定用户的详细信息,支持重置密码和吊销Token", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "用户管理" + ], + "summary": "更新用户信息", + "parameters": [ + { + "type": "integer", + "description": "用户ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "更新信息", + "name": "user", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/controllers.userAdminPayload" + } + } + ], + "responses": { + "200": { + "description": "更新成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "400": { + "description": "请求参数错误", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "404": { + "description": "用户不存在", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + }, + "delete": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "删除指定用户(不能删除admin账号和当前登录用户)", + "produces": [ + "application/json" + ], + "tags": [ + "用户管理" + ], + "summary": "删除用户", + "parameters": [ + { + "type": "integer", + "description": "用户ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "删除成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "400": { + "description": "无法删除受保护账号", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "404": { + "description": "用户不存在", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/gateways/by-mac": { + "get": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "根据MAC地址查询网关信息(支持格式兼容:带冒号/横线/纯数字)", + "produces": [ + "application/json" + ], + "tags": [ + "网关管理" + ], + "summary": "按MAC查询网关", + "parameters": [ + { + "type": "string", + "description": "MAC地址", + "name": "mac", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "查询成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "400": { + "description": "MAC参数为空", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "404": { + "description": "未找到该网关", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/lesson-plans": { + "get": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "获取教案文件列表(非分页),按创建时间倒序", + "produces": [ + "application/json" + ], + "tags": [ + "教案管理" + ], + "summary": "获取教案列表", + "responses": { + "200": { + "description": "查询成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "401": { + "description": "未认证", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/lesson-plans/page": { + "get": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "分页获取教案文件列表,支持文件名模糊搜索、上传者搜索、区域筛选、排序", + "produces": [ + "application/json" + ], + "tags": [ + "教案管理" + ], + "summary": "分页查询教案", + "parameters": [ + { + "type": "integer", + "description": "页码(默认1)", + "name": "pageNum", + "in": "query" + }, + { + "type": "integer", + "description": "每页数量(默认10,最大100)", + "name": "pageSize", + "in": "query" + }, + { + "type": "string", + "description": "文件名模糊搜索", + "name": "keyword", + "in": "query" + }, + { + "type": "string", + "description": "上传者名模糊搜索", + "name": "uploaderName", + "in": "query" + }, + { + "type": "integer", + "description": "区域ID", + "name": "regionId", + "in": "query" + }, + { + "type": "string", + "description": "排序字段: file_size | created_at", + "name": "sortBy", + "in": "query" + }, + { + "type": "string", + "description": "排序方向: asc | desc", + "name": "sortOrder", + "in": "query" + } + ], + "responses": { + "200": { + "description": "查询成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "400": { + "description": "请求参数错误", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "401": { + "description": "未认证", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/lesson-plans/share/{code}/download": { + "get": { + "description": "通过6位分享码下载教案文件(无需认证)", + "produces": [ + "application/octet-stream" + ], + "tags": [ + "教案管理" + ], + "summary": "通过分享码下载教案", + "parameters": [ + { + "type": "string", + "description": "6位分享码", + "name": "code", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "教案文件", + "schema": { + "type": "file" + } + }, + "400": { + "description": "分享码无效", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "404": { + "description": "分享码过期或不存在", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/lesson-plans/upload": { + "post": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "上传 .docx 格式的教案文件,支持MD5去重,最大10MB", + "consumes": [ + "multipart/form-data" + ], + "produces": [ + "application/json" + ], + "tags": [ + "教案管理" + ], + "summary": "上传教案文件", + "parameters": [ + { + "type": "file", + "description": "教案文件(.docx)", + "name": "file", + "in": "formData", + "required": true + } + ], + "responses": { + "201": { + "description": "上传成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "400": { + "description": "请求参数错误", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "401": { + "description": "未认证", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "409": { + "description": "文件已存在", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/lesson-plans/{id}": { + "delete": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "删除教案文件及其关联的分享码", + "produces": [ + "application/json" + ], + "tags": [ + "教案管理" + ], + "summary": "删除教案文件", + "parameters": [ + { + "type": "integer", + "description": "教案ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "删除成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "401": { + "description": "未认证", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "403": { + "description": "无权限", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "404": { + "description": "文件不存在", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/lesson-plans/{id}/download": { + "get": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "通过ID下载教案文件,自动更新下载计数和最后下载时间", + "produces": [ + "application/octet-stream" + ], + "tags": [ + "教案管理" + ], + "summary": "下载教案文件", + "parameters": [ + { + "type": "integer", + "description": "教案ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "教案文件", + "schema": { + "type": "file" + } + }, + "401": { + "description": "未认证", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "403": { + "description": "无权限", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "404": { + "description": "文件不存在", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/lesson-plans/{id}/share-code": { + "post": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "为教案文件生成6位数字分享码,有效期5分钟,每次生成会失效之前的分享码", + "produces": [ + "application/json" + ], + "tags": [ + "教案管理" + ], + "summary": "生成分享码", + "parameters": [ + { + "type": "integer", + "description": "教案ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "生成成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "401": { + "description": "未认证", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "403": { + "description": "无权限", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "404": { + "description": "文件不存在", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/login": { + "post": { + "description": "用户名密码登录,返回JWT Token和用户信息", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "认证" + ], + "summary": "用户登录", + "parameters": [ + { + "description": "登录信息", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/controllers.SwagLoginRequest" + } + } + ], + "responses": { + "200": { + "description": "登录成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "400": { + "description": "请求参数错误", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "401": { + "description": "用户名或密码错误", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "403": { + "description": "用户已禁用", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/register": { + "post": { + "description": "注册新用户,返回JWT Token", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "认证" + ], + "summary": "用户注册", + "parameters": [ + { + "description": "注册信息", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/controllers.SwagRegisterRequest" + } + } + ], + "responses": { + "201": { + "description": "注册成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "400": { + "description": "请求参数错误", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "409": { + "description": "用户名已存在", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/step": { + "post": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "接收并保存踏步训练记录,包含心率和步频数据,异步计算回归结果", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "踏步训练" + ], + "summary": "创建踏步训练记录", + "parameters": [ + { + "description": "踏步训练记录", + "name": "record", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + ], + "responses": { + "201": { + "description": "保存成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "400": { + "description": "请求参数错误", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "401": { + "description": "未认证", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/step/train-data/{trainId}": { + "get": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "根据训练ID获取踏步训练的详细信息,包含心率和步频数据", + "produces": [ + "application/json" + ], + "tags": [ + "踏步训练" + ], + "summary": "获取踏步训练详情", + "parameters": [ + { + "type": "integer", + "description": "训练ID", + "name": "trainId", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "查询成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "400": { + "description": "请求参数错误", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "401": { + "description": "未认证", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "404": { + "description": "训练记录不存在", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/step/train-rank/{trainId}": { + "get": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "根据训练ID和回归类型获取训练排名", + "produces": [ + "application/json" + ], + "tags": [ + "踏步训练" + ], + "summary": "获取训练排名", + "parameters": [ + { + "type": "integer", + "description": "训练ID", + "name": "trainId", + "in": "path", + "required": true + }, + { + "type": "integer", + "description": "回归类型: 1=线性回归 | 3=二次回归", + "name": "type", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "查询成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "400": { + "description": "请求参数错误", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "401": { + "description": "未认证", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/step/train-records": { + "get": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "分页获取当前用户的踏步训练记录,按开始时间倒序", + "produces": [ + "application/json" + ], + "tags": [ + "踏步训练" + ], + "summary": "获取踏步训练记录列表", + "parameters": [ + { + "type": "integer", + "description": "页码(默认1)", + "name": "pageNum", + "in": "query" + }, + { + "type": "integer", + "description": "每页数量(默认10,最大100)", + "name": "pageSize", + "in": "query" + } + ], + "responses": { + "200": { + "description": "查询成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "400": { + "description": "请求参数错误", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "401": { + "description": "未认证", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/train-records": { + "post": { + "description": "接收并保存训练记录及心率数据,支持重复上传(按train_id去重更新)", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "训练管理" + ], + "summary": "创建训练记录", + "parameters": [ + { + "description": "训练记录数据", + "name": "record", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + ], + "responses": { + "201": { + "description": "保存成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "400": { + "description": "请求参数错误", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/train-records/analysis": { + "get": { + "description": "对历史心率数据进行统计分析和正态分布曲线拟合", + "produces": [ + "application/json" + ], + "tags": [ + "训练管理" + ], + "summary": "心率曲线分析", + "responses": { + "200": { + "description": "分析成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "400": { + "description": "数据量不足", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/train-records/analysis-by-ai": { + "post": { + "description": "上传心率CSV和教案文件,通过AI生成课堂分析报告,支持流式和非流式输出", + "consumes": [ + "multipart/form-data" + ], + "produces": [ + "application/json" + ], + "tags": [ + "AI分析" + ], + "summary": "AI分析", + "parameters": [ + { + "type": "file", + "description": "心率数据CSV文件", + "name": "heart_rate_data", + "in": "formData", + "required": true + }, + { + "type": "file", + "description": "步数数据CSV文件(analysis_type为heart_rate_with_steps时必填)", + "name": "step_data", + "in": "formData" + }, + { + "type": "file", + "description": "教案DOCX文件(teaching_plan_source为upload/wechat时必填)", + "name": "teaching_plan", + "in": "formData" + }, + { + "type": "string", + "description": "分析类型: heart_rate_only(默认) | heart_rate_with_steps", + "name": "analysis_type", + "in": "formData" + }, + { + "type": "string", + "description": "教案来源: upload(默认) | cloud | wechat", + "name": "teaching_plan_source", + "in": "formData" + }, + { + "type": "string", + "description": "区域ID", + "name": "regionid", + "in": "formData" + }, + { + "type": "string", + "description": "训练ID", + "name": "trainid", + "in": "formData" + }, + { + "type": "string", + "description": "云端教案ID(teaching_plan_source=cloud时必填)", + "name": "lesson_plan_id", + "in": "formData" + }, + { + "type": "string", + "description": "是否流式输出: true | false", + "name": "stream", + "in": "formData" + } + ], + "responses": { + "200": { + "description": "分析成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "400": { + "description": "请求参数错误", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/train-records/cloud-files": { + "get": { + "description": "获取所有云端教案文件列表", + "produces": [ + "application/json" + ], + "tags": [ + "训练管理" + ], + "summary": "获取云端教案列表", + "responses": { + "200": { + "description": "查询成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/train-records/session": { + "post": { + "description": "上传训练开始/结束会话,用于MQTT训练会话追踪", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "训练管理" + ], + "summary": "上传训练会话", + "parameters": [ + { + "description": "训练会话数据", + "name": "session", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/controllers.trainingSessionRequest" + } + } + ], + "responses": { + "200": { + "description": "操作成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "400": { + "description": "请求参数错误", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + } + }, + "definitions": { + "controllers.SwagAPIResponse": { + "type": "object", + "properties": { + "code": { + "description": "HTTP状态码", + "type": "integer" + }, + "data": { + "description": "响应数据" + }, + "msg": { + "description": "响应消息", + "type": "string" + } + } + }, + "controllers.SwagLoginRequest": { + "type": "object", + "properties": { + "password": { + "description": "密码", + "type": "string" + }, + "username": { + "description": "用户名", + "type": "string" + } + } + }, + "controllers.SwagRegisterRequest": { + "type": "object", + "properties": { + "flavorType": { + "description": "类型", + "type": "string" + }, + "password": { + "description": "密码", + "type": "string" + }, + "regionIds": { + "description": "区域ID列表", + "type": "array", + "items": { + "type": "integer" + } + }, + "role": { + "description": "角色", + "type": "string" + }, + "username": { + "description": "用户名", + "type": "string" + } + } + }, + "controllers.gatewayPayload": { + "type": "object", + "properties": { + "isSold": { + "type": "boolean" + }, + "location": { + "type": "string" + }, + "mac": { + "type": "string" + }, + "name": { + "type": "string" + }, + "projectType": { + "type": "string" + }, + "regionId": { + "type": "integer" + }, + "soldAt": { + "description": "SoldAt 是可选字段。如果 IsSold 为 true 且未传此字段,后端自动设为当前时间", + "type": "string" + } + } + }, + "controllers.kindergartenPayload": { + "type": "object", + "properties": { + "address": { + "type": "string" + }, + "name": { + "type": "string" + }, + "regionId": { + "type": "integer" + } + } + }, + "controllers.mqttDebugStartRequest": { + "type": "object", + "properties": { + "persistToDatabase": { + "type": "boolean" + } + } + }, + "controllers.productDefinitionPayload": { + "type": "object", + "properties": { + "category": { + "type": "string" + }, + "code": { + "type": "string" + }, + "description": { + "type": "string" + }, + "isActive": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "parameterSchema": { + "type": "string" + }, + "sort": { + "type": "integer" + }, + "trackSerialNumber": { + "type": "boolean" + } + } + }, + "controllers.productInventoryPayload": { + "type": "object", + "properties": { + "assetName": { + "type": "string" + }, + "notes": { + "type": "string" + }, + "parameterValues": { + "type": "string" + }, + "productCode": { + "type": "string" + }, + "projectTypeCode": { + "type": "string" + }, + "regionId": { + "type": "integer" + }, + "serialNumber": { + "type": "string" + }, + "soldAt": { + "type": "string" + }, + "soldTargetName": { + "type": "string" + }, + "soldTargetType": { + "type": "string" + }, + "soldTo": { + "type": "string" + }, + "status": { + "type": "string" + }, + "storageLocation": { + "type": "string" + }, + "suiteCode": { + "type": "string" + }, + "suiteId": { + "type": "integer" + } + } + }, + "controllers.productPrototypePayload": { + "type": "object", + "properties": { + "assetName": { + "type": "string" + }, + "name": { + "type": "string" + }, + "notes": { + "type": "string" + }, + "parameterValues": { + "type": "string" + }, + "productCode": { + "type": "string" + }, + "projectTypeCode": { + "type": "string" + }, + "regionId": { + "type": "integer" + }, + "status": { + "type": "string" + }, + "storageLocation": { + "type": "string" + } + } + }, + "controllers.productSuitePayload": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "inventoryIds": { + "type": "array", + "items": { + "type": "integer" + } + }, + "name": { + "type": "string" + }, + "notes": { + "type": "string" + }, + "projectTypeCode": { + "type": "string" + }, + "regionId": { + "type": "integer" + }, + "soldTargetName": { + "type": "string" + }, + "soldTargetType": { + "type": "string" + } + } + }, + "controllers.projectTypePayload": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "description": { + "type": "string" + }, + "isActive": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "sort": { + "type": "integer" + }, + "supportsGateway": { + "type": "boolean" + } + } + }, + "controllers.trainingSessionRequest": { + "type": "object", + "properties": { + "age": { + "type": "integer" + }, + "aiResult": { + "type": "string" + }, + "appName": { + "type": "string" + }, + "duration": { + "type": "integer" + }, + "endTime": { + "type": "integer" + }, + "evaluation": { + "type": "string" + }, + "gender": { + "type": "string" + }, + "isStart": { + "type": "boolean" + }, + "maxHeartRate": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "peopleNum": { + "type": "integer" + }, + "regionId": { + "type": "integer" + }, + "runType": { + "type": "string" + }, + "testTime": { + "type": "integer" + }, + "tid": { + "type": "integer" + }, + "time": { + "type": "integer" + } + } + }, + "controllers.userAdminPayload": { + "type": "object", + "properties": { + "email": { + "type": "string" + }, + "flavorType": { + "$ref": "#/definitions/models.UserFlavorType" + }, + "isActive": { + "type": "boolean" + }, + "password": { + "type": "string" + }, + "phone": { + "type": "string" + }, + "regionIds": { + "type": "array", + "items": { + "type": "integer" + } + }, + "revokeTokens": { + "type": "boolean" + }, + "role": { + "$ref": "#/definitions/models.UserRole" + }, + "username": { + "type": "string" + } + } + }, + "models.UserFlavorType": { + "type": "string", + "enum": [ + "all", + "flink", + "full", + "light", + "heartrate", + "run50" + ], + "x-enum-varnames": [ + "UserFlavorAll", + "UserFlavorFlink", + "UserFlavorFull", + "UserFlavorLight", + "UserFlavorHeartRate", + "UserFlavorRun50" + ] + }, + "models.UserRole": { + "type": "string", + "enum": [ + "super_admin", + "region_admin", + "operator", + "viewer" + ], + "x-enum-varnames": [ + "UserRoleSuperAdmin", + "UserRoleRegionAdmin", + "UserRoleOperator", + "UserRoleViewer" + ] + } + }, + "securityDefinitions": { + "BearerAuth": { + "type": "apiKey", + "name": "Authorization", + "in": "header" + } + } +}` + +// SwaggerInfo holds exported Swagger Info so clients can modify it +var SwaggerInfo = &swag.Spec{ + Version: "1.0", + Host: "localhost:8081", + BasePath: "/api/v1", + Schemes: []string{}, + Title: "智能心率采集分析平台 API", + Description: "智能心率采集分析平台后端服务,基于 Gin 框架,提供心率采集、AI 分析、教案管理、设备管理等功能", + InfoInstanceName: "swagger", + SwaggerTemplate: docTemplate, +} + +func init() { + swag.Register(SwaggerInfo.InstanceName(), SwaggerInfo) +} diff --git a/docs/swagger.json b/docs/swagger.json new file mode 100644 index 0000000..1a75ba5 --- /dev/null +++ b/docs/swagger.json @@ -0,0 +1,3251 @@ +{ + "swagger": "2.0", + "info": { + "description": "智能心率采集分析平台后端服务,基于 Gin 框架,提供心率采集、AI 分析、教案管理、设备管理等功能", + "title": "智能心率采集分析平台 API", + "contact": {}, + "version": "1.0" + }, + "host": "localhost:8081", + "basePath": "/api/v1", + "paths": { + "/admin/gateways": { + "get": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "查询网关列表,支持关键词/售出状态/项目类型/区域筛选。超级管理员可查全部,操作员只能查所属区域", + "produces": [ + "application/json" + ], + "tags": [ + "网关管理" + ], + "summary": "获取网关列表", + "parameters": [ + { + "type": "string", + "description": "关键词(名称/MAC模糊搜索)", + "name": "keyword", + "in": "query" + }, + { + "type": "boolean", + "description": "售出状态", + "name": "isSold", + "in": "query" + }, + { + "type": "string", + "description": "项目类型", + "name": "projectType", + "in": "query" + }, + { + "type": "integer", + "description": "区域ID", + "name": "regionId", + "in": "query" + } + ], + "responses": { + "200": { + "description": "查询成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + }, + "post": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "创建新的网关记录,自动同步到产品库存", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "网关管理" + ], + "summary": "创建网关", + "parameters": [ + { + "description": "网关信息", + "name": "gateway", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/controllers.gatewayPayload" + } + } + ], + "responses": { + "201": { + "description": "创建成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "400": { + "description": "请求参数错误", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "409": { + "description": "MAC地址已存在", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/admin/gateways/{id}": { + "put": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "更新指定网关的详细信息,自动同步到产品库存", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "网关管理" + ], + "summary": "更新网关信息", + "parameters": [ + { + "type": "integer", + "description": "网关ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "更新信息", + "name": "gateway", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/controllers.gatewayPayload" + } + } + ], + "responses": { + "200": { + "description": "更新成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "400": { + "description": "请求参数错误", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "404": { + "description": "网关不存在", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + }, + "delete": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "删除指定网关(已售出的网关禁止删除),自动同步删除产品库存", + "produces": [ + "application/json" + ], + "tags": [ + "网关管理" + ], + "summary": "删除网关", + "parameters": [ + { + "type": "integer", + "description": "网关ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "删除成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "403": { + "description": "已售出无法删除", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "404": { + "description": "网关不存在", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/admin/kindergartens": { + "get": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "查询幼儿园列表,支持按名称/地址模糊搜索", + "produces": [ + "application/json" + ], + "tags": [ + "幼儿园管理" + ], + "summary": "获取幼儿园列表", + "parameters": [ + { + "type": "string", + "description": "关键词(名称/地址模糊搜索)", + "name": "keyword", + "in": "query" + } + ], + "responses": { + "200": { + "description": "查询成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + }, + "post": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "创建新的幼儿园记录", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "幼儿园管理" + ], + "summary": "创建幼儿园", + "parameters": [ + { + "description": "幼儿园信息", + "name": "kindergarten", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/controllers.kindergartenPayload" + } + } + ], + "responses": { + "201": { + "description": "创建成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "400": { + "description": "请求参数错误", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/admin/kindergartens/{id}": { + "put": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "更新指定幼儿园的名称、地址和区域", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "幼儿园管理" + ], + "summary": "更新幼儿园信息", + "parameters": [ + { + "type": "integer", + "description": "幼儿园ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "更新信息", + "name": "kindergarten", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/controllers.kindergartenPayload" + } + } + ], + "responses": { + "200": { + "description": "更新成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "400": { + "description": "请求参数错误", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "404": { + "description": "幼儿园不存在", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + }, + "delete": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "删除指定幼儿园,如果被用户绑定则无法删除", + "produces": [ + "application/json" + ], + "tags": [ + "幼儿园管理" + ], + "summary": "删除幼儿园", + "parameters": [ + { + "type": "integer", + "description": "幼儿园ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "删除成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "404": { + "description": "幼儿园不存在", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "409": { + "description": "已绑定用户无法删除", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/admin/product-definitions": { + "get": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "查询产品定义列表,支持按关键词/分类/启用状态筛选", + "produces": [ + "application/json" + ], + "tags": [ + "产品定义管理" + ], + "summary": "获取产品定义列表", + "parameters": [ + { + "type": "string", + "description": "关键词(代码/名称/描述模糊搜索)", + "name": "keyword", + "in": "query" + }, + { + "type": "string", + "description": "分类筛选", + "name": "category", + "in": "query" + }, + { + "type": "boolean", + "description": "是否启用", + "name": "isActive", + "in": "query" + } + ], + "responses": { + "200": { + "description": "查询成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + }, + "post": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "创建新的产品定义", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "产品定义管理" + ], + "summary": "创建产品定义", + "parameters": [ + { + "description": "产品定义信息", + "name": "productDefinition", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/controllers.productDefinitionPayload" + } + } + ], + "responses": { + "201": { + "description": "创建成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "400": { + "description": "请求参数错误", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/admin/product-definitions/{id}": { + "put": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "更新指定产品定义的信息", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "产品定义管理" + ], + "summary": "更新产品定义", + "parameters": [ + { + "type": "integer", + "description": "产品定义ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "更新信息", + "name": "productDefinition", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/controllers.productDefinitionPayload" + } + } + ], + "responses": { + "200": { + "description": "更新成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "400": { + "description": "请求参数错误", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "404": { + "description": "产品定义不存在", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + }, + "delete": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "删除指定产品定义(被库存或模板引用的无法删除)", + "produces": [ + "application/json" + ], + "tags": [ + "产品定义管理" + ], + "summary": "删除产品定义", + "parameters": [ + { + "type": "integer", + "description": "产品定义ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "删除成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "404": { + "description": "产品定义不存在", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "409": { + "description": "已被引用无法删除", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/admin/product-inventories": { + "get": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "查询产品库存列表,支持多条件筛选", + "produces": [ + "application/json" + ], + "tags": [ + "产品库存管理" + ], + "summary": "获取产品库存列表", + "parameters": [ + { + "type": "string", + "description": "关键词(资产名称/序列号/购买方等模糊搜索)", + "name": "keyword", + "in": "query" + }, + { + "type": "string", + "description": "产品代码筛选", + "name": "productCode", + "in": "query" + }, + { + "type": "string", + "description": "项目类型代码筛选", + "name": "projectTypeCode", + "in": "query" + }, + { + "type": "string", + "description": "套件代码筛选", + "name": "suiteCode", + "in": "query" + }, + { + "type": "string", + "description": "状态筛选", + "name": "status", + "in": "query" + }, + { + "type": "string", + "description": "购买方类型筛选", + "name": "soldTargetType", + "in": "query" + }, + { + "type": "integer", + "description": "区域ID", + "name": "regionId", + "in": "query" + } + ], + "responses": { + "200": { + "description": "查询成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + }, + "post": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "创建新的产品库存记录", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "产品库存管理" + ], + "summary": "创建产品库存记录", + "parameters": [ + { + "description": "库存信息", + "name": "inventory", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/controllers.productInventoryPayload" + } + } + ], + "responses": { + "201": { + "description": "创建成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "400": { + "description": "请求参数错误", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/admin/product-inventories/{id}": { + "put": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "更新指定产品库存记录", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "产品库存管理" + ], + "summary": "更新产品库存", + "parameters": [ + { + "type": "integer", + "description": "库存ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "更新信息", + "name": "inventory", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/controllers.productInventoryPayload" + } + } + ], + "responses": { + "200": { + "description": "更新成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "400": { + "description": "请求参数错误", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "404": { + "description": "库存记录不存在", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + }, + "delete": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "删除指定产品库存记录(已售出的无法删除)", + "produces": [ + "application/json" + ], + "tags": [ + "产品库存管理" + ], + "summary": "删除产品库存", + "parameters": [ + { + "type": "integer", + "description": "库存ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "删除成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "404": { + "description": "库存记录不存在", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "409": { + "description": "已售出无法删除", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/admin/product-prototypes": { + "get": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "查询产品原型列表,支持按关键词/产品代码/项目类型筛选", + "produces": [ + "application/json" + ], + "tags": [ + "产品原型管理" + ], + "summary": "获取产品原型列表", + "parameters": [ + { + "type": "string", + "description": "关键词(名称/备注模糊搜索)", + "name": "keyword", + "in": "query" + }, + { + "type": "string", + "description": "产品代码筛选", + "name": "productCode", + "in": "query" + }, + { + "type": "string", + "description": "项目类型代码筛选", + "name": "projectTypeCode", + "in": "query" + } + ], + "responses": { + "200": { + "description": "查询成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + }, + "post": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "创建新的产品原型", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "产品原型管理" + ], + "summary": "创建产品原型", + "parameters": [ + { + "description": "产品原型信息", + "name": "productPrototype", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/controllers.productPrototypePayload" + } + } + ], + "responses": { + "201": { + "description": "创建成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "400": { + "description": "请求参数错误", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/admin/product-prototypes/{id}": { + "put": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "更新指定产品原型的信息", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "产品原型管理" + ], + "summary": "更新产品原型", + "parameters": [ + { + "type": "integer", + "description": "产品原型ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "更新信息", + "name": "productPrototype", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/controllers.productPrototypePayload" + } + } + ], + "responses": { + "200": { + "description": "更新成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "400": { + "description": "请求参数错误", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "404": { + "description": "产品原型不存在", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + }, + "delete": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "删除指定产品原型", + "produces": [ + "application/json" + ], + "tags": [ + "产品原型管理" + ], + "summary": "删除产品原型", + "parameters": [ + { + "type": "integer", + "description": "产品原型ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "删除成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "404": { + "description": "产品原型不存在", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/admin/product-suites": { + "get": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "查询产品套件列表,含套件下的库存明细", + "produces": [ + "application/json" + ], + "tags": [ + "产品套件管理" + ], + "summary": "获取产品套件列表", + "parameters": [ + { + "type": "string", + "description": "关键词(代码/名称/备注模糊搜索)", + "name": "keyword", + "in": "query" + }, + { + "type": "string", + "description": "项目类型代码筛选", + "name": "projectTypeCode", + "in": "query" + } + ], + "responses": { + "200": { + "description": "查询成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + }, + "post": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "创建新的产品套件,可选关联库存记录", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "产品套件管理" + ], + "summary": "创建产品套件", + "parameters": [ + { + "description": "套件信息", + "name": "suite", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/controllers.productSuitePayload" + } + } + ], + "responses": { + "201": { + "description": "创建成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "400": { + "description": "请求参数错误", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/admin/product-suites/{id}": { + "put": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "更新指定产品套件的信息和关联库存", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "产品套件管理" + ], + "summary": "更新产品套件", + "parameters": [ + { + "type": "integer", + "description": "套件ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "更新信息", + "name": "suite", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/controllers.productSuitePayload" + } + } + ], + "responses": { + "200": { + "description": "更新成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "400": { + "description": "请求参数错误", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "404": { + "description": "套件不存在", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + }, + "delete": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "删除指定产品套件,自动解除关联库存的绑定", + "produces": [ + "application/json" + ], + "tags": [ + "产品套件管理" + ], + "summary": "删除产品套件", + "parameters": [ + { + "type": "integer", + "description": "套件ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "删除成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "404": { + "description": "套件不存在", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/admin/project-product-templates": { + "get": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "查询项目产品模板列表,含项目类型和产品名称", + "produces": [ + "application/json" + ], + "tags": [ + "项目产品模板管理" + ], + "summary": "获取项目产品模板列表", + "parameters": [ + { + "type": "string", + "description": "项目类型代码筛选", + "name": "projectTypeCode", + "in": "query" + } + ], + "responses": { + "200": { + "description": "查询成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/admin/project-types": { + "get": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "查询项目类型列表,支持按关键词/是否支持网关/是否启用筛选", + "produces": [ + "application/json" + ], + "tags": [ + "项目类型管理" + ], + "summary": "获取项目类型列表", + "parameters": [ + { + "type": "string", + "description": "关键词(代码/名称/描述模糊搜索)", + "name": "keyword", + "in": "query" + }, + { + "type": "boolean", + "description": "是否支持网关", + "name": "supportsGateway", + "in": "query" + }, + { + "type": "boolean", + "description": "是否启用", + "name": "isActive", + "in": "query" + } + ], + "responses": { + "200": { + "description": "查询成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + }, + "post": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "创建新的项目类型", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "项目类型管理" + ], + "summary": "创建项目类型", + "parameters": [ + { + "description": "项目类型信息", + "name": "projectType", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/controllers.projectTypePayload" + } + } + ], + "responses": { + "201": { + "description": "创建成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "400": { + "description": "请求参数错误", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/admin/project-types/{id}": { + "put": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "更新指定项目类型的信息", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "项目类型管理" + ], + "summary": "更新项目类型", + "parameters": [ + { + "type": "integer", + "description": "项目类型ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "更新信息", + "name": "projectType", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/controllers.projectTypePayload" + } + } + ], + "responses": { + "200": { + "description": "更新成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "400": { + "description": "请求参数错误", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "404": { + "description": "项目类型不存在", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + }, + "delete": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "删除指定项目类型(被网关引用的无法删除)", + "produces": [ + "application/json" + ], + "tags": [ + "项目类型管理" + ], + "summary": "删除项目类型", + "parameters": [ + { + "type": "integer", + "description": "项目类型ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "删除成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "404": { + "description": "项目类型不存在", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "409": { + "description": "已被网关引用无法删除", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/admin/statistics/ai-analysis": { + "get": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "按区域统计AI分析的使用情况,包括调用次数、Token消耗、费用等", + "produces": [ + "application/json" + ], + "tags": [ + "统计管理" + ], + "summary": "AI分析区域统计", + "parameters": [ + { + "type": "integer", + "description": "区域ID", + "name": "regionId", + "in": "query" + }, + { + "type": "integer", + "description": "开始时间(毫秒时间戳)", + "name": "startTime", + "in": "query" + }, + { + "type": "integer", + "description": "结束时间(毫秒时间戳)", + "name": "endTime", + "in": "query" + } + ], + "responses": { + "200": { + "description": "查询成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/admin/statistics/ai-analysis-records": { + "get": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "分页查询AI分析记录,支持按区域和时间范围筛选", + "produces": [ + "application/json" + ], + "tags": [ + "统计管理" + ], + "summary": "获取AI分析记录列表", + "parameters": [ + { + "type": "integer", + "description": "页码(默认1)", + "name": "pageNum", + "in": "query" + }, + { + "type": "integer", + "description": "每页数量(默认10,最大100)", + "name": "pageSize", + "in": "query" + }, + { + "type": "integer", + "description": "区域ID", + "name": "regionId", + "in": "query" + }, + { + "type": "integer", + "description": "开始时间(毫秒时间戳)", + "name": "startTime", + "in": "query" + }, + { + "type": "integer", + "description": "结束时间(毫秒时间戳)", + "name": "endTime", + "in": "query" + } + ], + "responses": { + "200": { + "description": "查询成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/admin/statistics/ai-analysis-records/{id}": { + "delete": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "删除指定的AI分析记录", + "produces": [ + "application/json" + ], + "tags": [ + "统计管理" + ], + "summary": "删除AI分析记录", + "parameters": [ + { + "type": "integer", + "description": "记录ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "删除成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "404": { + "description": "记录不存在", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/admin/statistics/ai-analysis-timeline": { + "get": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "按日期统计AI分析的使用情况趋势,含总体和分区域数据", + "produces": [ + "application/json" + ], + "tags": [ + "统计管理" + ], + "summary": "AI分析时间线统计", + "parameters": [ + { + "type": "integer", + "description": "区域ID", + "name": "regionId", + "in": "query" + }, + { + "type": "integer", + "description": "开始时间(毫秒时间戳)", + "name": "startTime", + "in": "query" + }, + { + "type": "integer", + "description": "结束时间(毫秒时间戳)", + "name": "endTime", + "in": "query" + } + ], + "responses": { + "200": { + "description": "查询成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/admin/statistics/mqtt-training-sessions": { + "get": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "按区域统计MQTT训练会话情况,包括开始、结束、完成、进行中的会话数", + "produces": [ + "application/json" + ], + "tags": [ + "统计管理" + ], + "summary": "训练会话区域统计", + "parameters": [ + { + "type": "integer", + "description": "区域ID", + "name": "regionId", + "in": "query" + }, + { + "type": "string", + "description": "类型筛选", + "name": "flavorType", + "in": "query" + }, + { + "type": "integer", + "description": "开始时间(毫秒时间戳)", + "name": "startTime", + "in": "query" + }, + { + "type": "integer", + "description": "结束时间(毫秒时间戳)", + "name": "endTime", + "in": "query" + } + ], + "responses": { + "200": { + "description": "查询成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/admin/system-debug/mqtt/start": { + "post": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "启动MQTT调试服务", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "系统调试" + ], + "summary": "启动MQTT调试", + "parameters": [ + { + "description": "是否持久化到数据库", + "name": "persist", + "in": "body", + "schema": { + "$ref": "#/definitions/controllers.mqttDebugStartRequest" + } + } + ], + "responses": { + "200": { + "description": "启动成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/admin/system-debug/mqtt/status": { + "get": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "获取MQTT调试服务的当前运行状态", + "produces": [ + "application/json" + ], + "tags": [ + "系统调试" + ], + "summary": "获取MQTT调试状态", + "responses": { + "200": { + "description": "查询成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/admin/system-debug/mqtt/stop": { + "post": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "停止MQTT调试服务", + "produces": [ + "application/json" + ], + "tags": [ + "系统调试" + ], + "summary": "停止MQTT调试", + "responses": { + "200": { + "description": "停止成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/admin/system-debug/mqtt/ws": { + "get": { + "description": "通过WebSocket实时监听MQTT消息(需要SuperAdmin权限)", + "tags": [ + "系统调试" + ], + "summary": "MQTT WebSocket连接", + "parameters": [ + { + "type": "string", + "description": "JWT Token", + "name": "token", + "in": "query", + "required": true + } + ], + "responses": { + "101": { + "description": "切换为WebSocket协议" + } + } + } + }, + "/admin/users": { + "get": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "查询系统用户列表,支持按关键词/角色/类型筛选", + "produces": [ + "application/json" + ], + "tags": [ + "用户管理" + ], + "summary": "获取用户列表", + "parameters": [ + { + "type": "string", + "description": "关键词(用户名/邮箱/手机号模糊搜索)", + "name": "keyword", + "in": "query" + }, + { + "type": "string", + "description": "角色筛选", + "name": "role", + "in": "query" + }, + { + "type": "string", + "description": "类型筛选", + "name": "flavorType", + "in": "query" + } + ], + "responses": { + "200": { + "description": "查询成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + }, + "post": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "创建新的系统用户", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "用户管理" + ], + "summary": "创建用户", + "parameters": [ + { + "description": "用户信息", + "name": "user", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/controllers.userAdminPayload" + } + } + ], + "responses": { + "201": { + "description": "创建成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "400": { + "description": "请求参数错误", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/admin/users/{id}": { + "put": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "更新指定用户的详细信息,支持重置密码和吊销Token", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "用户管理" + ], + "summary": "更新用户信息", + "parameters": [ + { + "type": "integer", + "description": "用户ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "更新信息", + "name": "user", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/controllers.userAdminPayload" + } + } + ], + "responses": { + "200": { + "description": "更新成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "400": { + "description": "请求参数错误", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "404": { + "description": "用户不存在", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + }, + "delete": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "删除指定用户(不能删除admin账号和当前登录用户)", + "produces": [ + "application/json" + ], + "tags": [ + "用户管理" + ], + "summary": "删除用户", + "parameters": [ + { + "type": "integer", + "description": "用户ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "删除成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "400": { + "description": "无法删除受保护账号", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "404": { + "description": "用户不存在", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/gateways/by-mac": { + "get": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "根据MAC地址查询网关信息(支持格式兼容:带冒号/横线/纯数字)", + "produces": [ + "application/json" + ], + "tags": [ + "网关管理" + ], + "summary": "按MAC查询网关", + "parameters": [ + { + "type": "string", + "description": "MAC地址", + "name": "mac", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "查询成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "400": { + "description": "MAC参数为空", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "404": { + "description": "未找到该网关", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/lesson-plans": { + "get": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "获取教案文件列表(非分页),按创建时间倒序", + "produces": [ + "application/json" + ], + "tags": [ + "教案管理" + ], + "summary": "获取教案列表", + "responses": { + "200": { + "description": "查询成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "401": { + "description": "未认证", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/lesson-plans/page": { + "get": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "分页获取教案文件列表,支持文件名模糊搜索、上传者搜索、区域筛选、排序", + "produces": [ + "application/json" + ], + "tags": [ + "教案管理" + ], + "summary": "分页查询教案", + "parameters": [ + { + "type": "integer", + "description": "页码(默认1)", + "name": "pageNum", + "in": "query" + }, + { + "type": "integer", + "description": "每页数量(默认10,最大100)", + "name": "pageSize", + "in": "query" + }, + { + "type": "string", + "description": "文件名模糊搜索", + "name": "keyword", + "in": "query" + }, + { + "type": "string", + "description": "上传者名模糊搜索", + "name": "uploaderName", + "in": "query" + }, + { + "type": "integer", + "description": "区域ID", + "name": "regionId", + "in": "query" + }, + { + "type": "string", + "description": "排序字段: file_size | created_at", + "name": "sortBy", + "in": "query" + }, + { + "type": "string", + "description": "排序方向: asc | desc", + "name": "sortOrder", + "in": "query" + } + ], + "responses": { + "200": { + "description": "查询成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "400": { + "description": "请求参数错误", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "401": { + "description": "未认证", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/lesson-plans/share/{code}/download": { + "get": { + "description": "通过6位分享码下载教案文件(无需认证)", + "produces": [ + "application/octet-stream" + ], + "tags": [ + "教案管理" + ], + "summary": "通过分享码下载教案", + "parameters": [ + { + "type": "string", + "description": "6位分享码", + "name": "code", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "教案文件", + "schema": { + "type": "file" + } + }, + "400": { + "description": "分享码无效", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "404": { + "description": "分享码过期或不存在", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/lesson-plans/upload": { + "post": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "上传 .docx 格式的教案文件,支持MD5去重,最大10MB", + "consumes": [ + "multipart/form-data" + ], + "produces": [ + "application/json" + ], + "tags": [ + "教案管理" + ], + "summary": "上传教案文件", + "parameters": [ + { + "type": "file", + "description": "教案文件(.docx)", + "name": "file", + "in": "formData", + "required": true + } + ], + "responses": { + "201": { + "description": "上传成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "400": { + "description": "请求参数错误", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "401": { + "description": "未认证", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "409": { + "description": "文件已存在", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/lesson-plans/{id}": { + "delete": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "删除教案文件及其关联的分享码", + "produces": [ + "application/json" + ], + "tags": [ + "教案管理" + ], + "summary": "删除教案文件", + "parameters": [ + { + "type": "integer", + "description": "教案ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "删除成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "401": { + "description": "未认证", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "403": { + "description": "无权限", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "404": { + "description": "文件不存在", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/lesson-plans/{id}/download": { + "get": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "通过ID下载教案文件,自动更新下载计数和最后下载时间", + "produces": [ + "application/octet-stream" + ], + "tags": [ + "教案管理" + ], + "summary": "下载教案文件", + "parameters": [ + { + "type": "integer", + "description": "教案ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "教案文件", + "schema": { + "type": "file" + } + }, + "401": { + "description": "未认证", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "403": { + "description": "无权限", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "404": { + "description": "文件不存在", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/lesson-plans/{id}/share-code": { + "post": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "为教案文件生成6位数字分享码,有效期5分钟,每次生成会失效之前的分享码", + "produces": [ + "application/json" + ], + "tags": [ + "教案管理" + ], + "summary": "生成分享码", + "parameters": [ + { + "type": "integer", + "description": "教案ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "生成成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "401": { + "description": "未认证", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "403": { + "description": "无权限", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "404": { + "description": "文件不存在", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/login": { + "post": { + "description": "用户名密码登录,返回JWT Token和用户信息", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "认证" + ], + "summary": "用户登录", + "parameters": [ + { + "description": "登录信息", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/controllers.SwagLoginRequest" + } + } + ], + "responses": { + "200": { + "description": "登录成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "400": { + "description": "请求参数错误", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "401": { + "description": "用户名或密码错误", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "403": { + "description": "用户已禁用", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/register": { + "post": { + "description": "注册新用户,返回JWT Token", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "认证" + ], + "summary": "用户注册", + "parameters": [ + { + "description": "注册信息", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/controllers.SwagRegisterRequest" + } + } + ], + "responses": { + "201": { + "description": "注册成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "400": { + "description": "请求参数错误", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "409": { + "description": "用户名已存在", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/step": { + "post": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "接收并保存踏步训练记录,包含心率和步频数据,异步计算回归结果", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "踏步训练" + ], + "summary": "创建踏步训练记录", + "parameters": [ + { + "description": "踏步训练记录", + "name": "record", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + ], + "responses": { + "201": { + "description": "保存成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "400": { + "description": "请求参数错误", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "401": { + "description": "未认证", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/step/train-data/{trainId}": { + "get": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "根据训练ID获取踏步训练的详细信息,包含心率和步频数据", + "produces": [ + "application/json" + ], + "tags": [ + "踏步训练" + ], + "summary": "获取踏步训练详情", + "parameters": [ + { + "type": "integer", + "description": "训练ID", + "name": "trainId", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "查询成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "400": { + "description": "请求参数错误", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "401": { + "description": "未认证", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "404": { + "description": "训练记录不存在", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/step/train-rank/{trainId}": { + "get": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "根据训练ID和回归类型获取训练排名", + "produces": [ + "application/json" + ], + "tags": [ + "踏步训练" + ], + "summary": "获取训练排名", + "parameters": [ + { + "type": "integer", + "description": "训练ID", + "name": "trainId", + "in": "path", + "required": true + }, + { + "type": "integer", + "description": "回归类型: 1=线性回归 | 3=二次回归", + "name": "type", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "查询成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "400": { + "description": "请求参数错误", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "401": { + "description": "未认证", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/step/train-records": { + "get": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "分页获取当前用户的踏步训练记录,按开始时间倒序", + "produces": [ + "application/json" + ], + "tags": [ + "踏步训练" + ], + "summary": "获取踏步训练记录列表", + "parameters": [ + { + "type": "integer", + "description": "页码(默认1)", + "name": "pageNum", + "in": "query" + }, + { + "type": "integer", + "description": "每页数量(默认10,最大100)", + "name": "pageSize", + "in": "query" + } + ], + "responses": { + "200": { + "description": "查询成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "400": { + "description": "请求参数错误", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "401": { + "description": "未认证", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/train-records": { + "post": { + "description": "接收并保存训练记录及心率数据,支持重复上传(按train_id去重更新)", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "训练管理" + ], + "summary": "创建训练记录", + "parameters": [ + { + "description": "训练记录数据", + "name": "record", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + ], + "responses": { + "201": { + "description": "保存成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "400": { + "description": "请求参数错误", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/train-records/analysis": { + "get": { + "description": "对历史心率数据进行统计分析和正态分布曲线拟合", + "produces": [ + "application/json" + ], + "tags": [ + "训练管理" + ], + "summary": "心率曲线分析", + "responses": { + "200": { + "description": "分析成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "400": { + "description": "数据量不足", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/train-records/analysis-by-ai": { + "post": { + "description": "上传心率CSV和教案文件,通过AI生成课堂分析报告,支持流式和非流式输出", + "consumes": [ + "multipart/form-data" + ], + "produces": [ + "application/json" + ], + "tags": [ + "AI分析" + ], + "summary": "AI分析", + "parameters": [ + { + "type": "file", + "description": "心率数据CSV文件", + "name": "heart_rate_data", + "in": "formData", + "required": true + }, + { + "type": "file", + "description": "步数数据CSV文件(analysis_type为heart_rate_with_steps时必填)", + "name": "step_data", + "in": "formData" + }, + { + "type": "file", + "description": "教案DOCX文件(teaching_plan_source为upload/wechat时必填)", + "name": "teaching_plan", + "in": "formData" + }, + { + "type": "string", + "description": "分析类型: heart_rate_only(默认) | heart_rate_with_steps", + "name": "analysis_type", + "in": "formData" + }, + { + "type": "string", + "description": "教案来源: upload(默认) | cloud | wechat", + "name": "teaching_plan_source", + "in": "formData" + }, + { + "type": "string", + "description": "区域ID", + "name": "regionid", + "in": "formData" + }, + { + "type": "string", + "description": "训练ID", + "name": "trainid", + "in": "formData" + }, + { + "type": "string", + "description": "云端教案ID(teaching_plan_source=cloud时必填)", + "name": "lesson_plan_id", + "in": "formData" + }, + { + "type": "string", + "description": "是否流式输出: true | false", + "name": "stream", + "in": "formData" + } + ], + "responses": { + "200": { + "description": "分析成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "400": { + "description": "请求参数错误", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/train-records/cloud-files": { + "get": { + "description": "获取所有云端教案文件列表", + "produces": [ + "application/json" + ], + "tags": [ + "训练管理" + ], + "summary": "获取云端教案列表", + "responses": { + "200": { + "description": "查询成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + }, + "/train-records/session": { + "post": { + "description": "上传训练开始/结束会话,用于MQTT训练会话追踪", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "训练管理" + ], + "summary": "上传训练会话", + "parameters": [ + { + "description": "训练会话数据", + "name": "session", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/controllers.trainingSessionRequest" + } + } + ], + "responses": { + "200": { + "description": "操作成功", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + }, + "400": { + "description": "请求参数错误", + "schema": { + "$ref": "#/definitions/controllers.SwagAPIResponse" + } + } + } + } + } + }, + "definitions": { + "controllers.SwagAPIResponse": { + "type": "object", + "properties": { + "code": { + "description": "HTTP状态码", + "type": "integer" + }, + "data": { + "description": "响应数据" + }, + "msg": { + "description": "响应消息", + "type": "string" + } + } + }, + "controllers.SwagLoginRequest": { + "type": "object", + "properties": { + "password": { + "description": "密码", + "type": "string" + }, + "username": { + "description": "用户名", + "type": "string" + } + } + }, + "controllers.SwagRegisterRequest": { + "type": "object", + "properties": { + "flavorType": { + "description": "类型", + "type": "string" + }, + "password": { + "description": "密码", + "type": "string" + }, + "regionIds": { + "description": "区域ID列表", + "type": "array", + "items": { + "type": "integer" + } + }, + "role": { + "description": "角色", + "type": "string" + }, + "username": { + "description": "用户名", + "type": "string" + } + } + }, + "controllers.gatewayPayload": { + "type": "object", + "properties": { + "isSold": { + "type": "boolean" + }, + "location": { + "type": "string" + }, + "mac": { + "type": "string" + }, + "name": { + "type": "string" + }, + "projectType": { + "type": "string" + }, + "regionId": { + "type": "integer" + }, + "soldAt": { + "description": "SoldAt 是可选字段。如果 IsSold 为 true 且未传此字段,后端自动设为当前时间", + "type": "string" + } + } + }, + "controllers.kindergartenPayload": { + "type": "object", + "properties": { + "address": { + "type": "string" + }, + "name": { + "type": "string" + }, + "regionId": { + "type": "integer" + } + } + }, + "controllers.mqttDebugStartRequest": { + "type": "object", + "properties": { + "persistToDatabase": { + "type": "boolean" + } + } + }, + "controllers.productDefinitionPayload": { + "type": "object", + "properties": { + "category": { + "type": "string" + }, + "code": { + "type": "string" + }, + "description": { + "type": "string" + }, + "isActive": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "parameterSchema": { + "type": "string" + }, + "sort": { + "type": "integer" + }, + "trackSerialNumber": { + "type": "boolean" + } + } + }, + "controllers.productInventoryPayload": { + "type": "object", + "properties": { + "assetName": { + "type": "string" + }, + "notes": { + "type": "string" + }, + "parameterValues": { + "type": "string" + }, + "productCode": { + "type": "string" + }, + "projectTypeCode": { + "type": "string" + }, + "regionId": { + "type": "integer" + }, + "serialNumber": { + "type": "string" + }, + "soldAt": { + "type": "string" + }, + "soldTargetName": { + "type": "string" + }, + "soldTargetType": { + "type": "string" + }, + "soldTo": { + "type": "string" + }, + "status": { + "type": "string" + }, + "storageLocation": { + "type": "string" + }, + "suiteCode": { + "type": "string" + }, + "suiteId": { + "type": "integer" + } + } + }, + "controllers.productPrototypePayload": { + "type": "object", + "properties": { + "assetName": { + "type": "string" + }, + "name": { + "type": "string" + }, + "notes": { + "type": "string" + }, + "parameterValues": { + "type": "string" + }, + "productCode": { + "type": "string" + }, + "projectTypeCode": { + "type": "string" + }, + "regionId": { + "type": "integer" + }, + "status": { + "type": "string" + }, + "storageLocation": { + "type": "string" + } + } + }, + "controllers.productSuitePayload": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "inventoryIds": { + "type": "array", + "items": { + "type": "integer" + } + }, + "name": { + "type": "string" + }, + "notes": { + "type": "string" + }, + "projectTypeCode": { + "type": "string" + }, + "regionId": { + "type": "integer" + }, + "soldTargetName": { + "type": "string" + }, + "soldTargetType": { + "type": "string" + } + } + }, + "controllers.projectTypePayload": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "description": { + "type": "string" + }, + "isActive": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "sort": { + "type": "integer" + }, + "supportsGateway": { + "type": "boolean" + } + } + }, + "controllers.trainingSessionRequest": { + "type": "object", + "properties": { + "age": { + "type": "integer" + }, + "aiResult": { + "type": "string" + }, + "appName": { + "type": "string" + }, + "duration": { + "type": "integer" + }, + "endTime": { + "type": "integer" + }, + "evaluation": { + "type": "string" + }, + "gender": { + "type": "string" + }, + "isStart": { + "type": "boolean" + }, + "maxHeartRate": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "peopleNum": { + "type": "integer" + }, + "regionId": { + "type": "integer" + }, + "runType": { + "type": "string" + }, + "testTime": { + "type": "integer" + }, + "tid": { + "type": "integer" + }, + "time": { + "type": "integer" + } + } + }, + "controllers.userAdminPayload": { + "type": "object", + "properties": { + "email": { + "type": "string" + }, + "flavorType": { + "$ref": "#/definitions/models.UserFlavorType" + }, + "isActive": { + "type": "boolean" + }, + "password": { + "type": "string" + }, + "phone": { + "type": "string" + }, + "regionIds": { + "type": "array", + "items": { + "type": "integer" + } + }, + "revokeTokens": { + "type": "boolean" + }, + "role": { + "$ref": "#/definitions/models.UserRole" + }, + "username": { + "type": "string" + } + } + }, + "models.UserFlavorType": { + "type": "string", + "enum": [ + "all", + "flink", + "full", + "light", + "heartrate", + "run50" + ], + "x-enum-varnames": [ + "UserFlavorAll", + "UserFlavorFlink", + "UserFlavorFull", + "UserFlavorLight", + "UserFlavorHeartRate", + "UserFlavorRun50" + ] + }, + "models.UserRole": { + "type": "string", + "enum": [ + "super_admin", + "region_admin", + "operator", + "viewer" + ], + "x-enum-varnames": [ + "UserRoleSuperAdmin", + "UserRoleRegionAdmin", + "UserRoleOperator", + "UserRoleViewer" + ] + } + }, + "securityDefinitions": { + "BearerAuth": { + "type": "apiKey", + "name": "Authorization", + "in": "header" + } + } +} \ No newline at end of file diff --git a/docs/swagger.yaml b/docs/swagger.yaml new file mode 100644 index 0000000..1ae7734 --- /dev/null +++ b/docs/swagger.yaml @@ -0,0 +1,2078 @@ +basePath: /api/v1 +definitions: + controllers.SwagAPIResponse: + properties: + code: + description: HTTP状态码 + type: integer + data: + description: 响应数据 + msg: + description: 响应消息 + type: string + type: object + controllers.SwagLoginRequest: + properties: + password: + description: 密码 + type: string + username: + description: 用户名 + type: string + type: object + controllers.SwagRegisterRequest: + properties: + flavorType: + description: 类型 + type: string + password: + description: 密码 + type: string + regionIds: + description: 区域ID列表 + items: + type: integer + type: array + role: + description: 角色 + type: string + username: + description: 用户名 + type: string + type: object + controllers.gatewayPayload: + properties: + isSold: + type: boolean + location: + type: string + mac: + type: string + name: + type: string + projectType: + type: string + regionId: + type: integer + soldAt: + description: SoldAt 是可选字段。如果 IsSold 为 true 且未传此字段,后端自动设为当前时间 + type: string + type: object + controllers.kindergartenPayload: + properties: + address: + type: string + name: + type: string + regionId: + type: integer + type: object + controllers.mqttDebugStartRequest: + properties: + persistToDatabase: + type: boolean + type: object + controllers.productDefinitionPayload: + properties: + category: + type: string + code: + type: string + description: + type: string + isActive: + type: boolean + name: + type: string + parameterSchema: + type: string + sort: + type: integer + trackSerialNumber: + type: boolean + type: object + controllers.productInventoryPayload: + properties: + assetName: + type: string + notes: + type: string + parameterValues: + type: string + productCode: + type: string + projectTypeCode: + type: string + regionId: + type: integer + serialNumber: + type: string + soldAt: + type: string + soldTargetName: + type: string + soldTargetType: + type: string + soldTo: + type: string + status: + type: string + storageLocation: + type: string + suiteCode: + type: string + suiteId: + type: integer + type: object + controllers.productPrototypePayload: + properties: + assetName: + type: string + name: + type: string + notes: + type: string + parameterValues: + type: string + productCode: + type: string + projectTypeCode: + type: string + regionId: + type: integer + status: + type: string + storageLocation: + type: string + type: object + controllers.productSuitePayload: + properties: + code: + type: string + inventoryIds: + items: + type: integer + type: array + name: + type: string + notes: + type: string + projectTypeCode: + type: string + regionId: + type: integer + soldTargetName: + type: string + soldTargetType: + type: string + type: object + controllers.projectTypePayload: + properties: + code: + type: string + description: + type: string + isActive: + type: boolean + name: + type: string + sort: + type: integer + supportsGateway: + type: boolean + type: object + controllers.trainingSessionRequest: + properties: + age: + type: integer + aiResult: + type: string + appName: + type: string + duration: + type: integer + endTime: + type: integer + evaluation: + type: string + gender: + type: string + isStart: + type: boolean + maxHeartRate: + type: integer + name: + type: string + peopleNum: + type: integer + regionId: + type: integer + runType: + type: string + testTime: + type: integer + tid: + type: integer + time: + type: integer + type: object + controllers.userAdminPayload: + properties: + email: + type: string + flavorType: + $ref: '#/definitions/models.UserFlavorType' + isActive: + type: boolean + password: + type: string + phone: + type: string + regionIds: + items: + type: integer + type: array + revokeTokens: + type: boolean + role: + $ref: '#/definitions/models.UserRole' + username: + type: string + type: object + models.UserFlavorType: + enum: + - all + - flink + - full + - light + - heartrate + - run50 + type: string + x-enum-varnames: + - UserFlavorAll + - UserFlavorFlink + - UserFlavorFull + - UserFlavorLight + - UserFlavorHeartRate + - UserFlavorRun50 + models.UserRole: + enum: + - super_admin + - region_admin + - operator + - viewer + type: string + x-enum-varnames: + - UserRoleSuperAdmin + - UserRoleRegionAdmin + - UserRoleOperator + - UserRoleViewer +host: localhost:8081 +info: + contact: {} + description: 智能心率采集分析平台后端服务,基于 Gin 框架,提供心率采集、AI 分析、教案管理、设备管理等功能 + title: 智能心率采集分析平台 API + version: "1.0" +paths: + /admin/gateways: + get: + description: 查询网关列表,支持关键词/售出状态/项目类型/区域筛选。超级管理员可查全部,操作员只能查所属区域 + parameters: + - description: 关键词(名称/MAC模糊搜索) + in: query + name: keyword + type: string + - description: 售出状态 + in: query + name: isSold + type: boolean + - description: 项目类型 + in: query + name: projectType + type: string + - description: 区域ID + in: query + name: regionId + type: integer + produces: + - application/json + responses: + "200": + description: 查询成功 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + security: + - BearerAuth: [] + summary: 获取网关列表 + tags: + - 网关管理 + post: + consumes: + - application/json + description: 创建新的网关记录,自动同步到产品库存 + parameters: + - description: 网关信息 + in: body + name: gateway + required: true + schema: + $ref: '#/definitions/controllers.gatewayPayload' + produces: + - application/json + responses: + "201": + description: 创建成功 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "400": + description: 请求参数错误 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "409": + description: MAC地址已存在 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + security: + - BearerAuth: [] + summary: 创建网关 + tags: + - 网关管理 + /admin/gateways/{id}: + delete: + description: 删除指定网关(已售出的网关禁止删除),自动同步删除产品库存 + parameters: + - description: 网关ID + in: path + name: id + required: true + type: integer + produces: + - application/json + responses: + "200": + description: 删除成功 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "403": + description: 已售出无法删除 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "404": + description: 网关不存在 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + security: + - BearerAuth: [] + summary: 删除网关 + tags: + - 网关管理 + put: + consumes: + - application/json + description: 更新指定网关的详细信息,自动同步到产品库存 + parameters: + - description: 网关ID + in: path + name: id + required: true + type: integer + - description: 更新信息 + in: body + name: gateway + required: true + schema: + $ref: '#/definitions/controllers.gatewayPayload' + produces: + - application/json + responses: + "200": + description: 更新成功 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "400": + description: 请求参数错误 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "404": + description: 网关不存在 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + security: + - BearerAuth: [] + summary: 更新网关信息 + tags: + - 网关管理 + /admin/kindergartens: + get: + description: 查询幼儿园列表,支持按名称/地址模糊搜索 + parameters: + - description: 关键词(名称/地址模糊搜索) + in: query + name: keyword + type: string + produces: + - application/json + responses: + "200": + description: 查询成功 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + security: + - BearerAuth: [] + summary: 获取幼儿园列表 + tags: + - 幼儿园管理 + post: + consumes: + - application/json + description: 创建新的幼儿园记录 + parameters: + - description: 幼儿园信息 + in: body + name: kindergarten + required: true + schema: + $ref: '#/definitions/controllers.kindergartenPayload' + produces: + - application/json + responses: + "201": + description: 创建成功 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "400": + description: 请求参数错误 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + security: + - BearerAuth: [] + summary: 创建幼儿园 + tags: + - 幼儿园管理 + /admin/kindergartens/{id}: + delete: + description: 删除指定幼儿园,如果被用户绑定则无法删除 + parameters: + - description: 幼儿园ID + in: path + name: id + required: true + type: integer + produces: + - application/json + responses: + "200": + description: 删除成功 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "404": + description: 幼儿园不存在 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "409": + description: 已绑定用户无法删除 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + security: + - BearerAuth: [] + summary: 删除幼儿园 + tags: + - 幼儿园管理 + put: + consumes: + - application/json + description: 更新指定幼儿园的名称、地址和区域 + parameters: + - description: 幼儿园ID + in: path + name: id + required: true + type: integer + - description: 更新信息 + in: body + name: kindergarten + required: true + schema: + $ref: '#/definitions/controllers.kindergartenPayload' + produces: + - application/json + responses: + "200": + description: 更新成功 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "400": + description: 请求参数错误 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "404": + description: 幼儿园不存在 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + security: + - BearerAuth: [] + summary: 更新幼儿园信息 + tags: + - 幼儿园管理 + /admin/product-definitions: + get: + description: 查询产品定义列表,支持按关键词/分类/启用状态筛选 + parameters: + - description: 关键词(代码/名称/描述模糊搜索) + in: query + name: keyword + type: string + - description: 分类筛选 + in: query + name: category + type: string + - description: 是否启用 + in: query + name: isActive + type: boolean + produces: + - application/json + responses: + "200": + description: 查询成功 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + security: + - BearerAuth: [] + summary: 获取产品定义列表 + tags: + - 产品定义管理 + post: + consumes: + - application/json + description: 创建新的产品定义 + parameters: + - description: 产品定义信息 + in: body + name: productDefinition + required: true + schema: + $ref: '#/definitions/controllers.productDefinitionPayload' + produces: + - application/json + responses: + "201": + description: 创建成功 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "400": + description: 请求参数错误 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + security: + - BearerAuth: [] + summary: 创建产品定义 + tags: + - 产品定义管理 + /admin/product-definitions/{id}: + delete: + description: 删除指定产品定义(被库存或模板引用的无法删除) + parameters: + - description: 产品定义ID + in: path + name: id + required: true + type: integer + produces: + - application/json + responses: + "200": + description: 删除成功 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "404": + description: 产品定义不存在 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "409": + description: 已被引用无法删除 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + security: + - BearerAuth: [] + summary: 删除产品定义 + tags: + - 产品定义管理 + put: + consumes: + - application/json + description: 更新指定产品定义的信息 + parameters: + - description: 产品定义ID + in: path + name: id + required: true + type: integer + - description: 更新信息 + in: body + name: productDefinition + required: true + schema: + $ref: '#/definitions/controllers.productDefinitionPayload' + produces: + - application/json + responses: + "200": + description: 更新成功 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "400": + description: 请求参数错误 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "404": + description: 产品定义不存在 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + security: + - BearerAuth: [] + summary: 更新产品定义 + tags: + - 产品定义管理 + /admin/product-inventories: + get: + description: 查询产品库存列表,支持多条件筛选 + parameters: + - description: 关键词(资产名称/序列号/购买方等模糊搜索) + in: query + name: keyword + type: string + - description: 产品代码筛选 + in: query + name: productCode + type: string + - description: 项目类型代码筛选 + in: query + name: projectTypeCode + type: string + - description: 套件代码筛选 + in: query + name: suiteCode + type: string + - description: 状态筛选 + in: query + name: status + type: string + - description: 购买方类型筛选 + in: query + name: soldTargetType + type: string + - description: 区域ID + in: query + name: regionId + type: integer + produces: + - application/json + responses: + "200": + description: 查询成功 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + security: + - BearerAuth: [] + summary: 获取产品库存列表 + tags: + - 产品库存管理 + post: + consumes: + - application/json + description: 创建新的产品库存记录 + parameters: + - description: 库存信息 + in: body + name: inventory + required: true + schema: + $ref: '#/definitions/controllers.productInventoryPayload' + produces: + - application/json + responses: + "201": + description: 创建成功 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "400": + description: 请求参数错误 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + security: + - BearerAuth: [] + summary: 创建产品库存记录 + tags: + - 产品库存管理 + /admin/product-inventories/{id}: + delete: + description: 删除指定产品库存记录(已售出的无法删除) + parameters: + - description: 库存ID + in: path + name: id + required: true + type: integer + produces: + - application/json + responses: + "200": + description: 删除成功 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "404": + description: 库存记录不存在 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "409": + description: 已售出无法删除 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + security: + - BearerAuth: [] + summary: 删除产品库存 + tags: + - 产品库存管理 + put: + consumes: + - application/json + description: 更新指定产品库存记录 + parameters: + - description: 库存ID + in: path + name: id + required: true + type: integer + - description: 更新信息 + in: body + name: inventory + required: true + schema: + $ref: '#/definitions/controllers.productInventoryPayload' + produces: + - application/json + responses: + "200": + description: 更新成功 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "400": + description: 请求参数错误 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "404": + description: 库存记录不存在 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + security: + - BearerAuth: [] + summary: 更新产品库存 + tags: + - 产品库存管理 + /admin/product-prototypes: + get: + description: 查询产品原型列表,支持按关键词/产品代码/项目类型筛选 + parameters: + - description: 关键词(名称/备注模糊搜索) + in: query + name: keyword + type: string + - description: 产品代码筛选 + in: query + name: productCode + type: string + - description: 项目类型代码筛选 + in: query + name: projectTypeCode + type: string + produces: + - application/json + responses: + "200": + description: 查询成功 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + security: + - BearerAuth: [] + summary: 获取产品原型列表 + tags: + - 产品原型管理 + post: + consumes: + - application/json + description: 创建新的产品原型 + parameters: + - description: 产品原型信息 + in: body + name: productPrototype + required: true + schema: + $ref: '#/definitions/controllers.productPrototypePayload' + produces: + - application/json + responses: + "201": + description: 创建成功 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "400": + description: 请求参数错误 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + security: + - BearerAuth: [] + summary: 创建产品原型 + tags: + - 产品原型管理 + /admin/product-prototypes/{id}: + delete: + description: 删除指定产品原型 + parameters: + - description: 产品原型ID + in: path + name: id + required: true + type: integer + produces: + - application/json + responses: + "200": + description: 删除成功 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "404": + description: 产品原型不存在 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + security: + - BearerAuth: [] + summary: 删除产品原型 + tags: + - 产品原型管理 + put: + consumes: + - application/json + description: 更新指定产品原型的信息 + parameters: + - description: 产品原型ID + in: path + name: id + required: true + type: integer + - description: 更新信息 + in: body + name: productPrototype + required: true + schema: + $ref: '#/definitions/controllers.productPrototypePayload' + produces: + - application/json + responses: + "200": + description: 更新成功 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "400": + description: 请求参数错误 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "404": + description: 产品原型不存在 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + security: + - BearerAuth: [] + summary: 更新产品原型 + tags: + - 产品原型管理 + /admin/product-suites: + get: + description: 查询产品套件列表,含套件下的库存明细 + parameters: + - description: 关键词(代码/名称/备注模糊搜索) + in: query + name: keyword + type: string + - description: 项目类型代码筛选 + in: query + name: projectTypeCode + type: string + produces: + - application/json + responses: + "200": + description: 查询成功 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + security: + - BearerAuth: [] + summary: 获取产品套件列表 + tags: + - 产品套件管理 + post: + consumes: + - application/json + description: 创建新的产品套件,可选关联库存记录 + parameters: + - description: 套件信息 + in: body + name: suite + required: true + schema: + $ref: '#/definitions/controllers.productSuitePayload' + produces: + - application/json + responses: + "201": + description: 创建成功 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "400": + description: 请求参数错误 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + security: + - BearerAuth: [] + summary: 创建产品套件 + tags: + - 产品套件管理 + /admin/product-suites/{id}: + delete: + description: 删除指定产品套件,自动解除关联库存的绑定 + parameters: + - description: 套件ID + in: path + name: id + required: true + type: integer + produces: + - application/json + responses: + "200": + description: 删除成功 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "404": + description: 套件不存在 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + security: + - BearerAuth: [] + summary: 删除产品套件 + tags: + - 产品套件管理 + put: + consumes: + - application/json + description: 更新指定产品套件的信息和关联库存 + parameters: + - description: 套件ID + in: path + name: id + required: true + type: integer + - description: 更新信息 + in: body + name: suite + required: true + schema: + $ref: '#/definitions/controllers.productSuitePayload' + produces: + - application/json + responses: + "200": + description: 更新成功 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "400": + description: 请求参数错误 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "404": + description: 套件不存在 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + security: + - BearerAuth: [] + summary: 更新产品套件 + tags: + - 产品套件管理 + /admin/project-product-templates: + get: + description: 查询项目产品模板列表,含项目类型和产品名称 + parameters: + - description: 项目类型代码筛选 + in: query + name: projectTypeCode + type: string + produces: + - application/json + responses: + "200": + description: 查询成功 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + security: + - BearerAuth: [] + summary: 获取项目产品模板列表 + tags: + - 项目产品模板管理 + /admin/project-types: + get: + description: 查询项目类型列表,支持按关键词/是否支持网关/是否启用筛选 + parameters: + - description: 关键词(代码/名称/描述模糊搜索) + in: query + name: keyword + type: string + - description: 是否支持网关 + in: query + name: supportsGateway + type: boolean + - description: 是否启用 + in: query + name: isActive + type: boolean + produces: + - application/json + responses: + "200": + description: 查询成功 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + security: + - BearerAuth: [] + summary: 获取项目类型列表 + tags: + - 项目类型管理 + post: + consumes: + - application/json + description: 创建新的项目类型 + parameters: + - description: 项目类型信息 + in: body + name: projectType + required: true + schema: + $ref: '#/definitions/controllers.projectTypePayload' + produces: + - application/json + responses: + "201": + description: 创建成功 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "400": + description: 请求参数错误 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + security: + - BearerAuth: [] + summary: 创建项目类型 + tags: + - 项目类型管理 + /admin/project-types/{id}: + delete: + description: 删除指定项目类型(被网关引用的无法删除) + parameters: + - description: 项目类型ID + in: path + name: id + required: true + type: integer + produces: + - application/json + responses: + "200": + description: 删除成功 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "404": + description: 项目类型不存在 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "409": + description: 已被网关引用无法删除 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + security: + - BearerAuth: [] + summary: 删除项目类型 + tags: + - 项目类型管理 + put: + consumes: + - application/json + description: 更新指定项目类型的信息 + parameters: + - description: 项目类型ID + in: path + name: id + required: true + type: integer + - description: 更新信息 + in: body + name: projectType + required: true + schema: + $ref: '#/definitions/controllers.projectTypePayload' + produces: + - application/json + responses: + "200": + description: 更新成功 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "400": + description: 请求参数错误 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "404": + description: 项目类型不存在 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + security: + - BearerAuth: [] + summary: 更新项目类型 + tags: + - 项目类型管理 + /admin/statistics/ai-analysis: + get: + description: 按区域统计AI分析的使用情况,包括调用次数、Token消耗、费用等 + parameters: + - description: 区域ID + in: query + name: regionId + type: integer + - description: 开始时间(毫秒时间戳) + in: query + name: startTime + type: integer + - description: 结束时间(毫秒时间戳) + in: query + name: endTime + type: integer + produces: + - application/json + responses: + "200": + description: 查询成功 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + security: + - BearerAuth: [] + summary: AI分析区域统计 + tags: + - 统计管理 + /admin/statistics/ai-analysis-records: + get: + description: 分页查询AI分析记录,支持按区域和时间范围筛选 + parameters: + - description: 页码(默认1) + in: query + name: pageNum + type: integer + - description: 每页数量(默认10,最大100) + in: query + name: pageSize + type: integer + - description: 区域ID + in: query + name: regionId + type: integer + - description: 开始时间(毫秒时间戳) + in: query + name: startTime + type: integer + - description: 结束时间(毫秒时间戳) + in: query + name: endTime + type: integer + produces: + - application/json + responses: + "200": + description: 查询成功 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + security: + - BearerAuth: [] + summary: 获取AI分析记录列表 + tags: + - 统计管理 + /admin/statistics/ai-analysis-records/{id}: + delete: + description: 删除指定的AI分析记录 + parameters: + - description: 记录ID + in: path + name: id + required: true + type: integer + produces: + - application/json + responses: + "200": + description: 删除成功 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "404": + description: 记录不存在 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + security: + - BearerAuth: [] + summary: 删除AI分析记录 + tags: + - 统计管理 + /admin/statistics/ai-analysis-timeline: + get: + description: 按日期统计AI分析的使用情况趋势,含总体和分区域数据 + parameters: + - description: 区域ID + in: query + name: regionId + type: integer + - description: 开始时间(毫秒时间戳) + in: query + name: startTime + type: integer + - description: 结束时间(毫秒时间戳) + in: query + name: endTime + type: integer + produces: + - application/json + responses: + "200": + description: 查询成功 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + security: + - BearerAuth: [] + summary: AI分析时间线统计 + tags: + - 统计管理 + /admin/statistics/mqtt-training-sessions: + get: + description: 按区域统计MQTT训练会话情况,包括开始、结束、完成、进行中的会话数 + parameters: + - description: 区域ID + in: query + name: regionId + type: integer + - description: 类型筛选 + in: query + name: flavorType + type: string + - description: 开始时间(毫秒时间戳) + in: query + name: startTime + type: integer + - description: 结束时间(毫秒时间戳) + in: query + name: endTime + type: integer + produces: + - application/json + responses: + "200": + description: 查询成功 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + security: + - BearerAuth: [] + summary: 训练会话区域统计 + tags: + - 统计管理 + /admin/system-debug/mqtt/start: + post: + consumes: + - application/json + description: 启动MQTT调试服务 + parameters: + - description: 是否持久化到数据库 + in: body + name: persist + schema: + $ref: '#/definitions/controllers.mqttDebugStartRequest' + produces: + - application/json + responses: + "200": + description: 启动成功 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + security: + - BearerAuth: [] + summary: 启动MQTT调试 + tags: + - 系统调试 + /admin/system-debug/mqtt/status: + get: + description: 获取MQTT调试服务的当前运行状态 + produces: + - application/json + responses: + "200": + description: 查询成功 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + security: + - BearerAuth: [] + summary: 获取MQTT调试状态 + tags: + - 系统调试 + /admin/system-debug/mqtt/stop: + post: + description: 停止MQTT调试服务 + produces: + - application/json + responses: + "200": + description: 停止成功 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + security: + - BearerAuth: [] + summary: 停止MQTT调试 + tags: + - 系统调试 + /admin/system-debug/mqtt/ws: + get: + description: 通过WebSocket实时监听MQTT消息(需要SuperAdmin权限) + parameters: + - description: JWT Token + in: query + name: token + required: true + type: string + responses: + "101": + description: 切换为WebSocket协议 + summary: MQTT WebSocket连接 + tags: + - 系统调试 + /admin/users: + get: + description: 查询系统用户列表,支持按关键词/角色/类型筛选 + parameters: + - description: 关键词(用户名/邮箱/手机号模糊搜索) + in: query + name: keyword + type: string + - description: 角色筛选 + in: query + name: role + type: string + - description: 类型筛选 + in: query + name: flavorType + type: string + produces: + - application/json + responses: + "200": + description: 查询成功 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + security: + - BearerAuth: [] + summary: 获取用户列表 + tags: + - 用户管理 + post: + consumes: + - application/json + description: 创建新的系统用户 + parameters: + - description: 用户信息 + in: body + name: user + required: true + schema: + $ref: '#/definitions/controllers.userAdminPayload' + produces: + - application/json + responses: + "201": + description: 创建成功 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "400": + description: 请求参数错误 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + security: + - BearerAuth: [] + summary: 创建用户 + tags: + - 用户管理 + /admin/users/{id}: + delete: + description: 删除指定用户(不能删除admin账号和当前登录用户) + parameters: + - description: 用户ID + in: path + name: id + required: true + type: integer + produces: + - application/json + responses: + "200": + description: 删除成功 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "400": + description: 无法删除受保护账号 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "404": + description: 用户不存在 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + security: + - BearerAuth: [] + summary: 删除用户 + tags: + - 用户管理 + put: + consumes: + - application/json + description: 更新指定用户的详细信息,支持重置密码和吊销Token + parameters: + - description: 用户ID + in: path + name: id + required: true + type: integer + - description: 更新信息 + in: body + name: user + required: true + schema: + $ref: '#/definitions/controllers.userAdminPayload' + produces: + - application/json + responses: + "200": + description: 更新成功 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "400": + description: 请求参数错误 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "404": + description: 用户不存在 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + security: + - BearerAuth: [] + summary: 更新用户信息 + tags: + - 用户管理 + /gateways/by-mac: + get: + description: 根据MAC地址查询网关信息(支持格式兼容:带冒号/横线/纯数字) + parameters: + - description: MAC地址 + in: query + name: mac + required: true + type: string + produces: + - application/json + responses: + "200": + description: 查询成功 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "400": + description: MAC参数为空 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "404": + description: 未找到该网关 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + security: + - BearerAuth: [] + summary: 按MAC查询网关 + tags: + - 网关管理 + /lesson-plans: + get: + description: 获取教案文件列表(非分页),按创建时间倒序 + produces: + - application/json + responses: + "200": + description: 查询成功 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "401": + description: 未认证 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + security: + - BearerAuth: [] + summary: 获取教案列表 + tags: + - 教案管理 + /lesson-plans/{id}: + delete: + description: 删除教案文件及其关联的分享码 + parameters: + - description: 教案ID + in: path + name: id + required: true + type: integer + produces: + - application/json + responses: + "200": + description: 删除成功 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "401": + description: 未认证 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "403": + description: 无权限 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "404": + description: 文件不存在 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + security: + - BearerAuth: [] + summary: 删除教案文件 + tags: + - 教案管理 + /lesson-plans/{id}/download: + get: + description: 通过ID下载教案文件,自动更新下载计数和最后下载时间 + parameters: + - description: 教案ID + in: path + name: id + required: true + type: integer + produces: + - application/octet-stream + responses: + "200": + description: 教案文件 + schema: + type: file + "401": + description: 未认证 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "403": + description: 无权限 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "404": + description: 文件不存在 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + security: + - BearerAuth: [] + summary: 下载教案文件 + tags: + - 教案管理 + /lesson-plans/{id}/share-code: + post: + description: 为教案文件生成6位数字分享码,有效期5分钟,每次生成会失效之前的分享码 + parameters: + - description: 教案ID + in: path + name: id + required: true + type: integer + produces: + - application/json + responses: + "200": + description: 生成成功 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "401": + description: 未认证 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "403": + description: 无权限 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "404": + description: 文件不存在 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + security: + - BearerAuth: [] + summary: 生成分享码 + tags: + - 教案管理 + /lesson-plans/page: + get: + description: 分页获取教案文件列表,支持文件名模糊搜索、上传者搜索、区域筛选、排序 + parameters: + - description: 页码(默认1) + in: query + name: pageNum + type: integer + - description: 每页数量(默认10,最大100) + in: query + name: pageSize + type: integer + - description: 文件名模糊搜索 + in: query + name: keyword + type: string + - description: 上传者名模糊搜索 + in: query + name: uploaderName + type: string + - description: 区域ID + in: query + name: regionId + type: integer + - description: '排序字段: file_size | created_at' + in: query + name: sortBy + type: string + - description: '排序方向: asc | desc' + in: query + name: sortOrder + type: string + produces: + - application/json + responses: + "200": + description: 查询成功 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "400": + description: 请求参数错误 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "401": + description: 未认证 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + security: + - BearerAuth: [] + summary: 分页查询教案 + tags: + - 教案管理 + /lesson-plans/share/{code}/download: + get: + description: 通过6位分享码下载教案文件(无需认证) + parameters: + - description: 6位分享码 + in: path + name: code + required: true + type: string + produces: + - application/octet-stream + responses: + "200": + description: 教案文件 + schema: + type: file + "400": + description: 分享码无效 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "404": + description: 分享码过期或不存在 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + summary: 通过分享码下载教案 + tags: + - 教案管理 + /lesson-plans/upload: + post: + consumes: + - multipart/form-data + description: 上传 .docx 格式的教案文件,支持MD5去重,最大10MB + parameters: + - description: 教案文件(.docx) + in: formData + name: file + required: true + type: file + produces: + - application/json + responses: + "201": + description: 上传成功 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "400": + description: 请求参数错误 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "401": + description: 未认证 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "409": + description: 文件已存在 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + security: + - BearerAuth: [] + summary: 上传教案文件 + tags: + - 教案管理 + /login: + post: + consumes: + - application/json + description: 用户名密码登录,返回JWT Token和用户信息 + parameters: + - description: 登录信息 + in: body + name: request + required: true + schema: + $ref: '#/definitions/controllers.SwagLoginRequest' + produces: + - application/json + responses: + "200": + description: 登录成功 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "400": + description: 请求参数错误 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "401": + description: 用户名或密码错误 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "403": + description: 用户已禁用 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + summary: 用户登录 + tags: + - 认证 + /register: + post: + consumes: + - application/json + description: 注册新用户,返回JWT Token + parameters: + - description: 注册信息 + in: body + name: request + required: true + schema: + $ref: '#/definitions/controllers.SwagRegisterRequest' + produces: + - application/json + responses: + "201": + description: 注册成功 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "400": + description: 请求参数错误 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "409": + description: 用户名已存在 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + summary: 用户注册 + tags: + - 认证 + /step: + post: + consumes: + - application/json + description: 接收并保存踏步训练记录,包含心率和步频数据,异步计算回归结果 + parameters: + - description: 踏步训练记录 + in: body + name: record + required: true + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + produces: + - application/json + responses: + "201": + description: 保存成功 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "400": + description: 请求参数错误 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "401": + description: 未认证 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + security: + - BearerAuth: [] + summary: 创建踏步训练记录 + tags: + - 踏步训练 + /step/train-data/{trainId}: + get: + description: 根据训练ID获取踏步训练的详细信息,包含心率和步频数据 + parameters: + - description: 训练ID + in: path + name: trainId + required: true + type: integer + produces: + - application/json + responses: + "200": + description: 查询成功 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "400": + description: 请求参数错误 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "401": + description: 未认证 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "404": + description: 训练记录不存在 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + security: + - BearerAuth: [] + summary: 获取踏步训练详情 + tags: + - 踏步训练 + /step/train-rank/{trainId}: + get: + description: 根据训练ID和回归类型获取训练排名 + parameters: + - description: 训练ID + in: path + name: trainId + required: true + type: integer + - description: '回归类型: 1=线性回归 | 3=二次回归' + in: query + name: type + required: true + type: integer + produces: + - application/json + responses: + "200": + description: 查询成功 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "400": + description: 请求参数错误 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "401": + description: 未认证 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + security: + - BearerAuth: [] + summary: 获取训练排名 + tags: + - 踏步训练 + /step/train-records: + get: + description: 分页获取当前用户的踏步训练记录,按开始时间倒序 + parameters: + - description: 页码(默认1) + in: query + name: pageNum + type: integer + - description: 每页数量(默认10,最大100) + in: query + name: pageSize + type: integer + produces: + - application/json + responses: + "200": + description: 查询成功 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "400": + description: 请求参数错误 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "401": + description: 未认证 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + security: + - BearerAuth: [] + summary: 获取踏步训练记录列表 + tags: + - 踏步训练 + /train-records: + post: + consumes: + - application/json + description: 接收并保存训练记录及心率数据,支持重复上传(按train_id去重更新) + parameters: + - description: 训练记录数据 + in: body + name: record + required: true + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + produces: + - application/json + responses: + "201": + description: 保存成功 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "400": + description: 请求参数错误 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + summary: 创建训练记录 + tags: + - 训练管理 + /train-records/analysis: + get: + description: 对历史心率数据进行统计分析和正态分布曲线拟合 + produces: + - application/json + responses: + "200": + description: 分析成功 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "400": + description: 数据量不足 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + summary: 心率曲线分析 + tags: + - 训练管理 + /train-records/analysis-by-ai: + post: + consumes: + - multipart/form-data + description: 上传心率CSV和教案文件,通过AI生成课堂分析报告,支持流式和非流式输出 + parameters: + - description: 心率数据CSV文件 + in: formData + name: heart_rate_data + required: true + type: file + - description: 步数数据CSV文件(analysis_type为heart_rate_with_steps时必填) + in: formData + name: step_data + type: file + - description: 教案DOCX文件(teaching_plan_source为upload/wechat时必填) + in: formData + name: teaching_plan + type: file + - description: '分析类型: heart_rate_only(默认) | heart_rate_with_steps' + in: formData + name: analysis_type + type: string + - description: '教案来源: upload(默认) | cloud | wechat' + in: formData + name: teaching_plan_source + type: string + - description: 区域ID + in: formData + name: regionid + type: string + - description: 训练ID + in: formData + name: trainid + type: string + - description: 云端教案ID(teaching_plan_source=cloud时必填) + in: formData + name: lesson_plan_id + type: string + - description: '是否流式输出: true | false' + in: formData + name: stream + type: string + produces: + - application/json + responses: + "200": + description: 分析成功 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "400": + description: 请求参数错误 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + summary: AI分析 + tags: + - AI分析 + /train-records/cloud-files: + get: + description: 获取所有云端教案文件列表 + produces: + - application/json + responses: + "200": + description: 查询成功 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + summary: 获取云端教案列表 + tags: + - 训练管理 + /train-records/session: + post: + consumes: + - application/json + description: 上传训练开始/结束会话,用于MQTT训练会话追踪 + parameters: + - description: 训练会话数据 + in: body + name: session + required: true + schema: + $ref: '#/definitions/controllers.trainingSessionRequest' + produces: + - application/json + responses: + "200": + description: 操作成功 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + "400": + description: 请求参数错误 + schema: + $ref: '#/definitions/controllers.SwagAPIResponse' + summary: 上传训练会话 + tags: + - 训练管理 +securityDefinitions: + BearerAuth: + in: header + name: Authorization + type: apiKey +swagger: "2.0" diff --git a/go.mod b/go.mod index 2950073..29b2f76 100644 --- a/go.mod +++ b/go.mod @@ -15,6 +15,9 @@ require ( ) require ( + github.com/KyleBanks/depth v1.2.1 // indirect + github.com/PuerkitoBio/purell v1.1.1 // indirect + github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect github.com/bytedance/sonic v1.11.6 // indirect github.com/bytedance/sonic/loader v0.1.1 // indirect github.com/cloudwego/base64x v0.1.4 // indirect @@ -24,6 +27,10 @@ require ( github.com/fumiama/imgsz v0.0.2 // indirect github.com/gabriel-vasile/mimetype v1.4.3 // indirect github.com/gin-contrib/sse v0.1.0 // indirect + github.com/go-openapi/jsonpointer v0.19.5 // indirect + github.com/go-openapi/jsonreference v0.19.6 // indirect + github.com/go-openapi/spec v0.20.4 // indirect + github.com/go-openapi/swag v0.19.15 // indirect github.com/go-pdf/fpdf v0.9.0 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect @@ -37,9 +44,11 @@ require ( github.com/jackc/puddle/v2 v2.2.1 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect + github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/cpuid/v2 v2.2.7 // indirect github.com/leodido/go-urn v1.4.0 // indirect + github.com/mailru/easyjson v0.7.6 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect @@ -51,16 +60,21 @@ require ( github.com/spf13/cast v1.7.1 // indirect github.com/spf13/pflag v1.0.6 // indirect github.com/subosito/gotenv v1.6.0 // indirect + github.com/swaggo/files v1.0.1 // indirect + github.com/swaggo/gin-swagger v1.6.1 // indirect + github.com/swaggo/swag v1.8.12 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/ugorji/go/codec v1.2.12 // indirect go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.9.0 // indirect golang.org/x/arch v0.8.0 // indirect - golang.org/x/crypto v0.32.0 // indirect - golang.org/x/net v0.33.0 // indirect + golang.org/x/crypto v0.36.0 // indirect + golang.org/x/net v0.38.0 // indirect golang.org/x/sync v0.12.0 // indirect - golang.org/x/sys v0.29.0 // indirect + golang.org/x/sys v0.31.0 // indirect golang.org/x/text v0.23.0 // indirect + golang.org/x/tools v0.26.0 // indirect google.golang.org/protobuf v1.36.1 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index ffe7193..53eca57 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,9 @@ +github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc= +github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE= +github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI= +github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc0= github.com/bytedance/sonic v1.11.6/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4= github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM= @@ -6,6 +12,7 @@ github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/ github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg= github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -25,6 +32,16 @@ github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU= github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y= +github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= +github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonreference v0.19.6 h1:UBIxjkht+AWIgYzCDSv2GN+E/togfwXUJFRTWhl2Jjs= +github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns= +github.com/go-openapi/spec v0.20.4 h1:O8hJrt0UMnhHcluhIdUgCLRWyM2x7QkBXRvOs7m+O1M= +github.com/go-openapi/spec v0.20.4/go.mod h1:faYFR1CvsJZ0mNsmsphTMSoRrNV3TEDoAM7FOEWeq8I= +github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-openapi/swag v0.19.15 h1:D2NRCBzS9/pEY3gP9Nl8aDqGUcPFrwG2p+CNFrLyrCM= +github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= github.com/go-pdf/fpdf v0.9.0 h1:PPvSaUuo1iMi9KkaAn90NuKi+P4gwMedWPHhj8YlJQw= github.com/go-pdf/fpdf v0.9.0/go.mod h1:oO8N111TkmKb9D7VvWGLvLJlaZUQVPM+6V42pp3iV4Y= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= @@ -58,18 +75,27 @@ github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= +github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA= +github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -77,6 +103,7 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M= github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -103,6 +130,7 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= @@ -111,10 +139,17 @@ github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOf github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= +github.com/swaggo/files v1.0.1 h1:J1bVJ4XHZNq0I46UU90611i9/YzdrF7x92oX1ig5IdE= +github.com/swaggo/files v1.0.1/go.mod h1:0qXmMNH6sXNf+73t65aKeB+ApmgxdnkQzVTAj2uaMUg= +github.com/swaggo/gin-swagger v1.6.1 h1:Ri06G4gc9N4t4k8hekMigJ9zKTFSlqj/9paAQCQs7cY= +github.com/swaggo/gin-swagger v1.6.1/go.mod h1:LQ+hJStHakCWRiK/YNYtJOu4mR2FP+pxLnILT/qNiTw= +github.com/swaggo/swag v1.8.12 h1:pctzkNPu0AlQP2royqX3apjKCQonAnf7KGoxeO4y64w= +github.com/swaggo/swag v1.8.12/go.mod h1:lNfm6Gg+oAq3zRJQNEMBE66LIJKM44mxFqhEEgy2its= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= @@ -122,26 +157,68 @@ go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTV golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc= golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= +golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= +golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= +golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= +golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw= golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= +golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ= +golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= google.golang.org/protobuf v1.36.1 h1:yBPeRvTftaleIgM3PZ/WBIZ7XM/eEYAaEyCwvyjq/gk= google.golang.org/protobuf v1.36.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gorm.io/driver/postgres v1.5.11 h1:ubBVAfbKEUld/twyKZ0IYn9rSQh448EdelLYk9Mv314= diff --git a/main.go b/main.go index c82d220..0afd372 100644 --- a/main.go +++ b/main.go @@ -1,3 +1,11 @@ +// @title 智能心率采集分析平台 API +// @version 1.0 +// @description 智能心率采集分析平台后端服务,基于 Gin 框架,提供心率采集、AI 分析、教案管理、设备管理等功能 +// @host localhost:8081 +// @BasePath /api/v1 +// @securityDefinitions.apikey BearerAuth +// @in header +// @name Authorization package main import ( diff --git a/routes/routes.go b/routes/routes.go index a3f57ad..689466b 100644 --- a/routes/routes.go +++ b/routes/routes.go @@ -2,7 +2,10 @@ package routes import ( "github.com/gin-gonic/gin" + swaggerFiles "github.com/swaggo/files" + ginSwagger "github.com/swaggo/gin-swagger" "hr_receiver/controllers" + _ "hr_receiver/docs" "hr_receiver/middleware" "net/http" ) @@ -46,6 +49,9 @@ func SetupRouter() *gin.Engine { r.GET("/auth/token", deviceTokenHandler) + // Swagger API文档 + r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler)) + v1 := r.Group("/api/v1") { records := v1.Group("/train-records") //.Use(middleware.AuthMiddleware())