package controllers import ( "bytes" "encoding/json" "fmt" "image" "image/draw" _ "image/gif" "image/jpeg" _ "image/png" "shudao-chat-go/models" "shudao-chat-go/utils" "strings" "time" "github.com/beego/beego/v2/server/web" ) type SceneController struct { web.Controller } // 隐患识别获取历史记录 func (c *SceneController) GetHistoryRecognitionRecord() { // 从token中获取用户信息 userInfo, err := utils.GetUserInfoFromContext(c.Ctx.Input.GetData("userInfo")) if err != nil { c.Data["json"] = map[string]interface{}{ "statusCode": 401, "msg": "获取用户信息失败: " + err.Error(), } c.ServeJSON() return } user_id := int64(userInfo.ID) if user_id == 0 { user_id = 1 } var recognitionRecords []models.RecognitionRecord models.DB.Model(&models.RecognitionRecord{}).Where("user_id = ? AND is_deleted = ?", user_id, 0).Order("-updated_at").Find(&recognitionRecords) // 将原始OSS URL转换为代理URL,前端需要显示图片 for i := range recognitionRecords { if recognitionRecords[i].OriginalImageUrl != "" { // 检查是否已经是代理URL格式 if !strings.Contains(recognitionRecords[i].OriginalImageUrl, "/apiv1/oss/parse/?url=") { recognitionRecords[i].OriginalImageUrl = utils.GetProxyURL(recognitionRecords[i].OriginalImageUrl) } } if recognitionRecords[i].RecognitionImageUrl != "" { // 检查是否已经是代理URL格式 if !strings.Contains(recognitionRecords[i].RecognitionImageUrl, "/apiv1/oss/parse/?url=") { recognitionRecords[i].RecognitionImageUrl = utils.GetProxyURL(recognitionRecords[i].RecognitionImageUrl) } } } //计算返回的总共的数据数量 var total int64 models.DB.Model(&models.RecognitionRecord{}).Where("user_id = ? AND is_deleted = ?", user_id, 0).Count(&total) c.Data["json"] = map[string]interface{}{ "statusCode": 200, "msg": "success", "data": recognitionRecords, // 返回处理后的数据,包含代理URL "total": total, } c.ServeJSON() } // 获取识别记录详情 func (c *SceneController) GetRecognitionRecordDetail() { recognition_record_id, _ := c.GetInt64("recognition_record_id") if recognition_record_id == 0 { c.Data["json"] = map[string]interface{}{ "statusCode": 400, "msg": "识别记录ID不能为空", } c.ServeJSON() return } var record models.RecognitionRecord if err := models.DB.Where("id = ? AND is_deleted = ?", recognition_record_id, 0).First(&record).Error; err != nil { c.Data["json"] = map[string]interface{}{ "statusCode": 404, "msg": "识别记录不存在", } c.ServeJSON() return } // 将Description字符串转换为数组 var thirdScenes []string if record.Description != "" { thirdScenes = strings.Split(record.Description, " ") } // 通过关联表查询二级场景名称 // var secondSceneNames []string // var recognitionRecordSecondScenes []models.RecognitionRecordSecondScene // models.DB.Preload("SecondScene").Where("recognition_record_id = ?", record.ID).Find(&recognitionRecordSecondScenes) // for _, rrss := range recognitionRecordSecondScenes { // secondSceneNames = append(secondSceneNames, rrss.SecondScene.SecondSceneName) // } // 将原始OSS URL转换为代理URL,前端需要显示图片 originalImageURL := record.OriginalImageUrl recognitionImageURL := record.RecognitionImageUrl if originalImageURL != "" { // 检查是否已经是代理URL格式 if !strings.Contains(originalImageURL, "/apiv1/oss/parse/?url=") { originalImageURL = utils.GetProxyURL(originalImageURL) } } if recognitionImageURL != "" { // 检查是否已经是代理URL格式 if !strings.Contains(recognitionImageURL, "/apiv1/oss/parse/?url=") { recognitionImageURL = utils.GetProxyURL(recognitionImageURL) } } // 构建详情数据 detailData := map[string]interface{}{ "id": record.ID, "original_image_url": originalImageURL, "recognition_image_url": recognitionImageURL, "user_id": record.UserID, "title": record.Title, "description": record.Description, "created_at": record.CreatedAt, "updated_at": record.UpdatedAt, // 添加与隐患识别接口一致的字段 "labels": record.Labels, // 二级场景名称数组 "third_scenes": thirdScenes, // 三级场景名称数组 "tag_type": record.TagType, "scene_match": record.SceneMatch, "tip_accuracy": record.TipAccuracy, "effect_evaluation": record.EffectEvaluation, "user_remark": record.UserRemark, } c.Data["json"] = map[string]interface{}{ "statusCode": 200, "msg": "success", "data": detailData, } c.ServeJSON() } // 用户提交点评 func (c *SceneController) SubmitEvaluation() { var requestData models.RecognitionRecord if err := json.Unmarshal(c.Ctx.Input.RequestBody, &requestData); err != nil { c.Data["json"] = map[string]interface{}{ "statusCode": 400, "msg": "JSON解析失败: " + err.Error(), } } scene_match := requestData.SceneMatch tip_accuracy := requestData.TipAccuracy effect_evaluation := requestData.EffectEvaluation tx := models.DB.Begin() if err := tx.Model(&models.RecognitionRecord{}).Where("id = ?", requestData.ID).Updates(map[string]interface{}{ "scene_match": scene_match, "tip_accuracy": tip_accuracy, "effect_evaluation": effect_evaluation, "user_remark": requestData.UserRemark, }).Error; err != nil { tx.Rollback() c.Data["json"] = map[string]interface{}{ "statusCode": 500, "msg": "点评失败: " + err.Error(), } } tx.Commit() c.Data["json"] = map[string]interface{}{ "statusCode": 200, "msg": "success", } c.ServeJSON() } // 查询用户最新的一条识别记录是否点评 func (c *SceneController) GetLatestRecognitionRecord() { // 从token中获取用户信息 userInfo, err := utils.GetUserInfoFromContext(c.Ctx.Input.GetData("userInfo")) if err != nil { c.Data["json"] = map[string]interface{}{ "statusCode": 401, "msg": "获取用户信息失败: " + err.Error(), } c.ServeJSON() return } user_id := int64(userInfo.ID) if user_id == 0 { user_id = 1 } var recognitionRecord models.RecognitionRecord models.DB.Model(&models.RecognitionRecord{}).Where("user_id = ? AND is_deleted = ?", user_id, 0).Order("-created_at").First(&recognitionRecord) //如果数据为空,则无需判断上一条是否点评则构架一个假数据EffectEvaluation=1给前端 if recognitionRecord.ID == 0 { recognitionRecord = models.RecognitionRecord{ EffectEvaluation: 1, } } c.Data["json"] = map[string]interface{}{ "statusCode": 200, "msg": "success", "data": recognitionRecord, } c.ServeJSON() } // 获取隐患识别三级场景标题查询正确和错误的示例图 func (c *SceneController) GetThirdSceneExampleImage() { // 从token中获取用户信息用于生成水印 userInfo, err := utils.GetUserInfoFromContext(c.Ctx.Input.GetData("userInfo")) if err != nil { c.Data["json"] = map[string]interface{}{ "statusCode": 401, "msg": "获取用户信息失败: " + err.Error(), } c.ServeJSON() return } third_scene_name := c.GetString("third_scene_name") if third_scene_name == "" { c.Data["json"] = map[string]interface{}{ "statusCode": 400, "msg": "三级场景名称不能为空", } c.ServeJSON() return } var thirdScene models.ThirdScene models.DB.Where("third_scene_name = ? and is_deleted = ?", third_scene_name, 0).First(&thirdScene) if thirdScene.ID == 0 { c.Data["json"] = map[string]interface{}{ "statusCode": 404, "msg": "三级场景不存在", } c.ServeJSON() return } watermarkDate := time.Now().Format("2006/01/02") if thirdScene.CorrectExampleImage != "" { correctURL, err := generateWatermarkedExampleImage(thirdScene.CorrectExampleImage, userInfo.Name, userInfo.ContactNumber, watermarkDate, fmt.Sprintf("third_scene_correct_%d", thirdScene.ID)) if err != nil { c.Data["json"] = map[string]interface{}{ "statusCode": 500, "msg": "正确示例图加水印失败: " + err.Error(), } c.ServeJSON() return } thirdScene.CorrectExampleImage = correctURL } if thirdScene.WrongExampleImage != "" { wrongURL, err := generateWatermarkedExampleImage(thirdScene.WrongExampleImage, userInfo.Name, userInfo.ContactNumber, watermarkDate, fmt.Sprintf("third_scene_wrong_%d", thirdScene.ID)) if err != nil { c.Data["json"] = map[string]interface{}{ "statusCode": 500, "msg": "错误示例图加水印失败: " + err.Error(), } c.ServeJSON() return } thirdScene.WrongExampleImage = wrongURL } // 将示例图URL转换为代理URL,前端需要显示图片 if thirdScene.CorrectExampleImage != "" { // 检查是否已经是代理URL格式 if !strings.Contains(thirdScene.CorrectExampleImage, "/apiv1/oss/parse/?url=") { thirdScene.CorrectExampleImage = utils.GetProxyURL(thirdScene.CorrectExampleImage) } } if thirdScene.WrongExampleImage != "" { // 检查是否已经是代理URL格式 if !strings.Contains(thirdScene.WrongExampleImage, "/apiv1/oss/parse/?url=") { thirdScene.WrongExampleImage = utils.GetProxyURL(thirdScene.WrongExampleImage) } } c.Data["json"] = map[string]interface{}{ "statusCode": 200, "msg": "success", "data": thirdScene, } c.ServeJSON() } // generateWatermarkedExampleImage 为示例图添加水印并返回新的OSS代理URL func generateWatermarkedExampleImage(originalURL, username, account, date, keyPrefix string) (string, error) { if originalURL == "" { return "", fmt.Errorf("示例图地址为空") } imageData, err := downloadImageFromOSS(originalURL) if err != nil { return "", fmt.Errorf("下载示例图失败: %w", err) } img, _, err := image.Decode(bytes.NewReader(imageData)) if err != nil { return "", fmt.Errorf("解析示例图失败: %w", err) } bounds := img.Bounds() drawableImg := image.NewRGBA(bounds) draw.Draw(drawableImg, bounds, img, image.Point{}, draw.Src) drawableImg = addLogoToImage(drawableImg) drawableImg = addTextWatermark(drawableImg, username, account, date) var buf bytes.Buffer if err := jpeg.Encode(&buf, drawableImg, &jpeg.Options{Quality: 95}); err != nil { return "", fmt.Errorf("编码水印示例图失败: %w", err) } now := time.Now().UTC() fileName := fmt.Sprintf("third_scene_examples/%d/%s_%s_%d.jpg", now.Year(), now.Format("0102"), keyPrefix, now.UnixNano()) url, err := uploadImageToOSS(buf.Bytes(), fileName) if err != nil { return "", fmt.Errorf("上传水印示例图失败: %w", err) } return url, nil }