diff --git a/api/feedback/feedback.go b/api/feedback/feedback.go new file mode 100644 index 0000000..e98ea28 --- /dev/null +++ b/api/feedback/feedback.go @@ -0,0 +1,19 @@ +// ================================================================================= +// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package feedback + +import ( + "context" + + "server/api/feedback/v1" +) + +type IFeedbackV1 interface { + List(ctx context.Context, req *v1.ListReq) (res *v1.ListRes, err error) + Create(ctx context.Context, req *v1.CreateReq) (res *v1.CreateRes, err error) + Update(ctx context.Context, req *v1.UpdateReq) (res *v1.UpdateRes, err error) + UpdateReply(ctx context.Context, req *v1.UpdateReplyReq) (res *v1.UpdateReplyRes, err error) + InfoFeedback(ctx context.Context, req *v1.InfoFeedbackReq) (res *v1.InfoFeedbackRes, err error) +} diff --git a/api/feedback/v1/feedback.go b/api/feedback/v1/feedback.go new file mode 100644 index 0000000..63a3172 --- /dev/null +++ b/api/feedback/v1/feedback.go @@ -0,0 +1,77 @@ +package v1 + +import "github.com/gogf/gf/v2/frame/g" + +type ListReq struct { + g.Meta `path:"/feedback" method:"get" tags:"Feedback" summary:"根据用户查询反馈列表"` + //UserId int64 `json:"userId" v:"required#用户ID不能为空" dc:"用户ID"` + Status int `json:"status" v:"required#状态不能为空" dc:"状态"` + Page int `json:"page" v:"required#页数不能为空" dc:"页数"` + Size int `json:"size" v:"required#页大小不能为"` + FeedbackType int `json:"feedbackType" v:"required#反馈类型不能为空" dc:"反馈类型"` + Title string `json:"title" v:"required#标题不能为空" dc:"标题"` +} + +type ListRes struct { + List interface{} `json:"list" dc:"反馈列表"` + Total int `json:"total" dc:"总数"` +} + +type CreateReq struct { + g.Meta `path:"/feedback" method:"post" tags:"Feedback" summary:"创建反馈"` + Title string `json:"title" v:"required#标题不能为空" dc:"标题"` + Content string `json:"content" v:"required#反馈内容不能为空" dc:"反馈内容"` + FeedbackType int `json:"feedbackType" v:"required#反馈类型不能为空" dc:"反馈类型"` +} + +type CreateRes struct { + Success bool `json:"success" dc:"是否成功"` +} + +type UpdateReq struct { + g.Meta `path:"/feedback" method:"put" tags:"Feedback" summary:"更新反馈"` + Id int64 `json:"id" v:"required#ID不能为空" dc:"ID"` + Title string `json:"title" v:"required#标题不能为空" dc:"标题"` + Content string `json:"content" v:"required#反馈内容不能为空" dc:"反馈内容"` + FeedbackType int `json:"feedbackType" v:"required#反馈类型不能为空" dc:"反馈类型"` +} + +type UpdateRes struct { + Success bool `json:"success" dc:"是否成功"` +} + +//type DeleteReq struct { +// g.Meta `path:"/feedback" method:"delete" tags:"Feedback" summary:"删除反馈"` +// Id int64 `json:"id" v:"required#ID不能为空" dc:"ID"` +//} + +type UpdateReplyReq struct { + g.Meta `path:"/feedback/reply" method:"put" tags:"Feedback" summary:"更新反馈回复"` + Id int64 `json:"id" v:"required#ID不能为空" dc:"ID"` + Reply string `json:"reply" v:"required#回复内容不能为空" dc:"回复内容"` + Status int `json:"status" v:"required#状态不能为空" dc:"状态"` +} + +type UpdateReplyRes struct { + Success bool `json:"success" dc:"是否成功"` +} + +type InfoFeedbackReq struct { + g.Meta `path:"/feedback/{id}" method:"get" tags:"Feedback" summary:"获取反馈信息"` + Id int64 `in:"path" json:"id" v:"required#ID不能为空" dc:"ID"` +} + +type InfoFeedbackRes struct { + Id int64 `json:"id" dc:"ID"` + Title string `json:"title" dc:"标题"` + Content string `json:"content" dc:"反馈内容"` + FeedbackType int `json:"feedbackType" dc:"反馈类型"` + Reply string `json:"reply" dc:"回复"` + Status int `json:"status" dc:"状态"` + CreateTime int64 `json:"createTime" dc:"创建时间"` + UpdateTime int64 `json:"updateTime" dc:"更新时间"` + DeleteTime int64 `json:"deleteTime" dc:"删除时间"` + UserId int64 `json:"userId" dc:"用户ID"` + MerchantId int64 `json:"merchantId" dc:"商户ID"` + StoreId int64 `json:"storeId" dc:"店铺ID"` +} diff --git a/internal/cmd/cmd.go b/internal/cmd/cmd.go index 2739cac..33106f6 100644 --- a/internal/cmd/cmd.go +++ b/internal/cmd/cmd.go @@ -7,6 +7,7 @@ import ( "github.com/gogf/gf/v2/os/gcmd" "server/internal/controller/admin" "server/internal/controller/auth" + "server/internal/controller/feedback" "server/internal/controller/merchant" "server/internal/controller/rewardType" "server/internal/controller/role" @@ -36,6 +37,7 @@ var ( role.NewV1(), merchant.NewV1(), rewardType.NewV1(), + feedback.NewV1(), ) }) }) diff --git a/internal/consts/feedback.go b/internal/consts/feedback.go new file mode 100644 index 0000000..6643819 --- /dev/null +++ b/internal/consts/feedback.go @@ -0,0 +1,8 @@ +package consts + +const ( + Unprocess = iota + 1 + Processing + Processed + Rejected +) diff --git a/internal/controller/feedback/feedback.go b/internal/controller/feedback/feedback.go new file mode 100644 index 0000000..e65ec14 --- /dev/null +++ b/internal/controller/feedback/feedback.go @@ -0,0 +1,5 @@ +// ================================================================================= +// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish. +// ================================================================================= + +package feedback diff --git a/internal/controller/feedback/feedback_new.go b/internal/controller/feedback/feedback_new.go new file mode 100644 index 0000000..49b09fd --- /dev/null +++ b/internal/controller/feedback/feedback_new.go @@ -0,0 +1,15 @@ +// ================================================================================= +// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish. +// ================================================================================= + +package feedback + +import ( + "server/api/feedback" +) + +type ControllerV1 struct{} + +func NewV1() feedback.IFeedbackV1 { + return &ControllerV1{} +} diff --git a/internal/controller/feedback/feedback_v1_create.go b/internal/controller/feedback/feedback_v1_create.go new file mode 100644 index 0000000..aab9200 --- /dev/null +++ b/internal/controller/feedback/feedback_v1_create.go @@ -0,0 +1,28 @@ +package feedback + +import ( + "context" + "github.com/gogf/gf/v2/frame/g" + "server/internal/model" + "server/internal/service" + + "server/api/feedback/v1" +) + +func (c *ControllerV1) Create(ctx context.Context, req *v1.CreateReq) (res *v1.CreateRes, err error) { + + id := g.RequestFromCtx(ctx).GetCtxVar("Id") + + out, err := service.Feedback().Create(ctx, &model.FeedbackCreateIn{ + Content: req.Content, + FeedbackType: req.FeedbackType, + OperatorId: id.Int64(), + Title: req.Title, + }) + if err != nil { + return nil, err + } + return &v1.CreateRes{ + Success: out.Success, + }, nil +} diff --git a/internal/controller/feedback/feedback_v1_info_feedback.go b/internal/controller/feedback/feedback_v1_info_feedback.go new file mode 100644 index 0000000..fd98466 --- /dev/null +++ b/internal/controller/feedback/feedback_v1_info_feedback.go @@ -0,0 +1,33 @@ +package feedback + +import ( + "context" + "server/internal/model" + "server/internal/service" + + "server/api/feedback/v1" +) + +func (c *ControllerV1) InfoFeedback(ctx context.Context, req *v1.InfoFeedbackReq) (res *v1.InfoFeedbackRes, err error) { + out, err := service.Feedback().InfoFeedback(ctx, &model.FeedbackInfoIn{ + Id: req.Id, + }) + + if err != nil { + return nil, err + } + return &v1.InfoFeedbackRes{ + Id: out.Id, + UserId: out.UserId, + Title: out.Title, + Content: out.Content, + FeedbackType: out.FeedbackType, + Status: out.Status, + Reply: out.Reply, + CreateTime: out.CreateTime.Unix(), + UpdateTime: out.UpdateTime.Unix(), + DeleteTime: out.DeleteTime.Unix(), + StoreId: out.StoreId, + MerchantId: out.MerchantId, + }, nil +} diff --git a/internal/controller/feedback/feedback_v1_list.go b/internal/controller/feedback/feedback_v1_list.go new file mode 100644 index 0000000..9fca580 --- /dev/null +++ b/internal/controller/feedback/feedback_v1_list.go @@ -0,0 +1,36 @@ +package feedback + +import ( + "context" + "github.com/gogf/gf/v2/frame/g" + "server/internal/model" + "server/internal/service" + + "server/api/feedback/v1" +) + +func (c *ControllerV1) List(ctx context.Context, req *v1.ListReq) (res *v1.ListRes, err error) { + + // 获取当前角色 + role := g.RequestFromCtx(ctx).GetCtxVar("role").String() + + operatorId := g.RequestFromCtx(ctx).GetCtxVar("id").Int64() + + out, err := service.Feedback().List(ctx, &model.FeedbackIn{ + Page: req.Page, + Size: req.Size, + Keyword: req.Title, + FeedbackType: req.FeedbackType, + Status: req.Status, + Role: role, + OperatorId: operatorId, + }) + + if err != nil { + return nil, err + } + return &v1.ListRes{ + List: out.List, + Total: out.Total, + }, nil +} diff --git a/internal/controller/feedback/feedback_v1_update.go b/internal/controller/feedback/feedback_v1_update.go new file mode 100644 index 0000000..2c50203 --- /dev/null +++ b/internal/controller/feedback/feedback_v1_update.go @@ -0,0 +1,23 @@ +package feedback + +import ( + "context" + "server/internal/model" + "server/internal/service" + + "server/api/feedback/v1" +) + +func (c *ControllerV1) Update(ctx context.Context, req *v1.UpdateReq) (res *v1.UpdateRes, err error) { + + out, err := service.Feedback().Update(ctx, &model.FeedbackUpdateIn{ + Id: req.Id, + Title: req.Title, + Content: req.Content, + FeedbackType: req.FeedbackType, + }) + if err != nil { + return nil, err + } + return &v1.UpdateRes{Success: out.Success}, nil +} diff --git a/internal/controller/feedback/feedback_v1_update_reply.go b/internal/controller/feedback/feedback_v1_update_reply.go new file mode 100644 index 0000000..8362e19 --- /dev/null +++ b/internal/controller/feedback/feedback_v1_update_reply.go @@ -0,0 +1,22 @@ +package feedback + +import ( + "context" + "server/internal/model" + "server/internal/service" + + "server/api/feedback/v1" +) + +func (c *ControllerV1) UpdateReply(ctx context.Context, req *v1.UpdateReplyReq) (res *v1.UpdateReplyRes, err error) { + + out, err := service.Feedback().UpdateReply(ctx, &model.FeedbackUpdateReplyIn{ + Id: req.Id, + Reply: req.Reply, + Status: req.Status, + }) + if err != nil { + return nil, err + } + return &v1.UpdateReplyRes{Success: out.Success}, nil +} diff --git a/internal/dao/internal/admins.go b/internal/dao/internal/admins.go index 7c3f2be..dc72d15 100644 --- a/internal/dao/internal/admins.go +++ b/internal/dao/internal/admins.go @@ -13,9 +13,10 @@ import ( // AdminsDao is the data access object for the table admins. type AdminsDao struct { - table string // table is the underlying table name of the DAO. - group string // group is the database configuration group name of the current DAO. - columns AdminsColumns // columns contains all the column names of Table for convenient usage. + table string // table is the underlying table name of the DAO. + group string // group is the database configuration group name of the current DAO. + columns AdminsColumns // columns contains all the column names of Table for convenient usage. + handlers []gdb.ModelHandler // handlers for customized model modification. } // AdminsColumns defines and stores column names for the table admins. @@ -49,11 +50,12 @@ var adminsColumns = AdminsColumns{ } // NewAdminsDao creates and returns a new DAO object for table data access. -func NewAdminsDao() *AdminsDao { +func NewAdminsDao(handlers ...gdb.ModelHandler) *AdminsDao { return &AdminsDao{ - group: "default", - table: "admins", - columns: adminsColumns, + group: "default", + table: "admins", + columns: adminsColumns, + handlers: handlers, } } @@ -79,7 +81,11 @@ func (dao *AdminsDao) Group() string { // Ctx creates and returns a Model for the current DAO. It automatically sets the context for the current operation. func (dao *AdminsDao) Ctx(ctx context.Context) *gdb.Model { - return dao.DB().Model(dao.table).Safe().Ctx(ctx) + model := dao.DB().Model(dao.table) + for _, handler := range dao.handlers { + model = handler(model) + } + return model.Safe().Ctx(ctx) } // Transaction wraps the transaction logic using function f. diff --git a/internal/dao/internal/merchant_admins.go b/internal/dao/internal/merchant_admins.go index 706ef30..1dacbd5 100644 --- a/internal/dao/internal/merchant_admins.go +++ b/internal/dao/internal/merchant_admins.go @@ -13,9 +13,10 @@ import ( // MerchantAdminsDao is the data access object for the table merchant_admins. type MerchantAdminsDao struct { - table string // table is the underlying table name of the DAO. - group string // group is the database configuration group name of the current DAO. - columns MerchantAdminsColumns // columns contains all the column names of Table for convenient usage. + table string // table is the underlying table name of the DAO. + group string // group is the database configuration group name of the current DAO. + columns MerchantAdminsColumns // columns contains all the column names of Table for convenient usage. + handlers []gdb.ModelHandler // handlers for customized model modification. } // MerchantAdminsColumns defines and stores column names for the table merchant_admins. @@ -59,11 +60,12 @@ var merchantAdminsColumns = MerchantAdminsColumns{ } // NewMerchantAdminsDao creates and returns a new DAO object for table data access. -func NewMerchantAdminsDao() *MerchantAdminsDao { +func NewMerchantAdminsDao(handlers ...gdb.ModelHandler) *MerchantAdminsDao { return &MerchantAdminsDao{ - group: "default", - table: "merchant_admins", - columns: merchantAdminsColumns, + group: "default", + table: "merchant_admins", + columns: merchantAdminsColumns, + handlers: handlers, } } @@ -89,7 +91,11 @@ func (dao *MerchantAdminsDao) Group() string { // Ctx creates and returns a Model for the current DAO. It automatically sets the context for the current operation. func (dao *MerchantAdminsDao) Ctx(ctx context.Context) *gdb.Model { - return dao.DB().Model(dao.table).Safe().Ctx(ctx) + model := dao.DB().Model(dao.table) + for _, handler := range dao.handlers { + model = handler(model) + } + return model.Safe().Ctx(ctx) } // Transaction wraps the transaction logic using function f. diff --git a/internal/dao/internal/merchants.go b/internal/dao/internal/merchants.go index 76bbac8..69d7ee7 100644 --- a/internal/dao/internal/merchants.go +++ b/internal/dao/internal/merchants.go @@ -13,9 +13,10 @@ import ( // MerchantsDao is the data access object for the table merchants. type MerchantsDao struct { - table string // table is the underlying table name of the DAO. - group string // group is the database configuration group name of the current DAO. - columns MerchantsColumns // columns contains all the column names of Table for convenient usage. + table string // table is the underlying table name of the DAO. + group string // group is the database configuration group name of the current DAO. + columns MerchantsColumns // columns contains all the column names of Table for convenient usage. + handlers []gdb.ModelHandler // handlers for customized model modification. } // MerchantsColumns defines and stores column names for the table merchants. @@ -69,11 +70,12 @@ var merchantsColumns = MerchantsColumns{ } // NewMerchantsDao creates and returns a new DAO object for table data access. -func NewMerchantsDao() *MerchantsDao { +func NewMerchantsDao(handlers ...gdb.ModelHandler) *MerchantsDao { return &MerchantsDao{ - group: "default", - table: "merchants", - columns: merchantsColumns, + group: "default", + table: "merchants", + columns: merchantsColumns, + handlers: handlers, } } @@ -99,7 +101,11 @@ func (dao *MerchantsDao) Group() string { // Ctx creates and returns a Model for the current DAO. It automatically sets the context for the current operation. func (dao *MerchantsDao) Ctx(ctx context.Context) *gdb.Model { - return dao.DB().Model(dao.table).Safe().Ctx(ctx) + model := dao.DB().Model(dao.table) + for _, handler := range dao.handlers { + model = handler(model) + } + return model.Safe().Ctx(ctx) } // Transaction wraps the transaction logic using function f. diff --git a/internal/dao/internal/reward_types.go b/internal/dao/internal/reward_types.go index ee07106..9703427 100644 --- a/internal/dao/internal/reward_types.go +++ b/internal/dao/internal/reward_types.go @@ -13,9 +13,10 @@ import ( // RewardTypesDao is the data access object for the table reward_types. type RewardTypesDao struct { - table string // table is the underlying table name of the DAO. - group string // group is the database configuration group name of the current DAO. - columns RewardTypesColumns // columns contains all the column names of Table for convenient usage. + table string // table is the underlying table name of the DAO. + group string // group is the database configuration group name of the current DAO. + columns RewardTypesColumns // columns contains all the column names of Table for convenient usage. + handlers []gdb.ModelHandler // handlers for customized model modification. } // RewardTypesColumns defines and stores column names for the table reward_types. @@ -43,11 +44,12 @@ var rewardTypesColumns = RewardTypesColumns{ } // NewRewardTypesDao creates and returns a new DAO object for table data access. -func NewRewardTypesDao() *RewardTypesDao { +func NewRewardTypesDao(handlers ...gdb.ModelHandler) *RewardTypesDao { return &RewardTypesDao{ - group: "default", - table: "reward_types", - columns: rewardTypesColumns, + group: "default", + table: "reward_types", + columns: rewardTypesColumns, + handlers: handlers, } } @@ -73,7 +75,11 @@ func (dao *RewardTypesDao) Group() string { // Ctx creates and returns a Model for the current DAO. It automatically sets the context for the current operation. func (dao *RewardTypesDao) Ctx(ctx context.Context) *gdb.Model { - return dao.DB().Model(dao.table).Safe().Ctx(ctx) + model := dao.DB().Model(dao.table) + for _, handler := range dao.handlers { + model = handler(model) + } + return model.Safe().Ctx(ctx) } // Transaction wraps the transaction logic using function f. diff --git a/internal/dao/internal/roles.go b/internal/dao/internal/roles.go index c8c80b4..563bfdb 100644 --- a/internal/dao/internal/roles.go +++ b/internal/dao/internal/roles.go @@ -13,9 +13,10 @@ import ( // RolesDao is the data access object for the table roles. type RolesDao struct { - table string // table is the underlying table name of the DAO. - group string // group is the database configuration group name of the current DAO. - columns RolesColumns // columns contains all the column names of Table for convenient usage. + table string // table is the underlying table name of the DAO. + group string // group is the database configuration group name of the current DAO. + columns RolesColumns // columns contains all the column names of Table for convenient usage. + handlers []gdb.ModelHandler // handlers for customized model modification. } // RolesColumns defines and stores column names for the table roles. @@ -45,11 +46,12 @@ var rolesColumns = RolesColumns{ } // NewRolesDao creates and returns a new DAO object for table data access. -func NewRolesDao() *RolesDao { +func NewRolesDao(handlers ...gdb.ModelHandler) *RolesDao { return &RolesDao{ - group: "default", - table: "roles", - columns: rolesColumns, + group: "default", + table: "roles", + columns: rolesColumns, + handlers: handlers, } } @@ -75,7 +77,11 @@ func (dao *RolesDao) Group() string { // Ctx creates and returns a Model for the current DAO. It automatically sets the context for the current operation. func (dao *RolesDao) Ctx(ctx context.Context) *gdb.Model { - return dao.DB().Model(dao.table).Safe().Ctx(ctx) + model := dao.DB().Model(dao.table) + for _, handler := range dao.handlers { + model = handler(model) + } + return model.Safe().Ctx(ctx) } // Transaction wraps the transaction logic using function f. diff --git a/internal/dao/internal/stores.go b/internal/dao/internal/stores.go index b97c4c8..9725b7c 100644 --- a/internal/dao/internal/stores.go +++ b/internal/dao/internal/stores.go @@ -13,9 +13,10 @@ import ( // StoresDao is the data access object for the table stores. type StoresDao struct { - table string // table is the underlying table name of the DAO. - group string // group is the database configuration group name of the current DAO. - columns StoresColumns // columns contains all the column names of Table for convenient usage. + table string // table is the underlying table name of the DAO. + group string // group is the database configuration group name of the current DAO. + columns StoresColumns // columns contains all the column names of Table for convenient usage. + handlers []gdb.ModelHandler // handlers for customized model modification. } // StoresColumns defines and stores column names for the table stores. @@ -49,11 +50,12 @@ var storesColumns = StoresColumns{ } // NewStoresDao creates and returns a new DAO object for table data access. -func NewStoresDao() *StoresDao { +func NewStoresDao(handlers ...gdb.ModelHandler) *StoresDao { return &StoresDao{ - group: "default", - table: "stores", - columns: storesColumns, + group: "default", + table: "stores", + columns: storesColumns, + handlers: handlers, } } @@ -79,7 +81,11 @@ func (dao *StoresDao) Group() string { // Ctx creates and returns a Model for the current DAO. It automatically sets the context for the current operation. func (dao *StoresDao) Ctx(ctx context.Context) *gdb.Model { - return dao.DB().Model(dao.table).Safe().Ctx(ctx) + model := dao.DB().Model(dao.table) + for _, handler := range dao.handlers { + model = handler(model) + } + return model.Safe().Ctx(ctx) } // Transaction wraps the transaction logic using function f. diff --git a/internal/dao/internal/users.go b/internal/dao/internal/users.go index 448ffe6..45b4639 100644 --- a/internal/dao/internal/users.go +++ b/internal/dao/internal/users.go @@ -13,9 +13,10 @@ import ( // UsersDao is the data access object for the table users. type UsersDao struct { - table string // table is the underlying table name of the DAO. - group string // group is the database configuration group name of the current DAO. - columns UsersColumns // columns contains all the column names of Table for convenient usage. + table string // table is the underlying table name of the DAO. + group string // group is the database configuration group name of the current DAO. + columns UsersColumns // columns contains all the column names of Table for convenient usage. + handlers []gdb.ModelHandler // handlers for customized model modification. } // UsersColumns defines and stores column names for the table users. @@ -59,11 +60,12 @@ var usersColumns = UsersColumns{ } // NewUsersDao creates and returns a new DAO object for table data access. -func NewUsersDao() *UsersDao { +func NewUsersDao(handlers ...gdb.ModelHandler) *UsersDao { return &UsersDao{ - group: "default", - table: "users", - columns: usersColumns, + group: "default", + table: "users", + columns: usersColumns, + handlers: handlers, } } @@ -89,7 +91,11 @@ func (dao *UsersDao) Group() string { // Ctx creates and returns a Model for the current DAO. It automatically sets the context for the current operation. func (dao *UsersDao) Ctx(ctx context.Context) *gdb.Model { - return dao.DB().Model(dao.table).Safe().Ctx(ctx) + model := dao.DB().Model(dao.table) + for _, handler := range dao.handlers { + model = handler(model) + } + return model.Safe().Ctx(ctx) } // Transaction wraps the transaction logic using function f. diff --git a/internal/logic/feedback/feedback.go b/internal/logic/feedback/feedback.go new file mode 100644 index 0000000..ba0be78 --- /dev/null +++ b/internal/logic/feedback/feedback.go @@ -0,0 +1,172 @@ +package feedback + +import ( + "context" + "server/internal/consts" + "server/internal/dao" + "server/internal/model" + "server/internal/model/do" + "server/internal/service" + "server/utility/ecode" +) + +type sFeedback struct { +} + +func New() service.IFeedback { + return &sFeedback{} +} + +func init() { + service.RegisterFeedback(New()) +} + +func (s *sFeedback) List(ctx context.Context, in *model.FeedbackIn) (out *model.FeedbackOut, err error) { + m := dao.Feedbacks.Ctx(ctx) + + // 默认分页 + if in.Page == 0 { + in.Page = 1 + } + if in.Size == 0 { + in.Size = 10 + } + + // 判断角色 + if in.Role == consts.MerchantRoleCode { + m = m.Where(do.Feedbacks{ + MerchatId: in.OperatorId, + }) + } else if in.Role == consts.StoreRoleCode { + m = m.Where(do.Feedbacks{ + StoreId: in.OperatorId, + }) + } else if in.Role == consts.UserRoleCode { + m = m.Where(do.Feedbacks{ + UserId: in.OperatorId, + }) + } + + // 构建查询条件 + if in.Keyword != "" { + m = m.WhereLike(dao.Feedbacks.Columns().Title, "%"+in.Keyword+"%") + } + + if in.FeedbackType > 0 { + m = m.Where(do.Feedbacks{ + FeedbackType: in.FeedbackType, + }) + } + + if in.Status > 0 { + m = m.Where(do.Feedbacks{ + Status: in.Status, + }) + } + + // 分页查询 + list := make([]model.Feedback, 0) + var total int + err = m.Page(in.Page, in.Size).OrderDesc(dao.Feedbacks.Columns().CreatedAt).OrderDesc(dao.Feedbacks.Columns().Id).ScanAndCount(&list, &total, false) + if err != nil { + return nil, err + } + + return &model.FeedbackOut{ + List: list, + Total: total, + }, nil +} + +func (s *sFeedback) Create(ctx context.Context, in *model.FeedbackCreateIn) (out *model.FeedbackCreateOut, err error) { + + // 暂定只能用户提交反馈信息 + _, err = dao.Feedbacks.Ctx(ctx).Insert(do.Feedbacks{ + Title: in.Title, + Content: in.Content, + FeedbackType: in.FeedbackType, + UserId: in.OperatorId, + }) + if err != nil { + return nil, err + } + return &model.FeedbackCreateOut{ + Success: true, + }, nil +} + +func (s *sFeedback) Update(ctx context.Context, in *model.FeedbackUpdateIn) (out *model.FeedbackUpdateOut, err error) { + + // 暂定用户修改反馈信息 + + // 是否存在该信息 + var feedback *model.Feedback + err = dao.Feedbacks.Ctx(ctx).Where(do.Feedbacks{Id: in.Id}).Scan(&feedback) + if err != nil || feedback == nil { + return nil, ecode.Fail.Sub("未查询到该反馈信息") + } + + // 该反馈信息是否未处理 + if feedback.Status != consts.Unprocess { + return nil, ecode.Fail.Sub("该反馈信息已处理") + } + + _, err = dao.Feedbacks.Ctx(ctx).Where(do.Feedbacks{Id: in.Id}).Update(do.Feedbacks{ + Title: in.Title, + Content: in.Content, + FeedbackType: in.FeedbackType, + }) + + if err != nil { + return nil, ecode.Fail.Sub("更新反馈信息出现异常") + } + + return &model.FeedbackUpdateOut{ + Success: true, + }, nil +} + +func (s *sFeedback) UpdateReply(ctx context.Context, in *model.FeedbackUpdateReplyIn) (out *model.FeedbackUpdateReplyOut, err error) { + + var feedback *model.Feedback + err = dao.Feedbacks.Ctx(ctx).Where(do.Feedbacks{Id: in.Id}).Scan(&feedback) + + if err != nil || feedback == nil { + return nil, ecode.Fail.Sub("该反馈信息不存在") + } + + if feedback.Status == consts.Processed || feedback.Status == consts.Rejected { + return nil, ecode.Fail.Sub("该反馈信息已处理") + } + + _, err = dao.Feedbacks.Ctx(ctx).Where(do.Feedbacks{Id: in.Id}).Update(do.Feedbacks{ + Reply: in.Reply, + Status: in.Status, + }) + + if err != nil { + return nil, err + } + + return &model.FeedbackUpdateReplyOut{ + Success: true, + }, nil +} + +func (s *sFeedback) InfoFeedback(ctx context.Context, in *model.FeedbackInfoIn) (out *model.FeedbackInfoOut, err error) { + + exist, err := dao.Feedbacks.Ctx(ctx).Where(do.Feedbacks{Id: in.Id}).Exist() + if err != nil { + return nil, ecode.Fail.Sub("查询该反馈信息失败") + } + + if !exist { + return nil, ecode.Params.Sub("该反馈信息不存在") + } + + err = dao.Feedbacks.Ctx(ctx).Where(do.Feedbacks{Id: in.Id}).Scan(&out) + if err != nil { + return nil, ecode.Fail.Sub("查询该反馈信息失败") + } + return out, nil +} diff --git a/internal/logic/logic.go b/internal/logic/logic.go index f6ea15f..e846597 100644 --- a/internal/logic/logic.go +++ b/internal/logic/logic.go @@ -6,6 +6,7 @@ package logic import ( _ "server/internal/logic/admin" + _ "server/internal/logic/feedback" _ "server/internal/logic/merchant" _ "server/internal/logic/merchantAdmin" _ "server/internal/logic/rewardType" diff --git a/internal/model/feedback.go b/internal/model/feedback.go new file mode 100644 index 0000000..7e8c4a8 --- /dev/null +++ b/internal/model/feedback.go @@ -0,0 +1,96 @@ +package model + +import ( + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/os/gtime" +) + +type Feedback struct { + g.Meta `orm:"table:feedback"` + Id int64 `json:"id" dc:"ID" orm:"id,primary"` + UserId int64 `json:"user_id" dc:"用户ID" orm:"user_id"` + Title string `json:"title" dc:"反馈标题" orm:"title"` + Content string `json:"content" dc:"反馈内容" orm:"content"` + FeedbackType int `json:"feedback_type" dc:"反馈类型" orm:"feedback_type"` + Status int `json:"status" dc:"状态:1=已处理,2=未处理" orm:"status"` + Reply string `json:"reply" dc:"管理员回复" orm:"reply"` + CreateTime *gtime.Time `json:"create_time" dc:"创建时间" orm:"create_time"` + UpdateTime *gtime.Time `json:"update_time" dc:"更新时间" orm:"update_time"` + DeleteTime *gtime.Time `json:"delete_time" dc:"删除时间" orm:"delete_time"` + StoreId int64 `json:"store_id" dc:"店铺ID" orm:"store_id"` + MerchantId int64 `json:"merchant_id" dc:"商户ID" orm:"merchant_id"` +} + +type FeedbackIn struct { + Keyword string + Page int + Size int + FeedbackType int + Status int + Role string + OperatorId int64 +} + +type FeedbackOut struct { + List []Feedback + Total int +} + +type FeedbackCreateIn struct { + Title string + Content string + FeedbackType int + OperatorId int64 +} + +type FeedbackCreateOut struct { + Success bool `json:"success" dc:"是否成功"` +} + +// FeedbackUpdateIn 修改反馈信息传入参数 +type FeedbackUpdateIn struct { + Id int64 + Title string + Content string + FeedbackType int + //OperatorId int64 + //OperatorRole string +} + +// FeedbackUpdateOut 修改反馈信息返回参数 +type FeedbackUpdateOut struct { + Success bool `json:"success" dc:"是否成功"` +} + +// FeedbackUpdateReplyIn 修改反馈回复信息传入参数 +type FeedbackUpdateReplyIn struct { + Id int64 + Reply string + Status int +} + +// FeedbackUpdateReplyOut 修改反馈回复信息返回参数 +type FeedbackUpdateReplyOut struct { + Success bool `json:"success" dc:"是否成功"` +} + +// FeedbackInfoIn 反馈信息详情传入参数 +type FeedbackInfoIn struct { + Id int64 +} + +// FeedbackInfoOut 反馈信息详情返回参数 +type FeedbackInfoOut struct { + Id int64 + UserId int64 + Title string + Content string + FeedbackType int + Status int + Reply string + CreateTime *gtime.Time + UpdateTime *gtime.Time + DeleteTime *gtime.Time + StoreId int64 + MerchantId int64 +} diff --git a/internal/service/feedback.go b/internal/service/feedback.go new file mode 100644 index 0000000..744da4b --- /dev/null +++ b/internal/service/feedback.go @@ -0,0 +1,36 @@ +// ================================================================================ +// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT. +// You can delete these comments if you wish manually maintain this interface file. +// ================================================================================ + +package service + +import ( + "context" + "server/internal/model" +) + +type ( + IFeedback interface { + List(ctx context.Context, in *model.FeedbackIn) (out *model.FeedbackOut, err error) + Create(ctx context.Context, in *model.FeedbackCreateIn) (out *model.FeedbackCreateOut, err error) + Update(ctx context.Context, in *model.FeedbackUpdateIn) (out *model.FeedbackUpdateOut, err error) + UpdateReply(ctx context.Context, in *model.FeedbackUpdateReplyIn) (out *model.FeedbackUpdateReplyOut, err error) + InfoFeedback(ctx context.Context, in *model.FeedbackInfoIn) (out *model.FeedbackInfoOut, err error) + } +) + +var ( + localFeedback IFeedback +) + +func Feedback() IFeedback { + if localFeedback == nil { + panic("implement not found for interface IFeedback, forgot register?") + } + return localFeedback +} + +func RegisterFeedback(i IFeedback) { + localFeedback = i +} diff --git a/utility/myCasbin/casbin.go b/utility/myCasbin/casbin.go index d27e161..60075e7 100644 --- a/utility/myCasbin/casbin.go +++ b/utility/myCasbin/casbin.go @@ -34,10 +34,19 @@ func init() { } enforcer.LoadPolicy() - enforcer.AddGroupingPolicy(consts.UserRoleCode, consts.GuestRoleCode) // 用户继承游客角色权限 - + enforcer.AddGroupingPolicy(consts.UserRoleCode, consts.GuestRoleCode) // 用户继承游客角色权限 + enforcer.AddGroupingPolicy(consts.StoreRoleCode, consts.UserRoleCode) // 门店继承用户角色权限 enforcer.AddGroupingPolicy(consts.MerchantRoleCode, consts.StoreRoleCode) // 商户继承门店角色权限 enforcer.AddGroupingPolicy(consts.AdminRoleCode, consts.MerchantRoleCode) // 管理员继承商户角色权限 + // 用户 + { + // 反馈信息 + enforcer.AddPolicy("user", "/x/feedback", "GET", "获取反馈信息列表") + enforcer.AddPolicy("user", "/x/feedback", "POST", "添加反馈信息") + enforcer.AddPolicy("user", "/x/feedback", "PUT", "更新反馈信息") + //enforcer.AddPolicy("user", "/x/feedback/*", "DELETE", "删除反馈信息")* + enforcer.AddPolicy("user", "/x/feedback/*", "Get", "查询反馈详情") + } // 门店 { // 奖励类型