scene.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. package controllers
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "fmt"
  6. "image"
  7. "image/draw"
  8. _ "image/gif"
  9. "image/jpeg"
  10. _ "image/png"
  11. "shudao-chat-go/models"
  12. "shudao-chat-go/utils"
  13. "strings"
  14. "time"
  15. "github.com/beego/beego/v2/server/web"
  16. )
  17. type SceneController struct {
  18. web.Controller
  19. }
  20. // 隐患识别获取历史记录
  21. func (c *SceneController) GetHistoryRecognitionRecord() {
  22. // 从token中获取用户信息
  23. userInfo, err := utils.GetUserInfoFromContext(c.Ctx.Input.GetData("userInfo"))
  24. if err != nil {
  25. c.Data["json"] = map[string]interface{}{
  26. "statusCode": 401,
  27. "msg": "获取用户信息失败: " + err.Error(),
  28. }
  29. c.ServeJSON()
  30. return
  31. }
  32. user_id := int64(userInfo.ID)
  33. if user_id == 0 {
  34. user_id = 1
  35. }
  36. var recognitionRecords []models.RecognitionRecord
  37. models.DB.Model(&models.RecognitionRecord{}).Where("user_id = ? AND is_deleted = ?", user_id, 0).Order("-updated_at").Find(&recognitionRecords)
  38. // 将原始OSS URL转换为代理URL,前端需要显示图片
  39. for i := range recognitionRecords {
  40. if recognitionRecords[i].OriginalImageUrl != "" {
  41. // 检查是否已经是代理URL格式
  42. if !strings.Contains(recognitionRecords[i].OriginalImageUrl, "/apiv1/oss/parse/?url=") {
  43. recognitionRecords[i].OriginalImageUrl = utils.GetProxyURL(recognitionRecords[i].OriginalImageUrl)
  44. }
  45. }
  46. if recognitionRecords[i].RecognitionImageUrl != "" {
  47. // 检查是否已经是代理URL格式
  48. if !strings.Contains(recognitionRecords[i].RecognitionImageUrl, "/apiv1/oss/parse/?url=") {
  49. recognitionRecords[i].RecognitionImageUrl = utils.GetProxyURL(recognitionRecords[i].RecognitionImageUrl)
  50. }
  51. }
  52. }
  53. //计算返回的总共的数据数量
  54. var total int64
  55. models.DB.Model(&models.RecognitionRecord{}).Where("user_id = ? AND is_deleted = ?", user_id, 0).Count(&total)
  56. c.Data["json"] = map[string]interface{}{
  57. "statusCode": 200,
  58. "msg": "success",
  59. "data": recognitionRecords, // 返回处理后的数据,包含代理URL
  60. "total": total,
  61. }
  62. c.ServeJSON()
  63. }
  64. // 获取识别记录详情
  65. func (c *SceneController) GetRecognitionRecordDetail() {
  66. recognition_record_id, _ := c.GetInt64("recognition_record_id")
  67. if recognition_record_id == 0 {
  68. c.Data["json"] = map[string]interface{}{
  69. "statusCode": 400,
  70. "msg": "识别记录ID不能为空",
  71. }
  72. c.ServeJSON()
  73. return
  74. }
  75. var record models.RecognitionRecord
  76. if err := models.DB.Where("id = ? AND is_deleted = ?", recognition_record_id, 0).First(&record).Error; err != nil {
  77. c.Data["json"] = map[string]interface{}{
  78. "statusCode": 404,
  79. "msg": "识别记录不存在",
  80. }
  81. c.ServeJSON()
  82. return
  83. }
  84. // 将Description字符串转换为数组
  85. var thirdScenes []string
  86. if record.Description != "" {
  87. thirdScenes = strings.Split(record.Description, " ")
  88. }
  89. // 通过关联表查询二级场景名称
  90. // var secondSceneNames []string
  91. // var recognitionRecordSecondScenes []models.RecognitionRecordSecondScene
  92. // models.DB.Preload("SecondScene").Where("recognition_record_id = ?", record.ID).Find(&recognitionRecordSecondScenes)
  93. // for _, rrss := range recognitionRecordSecondScenes {
  94. // secondSceneNames = append(secondSceneNames, rrss.SecondScene.SecondSceneName)
  95. // }
  96. // 将原始OSS URL转换为代理URL,前端需要显示图片
  97. originalImageURL := record.OriginalImageUrl
  98. recognitionImageURL := record.RecognitionImageUrl
  99. if originalImageURL != "" {
  100. // 检查是否已经是代理URL格式
  101. if !strings.Contains(originalImageURL, "/apiv1/oss/parse/?url=") {
  102. originalImageURL = utils.GetProxyURL(originalImageURL)
  103. }
  104. }
  105. if recognitionImageURL != "" {
  106. // 检查是否已经是代理URL格式
  107. if !strings.Contains(recognitionImageURL, "/apiv1/oss/parse/?url=") {
  108. recognitionImageURL = utils.GetProxyURL(recognitionImageURL)
  109. }
  110. }
  111. // 构建详情数据
  112. detailData := map[string]interface{}{
  113. "id": record.ID,
  114. "original_image_url": originalImageURL,
  115. "recognition_image_url": recognitionImageURL,
  116. "user_id": record.UserID,
  117. "title": record.Title,
  118. "description": record.Description,
  119. "created_at": record.CreatedAt,
  120. "updated_at": record.UpdatedAt,
  121. // 添加与隐患识别接口一致的字段
  122. "labels": record.Labels, // 二级场景名称数组
  123. "third_scenes": thirdScenes, // 三级场景名称数组
  124. "tag_type": record.TagType,
  125. "scene_match": record.SceneMatch,
  126. "tip_accuracy": record.TipAccuracy,
  127. "effect_evaluation": record.EffectEvaluation,
  128. "user_remark": record.UserRemark,
  129. }
  130. c.Data["json"] = map[string]interface{}{
  131. "statusCode": 200,
  132. "msg": "success",
  133. "data": detailData,
  134. }
  135. c.ServeJSON()
  136. }
  137. // 用户提交点评
  138. func (c *SceneController) SubmitEvaluation() {
  139. var requestData models.RecognitionRecord
  140. if err := json.Unmarshal(c.Ctx.Input.RequestBody, &requestData); err != nil {
  141. c.Data["json"] = map[string]interface{}{
  142. "statusCode": 400,
  143. "msg": "JSON解析失败: " + err.Error(),
  144. }
  145. }
  146. scene_match := requestData.SceneMatch
  147. tip_accuracy := requestData.TipAccuracy
  148. effect_evaluation := requestData.EffectEvaluation
  149. tx := models.DB.Begin()
  150. if err := tx.Model(&models.RecognitionRecord{}).Where("id = ?", requestData.ID).Updates(map[string]interface{}{
  151. "scene_match": scene_match,
  152. "tip_accuracy": tip_accuracy,
  153. "effect_evaluation": effect_evaluation,
  154. "user_remark": requestData.UserRemark,
  155. }).Error; err != nil {
  156. tx.Rollback()
  157. c.Data["json"] = map[string]interface{}{
  158. "statusCode": 500,
  159. "msg": "点评失败: " + err.Error(),
  160. }
  161. }
  162. tx.Commit()
  163. c.Data["json"] = map[string]interface{}{
  164. "statusCode": 200,
  165. "msg": "success",
  166. }
  167. c.ServeJSON()
  168. }
  169. // 查询用户最新的一条识别记录是否点评
  170. func (c *SceneController) GetLatestRecognitionRecord() {
  171. // 从token中获取用户信息
  172. userInfo, err := utils.GetUserInfoFromContext(c.Ctx.Input.GetData("userInfo"))
  173. if err != nil {
  174. c.Data["json"] = map[string]interface{}{
  175. "statusCode": 401,
  176. "msg": "获取用户信息失败: " + err.Error(),
  177. }
  178. c.ServeJSON()
  179. return
  180. }
  181. user_id := int64(userInfo.ID)
  182. if user_id == 0 {
  183. user_id = 1
  184. }
  185. var recognitionRecord models.RecognitionRecord
  186. models.DB.Model(&models.RecognitionRecord{}).Where("user_id = ? AND is_deleted = ?", user_id, 0).Order("-created_at").First(&recognitionRecord)
  187. //如果数据为空,则无需判断上一条是否点评则构架一个假数据EffectEvaluation=1给前端
  188. if recognitionRecord.ID == 0 {
  189. recognitionRecord = models.RecognitionRecord{
  190. EffectEvaluation: 1,
  191. }
  192. }
  193. c.Data["json"] = map[string]interface{}{
  194. "statusCode": 200,
  195. "msg": "success",
  196. "data": recognitionRecord,
  197. }
  198. c.ServeJSON()
  199. }
  200. // 获取隐患识别三级场景标题查询正确和错误的示例图
  201. func (c *SceneController) GetThirdSceneExampleImage() {
  202. // 从token中获取用户信息用于生成水印
  203. userInfo, err := utils.GetUserInfoFromContext(c.Ctx.Input.GetData("userInfo"))
  204. if err != nil {
  205. c.Data["json"] = map[string]interface{}{
  206. "statusCode": 401,
  207. "msg": "获取用户信息失败: " + err.Error(),
  208. }
  209. c.ServeJSON()
  210. return
  211. }
  212. third_scene_name := c.GetString("third_scene_name")
  213. if third_scene_name == "" {
  214. c.Data["json"] = map[string]interface{}{
  215. "statusCode": 400,
  216. "msg": "三级场景名称不能为空",
  217. }
  218. c.ServeJSON()
  219. return
  220. }
  221. var thirdScene models.ThirdScene
  222. models.DB.Where("third_scene_name = ? and is_deleted = ?", third_scene_name, 0).First(&thirdScene)
  223. if thirdScene.ID == 0 {
  224. c.Data["json"] = map[string]interface{}{
  225. "statusCode": 404,
  226. "msg": "三级场景不存在",
  227. }
  228. c.ServeJSON()
  229. return
  230. }
  231. watermarkDate := time.Now().Format("2006/01/02")
  232. if thirdScene.CorrectExampleImage != "" {
  233. correctURL, err := generateWatermarkedExampleImage(thirdScene.CorrectExampleImage, userInfo.Name, userInfo.ContactNumber, watermarkDate, fmt.Sprintf("third_scene_correct_%d", thirdScene.ID))
  234. if err != nil {
  235. c.Data["json"] = map[string]interface{}{
  236. "statusCode": 500,
  237. "msg": "正确示例图加水印失败: " + err.Error(),
  238. }
  239. c.ServeJSON()
  240. return
  241. }
  242. thirdScene.CorrectExampleImage = correctURL
  243. }
  244. if thirdScene.WrongExampleImage != "" {
  245. wrongURL, err := generateWatermarkedExampleImage(thirdScene.WrongExampleImage, userInfo.Name, userInfo.ContactNumber, watermarkDate, fmt.Sprintf("third_scene_wrong_%d", thirdScene.ID))
  246. if err != nil {
  247. c.Data["json"] = map[string]interface{}{
  248. "statusCode": 500,
  249. "msg": "错误示例图加水印失败: " + err.Error(),
  250. }
  251. c.ServeJSON()
  252. return
  253. }
  254. thirdScene.WrongExampleImage = wrongURL
  255. }
  256. // 将示例图URL转换为代理URL,前端需要显示图片
  257. if thirdScene.CorrectExampleImage != "" {
  258. // 检查是否已经是代理URL格式
  259. if !strings.Contains(thirdScene.CorrectExampleImage, "/apiv1/oss/parse/?url=") {
  260. thirdScene.CorrectExampleImage = utils.GetProxyURL(thirdScene.CorrectExampleImage)
  261. }
  262. }
  263. if thirdScene.WrongExampleImage != "" {
  264. // 检查是否已经是代理URL格式
  265. if !strings.Contains(thirdScene.WrongExampleImage, "/apiv1/oss/parse/?url=") {
  266. thirdScene.WrongExampleImage = utils.GetProxyURL(thirdScene.WrongExampleImage)
  267. }
  268. }
  269. c.Data["json"] = map[string]interface{}{
  270. "statusCode": 200,
  271. "msg": "success",
  272. "data": thirdScene,
  273. }
  274. c.ServeJSON()
  275. }
  276. // generateWatermarkedExampleImage 为示例图添加水印并返回新的OSS代理URL
  277. func generateWatermarkedExampleImage(originalURL, username, account, date, keyPrefix string) (string, error) {
  278. if originalURL == "" {
  279. return "", fmt.Errorf("示例图地址为空")
  280. }
  281. imageData, err := downloadImageFromOSS(originalURL)
  282. if err != nil {
  283. return "", fmt.Errorf("下载示例图失败: %w", err)
  284. }
  285. img, _, err := image.Decode(bytes.NewReader(imageData))
  286. if err != nil {
  287. return "", fmt.Errorf("解析示例图失败: %w", err)
  288. }
  289. bounds := img.Bounds()
  290. drawableImg := image.NewRGBA(bounds)
  291. draw.Draw(drawableImg, bounds, img, image.Point{}, draw.Src)
  292. drawableImg = addLogoToImage(drawableImg)
  293. drawableImg = addTextWatermark(drawableImg, username, account, date)
  294. var buf bytes.Buffer
  295. if err := jpeg.Encode(&buf, drawableImg, &jpeg.Options{Quality: 95}); err != nil {
  296. return "", fmt.Errorf("编码水印示例图失败: %w", err)
  297. }
  298. now := time.Now().UTC()
  299. fileName := fmt.Sprintf("third_scene_examples/%d/%s_%s_%d.jpg",
  300. now.Year(),
  301. now.Format("0102"),
  302. keyPrefix,
  303. now.UnixNano())
  304. url, err := uploadImageToOSS(buf.Bytes(), fileName)
  305. if err != nil {
  306. return "", fmt.Errorf("上传水印示例图失败: %w", err)
  307. }
  308. return url, nil
  309. }