total.go 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380
  1. package controllers
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "io"
  6. "net/http"
  7. "path/filepath"
  8. "shudao-chat-go/models"
  9. "shudao-chat-go/utils"
  10. "strings"
  11. "time"
  12. "github.com/beego/beego/v2/server/web"
  13. )
  14. type TotalController struct {
  15. web.Controller
  16. }
  17. // 随机返回5条推荐问题
  18. func (c *TotalController) GetRecommendQuestion() {
  19. //获取limit数量
  20. limit, _ := c.GetInt("limit")
  21. if limit == 0 {
  22. limit = 5
  23. }
  24. var result []map[string]interface{}
  25. // 直接查询需要的字段,避免循环
  26. models.DB.Model(&models.RecommendQuestion{}).
  27. Select("question").
  28. Order("rand()").
  29. Limit(limit).Where("is_deleted = ?", 0).
  30. Find(&result)
  31. c.Data["json"] = map[string]interface{}{
  32. "statusCode": 200,
  33. "msg": "success",
  34. "data": result,
  35. }
  36. c.ServeJSON()
  37. }
  38. // 提交意见反馈
  39. func (c *TotalController) SubmitFeedback() {
  40. var feedback models.FeedbackQuestion
  41. // 尝试解析JSON数据
  42. if err := json.Unmarshal(c.Ctx.Input.RequestBody, &feedback); err != nil {
  43. c.Data["json"] = map[string]interface{}{
  44. "statusCode": 400,
  45. "msg": "JSON解析失败: " + err.Error(),
  46. }
  47. c.ServeJSON()
  48. return
  49. }
  50. // 打印解析后的数据
  51. fmt.Println("解析后的数据:", feedback)
  52. tx := models.DB.Begin()
  53. if err := tx.Create(&feedback).Error; err != nil {
  54. tx.Rollback()
  55. c.Data["json"] = map[string]interface{}{
  56. "statusCode": 500,
  57. "msg": "fail",
  58. }
  59. c.ServeJSON()
  60. return
  61. }
  62. tx.Commit()
  63. c.Data["json"] = map[string]interface{}{
  64. "statusCode": 200,
  65. "msg": "success",
  66. }
  67. c.ServeJSON()
  68. }
  69. // 返回政策文件
  70. func (c *TotalController) GetPolicyFile() {
  71. policy_type, _ := c.GetInt("policy_type")
  72. search := c.GetString("search")
  73. page, _ := c.GetInt("page")
  74. pageSize, _ := c.GetInt("pageSize")
  75. var policyFile []models.PolicyFile
  76. offset := (page - 1) * pageSize
  77. if policy_type == 0 {
  78. models.DB.Model(&models.PolicyFile{}).Where("is_deleted = ? AND policy_name LIKE ?", 0, "%"+search+"%").Offset(offset).Limit(pageSize).Order("-updated_at").Find(&policyFile)
  79. } else {
  80. models.DB.Model(&models.PolicyFile{}).Where("is_deleted = ? AND policy_type = ? AND policy_name LIKE ?", 0, policy_type, "%"+search+"%").Offset(offset).Limit(pageSize).Order("-updated_at").Find(&policyFile)
  81. }
  82. // 将原始OSS URL转换为代理URL
  83. for i := range policyFile {
  84. if policyFile[i].PolicyFileUrl != "" {
  85. // 检查是否已经是代理URL格式
  86. if !strings.Contains(policyFile[i].PolicyFileUrl, "/apiv1/oss/parse/?url=") {
  87. policyFile[i].PolicyFileUrl = utils.GetProxyURL(policyFile[i].PolicyFileUrl)
  88. }
  89. }
  90. }
  91. c.Data["json"] = map[string]interface{}{
  92. "statusCode": 200,
  93. "msg": "success",
  94. "data": policyFile,
  95. }
  96. c.ServeJSON()
  97. }
  98. // 随机返回四条功能卡片
  99. func (c *TotalController) GetFunctionCard() {
  100. //问题类型,0为AI问答,1为安全培训
  101. functionType, _ := c.GetInt("function_type")
  102. var functionCard []models.FunctionCard
  103. models.DB.Model(&models.FunctionCard{}).Order("rand()").Limit(4).Where("function_type = ? AND is_deleted = ?", functionType, 0).Find(&functionCard)
  104. c.Data["json"] = map[string]interface{}{
  105. "statusCode": 200,
  106. "msg": "success",
  107. "data": functionCard,
  108. }
  109. c.ServeJSON()
  110. }
  111. // 随机返回三条热点问题
  112. func (c *TotalController) GetHotQuestion() {
  113. //问题类型,0为AI问答,1为安全培训
  114. questionType, _ := c.GetInt("question_type")
  115. var hotQuestion []models.HotQuestion
  116. models.DB.Model(&models.HotQuestion{}).Order("rand()").Limit(4).Where("question_type = ? AND is_deleted = ?", questionType, 0).Find(&hotQuestion)
  117. c.Data["json"] = map[string]interface{}{
  118. "statusCode": 200,
  119. "msg": "success",
  120. "data": hotQuestion,
  121. }
  122. c.ServeJSON()
  123. }
  124. type LikeAndDislikeRequest struct {
  125. ID uint `json:"id"`
  126. UserFeedback int `json:"user_feedback"`
  127. }
  128. // 点赞和踩
  129. func (c *TotalController) LikeAndDislike() {
  130. var likeAndDislike LikeAndDislikeRequest
  131. if err := json.Unmarshal(c.Ctx.Input.RequestBody, &likeAndDislike); err != nil {
  132. c.Data["json"] = map[string]interface{}{
  133. "statusCode": 400,
  134. "msg": "JSON解析失败: " + err.Error(),
  135. }
  136. c.ServeJSON()
  137. return
  138. }
  139. id := likeAndDislike.ID
  140. userFeedback := likeAndDislike.UserFeedback
  141. models.DB.Model(&models.AIMessage{}).Where("id = ?", id).Update("user_feedback", userFeedback)
  142. c.Data["json"] = map[string]interface{}{
  143. "statusCode": 200,
  144. "msg": "success",
  145. }
  146. c.ServeJSON()
  147. }
  148. // 下载文件接口,支持从OSS链接下载文件并返回给前端
  149. func (c *TotalController) GetPdfOssDownloadLink() {
  150. pdfOssDownloadLink := c.GetString("pdf_oss_download_link")
  151. customFileName := c.GetString("file_name") // 支持自定义文件名
  152. // 验证URL是否为空
  153. if pdfOssDownloadLink == "" {
  154. c.Data["json"] = map[string]interface{}{
  155. "statusCode": 400,
  156. "msg": "下载链接不能为空",
  157. }
  158. c.ServeJSON()
  159. return
  160. }
  161. // 创建HTTP客户端,设置超时时间
  162. client := &http.Client{
  163. Timeout: 30 * time.Second,
  164. }
  165. // 发送GET请求下载文件
  166. resp, err := client.Get(pdfOssDownloadLink)
  167. if err != nil {
  168. c.Data["json"] = map[string]interface{}{
  169. "statusCode": 500,
  170. "msg": "下载文件失败: " + err.Error(),
  171. }
  172. c.ServeJSON()
  173. return
  174. }
  175. defer resp.Body.Close()
  176. // 检查HTTP状态码
  177. if resp.StatusCode != http.StatusOK {
  178. c.Data["json"] = map[string]interface{}{
  179. "statusCode": 500,
  180. "msg": "文件下载失败,状态码: " + fmt.Sprintf("%d", resp.StatusCode),
  181. }
  182. c.ServeJSON()
  183. return
  184. }
  185. // 从URL中提取文件名
  186. fileName := filepath.Base(pdfOssDownloadLink)
  187. if fileName == "." || fileName == "/" {
  188. fileName = "download_file_" + fmt.Sprintf("%d", time.Now().Unix())
  189. }
  190. // 如果提供了自定义文件名,使用自定义文件名
  191. if customFileName != "" {
  192. fileName = customFileName
  193. }
  194. // 从Content-Disposition头中获取文件名(如果存在)
  195. if contentDisposition := resp.Header.Get("Content-Disposition"); contentDisposition != "" {
  196. if strings.Contains(contentDisposition, "filename=") {
  197. parts := strings.Split(contentDisposition, "filename=")
  198. if len(parts) > 1 {
  199. fileName = strings.Trim(parts[1], "\"")
  200. }
  201. }
  202. }
  203. // 获取文件大小
  204. contentLength := resp.Header.Get("Content-Length")
  205. // 设置文件下载响应头
  206. c.Ctx.Output.Header("Content-Type", "application/octet-stream")
  207. c.Ctx.Output.Header("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", fileName))
  208. if contentLength != "" {
  209. c.Ctx.Output.Header("Content-Length", contentLength)
  210. }
  211. c.Ctx.Output.Header("Cache-Control", "no-cache")
  212. // 将文件内容写入响应(流式传输)
  213. _, err = io.Copy(c.Ctx.ResponseWriter, resp.Body)
  214. if err != nil {
  215. c.Data["json"] = map[string]interface{}{
  216. "statusCode": 500,
  217. "msg": "文件传输失败: " + err.Error(),
  218. }
  219. c.ServeJSON()
  220. return
  221. }
  222. // 注意:文件下载成功后,响应已经通过io.Copy发送给客户端
  223. // 此时不能再调用c.ServeJSON(),因为响应已经完成
  224. }
  225. // 政策文件查看和下载查看次数+1
  226. func (c *TotalController) GetPolicyFileViewAndDownloadCount() {
  227. // 定义请求结构体
  228. type PolicyFileCountRequest struct {
  229. PolicyFileID int `json:"policy_file_id"`
  230. ActionType int `json:"action_type"`
  231. }
  232. var request PolicyFileCountRequest
  233. // 解析JSON请求体
  234. if err := json.Unmarshal(c.Ctx.Input.RequestBody, &request); err != nil {
  235. c.Data["json"] = map[string]interface{}{
  236. "statusCode": 400,
  237. "msg": "JSON解析失败: " + err.Error(),
  238. }
  239. c.ServeJSON()
  240. return
  241. }
  242. policyFileID := request.PolicyFileID
  243. actionType := request.ActionType
  244. fmt.Println("policyFileID", policyFileID)
  245. if policyFileID <= 0 {
  246. c.Data["json"] = map[string]interface{}{
  247. "statusCode": 400,
  248. "msg": "政策文件ID不能为空或无效",
  249. }
  250. c.ServeJSON()
  251. return
  252. }
  253. fmt.Println("actionType", actionType)
  254. if actionType != 1 && actionType != 2 {
  255. c.Data["json"] = map[string]interface{}{
  256. "statusCode": 400,
  257. "msg": "操作类型无效,1-查看,2-下载",
  258. }
  259. c.ServeJSON()
  260. return
  261. }
  262. // 检查政策文件是否存在
  263. var policyFile models.PolicyFile
  264. if err := models.DB.Where("id = ? AND is_deleted = ?", policyFileID, 0).First(&policyFile).Error; err != nil {
  265. c.Data["json"] = map[string]interface{}{
  266. "statusCode": 404,
  267. "msg": "政策文件不存在",
  268. }
  269. c.ServeJSON()
  270. return
  271. }
  272. // 更新查看次数
  273. if err := models.DB.Model(&models.PolicyFile{}).Where("id = ?", policyFileID).Update("view_count", policyFile.ViewCount+1).Error; err != nil {
  274. c.Data["json"] = map[string]interface{}{
  275. "statusCode": 500,
  276. "msg": "更新查看次数失败: " + err.Error(),
  277. }
  278. c.ServeJSON()
  279. return
  280. }
  281. // 返回成功响应
  282. var actionText string
  283. if actionType == 1 {
  284. actionText = "查看"
  285. } else {
  286. actionText = "下载"
  287. }
  288. c.Data["json"] = map[string]interface{}{
  289. "statusCode": 200,
  290. "msg": fmt.Sprintf("政策文件%s次数更新成功", actionText),
  291. "data": map[string]interface{}{
  292. "policy_file_id": policyFileID,
  293. "action_type": actionType,
  294. "action_text": actionText,
  295. "view_count": policyFile.ViewCount + 1,
  296. },
  297. }
  298. c.ServeJSON()
  299. }
  300. // GetUserDataID 从token中获取用户信息并返回用户数据
  301. func (c *TotalController) GetUserDataID() {
  302. // 从token中获取用户信息
  303. userInfo, err := utils.GetUserInfoFromContext(c.Ctx.Input.GetData("userInfo"))
  304. if err != nil {
  305. c.Data["json"] = map[string]interface{}{
  306. "statusCode": 401,
  307. "msg": "获取用户信息失败: " + err.Error(),
  308. }
  309. c.ServeJSON()
  310. return
  311. }
  312. accountID := userInfo.AccountID
  313. if accountID == "" {
  314. c.Data["json"] = map[string]interface{}{
  315. "statusCode": 400,
  316. "msg": "account_id不能为空",
  317. }
  318. c.ServeJSON()
  319. return
  320. }
  321. // 查询用户数据
  322. var userData models.UserData
  323. if err := models.DB.Where("accountID = ?", accountID).First(&userData).Error; err != nil {
  324. c.Data["json"] = map[string]interface{}{
  325. "statusCode": 404,
  326. "msg": "未找到对应的用户数据",
  327. }
  328. c.ServeJSON()
  329. return
  330. }
  331. // 返回主键id
  332. c.Data["json"] = map[string]interface{}{
  333. "statusCode": 200,
  334. "msg": "success",
  335. "data": map[string]interface{}{
  336. "id": userData.ID,
  337. },
  338. }
  339. c.ServeJSON()
  340. }