Files
ticket-workbench/backend/internal/service/ticket_service.go
绝尘 e94f160782 修复: 代码审查4个必改项+4个建议改进
- 工单编号改为业务格式 TK-yyMMdd-NNN
- 类型断言加 comma-ok 防 panic
- priority 用指针区分未传/P0
- json.Marshal 错误处理
- 提取 ParseID 公共函数消除重复
- HTTP client 包级别复用
- LIKE 查询特殊字符转义
- interface{} → any
- auth 中间件用 dto.Fail 统一响应
2026-05-13 19:01:06 +08:00

155 lines
4.1 KiB
Go

package service
import (
"fmt"
"strings"
"time"
"github.com/casehub/ticket-workbench/internal/model"
"gorm.io/gorm"
)
type TicketListResult struct {
Total int64 `json:"total"`
Rows []model.TicketInfo `json:"rows"`
}
func ListTickets(db *gorm.DB, status *int16, category string, priority *int16, keyword string, page, pageSize int) (*TicketListResult, error) {
var total int64
var tickets []model.TicketInfo
query := db.Model(&model.TicketInfo{})
if status != nil {
query = query.Where("status = ?", *status)
}
if category != "" {
query = query.Where("category = ?", category)
}
if priority != nil {
query = query.Where("priority = ?", *priority)
}
if keyword != "" {
escaped := strings.ReplaceAll(keyword, "%", "\\%")
escaped = strings.ReplaceAll(escaped, "_", "\\_")
query = query.Where("title LIKE ? OR content LIKE ?", "%"+escaped+"%", "%"+escaped+"%")
}
if err := query.Count(&total).Error; err != nil {
return nil, err
}
offset := (page - 1) * pageSize
if err := query.Offset(offset).Limit(pageSize).Order("createtime DESC").Find(&tickets).Error; err != nil {
return nil, err
}
return &TicketListResult{Total: total, Rows: tickets}, nil
}
func GetTicketByID(db *gorm.DB, ticketid int) (*model.TicketInfo, error) {
var ticket model.TicketInfo
err := db.Where("ticketid = ?", ticketid).First(&ticket).Error
if err != nil {
return nil, err
}
return &ticket, nil
}
func CreateTicket(db *gorm.DB, title, content, contactname, contactphone, source, category string, priority int16, submitterid int) (*model.TicketInfo, error) {
now := time.Now()
dateStr := now.Format("060102")
var count int64
db.Model(&model.TicketInfo{}).Where("DATE(createtime) = CURDATE()").Count(&count)
ticketno := fmt.Sprintf("TK-%s-%03d", dateStr, count+1)
ticket := &model.TicketInfo{
Ticketno: ticketno,
Title: title,
Content: content,
Contactname: contactname,
Contactphone: contactphone,
Source: source,
Category: category,
Priority: priority,
Submitterid: submitterid,
Status: 0,
Createtime: now,
Updatetime: now,
}
if err := db.Create(ticket).Error; err != nil {
return nil, err
}
AddOperationLog(db, ticket.Ticketid, submitterid, "create", "创建工单")
return ticket, nil
}
func UpdateTicket(db *gorm.DB, ticketid int, title, content, contactname, contactphone, category string, priority *int16, handlerid *int, operatorid int) error {
updates := map[string]interface{}{
"updatetime": time.Now(),
}
if title != "" {
updates["title"] = title
}
if content != "" {
updates["content"] = content
}
if contactname != "" {
updates["contactname"] = contactname
}
if contactphone != "" {
updates["contactphone"] = contactphone
}
if category != "" {
updates["category"] = category
}
if priority != nil {
updates["priority"] = *priority
}
if handlerid != nil {
updates["handlerid"] = handlerid
}
if err := db.Model(&model.TicketInfo{}).Where("ticketid = ?", ticketid).Updates(updates).Error; err != nil {
return err
}
AddOperationLog(db, ticketid, operatorid, "update", "更新工单信息")
return nil
}
func UpdateTicketStatus(db *gorm.DB, ticketid int, status int16, operatorid int) error {
if err := db.Model(&model.TicketInfo{}).Where("ticketid = ?", ticketid).Updates(map[string]interface{}{
"status": status,
"updatetime": time.Now(),
}).Error; err != nil {
return err
}
statusText := map[int16]string{0: "待处理", 1: "分析中", 2: "已确认", 3: "处理中", 4: "已关闭"}
AddOperationLog(db, ticketid, operatorid, "status", "状态变更为: "+statusText[status])
return nil
}
func AddOperationLog(db *gorm.DB, ticketid, operatorid int, action, detail string) error {
log := &model.TicketOperationLog{
Ticketid: ticketid,
Operatorid: operatorid,
Action: action,
Detail: detail,
Createtime: time.Now(),
}
return db.Create(log).Error
}
func GetOperationLogs(db *gorm.DB, ticketid int) ([]model.TicketOperationLog, error) {
var logs []model.TicketOperationLog
err := db.Where("ticketid = ?", ticketid).Order("createtime ASC").Find(&logs).Error
return logs, err
}