新增: AI工单处理工作台 v1.0
- Go Gin 后端 (19个源文件): 认证、工单CRUD、GLM AI分析、状态流转、备注、操作日志 - Arco Design Vue 前端: 登录、工单列表/详情/创建、AI分析触发与确认 - MySQL 5表: ticket_user/ticket_info/ticket_ai_analysis/ticket_operation_log/ticket_note - 部署: tk.1216.top HTTPS, Nginx反代
This commit is contained in:
95
backend/internal/handler/analysis_handler.go
Normal file
95
backend/internal/handler/analysis_handler.go
Normal file
@@ -0,0 +1,95 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"github.com/casehub/ticket-workbench/internal/config"
|
||||
"github.com/casehub/ticket-workbench/internal/dto"
|
||||
"github.com/casehub/ticket-workbench/internal/middleware"
|
||||
"github.com/casehub/ticket-workbench/internal/model"
|
||||
"github.com/casehub/ticket-workbench/internal/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func AnalyzeTicket(db *gorm.DB, cfg *config.Config) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
idStr := c.Param("id")
|
||||
id, err := strconv.Atoi(idStr)
|
||||
if err != nil {
|
||||
c.JSON(200, dto.Fail("参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
var ticket model.TicketInfo
|
||||
if err := db.Where("ticketid = ?", id).First(&ticket).Error; err != nil {
|
||||
c.JSON(200, dto.Fail("工单不存在"))
|
||||
return
|
||||
}
|
||||
|
||||
analysis, err := service.AnalyzeTicket(db, id, cfg.GLM.APIKey, cfg.GLM.BaseURL, cfg.GLM.Model,
|
||||
ticket.Title, ticket.Content, ticket.Contactname, ticket.Contactphone)
|
||||
if err != nil {
|
||||
c.JSON(200, dto.Fail("AI分析失败: "+err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(200, dto.Success(analysis))
|
||||
}
|
||||
}
|
||||
|
||||
func GetAnalysis(db *gorm.DB) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
idStr := c.Param("id")
|
||||
id, err := strconv.Atoi(idStr)
|
||||
if err != nil {
|
||||
c.JSON(200, dto.Fail("参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
analyses, err := service.GetAnalysisByTicketID(db, id)
|
||||
if err != nil {
|
||||
c.JSON(200, dto.Fail("查询失败"))
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(200, dto.Success(analyses))
|
||||
}
|
||||
}
|
||||
|
||||
func ConfirmAnalysis(db *gorm.DB) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
idStr := c.Param("id")
|
||||
ticketid, err := strconv.Atoi(idStr)
|
||||
if err != nil {
|
||||
c.JSON(200, dto.Fail("参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
var req dto.ConfirmAnalysisRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(200, dto.Fail("参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
user := middleware.GetCurrentUser(c)
|
||||
if user == nil {
|
||||
c.JSON(200, dto.Fail("未登录"))
|
||||
return
|
||||
}
|
||||
|
||||
var analysis model.TicketAiAnalysis
|
||||
if err := db.Where("ticketid = ? AND confirmed = 0", ticketid).Order("createtime DESC").First(&analysis).Error; err != nil {
|
||||
c.JSON(200, dto.Fail("未找到待确认的分析结果"))
|
||||
return
|
||||
}
|
||||
|
||||
err = service.ConfirmAnalysis(db, analysis.Analysisid, req.Category, req.Priority, req.Summary, user.Userid)
|
||||
if err != nil {
|
||||
c.JSON(200, dto.Fail("确认失败"))
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(200, dto.Success(nil))
|
||||
}
|
||||
}
|
||||
64
backend/internal/handler/auth_handler.go
Normal file
64
backend/internal/handler/auth_handler.go
Normal file
@@ -0,0 +1,64 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"github.com/casehub/ticket-workbench/internal/dto"
|
||||
"github.com/casehub/ticket-workbench/internal/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func Login(db *gorm.DB) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
var req dto.LoginRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(200, dto.Fail("参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
user, sessionID, err := service.Login(db, req.Account, req.Password)
|
||||
if err != nil {
|
||||
c.JSON(200, dto.Fail(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(200, dto.Success(map[string]interface{}{
|
||||
"token": sessionID,
|
||||
"user": map[string]interface{}{
|
||||
"userid": user.Userid,
|
||||
"username": user.Username,
|
||||
"account": user.Account,
|
||||
"role": user.Role,
|
||||
"team": user.Team,
|
||||
},
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
func Logout() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
sessionID := c.GetHeader("Authorization")
|
||||
if sessionID == "" {
|
||||
sessionID = c.GetHeader("jsessionid")
|
||||
}
|
||||
service.Logout(sessionID)
|
||||
c.JSON(200, dto.Success(nil))
|
||||
}
|
||||
}
|
||||
|
||||
func UserInfo() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
userid, _ := c.Get("userid")
|
||||
username, _ := c.Get("username")
|
||||
account := c.GetString("account")
|
||||
role, _ := c.Get("role")
|
||||
team, _ := c.Get("team")
|
||||
|
||||
c.JSON(200, dto.Success(map[string]interface{}{
|
||||
"userid": userid,
|
||||
"username": username,
|
||||
"account": account,
|
||||
"role": role,
|
||||
"team": team,
|
||||
}))
|
||||
}
|
||||
}
|
||||
61
backend/internal/handler/note_handler.go
Normal file
61
backend/internal/handler/note_handler.go
Normal file
@@ -0,0 +1,61 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"github.com/casehub/ticket-workbench/internal/dto"
|
||||
"github.com/casehub/ticket-workbench/internal/middleware"
|
||||
"github.com/casehub/ticket-workbench/internal/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func ListNotes(db *gorm.DB) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
idStr := c.Param("id")
|
||||
id, err := strconv.Atoi(idStr)
|
||||
if err != nil {
|
||||
c.JSON(200, dto.Fail("参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
notes, err := service.ListNotes(db, id)
|
||||
if err != nil {
|
||||
c.JSON(200, dto.Fail("查询失败"))
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(200, dto.Success(notes))
|
||||
}
|
||||
}
|
||||
|
||||
func AddNote(db *gorm.DB) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
idStr := c.Param("id")
|
||||
id, err := strconv.Atoi(idStr)
|
||||
if err != nil {
|
||||
c.JSON(200, dto.Fail("参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
var req dto.AddNoteRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(200, dto.Fail("参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
user := middleware.GetCurrentUser(c)
|
||||
if user == nil {
|
||||
c.JSON(200, dto.Fail("未登录"))
|
||||
return
|
||||
}
|
||||
|
||||
note, err := service.AddNote(db, id, user.Userid, req.Content)
|
||||
if err != nil {
|
||||
c.JSON(200, dto.Fail("添加失败"))
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(200, dto.Success(note))
|
||||
}
|
||||
}
|
||||
160
backend/internal/handler/ticket_handler.go
Normal file
160
backend/internal/handler/ticket_handler.go
Normal file
@@ -0,0 +1,160 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"github.com/casehub/ticket-workbench/internal/dto"
|
||||
"github.com/casehub/ticket-workbench/internal/middleware"
|
||||
"github.com/casehub/ticket-workbench/internal/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func ListTickets(db *gorm.DB) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
var query dto.TicketListQuery
|
||||
if err := c.ShouldBindQuery(&query); err != nil {
|
||||
c.JSON(200, dto.Fail("参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
if query.Page <= 0 {
|
||||
query.Page = 1
|
||||
}
|
||||
if query.PageSize <= 0 {
|
||||
query.PageSize = 20
|
||||
}
|
||||
|
||||
result, err := service.ListTickets(db, query.Status, query.Category, query.Priority, query.Keyword, query.Page, query.PageSize)
|
||||
if err != nil {
|
||||
c.JSON(200, dto.Fail("查询失败"))
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(200, dto.Success(result))
|
||||
}
|
||||
}
|
||||
|
||||
func GetTicket(db *gorm.DB) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
idStr := c.Param("id")
|
||||
id, err := strconv.Atoi(idStr)
|
||||
if err != nil {
|
||||
c.JSON(200, dto.Fail("参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
ticket, err := service.GetTicketByID(db, id)
|
||||
if err != nil {
|
||||
c.JSON(200, dto.Fail("工单不存在"))
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(200, dto.Success(ticket))
|
||||
}
|
||||
}
|
||||
|
||||
func CreateTicket(db *gorm.DB) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
var req dto.CreateTicketRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(200, dto.Fail("参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
user := middleware.GetCurrentUser(c)
|
||||
if user == nil {
|
||||
c.JSON(200, dto.Fail("未登录"))
|
||||
return
|
||||
}
|
||||
|
||||
ticket, err := service.CreateTicket(db, req.Title, req.Content, req.Contactname, req.Contactphone, req.Source, req.Category, req.Priority, user.Userid)
|
||||
if err != nil {
|
||||
c.JSON(200, dto.Fail("创建失败"))
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(200, dto.Success(ticket))
|
||||
}
|
||||
}
|
||||
|
||||
func UpdateTicket(db *gorm.DB) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
idStr := c.Param("id")
|
||||
id, err := strconv.Atoi(idStr)
|
||||
if err != nil {
|
||||
c.JSON(200, dto.Fail("参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
var req dto.UpdateTicketRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(200, dto.Fail("参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
user := middleware.GetCurrentUser(c)
|
||||
if user == nil {
|
||||
c.JSON(200, dto.Fail("未登录"))
|
||||
return
|
||||
}
|
||||
|
||||
err = service.UpdateTicket(db, id, req.Title, req.Content, req.Contactname, req.Contactphone, req.Category, req.Priority, req.Handlerid, user.Userid)
|
||||
if err != nil {
|
||||
c.JSON(200, dto.Fail("更新失败"))
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(200, dto.Success(nil))
|
||||
}
|
||||
}
|
||||
|
||||
func UpdateTicketStatus(db *gorm.DB) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
idStr := c.Param("id")
|
||||
id, err := strconv.Atoi(idStr)
|
||||
if err != nil {
|
||||
c.JSON(200, dto.Fail("参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
var req dto.UpdateStatusRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(200, dto.Fail("参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
user := middleware.GetCurrentUser(c)
|
||||
if user == nil {
|
||||
c.JSON(200, dto.Fail("未登录"))
|
||||
return
|
||||
}
|
||||
|
||||
err = service.UpdateTicketStatus(db, id, req.Status, user.Userid)
|
||||
if err != nil {
|
||||
c.JSON(200, dto.Fail("更新失败"))
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(200, dto.Success(nil))
|
||||
}
|
||||
}
|
||||
|
||||
func GetOperationLogs(db *gorm.DB) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
idStr := c.Param("id")
|
||||
id, err := strconv.Atoi(idStr)
|
||||
if err != nil {
|
||||
c.JSON(200, dto.Fail("参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
logs, err := service.GetOperationLogs(db, id)
|
||||
if err != nil {
|
||||
c.JSON(200, dto.Fail("查询失败"))
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(200, dto.Success(logs))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user