评价.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512
  1. package controllers
  2. import (
  3. // 根据实际项目结构调整导入路径
  4. "Tech/models"
  5. "encoding/json"
  6. "github.com/beego/beego/v2/client/orm"
  7. beego "github.com/beego/beego/v2/server/web"
  8. // 新增导入
  9. )
  10. type EvaController struct {
  11. beego.Controller
  12. }
  13. // /eva/list 获取课程评价列表
  14. func (c *EvaController) List() {
  15. type Request struct {
  16. CourseID int `json:"courseID"`
  17. }
  18. var req Request
  19. requestBody := c.Ctx.Input.RequestBody
  20. println("Request Body:", string(requestBody))
  21. if err := json.Unmarshal(requestBody, &req); err != nil {
  22. c.Ctx.Output.SetStatus(400)
  23. c.Data["json"] = map[string]interface{}{
  24. "code": 400,
  25. "msg": "请求参数格式错误: " + err.Error(),
  26. }
  27. c.ServeJSON()
  28. return
  29. }
  30. if req.CourseID == 0 {
  31. c.Ctx.Output.SetStatus(400)
  32. c.Data["json"] = map[string]interface{}{
  33. "code": 400,
  34. "msg": "缺少课程ID参数",
  35. }
  36. c.ServeJSON()
  37. return
  38. }
  39. o := orm.NewOrm()
  40. var evaList []*models.CourseEvaList
  41. // 根据课程ID查询评价列表
  42. count, err := o.QueryTable(new(models.CourseEvaList)).
  43. Filter("CourseID", req.CourseID).
  44. All(&evaList)
  45. if err != nil {
  46. c.Data["json"] = map[string]interface{}{
  47. "code": 500,
  48. "msg": "查询评价列表失败: " + err.Error(),
  49. }
  50. c.ServeJSON()
  51. return
  52. }
  53. // 获取所有角色信息用于关联角色名称
  54. var roleInfos []*models.RoleInfo
  55. _, err = o.QueryTable(new(models.RoleInfo)).All(&roleInfos)
  56. if err != nil {
  57. c.Data["json"] = map[string]interface{}{
  58. "code": 500,
  59. "msg": "查询角色信息失败: " + err.Error(),
  60. }
  61. c.ServeJSON()
  62. return
  63. }
  64. // 创建角色ID到角色名称的映射
  65. roleMap := make(map[int]string)
  66. for _, role := range roleInfos {
  67. roleMap[role.RoleID] = role.RoleName
  68. }
  69. // 为每个评价项添加角色名称
  70. type EvaWithRoleName struct {
  71. *models.CourseEvaList
  72. RoleName string `json:"roleName"`
  73. }
  74. evaWithRoles := make([]EvaWithRoleName, len(evaList))
  75. for i, eva := range evaList {
  76. evaWithRoles[i] = EvaWithRoleName{
  77. CourseEvaList: eva,
  78. RoleName: roleMap[eva.EvaTargetRole],
  79. }
  80. }
  81. c.Data["json"] = map[string]interface{}{
  82. "code": 200,
  83. "count": count,
  84. "msg": "成功",
  85. "data": evaWithRoles,
  86. }
  87. c.ServeJSON()
  88. }
  89. // /eva/add 添加课程评价
  90. func (c *EvaController) Add() {
  91. var eva models.CourseEvaList
  92. requestBody := c.Ctx.Input.RequestBody
  93. println("Request Body:", string(requestBody))
  94. if err := json.Unmarshal(requestBody, &eva); err != nil {
  95. c.Ctx.Output.SetStatus(400)
  96. c.Data["json"] = map[string]interface{}{
  97. "code": 400,
  98. "msg": "请求参数格式错误: " + err.Error(),
  99. }
  100. c.ServeJSON()
  101. return
  102. }
  103. if eva.CourseID == 0 {
  104. c.Ctx.Output.SetStatus(400)
  105. c.Data["json"] = map[string]interface{}{
  106. "code": 400,
  107. "msg": "缺少课程ID参数",
  108. }
  109. c.ServeJSON()
  110. return
  111. }
  112. o := orm.NewOrm()
  113. // 如果SeqNo为0,则查询该课程下最大的SeqNo并加1
  114. if eva.SeqNo == 0 {
  115. var maxSeqNo int
  116. err := o.Raw("SELECT COALESCE(MAX(序号), 0) FROM CourseEvaList WHERE 课程ID = ?", eva.CourseID).QueryRow(&maxSeqNo)
  117. if err != nil {
  118. c.Data["json"] = map[string]interface{}{
  119. "code": 500,
  120. "msg": "查询序号失败: " + err.Error(),
  121. }
  122. c.ServeJSON()
  123. return
  124. }
  125. eva.SeqNo = maxSeqNo + 1
  126. } else {
  127. // 如果指定了SeqNo,检查该SeqNo是否已存在
  128. var count int64
  129. count, err := o.QueryTable(new(models.CourseEvaList)).
  130. Filter("CourseID", eva.CourseID).
  131. Filter("SeqNo", eva.SeqNo).
  132. Count()
  133. if err != nil {
  134. c.Data["json"] = map[string]interface{}{
  135. "code": 500,
  136. "msg": "查询序号失败: " + err.Error(),
  137. }
  138. c.ServeJSON()
  139. return
  140. }
  141. // 如果SeqNo已存在,则将该SeqNo及之后的所有序号都加1
  142. if count > 0 {
  143. // 使用倒序更新,避免主键冲突
  144. _, err := o.Raw("UPDATE CourseEvaList SET 序号 = 序号 + 1 WHERE 课程ID = ? AND 序号 >= ? ORDER BY 序号 DESC",
  145. eva.CourseID, eva.SeqNo).Exec()
  146. if err != nil {
  147. c.Data["json"] = map[string]interface{}{
  148. "code": 500,
  149. "msg": "调整序号失败: " + err.Error(),
  150. }
  151. c.ServeJSON()
  152. return
  153. }
  154. }
  155. }
  156. // 设置评价来源为教员自定义
  157. eva.EvaSource = 1
  158. _, err := o.Insert(&eva)
  159. if err != nil {
  160. c.Data["json"] = map[string]interface{}{
  161. "code": 500,
  162. "msg": "添加评价失败: " + err.Error(),
  163. }
  164. c.ServeJSON()
  165. return
  166. }
  167. c.Data["json"] = map[string]interface{}{
  168. "code": 200,
  169. "msg": "添加评价成功",
  170. "seqNo": eva.SeqNo,
  171. }
  172. c.ServeJSON()
  173. }
  174. // /eva/delete 删除课程评价
  175. func (c *EvaController) Delete() {
  176. type Request struct {
  177. CourseID int `json:"courseID"`
  178. SeqNo int `json:"seqNo"`
  179. }
  180. var req Request
  181. requestBody := c.Ctx.Input.RequestBody
  182. println("Request Body:", string(requestBody))
  183. if err := json.Unmarshal(requestBody, &req); err != nil {
  184. c.Ctx.Output.SetStatus(400)
  185. c.Data["json"] = map[string]interface{}{
  186. "code": 400,
  187. "msg": "请求参数格式错误: " + err.Error(),
  188. }
  189. c.ServeJSON()
  190. return
  191. }
  192. if req.CourseID == 0 || req.SeqNo == 0 {
  193. c.Ctx.Output.SetStatus(400)
  194. c.Data["json"] = map[string]interface{}{
  195. "code": 400,
  196. "msg": "缺少必要参数",
  197. }
  198. c.ServeJSON()
  199. return
  200. }
  201. o := orm.NewOrm()
  202. // 先查询评价记录,判断是否来自流程图
  203. var eva models.CourseEvaList
  204. err := o.Raw("SELECT * FROM CourseEvaList WHERE 课程ID = ? AND 序号 = ?", req.CourseID, req.SeqNo).QueryRow(&eva)
  205. if err != nil {
  206. c.Data["json"] = map[string]interface{}{
  207. "code": 500,
  208. "msg": "查询评价记录失败: " + err.Error(),
  209. }
  210. c.ServeJSON()
  211. return
  212. }
  213. // 如果评价来自流程图(EvaSource=0),则不允许删除
  214. if eva.EvaSource == 0 {
  215. c.Data["json"] = map[string]interface{}{
  216. "code": 403,
  217. "msg": "来自流程图的评价不能删除",
  218. }
  219. c.ServeJSON()
  220. return
  221. }
  222. // 执行删除操作(仅对教员自定义的评价)
  223. result, err := o.Raw("DELETE FROM CourseEvaList WHERE 课程ID = ? AND 序号 = ?", req.CourseID, req.SeqNo).Exec()
  224. if err != nil {
  225. c.Data["json"] = map[string]interface{}{
  226. "code": 500,
  227. "msg": "删除评价失败: " + err.Error(),
  228. }
  229. c.ServeJSON()
  230. return
  231. }
  232. n, _ := result.RowsAffected()
  233. if n == 0 {
  234. c.Data["json"] = map[string]interface{}{
  235. "code": 404,
  236. "msg": "未找到对应的评价记录",
  237. }
  238. c.ServeJSON()
  239. return
  240. }
  241. c.Data["json"] = map[string]interface{}{
  242. "code": 200,
  243. "msg": "删除评价成功",
  244. }
  245. c.ServeJSON()
  246. }
  247. // /eva/update 更新课程评价
  248. func (c *EvaController) Update() {
  249. var eva models.CourseEvaList
  250. requestBody := c.Ctx.Input.RequestBody
  251. println("Request Body:", string(requestBody))
  252. if err := json.Unmarshal(requestBody, &eva); err != nil {
  253. c.Ctx.Output.SetStatus(400)
  254. c.Data["json"] = map[string]interface{}{
  255. "code": 400,
  256. "msg": "请求参数格式错误: " + err.Error(),
  257. }
  258. c.ServeJSON()
  259. return
  260. }
  261. if eva.CourseID == 0 || eva.SeqNo == 0 {
  262. c.Ctx.Output.SetStatus(400)
  263. c.Data["json"] = map[string]interface{}{
  264. "code": 400,
  265. "msg": "缺少必要参数",
  266. }
  267. c.ServeJSON()
  268. return
  269. }
  270. o := orm.NewOrm()
  271. // 先尝试读取记录,判断是否存在
  272. existingEva := models.CourseEvaList{CourseID: eva.CourseID, SeqNo: eva.SeqNo}
  273. err := o.Read(&existingEva, "CourseID", "SeqNo")
  274. if err != nil {
  275. if err == orm.ErrNoRows {
  276. c.Data["json"] = map[string]interface{}{
  277. "code": 404,
  278. "msg": "未找到对应的评价记录",
  279. }
  280. c.ServeJSON()
  281. return
  282. } else {
  283. c.Data["json"] = map[string]interface{}{
  284. "code": 500,
  285. "msg": "查询评价记录失败: " + err.Error(),
  286. }
  287. c.ServeJSON()
  288. return
  289. }
  290. }
  291. // 如果请求中没有提供相应字段,则使用现有记录中的值
  292. if eva.EvaTargetRole == 0 {
  293. eva.EvaTargetRole = existingEva.EvaTargetRole
  294. }
  295. if eva.EvaName == "" {
  296. eva.EvaName = existingEva.EvaName
  297. }
  298. if eva.EvaMapID == 0 {
  299. eva.EvaMapID = existingEva.EvaMapID
  300. }
  301. // 评价来源始终使用现有记录中的值(保留原始来源)
  302. eva.EvaSource = existingEva.EvaSource
  303. // 使用原生SQL更新记录
  304. _, err = o.Raw("UPDATE CourseEvaList SET 评价目标角色=?, 评价名称=?, 评价映射ID=?, 评价类型=?, 评价赋分=?, 评价失分=?, 评价来源=?, 失格项=? WHERE 课程ID=? AND 序号=?",
  305. eva.EvaTargetRole, eva.EvaName, eva.EvaMapID, eva.EvaType, eva.EvaScore, eva.EvaDeduction, eva.EvaSource, eva.DisqualificationItem,
  306. eva.CourseID, eva.SeqNo).Exec()
  307. if err != nil {
  308. c.Data["json"] = map[string]interface{}{
  309. "code": 500,
  310. "msg": "更新评价失败: " + err.Error(),
  311. }
  312. c.ServeJSON()
  313. return
  314. }
  315. c.Data["json"] = map[string]interface{}{
  316. "code": 200,
  317. "msg": "更新评价成功",
  318. "data": eva,
  319. }
  320. c.ServeJSON()
  321. }
  322. // /eva/orderupdate 评价排序更新
  323. func (c *EvaController) Orderupdate() {
  324. type Request struct {
  325. CourseID int `json:"courseID"`
  326. SeqNo int `json:"seqNo"`
  327. SetOrder int `json:"setorder"`
  328. }
  329. var req Request
  330. requestBody := c.Ctx.Input.RequestBody
  331. println("Request Body:", string(requestBody))
  332. if err := json.Unmarshal(requestBody, &req); err != nil {
  333. c.Ctx.Output.SetStatus(400)
  334. c.Data["json"] = map[string]interface{}{
  335. "code": 400,
  336. "msg": "请求参数格式错误: " + err.Error(),
  337. }
  338. c.ServeJSON()
  339. return
  340. }
  341. if req.CourseID == 0 || req.SeqNo == 0 || req.SetOrder == 0 {
  342. c.Ctx.Output.SetStatus(400)
  343. c.Data["json"] = map[string]interface{}{
  344. "code": 400,
  345. "msg": "缺少必要参数",
  346. }
  347. c.ServeJSON()
  348. return
  349. }
  350. o := orm.NewOrm()
  351. // 先尝试读取记录,判断是否存在
  352. existingEva := models.CourseEvaList{CourseID: req.CourseID, SeqNo: req.SeqNo}
  353. err := o.Read(&existingEva, "CourseID", "SeqNo")
  354. if err != nil {
  355. if err == orm.ErrNoRows {
  356. c.Data["json"] = map[string]interface{}{
  357. "code": 404,
  358. "msg": "未找到对应的评价记录",
  359. }
  360. } else {
  361. c.Data["json"] = map[string]interface{}{
  362. "code": 500,
  363. "msg": "查询评价记录失败: " + err.Error(),
  364. }
  365. }
  366. c.ServeJSON()
  367. return
  368. }
  369. // 获取该课程的所有评价记录,按序号排序
  370. var evaList []models.CourseEvaList
  371. _, err = o.QueryTable(new(models.CourseEvaList)).
  372. Filter("CourseID", req.CourseID).
  373. OrderBy("SeqNo").
  374. All(&evaList)
  375. if err != nil {
  376. c.Data["json"] = map[string]interface{}{
  377. "code": 500,
  378. "msg": "查询评价列表失败: " + err.Error(),
  379. }
  380. c.ServeJSON()
  381. return
  382. }
  383. // 检查边界条件
  384. if req.SetOrder == 1 && req.SeqNo <= 1 {
  385. // 上移但已经在最顶部
  386. c.Data["json"] = map[string]interface{}{
  387. "code": 400,
  388. "msg": "无法执行上移操作,已到达顶部",
  389. }
  390. c.ServeJSON()
  391. return
  392. }
  393. if req.SetOrder == 2 && req.SeqNo >= len(evaList) {
  394. // 下移但已经在最底部
  395. c.Data["json"] = map[string]interface{}{
  396. "code": 400,
  397. "msg": "无法执行下移操作,已到达底部",
  398. }
  399. c.ServeJSON()
  400. return
  401. }
  402. // 确定要交换的两个序号
  403. var targetSeqNo int
  404. if req.SetOrder == 1 {
  405. // 上移:与前一个序号交换
  406. targetSeqNo = req.SeqNo - 1
  407. } else {
  408. // 下移:与后一个序号交换
  409. targetSeqNo = req.SeqNo + 1
  410. }
  411. // 使用三步更新避免主键冲突
  412. // 第一步:将目标序号临时设为0
  413. _, err = o.Raw("UPDATE CourseEvaList SET 序号 = 0 WHERE 课程ID = ? AND 序号 = ?",
  414. req.CourseID, targetSeqNo).Exec()
  415. if err != nil {
  416. c.Data["json"] = map[string]interface{}{
  417. "code": 500,
  418. "msg": "更新序号失败: " + err.Error(),
  419. }
  420. c.ServeJSON()
  421. return
  422. }
  423. // 第二步:将当前序号更新为目标序号
  424. _, err = o.Raw("UPDATE CourseEvaList SET 序号 = ? WHERE 课程ID = ? AND 序号 = ?",
  425. targetSeqNo, req.CourseID, req.SeqNo).Exec()
  426. if err != nil {
  427. c.Data["json"] = map[string]interface{}{
  428. "code": 500,
  429. "msg": "更新序号失败: " + err.Error(),
  430. }
  431. c.ServeJSON()
  432. return
  433. }
  434. // 第三步:将临时序号0更新为当前序号
  435. _, err = o.Raw("UPDATE CourseEvaList SET 序号 = ? WHERE 课程ID = ? AND 序号 = 0",
  436. req.SeqNo, req.CourseID).Exec()
  437. if err != nil {
  438. c.Data["json"] = map[string]interface{}{
  439. "code": 500,
  440. "msg": "更新序号失败: " + err.Error(),
  441. }
  442. c.ServeJSON()
  443. return
  444. }
  445. c.Data["json"] = map[string]interface{}{
  446. "code": 200,
  447. "msg": "顺序调整成功",
  448. }
  449. c.ServeJSON()
  450. }