This commit is contained in:
2026-08-17 13:19:15 +08:00
parent 2b7c1c790b
commit 0e93c4f0a9
314 changed files with 2151 additions and 17468 deletions
@@ -16,11 +16,5 @@ var Ad = new(ad)
// RewardClaim 领取广告激励(限频:effect_extra 每日 2 次 / vip_trial 每日 1 次)
func (c *ad) RewardClaim(ctx context.Context, req *dto.AdRewardClaimReq) (res *dto.AdRewardClaimRes, err error) {
result, err := service.AdService.Claim(ctx, commonHttp.GetUserId(g.RequestFromCtx(ctx)), req.AdType)
if err != nil {
return nil, err
}
return &dto.AdRewardClaimRes{Reward: &dto.AdRewardInfo{
AdType: result.AdType, RemainingToday: result.RemainingToday,
}}, nil
return service.AdService.Claim(ctx, commonHttp.GetUserId(g.RequestFromCtx(ctx)), req)
}
@@ -15,25 +15,9 @@ type avatar struct{}
var Avatar = new(avatar)
func (c *avatar) Build(ctx context.Context, req *dto.AvatarBuildReq) (res *dto.AvatarBuildRes, err error) {
a, err := service.AvatarService.Build(ctx, common.GetUserId(g.RequestFromCtx(ctx)))
if err != nil {
return nil, err
}
return &dto.AvatarBuildRes{AvatarId: a.Id, Status: a.BuildStatus}, nil
return service.AvatarService.Build(ctx, common.GetUserId(g.RequestFromCtx(ctx)))
}
func (c *avatar) Get(ctx context.Context, req *dto.AvatarGetReq) (res *dto.AvatarGetRes, err error) {
a, err := service.AvatarService.Get(ctx, common.GetUserId(g.RequestFromCtx(ctx)))
if err != nil || a == nil {
return &dto.AvatarGetRes{}, nil
}
return &dto.AvatarGetRes{
FaceTemplateId: a.FaceTemplateId,
BodyTemplateId: a.BodyTemplateId,
SkinToneIndex: a.SkinToneIndex,
GlbUrl: a.GlbUrl,
FramesUrl: a.FramesUrl,
BuildStatus: a.BuildStatus,
Error: a.Error,
}, nil
return service.AvatarService.Get(ctx, common.GetUserId(g.RequestFromCtx(ctx)))
}
@@ -5,7 +5,6 @@ import (
"slogan-agent/common"
"slogan-agent/styleagent/model/dto"
"slogan-agent/styleagent/model/entity"
"slogan-agent/styleagent/service"
"github.com/gogf/gf/v2/frame/g"
@@ -15,35 +14,10 @@ type body_measurement struct{}
var BodyMeasurement = new(body_measurement)
func (c *body_measurement) Save(ctx context.Context, req *dto.BodyMeasurementSaveReq) (res *struct{}, err error) {
if err := service.BodyMeasurementService.Save(ctx, common.GetUserId(g.RequestFromCtx(ctx)), &entity.BodyMeasurement{
Height: req.Height,
Weight: req.Weight,
SkinTone: req.SkinTone,
Bust: req.Bust,
Waist: req.Waist,
Hip: req.Hip,
Shoulder: req.Shoulder,
FitParams: req.FitParams,
}); err != nil {
return nil, err
}
return &struct{}{}, nil
func (c *body_measurement) Save(ctx context.Context, req *dto.BodyMeasurementSaveReq) (res *dto.BodyMeasurementSaveRes, err error) {
return service.BodyMeasurementService.Save(ctx, common.GetUserId(g.RequestFromCtx(ctx)), req)
}
func (c *body_measurement) Get(ctx context.Context, req *dto.BodyMeasurementGetReq) (res *dto.BodyMeasurementGetRes, err error) {
b, err := service.BodyMeasurementService.Get(ctx, common.GetUserId(g.RequestFromCtx(ctx)))
if err != nil || b == nil {
return &dto.BodyMeasurementGetRes{}, nil
}
return &dto.BodyMeasurementGetRes{
Height: b.Height,
Weight: b.Weight,
SkinTone: b.SkinTone,
Bust: b.Bust,
Waist: b.Waist,
Hip: b.Hip,
Shoulder: b.Shoulder,
FitParams: b.FitParams,
}, nil
return service.BodyMeasurementService.Get(ctx, common.GetUserId(g.RequestFromCtx(ctx)))
}
@@ -9,9 +9,5 @@ import (
// CategoryList 联盟分类列表(客户端 chips)
func (c *cps) CategoryList(ctx context.Context, req *dto.CpsCategoryListReq) (res *dto.CpsCategoryListRes, err error) {
list, err := service.CpsCategoryService.List(ctx)
if err != nil {
return nil, err
}
return &dto.CpsCategoryListRes{List: list}, nil
return service.CpsCategoryService.List(ctx)
}
@@ -12,9 +12,5 @@ import (
// MyRecent 最近优惠(点击日志 → 商品)
func (c *cps) MyRecent(ctx context.Context, req *dto.CpsMyRecentReq) (res *dto.CpsMyRecentRes, err error) {
list, err := service.CpsClickLogService.MyRecent(ctx, common.GetUserId(g.RequestFromCtx(ctx)))
if err != nil {
return nil, err
}
return &dto.CpsMyRecentRes{List: list}, nil
return service.CpsClickLogService.MyRecent(ctx, common.GetUserId(g.RequestFromCtx(ctx)))
}
@@ -17,19 +17,11 @@ var Cps = new(cps)
// ProductList 选品池分页列表
func (c *cps) ProductList(ctx context.Context, req *dto.CpsProductListReq) (res *dto.CpsProductListRes, err error) {
list, hasMore, err := service.CpsProductService.ListByCategory(ctx, req.Source, req.CategoryCode, req.City, req.Page, 0)
if err != nil {
return nil, err
}
return &dto.CpsProductListRes{List: list, HasMore: hasMore}, nil
return service.CpsProductService.ListByCategory(ctx, req.Source, req.CategoryCode, req.City, req.Page, 0)
}
// ProductLink 商品转链(记录点击日志)
func (c *cps) ProductLink(ctx context.Context, req *dto.CpsProductLinkReq) (res *dto.CpsProductLinkRes, err error) {
r := g.RequestFromCtx(ctx)
link, err := service.CpsProductService.ClickLink(ctx, common.GetUserId(r), req.ProductId, req.Scene, req.PlanId, r.GetClientIp())
if err != nil {
return nil, err
}
return &dto.CpsProductLinkRes{Deeplink: link}, nil
return service.CpsProductService.ClickLink(ctx, common.GetUserId(r), req.ProductId, req.Scene, req.PlanId, r.GetClientIp())
}
@@ -12,9 +12,5 @@ type hairstyle struct{}
var Hairstyle = new(hairstyle)
func (c *hairstyle) List(ctx context.Context, req *dto.HairstyleListReq) (res *dto.HairstyleListRes, err error) {
list, err := service.HairstyleService.List(ctx)
if err != nil {
return nil, err
}
return &dto.HairstyleListRes{List: list}, nil
return service.HairstyleService.List(ctx)
}
@@ -18,20 +18,10 @@ var Member = new(member)
// PlanList 会员套餐列表
func (c *member) PlanList(ctx context.Context, req *dto.MemberPlanListReq) (res *dto.MemberPlanListRes, err error) {
list, err := service.MemberPlanService.PlanList(ctx)
if err != nil {
return nil, err
}
return &dto.MemberPlanListRes{List: list}, nil
return service.MemberPlanService.PlanList(ctx)
}
// Status 我的会员状态
func (c *member) Status(ctx context.Context, req *dto.MemberStatusReq) (res *dto.MemberStatusRes, err error) {
st, err := service.MemberPlanService.Status(ctx, commonHttp.GetUserId(g.RequestFromCtx(ctx)))
if err != nil {
return nil, err
}
return &dto.MemberStatusRes{
IsVip: st.IsVip, ExpireAt: st.ExpireAt, PlanName: st.PlanName, Benefits: st.Benefits,
}, nil
return service.MemberPlanService.Status(ctx, commonHttp.GetUserId(g.RequestFromCtx(ctx)))
}
@@ -18,18 +18,10 @@ var Outfit = new(outfit)
// Generate 生成穿搭方案(异步任务)
func (c *outfit) Generate(ctx context.Context, req *dto.OutfitGenerateReq) (res *dto.OutfitGenerateRes, err error) {
taskId, err := service.OutfitService.Generate(ctx, common.GetUserId(g.RequestFromCtx(ctx)), req)
if err != nil {
return nil, err
}
return &dto.OutfitGenerateRes{TaskId: taskId}, nil
return service.OutfitService.Generate(ctx, common.GetUserId(g.RequestFromCtx(ctx)), req)
}
// TaskStatus 查询生成任务状态
func (c *outfit) TaskStatus(ctx context.Context, req *dto.OutfitTaskStatusReq) (res *dto.OutfitTaskStatusRes, err error) {
status, msg, err := service.OutfitService.GetTaskStatus(ctx, common.GetUserId(g.RequestFromCtx(ctx)), req.TaskId)
if err != nil {
return nil, err
}
return &dto.OutfitTaskStatusRes{Status: status, Error: msg}, nil
return service.OutfitService.GetTaskStatus(ctx, common.GetUserId(g.RequestFromCtx(ctx)), req.TaskId)
}
@@ -12,11 +12,7 @@ import (
// PlanList 方案列表
func (c *outfit) PlanList(ctx context.Context, req *dto.OutfitPlanListReq) (res *dto.OutfitPlanListRes, err error) {
list, err := service.OutfitPlanService.ListPlans(ctx, common.GetUserId(g.RequestFromCtx(ctx)))
if err != nil {
return nil, err
}
return &dto.OutfitPlanListRes{List: list}, nil
return service.OutfitPlanService.ListPlans(ctx, common.GetUserId(g.RequestFromCtx(ctx)))
}
// PlanDetail 方案详情(items + images + hairstyle
@@ -25,9 +21,6 @@ func (c *outfit) PlanDetail(ctx context.Context, req *dto.OutfitPlanDetailReq) (
}
// SelectMain 选定主方案(触发效果图生成)
func (c *outfit) SelectMain(ctx context.Context, req *dto.OutfitSelectMainReq) (res *struct{}, err error) {
if err = service.OutfitPlanService.SelectMain(ctx, common.GetUserId(g.RequestFromCtx(ctx)), req.PlanId); err != nil {
return nil, err
}
return &struct{}{}, nil
func (c *outfit) SelectMain(ctx context.Context, req *dto.OutfitSelectMainReq) (res *dto.OutfitSelectMainRes, err error) {
return service.OutfitPlanService.SelectMain(ctx, common.GetUserId(g.RequestFromCtx(ctx)), req.PlanId)
}
@@ -13,9 +13,5 @@ var PartnerStore = new(partner_store)
// List 合作门店列表
func (c *partner_store) List(ctx context.Context, req *dto.StoreListReq) (res *dto.StoreListRes, err error) {
list, err := service.PartnerStoreService.List(ctx, req.Type)
if err != nil {
return nil, err
}
return &dto.StoreListRes{List: list}, nil
return service.PartnerStoreService.List(ctx, req.Type)
}
@@ -1,3 +0,0 @@
package controller
// pay_notify_log 表控制器:无独立路由 handler(回调日志由 /member/order/notify 审计写入)
@@ -2,7 +2,6 @@ package controller
import (
"context"
"errors"
"fmt"
commonHttp "slogan-agent/common"
@@ -10,65 +9,32 @@ import (
"slogan-agent/styleagent/service"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
)
// OrderCreate 下单 → 返回支付 URL
func (c *member) OrderCreate(ctx context.Context, req *dto.MemberOrderCreateReq) (res *dto.MemberOrderCreateRes, err error) {
order, payURL, err := service.PaymentOrderService.CreateMemberOrder(ctx, commonHttp.GetUserId(g.RequestFromCtx(ctx)), req.PlanId)
if err != nil {
return nil, err
}
return &dto.MemberOrderCreateRes{OrderNo: order.OrderNo, PayUrl: payURL}, nil
return service.PaymentOrderService.CreateMemberOrder(ctx, commonHttp.GetUserId(g.RequestFromCtx(ctx)), req.PlanId)
}
// OrderStatus 订单状态(App 轮询)
func (c *member) OrderStatus(ctx context.Context, req *dto.MemberOrderStatusReq) (res *dto.MemberOrderStatusRes, err error) {
order, err := service.PaymentOrderService.OrderStatus(ctx, req.OrderNo)
if err != nil || order == nil {
return nil, errors.New("订单不存在")
}
paidAt := ""
if order.PaidAt != nil {
paidAt = order.PaidAt.Format("Y-m-d H:i:s")
}
return &dto.MemberOrderStatusRes{Status: order.Status, TradeNo: order.TradeNo, PaidAt: paidAt}, nil
return service.PaymentOrderService.OrderStatus(ctx, req.OrderNo)
}
// MemberNotify 虎皮棋支付回调:验签幂等开通 → 返回裸文本 "success"
// 虎皮棋要求回调响应体为字面 "success"不走统一 JSON 包装main.go 手动绑定
func MemberNotify(r *ghttp.Request) {
ctx := r.Context()
// Notify 虎皮棋支付回调:验签/幂等开通在 service,此处仅做 HTTP 协议职责——读取回调参数、
// 直接写裸文本响应体(虎皮棋要求字面 "success",不走统一 JSON 包装,属"直接写响应体"例外
func (c *member) Notify(ctx context.Context, req *dto.MemberNotifyReq) (res *dto.MemberNotifyRes, err error) {
r := g.RequestFromCtx(ctx)
body := r.GetBodyString()
hash := r.Get("hash").String()
orderNo := r.Get("trade_order_id").String()
remoteIP := r.GetClientIp()
params := make(map[string]string)
for k, v := range r.GetRequestMap() {
params[k] = fmt.Sprint(v)
}
ok := service.PaymentOrderService.VerifyNotify(params, hash, g.Cfg().MustGet(ctx, "payment.xunhu_appsecret", "").String())
text := service.PaymentOrderService.HandleNotify(ctx, params, body, remoteIP)
if !ok {
if err := service.PayNotifyLogService.Insert(ctx, orderNo, body, hash, remoteIP, "bad_sign"); err != nil {
g.Log().Warningf(ctx, "写入支付回调日志失败(bad_sign: %v", err)
}
r.Response.Write("fail")
r.ExitAll()
return
}
state, err := service.PaymentOrderService.HandlePaidNotify(ctx, orderNo, r.Get("transaction_id").String(), body)
if logErr := service.PayNotifyLogService.Insert(ctx, orderNo, body, hash, remoteIP, state); logErr != nil {
g.Log().Warningf(ctx, "写入支付回调日志失败: %v", logErr)
}
// duplicate(幂等重复回调)同样返回 success,避免支付渠道无限重试
if err != nil || state == "no_order" {
r.Response.Write("fail")
r.ExitAll()
return
}
r.Response.Write("success")
r.Response.Write(text)
r.ExitAll()
return nil, nil
}
@@ -1,4 +0,0 @@
package controller
// plan_effect_image 表控制器:无独立路由 handler,逻辑归属 outfit/* 簇
// (效果图由选定主方案后异步生成,经 /outfit/plan/detail 返回)
@@ -1,4 +0,0 @@
package controller
// plan_outfit_item 表控制器:无独立路由 handler,逻辑归属 outfit/* 簇
// (方案条目数据由 /outfit/plan/detail 承载)
@@ -11,9 +11,6 @@ import (
)
// Review 方案反馈
func (c *outfit) Review(ctx context.Context, req *dto.OutfitReviewReq) (res *struct{}, err error) {
if err = service.PlanReviewService.Review(ctx, common.GetUserId(g.RequestFromCtx(ctx)), req.PlanId, req.Action, req.Note); err != nil {
return nil, err
}
return &struct{}{}, nil
func (c *outfit) Review(ctx context.Context, req *dto.OutfitReviewReq) (res *dto.OutfitReviewRes, err error) {
return service.PlanReviewService.Review(ctx, common.GetUserId(g.RequestFromCtx(ctx)), req)
}
@@ -2,7 +2,6 @@ package controller
import (
"context"
"errors"
"slogan-agent/common"
"slogan-agent/styleagent/model/dto"
@@ -13,23 +12,10 @@ import (
// PlanRecommend 方案驱动推荐(发型/买同款/到店试穿/场合)
func (c *cps) PlanRecommend(ctx context.Context, req *dto.CpsPlanRecommendReq) (res *dto.CpsPlanRecommendRes, err error) {
userId := common.GetUserId(g.RequestFromCtx(ctx))
plan, err := service.OutfitPlanService.GetPlan(ctx, userId, req.PlanId)
if err != nil || plan == nil {
return nil, errors.New("方案不存在")
}
list, err := service.SceneCategoryMapService.Recommend(ctx, plan, req.Scene)
if err != nil {
return nil, err
}
return &dto.CpsPlanRecommendRes{List: list}, nil
return service.SceneCategoryMapService.PlanRecommend(ctx, common.GetUserId(g.RequestFromCtx(ctx)), req)
}
// WardrobeUpgrade 衣橱升级款
func (c *cps) WardrobeUpgrade(ctx context.Context, req *dto.CpsWardrobeUpgradeReq) (res *dto.CpsWardrobeUpgradeRes, err error) {
list, err := service.SceneCategoryMapService.WardrobeUpgrade(ctx, common.GetUserId(g.RequestFromCtx(ctx)), req.ItemId)
if err != nil {
return nil, err
}
return &dto.CpsWardrobeUpgradeRes{List: list}, nil
return service.SceneCategoryMapService.WardrobeUpgrade(ctx, common.GetUserId(g.RequestFromCtx(ctx)), req)
}
@@ -1,3 +0,0 @@
package controller
// scoring_rule 表控制器:无独立路由 handler,规则在服务端读取(评分阈值/效果图额度)
@@ -4,7 +4,6 @@ import (
"context"
"slogan-agent/common"
"slogan-agent/styleagent/dao"
"slogan-agent/styleagent/model/dto"
"slogan-agent/styleagent/service"
@@ -15,33 +14,18 @@ type user struct{}
var User = new(user)
func (c *user) Register(ctx context.Context, req *dto.RegisterReq) (res *struct{}, err error) {
_, err = service.UserService.Register(ctx, req.Account, req.Password, req.Name)
if err != nil {
return nil, err
}
return &struct{}{}, nil
func (c *user) Register(ctx context.Context, req *dto.RegisterReq) (res *dto.RegisterRes, err error) {
return service.UserService.Register(ctx, req)
}
func (c *user) Login(ctx context.Context, req *dto.LoginReq) (res *dto.LoginRes, err error) {
user, token, err := service.UserService.Login(ctx, req.Account, req.Password)
if err != nil {
return nil, err
}
return &dto.LoginRes{
Token: token,
User: &dto.LoginUser{Id: user.Id, Role: user.Role, Name: user.Name},
}, nil
return service.UserService.Login(ctx, req)
}
func (c *user) ChangePassword(ctx context.Context, req *dto.ChangePasswordReq) (res *struct{}, err error) {
return nil, service.UserService.ChangePassword(ctx, common.GetUserId(g.RequestFromCtx(ctx)), req.OldPassword, req.NewPassword)
func (c *user) ChangePassword(ctx context.Context, req *dto.ChangePasswordReq) (res *dto.ChangePasswordRes, err error) {
return service.UserService.ChangePassword(ctx, common.GetUserId(g.RequestFromCtx(ctx)), req)
}
func (c *user) Profile(ctx context.Context, req *dto.ProfileReq) (res *dto.ProfileRes, err error) {
user, err := dao.User.GetOne(ctx, common.GetUserId(g.RequestFromCtx(ctx)))
if err != nil || user == nil {
return nil, err
}
return &dto.ProfileRes{Id: user.Id, Role: user.Role, Name: user.Name, Username: user.Username, Phone: user.Phone}, nil
return service.UserService.Profile(ctx, common.GetUserId(g.RequestFromCtx(ctx)))
}
@@ -1,4 +0,0 @@
package controller
// user_member 表控制器:无独立路由 handler(会员状态经 /member/status 返回,
// 开通由支付回调与广告激励写入)
@@ -15,24 +15,13 @@ type user_photo struct{}
var UserPhoto = new(user_photo)
func (c *user_photo) Upload(ctx context.Context, req *dto.UserPhotoUploadReq) (res *dto.UserPhotoUploadRes, err error) {
id, err := service.UserPhotoService.Upload(ctx, common.GetUserId(g.RequestFromCtx(ctx)), req.Type, g.RequestFromCtx(ctx).GetUploadFile("file"))
if err != nil {
return nil, err
}
return &dto.UserPhotoUploadRes{Id: id}, nil
return service.UserPhotoService.Upload(ctx, common.GetUserId(g.RequestFromCtx(ctx)), req, g.RequestFromCtx(ctx).GetUploadFile("file"))
}
func (c *user_photo) List(ctx context.Context, req *dto.UserPhotoListReq) (res *dto.UserPhotoListRes, err error) {
list, err := service.UserPhotoService.List(ctx, common.GetUserId(g.RequestFromCtx(ctx)), req.Type)
if err != nil {
return nil, err
}
return &dto.UserPhotoListRes{List: list}, nil
return service.UserPhotoService.List(ctx, common.GetUserId(g.RequestFromCtx(ctx)), req.Type)
}
func (c *user_photo) Delete(ctx context.Context, req *dto.UserPhotoDeleteReq) (res *struct{}, err error) {
if err := service.UserPhotoService.Delete(ctx, common.GetUserId(g.RequestFromCtx(ctx)), req.Id); err != nil {
return nil, err
}
return &struct{}{}, nil
func (c *user_photo) Delete(ctx context.Context, req *dto.UserPhotoDeleteReq) (res *dto.UserPhotoDeleteRes, err error) {
return service.UserPhotoService.Delete(ctx, common.GetUserId(g.RequestFromCtx(ctx)), req.Id)
}
@@ -5,7 +5,6 @@ import (
"slogan-agent/common"
"slogan-agent/styleagent/model/dto"
"slogan-agent/styleagent/model/entity"
"slogan-agent/styleagent/service"
"github.com/gogf/gf/v2/frame/g"
@@ -16,46 +15,17 @@ type wardrobe struct{}
var Wardrobe = new(wardrobe)
func (c *wardrobe) Upload(ctx context.Context, req *dto.WardrobeUploadReq) (res *dto.WardrobeUploadRes, err error) {
id, err := service.WardrobeService.Upload(ctx, common.GetUserId(g.RequestFromCtx(ctx)), entity.WardrobeItem{
Category: req.Category,
Season: req.Season,
StyleTags: req.StyleTags,
ColorInfo: req.ColorInfo,
}, g.RequestFromCtx(ctx).GetUploadFile("file"))
if err != nil {
return nil, err
}
return &dto.WardrobeUploadRes{Id: id}, nil
return service.WardrobeService.Upload(ctx, common.GetUserId(g.RequestFromCtx(ctx)), req, g.RequestFromCtx(ctx).GetUploadFile("file"))
}
func (c *wardrobe) List(ctx context.Context, req *dto.WardrobeListReq) (res *dto.WardrobeListRes, err error) {
list, err := service.WardrobeService.List(ctx, common.GetUserId(g.RequestFromCtx(ctx)), req.Category)
if err != nil {
return nil, err
}
return &dto.WardrobeListRes{List: list}, nil
return service.WardrobeService.List(ctx, common.GetUserId(g.RequestFromCtx(ctx)), req.Category)
}
func (c *wardrobe) Update(ctx context.Context, req *dto.WardrobeUpdateReq) (res *struct{}, err error) {
data := map[string]any{}
if req.Category != "" {
data["category"] = req.Category
}
if req.Season != "" {
data["season"] = req.Season
}
if req.StyleTags != "" {
data["style_tags"] = req.StyleTags
}
if err := service.WardrobeService.Update(ctx, common.GetUserId(g.RequestFromCtx(ctx)), req.Id, data); err != nil {
return nil, err
}
return &struct{}{}, nil
func (c *wardrobe) Update(ctx context.Context, req *dto.WardrobeUpdateReq) (res *dto.WardrobeUpdateRes, err error) {
return service.WardrobeService.Update(ctx, common.GetUserId(g.RequestFromCtx(ctx)), req)
}
func (c *wardrobe) Delete(ctx context.Context, req *dto.WardrobeDeleteReq) (res *struct{}, err error) {
if err := service.WardrobeService.Delete(ctx, common.GetUserId(g.RequestFromCtx(ctx)), req.Id); err != nil {
return nil, err
}
return &struct{}{}, nil
func (c *wardrobe) Delete(ctx context.Context, req *dto.WardrobeDeleteReq) (res *dto.WardrobeDeleteRes, err error) {
return service.WardrobeService.Delete(ctx, common.GetUserId(g.RequestFromCtx(ctx)), req.Id)
}