feat: gateway store.
This commit is contained in:
+9
-1
@@ -30,6 +30,7 @@ const (
|
||||
analysisTypeHeartRateWithSteps = "heart_rate_with_steps"
|
||||
sourceUpload = "upload"
|
||||
sourceCloud = "cloud"
|
||||
sourceWechat = "wechat"
|
||||
)
|
||||
|
||||
// readDocxContent 读取 .docx 文件并将其转换为结构化文本
|
||||
@@ -449,6 +450,13 @@ func resolveTeachingPlanContent(c *gin.Context, form *multipart.Form, source str
|
||||
}
|
||||
content, err := readDocxContent(docxFiles[0])
|
||||
return content, docxFiles[0].Size, err
|
||||
case sourceWechat:
|
||||
docxFiles := form.File["teaching_plan"]
|
||||
if len(docxFiles) == 0 {
|
||||
return "", 0, fmt.Errorf("Missing required file: teaching_plan (.docx)")
|
||||
}
|
||||
content, err := readDocxContent(docxFiles[0])
|
||||
return content, docxFiles[0].Size, err
|
||||
case sourceCloud:
|
||||
lessonPlanID := c.PostForm("lesson_plan_id")
|
||||
if strings.TrimSpace(lessonPlanID) == "" {
|
||||
@@ -461,6 +469,6 @@ func resolveTeachingPlanContent(c *gin.Context, form *multipart.Form, source str
|
||||
content, err := readDocxContentFromPath(fileRecord.FilePath)
|
||||
return content, fileRecord.FileSize, err
|
||||
default:
|
||||
return "", 0, fmt.Errorf("invalid teaching_plan_source, expected %s or %s", sourceUpload, sourceCloud)
|
||||
return "", 0, fmt.Errorf("invalid teaching_plan_source, expected %s, %s or %s", sourceUpload, sourceWechat, sourceCloud)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -577,6 +577,8 @@ func translateSourceType(sourceType string) string {
|
||||
switch strings.TrimSpace(strings.ToLower(sourceType)) {
|
||||
case "upload":
|
||||
return "上传文件"
|
||||
case "wechat":
|
||||
return "微信分享"
|
||||
case "cloud":
|
||||
return "云端文件"
|
||||
default:
|
||||
|
||||
@@ -74,6 +74,47 @@ func (gc *GatewayAdminController) List(c *gin.Context) {
|
||||
writeSuccess(c, http.StatusOK, "查询成功", items)
|
||||
}
|
||||
|
||||
// GetByMACForUser 按 MAC 查询网关信息
|
||||
// GET /api/v1/gateways/by-mac?mac=
|
||||
func (gc *GatewayAdminController) GetByMACForUser(c *gin.Context) {
|
||||
macInput := strings.ToUpper(strings.TrimSpace(c.Query("mac")))
|
||||
if macInput == "" {
|
||||
writeError(c, http.StatusBadRequest, "mac参数不能为空")
|
||||
return
|
||||
}
|
||||
// 规范化:去掉冒号和横线,兼容不同存储格式
|
||||
macClean := strings.ReplaceAll(strings.ReplaceAll(macInput, ":", ""), "-", "")
|
||||
|
||||
query := gc.DB.Where("REPLACE(REPLACE(UPPER(mac), ':', ''), '-', '') = ?", macClean)
|
||||
|
||||
roleValue, _ := c.Get("role")
|
||||
role, _ := roleValue.(models.UserRole)
|
||||
if role != models.UserRoleSuperAdmin {
|
||||
regionIDs, err := getUserRegionIDsFromContext(c)
|
||||
if err != nil {
|
||||
writeError(c, http.StatusForbidden, err.Error())
|
||||
return
|
||||
}
|
||||
if len(regionIDs) == 0 {
|
||||
writeError(c, http.StatusForbidden, "当前用户未配置可访问区域")
|
||||
return
|
||||
}
|
||||
query = query.Where("region_id IN ?", regionIDs)
|
||||
}
|
||||
|
||||
var item models.Gateway
|
||||
if err := query.First(&item).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
writeError(c, http.StatusNotFound, "未找到该网关")
|
||||
return
|
||||
}
|
||||
writeError(c, http.StatusInternalServerError, "查询网关失败")
|
||||
return
|
||||
}
|
||||
|
||||
writeSuccess(c, http.StatusOK, "查询成功", item)
|
||||
}
|
||||
|
||||
// Create 创建新网关
|
||||
// POST /api/gateways
|
||||
func (gc *GatewayAdminController) Create(c *gin.Context) {
|
||||
@@ -341,3 +382,22 @@ func respondGatewayLookupError(c *gin.Context, err error) {
|
||||
}
|
||||
writeError(c, http.StatusInternalServerError, "查询网关时出错")
|
||||
}
|
||||
|
||||
func getUserRegionIDsFromContext(c *gin.Context) ([]uint32, error) {
|
||||
regionValue, exists := c.Get("regionIDs")
|
||||
if !exists {
|
||||
return nil, errors.New("missing user regions")
|
||||
}
|
||||
regionIDs, ok := regionValue.([]uint32)
|
||||
if !ok {
|
||||
return nil, errors.New("invalid user regions")
|
||||
}
|
||||
filtered := make([]uint32, 0, len(regionIDs))
|
||||
for _, regionID := range regionIDs {
|
||||
if regionID == 0 {
|
||||
continue
|
||||
}
|
||||
filtered = append(filtered, regionID)
|
||||
}
|
||||
return filtered, nil
|
||||
}
|
||||
|
||||
@@ -121,6 +121,7 @@ type regionStatisticsItem struct {
|
||||
TotalOutputSizeBytes int64 `json:"totalOutputSizeBytes"`
|
||||
TotalDurationMs int64 `json:"totalDurationMs"`
|
||||
AvgDurationMs float64 `json:"avgDurationMs"`
|
||||
AvgTotalCost float64 `json:"avgTotalCost"`
|
||||
TotalOriginalFileSize int64 `json:"totalOriginalFileSize"`
|
||||
TotalCompressedSize int64 `json:"totalCompressedSize"`
|
||||
TotalCost float64 `json:"totalCost"`
|
||||
@@ -272,6 +273,10 @@ func (sc *StatisticsController) StatisticsByRegion(c *gin.Context) {
|
||||
if r.Count > 0 {
|
||||
avgDuration = float64(r.TotalDurationMs) / float64(r.Count)
|
||||
}
|
||||
avgTotalCost := float64(0)
|
||||
if r.Count > 0 {
|
||||
avgTotalCost = r.TotalCost / float64(r.Count)
|
||||
}
|
||||
kgName := ""
|
||||
if regionID > 0 {
|
||||
kgName = kindergartenMap[regionID]
|
||||
@@ -297,6 +302,7 @@ func (sc *StatisticsController) StatisticsByRegion(c *gin.Context) {
|
||||
TotalOutputSizeBytes: r.TotalOutputSizeBytes,
|
||||
TotalDurationMs: r.TotalDurationMs,
|
||||
AvgDurationMs: avgDuration,
|
||||
AvgTotalCost: avgTotalCost,
|
||||
TotalOriginalFileSize: r.TotalOriginalFileSize,
|
||||
TotalCompressedSize: r.TotalCompressedSize,
|
||||
TotalCost: r.TotalCost,
|
||||
@@ -343,6 +349,7 @@ func (sc *StatisticsController) StatisticsByRegion(c *gin.Context) {
|
||||
|
||||
if overall.Count > 0 {
|
||||
overall.AvgDurationMs = float64(overall.TotalDurationMs) / float64(overall.Count)
|
||||
overall.AvgTotalCost = overall.TotalCost / float64(overall.Count)
|
||||
}
|
||||
|
||||
writeSuccess(c, http.StatusOK, "query success", gin.H{
|
||||
|
||||
Reference in New Issue
Block a user