Files
full/module/base/feedback/internal/logic/method/modify.go
2026-09-22 21:15:34 +08:00

133 lines
3.9 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Package method 业务逻辑方法包,实现反馈相关的业务操作
package method
import (
"context"
"errors"
"time"
"bsm/full/module/base/feedback/internal/impl"
"bsm/full/module/base/feedback/internal/models"
pb "bsm/full/module/base/feedback/pb"
"git.apinb.com/bsm-sdk/core/errcode"
"git.apinb.com/bsm-sdk/core/service"
"git.apinb.com/bsm-sdk/core/types"
"git.apinb.com/bsm-sdk/core/utils"
"git.apinb.com/bsm-sdk/core/vars"
"gorm.io/gorm"
"gorm.io/gorm/clause"
)
// Modify 修改反馈记录
// ctx: 上下文,包含用户认证信息
// in: 修改请求参数包含记录ID和要修改的字段
// 返回: 修改操作结果
func Modify(ctx context.Context, in *pb.ModifyRequest) (reply *pb.StatusReply, err error) {
// 解析用户认证信息
auth, err := service.ParseMetaCtx(ctx, nil)
if err != nil {
return nil, err
}
// 验证请求参数
if in.GetIdentity() == "" {
return nil, errcode.ErrInvalidArgument
}
// 归属校验:仅本人或管理端可修改
exist := new(models.FeedbackItem)
if err = impl.DBService.Where("identity = ?", in.GetIdentity()).First(exist).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, errcode.ErrPermissionDenied
}
return nil, err
}
if !canAccess(auth, exist.PassportIdentity) {
return nil, errcode.ErrPermissionDenied
}
// 构建更新字段:不改写 identity 与归属,避免记录"消失"或归属被转移
record := &models.FeedbackItem{
UserName: in.GetUserName(), // 用户名
Email: in.GetEmail(), // 邮箱
Phone: in.GetPhone(), // 手机号
Status: in.GetStatus(), // 状态
Title: in.GetTitle(), // 标题
Content: in.GetContent(), // 内容
Category: in.GetCategory(), // 分类
}
// 处理图片信息
images := make([]models.FeedbackImage, 0, len(in.GetImages()))
for _, v := range in.GetImages() {
identity := v.GetIdentity()
if identity == "" {
identity = utils.UUID() // 生成新的图片ID
}
images = append(images, models.FeedbackImage{
Std_IICUDS: types.Std_IICUDS{
Identity: identity,
},
ItemIdentity: in.GetIdentity(), // 关联的反馈记录ID
URL: v.GetUrl(), // 图片URL
})
}
// 处理附件信息:子表 identity 为唯一索引,必须逐个赋值,否则多条附件必然唯一键冲突
accessories := make([]models.FeedbackAccessory, 0, len(in.GetAccessories()))
for _, v := range in.GetAccessories() {
identity := v.GetIdentity()
if identity == "" {
identity = utils.UUID() // 生成新的附件ID
}
accessories = append(accessories, models.FeedbackAccessory{
Std_IICUDS: types.Std_IICUDS{
Identity: identity,
},
ItemIdentity: in.GetIdentity(), // 关联的反馈记录ID
Title: v.Title, // 附件标题
FilePath: v.FilePath, // 附件文件路径
})
}
// 主表字段与子表重建放在同一事务内,任一步失败整体回滚
err = impl.DBService.Transaction(func(tx *gorm.DB) error {
// 只更新主表标量字段Omit 关联后由下面显式重建子表,避免同一次修改写入两遍
if err := tx.Model(&models.FeedbackItem{}).
Where("identity = ?", in.GetIdentity()).
Omit(clause.Associations).
Updates(record).Error; err != nil {
return err
}
// 先删除关联的图片和附件
if err := tx.Where("item_identity = ?", in.GetIdentity()).Delete(&models.FeedbackImage{}).Error; err != nil {
return err
}
if err := tx.Where("item_identity = ?", in.GetIdentity()).Delete(&models.FeedbackAccessory{}).Error; err != nil {
return err
}
// 重新创建关联的图片和附件
if len(images) > 0 {
if err := tx.Create(&images).Error; err != nil {
return err
}
}
if len(accessories) > 0 {
if err := tx.Create(&accessories).Error; err != nil {
return err
}
}
return nil
})
if err != nil {
return nil, err
}
return &pb.StatusReply{
Message: vars.OK,
Timeseq: time.Now().UnixMilli(),
}, nil
}