100 lines
3.8 KiB
Go
100 lines
3.8 KiB
Go
|
|
// 功能描述:报修现场照片关联与本人受保护读取;不公开照片文件目录。
|
|||
|
|
// 版本:1.0.0。
|
|||
|
|
package user
|
|||
|
|
|
|||
|
|
import (
|
|||
|
|
"crypto/sha256"
|
|||
|
|
"fmt"
|
|||
|
|
"git.apinb.com/bsm-sdk/core/errcode"
|
|||
|
|
"git.apinb.com/heqiapp/platforms/backend/api/internal/impl"
|
|||
|
|
common "git.apinb.com/heqiapp/platforms/backend/api/internal/logic/common"
|
|||
|
|
"git.apinb.com/heqiapp/platforms/backend/api/internal/logic/upload"
|
|||
|
|
"git.apinb.com/heqiapp/platforms/backend/api/internal/models"
|
|||
|
|
"github.com/gin-gonic/gin"
|
|||
|
|
"gorm.io/gorm"
|
|||
|
|
"time"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
// ticketPhotoRequest 记录添加时间,导入照片不冒充已验证的原始拍摄时间。
|
|||
|
|
type ticketPhotoRequest struct {
|
|||
|
|
URI string `json:"uri" binding:"required"`
|
|||
|
|
AddedAt time.Time `json:"added_at" binding:"required"`
|
|||
|
|
Source string `json:"source" binding:"required,oneof=camera gallery"`
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
func UploadTicketPhoto(ctx *gin.Context) {
|
|||
|
|
account, ok := common.UserAccount(ctx)
|
|||
|
|
if !ok {
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
upload.UploadTicketPhoto(ctx, account.Identity)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// UploadedTicketPhoto 恢复本人草稿照片,不接受其他账户或任意路径。
|
|||
|
|
func UploadedTicketPhoto(ctx *gin.Context) {
|
|||
|
|
account, ok := common.UserAccount(ctx)
|
|||
|
|
if !ok {
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
upload.ServeOwnedTicketPhoto(ctx, account.Identity, ctx.Param("name"))
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// saveTicketPhotos 与工单创建共用事务,任一图片不属于本人时全部回滚。
|
|||
|
|
func saveTicketPhotos(tx *gorm.DB, ticket models.CsTicket, owner string, photos []ticketPhotoRequest) error {
|
|||
|
|
seen := map[string]bool{}
|
|||
|
|
for index, photo := range photos {
|
|||
|
|
if seen[photo.URI] || !upload.OwnsTicketPhoto(owner, photo.URI) || photo.AddedAt.IsZero() || photo.AddedAt.After(time.Now().Add(5*time.Minute)) {
|
|||
|
|
return errcode.ErrInvalidArgument
|
|||
|
|
}
|
|||
|
|
seen[photo.URI] = true
|
|||
|
|
evidence := models.CsTicketEvidence{
|
|||
|
|
Entity: common.NewEntity(common.StatusEnable), CsTicketID: ticket.ID, EvidenceType: "reported", MediaType: "image", FileURI: photo.URI,
|
|||
|
|
CapturedAt: photo.AddedAt, ReceivedAt: time.Now(), Source: "user_" + photo.Source, IntegrityStatus: "capture_time_unknown", OperatorIdentity: owner,
|
|||
|
|
RequestNo: fmt.Sprintf("%x", sha256.Sum256([]byte(fmt.Sprintf("user-photo:%s:%d", ticket.Identity, index)))),
|
|||
|
|
}
|
|||
|
|
if err := tx.Create(&evidence).Error; err != nil {
|
|||
|
|
return err
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return nil
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// ticketPhotosForList 一次查询本人列表涉及的证据,只发布元数据与公开证据UUID。
|
|||
|
|
func ticketPhotosForList(tickets []models.CsTicket) (map[uint64][]gin.H, error) {
|
|||
|
|
result := map[uint64][]gin.H{}
|
|||
|
|
ids := make([]uint64, 0, len(tickets))
|
|||
|
|
for _, ticket := range tickets {
|
|||
|
|
ids = append(ids, ticket.ID)
|
|||
|
|
}
|
|||
|
|
if len(ids) == 0 {
|
|||
|
|
return result, nil
|
|||
|
|
}
|
|||
|
|
var photos []models.CsTicketEvidence
|
|||
|
|
if err := impl.DBService.Where("cs_ticket_id IN ? AND evidence_type = ? AND status <> ?", ids, "reported", common.StatusArchived).Order("created_at asc").Find(&photos).Error; err != nil {
|
|||
|
|
return nil, err
|
|||
|
|
}
|
|||
|
|
for _, photo := range photos {
|
|||
|
|
result[photo.CsTicketID] = append(result[photo.CsTicketID], gin.H{"identity": photo.Identity, "added_at": photo.CapturedAt, "source": photo.Source, "integrity_status": photo.IntegrityStatus})
|
|||
|
|
}
|
|||
|
|
return result, nil
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// TicketPhoto 不允许借工单UUID读取其他工单照片,也不允许读取他人报修。
|
|||
|
|
func TicketPhoto(ctx *gin.Context) {
|
|||
|
|
account, ok := common.UserAccount(ctx)
|
|||
|
|
if !ok {
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
var ticket models.CsTicket
|
|||
|
|
if impl.DBService.Where("identity = ? AND user_account_id = ? AND status <> ?", ctx.Param("identity"), account.ID, common.StatusArchived).First(&ticket).Error != nil {
|
|||
|
|
ctx.Status(404)
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
var photo models.CsTicketEvidence
|
|||
|
|
if impl.DBService.Where("identity = ? AND cs_ticket_id = ? AND evidence_type = ? AND status <> ?", ctx.Param("photoIdentity"), ticket.ID, "reported", common.StatusArchived).First(&photo).Error != nil {
|
|||
|
|
ctx.Status(404)
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
upload.ServeTicketPhoto(ctx, account.Identity, photo.FileURI)
|
|||
|
|
}
|