Files
backend-go/models/models.go
T
2026-06-06 13:50:56 +08:00

452 lines
19 KiB
Go

package models
import (
"time"
"gorm.io/gorm"
)
const (
RoleAdmin = "admin"
RoleTechnicianLegacy = "technician"
RoleEmployee = "employee"
RoleSoftwareEngineer = "software_engineer"
RoleHardwareEngineer = "hardware_engineer"
RoleBusinessManager = "business_manager"
RoleProjectManager = "project_manager"
)
// WorkOrderRoles 是权限管理中可创建/编辑的四个对等角色。
var WorkOrderRoles = []string{
RoleSoftwareEngineer,
RoleHardwareEngineer,
RoleBusinessManager,
RoleProjectManager,
}
// AssignableWorkOrderRoles 是可被派单的角色,包含旧 technician 数据兼容。
var AssignableWorkOrderRoles = append([]string{}, append(WorkOrderRoles, RoleTechnicianLegacy)...)
func IsWorkOrderRole(role string) bool {
for _, item := range WorkOrderRoles {
if role == item {
return true
}
}
return false
}
func IsAssignableWorkOrderRole(role string) bool {
for _, item := range AssignableWorkOrderRoles {
if role == item {
return true
}
}
return false
}
func HasBackendAccess(role string) bool {
return role == RoleAdmin || IsAssignableWorkOrderRole(role)
}
func HasWorkOrderAccess(role string) bool {
return role == RoleAdmin || IsAssignableWorkOrderRole(role)
}
// User 模型
type User struct {
ID uint `gorm:"primaryKey" json:"id"`
Username string `gorm:"uniqueIndex;size:255" json:"username"`
Password string `gorm:"size:255" json:"-"`
Name string `gorm:"size:255" json:"name"`
Email string `gorm:"size:255" json:"email"`
Phone string `gorm:"size:50" json:"phone"`
EmployeeNo string `gorm:"uniqueIndex;size:100" json:"employeeNo"`
Position string `gorm:"size:255" json:"position"`
Role string `gorm:"size:50;default:'employee'" json:"role"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
EmployeeSerials []EmployeeSerial `gorm:"foreignKey:EmployeeID" json:"employeeSerials,omitempty"`
}
// Company 模型
type Company struct {
ID uint `gorm:"primaryKey" json:"id"`
CompanyName string `gorm:"uniqueIndex;size:255" json:"companyName"`
IsActive bool `gorm:"default:true" json:"isActive"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
}
// ProductTrace 产品溯源模型
type ProductTrace struct {
ID uint `gorm:"primaryKey" json:"id"`
CompanyName string `gorm:"index;size:255" json:"companyName"`
CompanyAddress string `gorm:"size:500" json:"companyAddress"`
CompanyPhone string `gorm:"size:32" json:"companyPhone"`
DeviceInfo string `gorm:"type:text" json:"deviceInfo"`
WarrantyPeriod string `gorm:"size:100" json:"warrantyPeriod"`
ManufactureDate time.Time `json:"manufactureDate"`
SerialNumber string `gorm:"uniqueIndex;size:255" json:"serialNumber"`
OfficialWebsite string `gorm:"size:500" json:"officialWebsite,omitempty"`
WechatQRCode string `gorm:"type:text" json:"wechatQrCode,omitempty"`
IsActive bool `gorm:"default:true" json:"isActive"`
CreatedBy *uint `json:"createdBy"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
Creator *User `gorm:"foreignKey:CreatedBy" json:"creator,omitempty"`
}
// UserDTO 数据传输对象
type UserDTO struct {
ID uint `json:"id"`
Username string `json:"username"`
Name string `json:"name"`
Email string `json:"email"`
Phone string `json:"phone"`
EmployeeNo string `json:"employeeNo"`
Position string `json:"position"`
Role string `json:"role"`
CreatedAt time.Time `json:"createdAt"`
EmployeeSerials []EmployeeSerial `json:"employeeSerials,omitempty"`
}
// LoginDTO 登录请求数据
type LoginDTO struct {
Username string `json:"username" validate:"required"`
Password string `json:"password" validate:"required,min=6"`
}
// ChangePasswordDTO 密码修改请求数据
type ChangePasswordDTO struct {
CurrentPassword string `json:"currentPassword" validate:"required"`
NewPassword string `json:"newPassword" validate:"required,min=6"`
}
// UpdateProfileDTO 个人信息更新请求数据
type UpdateProfileDTO struct {
Name string `json:"name" validate:"required"`
Email string `json:"email" validate:"required,email"`
}
// CreateUserDTO 管理员创建用户请求
type CreateUserDTO struct {
Username string `json:"username,omitempty"`
Password string `json:"password,omitempty"`
Name string `json:"name" validate:"required"`
Email string `json:"email" validate:"omitempty,email"`
Phone string `json:"phone" validate:"required"`
EmployeeNo string `json:"employeeNo" validate:"required"`
Position string `json:"position" validate:"required"`
Role string `json:"role" validate:"required,oneof=software_engineer hardware_engineer business_manager project_manager"`
}
// UpdateUserDTO 管理员更新用户信息请求
type UpdateUserDTO struct {
Name string `json:"name,omitempty"`
Email string `json:"email,omitempty" validate:"omitempty,email"`
Phone string `json:"phone,omitempty"`
EmployeeNo string `json:"employeeNo,omitempty"`
Position string `json:"position,omitempty"`
Role string `json:"role,omitempty" validate:"omitempty,oneof=software_engineer hardware_engineer business_manager project_manager"`
}
// AdminResetPasswordDTO 管理员重置用户密码
type AdminResetPasswordDTO struct {
NewPassword string `json:"newPassword" validate:"required,min=6"`
}
// CreateProductTraceDTO 创建产品溯源请求数据
type CreateProductTraceDTO struct {
CompanyName string `json:"companyName" validate:"required"`
CompanyAddress string `json:"companyAddress" validate:"required"`
CompanyPhone string `json:"companyPhone" validate:"required"`
DeviceInfo string `json:"deviceInfo" validate:"required"`
WarrantyPeriod string `json:"warrantyPeriod" validate:"required"`
ManufactureDate time.Time `json:"manufactureDate" validate:"required"`
SerialNumber string `json:"serialNumber" validate:"required"`
OfficialWebsite string `json:"officialWebsite,omitempty" validate:"omitempty,url"`
WechatQRCode string `json:"wechatQrCode,omitempty"`
}
// UpdateProductTraceDTO 更新产品溯源请求数据
type UpdateProductTraceDTO struct {
CompanyName string `json:"companyName,omitempty"`
CompanyAddress string `json:"companyAddress,omitempty"`
CompanyPhone string `json:"companyPhone,omitempty"`
DeviceInfo string `json:"deviceInfo,omitempty"`
WarrantyPeriod string `json:"warrantyPeriod,omitempty"`
ManufactureDate *time.Time `json:"manufactureDate,omitempty"`
OfficialWebsite string `json:"officialWebsite,omitempty" validate:"omitempty,url"`
WechatQRCode string `json:"wechatQrCode,omitempty"`
IsActive *bool `json:"isActive,omitempty"`
}
// QRCodeDTO 二维码生成请求数据
type QRCodeDTO struct {
BaseUrl string `json:"baseUrl,omitempty"`
}
// LoginResponse 登录响应
type LoginResponse struct {
Message string `json:"message"`
AccessToken string `json:"accessToken"`
User UserDTO `json:"user"`
}
// BaseResponse 基础响应
type BaseResponse struct {
Message string `json:"message"`
}
// ErrorResponse 错误响应
type ErrorResponse struct {
Message string `json:"message"`
Error string `json:"error,omitempty"`
}
// DataResponse 数据响应
type DataResponse struct {
Message string `json:"message"`
Data any `json:"data"`
}
// PaginationResponse 分页响应
type PaginationResponse struct {
Message string `json:"message"`
Data any `json:"data"`
Pagination Pagination `json:"pagination"`
}
// Pagination 分页信息
type Pagination struct {
Page int `json:"page"`
Limit int `json:"limit"`
Total int64 `json:"total"`
TotalPages int `json:"totalPages"`
}
// QRCodeResponse 二维码响应
type QRCodeResponse struct {
Message string `json:"message"`
QRCodeData string `json:"qrCodeData"`
QueryURL string `json:"queryUrl"`
}
// EmployeeSerial 员工序列号模型
type EmployeeSerial struct {
ID uint `gorm:"primaryKey" json:"id"`
SerialNumber string `gorm:"uniqueIndex;size:255" json:"serialNumber"`
CompanyName string `gorm:"index;size:255" json:"companyName"`
Position string `gorm:"size:255" json:"position"`
EmployeeName string `gorm:"size:255" json:"employeeName"`
EmployeeID *uint `gorm:"index" json:"employeeId,omitempty"`
IsActive bool `gorm:"default:true" json:"isActive"`
CreatedBy *uint `json:"createdBy"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
User *User `gorm:"foreignKey:CreatedBy" json:"user,omitempty"`
Employee *User `gorm:"foreignKey:EmployeeID" json:"employee,omitempty"`
Company *Company `gorm:"foreignKey:CompanyName;references:CompanyName" json:"company,omitempty"`
}
// GenerateEmployeeSerialDTO 生成员工序列号请求数据
type GenerateEmployeeSerialDTO struct {
CompanyName string `json:"companyName" validate:"required"`
Position string `json:"position" validate:"required"`
EmployeeName string `json:"employeeName" validate:"required"`
Quantity int `json:"quantity" validate:"min=1,max=1000"`
SerialPrefix string `json:"serialPrefix,omitempty"`
}
// UpdateEmployeeSerialDTO 员工序列号更新请求数据
type UpdateEmployeeSerialDTO struct {
CompanyName string `json:"companyName,omitempty" validate:"omitempty"`
Position string `json:"position,omitempty" validate:"omitempty"`
EmployeeName string `json:"employeeName,omitempty" validate:"omitempty"`
IsActive *bool `json:"isActive,omitempty"`
}
// AftersalesOrder 售后工单模型
type AftersalesOrder struct {
ID uint `gorm:"primaryKey" json:"id"`
SerialNumber string `gorm:"uniqueIndex;size:64" json:"serialNumber"`
CompanyName string `gorm:"index;size:255" json:"companyName"`
CompanyAddress string `gorm:"size:500" json:"companyAddress"`
ContactName string `gorm:"size:100" json:"contactName"`
ContactPhone string `gorm:"size:32" json:"contactPhone"`
ServiceType string `gorm:"size:32" json:"serviceType"`
IssueDescription string `gorm:"type:text" json:"issueDescription"`
ResolutionNote string `gorm:"type:text" json:"resolutionNote"`
WorkOrderStatus string `gorm:"size:32;default:'created'" json:"workOrderStatus"`
AuthorizationStatus string `gorm:"size:32;default:'pending'" json:"authorizationStatus"`
TechnicianID *uint `json:"technicianId"`
CreatedBy *uint `json:"createdBy"`
ScannedAt *time.Time `json:"scannedAt"`
ConfirmedAt *time.Time `json:"confirmedAt"`
RejectCount int `gorm:"default:0" json:"rejectCount"`
Signature string `gorm:"type:text" json:"signature,omitempty"`
ResponsibleSignature string `gorm:"type:text" json:"responsibleSignature,omitempty"`
SiteImagesJSON string `gorm:"type:text;column:site_images" json:"-"`
SiteImages []string `gorm:"-" json:"siteImages,omitempty"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
Technician *User `gorm:"foreignKey:TechnicianID" json:"technician,omitempty"`
Creator *User `gorm:"foreignKey:CreatedBy" json:"creator,omitempty"`
}
// CreateAftersalesOrderDTO 创建售后工单请求数据
type CreateAftersalesOrderDTO struct {
CompanyName string `json:"companyName" validate:"required"`
CompanyAddress string `json:"companyAddress" validate:"required"`
ContactName string `json:"contactName" validate:"required"`
ContactPhone string `json:"contactPhone" validate:"required,len=11"`
ServiceType string `json:"serviceType" validate:"required,oneof=software hardware maintenance"`
IssueDescription string `json:"issueDescription" validate:"required"`
TechnicianID *uint `json:"technicianId,omitempty"`
}
// UpdateAftersalesOrderDTO 更新售后工单请求数据
type UpdateAftersalesOrderDTO struct {
CompanyAddress string `json:"companyAddress,omitempty"`
ContactName string `json:"contactName,omitempty"`
ContactPhone string `json:"contactPhone,omitempty" validate:"omitempty,len=11"`
ServiceType string `json:"serviceType,omitempty" validate:"omitempty,oneof=software hardware maintenance"`
IssueDescription string `json:"issueDescription,omitempty"`
ResolutionNote string `json:"resolutionNote,omitempty"`
TechnicianID *uint `json:"technicianId,omitempty"`
}
// SubmitForConfirmationDTO 提交客户确认请求
type SubmitForConfirmationDTO struct {
ResolutionNote string `json:"resolutionNote" validate:"required"`
}
// CustomerConfirmDTO 客户确认请求
// Signature 为客户在网页上手写签名的 base64 PNG dataURL,仅 authorize 时必填
// ResponsibleSignature 为负责人在网页上手写签名的 base64 PNG dataURL,仅 authorize 时必填
// RejectReason 为客户拒绝的原因,仅 reject 时必填
type CustomerConfirmDTO struct {
Action string `json:"action" validate:"required,oneof=authorize reject"`
Signature string `json:"signature,omitempty" validate:"required_if=Action authorize"`
ResponsibleSignature string `json:"responsibleSignature,omitempty" validate:"required_if=Action authorize"`
RejectReason string `json:"rejectReason,omitempty" validate:"required_if=Action reject"`
}
// ReassignAftersalesDTO 重新分配工单负责人请求
type ReassignAftersalesDTO struct {
TechnicianID uint `json:"technicianId" validate:"required"`
}
// AftersalesPublicView 公开查询返回视图(脱敏)
type AftersalesPublicView struct {
SerialNumber string `json:"serialNumber"`
CompanyName string `json:"companyName"`
CompanyAddress string `json:"companyAddress"`
ContactName string `json:"contactName"`
ServiceType string `json:"serviceType"`
IssueDescription string `json:"issueDescription"`
ResolutionNote string `json:"resolutionNote"`
WorkOrderStatus string `json:"workOrderStatus"`
AuthorizationStatus string `json:"authorizationStatus"`
TechnicianName string `json:"technicianName"`
CreatedAt time.Time `json:"createdAt"`
ConfirmedAt *time.Time `json:"confirmedAt"`
Signature string `json:"signature,omitempty"`
ResponsibleSignature string `json:"responsibleSignature,omitempty"`
SiteImages []string `json:"siteImages,omitempty"`
}
// ProjectOrder 项目工单模型
type ProjectOrder struct {
ID uint `gorm:"primaryKey" json:"id"`
SerialNumber string `gorm:"uniqueIndex;size:64" json:"serialNumber"`
CompanyName string `gorm:"index;size:255" json:"companyName"`
CompanyAddress string `gorm:"size:500" json:"companyAddress"`
ContactName string `gorm:"size:100" json:"contactName"`
ContactPhone string `gorm:"size:32" json:"contactPhone"`
ProjectType string `gorm:"size:32" json:"projectType"`
SiteDescription string `gorm:"type:text" json:"siteDescription"`
CompletionNote string `gorm:"type:text" json:"completionNote"`
WorkOrderStatus string `gorm:"size:32;default:'created'" json:"workOrderStatus"`
TechnicianID *uint `json:"technicianId"`
CreatedBy *uint `json:"createdBy"`
ScannedAt *time.Time `json:"scannedAt"`
CompletedAt *time.Time `json:"completedAt"`
EngineerSignature string `gorm:"type:text" json:"engineerSignature,omitempty"`
SiteImagesJSON string `gorm:"type:text;column:site_images" json:"-"`
SiteImages []string `gorm:"-" json:"siteImages,omitempty"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
Technician *User `gorm:"foreignKey:TechnicianID" json:"technician,omitempty"`
Creator *User `gorm:"foreignKey:CreatedBy" json:"creator,omitempty"`
}
// CreateProjectOrderDTO 创建项目工单请求数据
type CreateProjectOrderDTO struct {
CompanyName string `json:"companyName" validate:"required"`
CompanyAddress string `json:"companyAddress" validate:"required"`
ContactName string `json:"contactName" validate:"required"`
ContactPhone string `json:"contactPhone" validate:"required,len=11"`
ProjectType string `json:"projectType" validate:"required,oneof=survey implementation maintenance other"`
SiteDescription string `json:"siteDescription" validate:"required"`
TechnicianID *uint `json:"technicianId,omitempty"`
}
// UpdateProjectOrderDTO 更新项目工单请求数据
type UpdateProjectOrderDTO struct {
CompanyAddress string `json:"companyAddress,omitempty"`
ContactName string `json:"contactName,omitempty"`
ContactPhone string `json:"contactPhone,omitempty" validate:"omitempty,len=11"`
ProjectType string `json:"projectType,omitempty" validate:"omitempty,oneof=survey implementation maintenance other"`
SiteDescription string `json:"siteDescription,omitempty"`
CompletionNote string `json:"completionNote,omitempty"`
TechnicianID *uint `json:"technicianId,omitempty"`
}
// SubmitProjectCompletionDTO 提交完成资料请求
type SubmitProjectCompletionDTO struct {
CompletionNote string `json:"completionNote" validate:"required"`
}
// ProjectEngineerCompleteDTO 工程师完成确认请求
type ProjectEngineerCompleteDTO struct {
EngineerSignature string `json:"engineerSignature" validate:"required"`
CompletionNote string `json:"completionNote,omitempty"`
}
// ReassignProjectOrderDTO 重新分配工程师请求
type ReassignProjectOrderDTO struct {
TechnicianID uint `json:"technicianId" validate:"required"`
}
// ProjectOrderPublicView 公开查询返回视图
type ProjectOrderPublicView struct {
SerialNumber string `json:"serialNumber"`
CompanyName string `json:"companyName"`
CompanyAddress string `json:"companyAddress"`
ContactName string `json:"contactName"`
ProjectType string `json:"projectType"`
SiteDescription string `json:"siteDescription"`
CompletionNote string `json:"completionNote"`
WorkOrderStatus string `json:"workOrderStatus"`
TechnicianName string `json:"technicianName"`
CreatedAt time.Time `json:"createdAt"`
CompletedAt *time.Time `json:"completedAt"`
EngineerSignature string `json:"engineerSignature,omitempty"`
SiteImages []string `json:"siteImages,omitempty"`
}