diff --git a/.gitea/workflows/cd-test.yml b/.gitea/workflows/cd-test.yml index bd84a13..9bc68c2 100644 --- a/.gitea/workflows/cd-test.yml +++ b/.gitea/workflows/cd-test.yml @@ -41,6 +41,7 @@ jobs: docker pull ${{ vars.REGISTRY }}/lone/user:latest docker pull ${{ vars.REGISTRY }}/lone/ad:latest docker pull ${{ vars.REGISTRY }}/lone/chore:latest + docker pull ${{ vars.REGISTRY }}/lone/order:latest docker pull ${{ vars.REGISTRY }}/lone/express:latest docker pull ${{ vars.REGISTRY }}/lone/sale:latest docker pull ${{ vars.REGISTRY }}/lone/equipment:latest diff --git a/services/store/internal/dao/salesPersonHistory.go b/services/store/internal/dao/salesPersonHistory.go index c72fb07..ebd8af8 100644 --- a/services/store/internal/dao/salesPersonHistory.go +++ b/services/store/internal/dao/salesPersonHistory.go @@ -2,17 +2,17 @@ package dao import "lone-services/pkg/utils" -type SalesPersonHistoryCreate struct { - Id int64 `json:"id" gorm:"id"` - StoreId int64 `json:"store_id" gorm:"store_id"` // 门店ID - SalesPersonId int64 `json:"sales_person_id" gorm:"sales_person_id"` // 关联销售员的id - AdminId int64 `json:"admin_id" gorm:"admin_id"` // 修改人,0 为系统 +type SaleChangeHistoryCreate struct { + Id int64 `json:"id" gorm:"id"` + StoreId int64 `json:"store_id" gorm:"store_id"` // 门店ID + SaleId int64 `json:"sale_id" gorm:"sale_id"` // 关联销售员的id + AdminId int64 `json:"admin_id" gorm:"admin_id"` // 修改人,0 为系统 } -type SalesPersonHistoryInfo struct { - Id int64 `json:"id" gorm:"id"` - StoreId int64 `json:"store_id" gorm:"store_id"` // 门店ID - SalesPersonId int64 `json:"sales_person_id" gorm:"sales_person_id"` // 关联销售员的id - AdminId int64 `json:"admin_id" gorm:"admin_id"` // 修改人,0 为系统 - CreateTime utils.CustomTime `gorm:"column:create_time;type:datetime;default:CURRENT_TIMESTAMP;comment:添加时间" json:"create_time"` +type SaleChangeHistoryInfo struct { + Id int64 `json:"id" gorm:"id"` + StoreId int64 `json:"store_id" gorm:"store_id"` // 门店ID + SaleId int64 `json:"sale_id" gorm:"sale_id"` // 关联销售员的id + AdminId int64 `json:"admin_id" gorm:"admin_id"` // 修改人,0 为系统 + CreateTime utils.CustomTime `gorm:"column:create_time;type:datetime;default:CURRENT_TIMESTAMP;comment:添加时间" json:"create_time"` } diff --git a/services/store/internal/dao/store.go b/services/store/internal/dao/store.go index d88f117..0c7a7c0 100644 --- a/services/store/internal/dao/store.go +++ b/services/store/internal/dao/store.go @@ -2,6 +2,18 @@ package dao import "lone-services/pkg/utils" +const ( + StoreApplyReview = 1 // 提交审核(按钮消息) + StoreNeedReview = 2 // 通知申请人 + StoreSubmitReview = 3 // 通知一审人员 + StoreFirstReview = 4 // 一审审核结果 + StoreSecondReview = 5 // 二审审核结果 + + LoginTypePassword = "password" + LoginTypeSms = "sms" + UserTypeName = "store" +) + type StoreCreate struct { Id int64 `gorm:"column:id;type:int(11);primary_key;AUTO_INCREMENT" json:"id"` Name string `gorm:"column:name;type:varchar(256);comment:门店名;NOT NULL" json:"name"` @@ -26,7 +38,7 @@ type StoreCreate struct { OpenTime string `gorm:"column:open_time;type:varchar(100);comment:营业时间" json:"open_time"` Province int64 `gorm:"column:province;type:int(11);default:0" json:"province"` ProvinceName string `gorm:"column:province_name;type:varchar(255)" json:"province_name"` - StoreType int64 `json:"store_type" gorm:"store_type"` // 门店类型,1为面膜,2为门店,3为制氧机,4为软水机,5智能化妆盒 + StoreType string `json:"store_type" gorm:"store_type"` // 门店类型,1为面膜,2为门店,3为制氧机,4为软水机,5智能化妆盒 City int64 `json:"city" gorm:"city"` CityName string `json:"city_name" gorm:"city_name"` County int64 `json:"county" gorm:"county"` @@ -45,7 +57,7 @@ type StoreInfo struct { UserName string `gorm:"column:user_name;type:varchar(128);comment:负责人姓名;NOT NULL" json:"user_name"` UserMobile string `gorm:"column:user_mobile;type:varchar(128);comment:负责人手机号,也是登录账号;NOT NULL" json:"user_mobile"` BusinessLicense string `gorm:"column:business_license;type:varchar(512);comment:营业执照;NOT NULL" json:"business_license"` - StoreType int64 `json:"store_type" gorm:"store_type"` // 门店类型,1为面膜,2为门店,3为制氧机,4为软水机,5智能化妆盒 + StoreType string `json:"store_type" gorm:"store_type"` // 门店类型,1为面膜,2为门店,3为制氧机,4为软水机,5智能化妆盒 Amount float64 `gorm:"column:amount;type:decimal(10,2);default:0.00;comment:余额" json:"amount"` District string `gorm:"column:district;type:varchar(255);comment:地区(省,市,县)ID" json:"district"` IdCard string `gorm:"column:id_card;type:varchar(255);comment:身份证正反面" json:"id_card"` @@ -95,7 +107,7 @@ type StoreWebInfo struct { BusinessLicense string `gorm:"column:business_license;type:varchar(512);comment:营业执照;NOT NULL" json:"business_license"` District string `gorm:"column:district;type:varchar(255);comment:地区(省,市,县)ID" json:"district"` Address string `gorm:"column:address;type:varchar(512);comment:地址" json:"address"` - StoreType int64 `json:"store_type" gorm:"store_type"` // 门店类型,1为面膜,2为门店,3为制氧机,4为软水机,5智能化妆盒 + StoreType string `json:"store_type" gorm:"store_type"` // 门店类型,1为面膜,2为门店,3为制氧机,4为软水机,5智能化妆盒 BankInfo string `gorm:"column:bank_info;type:varchar(255);comment:银行卡信息" json:"bank_info"` Status int32 `gorm:"column:status;type:tinyint(1);default:9;comment:状态9是待审核 1是已通过 2是未通过,3为禁用" json:"status"` SourceType int32 `gorm:"column:source_type;type:tinyint(1);default:1;comment:来源类型,1为公司添加,2为销售添加" json:"source_type"` @@ -151,6 +163,7 @@ type StoreVerifyEdit struct { type StoreStatus struct { Id int64 `gorm:"column:id;type:int(11);primary_key;AUTO_INCREMENT" json:"id"` Name string `gorm:"column:name;type:varchar(256);comment:姓名或公司名;NOT NULL" json:"name"` + UserName string `gorm:"column:user_name;type:varchar(128);comment:负责人姓名;NOT NULL" json:"user_name"` SaleId int64 `gorm:"column:sale_id;type:int(11);default:0;comment:父级销售;NOT NULL" json:"sale_id"` UserMobile string `gorm:"column:user_mobile;type:varchar(128);comment:负责人手机号,也是登录账号;NOT NULL" json:"user_mobile"` NewContent string `gorm:"column:new_content;type:text;comment:修改的内容" json:"new_content"` @@ -225,11 +238,15 @@ type StoreNewCreate struct { SaleId int64 `gorm:"column:sale_id;type:varchar(256);comment:关联销售员的id" json:"sale_id"` Province int64 `gorm:"column:province;type:int(11);default:0" json:"province"` ProvinceName string `gorm:"column:province_name;type:varchar(255)" json:"province_name"` + City int64 `json:"city" gorm:"city"` + CityName string `json:"city_name" gorm:"city_name"` + County int64 `json:"county" gorm:"county"` + CountyName string `json:"county_name" gorm:"county_name"` SourceType int32 `gorm:"column:source_type;type:tinyint(1);default:1;comment:来源类型,1为公司添加,2为销售添加" json:"source_type"` Images string `gorm:"column:images;type:varchar(255);comment:门店门头照片" json:"images"` StoreImages string `gorm:"column:store_images;type:text;comment:店内照片" json:"store_images"` Contact string `gorm:"column:contact;type:varchar(255);comment:联系方式,多个,号分割" json:"contact"` - StoreType int64 `json:"store_type" gorm:"store_type"` // 门店类型,1为面膜,2为门店,3为制氧机,4为软水机,5智能化妆盒 + StoreType string `json:"store_type" gorm:"store_type"` // 门店类型,1为面膜,2为门店,3为制氧机,4为软水机,5智能化妆盒 Content string `gorm:"column:content;type:text" json:"content"` NewContent string `gorm:"column:new_content;type:text;comment:修改的内容" json:"new_content"` OpenTime string `gorm:"column:open_time;type:varchar(100);comment:营业时间" json:"open_time"` diff --git a/services/store/internal/logic/base.go b/services/store/internal/logic/base.go index 9bc96a5..66e3520 100644 --- a/services/store/internal/logic/base.go +++ b/services/store/internal/logic/base.go @@ -1,10 +1,12 @@ package logic import ( + "lone-services/pkg/modelbase" "lone-services/pkg/utils" "lone-services/pkg/validate" store "lone-services/rpc/store/pb" "reflect" + "strconv" jsoniter "github.com/json-iterator/go" ) @@ -46,3 +48,29 @@ func (l *BaseLogic) ok(data any) (*store.Response, error) { buf, _ := jsoniter.Marshal(data) return &store.Response{Code: utils.Ok.Code, Msg: utils.Ok.Msg, Data: string(buf)}, nil } + +func (s BaseLogic) SetWhere(w *modelbase.Params, u utils.UserInfo) { + if u.Type == utils.SaleType { + s.SetGroupWhere(w, u, false) + } +} + +func (s BaseLogic) SetGroupWhere(w *modelbase.Params, u utils.UserInfo, checkProvince bool) { + if w.Eq == nil { + w.Eq = make(map[string]string) + } + if u.GroupId < utils.NumberOne { + return + } + + //如果是公司销售 + if u.Type == utils.SaleType { + w.Eq["group_id"] = strconv.Itoa(int(u.GroupId)) + } else if u.SaleProvince > utils.NumberZero { + if checkProvince { + w.Eq["sale_province"] = strconv.Itoa(int(u.SaleProvince)) + } else { + w.Eq["group_id"] = strconv.Itoa(int(u.GroupId)) + } + } +} diff --git a/services/store/internal/model/deposit.go b/services/store/internal/model/deposit.go index ced9d81..3dae2e0 100644 --- a/services/store/internal/model/deposit.go +++ b/services/store/internal/model/deposit.go @@ -18,6 +18,6 @@ func (m DepositModel) Init() DepositModel { return m } -func (m DepositModel) Create(data *dao.StoreCreate) error { +func (m DepositModel) Create(data *dao.DepositCreate) error { return m.Base.Create(data) } diff --git a/services/store/internal/model/saleChangeHistory.go b/services/store/internal/model/saleChangeHistory.go index 4b8a0c0..818a9b4 100644 --- a/services/store/internal/model/saleChangeHistory.go +++ b/services/store/internal/model/saleChangeHistory.go @@ -5,19 +5,19 @@ import ( "lone-services/services/store/internal/dao" ) -type SalesPersonHistoryModel struct { +type SaleChangeHistoryModel struct { modelbase.Base } -func (m SalesPersonHistoryModel) TableName() string { - return modelbase.Prefix() + "deposit" +func (m SaleChangeHistoryModel) TableName() string { + return modelbase.Prefix() + "sale_change_history" } -func (m SalesPersonHistoryModel) Init() SalesPersonHistoryModel { +func (m SaleChangeHistoryModel) Init() SaleChangeHistoryModel { m.Table = m.TableName() return m } -func (m SalesPersonHistoryModel) Create(data *dao.SalesPersonHistoryCreate) error { +func (m SaleChangeHistoryModel) Create(data *dao.SaleChangeHistoryCreate) error { return m.Base.Create(data) } diff --git a/services/store/internal/server/storeServer.go b/services/store/internal/server/storeServer.go index ac5f072..9bb5b2e 100644 --- a/services/store/internal/server/storeServer.go +++ b/services/store/internal/server/storeServer.go @@ -108,7 +108,7 @@ func (s *StoreServer) DepositVerify(ctx context.Context, in *store.DepositVerify return l.DepositVerify(in) } -func (s *StoreServer) DepositDown(ctx context.Context, in *store.DepositItemsRequest) (*store.Response, error) { +func (s *StoreServer) DepositDown(ctx context.Context, in *store.DepositItemsRequest) (*store.ExcelExportResponse, error) { l := logic.NewDepositDownLogic(ctx, s.svcCtx) return l.DepositDown(in) } @@ -147,3 +147,13 @@ func (s *StoreServer) SetDef(ctx context.Context, in *store.EmptyRequest) (*stor l := logic.NewSetDefLogic(ctx, s.svcCtx) return l.SetDef(in) } + +func (s *StoreServer) GetInfoById(ctx context.Context, in *store.IdRequest) (*store.InfoResponse, error) { + l := logic.NewGetInfoByIdLogic(ctx, s.svcCtx) + return l.GetInfoById(in) +} + +func (s *StoreServer) GetInfoByIds(ctx context.Context, in *store.IdsRequest) (*store.ItemsResponse, error) { + l := logic.NewGetInfoByIdsLogic(ctx, s.svcCtx) + return l.GetInfoByIds(in) +} diff --git a/services/store/internal/svc/apply.go b/services/store/internal/svc/apply.go new file mode 100644 index 0000000..0a09f59 --- /dev/null +++ b/services/store/internal/svc/apply.go @@ -0,0 +1,158 @@ +package svc + +import ( + "context" + "lone-services/pkg/redis" + "lone-services/pkg/utils" + "strconv" + "time" + + "github.com/zeromicro/go-zero/core/logx" +) + +type ApplySvc struct { +} + +type ApplyData 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"` +} + +const ( + applyProductEditKey = "apply:edit:product:" //产品redis KEY + applyStoreEditKey = "apply:edit:store:" //门店redis KEY + applyEditTimeOut = 60 * 24 + applyMd5Key = "keys:" +) + +func (l *ApplySvc) GetActionApply(uId, objId int) (ApplyData, utils.Status) { + key := l.getKey(applyStoreEditKey, uId, objId) + var data ApplyData + _, err := l.run(key, &data) + return data, err +} + +func (l *ApplySvc) getKey(key string, uId, id int) string { + return key + strconv.Itoa(uId) + "_" + strconv.Itoa(id) +} + +func (l *ApplySvc) Run(uId, objId int, Type uint8, reason string) (string, utils.Status) { + data := ApplyData{ + Uid: uId, + Id: objId, + Reason: reason, + Status: utils.StatusWaitPass, + Type: Type, + } + return l.run(applyStoreEditKey, &data) +} + +func (l *ApplySvc) run(key string, data *ApplyData) (string, utils.Status) { + redisKey := l.getKey(key, data.Uid, data.Id) + ctx := context.Background() + if len(data.Reason) > utils.NumberZero { + data.Time = utils.Now().String() + md5 := utils.MD5Encrypt(strconv.Itoa(data.Uid) + strconv.Itoa(data.Id) + data.Time) + jsonStr := utils.StructToJson(data) + expire := l.getOutTime() + _, err := redis.Client.Set(ctx, redisKey, jsonStr, time.Duration(expire)*time.Minute).Result() + if err != nil { + logx.Error(err) + return md5, utils.SetError(utils.Fail, err.Error()) + } + if data.Status == utils.StatusWaitPass { + _, err = redis.Client.Set(ctx, l.getMd5key(key+applyMd5Key, md5), redisKey, time.Duration(expire)*time.Minute).Result() + if err != nil { + logx.Error(err) + return md5, utils.SetError(utils.Fail, err.Error()) + } + } + return md5, utils.Ok + } + + result, err := redis.Client.Get(ctx, key).Result() + if err != nil && err.Error() != redis.RedisNil { + logx.Error(err) + return utils.StringEmpty, utils.SetError(utils.Fail, err.Error()) + } + if len(result) < utils.NumberFive { + return utils.StringEmpty, utils.Ok + } + if !utils.JsonStringToStruct(result, &data) { + return utils.StringEmpty, utils.SetError(utils.Fail, "数据解析失败") + } + return utils.StringEmpty, utils.Ok +} + +func (l *ApplySvc) getOutTime() int { + outTime := utils.GetConfigInt("apply.time_out") + if outTime <= utils.NumberZero { + outTime = applyEditTimeOut + } + return outTime +} + +func (l *ApplySvc) getMd5key(key, key2 string) string { + return key + key2 +} + +func (l *ApplySvc) SetActionApply(uId, objId int, Type uint8, reason string) utils.Status { + //data := ApplyData{ + // Uid: uId, + // Id: objId, + // Reason: reason, + // Status: utils.StatusWaitPass, + // Type: Type, + //} + //key, err := l.run(applyStoreEditKey, &data) + //if err == utils.Ok { + //TODO 写入日志 + //add := dao.ActionApplyLogCreate{ + // AdminId: uId, + // ObjId: objId, + // Type: Type, + // Status: utils.StatusWaitPass, + //} + //addErr := model.Create(&add) + //if addErr != nil { + // logx.Error(addErr) + // s.DelActionApply(uId, objId) + // return utils.SetError(utils.Fail, addErr) + //} + + // TODO 调取企业微信发消息 队列类型 + //qErr := QueueService{}.Create(utils.WecomStream, dao.WeComJob{ + // ObjId: data.Id, + // ObjType: Type, + // Type: dao.StoreApplyReview, + // Ext: map[string]any{ + // "reason": reason, + // "key": key, + // }, + //}) + // + //if qErr != nil { + // utils.Logger.Error(qErr) + // return qErr + //} + + //return err + //} + //return err + + return utils.Ok +} + +func (l *ApplySvc) DelActionApply(uId, objId int) utils.Status { + key := l.getKey(applyStoreEditKey, uId, objId) + _, err := redis.Client.Del(context.Background(), key).Result() + if err != nil { + logx.Error(err) + return utils.SetError(utils.Fail, err.Error()) + } + return utils.Ok +} diff --git a/services/store/internal/svc/servicecontext.go b/services/store/internal/svc/servicecontext.go index 60d2c5e..40f6130 100644 --- a/services/store/internal/svc/servicecontext.go +++ b/services/store/internal/svc/servicecontext.go @@ -77,6 +77,7 @@ type ServiceContext struct { Prefix string SaleName string OrderName string + UserName string } func NewServiceContext(c config.Config, db *gorm.DB) *ServiceContext { @@ -90,6 +91,11 @@ func NewServiceContext(c config.Config, db *gorm.DB) *ServiceContext { if OrderSvc == utils.StringEmpty { logx.Error("config services.order empty") } + //启动仅读取配置,不建立rpc连接 多个服务就多个 + UserSvc := utils.GetConfigString("services.user") + if UserSvc == utils.StringEmpty { + logx.Error("config services.user empty") + } svcCtx := &ServiceContext{ Config: c, @@ -97,6 +103,7 @@ func NewServiceContext(c config.Config, db *gorm.DB) *ServiceContext { Prefix: utils.GetConfigString("mysql.prefix"), SaleName: SaleSvc, OrderName: OrderSvc, + UserName: UserSvc, } return svcCtx diff --git a/services/store/internal/svc/weCom.go b/services/store/internal/svc/weCom.go new file mode 100644 index 0000000..8b7a1b6 --- /dev/null +++ b/services/store/internal/svc/weCom.go @@ -0,0 +1,17 @@ +package svc + +func WeCom(status, Type int32, id int64, reason string) { + //_ = QueueService{}.Create( + // utils.WecomStream, + // dao.WeComJob{ + // ObjId: id, + // ObjType: utils.EditLogTypeStore, + // Type: Type, + // Action: status, + // Ext: map[string]any{ + // "reason": reason, + // }, + // }, + //) + +} diff --git a/services/store/storeclient/store.go b/services/store/storeclient/store.go index 0495144..8fd29a4 100644 --- a/services/store/storeclient/store.go +++ b/services/store/storeclient/store.go @@ -23,8 +23,12 @@ type ( DepositVerifyRequest = store.DepositVerifyRequest EditRequest = store.EditRequest EmptyRequest = store.EmptyRequest + ExcelExportResponse = store.ExcelExportResponse IdRequest = store.IdRequest + IdsRequest = store.IdsRequest + InfoResponse = store.InfoResponse ItemsRequest = store.ItemsRequest + ItemsResponse = store.ItemsResponse Response = store.Response StatusRequest = store.StatusRequest ToSaleRequest = store.ToSaleRequest @@ -51,7 +55,7 @@ type ( DepositDone(ctx context.Context, in *IdRequest, opts ...grpc.CallOption) (*Response, error) DepositIgnore(ctx context.Context, in *DepositIgnoreRequest, opts ...grpc.CallOption) (*Response, error) DepositVerify(ctx context.Context, in *DepositVerifyRequest, opts ...grpc.CallOption) (*Response, error) - DepositDown(ctx context.Context, in *DepositItemsRequest, opts ...grpc.CallOption) (*Response, error) + DepositDown(ctx context.Context, in *DepositItemsRequest, opts ...grpc.CallOption) (*ExcelExportResponse, error) DepositItems(ctx context.Context, in *DepositItemsRequest, opts ...grpc.CallOption) (*Response, error) DepositIgnoreItems(ctx context.Context, in *DepositVerifyRequest, opts ...grpc.CallOption) (*Response, error) DepositRecover(ctx context.Context, in *IdRequest, opts ...grpc.CallOption) (*Response, error) @@ -59,6 +63,8 @@ type ( WebDepositCreate(ctx context.Context, in *WebDepositCreateRequest, opts ...grpc.CallOption) (*Response, error) WebDepositItems(ctx context.Context, in *WebDepositItemsRequest, opts ...grpc.CallOption) (*Response, error) SetDef(ctx context.Context, in *EmptyRequest, opts ...grpc.CallOption) (*Response, error) + GetInfoById(ctx context.Context, in *IdRequest, opts ...grpc.CallOption) (*InfoResponse, error) + GetInfoByIds(ctx context.Context, in *IdsRequest, opts ...grpc.CallOption) (*ItemsResponse, error) } defaultStore struct { @@ -157,7 +163,7 @@ func (m *defaultStore) DepositVerify(ctx context.Context, in *DepositVerifyReque return client.DepositVerify(ctx, in, opts...) } -func (m *defaultStore) DepositDown(ctx context.Context, in *DepositItemsRequest, opts ...grpc.CallOption) (*Response, error) { +func (m *defaultStore) DepositDown(ctx context.Context, in *DepositItemsRequest, opts ...grpc.CallOption) (*ExcelExportResponse, error) { client := store.NewStoreClient(m.cli.Conn()) return client.DepositDown(ctx, in, opts...) } @@ -196,3 +202,13 @@ func (m *defaultStore) SetDef(ctx context.Context, in *EmptyRequest, opts ...grp client := store.NewStoreClient(m.cli.Conn()) return client.SetDef(ctx, in, opts...) } + +func (m *defaultStore) GetInfoById(ctx context.Context, in *IdRequest, opts ...grpc.CallOption) (*InfoResponse, error) { + client := store.NewStoreClient(m.cli.Conn()) + return client.GetInfoById(ctx, in, opts...) +} + +func (m *defaultStore) GetInfoByIds(ctx context.Context, in *IdsRequest, opts ...grpc.CallOption) (*ItemsResponse, error) { + client := store.NewStoreClient(m.cli.Conn()) + return client.GetInfoByIds(ctx, in, opts...) +} diff --git a/services/store/validator/store.go b/services/store/validator/store.go index d698226..a33b8ea 100644 --- a/services/store/validator/store.go +++ b/services/store/validator/store.go @@ -263,3 +263,16 @@ func (p StoreWebPayPasswordValidator) GetMessage() validate.ValidatorMessages { "Password.required": "支付密码不能为空", } } + +type ApplyEditValidator struct { + Id int64 `form:"id" json:"id" validate:"required"` + Reason string `form:"reason" json:"reason" validate:"required"` +} + +// GetMessage 提示消息 +func (p ApplyEditValidator) GetMessage() validate.ValidatorMessages { + return validate.ValidatorMessages{ + validate.FieldId: validate.FieldIdValue, + "Reason.required": "理由不能为空", + } +}