diff --git a/bff/etc/product.pb b/bff/etc/product.pb index 3c80fbe..8d99a51 100644 Binary files a/bff/etc/product.pb and b/bff/etc/product.pb differ diff --git a/product/internal/apply/apply.go b/product/internal/apply/apply.go new file mode 100644 index 0000000..c171e91 --- /dev/null +++ b/product/internal/apply/apply.go @@ -0,0 +1,211 @@ +package apply + +import ( + "context" + "encoding/json" + "strconv" + "time" + + "product/internal/dao" + "product/internal/model" + "product/internal/wecom" + + "pkg.local/log" + "pkg.local/redis" + "pkg.local/utils" +) + +const ( + applyProductEditKey = "apply:edit:product:" + applyEditTimeOut = 60 * 24 // 分钟 + applyMd5Key = "keys:" +) + +// Data Redis 中的编辑申请状态 +type Data struct { + Uid int `json:"uid"` + Id int `json:"id"` + Reason string `json:"reason"` + Status uint8 `json:"status"` // 9待审 1通过 2驳回 0未申请 + Time string `json:"time"` + Type uint8 `json:"type"` +} + +func redisKey(uId, objId int) string { + return applyProductEditKey + strconv.Itoa(uId) + "_" + strconv.Itoa(objId) +} + +func md5MapKey(md5 string) string { + return applyProductEditKey + applyMd5Key + md5 +} + +// Get 读取申请状态 +func Get(ctx context.Context, uId, objId int) (Data, error) { + var data Data + if redis.Client == nil { + return data, nil + } + result, err := redis.Client.Get(ctx, redisKey(uId, objId)).Result() + if err == redis.Nil { + return data, nil + } + if err != nil { + return data, err + } + if len(result) < utils.NumberFive { + return data, nil + } + if err = json.Unmarshal([]byte(result), &data); err != nil { + return data, err + } + return data, nil +} + +// Del 删除申请缓存(编辑成功后清除) +func Del(ctx context.Context, uId, objId int) error { + if redis.Client == nil { + return nil + } + return redis.Client.Del(ctx, redisKey(uId, objId)).Err() +} + +// Set 发起编辑申请:写 Redis + action_apply_log,企微消息预留 +func Set(ctx context.Context, uId, objId int, reason string) error { + data := Data{ + Uid: uId, + Id: objId, + Reason: reason, + Status: dao.ApplyStatusWaitPass, + Type: dao.EditLogTypeProduct, + Time: time.Now().Format(time.DateTime), + } + + md5, err := saveRedis(ctx, &data) + if err != nil { + return err + } + + add := dao.ActionApplyLogCreate{ + AdminId: uId, + ObjId: objId, + Type: dao.EditLogTypeProduct, + Reason: reason, + Status: dao.ApplyStatusWaitPass, + } + err = model.ActionApplyLogModel{}.Init().Create(&add) + if err != nil { + _ = Del(ctx, uId, objId) + log.Errorf("action apply log create: %v", err) + return err + } + + wecom.NotifyProduct(wecom.NotifyJob{ + ObjId: objId, + ObjType: dao.EditLogTypeProduct, + Type: wecom.ProductApplyReview, + Reason: reason, + Key: md5, + }) + return nil +} + +func saveRedis(ctx context.Context, data *Data) (string, error) { + if redis.Client == nil { + return "", nil + } + key := redisKey(data.Uid, data.Id) + md5 := utils.MD5Encrypt(strconv.Itoa(data.Uid) + strconv.Itoa(data.Id) + data.Time) + payload, err := json.Marshal(data) + if err != nil { + return md5, err + } + expire := time.Duration(applyEditTimeOut) * time.Minute + if err = redis.Client.Set(ctx, key, string(payload), expire).Err(); err != nil { + return md5, err + } + if data.Status == dao.ApplyStatusWaitPass { + if err = redis.Client.Set(ctx, md5MapKey(md5), key, expire).Err(); err != nil { + return md5, err + } + } + return md5, nil +} + +// CanEdit 是否已获编辑权限(申请通过) +func CanEdit(ctx context.Context, uId, objId int) bool { + data, err := Get(ctx, uId, objId) + if err != nil { + log.Errorf("apply get: %v", err) + return false + } + return data.Status == dao.ApplyStatusDone +} + +// Pass 临时:将编辑申请置为通过(企微审批对接后删除) +func Pass(ctx context.Context, uId, objId int) error { + data, err := Get(ctx, uId, objId) + if err != nil { + return err + } + if data.Status == dao.ApplyStatusDone { + return nil + } + if data.Status != dao.ApplyStatusWaitPass && data.Status != 0 { + return errAlreadyHandled + } + + reason := data.Reason + if data.Status == 0 { + data = Data{ + Uid: uId, + Id: objId, + Reason: "临时通过", + Type: dao.EditLogTypeProduct, + Time: time.Now().Format(time.DateTime), + } + reason = data.Reason + } + data.Status = dao.ApplyStatusDone + if data.Time == "" { + data.Time = time.Now().Format(time.DateTime) + } + + if _, err = saveRedis(ctx, &data); err != nil { + return err + } + + add := dao.ActionApplyLogCreate{ + AdminId: uId, + ObjId: objId, + Type: dao.EditLogTypeProduct, + Reason: reason, + Status: dao.ApplyStatusDone, + } + err = model.ActionApplyLogModel{}.Init().Create(&add) + if err != nil { + log.Errorf("action apply log pass: %v", err) + return err + } + + wecom.NotifyProduct(wecom.NotifyJob{ + ObjId: objId, + ObjType: dao.EditLogTypeProduct, + Type: wecom.ProductNeedReview, + Action: dao.ApplyStatusDone, + Reason: reason, + }) + return nil +} + +// errAlreadyHandled 申请已驳回等不可再通过 +var errAlreadyHandled = errApply("申请状态不可通过") + +type errApply string + +func (e errApply) Error() string { return string(e) } + +// IsAlreadyHandled 是否为「状态不可通过」 +func IsAlreadyHandled(err error) bool { + _, ok := err.(errApply) + return ok +} diff --git a/product/internal/dao/edit.go b/product/internal/dao/edit.go new file mode 100644 index 0000000..31d296c --- /dev/null +++ b/product/internal/dao/edit.go @@ -0,0 +1,34 @@ +package dao + +// 编辑日志对象类型 +const ( + EditLogTypeProduct uint8 = 1 // 产品 + EditLogTypeStore uint8 = 2 // 门店 + EditLogTypeAddress uint8 = 3 // 地址 + EditLogTypeSales uint8 = 4 // 销售 +) + +// 编辑申请状态(Redis / action_apply_log) +const ( + ApplyStatusDone uint8 = 1 // 通过,可编辑 + ApplyStatusNotPass uint8 = 2 // 驳回 + ApplyStatusWaitPass uint8 = 9 // 待审核 +) + +type EditLogCreate struct { + Id int `gorm:"column:id;primaryKey;autoIncrement"` + ObjId int `gorm:"column:obj_id"` + ObjType uint8 `gorm:"column:obj_type"` + Content string `gorm:"column:content"` + AdminId int `gorm:"column:admin_id"` + AdminName string `gorm:"column:admin_name"` +} + +type ActionApplyLogCreate struct { + Id int `gorm:"column:id;primaryKey;autoIncrement"` + AdminId int `gorm:"column:admin_id"` + ObjId int `gorm:"column:obj_id"` + Type uint8 `gorm:"column:type"` + Reason string `gorm:"column:reason"` + Status uint8 `gorm:"column:status"` +} diff --git a/product/internal/dao/product.go b/product/internal/dao/product.go index c3fea9b..15f6053 100644 --- a/product/internal/dao/product.go +++ b/product/internal/dao/product.go @@ -130,22 +130,44 @@ type ProductVerify struct { } type ProductEditBase struct { - Id int `gorm:"column:id;primaryKey"` - Name string `gorm:"column:name"` - Subhead string `gorm:"column:subhead"` - Content string `gorm:"column:content"` - Images string `gorm:"column:images"` - Weight float32 `gorm:"column:weight"` - Cubage string `gorm:"column:cubage"` - Waybill string `gorm:"column:waybill"` - Label string `gorm:"column:label"` - IsIndex uint8 `gorm:"column:is_index"` - IndexImage string `gorm:"column:index_image"` - PeriodValidity int16 `gorm:"column:period_validity"` - IsBuy uint8 `gorm:"column:is_buy"` - PublishTime time.Time `gorm:"column:publish_time"` - AdminName string `gorm:"column:admin_name"` - AdminId int `gorm:"column:admin_id"` + Id int `gorm:"column:id;primaryKey" json:"id"` + Name string `gorm:"column:name" json:"name"` + Subhead string `gorm:"column:subhead" json:"subhead"` + Content string `gorm:"column:content" json:"content"` + Images string `gorm:"column:images" json:"images"` + Weight float32 `gorm:"column:weight" json:"weight"` + Cubage string `gorm:"column:cubage" json:"cubage"` + Waybill string `gorm:"column:waybill" json:"waybill"` + Label string `gorm:"column:label" json:"label"` + IsIndex uint8 `gorm:"column:is_index" json:"is_index"` + IndexImage string `gorm:"column:index_image" json:"index_image"` + PeriodValidity int16 `gorm:"column:period_validity" json:"period_validity"` + IsBuy uint8 `gorm:"column:is_buy" json:"is_buy"` + PublishTime time.Time `gorm:"column:publish_time" json:"publish_time"` + AdminName string `gorm:"column:admin_name" json:"admin_name"` + AdminId int `gorm:"column:admin_id" json:"admin_id"` +} + +// ProductEditSusceptible 敏感字段(查询旧值 / 写入 verify 快照) +type ProductEditSusceptible struct { + Id int `gorm:"column:id" json:"id"` + ModelCode string `gorm:"column:model_code" json:"model_code"` + Price float32 `gorm:"column:price" json:"price"` + StorePrice float32 `gorm:"column:store_price" json:"store_price"` + SalePrice float32 `gorm:"column:sale_price" json:"sale_price"` + SharePrice float32 `gorm:"column:share_price" json:"share_price"` + AgentPrice float32 `gorm:"column:agent_price" json:"agent_price"` + SaleReward string `gorm:"column:sale_reward" json:"sale_reward"` + BoxNumber float64 `gorm:"column:box_number" json:"box_number"` + Type uint8 `gorm:"column:type" json:"type"` + NormsNumber uint8 `gorm:"column:norms_number" json:"norms_number"` + AdminName string `gorm:"column:admin_name" json:"admin_name"` + AdminId int `gorm:"column:admin_id" json:"admin_id"` +} + +// ProductVerifyFirstEditStatus 敏感编辑提交后置为一审中 +type ProductVerifyFirstEditStatus struct { + VerifyStatus uint8 `gorm:"column:verify_status"` } // ProductInfo 列表/详情查询投影 @@ -206,3 +228,54 @@ type ProductSort struct { AdminName string `gorm:"column:admin_name" json:"admin_name"` AdminId int `gorm:"column:admin_id" json:"admin_id"` } + +// ProductVerifyListRow 审核列表产品侧字段 +type ProductVerifyListRow struct { + Id int `gorm:"column:id"` + Name string `gorm:"column:name"` + ModelCode string `gorm:"column:model_code"` + Price float32 `gorm:"column:price"` + StorePrice float32 `gorm:"column:store_price"` + SalePrice float32 `gorm:"column:sale_price"` + SharePrice float32 `gorm:"column:share_price"` + AgentPrice float32 `gorm:"column:agent_price"` + SaleReward string `gorm:"column:sale_reward"` + SalesModel uint8 `gorm:"column:sales_model"` + Type uint8 `gorm:"column:type"` + NormsNumber uint8 `gorm:"column:norms_number"` + BoxNumber float64 `gorm:"column:box_number"` +} + +// ProductVerifyFirstStatus 一审后回写产品审核状态 +type ProductVerifyFirstStatus struct { + VerifyStatus uint8 `gorm:"column:verify_status"` + VerifyId int `gorm:"column:verify_id"` + VerifyName string `gorm:"column:verify_name"` + Reason string `gorm:"column:reason"` +} + +// ProductVerifySecondStatus 二审驳回回写 +type ProductVerifySecondStatus struct { + VerifyStatus uint8 `gorm:"column:verify_status"` + VerifySecondId int `gorm:"column:verify_second_id"` + VerifySecondName string `gorm:"column:verify_second_name"` + Reason string `gorm:"column:reason"` +} + +// ProductVerifySecondOkStatus 二审通过:应用快照并回写审核人 +type ProductVerifySecondOkStatus struct { + ModelCode string `gorm:"column:model_code"` + Price float32 `gorm:"column:price"` + StorePrice float32 `gorm:"column:store_price"` + SalePrice float32 `gorm:"column:sale_price"` + SharePrice float32 `gorm:"column:share_price"` + AgentPrice float32 `gorm:"column:agent_price"` + SaleReward string `gorm:"column:sale_reward"` + Type uint8 `gorm:"column:type"` + NormsNumber uint8 `gorm:"column:norms_number"` + BoxNumber float64 `gorm:"column:box_number"` + VerifyStatus uint8 `gorm:"column:verify_status"` + VerifySecondId int `gorm:"column:verify_second_id"` + VerifySecondName string `gorm:"column:verify_second_name"` + Reason string `gorm:"column:reason"` +} diff --git a/product/internal/dao/verify.go b/product/internal/dao/verify.go index 8b5ff32..b6f9aa0 100644 --- a/product/internal/dao/verify.go +++ b/product/internal/dao/verify.go @@ -11,6 +11,18 @@ const ( VerifyTypeRefund uint8 = 5 // 退款 ) +// 审核操作结果(请求 status) +const ( + VerifyActionPass uint8 = 1 // 通过 + VerifyActionReject uint8 = 2 // 驳回 +) + +// 审核列表筛选(请求 status) +const ( + VerifyListFirst uint8 = 1 // 一审列表 + VerifyListSecond uint8 = 2 // 二审列表 +) + // Verify 审核表完整字段映射 type Verify struct { Id int `gorm:"column:id;primaryKey;autoIncrement"` @@ -33,3 +45,44 @@ type VerifyCreate struct { Content string `gorm:"column:content"` Type uint8 `gorm:"column:type"` } + +// VerifyInfo 审核列表关联查询 +type VerifyInfo struct { + Id int `gorm:"column:id"` + VerifyId string `gorm:"column:verify_id"` + Content string `gorm:"column:content"` + VerifyStatus uint8 `gorm:"column:verify_status"` + Type uint8 `gorm:"column:type"` +} + +// VerifyStatusRow 审核操作加载行 +type VerifyStatusRow struct { + Id int `gorm:"column:id"` + VerifyId string `gorm:"column:verify_id"` + AdminId int `gorm:"column:admin_id"` + AdminName string `gorm:"column:admin_name"` + AdminSecondId int `gorm:"column:admin_second_id"` + AdminSecondName string `gorm:"column:admin_second_name"` + Content string `gorm:"column:content"` + VerifyStatus uint8 `gorm:"column:verify_status"` + VerifyReason string `gorm:"column:verify_reason"` + VerifyTime time.Time `gorm:"column:verify_time"` +} + +// VerifyFirstUpdate 一审回写审核表 +type VerifyFirstUpdate struct { + AdminId int `gorm:"column:admin_id"` + AdminName string `gorm:"column:admin_name"` + VerifyStatus uint8 `gorm:"column:verify_status"` + VerifyReason string `gorm:"column:verify_reason"` + VerifyTime time.Time `gorm:"column:verify_time"` +} + +// VerifySecondUpdate 二审回写审核表 +type VerifySecondUpdate struct { + AdminSecondId int `gorm:"column:admin_second_id"` + AdminSecondName string `gorm:"column:admin_second_name"` + VerifyStatus uint8 `gorm:"column:verify_status"` + VerifyReason string `gorm:"column:verify_reason"` + VerifyTime time.Time `gorm:"column:verify_time"` +} diff --git a/product/internal/logic/editapplylogic.go b/product/internal/logic/editapplylogic.go new file mode 100644 index 0000000..515041a --- /dev/null +++ b/product/internal/logic/editapplylogic.go @@ -0,0 +1,105 @@ +package logic + +import ( + "context" + "strconv" + + "product/internal/apply" + "product/internal/dao" + "product/internal/model" + "product/internal/svc" + "product/product" + "product/validator" + + "pkg.local/log" + "pkg.local/modelbase" + "pkg.local/utils" + validateService "pkg.local/validate" + + "github.com/zeromicro/go-zero/core/logx" +) + +type EditApplyLogic struct { + ctx context.Context + svcCtx *svc.ServiceContext + logx.Logger +} + +func NewEditApplyLogic(ctx context.Context, svcCtx *svc.ServiceContext) *EditApplyLogic { + return &EditApplyLogic{ + ctx: ctx, + svcCtx: svcCtx, + Logger: logx.WithContext(ctx), + } +} + +func (l *EditApplyLogic) EditApply(in *product.EditApplyReq) (*product.Response, error) { + var req validator.ProductEditApplyValidator + if msg := validateService.ValidateFromProto(in, &req); msg != utils.StringEmpty { + return outResponse(utils.ErrorParams, msg), nil + } + + var exist dao.ProductCheckExist + err := model.ProductModel{}.Init().GetOne(modelbase.Params{ + Eq: map[string]string{"id": strconv.FormatInt(req.Id, 10)}, + }, &exist) + if err != nil { + log.Errorf("edit apply product get: %v", err) + return failResponse(utils.Fail), nil + } + if exist.Id < 1 { + return failResponse(utils.ErrorNotFund), nil + } + + // 管理员信息后续从 ctx / metadata 取 + adminId := 0 + + info, err := apply.Get(l.ctx, adminId, int(req.Id)) + if err != nil { + log.Errorf("edit apply get: %v", err) + return failResponse(utils.Fail), nil + } + if info.Status == dao.ApplyStatusWaitPass || info.Status == dao.ApplyStatusDone { + return outResponse(utils.Fail, "已经申请过"), nil + } + + if err = apply.Set(l.ctx, adminId, int(req.Id), req.Reason); err != nil { + log.Errorf("edit apply set: %v", err) + return failResponse(utils.Fail), nil + } + + return okResponse(utils.StringEmpty), nil +} + +// EditApplyPass TODO: 临时接口,企微编辑申请审批对接后删除 +func (l *EditApplyLogic) EditApplyPass(in *product.EditApplyPassReq) (*product.Response, error) { + var req validator.ProductEditApplyPassValidator + if msg := validateService.ValidateFromProto(in, &req); msg != utils.StringEmpty { + return outResponse(utils.ErrorParams, msg), nil + } + + var exist dao.ProductCheckExist + err := model.ProductModel{}.Init().GetOne(modelbase.Params{ + Eq: map[string]string{"id": strconv.FormatInt(req.Id, 10)}, + }, &exist) + if err != nil { + log.Errorf("edit apply pass product get: %v", err) + return failResponse(utils.Fail), nil + } + if exist.Id < 1 { + return failResponse(utils.ErrorNotFund), nil + } + + // 管理员信息后续从 ctx / metadata 取 + adminId := 0 + + if err = apply.Pass(l.ctx, adminId, int(req.Id)); err != nil { + if apply.IsAlreadyHandled(err) { + return outResponse(utils.Fail, err.Error()), nil + } + log.Errorf("edit apply pass: %v", err) + return failResponse(utils.Fail), nil + } + + return okResponse(utils.StringEmpty), nil +} diff --git a/product/internal/logic/editbaselogic.go b/product/internal/logic/editbaselogic.go new file mode 100644 index 0000000..2511673 --- /dev/null +++ b/product/internal/logic/editbaselogic.go @@ -0,0 +1,122 @@ +package logic + +import ( + "context" + "strconv" + "time" + + "product/internal/apply" + "product/internal/dao" + "product/internal/model" + "product/internal/svc" + "product/internal/wecom" + "product/product" + "product/validator" + + "pkg.local/log" + "pkg.local/modelbase" + "pkg.local/utils" + validateService "pkg.local/validate" + + "github.com/zeromicro/go-zero/core/logx" +) + +type EditBaseLogic struct { + ctx context.Context + svcCtx *svc.ServiceContext + logx.Logger +} + +func NewEditBaseLogic(ctx context.Context, svcCtx *svc.ServiceContext) *EditBaseLogic { + return &EditBaseLogic{ + ctx: ctx, + svcCtx: svcCtx, + Logger: logx.WithContext(ctx), + } +} + +func (l *EditBaseLogic) EditBase(in *product.EditBaseReq) (*product.Response, error) { + var req validator.ProductEditBaseValidator + if msg := validateService.ValidateFromProto(in, &req); msg != utils.StringEmpty { + return outResponse(utils.ErrorParams, msg), nil + } + + // 管理员信息后续从 ctx / metadata 取 + adminId := 0 + adminName := "" + + if !apply.CanEdit(l.ctx, adminId, int(req.Id)) { + return failErr(utils.ErrorAuthority), nil + } + + w := modelbase.Params{Eq: map[string]string{"id": strconv.FormatInt(req.Id, 10)}} + var old dao.ProductEditBase + m := model.ProductModel{}.Init() + err := m.GetOne(w, &old) + if err != nil { + log.Errorf("edit base get: %v", err) + return failResponse(utils.Fail), nil + } + if old.Id < 1 { + return failResponse(utils.ErrorNotFund), nil + } + + var nameCheck dao.ProductCheckExist + err = m.GetOne(modelbase.Params{Eq: map[string]string{"name": req.Name}}, &nameCheck) + if err != nil { + log.Errorf("edit base name check: %v", err) + return failResponse(utils.Fail), nil + } + if nameCheck.Id > 0 && nameCheck.Id != int(req.Id) { + return failErr(utils.ErrorDataIsExist), nil + } + + publishTime := time.Now() + if len(req.PublishTime) > 1 { + t, err := parsePublishTime(req.PublishTime) + if err != nil { + return outResponse(utils.ErrorParams, "时间错误"), nil + } + publishTime = t + } + + data := dao.ProductEditBase{ + Id: old.Id, + Name: req.Name, + Subhead: req.Subhead, + Content: req.Content, + Images: req.Images, + PeriodValidity: int16(req.PeriodValidity), + Waybill: req.Waybill, + Weight: float32(req.Weight), + Cubage: req.Cubage, + IsIndex: uint8(req.IsIndex), + IndexImage: req.IndexImage, + Label: req.Label, + PublishTime: publishTime, + AdminName: adminName, + AdminId: adminId, + IsBuy: uint8(req.IsBuy), + } + if data.IsIndex == 0 { + data.IsIndex = 2 + } + if data.IsBuy == 0 { + data.IsBuy = 2 + } + + if _, err = m.Edit(w, &data); err != nil { + log.Errorf("edit base: %v", err) + return failResponse(utils.Fail), nil + } + + addEditLog(int(req.Id), dao.EditLogTypeProduct, adminId, adminName, data, old) + wecom.NotifyProduct(wecom.NotifyJob{ + ObjId: int(req.Id), + ObjType: dao.EditLogTypeProduct, + Type: wecom.ProductOrdinaryReview, + }) + _ = apply.Del(l.ctx, adminId, int(req.Id)) + + return okResponse(utils.StringEmpty), nil +} diff --git a/product/internal/logic/editlog_helper.go b/product/internal/logic/editlog_helper.go new file mode 100644 index 0000000..4e7fb4c --- /dev/null +++ b/product/internal/logic/editlog_helper.go @@ -0,0 +1,27 @@ +package logic + +import ( + "product/internal/dao" + "product/internal/model" + + "pkg.local/log" + "pkg.local/utils" +) + +func addEditLog(objId int, objType uint8, adminId int, adminName string, data, oldData interface{}) { + content := map[string]interface{}{ + "new": data, + "old": oldData, + } + add := dao.EditLogCreate{ + ObjId: objId, + ObjType: objType, + Content: utils.StructToJson(content), + AdminId: adminId, + AdminName: adminName, + } + err := model.EditLogModel{}.Init().Create(&add) + if err != nil { + log.Errorf("edit log create: %v", err) + } +} diff --git a/product/internal/logic/editsusceptiblelogic.go b/product/internal/logic/editsusceptiblelogic.go new file mode 100644 index 0000000..89273c7 --- /dev/null +++ b/product/internal/logic/editsusceptiblelogic.go @@ -0,0 +1,130 @@ +package logic + +import ( + "context" + "encoding/json" + "strconv" + + "product/internal/apply" + "product/internal/dao" + "product/internal/model" + "product/internal/svc" + "product/internal/wecom" + "product/product" + "product/validator" + + "pkg.local/log" + "pkg.local/modelbase" + "pkg.local/utils" + validateService "pkg.local/validate" + + "github.com/zeromicro/go-zero/core/logx" + "gorm.io/gorm" +) + +type EditSusceptibleLogic struct { + ctx context.Context + svcCtx *svc.ServiceContext + logx.Logger +} + +func NewEditSusceptibleLogic(ctx context.Context, svcCtx *svc.ServiceContext) *EditSusceptibleLogic { + return &EditSusceptibleLogic{ + ctx: ctx, + svcCtx: svcCtx, + Logger: logx.WithContext(ctx), + } +} + +func (l *EditSusceptibleLogic) EditSusceptible(in *product.EditSusceptibleReq) (*product.Response, error) { + var req validator.ProductEditSusceptibleValidator + if msg := validateService.ValidateFromProto(in, &req); msg != utils.StringEmpty { + return outResponse(utils.ErrorParams, msg), nil + } + + if req.Type == dao.ProductTypeNormal { + if req.AgentPrice == 0 || req.StorePrice == 0 || + req.SalePrice == 0 || req.SharePrice == 0 || + req.SaleReward == "" { + return outResponse(utils.ErrorParams, "缺少相关价格"), nil + } + } + + // 管理员信息后续从 ctx / metadata 取 + adminId := 0 + adminName := "" + + if !apply.CanEdit(l.ctx, adminId, int(req.Id)) { + return failErr(utils.ErrorAuthority), nil + } + + w := modelbase.Params{ + Eq: map[string]string{"id": strconv.FormatInt(req.Id, 10)}, + In: map[string][]string{ + "verify_status": { + strconv.Itoa(int(dao.VerifyStatusPass)), + strconv.Itoa(int(dao.VerifyStatusRefuse)), + }, + }, + } + var old dao.ProductEditSusceptible + err := model.ProductModel{}.Init().GetOne(w, &old) + if err != nil { + log.Errorf("edit susceptible get: %v", err) + return failResponse(utils.Fail), nil + } + if old.Id < 1 { + return failResponse(utils.ErrorNotFund), nil + } + + data := dao.ProductEditSusceptible{ + Id: int(req.Id), + ModelCode: req.ModelCode, + Price: float32(req.Price), + StorePrice: float32(req.StorePrice), + SalePrice: float32(req.SalePrice), + SharePrice: float32(req.SharePrice), + AgentPrice: float32(req.AgentPrice), + SaleReward: req.SaleReward, + BoxNumber: req.BoxNumber, + Type: uint8(req.Type), + NormsNumber: uint8(req.NormsNumber), + AdminName: adminName, + AdminId: adminId, + } + + contentBytes, err := json.Marshal(data) + if err != nil { + log.Errorf("edit susceptible marshal: %v", err) + return failResponse(utils.Fail), nil + } + + err = l.svcCtx.DB.WithContext(l.ctx).Transaction(func(tx *gorm.DB) error { + pm := model.ProductModel{}.Init().WithTX(tx) + if _, err := pm.Edit(w, &dao.ProductVerifyFirstEditStatus{ + VerifyStatus: dao.VerifyStatusChecking, + }); err != nil { + return err + } + verify := dao.VerifyCreate{ + VerifyId: strconv.FormatInt(req.Id, 10), + Content: string(contentBytes), + Type: dao.VerifyTypeProduct, + } + return model.VerifyModel{}.Init().WithTX(tx).Create(&verify) + }) + if err != nil { + log.Errorf("edit susceptible tx: %v", err) + return failResponse(utils.Fail), nil + } + + addEditLog(int(req.Id), dao.EditLogTypeProduct, adminId, adminName, data, old) + wecom.NotifyProduct(wecom.NotifyJob{ + ObjId: int(req.Id), + ObjType: dao.EditLogTypeProduct, + Type: wecom.ProductSubmitReview, + }) + _ = apply.Del(l.ctx, adminId, int(req.Id)) + + return okResponse(utils.StringEmpty), nil +} diff --git a/product/internal/logic/infologic.go b/product/internal/logic/infologic.go index 72815e8..26f1bc4 100644 --- a/product/internal/logic/infologic.go +++ b/product/internal/logic/infologic.go @@ -4,6 +4,7 @@ import ( "context" "strconv" + "product/internal/apply" "product/internal/dao" "product/internal/model" "product/internal/svc" @@ -50,5 +51,11 @@ func (l *InfoLogic) Info(in *product.InfoReq) (*product.Response, error) { return failResponse(utils.ErrorNotFund), nil } + // 管理员信息后续从 ctx / metadata 取 + adminId := 0 + if applyData, err := apply.Get(l.ctx, adminId, info.Id); err == nil { + info.Edit = applyData.Status + } + return okResponse(utils.StructToJson(toProductItem(info))), nil } diff --git a/product/internal/logic/itemslogic.go b/product/internal/logic/itemslogic.go index 4f5be60..b374a46 100644 --- a/product/internal/logic/itemslogic.go +++ b/product/internal/logic/itemslogic.go @@ -3,6 +3,7 @@ package logic import ( "context" + "product/internal/apply" "product/internal/dao" "product/internal/model" "product/internal/svc" @@ -65,7 +66,12 @@ func (l *ItemsLogic) Items(in *product.ItemsReq) (*product.Response, error) { } items := make([]*product.Item, 0, len(info)) + // 管理员信息后续从 ctx / metadata 取 + adminId := 0 for _, row := range info { + if applyData, err := apply.Get(l.ctx, adminId, row.Id); err == nil { + row.Edit = applyData.Status + } items = append(items, toProductItem(row)) } diff --git a/product/internal/logic/verifylogic.go b/product/internal/logic/verifylogic.go new file mode 100644 index 0000000..9d42ce3 --- /dev/null +++ b/product/internal/logic/verifylogic.go @@ -0,0 +1,151 @@ +package logic + +import ( + "context" + "encoding/json" + "strconv" + + "product/internal/dao" + "product/internal/model" + "product/internal/svc" + "product/product" + "product/validator" + + "pkg.local/log" + "pkg.local/modelbase" + "pkg.local/utils" + validateService "pkg.local/validate" + + "github.com/zeromicro/go-zero/core/logx" +) + +type VerifyLogic struct { + ctx context.Context + svcCtx *svc.ServiceContext + logx.Logger +} + +func NewVerifyLogic(ctx context.Context, svcCtx *svc.ServiceContext) *VerifyLogic { + return &VerifyLogic{ + ctx: ctx, + svcCtx: svcCtx, + Logger: logx.WithContext(ctx), + } +} + +func (l *VerifyLogic) Verify(in *product.VerifyReq) (*product.Response, error) { + var req validator.ProductVerifyItemsValidator + if msg := validateService.ValidateFromProto(in, &req); msg != utils.StringEmpty { + return outResponse(utils.ErrorParams, msg), nil + } + + verifyStatus := dao.VerifyStatusChecking + if req.Status == uint32(dao.VerifyListSecond) { + verifyStatus = dao.VerifyStatusSecond + } + + page := int(req.Page) + size := int(req.PageSize) + if page < modelbase.DefaultPage { + page = modelbase.DefaultPage + } + if size < modelbase.DefaultPage { + size = modelbase.DefaultSize + } + + w := modelbase.Params{ + Eq: map[string]string{"verify_status": strconv.Itoa(int(verifyStatus))}, + Page: page, + Size: size, + Order: "id desc", + } + + var rows []dao.ProductVerifyListRow + result, err := model.ProductModel{}.Init().Page(w, &rows) + if err != nil { + log.Errorf("product verify list: %v", err) + return failResponse(utils.Fail), nil + } + + items := make([]*product.VerifyItem, 0) + if len(rows) == 0 { + return okResponse(utils.StructToJson(&product.VerifyItemsData{ + Count: result.Count, + Items: items, + })), nil + } + + ids := make([]string, 0, len(rows)) + for _, row := range rows { + ids = append(ids, strconv.Itoa(row.Id)) + } + + ww := modelbase.Params{ + Eq: map[string]string{ + "verify_status": strconv.Itoa(int(verifyStatus)), + "type": strconv.Itoa(int(dao.VerifyTypeProduct)), + }, + In: map[string][]string{"verify_id": ids}, + } + var verifies []dao.VerifyInfo + err = model.VerifyModel{}.Init().Items(ww, &verifies) + if err != nil { + log.Errorf("verify info items: %v", err) + return failResponse(utils.Fail), nil + } + + verifyByProduct := make(map[string]dao.VerifyInfo, len(verifies)) + for _, v := range verifies { + verifyByProduct[v.VerifyId] = v + } + + for _, row := range rows { + v, ok := verifyByProduct[strconv.Itoa(row.Id)] + if !ok || len(v.Content) <= utils.NumberTen { + continue + } + var content dao.ProductVerify + err = json.Unmarshal([]byte(v.Content), &content) + if err != nil { + log.Errorf("product verify content json: %v", err) + return failErr(utils.ErrorFormatDataError), nil + } + items = append(items, &product.VerifyItem{ + Name: row.Name, + SalesModel: uint32(row.SalesModel), + New: &product.VerifyParams{ + Id: int64(row.Id), + ModelCode: content.ModelCode, + Price: float64(content.Price), + StorePrice: float64(content.StorePrice), + SalePrice: float64(content.SalePrice), + SharePrice: float64(content.SharePrice), + AgentPrice: float64(content.AgentPrice), + SaleReward: content.SaleReward, + Type: uint32(content.Type), + NormsNumber: uint32(content.NormsNumber), + BoxNumber: content.BoxNumber, + VerifyId: int64(v.Id), + }, + Old: &product.VerifyParams{ + Id: int64(row.Id), + ModelCode: row.ModelCode, + Price: float64(row.Price), + StorePrice: float64(row.StorePrice), + SalePrice: float64(row.SalePrice), + SharePrice: float64(row.SharePrice), + AgentPrice: float64(row.AgentPrice), + SaleReward: row.SaleReward, + Type: uint32(row.Type), + NormsNumber: uint32(row.NormsNumber), + BoxNumber: row.BoxNumber, + VerifyId: int64(v.Id), + }, + }) + } + + return okResponse(utils.StructToJson(&product.VerifyItemsData{ + Count: result.Count, + Items: items, + })), nil +} diff --git a/product/internal/logic/verifystatuslogic.go b/product/internal/logic/verifystatuslogic.go new file mode 100644 index 0000000..e15360a --- /dev/null +++ b/product/internal/logic/verifystatuslogic.go @@ -0,0 +1,194 @@ +package logic + +import ( + "context" + "encoding/json" + "strconv" + "time" + + "product/internal/dao" + "product/internal/model" + "product/internal/svc" + "product/internal/wecom" + "product/product" + "product/validator" + + "pkg.local/log" + "pkg.local/modelbase" + "pkg.local/utils" + validateService "pkg.local/validate" + + "github.com/zeromicro/go-zero/core/logx" + "gorm.io/gorm" +) + +type VerifyStatusLogic struct { + ctx context.Context + svcCtx *svc.ServiceContext + logx.Logger +} + +func NewVerifyStatusLogic(ctx context.Context, svcCtx *svc.ServiceContext) *VerifyStatusLogic { + return &VerifyStatusLogic{ + ctx: ctx, + svcCtx: svcCtx, + Logger: logx.WithContext(ctx), + } +} + +func (l *VerifyStatusLogic) VerifyFirst(in *product.VerifyStatusReq) (*product.Response, error) { + return l.verifyStatus(dao.VerifyStatusChecking, in) +} + +func (l *VerifyStatusLogic) VerifySecond(in *product.VerifyStatusReq) (*product.Response, error) { + return l.verifyStatus(dao.VerifyStatusSecond, in) +} + +func (l *VerifyStatusLogic) verifyStatus(expectStatus uint8, in *product.VerifyStatusReq) (*product.Response, error) { + var req validator.ProductVerifyStatusValidator + if msg := validateService.ValidateFromProto(in, &req); msg != utils.StringEmpty { + return outResponse(utils.ErrorParams, msg), nil + } + + if req.Status == uint32(dao.VerifyActionReject) && len(req.Reason) < 1 { + return failErr(utils.ErrorReasonParams), nil + } + + var info dao.VerifyStatusRow + w := modelbase.Params{ + Eq: map[string]string{ + "id": strconv.FormatInt(req.Id, 10), + "verify_status": strconv.Itoa(int(expectStatus)), + }, + } + err := model.VerifyModel{}.Init().GetOne(w, &info) + if err != nil { + log.Errorf("verify status get: %v", err) + return failResponse(utils.Fail), nil + } + if info.Id < 1 { + return failResponse(utils.ErrorNotFund), nil + } + + // 管理员信息后续从 ctx / metadata 取 + adminId := 0 + adminName := "" + + nextStatus := dao.VerifyStatusPass + reason := req.Reason + if req.Status == uint32(dao.VerifyActionReject) { + nextStatus = dao.VerifyStatusRefuse + } else if expectStatus == dao.VerifyStatusChecking { + nextStatus = dao.VerifyStatusSecond + } + + productWhere := modelbase.Params{Eq: map[string]string{"id": info.VerifyId}} + var productExist dao.ProductCheckExist + err = model.ProductModel{}.Init().GetOne(productWhere, &productExist) + if err != nil { + log.Errorf("verify product get: %v", err) + return failResponse(utils.Fail), nil + } + if productExist.Id < 1 { + return outResponse(utils.ErrorNotFund, "没有找到产品信息"), nil + } + + err = l.svcCtx.DB.WithContext(l.ctx).Transaction(func(tx *gorm.DB) error { + vm := model.VerifyModel{}.Init().WithTX(tx) + pm := model.ProductModel{}.Init().WithTX(tx) + now := time.Now() + + if expectStatus == dao.VerifyStatusChecking { + if _, err := vm.Edit(w, &dao.VerifyFirstUpdate{ + AdminId: adminId, + AdminName: adminName, + VerifyStatus: nextStatus, + VerifyReason: reason, + VerifyTime: now, + }); err != nil { + return err + } + _, err := pm.Edit(productWhere, &dao.ProductVerifyFirstStatus{ + VerifyStatus: nextStatus, + VerifyId: adminId, + VerifyName: adminName, + Reason: reason, + }) + return err + } + + if _, err := vm.Edit(w, &dao.VerifySecondUpdate{ + AdminSecondId: adminId, + AdminSecondName: adminName, + VerifyStatus: nextStatus, + VerifyReason: reason, + VerifyTime: now, + }); err != nil { + return err + } + + if nextStatus == dao.VerifyStatusPass { + var content dao.ProductVerify + if err := json.Unmarshal([]byte(info.Content), &content); err != nil { + log.Errorf("product verify content json: %v content=%s", err, info.Content) + return err + } + _, err := pm.Edit(productWhere, &dao.ProductVerifySecondOkStatus{ + ModelCode: content.ModelCode, + Price: content.Price, + StorePrice: content.StorePrice, + SalePrice: content.SalePrice, + SharePrice: content.SharePrice, + AgentPrice: content.AgentPrice, + SaleReward: content.SaleReward, + Type: content.Type, + NormsNumber: content.NormsNumber, + BoxNumber: content.BoxNumber, + VerifyStatus: nextStatus, + VerifySecondId: adminId, + VerifySecondName: adminName, + Reason: reason, + }) + return err + } + + _, err := pm.Edit(productWhere, &dao.ProductVerifySecondStatus{ + VerifyStatus: nextStatus, + VerifySecondId: adminId, + VerifySecondName: adminName, + Reason: reason, + }) + return err + }) + if err != nil { + log.Errorf("verify status tx: %v", err) + if isJSONError(err) { + return failErr(utils.ErrorFormatDataError), nil + } + return failResponse(utils.Fail), nil + } + + notifyType := wecom.ProductFirstReview + if expectStatus == dao.VerifyStatusSecond { + notifyType = wecom.ProductSecondReview + } + objID, _ := strconv.Atoi(info.VerifyId) + wecom.NotifyProduct(wecom.NotifyJob{ + ObjId: objID, + ObjType: dao.VerifyTypeProduct, + Type: notifyType, + Action: uint8(req.Status), + Reason: reason, + }) + + return okResponse(utils.StringEmpty), nil +} + +func isJSONError(err error) bool { + switch err.(type) { + case *json.SyntaxError, *json.UnmarshalTypeError: + return true + default: + return false + } +} diff --git a/product/internal/model/action_apply_log_model.go b/product/internal/model/action_apply_log_model.go new file mode 100644 index 0000000..d15e194 --- /dev/null +++ b/product/internal/model/action_apply_log_model.go @@ -0,0 +1,24 @@ +package model + +import ( + "product/internal/dao" + + "pkg.local/modelbase" +) + +type ActionApplyLogModel struct { + modelbase.Base +} + +func (m ActionApplyLogModel) TableName() string { + return modelbase.Prefix() + "action_apply_log" +} + +func (m ActionApplyLogModel) Init() ActionApplyLogModel { + m.Table = m.TableName() + return m +} + +func (m ActionApplyLogModel) Create(data *dao.ActionApplyLogCreate) error { + return m.Base.Create(data) +} diff --git a/product/internal/model/edit_log_model.go b/product/internal/model/edit_log_model.go new file mode 100644 index 0000000..11ab3d8 --- /dev/null +++ b/product/internal/model/edit_log_model.go @@ -0,0 +1,24 @@ +package model + +import ( + "product/internal/dao" + + "pkg.local/modelbase" +) + +type EditLogModel struct { + modelbase.Base +} + +func (m EditLogModel) TableName() string { + return modelbase.Prefix() + "edit_log" +} + +func (m EditLogModel) Init() EditLogModel { + m.Table = m.TableName() + return m +} + +func (m EditLogModel) Create(data *dao.EditLogCreate) error { + return m.Base.Create(data) +} diff --git a/product/internal/server/productserver.go b/product/internal/server/productserver.go index ea2324d..875432b 100644 --- a/product/internal/server/productserver.go +++ b/product/internal/server/productserver.go @@ -51,3 +51,38 @@ func (s *ProductServer) Sort(ctx context.Context, in *product.SortReq) (*product l := logic.NewSortLogic(ctx, s.svcCtx) return l.Sort(in) } + +func (s *ProductServer) Verify(ctx context.Context, in *product.VerifyReq) (*product.Response, error) { + l := logic.NewVerifyLogic(ctx, s.svcCtx) + return l.Verify(in) +} + +func (s *ProductServer) VerifyFirst(ctx context.Context, in *product.VerifyStatusReq) (*product.Response, error) { + l := logic.NewVerifyStatusLogic(ctx, s.svcCtx) + return l.VerifyFirst(in) +} + +func (s *ProductServer) VerifySecond(ctx context.Context, in *product.VerifyStatusReq) (*product.Response, error) { + l := logic.NewVerifyStatusLogic(ctx, s.svcCtx) + return l.VerifySecond(in) +} + +func (s *ProductServer) EditApply(ctx context.Context, in *product.EditApplyReq) (*product.Response, error) { + l := logic.NewEditApplyLogic(ctx, s.svcCtx) + return l.EditApply(in) +} + +func (s *ProductServer) EditApplyPass(ctx context.Context, in *product.EditApplyPassReq) (*product.Response, error) { + l := logic.NewEditApplyLogic(ctx, s.svcCtx) + return l.EditApplyPass(in) +} + +func (s *ProductServer) EditBase(ctx context.Context, in *product.EditBaseReq) (*product.Response, error) { + l := logic.NewEditBaseLogic(ctx, s.svcCtx) + return l.EditBase(in) +} + +func (s *ProductServer) EditSusceptible(ctx context.Context, in *product.EditSusceptibleReq) (*product.Response, error) { + l := logic.NewEditSusceptibleLogic(ctx, s.svcCtx) + return l.EditSusceptible(in) +} diff --git a/product/internal/wecom/notify.go b/product/internal/wecom/notify.go new file mode 100644 index 0000000..15ef1cc --- /dev/null +++ b/product/internal/wecom/notify.go @@ -0,0 +1,26 @@ +package wecom + +import "pkg.local/log" + +const ( + ProductApplyReview uint8 = 1 // 编辑申请按钮卡片 + ProductNeedReview uint8 = 2 // 编辑申请结果通知申请人 + ProductSubmitReview uint8 = 3 // 提交敏感字段变更 → 通知一审 + ProductFirstReview uint8 = 4 // 一审结果通知 + ProductSecondReview uint8 = 5 // 二审结果通知 + ProductOrdinaryReview uint8 = 6 // 基础信息变更 diff 通知 +) + +type NotifyJob struct { + ObjId int + ObjType uint8 + Type uint8 + Action uint8 // 1: 通过, 2: 驳回 + Reason string + Key string // 编辑申请 Redis MD5 key,企微回调用 +} + +func NotifyProduct(job NotifyJob) { + log.Infof("wecom stub skip: type=%d objId=%d action=%d reason=%s key=%s", + job.Type, job.ObjId, job.Action, job.Reason, job.Key) +} diff --git a/product/product/product.pb.go b/product/product/product.pb.go index 0c6d0b1..91f1c4b 100644 --- a/product/product/product.pb.go +++ b/product/product/product.pb.go @@ -578,6 +578,497 @@ func (x *SortReq) GetSort() uint32 { return 0 } +// status: 1: 一审列表, 2: 二审列表 +type VerifyReq struct { + state protoimpl.MessageState `protogen:"open.v1"` + Status uint32 `protobuf:"varint,1,opt,name=status,proto3" json:"status,omitempty"` + Page uint32 `protobuf:"varint,2,opt,name=page,proto3" json:"page,omitempty"` + PageSize uint32 `protobuf:"varint,3,opt,name=page_size,json=pageSize,proto3" json:"page_size,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *VerifyReq) Reset() { + *x = VerifyReq{} + mi := &file_proto_admin_product_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *VerifyReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*VerifyReq) ProtoMessage() {} + +func (x *VerifyReq) ProtoReflect() protoreflect.Message { + mi := &file_proto_admin_product_proto_msgTypes[7] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use VerifyReq.ProtoReflect.Descriptor instead. +func (*VerifyReq) Descriptor() ([]byte, []int) { + return file_proto_admin_product_proto_rawDescGZIP(), []int{7} +} + +func (x *VerifyReq) GetStatus() uint32 { + if x != nil { + return x.Status + } + return 0 +} + +func (x *VerifyReq) GetPage() uint32 { + if x != nil { + return x.Page + } + return 0 +} + +func (x *VerifyReq) GetPageSize() uint32 { + if x != nil { + return x.PageSize + } + return 0 +} + +// id 为 verify 表主键;status: 1: 通过, 2: 驳回 +type VerifyStatusReq struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + Status uint32 `protobuf:"varint,2,opt,name=status,proto3" json:"status,omitempty"` + Reason string `protobuf:"bytes,3,opt,name=reason,proto3" json:"reason,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *VerifyStatusReq) Reset() { + *x = VerifyStatusReq{} + mi := &file_proto_admin_product_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *VerifyStatusReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*VerifyStatusReq) ProtoMessage() {} + +func (x *VerifyStatusReq) ProtoReflect() protoreflect.Message { + mi := &file_proto_admin_product_proto_msgTypes[8] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use VerifyStatusReq.ProtoReflect.Descriptor instead. +func (*VerifyStatusReq) Descriptor() ([]byte, []int) { + return file_proto_admin_product_proto_rawDescGZIP(), []int{8} +} + +func (x *VerifyStatusReq) GetId() int64 { + if x != nil { + return x.Id + } + return 0 +} + +func (x *VerifyStatusReq) GetStatus() uint32 { + if x != nil { + return x.Status + } + return 0 +} + +func (x *VerifyStatusReq) GetReason() string { + if x != nil { + return x.Reason + } + return "" +} + +type EditApplyReq struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + Reason string `protobuf:"bytes,2,opt,name=reason,proto3" json:"reason,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *EditApplyReq) Reset() { + *x = EditApplyReq{} + mi := &file_proto_admin_product_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *EditApplyReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EditApplyReq) ProtoMessage() {} + +func (x *EditApplyReq) ProtoReflect() protoreflect.Message { + mi := &file_proto_admin_product_proto_msgTypes[9] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use EditApplyReq.ProtoReflect.Descriptor instead. +func (*EditApplyReq) Descriptor() ([]byte, []int) { + return file_proto_admin_product_proto_rawDescGZIP(), []int{9} +} + +func (x *EditApplyReq) GetId() int64 { + if x != nil { + return x.Id + } + return 0 +} + +func (x *EditApplyReq) GetReason() string { + if x != nil { + return x.Reason + } + return "" +} + +// TODO: 临时,企微对接后删除 +type EditApplyPassReq struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *EditApplyPassReq) Reset() { + *x = EditApplyPassReq{} + mi := &file_proto_admin_product_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *EditApplyPassReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EditApplyPassReq) ProtoMessage() {} + +func (x *EditApplyPassReq) ProtoReflect() protoreflect.Message { + mi := &file_proto_admin_product_proto_msgTypes[10] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use EditApplyPassReq.ProtoReflect.Descriptor instead. +func (*EditApplyPassReq) Descriptor() ([]byte, []int) { + return file_proto_admin_product_proto_rawDescGZIP(), []int{10} +} + +func (x *EditApplyPassReq) GetId() int64 { + if x != nil { + return x.Id + } + return 0 +} + +type EditBaseReq struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Subhead string `protobuf:"bytes,3,opt,name=subhead,proto3" json:"subhead,omitempty"` + Content string `protobuf:"bytes,4,opt,name=content,proto3" json:"content,omitempty"` + Waybill string `protobuf:"bytes,5,opt,name=waybill,proto3" json:"waybill,omitempty"` + Weight float64 `protobuf:"fixed64,6,opt,name=weight,proto3" json:"weight,omitempty"` + Cubage string `protobuf:"bytes,7,opt,name=cubage,proto3" json:"cubage,omitempty"` + Images string `protobuf:"bytes,8,opt,name=images,proto3" json:"images,omitempty"` + PeriodValidity int32 `protobuf:"varint,9,opt,name=period_validity,json=periodValidity,proto3" json:"period_validity,omitempty"` + PublishTime string `protobuf:"bytes,10,opt,name=publish_time,json=publishTime,proto3" json:"publish_time,omitempty"` + Label string `protobuf:"bytes,11,opt,name=label,proto3" json:"label,omitempty"` + IsBuy uint32 `protobuf:"varint,12,opt,name=is_buy,json=isBuy,proto3" json:"is_buy,omitempty"` + IsIndex uint32 `protobuf:"varint,13,opt,name=is_index,json=isIndex,proto3" json:"is_index,omitempty"` + IndexImage string `protobuf:"bytes,14,opt,name=index_image,json=indexImage,proto3" json:"index_image,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *EditBaseReq) Reset() { + *x = EditBaseReq{} + mi := &file_proto_admin_product_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *EditBaseReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EditBaseReq) ProtoMessage() {} + +func (x *EditBaseReq) ProtoReflect() protoreflect.Message { + mi := &file_proto_admin_product_proto_msgTypes[11] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use EditBaseReq.ProtoReflect.Descriptor instead. +func (*EditBaseReq) Descriptor() ([]byte, []int) { + return file_proto_admin_product_proto_rawDescGZIP(), []int{11} +} + +func (x *EditBaseReq) GetId() int64 { + if x != nil { + return x.Id + } + return 0 +} + +func (x *EditBaseReq) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *EditBaseReq) GetSubhead() string { + if x != nil { + return x.Subhead + } + return "" +} + +func (x *EditBaseReq) GetContent() string { + if x != nil { + return x.Content + } + return "" +} + +func (x *EditBaseReq) GetWaybill() string { + if x != nil { + return x.Waybill + } + return "" +} + +func (x *EditBaseReq) GetWeight() float64 { + if x != nil { + return x.Weight + } + return 0 +} + +func (x *EditBaseReq) GetCubage() string { + if x != nil { + return x.Cubage + } + return "" +} + +func (x *EditBaseReq) GetImages() string { + if x != nil { + return x.Images + } + return "" +} + +func (x *EditBaseReq) GetPeriodValidity() int32 { + if x != nil { + return x.PeriodValidity + } + return 0 +} + +func (x *EditBaseReq) GetPublishTime() string { + if x != nil { + return x.PublishTime + } + return "" +} + +func (x *EditBaseReq) GetLabel() string { + if x != nil { + return x.Label + } + return "" +} + +func (x *EditBaseReq) GetIsBuy() uint32 { + if x != nil { + return x.IsBuy + } + return 0 +} + +func (x *EditBaseReq) GetIsIndex() uint32 { + if x != nil { + return x.IsIndex + } + return 0 +} + +func (x *EditBaseReq) GetIndexImage() string { + if x != nil { + return x.IndexImage + } + return "" +} + +type EditSusceptibleReq struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + ModelCode string `protobuf:"bytes,2,opt,name=model_code,json=modelCode,proto3" json:"model_code,omitempty"` + Price float64 `protobuf:"fixed64,3,opt,name=price,proto3" json:"price,omitempty"` + StorePrice float64 `protobuf:"fixed64,4,opt,name=store_price,json=storePrice,proto3" json:"store_price,omitempty"` + SalePrice float64 `protobuf:"fixed64,5,opt,name=sale_price,json=salePrice,proto3" json:"sale_price,omitempty"` + SharePrice float64 `protobuf:"fixed64,6,opt,name=share_price,json=sharePrice,proto3" json:"share_price,omitempty"` + AgentPrice float64 `protobuf:"fixed64,7,opt,name=agent_price,json=agentPrice,proto3" json:"agent_price,omitempty"` + SaleReward string `protobuf:"bytes,8,opt,name=sale_reward,json=saleReward,proto3" json:"sale_reward,omitempty"` + NormsNumber uint32 `protobuf:"varint,9,opt,name=norms_number,json=normsNumber,proto3" json:"norms_number,omitempty"` + BoxNumber float64 `protobuf:"fixed64,10,opt,name=box_number,json=boxNumber,proto3" json:"box_number,omitempty"` + Type uint32 `protobuf:"varint,11,opt,name=type,proto3" json:"type,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *EditSusceptibleReq) Reset() { + *x = EditSusceptibleReq{} + mi := &file_proto_admin_product_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *EditSusceptibleReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EditSusceptibleReq) ProtoMessage() {} + +func (x *EditSusceptibleReq) ProtoReflect() protoreflect.Message { + mi := &file_proto_admin_product_proto_msgTypes[12] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use EditSusceptibleReq.ProtoReflect.Descriptor instead. +func (*EditSusceptibleReq) Descriptor() ([]byte, []int) { + return file_proto_admin_product_proto_rawDescGZIP(), []int{12} +} + +func (x *EditSusceptibleReq) GetId() int64 { + if x != nil { + return x.Id + } + return 0 +} + +func (x *EditSusceptibleReq) GetModelCode() string { + if x != nil { + return x.ModelCode + } + return "" +} + +func (x *EditSusceptibleReq) GetPrice() float64 { + if x != nil { + return x.Price + } + return 0 +} + +func (x *EditSusceptibleReq) GetStorePrice() float64 { + if x != nil { + return x.StorePrice + } + return 0 +} + +func (x *EditSusceptibleReq) GetSalePrice() float64 { + if x != nil { + return x.SalePrice + } + return 0 +} + +func (x *EditSusceptibleReq) GetSharePrice() float64 { + if x != nil { + return x.SharePrice + } + return 0 +} + +func (x *EditSusceptibleReq) GetAgentPrice() float64 { + if x != nil { + return x.AgentPrice + } + return 0 +} + +func (x *EditSusceptibleReq) GetSaleReward() string { + if x != nil { + return x.SaleReward + } + return "" +} + +func (x *EditSusceptibleReq) GetNormsNumber() uint32 { + if x != nil { + return x.NormsNumber + } + return 0 +} + +func (x *EditSusceptibleReq) GetBoxNumber() float64 { + if x != nil { + return x.BoxNumber + } + return 0 +} + +func (x *EditSusceptibleReq) GetType() uint32 { + if x != nil { + return x.Type + } + return 0 +} + type ItemsData struct { state protoimpl.MessageState `protogen:"open.v1"` Count int64 `protobuf:"varint,1,opt,name=count,proto3" json:"count,omitempty"` @@ -588,7 +1079,7 @@ type ItemsData struct { func (x *ItemsData) Reset() { *x = ItemsData{} - mi := &file_proto_admin_product_proto_msgTypes[7] + mi := &file_proto_admin_product_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -600,7 +1091,7 @@ func (x *ItemsData) String() string { func (*ItemsData) ProtoMessage() {} func (x *ItemsData) ProtoReflect() protoreflect.Message { - mi := &file_proto_admin_product_proto_msgTypes[7] + mi := &file_proto_admin_product_proto_msgTypes[13] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -613,7 +1104,7 @@ func (x *ItemsData) ProtoReflect() protoreflect.Message { // Deprecated: Use ItemsData.ProtoReflect.Descriptor instead. func (*ItemsData) Descriptor() ([]byte, []int) { - return file_proto_admin_product_proto_rawDescGZIP(), []int{7} + return file_proto_admin_product_proto_rawDescGZIP(), []int{13} } func (x *ItemsData) GetCount() int64 { @@ -630,6 +1121,258 @@ func (x *ItemsData) GetItems() []*Item { return nil } +type VerifyItemsData struct { + state protoimpl.MessageState `protogen:"open.v1"` + Count int64 `protobuf:"varint,1,opt,name=count,proto3" json:"count,omitempty"` + Items []*VerifyItem `protobuf:"bytes,2,rep,name=items,proto3" json:"items,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *VerifyItemsData) Reset() { + *x = VerifyItemsData{} + mi := &file_proto_admin_product_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *VerifyItemsData) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*VerifyItemsData) ProtoMessage() {} + +func (x *VerifyItemsData) ProtoReflect() protoreflect.Message { + mi := &file_proto_admin_product_proto_msgTypes[14] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use VerifyItemsData.ProtoReflect.Descriptor instead. +func (*VerifyItemsData) Descriptor() ([]byte, []int) { + return file_proto_admin_product_proto_rawDescGZIP(), []int{14} +} + +func (x *VerifyItemsData) GetCount() int64 { + if x != nil { + return x.Count + } + return 0 +} + +func (x *VerifyItemsData) GetItems() []*VerifyItem { + if x != nil { + return x.Items + } + return nil +} + +type VerifyParams struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + ModelCode string `protobuf:"bytes,2,opt,name=model_code,json=modelCode,proto3" json:"model_code,omitempty"` + Price float64 `protobuf:"fixed64,3,opt,name=price,proto3" json:"price,omitempty"` + StorePrice float64 `protobuf:"fixed64,4,opt,name=store_price,json=storePrice,proto3" json:"store_price,omitempty"` + SalePrice float64 `protobuf:"fixed64,5,opt,name=sale_price,json=salePrice,proto3" json:"sale_price,omitempty"` + SharePrice float64 `protobuf:"fixed64,6,opt,name=share_price,json=sharePrice,proto3" json:"share_price,omitempty"` + AgentPrice float64 `protobuf:"fixed64,7,opt,name=agent_price,json=agentPrice,proto3" json:"agent_price,omitempty"` + SaleReward string `protobuf:"bytes,8,opt,name=sale_reward,json=saleReward,proto3" json:"sale_reward,omitempty"` + Type uint32 `protobuf:"varint,9,opt,name=type,proto3" json:"type,omitempty"` + NormsNumber uint32 `protobuf:"varint,10,opt,name=norms_number,json=normsNumber,proto3" json:"norms_number,omitempty"` + BoxNumber float64 `protobuf:"fixed64,11,opt,name=box_number,json=boxNumber,proto3" json:"box_number,omitempty"` + VerifyId int64 `protobuf:"varint,12,opt,name=verify_id,json=verifyId,proto3" json:"verify_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *VerifyParams) Reset() { + *x = VerifyParams{} + mi := &file_proto_admin_product_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *VerifyParams) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*VerifyParams) ProtoMessage() {} + +func (x *VerifyParams) ProtoReflect() protoreflect.Message { + mi := &file_proto_admin_product_proto_msgTypes[15] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use VerifyParams.ProtoReflect.Descriptor instead. +func (*VerifyParams) Descriptor() ([]byte, []int) { + return file_proto_admin_product_proto_rawDescGZIP(), []int{15} +} + +func (x *VerifyParams) GetId() int64 { + if x != nil { + return x.Id + } + return 0 +} + +func (x *VerifyParams) GetModelCode() string { + if x != nil { + return x.ModelCode + } + return "" +} + +func (x *VerifyParams) GetPrice() float64 { + if x != nil { + return x.Price + } + return 0 +} + +func (x *VerifyParams) GetStorePrice() float64 { + if x != nil { + return x.StorePrice + } + return 0 +} + +func (x *VerifyParams) GetSalePrice() float64 { + if x != nil { + return x.SalePrice + } + return 0 +} + +func (x *VerifyParams) GetSharePrice() float64 { + if x != nil { + return x.SharePrice + } + return 0 +} + +func (x *VerifyParams) GetAgentPrice() float64 { + if x != nil { + return x.AgentPrice + } + return 0 +} + +func (x *VerifyParams) GetSaleReward() string { + if x != nil { + return x.SaleReward + } + return "" +} + +func (x *VerifyParams) GetType() uint32 { + if x != nil { + return x.Type + } + return 0 +} + +func (x *VerifyParams) GetNormsNumber() uint32 { + if x != nil { + return x.NormsNumber + } + return 0 +} + +func (x *VerifyParams) GetBoxNumber() float64 { + if x != nil { + return x.BoxNumber + } + return 0 +} + +func (x *VerifyParams) GetVerifyId() int64 { + if x != nil { + return x.VerifyId + } + return 0 +} + +type VerifyItem struct { + state protoimpl.MessageState `protogen:"open.v1"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + SalesModel uint32 `protobuf:"varint,2,opt,name=sales_model,json=salesModel,proto3" json:"sales_model,omitempty"` + New *VerifyParams `protobuf:"bytes,3,opt,name=new,proto3" json:"new,omitempty"` + Old *VerifyParams `protobuf:"bytes,4,opt,name=old,proto3" json:"old,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *VerifyItem) Reset() { + *x = VerifyItem{} + mi := &file_proto_admin_product_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *VerifyItem) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*VerifyItem) ProtoMessage() {} + +func (x *VerifyItem) ProtoReflect() protoreflect.Message { + mi := &file_proto_admin_product_proto_msgTypes[16] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use VerifyItem.ProtoReflect.Descriptor instead. +func (*VerifyItem) Descriptor() ([]byte, []int) { + return file_proto_admin_product_proto_rawDescGZIP(), []int{16} +} + +func (x *VerifyItem) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *VerifyItem) GetSalesModel() uint32 { + if x != nil { + return x.SalesModel + } + return 0 +} + +func (x *VerifyItem) GetNew() *VerifyParams { + if x != nil { + return x.New + } + return nil +} + +func (x *VerifyItem) GetOld() *VerifyParams { + if x != nil { + return x.Old + } + return nil +} + type NameItem struct { state protoimpl.MessageState `protogen:"open.v1"` Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` @@ -640,7 +1383,7 @@ type NameItem struct { func (x *NameItem) Reset() { *x = NameItem{} - mi := &file_proto_admin_product_proto_msgTypes[8] + mi := &file_proto_admin_product_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -652,7 +1395,7 @@ func (x *NameItem) String() string { func (*NameItem) ProtoMessage() {} func (x *NameItem) ProtoReflect() protoreflect.Message { - mi := &file_proto_admin_product_proto_msgTypes[8] + mi := &file_proto_admin_product_proto_msgTypes[17] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -665,7 +1408,7 @@ func (x *NameItem) ProtoReflect() protoreflect.Message { // Deprecated: Use NameItem.ProtoReflect.Descriptor instead. func (*NameItem) Descriptor() ([]byte, []int) { - return file_proto_admin_product_proto_rawDescGZIP(), []int{8} + return file_proto_admin_product_proto_rawDescGZIP(), []int{17} } func (x *NameItem) GetId() int64 { @@ -726,7 +1469,7 @@ type Item struct { func (x *Item) Reset() { *x = Item{} - mi := &file_proto_admin_product_proto_msgTypes[9] + mi := &file_proto_admin_product_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -738,7 +1481,7 @@ func (x *Item) String() string { func (*Item) ProtoMessage() {} func (x *Item) ProtoReflect() protoreflect.Message { - mi := &file_proto_admin_product_proto_msgTypes[9] + mi := &file_proto_admin_product_proto_msgTypes[18] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -751,7 +1494,7 @@ func (x *Item) ProtoReflect() protoreflect.Message { // Deprecated: Use Item.ProtoReflect.Descriptor instead. func (*Item) Descriptor() ([]byte, []int) { - return file_proto_admin_product_proto_rawDescGZIP(), []int{9} + return file_proto_admin_product_proto_rawDescGZIP(), []int{18} } func (x *Item) GetId() int64 { @@ -1067,10 +1810,91 @@ const file_proto_admin_product_proto_rawDesc = "" + "\x06reason\x18\x03 \x01(\tR\x06reason\"-\n" + "\aSortReq\x12\x0e\n" + "\x02id\x18\x01 \x01(\x03R\x02id\x12\x12\n" + - "\x04sort\x18\x02 \x01(\rR\x04sort\"F\n" + + "\x04sort\x18\x02 \x01(\rR\x04sort\"T\n" + + "\tVerifyReq\x12\x16\n" + + "\x06status\x18\x01 \x01(\rR\x06status\x12\x12\n" + + "\x04page\x18\x02 \x01(\rR\x04page\x12\x1b\n" + + "\tpage_size\x18\x03 \x01(\rR\bpageSize\"Q\n" + + "\x0fVerifyStatusReq\x12\x0e\n" + + "\x02id\x18\x01 \x01(\x03R\x02id\x12\x16\n" + + "\x06status\x18\x02 \x01(\rR\x06status\x12\x16\n" + + "\x06reason\x18\x03 \x01(\tR\x06reason\"6\n" + + "\fEditApplyReq\x12\x0e\n" + + "\x02id\x18\x01 \x01(\x03R\x02id\x12\x16\n" + + "\x06reason\x18\x02 \x01(\tR\x06reason\"\"\n" + + "\x10EditApplyPassReq\x12\x0e\n" + + "\x02id\x18\x01 \x01(\x03R\x02id\"\xfc\x02\n" + + "\vEditBaseReq\x12\x0e\n" + + "\x02id\x18\x01 \x01(\x03R\x02id\x12\x12\n" + + "\x04name\x18\x02 \x01(\tR\x04name\x12\x18\n" + + "\asubhead\x18\x03 \x01(\tR\asubhead\x12\x18\n" + + "\acontent\x18\x04 \x01(\tR\acontent\x12\x18\n" + + "\awaybill\x18\x05 \x01(\tR\awaybill\x12\x16\n" + + "\x06weight\x18\x06 \x01(\x01R\x06weight\x12\x16\n" + + "\x06cubage\x18\a \x01(\tR\x06cubage\x12\x16\n" + + "\x06images\x18\b \x01(\tR\x06images\x12'\n" + + "\x0fperiod_validity\x18\t \x01(\x05R\x0eperiodValidity\x12!\n" + + "\fpublish_time\x18\n" + + " \x01(\tR\vpublishTime\x12\x14\n" + + "\x05label\x18\v \x01(\tR\x05label\x12\x15\n" + + "\x06is_buy\x18\f \x01(\rR\x05isBuy\x12\x19\n" + + "\bis_index\x18\r \x01(\rR\aisIndex\x12\x1f\n" + + "\vindex_image\x18\x0e \x01(\tR\n" + + "indexImage\"\xd2\x02\n" + + "\x12EditSusceptibleReq\x12\x0e\n" + + "\x02id\x18\x01 \x01(\x03R\x02id\x12\x1d\n" + + "\n" + + "model_code\x18\x02 \x01(\tR\tmodelCode\x12\x14\n" + + "\x05price\x18\x03 \x01(\x01R\x05price\x12\x1f\n" + + "\vstore_price\x18\x04 \x01(\x01R\n" + + "storePrice\x12\x1d\n" + + "\n" + + "sale_price\x18\x05 \x01(\x01R\tsalePrice\x12\x1f\n" + + "\vshare_price\x18\x06 \x01(\x01R\n" + + "sharePrice\x12\x1f\n" + + "\vagent_price\x18\a \x01(\x01R\n" + + "agentPrice\x12\x1f\n" + + "\vsale_reward\x18\b \x01(\tR\n" + + "saleReward\x12!\n" + + "\fnorms_number\x18\t \x01(\rR\vnormsNumber\x12\x1d\n" + + "\n" + + "box_number\x18\n" + + " \x01(\x01R\tboxNumber\x12\x12\n" + + "\x04type\x18\v \x01(\rR\x04type\"F\n" + "\tItemsData\x12\x14\n" + "\x05count\x18\x01 \x01(\x03R\x05count\x12#\n" + - "\x05items\x18\x02 \x03(\v2\r.product.ItemR\x05items\".\n" + + "\x05items\x18\x02 \x03(\v2\r.product.ItemR\x05items\"R\n" + + "\x0fVerifyItemsData\x12\x14\n" + + "\x05count\x18\x01 \x01(\x03R\x05count\x12)\n" + + "\x05items\x18\x02 \x03(\v2\x13.product.VerifyItemR\x05items\"\xe9\x02\n" + + "\fVerifyParams\x12\x0e\n" + + "\x02id\x18\x01 \x01(\x03R\x02id\x12\x1d\n" + + "\n" + + "model_code\x18\x02 \x01(\tR\tmodelCode\x12\x14\n" + + "\x05price\x18\x03 \x01(\x01R\x05price\x12\x1f\n" + + "\vstore_price\x18\x04 \x01(\x01R\n" + + "storePrice\x12\x1d\n" + + "\n" + + "sale_price\x18\x05 \x01(\x01R\tsalePrice\x12\x1f\n" + + "\vshare_price\x18\x06 \x01(\x01R\n" + + "sharePrice\x12\x1f\n" + + "\vagent_price\x18\a \x01(\x01R\n" + + "agentPrice\x12\x1f\n" + + "\vsale_reward\x18\b \x01(\tR\n" + + "saleReward\x12\x12\n" + + "\x04type\x18\t \x01(\rR\x04type\x12!\n" + + "\fnorms_number\x18\n" + + " \x01(\rR\vnormsNumber\x12\x1d\n" + + "\n" + + "box_number\x18\v \x01(\x01R\tboxNumber\x12\x1b\n" + + "\tverify_id\x18\f \x01(\x03R\bverifyId\"\x93\x01\n" + + "\n" + + "VerifyItem\x12\x12\n" + + "\x04name\x18\x01 \x01(\tR\x04name\x12\x1f\n" + + "\vsales_model\x18\x02 \x01(\rR\n" + + "salesModel\x12'\n" + + "\x03new\x18\x03 \x01(\v2\x15.product.VerifyParamsR\x03new\x12'\n" + + "\x03old\x18\x04 \x01(\v2\x15.product.VerifyParamsR\x03old\".\n" + "\bNameItem\x12\x0e\n" + "\x02id\x18\x01 \x01(\x03R\x02id\x12\x12\n" + "\x04name\x18\x02 \x01(\tR\x04name\"\x8e\b\n" + @@ -1122,14 +1946,21 @@ const file_proto_admin_product_proto_rawDesc = "" + "\x06reason\x18\" \x01(\tR\x06reason\x12\x1d\n" + "\n" + "admin_name\x18# \x01(\tR\tadminName\x12\x12\n" + - "\x04edit\x18$ \x01(\rR\x04edit2\xee\x03\n" + + "\x04edit\x18$ \x01(\rR\x04edit2\xa6\t\n" + "\aProduct\x12M\n" + "\x06Create\x12\x12.product.CreateReq\x1a\x11.product.Response\"\x1c\x82\xd3\xe4\x93\x02\x16:\x01*\"\x11/admin/v3/product\x12N\n" + "\x04Info\x12\x10.product.InfoReq\x1a\x11.product.Response\"!\x82\xd3\xe4\x93\x02\x1b:\x01*\x12\x16/admin/v3/product/info\x12K\n" + "\x05Items\x12\x11.product.ItemsReq\x1a\x11.product.Response\"\x1c\x82\xd3\xe4\x93\x02\x16:\x01*\x12\x11/admin/v3/product\x12Q\n" + "\x05Names\x12\x11.product.NamesReq\x1a\x11.product.Response\"\"\x82\xd3\xe4\x93\x02\x1c:\x01*\x12\x17/admin/v3/product/names\x12T\n" + "\x06Status\x12\x12.product.StatusReq\x1a\x11.product.Response\"#\x82\xd3\xe4\x93\x02\x1d:\x01*\x1a\x18/admin/v3/product/status\x12N\n" + - "\x04Sort\x12\x10.product.SortReq\x1a\x11.product.Response\"!\x82\xd3\xe4\x93\x02\x1b:\x01*\x1a\x16/admin/v3/product/sortB\vZ\t./productb\x06proto3" + "\x04Sort\x12\x10.product.SortReq\x1a\x11.product.Response\"!\x82\xd3\xe4\x93\x02\x1b:\x01*\x1a\x16/admin/v3/product/sort\x12T\n" + + "\x06Verify\x12\x12.product.VerifyReq\x1a\x11.product.Response\"#\x82\xd3\xe4\x93\x02\x1d:\x01*\x12\x18/admin/v3/product/verify\x12e\n" + + "\vVerifyFirst\x12\x18.product.VerifyStatusReq\x1a\x11.product.Response\")\x82\xd3\xe4\x93\x02#:\x01*\x1a\x1e/admin/v3/product/verify/first\x12g\n" + + "\fVerifySecond\x12\x18.product.VerifyStatusReq\x1a\x11.product.Response\"*\x82\xd3\xe4\x93\x02$:\x01*\x1a\x1f/admin/v3/product/verify/second\x12^\n" + + "\tEditApply\x12\x15.product.EditApplyReq\x1a\x11.product.Response\"'\x82\xd3\xe4\x93\x02!:\x01*\"\x1c/admin/v3/product/edit/apply\x12k\n" + + "\rEditApplyPass\x12\x19.product.EditApplyPassReq\x1a\x11.product.Response\",\x82\xd3\xe4\x93\x02&:\x01*\x1a!/admin/v3/product/edit/apply/pass\x12V\n" + + "\bEditBase\x12\x14.product.EditBaseReq\x1a\x11.product.Response\"!\x82\xd3\xe4\x93\x02\x1b:\x01*\x1a\x16/admin/v3/product/base\x12k\n" + + "\x0fEditSusceptible\x12\x1b.product.EditSusceptibleReq\x1a\x11.product.Response\"(\x82\xd3\xe4\x93\x02\":\x01*\x1a\x1d/admin/v3/product/susceptibleB\vZ\t./productb\x06proto3" var ( file_proto_admin_product_proto_rawDescOnce sync.Once @@ -1143,38 +1974,64 @@ func file_proto_admin_product_proto_rawDescGZIP() []byte { return file_proto_admin_product_proto_rawDescData } -var file_proto_admin_product_proto_msgTypes = make([]protoimpl.MessageInfo, 10) +var file_proto_admin_product_proto_msgTypes = make([]protoimpl.MessageInfo, 19) var file_proto_admin_product_proto_goTypes = []any{ - (*Response)(nil), // 0: product.Response - (*CreateReq)(nil), // 1: product.CreateReq - (*InfoReq)(nil), // 2: product.InfoReq - (*ItemsReq)(nil), // 3: product.ItemsReq - (*NamesReq)(nil), // 4: product.NamesReq - (*StatusReq)(nil), // 5: product.StatusReq - (*SortReq)(nil), // 6: product.SortReq - (*ItemsData)(nil), // 7: product.ItemsData - (*NameItem)(nil), // 8: product.NameItem - (*Item)(nil), // 9: product.Item + (*Response)(nil), // 0: product.Response + (*CreateReq)(nil), // 1: product.CreateReq + (*InfoReq)(nil), // 2: product.InfoReq + (*ItemsReq)(nil), // 3: product.ItemsReq + (*NamesReq)(nil), // 4: product.NamesReq + (*StatusReq)(nil), // 5: product.StatusReq + (*SortReq)(nil), // 6: product.SortReq + (*VerifyReq)(nil), // 7: product.VerifyReq + (*VerifyStatusReq)(nil), // 8: product.VerifyStatusReq + (*EditApplyReq)(nil), // 9: product.EditApplyReq + (*EditApplyPassReq)(nil), // 10: product.EditApplyPassReq + (*EditBaseReq)(nil), // 11: product.EditBaseReq + (*EditSusceptibleReq)(nil), // 12: product.EditSusceptibleReq + (*ItemsData)(nil), // 13: product.ItemsData + (*VerifyItemsData)(nil), // 14: product.VerifyItemsData + (*VerifyParams)(nil), // 15: product.VerifyParams + (*VerifyItem)(nil), // 16: product.VerifyItem + (*NameItem)(nil), // 17: product.NameItem + (*Item)(nil), // 18: product.Item } var file_proto_admin_product_proto_depIdxs = []int32{ - 9, // 0: product.ItemsData.items:type_name -> product.Item - 1, // 1: product.Product.Create:input_type -> product.CreateReq - 2, // 2: product.Product.Info:input_type -> product.InfoReq - 3, // 3: product.Product.Items:input_type -> product.ItemsReq - 4, // 4: product.Product.Names:input_type -> product.NamesReq - 5, // 5: product.Product.Status:input_type -> product.StatusReq - 6, // 6: product.Product.Sort:input_type -> product.SortReq - 0, // 7: product.Product.Create:output_type -> product.Response - 0, // 8: product.Product.Info:output_type -> product.Response - 0, // 9: product.Product.Items:output_type -> product.Response - 0, // 10: product.Product.Names:output_type -> product.Response - 0, // 11: product.Product.Status:output_type -> product.Response - 0, // 12: product.Product.Sort:output_type -> product.Response - 7, // [7:13] is the sub-list for method output_type - 1, // [1:7] is the sub-list for method input_type - 1, // [1:1] is the sub-list for extension type_name - 1, // [1:1] is the sub-list for extension extendee - 0, // [0:1] is the sub-list for field type_name + 18, // 0: product.ItemsData.items:type_name -> product.Item + 16, // 1: product.VerifyItemsData.items:type_name -> product.VerifyItem + 15, // 2: product.VerifyItem.new:type_name -> product.VerifyParams + 15, // 3: product.VerifyItem.old:type_name -> product.VerifyParams + 1, // 4: product.Product.Create:input_type -> product.CreateReq + 2, // 5: product.Product.Info:input_type -> product.InfoReq + 3, // 6: product.Product.Items:input_type -> product.ItemsReq + 4, // 7: product.Product.Names:input_type -> product.NamesReq + 5, // 8: product.Product.Status:input_type -> product.StatusReq + 6, // 9: product.Product.Sort:input_type -> product.SortReq + 7, // 10: product.Product.Verify:input_type -> product.VerifyReq + 8, // 11: product.Product.VerifyFirst:input_type -> product.VerifyStatusReq + 8, // 12: product.Product.VerifySecond:input_type -> product.VerifyStatusReq + 9, // 13: product.Product.EditApply:input_type -> product.EditApplyReq + 10, // 14: product.Product.EditApplyPass:input_type -> product.EditApplyPassReq + 11, // 15: product.Product.EditBase:input_type -> product.EditBaseReq + 12, // 16: product.Product.EditSusceptible:input_type -> product.EditSusceptibleReq + 0, // 17: product.Product.Create:output_type -> product.Response + 0, // 18: product.Product.Info:output_type -> product.Response + 0, // 19: product.Product.Items:output_type -> product.Response + 0, // 20: product.Product.Names:output_type -> product.Response + 0, // 21: product.Product.Status:output_type -> product.Response + 0, // 22: product.Product.Sort:output_type -> product.Response + 0, // 23: product.Product.Verify:output_type -> product.Response + 0, // 24: product.Product.VerifyFirst:output_type -> product.Response + 0, // 25: product.Product.VerifySecond:output_type -> product.Response + 0, // 26: product.Product.EditApply:output_type -> product.Response + 0, // 27: product.Product.EditApplyPass:output_type -> product.Response + 0, // 28: product.Product.EditBase:output_type -> product.Response + 0, // 29: product.Product.EditSusceptible:output_type -> product.Response + 17, // [17:30] is the sub-list for method output_type + 4, // [4:17] is the sub-list for method input_type + 4, // [4:4] is the sub-list for extension type_name + 4, // [4:4] is the sub-list for extension extendee + 0, // [0:4] is the sub-list for field type_name } func init() { file_proto_admin_product_proto_init() } @@ -1188,7 +2045,7 @@ func file_proto_admin_product_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_proto_admin_product_proto_rawDesc), len(file_proto_admin_product_proto_rawDesc)), NumEnums: 0, - NumMessages: 10, + NumMessages: 19, NumExtensions: 0, NumServices: 1, }, diff --git a/product/product/product_grpc.pb.go b/product/product/product_grpc.pb.go index 9dc8bbc..bd9b23f 100644 --- a/product/product/product_grpc.pb.go +++ b/product/product/product_grpc.pb.go @@ -19,12 +19,19 @@ import ( const _ = grpc.SupportPackageIsVersion9 const ( - Product_Create_FullMethodName = "/product.Product/Create" - Product_Info_FullMethodName = "/product.Product/Info" - Product_Items_FullMethodName = "/product.Product/Items" - Product_Names_FullMethodName = "/product.Product/Names" - Product_Status_FullMethodName = "/product.Product/Status" - Product_Sort_FullMethodName = "/product.Product/Sort" + Product_Create_FullMethodName = "/product.Product/Create" + Product_Info_FullMethodName = "/product.Product/Info" + Product_Items_FullMethodName = "/product.Product/Items" + Product_Names_FullMethodName = "/product.Product/Names" + Product_Status_FullMethodName = "/product.Product/Status" + Product_Sort_FullMethodName = "/product.Product/Sort" + Product_Verify_FullMethodName = "/product.Product/Verify" + Product_VerifyFirst_FullMethodName = "/product.Product/VerifyFirst" + Product_VerifySecond_FullMethodName = "/product.Product/VerifySecond" + Product_EditApply_FullMethodName = "/product.Product/EditApply" + Product_EditApplyPass_FullMethodName = "/product.Product/EditApplyPass" + Product_EditBase_FullMethodName = "/product.Product/EditBase" + Product_EditSusceptible_FullMethodName = "/product.Product/EditSusceptible" ) // ProductClient is the client API for Product service. @@ -37,6 +44,20 @@ type ProductClient interface { Names(ctx context.Context, in *NamesReq, opts ...grpc.CallOption) (*Response, error) Status(ctx context.Context, in *StatusReq, opts ...grpc.CallOption) (*Response, error) Sort(ctx context.Context, in *SortReq, opts ...grpc.CallOption) (*Response, error) + // 审核列表: status: 1: 一审, 2: 二审 + Verify(ctx context.Context, in *VerifyReq, opts ...grpc.CallOption) (*Response, error) + // 一审通过/驳回 + VerifyFirst(ctx context.Context, in *VerifyStatusReq, opts ...grpc.CallOption) (*Response, error) + // 二审通过/驳回 + VerifySecond(ctx context.Context, in *VerifyStatusReq, opts ...grpc.CallOption) (*Response, error) + // 编辑申请(解锁编辑权限) + EditApply(ctx context.Context, in *EditApplyReq, opts ...grpc.CallOption) (*Response, error) + // TODO: 临时接口,企微编辑申请审批对接后删除 + EditApplyPass(ctx context.Context, in *EditApplyPassReq, opts ...grpc.CallOption) (*Response, error) + // 编辑基础信息 + EditBase(ctx context.Context, in *EditBaseReq, opts ...grpc.CallOption) (*Response, error) + // 编辑敏感信息(进入一审) + EditSusceptible(ctx context.Context, in *EditSusceptibleReq, opts ...grpc.CallOption) (*Response, error) } type productClient struct { @@ -107,6 +128,76 @@ func (c *productClient) Sort(ctx context.Context, in *SortReq, opts ...grpc.Call return out, nil } +func (c *productClient) Verify(ctx context.Context, in *VerifyReq, opts ...grpc.CallOption) (*Response, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(Response) + err := c.cc.Invoke(ctx, Product_Verify_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *productClient) VerifyFirst(ctx context.Context, in *VerifyStatusReq, opts ...grpc.CallOption) (*Response, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(Response) + err := c.cc.Invoke(ctx, Product_VerifyFirst_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *productClient) VerifySecond(ctx context.Context, in *VerifyStatusReq, opts ...grpc.CallOption) (*Response, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(Response) + err := c.cc.Invoke(ctx, Product_VerifySecond_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *productClient) EditApply(ctx context.Context, in *EditApplyReq, opts ...grpc.CallOption) (*Response, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(Response) + err := c.cc.Invoke(ctx, Product_EditApply_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *productClient) EditApplyPass(ctx context.Context, in *EditApplyPassReq, opts ...grpc.CallOption) (*Response, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(Response) + err := c.cc.Invoke(ctx, Product_EditApplyPass_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *productClient) EditBase(ctx context.Context, in *EditBaseReq, opts ...grpc.CallOption) (*Response, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(Response) + err := c.cc.Invoke(ctx, Product_EditBase_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *productClient) EditSusceptible(ctx context.Context, in *EditSusceptibleReq, opts ...grpc.CallOption) (*Response, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(Response) + err := c.cc.Invoke(ctx, Product_EditSusceptible_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + // ProductServer is the server API for Product service. // All implementations must embed UnimplementedProductServer // for forward compatibility. @@ -117,6 +208,20 @@ type ProductServer interface { Names(context.Context, *NamesReq) (*Response, error) Status(context.Context, *StatusReq) (*Response, error) Sort(context.Context, *SortReq) (*Response, error) + // 审核列表: status: 1: 一审, 2: 二审 + Verify(context.Context, *VerifyReq) (*Response, error) + // 一审通过/驳回 + VerifyFirst(context.Context, *VerifyStatusReq) (*Response, error) + // 二审通过/驳回 + VerifySecond(context.Context, *VerifyStatusReq) (*Response, error) + // 编辑申请(解锁编辑权限) + EditApply(context.Context, *EditApplyReq) (*Response, error) + // TODO: 临时接口,企微编辑申请审批对接后删除 + EditApplyPass(context.Context, *EditApplyPassReq) (*Response, error) + // 编辑基础信息 + EditBase(context.Context, *EditBaseReq) (*Response, error) + // 编辑敏感信息(进入一审) + EditSusceptible(context.Context, *EditSusceptibleReq) (*Response, error) mustEmbedUnimplementedProductServer() } @@ -145,6 +250,27 @@ func (UnimplementedProductServer) Status(context.Context, *StatusReq) (*Response func (UnimplementedProductServer) Sort(context.Context, *SortReq) (*Response, error) { return nil, status.Error(codes.Unimplemented, "method Sort not implemented") } +func (UnimplementedProductServer) Verify(context.Context, *VerifyReq) (*Response, error) { + return nil, status.Error(codes.Unimplemented, "method Verify not implemented") +} +func (UnimplementedProductServer) VerifyFirst(context.Context, *VerifyStatusReq) (*Response, error) { + return nil, status.Error(codes.Unimplemented, "method VerifyFirst not implemented") +} +func (UnimplementedProductServer) VerifySecond(context.Context, *VerifyStatusReq) (*Response, error) { + return nil, status.Error(codes.Unimplemented, "method VerifySecond not implemented") +} +func (UnimplementedProductServer) EditApply(context.Context, *EditApplyReq) (*Response, error) { + return nil, status.Error(codes.Unimplemented, "method EditApply not implemented") +} +func (UnimplementedProductServer) EditApplyPass(context.Context, *EditApplyPassReq) (*Response, error) { + return nil, status.Error(codes.Unimplemented, "method EditApplyPass not implemented") +} +func (UnimplementedProductServer) EditBase(context.Context, *EditBaseReq) (*Response, error) { + return nil, status.Error(codes.Unimplemented, "method EditBase not implemented") +} +func (UnimplementedProductServer) EditSusceptible(context.Context, *EditSusceptibleReq) (*Response, error) { + return nil, status.Error(codes.Unimplemented, "method EditSusceptible not implemented") +} func (UnimplementedProductServer) mustEmbedUnimplementedProductServer() {} func (UnimplementedProductServer) testEmbeddedByValue() {} @@ -274,6 +400,132 @@ func _Product_Sort_Handler(srv interface{}, ctx context.Context, dec func(interf return interceptor(ctx, in, info, handler) } +func _Product_Verify_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(VerifyReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProductServer).Verify(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Product_Verify_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProductServer).Verify(ctx, req.(*VerifyReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _Product_VerifyFirst_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(VerifyStatusReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProductServer).VerifyFirst(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Product_VerifyFirst_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProductServer).VerifyFirst(ctx, req.(*VerifyStatusReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _Product_VerifySecond_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(VerifyStatusReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProductServer).VerifySecond(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Product_VerifySecond_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProductServer).VerifySecond(ctx, req.(*VerifyStatusReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _Product_EditApply_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(EditApplyReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProductServer).EditApply(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Product_EditApply_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProductServer).EditApply(ctx, req.(*EditApplyReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _Product_EditApplyPass_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(EditApplyPassReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProductServer).EditApplyPass(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Product_EditApplyPass_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProductServer).EditApplyPass(ctx, req.(*EditApplyPassReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _Product_EditBase_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(EditBaseReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProductServer).EditBase(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Product_EditBase_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProductServer).EditBase(ctx, req.(*EditBaseReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _Product_EditSusceptible_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(EditSusceptibleReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProductServer).EditSusceptible(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Product_EditSusceptible_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProductServer).EditSusceptible(ctx, req.(*EditSusceptibleReq)) + } + return interceptor(ctx, in, info, handler) +} + // Product_ServiceDesc is the grpc.ServiceDesc for Product service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -305,6 +557,34 @@ var Product_ServiceDesc = grpc.ServiceDesc{ MethodName: "Sort", Handler: _Product_Sort_Handler, }, + { + MethodName: "Verify", + Handler: _Product_Verify_Handler, + }, + { + MethodName: "VerifyFirst", + Handler: _Product_VerifyFirst_Handler, + }, + { + MethodName: "VerifySecond", + Handler: _Product_VerifySecond_Handler, + }, + { + MethodName: "EditApply", + Handler: _Product_EditApply_Handler, + }, + { + MethodName: "EditApplyPass", + Handler: _Product_EditApplyPass_Handler, + }, + { + MethodName: "EditBase", + Handler: _Product_EditBase_Handler, + }, + { + MethodName: "EditSusceptible", + Handler: _Product_EditSusceptible_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "proto/admin/product.proto", diff --git a/product/productclient/product.go b/product/productclient/product.go index 61e7616..d98e5b2 100644 --- a/product/productclient/product.go +++ b/product/productclient/product.go @@ -13,16 +13,25 @@ import ( ) type ( - CreateReq = product.CreateReq - InfoReq = product.InfoReq - ItemsReq = product.ItemsReq - NamesReq = product.NamesReq - StatusReq = product.StatusReq - SortReq = product.SortReq - ItemsData = product.ItemsData - NameItem = product.NameItem - Item = product.Item - Response = product.Response + CreateReq = product.CreateReq + InfoReq = product.InfoReq + ItemsReq = product.ItemsReq + NamesReq = product.NamesReq + StatusReq = product.StatusReq + SortReq = product.SortReq + VerifyReq = product.VerifyReq + VerifyStatusReq = product.VerifyStatusReq + EditApplyReq = product.EditApplyReq + EditApplyPassReq = product.EditApplyPassReq + EditBaseReq = product.EditBaseReq + EditSusceptibleReq = product.EditSusceptibleReq + ItemsData = product.ItemsData + VerifyItemsData = product.VerifyItemsData + VerifyParams = product.VerifyParams + VerifyItem = product.VerifyItem + NameItem = product.NameItem + Item = product.Item + Response = product.Response Product interface { Create(ctx context.Context, in *CreateReq, opts ...grpc.CallOption) (*Response, error) @@ -31,6 +40,13 @@ type ( Names(ctx context.Context, in *NamesReq, opts ...grpc.CallOption) (*Response, error) Status(ctx context.Context, in *StatusReq, opts ...grpc.CallOption) (*Response, error) Sort(ctx context.Context, in *SortReq, opts ...grpc.CallOption) (*Response, error) + Verify(ctx context.Context, in *VerifyReq, opts ...grpc.CallOption) (*Response, error) + VerifyFirst(ctx context.Context, in *VerifyStatusReq, opts ...grpc.CallOption) (*Response, error) + VerifySecond(ctx context.Context, in *VerifyStatusReq, opts ...grpc.CallOption) (*Response, error) + EditApply(ctx context.Context, in *EditApplyReq, opts ...grpc.CallOption) (*Response, error) + EditApplyPass(ctx context.Context, in *EditApplyPassReq, opts ...grpc.CallOption) (*Response, error) + EditBase(ctx context.Context, in *EditBaseReq, opts ...grpc.CallOption) (*Response, error) + EditSusceptible(ctx context.Context, in *EditSusceptibleReq, opts ...grpc.CallOption) (*Response, error) } defaultProduct struct { @@ -73,3 +89,38 @@ func (m *defaultProduct) Sort(ctx context.Context, in *SortReq, opts ...grpc.Cal client := product.NewProductClient(m.cli.Conn()) return client.Sort(ctx, in, opts...) } + +func (m *defaultProduct) Verify(ctx context.Context, in *VerifyReq, opts ...grpc.CallOption) (*Response, error) { + client := product.NewProductClient(m.cli.Conn()) + return client.Verify(ctx, in, opts...) +} + +func (m *defaultProduct) VerifyFirst(ctx context.Context, in *VerifyStatusReq, opts ...grpc.CallOption) (*Response, error) { + client := product.NewProductClient(m.cli.Conn()) + return client.VerifyFirst(ctx, in, opts...) +} + +func (m *defaultProduct) VerifySecond(ctx context.Context, in *VerifyStatusReq, opts ...grpc.CallOption) (*Response, error) { + client := product.NewProductClient(m.cli.Conn()) + return client.VerifySecond(ctx, in, opts...) +} + +func (m *defaultProduct) EditApply(ctx context.Context, in *EditApplyReq, opts ...grpc.CallOption) (*Response, error) { + client := product.NewProductClient(m.cli.Conn()) + return client.EditApply(ctx, in, opts...) +} + +func (m *defaultProduct) EditApplyPass(ctx context.Context, in *EditApplyPassReq, opts ...grpc.CallOption) (*Response, error) { + client := product.NewProductClient(m.cli.Conn()) + return client.EditApplyPass(ctx, in, opts...) +} + +func (m *defaultProduct) EditBase(ctx context.Context, in *EditBaseReq, opts ...grpc.CallOption) (*Response, error) { + client := product.NewProductClient(m.cli.Conn()) + return client.EditBase(ctx, in, opts...) +} + +func (m *defaultProduct) EditSusceptible(ctx context.Context, in *EditSusceptibleReq, opts ...grpc.CallOption) (*Response, error) { + client := product.NewProductClient(m.cli.Conn()) + return client.EditSusceptible(ctx, in, opts...) +} diff --git a/product/proto/admin/product.proto b/product/proto/admin/product.proto index 304a1e6..9abea73 100644 --- a/product/proto/admin/product.proto +++ b/product/proto/admin/product.proto @@ -42,6 +42,56 @@ service Product { body: "*" }; } + // 审核列表: status: 1: 一审, 2: 二审 + rpc Verify(VerifyReq) returns (Response) { + option (google.api.http) = { + get: "/admin/v3/product/verify" + body: "*" + }; + } + // 一审通过/驳回 + rpc VerifyFirst(VerifyStatusReq) returns (Response) { + option (google.api.http) = { + put: "/admin/v3/product/verify/first" + body: "*" + }; + } + // 二审通过/驳回 + rpc VerifySecond(VerifyStatusReq) returns (Response) { + option (google.api.http) = { + put: "/admin/v3/product/verify/second" + body: "*" + }; + } + // 编辑申请(解锁编辑权限) + rpc EditApply(EditApplyReq) returns (Response) { + option (google.api.http) = { + post: "/admin/v3/product/edit/apply" + body: "*" + }; + } + // 编辑基础信息 + rpc EditBase(EditBaseReq) returns (Response) { + option (google.api.http) = { + put: "/admin/v3/product/base" + body: "*" + }; + } + // 编辑敏感信息(进入一审) + rpc EditSusceptible(EditSusceptibleReq) returns (Response) { + option (google.api.http) = { + put: "/admin/v3/product/susceptible" + body: "*" + }; + } + + // TODO: 临时接口,企微编辑申请审批对接后删除 + rpc EditApplyPass(EditApplyPassReq) returns (Response) { + option (google.api.http) = { + put: "/admin/v3/product/edit/apply/pass" + body: "*" + }; + } } message Response { @@ -102,11 +152,93 @@ message SortReq { uint32 sort = 2; } +// status: 1: 一审列表, 2: 二审列表 +message VerifyReq { + uint32 status = 1; + uint32 page = 2; + uint32 page_size = 3; +} + +// id 为 verify 表主键;status: 1: 通过, 2: 驳回 +message VerifyStatusReq { + int64 id = 1; + uint32 status = 2; + string reason = 3; +} + +message EditApplyReq { + int64 id = 1; + string reason = 2; +} + +// TODO: 临时,企微对接后删除 +message EditApplyPassReq { + int64 id = 1; +} + +message EditBaseReq { + int64 id = 1; + string name = 2; + string subhead = 3; + string content = 4; + string waybill = 5; + double weight = 6; + string cubage = 7; + string images = 8; + int32 period_validity = 9; + string publish_time = 10; + string label = 11; + uint32 is_buy = 12; + uint32 is_index = 13; + string index_image = 14; +} + +message EditSusceptibleReq { + int64 id = 1; + string model_code = 2; + double price = 3; + double store_price = 4; + double sale_price = 5; + double share_price = 6; + double agent_price = 7; + string sale_reward = 8; + uint32 norms_number = 9; + double box_number = 10; + uint32 type = 11; +} + message ItemsData { int64 count = 1; repeated Item items = 2; } +message VerifyItemsData { + int64 count = 1; + repeated VerifyItem items = 2; +} + +message VerifyParams { + int64 id = 1; + string model_code = 2; + double price = 3; + double store_price = 4; + double sale_price = 5; + double share_price = 6; + double agent_price = 7; + string sale_reward = 8; + uint32 type = 9; + uint32 norms_number = 10; + double box_number = 11; + int64 verify_id = 12; +} + +message VerifyItem { + string name = 1; + uint32 sales_model = 2; + VerifyParams new = 3; + VerifyParams old = 4; +} + message NameItem { int64 id = 1; string name = 2; diff --git a/product/validator/validator.go b/product/validator/validator.go index 4f05953..242b148 100644 --- a/product/validator/validator.go +++ b/product/validator/validator.go @@ -107,3 +107,116 @@ func (p ProductSortValidator) GetMessage() validate.ValidatorMessages { "Sort.required": "排序不能为空", } } + +type ProductVerifyItemsValidator struct { + Status uint32 `validate:"required,oneof=1 2"` + Page uint32 `validate:"omitempty,min=1"` + PageSize uint32 `validate:"omitempty,min=1,max=100"` +} + +func (p ProductVerifyItemsValidator) GetMessage() validate.ValidatorMessages { + return validate.ValidatorMessages{ + "Status.required": "状态不能为空", + "Status.oneof": "状态不对", + "Page.min": "页码最小为1", + "PageSize.min": "每页数量最小为1", + "PageSize.max": "每页数量最大为100", + } +} + +type ProductVerifyStatusValidator struct { + Id int64 `validate:"required,gt=0"` + Status uint32 `validate:"required,oneof=1 2"` + Reason string `validate:"max=255"` +} + +func (p ProductVerifyStatusValidator) GetMessage() validate.ValidatorMessages { + return validate.ValidatorMessages{ + "Id.required": "ID不能为空", + "Id.gt": "ID必须大于0", + "Status.required": "状态不能为空", + "Status.oneof": "状态不对", + } +} + +type ProductEditApplyValidator struct { + Id int64 `validate:"required,gt=0"` + Reason string `validate:"required,max=255"` +} + +func (p ProductEditApplyValidator) GetMessage() validate.ValidatorMessages { + return validate.ValidatorMessages{ + "Id.required": "ID不能为空", + "Id.gt": "ID必须大于0", + "Reason.required": "原因不能为空", + } +} + +type ProductEditApplyPassValidator struct { + Id int64 `validate:"required,gt=0"` +} + +func (p ProductEditApplyPassValidator) GetMessage() validate.ValidatorMessages { + return validate.ValidatorMessages{ + "Id.required": "ID不能为空", + "Id.gt": "ID必须大于0", + } +} + +type ProductEditBaseValidator struct { + Id int64 `validate:"required,gt=0"` + Name string `validate:"required,max=256"` + Subhead string `validate:"required,max=255"` + Content string `validate:"required"` + Waybill string `validate:"required,max=255"` + Weight float64 `validate:"required"` + Cubage string `validate:"required,max=255"` + Images string `validate:"required,max=512"` + PeriodValidity int32 `validate:"required"` + PublishTime string `validate:"max=32"` + Label string `validate:"max=255"` + IsBuy uint32 `validate:"omitempty,oneof=1 2"` + IsIndex uint32 `validate:"omitempty,oneof=1 2"` + IndexImage string `validate:"max=255"` +} + +func (p ProductEditBaseValidator) GetMessage() validate.ValidatorMessages { + return validate.ValidatorMessages{ + "Id.required": "ID不能为空", + "Id.gt": "ID必须大于0", + "Name.required": "产品名不能为空", + "Subhead.required": "副标题不能为空", + "Content.required": "内容不能为空", + "Images.required": "图片不能为空", + "PeriodValidity.required": "有效期不能为空", + "Waybill.required": "运货单图片不能为空", + "Weight.required": "重量不能为空", + "Cubage.required": "体积不能为空", + } +} + +type ProductEditSusceptibleValidator struct { + Id int64 `validate:"required,gt=0"` + ModelCode string `validate:"required,max=255"` + Price float64 `validate:"required"` + StorePrice float64 + SalePrice float64 + SharePrice float64 + AgentPrice float64 + SaleReward string `validate:"max=255"` + NormsNumber uint32 `validate:"required,min=1"` + BoxNumber float64 + Type uint32 `validate:"required,oneof=1 2 3"` +} + +func (p ProductEditSusceptibleValidator) GetMessage() validate.ValidatorMessages { + return validate.ValidatorMessages{ + "Id.required": "ID不能为空", + "Id.gt": "ID必须大于0", + "ModelCode.required": "请输入机器码", + "Price.required": "价格不能为空", + "NormsNumber.required": "缺少一份中有几个", + "Type.required": "请选择类型", + "Type.oneof": "类型不对", + } +}