feat: 新增养成管理后台
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
package cultivatecontent
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"hotgo/internal/model/input/form"
|
||||
"hotgo/internal/model/input/sysin"
|
||||
)
|
||||
|
||||
type ListReq struct {
|
||||
g.Meta `path:"/cultivate/content/list" method:"get" tags:"养成管理" summary:"获取动态或评论审核列表"`
|
||||
sysin.CultivateContentListInp
|
||||
}
|
||||
type ListRes struct {
|
||||
form.PageRes
|
||||
List []*sysin.CultivateContentListModel `json:"list"`
|
||||
}
|
||||
type ReviewReq struct {
|
||||
g.Meta `path:"/cultivate/content/review" method:"post" tags:"养成管理" summary:"审核或下架动态评论"`
|
||||
sysin.CultivateContentReviewInp
|
||||
}
|
||||
type ReviewRes struct{}
|
||||
type ReportListReq struct {
|
||||
g.Meta `path:"/cultivate/reports/list" method:"get" tags:"养成管理" summary:"获取举报列表"`
|
||||
sysin.CultivateReportListInp
|
||||
}
|
||||
type ReportListRes struct {
|
||||
form.PageRes
|
||||
List []*sysin.CultivateReportListModel `json:"list"`
|
||||
}
|
||||
type ReportHandleReq struct {
|
||||
g.Meta `path:"/cultivate/reports/handle" method:"post" tags:"养成管理" summary:"处理举报"`
|
||||
sysin.CultivateReportHandleInp
|
||||
}
|
||||
type ReportHandleRes struct{}
|
||||
type LogListReq struct {
|
||||
g.Meta `path:"/cultivate/logs/list" method:"get" tags:"养成管理" summary:"获取养成管理操作日志"`
|
||||
sysin.CultivateOperationLogListInp
|
||||
}
|
||||
type LogListRes struct {
|
||||
form.PageRes
|
||||
List []*sysin.CultivateOperationLogListModel `json:"list"`
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package cultivateflower
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"hotgo/internal/model/input/form"
|
||||
"hotgo/internal/model/input/sysin"
|
||||
)
|
||||
|
||||
type ListReq struct {
|
||||
g.Meta `path:"/cultivate/flowers/list" method:"get" tags:"养成管理" summary:"获取花种列表"`
|
||||
sysin.CultivateFlowerListInp
|
||||
}
|
||||
type ListRes struct {
|
||||
form.PageRes
|
||||
List []*sysin.CultivateFlowerListModel `json:"list"`
|
||||
}
|
||||
type ViewReq struct {
|
||||
g.Meta `path:"/cultivate/flowers/view" method:"get" tags:"养成管理" summary:"获取花种详情"`
|
||||
sysin.CultivateFlowerViewInp
|
||||
}
|
||||
type ViewRes struct {
|
||||
*sysin.CultivateFlowerViewModel
|
||||
}
|
||||
type EditReq struct {
|
||||
g.Meta `path:"/cultivate/flowers/edit" method:"post" tags:"养成管理" summary:"新建或编辑花种及阶段规则"`
|
||||
sysin.CultivateFlowerEditInp
|
||||
}
|
||||
type EditRes struct{}
|
||||
type StatusReq struct {
|
||||
g.Meta `path:"/cultivate/flowers/status" method:"post" tags:"养成管理" summary:"更新花种上下架状态"`
|
||||
sysin.CultivateFlowerStatusInp
|
||||
}
|
||||
type StatusRes struct{}
|
||||
@@ -34,6 +34,16 @@ gfcli:
|
||||
gJsonSupport: true
|
||||
clear: false
|
||||
|
||||
- link: "mysql:root:root@tcp(127.0.0.1:3306)/cultivate?loc=Local&parseTime=true&charset=utf8mb4"
|
||||
group: "cultivate"
|
||||
tables: "cv_flower_catalog,cv_flower_stage_rule,cv_feed_post,cv_feed_media,cv_feed_comment,cv_feed_report,cv_content_audit_log,cv_admin_operation_log"
|
||||
removePrefix: "cv_"
|
||||
descriptionTag: true
|
||||
noModelComment: true
|
||||
jsonCase: "CamelLower"
|
||||
gJsonSupport: true
|
||||
clear: false
|
||||
|
||||
|
||||
# service: # 生成业务配置
|
||||
# srcFolder: "internal/logic"
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
package consts
|
||||
|
||||
import (
|
||||
"hotgo/internal/library/dict"
|
||||
"hotgo/internal/model"
|
||||
)
|
||||
|
||||
const (
|
||||
CultivateFlowerOnline = "online"
|
||||
CultivateFlowerOffline = "offline"
|
||||
CultivateFlowerActivityOnly = "activity_only"
|
||||
CultivateFlowerMaintenance = "maintenance"
|
||||
)
|
||||
|
||||
var CultivateFlowerStatusOptions = []*model.Option{
|
||||
dict.GenSuccessOption(CultivateFlowerOnline, "已上架"),
|
||||
dict.GenDefaultOption(CultivateFlowerOffline, "已下架"),
|
||||
dict.GenPrimaryOption(CultivateFlowerActivityOnly, "仅活动"),
|
||||
dict.GenWarningOption(CultivateFlowerMaintenance, "维护中"),
|
||||
}
|
||||
|
||||
var CultivateContentStatusOptions = []*model.Option{
|
||||
dict.GenWarningOption("reviewing", "待审核"),
|
||||
dict.GenSuccessOption("published", "已发布"),
|
||||
dict.GenErrorOption("rejected", "已拒绝"),
|
||||
dict.GenDefaultOption("taken_down", "已下架"),
|
||||
dict.GenDefaultOption("deleted", "已删除"),
|
||||
}
|
||||
|
||||
var CultivateReportStatusOptions = []*model.Option{
|
||||
dict.GenWarningOption("submitted", "待处理"),
|
||||
dict.GenPrimaryOption("processing", "处理中"),
|
||||
dict.GenSuccessOption("resolved", "已处理"),
|
||||
dict.GenDefaultOption("rejected", "已驳回"),
|
||||
}
|
||||
|
||||
var CultivateContentTypeOptions = []*model.Option{
|
||||
dict.GenPrimaryOption("feed_post", "动态"),
|
||||
dict.GenInfoOption("feed_comment", "评论"),
|
||||
}
|
||||
|
||||
var CultivateReportObjectTypeOptions = []*model.Option{
|
||||
dict.GenPrimaryOption("feed_post", "动态"),
|
||||
dict.GenInfoOption("feed_comment", "评论"),
|
||||
dict.GenDefaultOption("user", "用户"),
|
||||
}
|
||||
|
||||
func init() {
|
||||
dict.RegisterEnums("CultivateFlowerStatusOptions", "养成花种状态", CultivateFlowerStatusOptions)
|
||||
dict.RegisterEnums("CultivateContentStatusOptions", "养成内容状态", CultivateContentStatusOptions)
|
||||
dict.RegisterEnums("CultivateReportStatusOptions", "养成举报状态", CultivateReportStatusOptions)
|
||||
dict.RegisterEnums("CultivateContentTypeOptions", "养成内容类型", CultivateContentTypeOptions)
|
||||
dict.RegisterEnums("CultivateReportObjectTypeOptions", "养成举报对象类型", CultivateReportObjectTypeOptions)
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package sys
|
||||
|
||||
import (
|
||||
"context"
|
||||
"hotgo/api/admin/cultivatecontent"
|
||||
"hotgo/internal/model/input/sysin"
|
||||
"hotgo/internal/service"
|
||||
)
|
||||
|
||||
var CultivateContent = cCultivateContent{}
|
||||
|
||||
type cCultivateContent struct{}
|
||||
|
||||
func (*cCultivateContent) List(ctx context.Context, req *cultivatecontent.ListReq) (res *cultivatecontent.ListRes, err error) {
|
||||
list, total, err := service.SysCultivateContent().List(ctx, &req.CultivateContentListInp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if list == nil {
|
||||
list = []*sysin.CultivateContentListModel{}
|
||||
}
|
||||
res = &cultivatecontent.ListRes{List: list}
|
||||
res.PageRes.Pack(req, total)
|
||||
return
|
||||
}
|
||||
func (*cCultivateContent) Review(ctx context.Context, req *cultivatecontent.ReviewReq) (res *cultivatecontent.ReviewRes, err error) {
|
||||
err = service.SysCultivateContent().Review(ctx, &req.CultivateContentReviewInp)
|
||||
return
|
||||
}
|
||||
func (*cCultivateContent) ReportList(ctx context.Context, req *cultivatecontent.ReportListReq) (res *cultivatecontent.ReportListRes, err error) {
|
||||
list, total, err := service.SysCultivateContent().ReportList(ctx, &req.CultivateReportListInp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if list == nil {
|
||||
list = []*sysin.CultivateReportListModel{}
|
||||
}
|
||||
res = &cultivatecontent.ReportListRes{List: list}
|
||||
res.PageRes.Pack(req, total)
|
||||
return
|
||||
}
|
||||
func (*cCultivateContent) ReportHandle(ctx context.Context, req *cultivatecontent.ReportHandleReq) (res *cultivatecontent.ReportHandleRes, err error) {
|
||||
err = service.SysCultivateContent().ReportHandle(ctx, &req.CultivateReportHandleInp)
|
||||
return
|
||||
}
|
||||
func (*cCultivateContent) LogList(ctx context.Context, req *cultivatecontent.LogListReq) (res *cultivatecontent.LogListRes, err error) {
|
||||
list, total, err := service.SysCultivateContent().LogList(ctx, &req.CultivateOperationLogListInp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if list == nil {
|
||||
list = []*sysin.CultivateOperationLogListModel{}
|
||||
}
|
||||
res = &cultivatecontent.LogListRes{List: list}
|
||||
res.PageRes.Pack(req, total)
|
||||
return
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package sys
|
||||
|
||||
import (
|
||||
"context"
|
||||
"hotgo/api/admin/cultivateflower"
|
||||
"hotgo/internal/model/input/sysin"
|
||||
"hotgo/internal/service"
|
||||
)
|
||||
|
||||
var CultivateFlower = cCultivateFlower{}
|
||||
|
||||
type cCultivateFlower struct{}
|
||||
|
||||
func (*cCultivateFlower) List(ctx context.Context, req *cultivateflower.ListReq) (res *cultivateflower.ListRes, err error) {
|
||||
list, total, err := service.SysCultivateFlower().List(ctx, &req.CultivateFlowerListInp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if list == nil {
|
||||
list = []*sysin.CultivateFlowerListModel{}
|
||||
}
|
||||
res = &cultivateflower.ListRes{List: list}
|
||||
res.PageRes.Pack(req, total)
|
||||
return
|
||||
}
|
||||
func (*cCultivateFlower) View(ctx context.Context, req *cultivateflower.ViewReq) (res *cultivateflower.ViewRes, err error) {
|
||||
data, err := service.SysCultivateFlower().View(ctx, &req.CultivateFlowerViewInp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &cultivateflower.ViewRes{CultivateFlowerViewModel: data}, nil
|
||||
}
|
||||
func (*cCultivateFlower) Edit(ctx context.Context, req *cultivateflower.EditReq) (res *cultivateflower.EditRes, err error) {
|
||||
err = service.SysCultivateFlower().Edit(ctx, &req.CultivateFlowerEditInp)
|
||||
return
|
||||
}
|
||||
func (*cCultivateFlower) Status(ctx context.Context, req *cultivateflower.StatusReq) (res *cultivateflower.StatusRes, err error) {
|
||||
err = service.SysCultivateFlower().Status(ctx, &req.CultivateFlowerStatusInp)
|
||||
return
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
// =================================================================================
|
||||
// This file is auto-generated by the GoFrame CLI tool. You may modify it as needed.
|
||||
// =================================================================================
|
||||
|
||||
package dao
|
||||
|
||||
import (
|
||||
"hotgo/internal/dao/internal"
|
||||
)
|
||||
|
||||
// adminOperationLogDao is the data access object for the table cv_admin_operation_log.
|
||||
// You can define custom methods on it to extend its functionality as needed.
|
||||
type adminOperationLogDao struct {
|
||||
*internal.AdminOperationLogDao
|
||||
}
|
||||
|
||||
var (
|
||||
// AdminOperationLog is a globally accessible object for table cv_admin_operation_log operations.
|
||||
AdminOperationLog = adminOperationLogDao{internal.NewAdminOperationLogDao()}
|
||||
)
|
||||
|
||||
// Add your custom methods and functionality below.
|
||||
@@ -0,0 +1,22 @@
|
||||
// =================================================================================
|
||||
// This file is auto-generated by the GoFrame CLI tool. You may modify it as needed.
|
||||
// =================================================================================
|
||||
|
||||
package dao
|
||||
|
||||
import (
|
||||
"hotgo/internal/dao/internal"
|
||||
)
|
||||
|
||||
// contentAuditLogDao is the data access object for the table cv_content_audit_log.
|
||||
// You can define custom methods on it to extend its functionality as needed.
|
||||
type contentAuditLogDao struct {
|
||||
*internal.ContentAuditLogDao
|
||||
}
|
||||
|
||||
var (
|
||||
// ContentAuditLog is a globally accessible object for table cv_content_audit_log operations.
|
||||
ContentAuditLog = contentAuditLogDao{internal.NewContentAuditLogDao()}
|
||||
)
|
||||
|
||||
// Add your custom methods and functionality below.
|
||||
@@ -0,0 +1,22 @@
|
||||
// =================================================================================
|
||||
// This file is auto-generated by the GoFrame CLI tool. You may modify it as needed.
|
||||
// =================================================================================
|
||||
|
||||
package dao
|
||||
|
||||
import (
|
||||
"hotgo/internal/dao/internal"
|
||||
)
|
||||
|
||||
// feedCommentDao is the data access object for the table cv_feed_comment.
|
||||
// You can define custom methods on it to extend its functionality as needed.
|
||||
type feedCommentDao struct {
|
||||
*internal.FeedCommentDao
|
||||
}
|
||||
|
||||
var (
|
||||
// FeedComment is a globally accessible object for table cv_feed_comment operations.
|
||||
FeedComment = feedCommentDao{internal.NewFeedCommentDao()}
|
||||
)
|
||||
|
||||
// Add your custom methods and functionality below.
|
||||
@@ -0,0 +1,22 @@
|
||||
// =================================================================================
|
||||
// This file is auto-generated by the GoFrame CLI tool. You may modify it as needed.
|
||||
// =================================================================================
|
||||
|
||||
package dao
|
||||
|
||||
import (
|
||||
"hotgo/internal/dao/internal"
|
||||
)
|
||||
|
||||
// feedMediaDao is the data access object for the table cv_feed_media.
|
||||
// You can define custom methods on it to extend its functionality as needed.
|
||||
type feedMediaDao struct {
|
||||
*internal.FeedMediaDao
|
||||
}
|
||||
|
||||
var (
|
||||
// FeedMedia is a globally accessible object for table cv_feed_media operations.
|
||||
FeedMedia = feedMediaDao{internal.NewFeedMediaDao()}
|
||||
)
|
||||
|
||||
// Add your custom methods and functionality below.
|
||||
@@ -0,0 +1,22 @@
|
||||
// =================================================================================
|
||||
// This file is auto-generated by the GoFrame CLI tool. You may modify it as needed.
|
||||
// =================================================================================
|
||||
|
||||
package dao
|
||||
|
||||
import (
|
||||
"hotgo/internal/dao/internal"
|
||||
)
|
||||
|
||||
// feedPostDao is the data access object for the table cv_feed_post.
|
||||
// You can define custom methods on it to extend its functionality as needed.
|
||||
type feedPostDao struct {
|
||||
*internal.FeedPostDao
|
||||
}
|
||||
|
||||
var (
|
||||
// FeedPost is a globally accessible object for table cv_feed_post operations.
|
||||
FeedPost = feedPostDao{internal.NewFeedPostDao()}
|
||||
)
|
||||
|
||||
// Add your custom methods and functionality below.
|
||||
@@ -0,0 +1,22 @@
|
||||
// =================================================================================
|
||||
// This file is auto-generated by the GoFrame CLI tool. You may modify it as needed.
|
||||
// =================================================================================
|
||||
|
||||
package dao
|
||||
|
||||
import (
|
||||
"hotgo/internal/dao/internal"
|
||||
)
|
||||
|
||||
// feedReportDao is the data access object for the table cv_feed_report.
|
||||
// You can define custom methods on it to extend its functionality as needed.
|
||||
type feedReportDao struct {
|
||||
*internal.FeedReportDao
|
||||
}
|
||||
|
||||
var (
|
||||
// FeedReport is a globally accessible object for table cv_feed_report operations.
|
||||
FeedReport = feedReportDao{internal.NewFeedReportDao()}
|
||||
)
|
||||
|
||||
// Add your custom methods and functionality below.
|
||||
@@ -0,0 +1,22 @@
|
||||
// =================================================================================
|
||||
// This file is auto-generated by the GoFrame CLI tool. You may modify it as needed.
|
||||
// =================================================================================
|
||||
|
||||
package dao
|
||||
|
||||
import (
|
||||
"hotgo/internal/dao/internal"
|
||||
)
|
||||
|
||||
// flowerCatalogDao is the data access object for the table cv_flower_catalog.
|
||||
// You can define custom methods on it to extend its functionality as needed.
|
||||
type flowerCatalogDao struct {
|
||||
*internal.FlowerCatalogDao
|
||||
}
|
||||
|
||||
var (
|
||||
// FlowerCatalog is a globally accessible object for table cv_flower_catalog operations.
|
||||
FlowerCatalog = flowerCatalogDao{internal.NewFlowerCatalogDao()}
|
||||
)
|
||||
|
||||
// Add your custom methods and functionality below.
|
||||
@@ -0,0 +1,22 @@
|
||||
// =================================================================================
|
||||
// This file is auto-generated by the GoFrame CLI tool. You may modify it as needed.
|
||||
// =================================================================================
|
||||
|
||||
package dao
|
||||
|
||||
import (
|
||||
"hotgo/internal/dao/internal"
|
||||
)
|
||||
|
||||
// flowerStageRuleDao is the data access object for the table cv_flower_stage_rule.
|
||||
// You can define custom methods on it to extend its functionality as needed.
|
||||
type flowerStageRuleDao struct {
|
||||
*internal.FlowerStageRuleDao
|
||||
}
|
||||
|
||||
var (
|
||||
// FlowerStageRule is a globally accessible object for table cv_flower_stage_rule operations.
|
||||
FlowerStageRule = flowerStageRuleDao{internal.NewFlowerStageRuleDao()}
|
||||
)
|
||||
|
||||
// Add your custom methods and functionality below.
|
||||
@@ -0,0 +1,103 @@
|
||||
// ==========================================================================
|
||||
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
|
||||
// ==========================================================================
|
||||
|
||||
package internal
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/gogf/gf/v2/database/gdb"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
)
|
||||
|
||||
// AdminOperationLogDao is the data access object for the table cv_admin_operation_log.
|
||||
type AdminOperationLogDao 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 AdminOperationLogColumns // columns contains all the column names of Table for convenient usage.
|
||||
handlers []gdb.ModelHandler // handlers for customized model modification.
|
||||
}
|
||||
|
||||
// AdminOperationLogColumns defines and stores column names for the table cv_admin_operation_log.
|
||||
type AdminOperationLogColumns struct {
|
||||
Id string //
|
||||
TenantId string //
|
||||
OperatorId string //
|
||||
OperationType string //
|
||||
TargetType string //
|
||||
TargetId string //
|
||||
RequestId string //
|
||||
BeforeSnapshot string //
|
||||
AfterSnapshot string //
|
||||
Reason string //
|
||||
IpAddress string //
|
||||
UserAgent string //
|
||||
CreatedAt string //
|
||||
}
|
||||
|
||||
// adminOperationLogColumns holds the columns for the table cv_admin_operation_log.
|
||||
var adminOperationLogColumns = AdminOperationLogColumns{
|
||||
Id: "id",
|
||||
TenantId: "tenant_id",
|
||||
OperatorId: "operator_id",
|
||||
OperationType: "operation_type",
|
||||
TargetType: "target_type",
|
||||
TargetId: "target_id",
|
||||
RequestId: "request_id",
|
||||
BeforeSnapshot: "before_snapshot",
|
||||
AfterSnapshot: "after_snapshot",
|
||||
Reason: "reason",
|
||||
IpAddress: "ip_address",
|
||||
UserAgent: "user_agent",
|
||||
CreatedAt: "created_at",
|
||||
}
|
||||
|
||||
// NewAdminOperationLogDao creates and returns a new DAO object for table data access.
|
||||
func NewAdminOperationLogDao(handlers ...gdb.ModelHandler) *AdminOperationLogDao {
|
||||
return &AdminOperationLogDao{
|
||||
group: "cultivate",
|
||||
table: "cv_admin_operation_log",
|
||||
columns: adminOperationLogColumns,
|
||||
handlers: handlers,
|
||||
}
|
||||
}
|
||||
|
||||
// DB retrieves and returns the underlying raw database management object of the current DAO.
|
||||
func (dao *AdminOperationLogDao) DB() gdb.DB {
|
||||
return g.DB(dao.group)
|
||||
}
|
||||
|
||||
// Table returns the table name of the current DAO.
|
||||
func (dao *AdminOperationLogDao) Table() string {
|
||||
return dao.table
|
||||
}
|
||||
|
||||
// Columns returns all column names of the current DAO.
|
||||
func (dao *AdminOperationLogDao) Columns() AdminOperationLogColumns {
|
||||
return dao.columns
|
||||
}
|
||||
|
||||
// Group returns the database configuration group name of the current DAO.
|
||||
func (dao *AdminOperationLogDao) Group() string {
|
||||
return dao.group
|
||||
}
|
||||
|
||||
// Ctx creates and returns a Model for the current DAO. It automatically sets the context for the current operation.
|
||||
func (dao *AdminOperationLogDao) Ctx(ctx context.Context) *gdb.Model {
|
||||
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.
|
||||
// It rolls back the transaction and returns the error if function f returns a non-nil error.
|
||||
// It commits the transaction and returns nil if function f returns nil.
|
||||
//
|
||||
// Note: Do not commit or roll back the transaction in function f,
|
||||
// as it is automatically handled by this function.
|
||||
func (dao *AdminOperationLogDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
|
||||
return dao.Ctx(ctx).Transaction(ctx, f)
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
// ==========================================================================
|
||||
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
|
||||
// ==========================================================================
|
||||
|
||||
package internal
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/gogf/gf/v2/database/gdb"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
)
|
||||
|
||||
// ContentAuditLogDao is the data access object for the table cv_content_audit_log.
|
||||
type ContentAuditLogDao 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 ContentAuditLogColumns // columns contains all the column names of Table for convenient usage.
|
||||
handlers []gdb.ModelHandler // handlers for customized model modification.
|
||||
}
|
||||
|
||||
// ContentAuditLogColumns defines and stores column names for the table cv_content_audit_log.
|
||||
type ContentAuditLogColumns struct {
|
||||
Id string //
|
||||
TenantId string //
|
||||
ObjectType string //
|
||||
ObjectId string //
|
||||
AuditRequestId string //
|
||||
AuditSource string //
|
||||
StatusBefore string //
|
||||
StatusAfter string //
|
||||
ResultCode string //
|
||||
RiskLabels string //
|
||||
OperatorId string //
|
||||
OccurredAt string //
|
||||
CreatedAt string //
|
||||
}
|
||||
|
||||
// contentAuditLogColumns holds the columns for the table cv_content_audit_log.
|
||||
var contentAuditLogColumns = ContentAuditLogColumns{
|
||||
Id: "id",
|
||||
TenantId: "tenant_id",
|
||||
ObjectType: "object_type",
|
||||
ObjectId: "object_id",
|
||||
AuditRequestId: "audit_request_id",
|
||||
AuditSource: "audit_source",
|
||||
StatusBefore: "status_before",
|
||||
StatusAfter: "status_after",
|
||||
ResultCode: "result_code",
|
||||
RiskLabels: "risk_labels",
|
||||
OperatorId: "operator_id",
|
||||
OccurredAt: "occurred_at",
|
||||
CreatedAt: "created_at",
|
||||
}
|
||||
|
||||
// NewContentAuditLogDao creates and returns a new DAO object for table data access.
|
||||
func NewContentAuditLogDao(handlers ...gdb.ModelHandler) *ContentAuditLogDao {
|
||||
return &ContentAuditLogDao{
|
||||
group: "cultivate",
|
||||
table: "cv_content_audit_log",
|
||||
columns: contentAuditLogColumns,
|
||||
handlers: handlers,
|
||||
}
|
||||
}
|
||||
|
||||
// DB retrieves and returns the underlying raw database management object of the current DAO.
|
||||
func (dao *ContentAuditLogDao) DB() gdb.DB {
|
||||
return g.DB(dao.group)
|
||||
}
|
||||
|
||||
// Table returns the table name of the current DAO.
|
||||
func (dao *ContentAuditLogDao) Table() string {
|
||||
return dao.table
|
||||
}
|
||||
|
||||
// Columns returns all column names of the current DAO.
|
||||
func (dao *ContentAuditLogDao) Columns() ContentAuditLogColumns {
|
||||
return dao.columns
|
||||
}
|
||||
|
||||
// Group returns the database configuration group name of the current DAO.
|
||||
func (dao *ContentAuditLogDao) Group() string {
|
||||
return dao.group
|
||||
}
|
||||
|
||||
// Ctx creates and returns a Model for the current DAO. It automatically sets the context for the current operation.
|
||||
func (dao *ContentAuditLogDao) Ctx(ctx context.Context) *gdb.Model {
|
||||
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.
|
||||
// It rolls back the transaction and returns the error if function f returns a non-nil error.
|
||||
// It commits the transaction and returns nil if function f returns nil.
|
||||
//
|
||||
// Note: Do not commit or roll back the transaction in function f,
|
||||
// as it is automatically handled by this function.
|
||||
func (dao *ContentAuditLogDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
|
||||
return dao.Ctx(ctx).Transaction(ctx, f)
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
// ==========================================================================
|
||||
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
|
||||
// ==========================================================================
|
||||
|
||||
package internal
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/gogf/gf/v2/database/gdb"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
)
|
||||
|
||||
// FeedCommentDao is the data access object for the table cv_feed_comment.
|
||||
type FeedCommentDao 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 FeedCommentColumns // columns contains all the column names of Table for convenient usage.
|
||||
handlers []gdb.ModelHandler // handlers for customized model modification.
|
||||
}
|
||||
|
||||
// FeedCommentColumns defines and stores column names for the table cv_feed_comment.
|
||||
type FeedCommentColumns struct {
|
||||
Id string //
|
||||
TenantId string //
|
||||
PostId string //
|
||||
AuthorId string //
|
||||
ContentText string //
|
||||
Status string //
|
||||
AuditStatus string //
|
||||
AuditRequestId string //
|
||||
DeletedBy string //
|
||||
DeleteReason string //
|
||||
PublishedAt string //
|
||||
DeletedAt string //
|
||||
CreatedAt string //
|
||||
UpdatedAt string //
|
||||
}
|
||||
|
||||
// feedCommentColumns holds the columns for the table cv_feed_comment.
|
||||
var feedCommentColumns = FeedCommentColumns{
|
||||
Id: "id",
|
||||
TenantId: "tenant_id",
|
||||
PostId: "post_id",
|
||||
AuthorId: "author_id",
|
||||
ContentText: "content_text",
|
||||
Status: "status",
|
||||
AuditStatus: "audit_status",
|
||||
AuditRequestId: "audit_request_id",
|
||||
DeletedBy: "deleted_by",
|
||||
DeleteReason: "delete_reason",
|
||||
PublishedAt: "published_at",
|
||||
DeletedAt: "deleted_at",
|
||||
CreatedAt: "created_at",
|
||||
UpdatedAt: "updated_at",
|
||||
}
|
||||
|
||||
// NewFeedCommentDao creates and returns a new DAO object for table data access.
|
||||
func NewFeedCommentDao(handlers ...gdb.ModelHandler) *FeedCommentDao {
|
||||
return &FeedCommentDao{
|
||||
group: "cultivate",
|
||||
table: "cv_feed_comment",
|
||||
columns: feedCommentColumns,
|
||||
handlers: handlers,
|
||||
}
|
||||
}
|
||||
|
||||
// DB retrieves and returns the underlying raw database management object of the current DAO.
|
||||
func (dao *FeedCommentDao) DB() gdb.DB {
|
||||
return g.DB(dao.group)
|
||||
}
|
||||
|
||||
// Table returns the table name of the current DAO.
|
||||
func (dao *FeedCommentDao) Table() string {
|
||||
return dao.table
|
||||
}
|
||||
|
||||
// Columns returns all column names of the current DAO.
|
||||
func (dao *FeedCommentDao) Columns() FeedCommentColumns {
|
||||
return dao.columns
|
||||
}
|
||||
|
||||
// Group returns the database configuration group name of the current DAO.
|
||||
func (dao *FeedCommentDao) Group() string {
|
||||
return dao.group
|
||||
}
|
||||
|
||||
// Ctx creates and returns a Model for the current DAO. It automatically sets the context for the current operation.
|
||||
func (dao *FeedCommentDao) Ctx(ctx context.Context) *gdb.Model {
|
||||
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.
|
||||
// It rolls back the transaction and returns the error if function f returns a non-nil error.
|
||||
// It commits the transaction and returns nil if function f returns nil.
|
||||
//
|
||||
// Note: Do not commit or roll back the transaction in function f,
|
||||
// as it is automatically handled by this function.
|
||||
func (dao *FeedCommentDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
|
||||
return dao.Ctx(ctx).Transaction(ctx, f)
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
// ==========================================================================
|
||||
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
|
||||
// ==========================================================================
|
||||
|
||||
package internal
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/gogf/gf/v2/database/gdb"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
)
|
||||
|
||||
// FeedMediaDao is the data access object for the table cv_feed_media.
|
||||
type FeedMediaDao 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 FeedMediaColumns // columns contains all the column names of Table for convenient usage.
|
||||
handlers []gdb.ModelHandler // handlers for customized model modification.
|
||||
}
|
||||
|
||||
// FeedMediaColumns defines and stores column names for the table cv_feed_media.
|
||||
type FeedMediaColumns struct {
|
||||
Id string //
|
||||
TenantId string //
|
||||
PostId string //
|
||||
UserId string //
|
||||
MediaType string //
|
||||
FileId string //
|
||||
ThumbnailFileId string //
|
||||
Width string //
|
||||
Height string //
|
||||
SortNo string //
|
||||
AuditStatus string //
|
||||
AuditRequestId string //
|
||||
CreatedAt string //
|
||||
UpdatedAt string //
|
||||
}
|
||||
|
||||
// feedMediaColumns holds the columns for the table cv_feed_media.
|
||||
var feedMediaColumns = FeedMediaColumns{
|
||||
Id: "id",
|
||||
TenantId: "tenant_id",
|
||||
PostId: "post_id",
|
||||
UserId: "user_id",
|
||||
MediaType: "media_type",
|
||||
FileId: "file_id",
|
||||
ThumbnailFileId: "thumbnail_file_id",
|
||||
Width: "width",
|
||||
Height: "height",
|
||||
SortNo: "sort_no",
|
||||
AuditStatus: "audit_status",
|
||||
AuditRequestId: "audit_request_id",
|
||||
CreatedAt: "created_at",
|
||||
UpdatedAt: "updated_at",
|
||||
}
|
||||
|
||||
// NewFeedMediaDao creates and returns a new DAO object for table data access.
|
||||
func NewFeedMediaDao(handlers ...gdb.ModelHandler) *FeedMediaDao {
|
||||
return &FeedMediaDao{
|
||||
group: "cultivate",
|
||||
table: "cv_feed_media",
|
||||
columns: feedMediaColumns,
|
||||
handlers: handlers,
|
||||
}
|
||||
}
|
||||
|
||||
// DB retrieves and returns the underlying raw database management object of the current DAO.
|
||||
func (dao *FeedMediaDao) DB() gdb.DB {
|
||||
return g.DB(dao.group)
|
||||
}
|
||||
|
||||
// Table returns the table name of the current DAO.
|
||||
func (dao *FeedMediaDao) Table() string {
|
||||
return dao.table
|
||||
}
|
||||
|
||||
// Columns returns all column names of the current DAO.
|
||||
func (dao *FeedMediaDao) Columns() FeedMediaColumns {
|
||||
return dao.columns
|
||||
}
|
||||
|
||||
// Group returns the database configuration group name of the current DAO.
|
||||
func (dao *FeedMediaDao) Group() string {
|
||||
return dao.group
|
||||
}
|
||||
|
||||
// Ctx creates and returns a Model for the current DAO. It automatically sets the context for the current operation.
|
||||
func (dao *FeedMediaDao) Ctx(ctx context.Context) *gdb.Model {
|
||||
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.
|
||||
// It rolls back the transaction and returns the error if function f returns a non-nil error.
|
||||
// It commits the transaction and returns nil if function f returns nil.
|
||||
//
|
||||
// Note: Do not commit or roll back the transaction in function f,
|
||||
// as it is automatically handled by this function.
|
||||
func (dao *FeedMediaDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
|
||||
return dao.Ctx(ctx).Transaction(ctx, f)
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
// ==========================================================================
|
||||
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
|
||||
// ==========================================================================
|
||||
|
||||
package internal
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/gogf/gf/v2/database/gdb"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
)
|
||||
|
||||
// FeedPostDao is the data access object for the table cv_feed_post.
|
||||
type FeedPostDao 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 FeedPostColumns // columns contains all the column names of Table for convenient usage.
|
||||
handlers []gdb.ModelHandler // handlers for customized model modification.
|
||||
}
|
||||
|
||||
// FeedPostColumns defines and stores column names for the table cv_feed_post.
|
||||
type FeedPostColumns struct {
|
||||
Id string //
|
||||
TenantId string //
|
||||
AuthorId string //
|
||||
ContentText string //
|
||||
FlowerCode string //
|
||||
SourceType string //
|
||||
SourceId string //
|
||||
Visibility string //
|
||||
Status string //
|
||||
AuditStatus string //
|
||||
AuditRequestId string //
|
||||
RejectReasonCode string //
|
||||
LikeCount string //
|
||||
CommentCount string //
|
||||
Version string //
|
||||
PublishedAt string //
|
||||
DeletedAt string //
|
||||
TakenDownAt string //
|
||||
CreatedAt string //
|
||||
UpdatedAt string //
|
||||
}
|
||||
|
||||
// feedPostColumns holds the columns for the table cv_feed_post.
|
||||
var feedPostColumns = FeedPostColumns{
|
||||
Id: "id",
|
||||
TenantId: "tenant_id",
|
||||
AuthorId: "author_id",
|
||||
ContentText: "content_text",
|
||||
FlowerCode: "flower_code",
|
||||
SourceType: "source_type",
|
||||
SourceId: "source_id",
|
||||
Visibility: "visibility",
|
||||
Status: "status",
|
||||
AuditStatus: "audit_status",
|
||||
AuditRequestId: "audit_request_id",
|
||||
RejectReasonCode: "reject_reason_code",
|
||||
LikeCount: "like_count",
|
||||
CommentCount: "comment_count",
|
||||
Version: "version",
|
||||
PublishedAt: "published_at",
|
||||
DeletedAt: "deleted_at",
|
||||
TakenDownAt: "taken_down_at",
|
||||
CreatedAt: "created_at",
|
||||
UpdatedAt: "updated_at",
|
||||
}
|
||||
|
||||
// NewFeedPostDao creates and returns a new DAO object for table data access.
|
||||
func NewFeedPostDao(handlers ...gdb.ModelHandler) *FeedPostDao {
|
||||
return &FeedPostDao{
|
||||
group: "cultivate",
|
||||
table: "cv_feed_post",
|
||||
columns: feedPostColumns,
|
||||
handlers: handlers,
|
||||
}
|
||||
}
|
||||
|
||||
// DB retrieves and returns the underlying raw database management object of the current DAO.
|
||||
func (dao *FeedPostDao) DB() gdb.DB {
|
||||
return g.DB(dao.group)
|
||||
}
|
||||
|
||||
// Table returns the table name of the current DAO.
|
||||
func (dao *FeedPostDao) Table() string {
|
||||
return dao.table
|
||||
}
|
||||
|
||||
// Columns returns all column names of the current DAO.
|
||||
func (dao *FeedPostDao) Columns() FeedPostColumns {
|
||||
return dao.columns
|
||||
}
|
||||
|
||||
// Group returns the database configuration group name of the current DAO.
|
||||
func (dao *FeedPostDao) Group() string {
|
||||
return dao.group
|
||||
}
|
||||
|
||||
// Ctx creates and returns a Model for the current DAO. It automatically sets the context for the current operation.
|
||||
func (dao *FeedPostDao) Ctx(ctx context.Context) *gdb.Model {
|
||||
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.
|
||||
// It rolls back the transaction and returns the error if function f returns a non-nil error.
|
||||
// It commits the transaction and returns nil if function f returns nil.
|
||||
//
|
||||
// Note: Do not commit or roll back the transaction in function f,
|
||||
// as it is automatically handled by this function.
|
||||
func (dao *FeedPostDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
|
||||
return dao.Ctx(ctx).Transaction(ctx, f)
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
// ==========================================================================
|
||||
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
|
||||
// ==========================================================================
|
||||
|
||||
package internal
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/gogf/gf/v2/database/gdb"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
)
|
||||
|
||||
// FeedReportDao is the data access object for the table cv_feed_report.
|
||||
type FeedReportDao 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 FeedReportColumns // columns contains all the column names of Table for convenient usage.
|
||||
handlers []gdb.ModelHandler // handlers for customized model modification.
|
||||
}
|
||||
|
||||
// FeedReportColumns defines and stores column names for the table cv_feed_report.
|
||||
type FeedReportColumns struct {
|
||||
Id string //
|
||||
TenantId string //
|
||||
ReporterId string //
|
||||
ReportedUserId string //
|
||||
ObjectType string //
|
||||
ObjectId string //
|
||||
ReasonCode string //
|
||||
Description string //
|
||||
EvidenceFileIds string //
|
||||
SourcePage string //
|
||||
Status string //
|
||||
HandlerId string //
|
||||
HandleResult string //
|
||||
HandledAt string //
|
||||
CreatedAt string //
|
||||
UpdatedAt string //
|
||||
}
|
||||
|
||||
// feedReportColumns holds the columns for the table cv_feed_report.
|
||||
var feedReportColumns = FeedReportColumns{
|
||||
Id: "id",
|
||||
TenantId: "tenant_id",
|
||||
ReporterId: "reporter_id",
|
||||
ReportedUserId: "reported_user_id",
|
||||
ObjectType: "object_type",
|
||||
ObjectId: "object_id",
|
||||
ReasonCode: "reason_code",
|
||||
Description: "description",
|
||||
EvidenceFileIds: "evidence_file_ids",
|
||||
SourcePage: "source_page",
|
||||
Status: "status",
|
||||
HandlerId: "handler_id",
|
||||
HandleResult: "handle_result",
|
||||
HandledAt: "handled_at",
|
||||
CreatedAt: "created_at",
|
||||
UpdatedAt: "updated_at",
|
||||
}
|
||||
|
||||
// NewFeedReportDao creates and returns a new DAO object for table data access.
|
||||
func NewFeedReportDao(handlers ...gdb.ModelHandler) *FeedReportDao {
|
||||
return &FeedReportDao{
|
||||
group: "cultivate",
|
||||
table: "cv_feed_report",
|
||||
columns: feedReportColumns,
|
||||
handlers: handlers,
|
||||
}
|
||||
}
|
||||
|
||||
// DB retrieves and returns the underlying raw database management object of the current DAO.
|
||||
func (dao *FeedReportDao) DB() gdb.DB {
|
||||
return g.DB(dao.group)
|
||||
}
|
||||
|
||||
// Table returns the table name of the current DAO.
|
||||
func (dao *FeedReportDao) Table() string {
|
||||
return dao.table
|
||||
}
|
||||
|
||||
// Columns returns all column names of the current DAO.
|
||||
func (dao *FeedReportDao) Columns() FeedReportColumns {
|
||||
return dao.columns
|
||||
}
|
||||
|
||||
// Group returns the database configuration group name of the current DAO.
|
||||
func (dao *FeedReportDao) Group() string {
|
||||
return dao.group
|
||||
}
|
||||
|
||||
// Ctx creates and returns a Model for the current DAO. It automatically sets the context for the current operation.
|
||||
func (dao *FeedReportDao) Ctx(ctx context.Context) *gdb.Model {
|
||||
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.
|
||||
// It rolls back the transaction and returns the error if function f returns a non-nil error.
|
||||
// It commits the transaction and returns nil if function f returns nil.
|
||||
//
|
||||
// Note: Do not commit or roll back the transaction in function f,
|
||||
// as it is automatically handled by this function.
|
||||
func (dao *FeedReportDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
|
||||
return dao.Ctx(ctx).Transaction(ctx, f)
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
// ==========================================================================
|
||||
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
|
||||
// ==========================================================================
|
||||
|
||||
package internal
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/gogf/gf/v2/database/gdb"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
)
|
||||
|
||||
// FlowerCatalogDao is the data access object for the table cv_flower_catalog.
|
||||
type FlowerCatalogDao 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 FlowerCatalogColumns // columns contains all the column names of Table for convenient usage.
|
||||
handlers []gdb.ModelHandler // handlers for customized model modification.
|
||||
}
|
||||
|
||||
// FlowerCatalogColumns defines and stores column names for the table cv_flower_catalog.
|
||||
type FlowerCatalogColumns struct {
|
||||
Id string //
|
||||
TenantId string //
|
||||
FlowerCode string //
|
||||
FlowerName string //
|
||||
FlowerDesc string //
|
||||
IconFileId string //
|
||||
Status string //
|
||||
ConfigVersion string //
|
||||
DailyWaterLimit string //
|
||||
DailyFertilizeLimit string //
|
||||
ShareConfig string //
|
||||
SortNo string //
|
||||
OnlineAt string //
|
||||
OfflineAt string //
|
||||
CreatedAt string //
|
||||
UpdatedAt string //
|
||||
}
|
||||
|
||||
// flowerCatalogColumns holds the columns for the table cv_flower_catalog.
|
||||
var flowerCatalogColumns = FlowerCatalogColumns{
|
||||
Id: "id",
|
||||
TenantId: "tenant_id",
|
||||
FlowerCode: "flower_code",
|
||||
FlowerName: "flower_name",
|
||||
FlowerDesc: "flower_desc",
|
||||
IconFileId: "icon_file_id",
|
||||
Status: "status",
|
||||
ConfigVersion: "config_version",
|
||||
DailyWaterLimit: "daily_water_limit",
|
||||
DailyFertilizeLimit: "daily_fertilize_limit",
|
||||
ShareConfig: "share_config",
|
||||
SortNo: "sort_no",
|
||||
OnlineAt: "online_at",
|
||||
OfflineAt: "offline_at",
|
||||
CreatedAt: "created_at",
|
||||
UpdatedAt: "updated_at",
|
||||
}
|
||||
|
||||
// NewFlowerCatalogDao creates and returns a new DAO object for table data access.
|
||||
func NewFlowerCatalogDao(handlers ...gdb.ModelHandler) *FlowerCatalogDao {
|
||||
return &FlowerCatalogDao{
|
||||
group: "cultivate",
|
||||
table: "cv_flower_catalog",
|
||||
columns: flowerCatalogColumns,
|
||||
handlers: handlers,
|
||||
}
|
||||
}
|
||||
|
||||
// DB retrieves and returns the underlying raw database management object of the current DAO.
|
||||
func (dao *FlowerCatalogDao) DB() gdb.DB {
|
||||
return g.DB(dao.group)
|
||||
}
|
||||
|
||||
// Table returns the table name of the current DAO.
|
||||
func (dao *FlowerCatalogDao) Table() string {
|
||||
return dao.table
|
||||
}
|
||||
|
||||
// Columns returns all column names of the current DAO.
|
||||
func (dao *FlowerCatalogDao) Columns() FlowerCatalogColumns {
|
||||
return dao.columns
|
||||
}
|
||||
|
||||
// Group returns the database configuration group name of the current DAO.
|
||||
func (dao *FlowerCatalogDao) Group() string {
|
||||
return dao.group
|
||||
}
|
||||
|
||||
// Ctx creates and returns a Model for the current DAO. It automatically sets the context for the current operation.
|
||||
func (dao *FlowerCatalogDao) Ctx(ctx context.Context) *gdb.Model {
|
||||
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.
|
||||
// It rolls back the transaction and returns the error if function f returns a non-nil error.
|
||||
// It commits the transaction and returns nil if function f returns nil.
|
||||
//
|
||||
// Note: Do not commit or roll back the transaction in function f,
|
||||
// as it is automatically handled by this function.
|
||||
func (dao *FlowerCatalogDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
|
||||
return dao.Ctx(ctx).Transaction(ctx, f)
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
// ==========================================================================
|
||||
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
|
||||
// ==========================================================================
|
||||
|
||||
package internal
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/gogf/gf/v2/database/gdb"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
)
|
||||
|
||||
// FlowerStageRuleDao is the data access object for the table cv_flower_stage_rule.
|
||||
type FlowerStageRuleDao 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 FlowerStageRuleColumns // columns contains all the column names of Table for convenient usage.
|
||||
handlers []gdb.ModelHandler // handlers for customized model modification.
|
||||
}
|
||||
|
||||
// FlowerStageRuleColumns defines and stores column names for the table cv_flower_stage_rule.
|
||||
type FlowerStageRuleColumns struct {
|
||||
Id string //
|
||||
TenantId string //
|
||||
FlowerCatalogId string //
|
||||
Stage string //
|
||||
NextStage string //
|
||||
RequiredPoints string //
|
||||
WaterPoints string //
|
||||
FertilizePoints string //
|
||||
AllowedActions string //
|
||||
ImageFileId string //
|
||||
AnimationFileId string //
|
||||
ProgressTextTemplate string //
|
||||
CompletionText string //
|
||||
SortNo string //
|
||||
CreatedAt string //
|
||||
UpdatedAt string //
|
||||
}
|
||||
|
||||
// flowerStageRuleColumns holds the columns for the table cv_flower_stage_rule.
|
||||
var flowerStageRuleColumns = FlowerStageRuleColumns{
|
||||
Id: "id",
|
||||
TenantId: "tenant_id",
|
||||
FlowerCatalogId: "flower_catalog_id",
|
||||
Stage: "stage",
|
||||
NextStage: "next_stage",
|
||||
RequiredPoints: "required_points",
|
||||
WaterPoints: "water_points",
|
||||
FertilizePoints: "fertilize_points",
|
||||
AllowedActions: "allowed_actions",
|
||||
ImageFileId: "image_file_id",
|
||||
AnimationFileId: "animation_file_id",
|
||||
ProgressTextTemplate: "progress_text_template",
|
||||
CompletionText: "completion_text",
|
||||
SortNo: "sort_no",
|
||||
CreatedAt: "created_at",
|
||||
UpdatedAt: "updated_at",
|
||||
}
|
||||
|
||||
// NewFlowerStageRuleDao creates and returns a new DAO object for table data access.
|
||||
func NewFlowerStageRuleDao(handlers ...gdb.ModelHandler) *FlowerStageRuleDao {
|
||||
return &FlowerStageRuleDao{
|
||||
group: "cultivate",
|
||||
table: "cv_flower_stage_rule",
|
||||
columns: flowerStageRuleColumns,
|
||||
handlers: handlers,
|
||||
}
|
||||
}
|
||||
|
||||
// DB retrieves and returns the underlying raw database management object of the current DAO.
|
||||
func (dao *FlowerStageRuleDao) DB() gdb.DB {
|
||||
return g.DB(dao.group)
|
||||
}
|
||||
|
||||
// Table returns the table name of the current DAO.
|
||||
func (dao *FlowerStageRuleDao) Table() string {
|
||||
return dao.table
|
||||
}
|
||||
|
||||
// Columns returns all column names of the current DAO.
|
||||
func (dao *FlowerStageRuleDao) Columns() FlowerStageRuleColumns {
|
||||
return dao.columns
|
||||
}
|
||||
|
||||
// Group returns the database configuration group name of the current DAO.
|
||||
func (dao *FlowerStageRuleDao) Group() string {
|
||||
return dao.group
|
||||
}
|
||||
|
||||
// Ctx creates and returns a Model for the current DAO. It automatically sets the context for the current operation.
|
||||
func (dao *FlowerStageRuleDao) Ctx(ctx context.Context) *gdb.Model {
|
||||
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.
|
||||
// It rolls back the transaction and returns the error if function f returns a non-nil error.
|
||||
// It commits the transaction and returns nil if function f returns nil.
|
||||
//
|
||||
// Note: Do not commit or roll back the transaction in function f,
|
||||
// as it is automatically handled by this function.
|
||||
func (dao *FlowerStageRuleDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
|
||||
return dao.Ctx(ctx).Transaction(ctx, f)
|
||||
}
|
||||
@@ -0,0 +1,324 @@
|
||||
package sys
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"errors"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gogf/gf/v2/database/gdb"
|
||||
"github.com/gogf/gf/v2/encoding/gjson"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
|
||||
"hotgo/internal/dao"
|
||||
"hotgo/internal/library/contexts"
|
||||
"hotgo/internal/library/imtenant"
|
||||
"hotgo/internal/model/entity"
|
||||
"hotgo/internal/model/input/sysin"
|
||||
"hotgo/internal/service"
|
||||
)
|
||||
|
||||
type sSysCultivateContent struct{}
|
||||
|
||||
func NewSysCultivateContent() *sSysCultivateContent { return &sSysCultivateContent{} }
|
||||
func init() { service.RegisterSysCultivateContent(NewSysCultivateContent()) }
|
||||
|
||||
func (s *sSysCultivateContent) List(ctx context.Context, in *sysin.CultivateContentListInp) (list []*sysin.CultivateContentListModel, totalCount int, err error) {
|
||||
tenantID := cultivateTenantID(ctx)
|
||||
if in.ObjectType == "feed_comment" {
|
||||
columns := dao.FeedComment.Columns()
|
||||
mod := dao.FeedComment.Ctx(ctx).Where(columns.TenantId, tenantID)
|
||||
if in.AuthorId != "" {
|
||||
mod = mod.Where(columns.AuthorId, in.AuthorId)
|
||||
}
|
||||
if in.Status != "" {
|
||||
mod = mod.Where(columns.Status, in.Status)
|
||||
}
|
||||
if in.Keyword != "" {
|
||||
mod = mod.WhereLike(columns.ContentText, "%"+strings.TrimSpace(in.Keyword)+"%")
|
||||
}
|
||||
if len(in.CreatedAt) == 2 {
|
||||
mod = mod.WhereBetween(columns.CreatedAt, in.CreatedAt[0], in.CreatedAt[1])
|
||||
}
|
||||
var rows []*entity.FeedComment
|
||||
err = mod.Page(in.Page, in.PerPage).OrderDesc(columns.Id).ScanAndCount(&rows, &totalCount, false)
|
||||
if err != nil {
|
||||
return nil, 0, gerror.Wrap(err, "获取评论审核列表失败")
|
||||
}
|
||||
list = make([]*sysin.CultivateContentListModel, 0, len(rows))
|
||||
for _, row := range rows {
|
||||
list = append(list, &sysin.CultivateContentListModel{Id: strconv.FormatUint(row.Id, 10), ObjectType: "feed_comment", PostId: strconv.FormatUint(row.PostId, 10), AuthorId: strconv.FormatUint(row.AuthorId, 10), ContentText: row.ContentText, Status: row.Status, AuditStatus: row.AuditStatus, CreatedAt: row.CreatedAt, UpdatedAt: row.UpdatedAt})
|
||||
}
|
||||
return
|
||||
}
|
||||
columns := dao.FeedPost.Columns()
|
||||
mod := dao.FeedPost.Ctx(ctx).Where(columns.TenantId, tenantID)
|
||||
if in.AuthorId != "" {
|
||||
mod = mod.Where(columns.AuthorId, in.AuthorId)
|
||||
}
|
||||
if in.Status != "" {
|
||||
mod = mod.Where(columns.Status, in.Status)
|
||||
}
|
||||
if in.Keyword != "" {
|
||||
mod = mod.WhereLike(columns.ContentText, "%"+strings.TrimSpace(in.Keyword)+"%")
|
||||
}
|
||||
if len(in.CreatedAt) == 2 {
|
||||
mod = mod.WhereBetween(columns.CreatedAt, in.CreatedAt[0], in.CreatedAt[1])
|
||||
}
|
||||
var rows []*entity.FeedPost
|
||||
err = mod.Page(in.Page, in.PerPage).OrderDesc(columns.Id).ScanAndCount(&rows, &totalCount, false)
|
||||
if err != nil {
|
||||
return nil, 0, gerror.Wrap(err, "获取动态审核列表失败")
|
||||
}
|
||||
list = make([]*sysin.CultivateContentListModel, 0, len(rows))
|
||||
for _, row := range rows {
|
||||
list = append(list, &sysin.CultivateContentListModel{Id: strconv.FormatUint(row.Id, 10), ObjectType: "feed_post", AuthorId: strconv.FormatUint(row.AuthorId, 10), ContentText: row.ContentText, FlowerCode: row.FlowerCode, Visibility: row.Visibility, Status: row.Status, AuditStatus: row.AuditStatus, RejectReason: row.RejectReasonCode, LikeCount: row.LikeCount, CommentCount: row.CommentCount, CreatedAt: row.CreatedAt, UpdatedAt: row.UpdatedAt})
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (s *sSysCultivateContent) Review(ctx context.Context, in *sysin.CultivateContentReviewInp) error {
|
||||
tenantID, operatorID := cultivateTenantID(ctx), contexts.GetUserId(ctx)
|
||||
return dao.FeedPost.Transaction(ctx, func(txCtx context.Context, tx gdb.TX) error {
|
||||
if in.ObjectType == "feed_comment" {
|
||||
return s.reviewComment(txCtx, tx, tenantID, operatorID, in)
|
||||
}
|
||||
return s.reviewPost(txCtx, tx, tenantID, operatorID, in)
|
||||
})
|
||||
}
|
||||
|
||||
func (s *sSysCultivateContent) reviewPost(ctx context.Context, tx gdb.TX, tenantID, operatorID int64, in *sysin.CultivateContentReviewInp) error {
|
||||
columns := dao.FeedPost.Columns()
|
||||
var before entity.FeedPost
|
||||
err := tx.Model(dao.FeedPost.Table()).Where(g.Map{columns.Id: in.ObjectId, columns.TenantId: tenantID}).LockUpdate().Scan(&before)
|
||||
if err != nil && !errors.Is(err, sql.ErrNoRows) {
|
||||
return err
|
||||
}
|
||||
if before.Id == 0 {
|
||||
return gerror.New("动态不存在")
|
||||
}
|
||||
now := time.Now().UTC()
|
||||
data := g.Map{columns.UpdatedAt: now, columns.Version: gdb.Raw(columns.Version + "+1")}
|
||||
afterStatus := before.Status
|
||||
switch in.Action {
|
||||
case "approve":
|
||||
if before.Status != "reviewing" && before.Status != "rejected" {
|
||||
return gerror.New("仅待审核或已拒绝动态可审核通过")
|
||||
}
|
||||
afterStatus = "published"
|
||||
data[columns.Status] = afterStatus
|
||||
data[columns.AuditStatus] = "approved"
|
||||
data[columns.RejectReasonCode] = ""
|
||||
if before.PublishedAt == nil {
|
||||
data[columns.PublishedAt] = now
|
||||
}
|
||||
case "reject":
|
||||
if before.Status != "reviewing" {
|
||||
return gerror.New("仅待审核动态可拒绝")
|
||||
}
|
||||
afterStatus = "rejected"
|
||||
data[columns.Status] = afterStatus
|
||||
data[columns.AuditStatus] = "rejected"
|
||||
data[columns.RejectReasonCode] = in.Reason
|
||||
case "take_down":
|
||||
if before.Status != "published" {
|
||||
return gerror.New("仅已发布动态可下架")
|
||||
}
|
||||
afterStatus = "taken_down"
|
||||
data[columns.Status] = afterStatus
|
||||
data[columns.TakenDownAt] = now
|
||||
data[columns.RejectReasonCode] = in.Reason
|
||||
case "restore":
|
||||
if before.Status != "taken_down" {
|
||||
return gerror.New("仅已下架动态可恢复")
|
||||
}
|
||||
afterStatus = "published"
|
||||
data[columns.Status] = afterStatus
|
||||
data[columns.TakenDownAt] = nil
|
||||
data[columns.RejectReasonCode] = ""
|
||||
}
|
||||
if _, err = tx.Model(dao.FeedPost.Table()).Where(columns.Id, before.Id).Data(data).Update(); err != nil {
|
||||
return gerror.Wrap(err, "更新动态审核状态失败")
|
||||
}
|
||||
if err = writeContentAudit(ctx, tx, tenantID, operatorID, "feed_post", before.Id, before.Status, afterStatus, in.Action, now); err != nil {
|
||||
return err
|
||||
}
|
||||
return writeCultivateOperation(ctx, tx, tenantID, operatorID, "content."+in.Action, "feed_post", in.Id, before, data, in.Reason, now)
|
||||
}
|
||||
|
||||
func (s *sSysCultivateContent) reviewComment(ctx context.Context, tx gdb.TX, tenantID, operatorID int64, in *sysin.CultivateContentReviewInp) error {
|
||||
columns := dao.FeedComment.Columns()
|
||||
var before entity.FeedComment
|
||||
err := tx.Model(dao.FeedComment.Table()).Where(g.Map{columns.Id: in.ObjectId, columns.TenantId: tenantID}).LockUpdate().Scan(&before)
|
||||
if err != nil && !errors.Is(err, sql.ErrNoRows) {
|
||||
return err
|
||||
}
|
||||
if before.Id == 0 {
|
||||
return gerror.New("评论不存在")
|
||||
}
|
||||
now := time.Now().UTC()
|
||||
data := g.Map{columns.UpdatedAt: now}
|
||||
afterStatus := before.Status
|
||||
counterDelta := 0
|
||||
switch in.Action {
|
||||
case "approve":
|
||||
if before.Status != "reviewing" && before.Status != "rejected" {
|
||||
return gerror.New("仅待审核或已拒绝评论可审核通过")
|
||||
}
|
||||
afterStatus = "published"
|
||||
data[columns.Status] = afterStatus
|
||||
data[columns.AuditStatus] = "approved"
|
||||
data[columns.PublishedAt] = now
|
||||
counterDelta = 1
|
||||
case "reject":
|
||||
if before.Status != "reviewing" {
|
||||
return gerror.New("仅待审核评论可拒绝")
|
||||
}
|
||||
afterStatus = "rejected"
|
||||
data[columns.Status] = afterStatus
|
||||
data[columns.AuditStatus] = "rejected"
|
||||
data[columns.DeleteReason] = in.Reason
|
||||
case "take_down":
|
||||
if before.Status != "published" {
|
||||
return gerror.New("仅已发布评论可下架")
|
||||
}
|
||||
afterStatus = "taken_down"
|
||||
data[columns.Status] = afterStatus
|
||||
data[columns.DeleteReason] = in.Reason
|
||||
counterDelta = -1
|
||||
case "restore":
|
||||
if before.Status != "taken_down" {
|
||||
return gerror.New("仅已下架评论可恢复")
|
||||
}
|
||||
afterStatus = "published"
|
||||
data[columns.Status] = afterStatus
|
||||
data[columns.DeleteReason] = ""
|
||||
counterDelta = 1
|
||||
}
|
||||
if _, err = tx.Model(dao.FeedComment.Table()).Where(columns.Id, before.Id).Data(data).Update(); err != nil {
|
||||
return gerror.Wrap(err, "更新评论审核状态失败")
|
||||
}
|
||||
if counterDelta != 0 {
|
||||
postColumns := dao.FeedPost.Columns()
|
||||
expression := "`comment_count` + 1"
|
||||
if counterDelta < 0 {
|
||||
expression = "GREATEST(`comment_count` - 1, 0)"
|
||||
}
|
||||
if _, err = tx.Model(dao.FeedPost.Table()).Where(g.Map{postColumns.Id: before.PostId, postColumns.TenantId: tenantID}).Data(g.Map{postColumns.CommentCount: gdb.Raw(expression), postColumns.UpdatedAt: now}).Update(); err != nil {
|
||||
return gerror.Wrap(err, "更新动态评论数失败")
|
||||
}
|
||||
}
|
||||
if err = writeContentAudit(ctx, tx, tenantID, operatorID, "feed_comment", before.Id, before.Status, afterStatus, in.Action, now); err != nil {
|
||||
return err
|
||||
}
|
||||
return writeCultivateOperation(ctx, tx, tenantID, operatorID, "content."+in.Action, "feed_comment", in.Id, before, data, in.Reason, now)
|
||||
}
|
||||
|
||||
func writeContentAudit(ctx context.Context, tx gdb.TX, tenantID, operatorID int64, objectType string, objectID uint64, before, after, result string, now time.Time) error {
|
||||
id, err := imtenant.NextSnowflakeID(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
columns := dao.ContentAuditLog.Columns()
|
||||
_, err = tx.Model(dao.ContentAuditLog.Table()).Data(g.Map{columns.Id: id, columns.TenantId: tenantID, columns.ObjectType: objectType, columns.ObjectId: objectID, columns.AuditSource: "manual", columns.StatusBefore: before, columns.StatusAfter: after, columns.ResultCode: result, columns.RiskLabels: "[]", columns.OperatorId: operatorID, columns.OccurredAt: now, columns.CreatedAt: now}).Insert()
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *sSysCultivateContent) ReportList(ctx context.Context, in *sysin.CultivateReportListInp) (list []*sysin.CultivateReportListModel, totalCount int, err error) {
|
||||
columns := dao.FeedReport.Columns()
|
||||
mod := dao.FeedReport.Ctx(ctx).Where(columns.TenantId, cultivateTenantID(ctx))
|
||||
if in.ObjectType != "" {
|
||||
mod = mod.Where(columns.ObjectType, in.ObjectType)
|
||||
}
|
||||
if in.Status != "" {
|
||||
mod = mod.Where(columns.Status, in.Status)
|
||||
}
|
||||
if in.ReporterId != "" {
|
||||
mod = mod.Where(columns.ReporterId, in.ReporterId)
|
||||
}
|
||||
if len(in.CreatedAt) == 2 {
|
||||
mod = mod.WhereBetween(columns.CreatedAt, in.CreatedAt[0], in.CreatedAt[1])
|
||||
}
|
||||
var rows []*entity.FeedReport
|
||||
if err = mod.Page(in.Page, in.PerPage).OrderDesc(columns.Id).ScanAndCount(&rows, &totalCount, false); err != nil {
|
||||
return nil, 0, gerror.Wrap(err, "获取举报列表失败")
|
||||
}
|
||||
list = make([]*sysin.CultivateReportListModel, 0, len(rows))
|
||||
for _, row := range rows {
|
||||
list = append(list, &sysin.CultivateReportListModel{Id: strconv.FormatUint(row.Id, 10), ReporterId: strconv.FormatUint(row.ReporterId, 10), ReportedUserId: strconv.FormatUint(row.ReportedUserId, 10), ObjectType: row.ObjectType, ObjectId: row.ObjectId, ReasonCode: row.ReasonCode, Description: row.Description, EvidenceFileIds: row.EvidenceFileIds, SourcePage: row.SourcePage, Status: row.Status, HandlerId: optionalUint(row.HandlerId), HandleResult: row.HandleResult, HandledAt: row.HandledAt, CreatedAt: row.CreatedAt})
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (s *sSysCultivateContent) ReportHandle(ctx context.Context, in *sysin.CultivateReportHandleInp) error {
|
||||
tenantID, operatorID := cultivateTenantID(ctx), contexts.GetUserId(ctx)
|
||||
return dao.FeedReport.Transaction(ctx, func(txCtx context.Context, tx gdb.TX) error {
|
||||
columns := dao.FeedReport.Columns()
|
||||
var before entity.FeedReport
|
||||
err := tx.Model(dao.FeedReport.Table()).Where(g.Map{columns.Id: in.ReportId, columns.TenantId: tenantID}).LockUpdate().Scan(&before)
|
||||
if err != nil && !errors.Is(err, sql.ErrNoRows) {
|
||||
return err
|
||||
}
|
||||
if before.Id == 0 {
|
||||
return gerror.New("举报记录不存在")
|
||||
}
|
||||
if before.Status == "resolved" || before.Status == "rejected" {
|
||||
return gerror.New("举报已办结,不能重复处理")
|
||||
}
|
||||
now := time.Now().UTC()
|
||||
status := in.Action
|
||||
if status == "resolve" {
|
||||
status = "resolved"
|
||||
}
|
||||
data := g.Map{columns.Status: status, columns.HandlerId: operatorID, columns.HandleResult: in.HandleResult, columns.UpdatedAt: now}
|
||||
if status == "resolved" || status == "rejected" {
|
||||
data[columns.HandledAt] = now
|
||||
}
|
||||
if _, err = tx.Model(dao.FeedReport.Table()).Where(columns.Id, before.Id).Data(data).Update(); err != nil {
|
||||
return gerror.Wrap(err, "更新举报处理状态失败")
|
||||
}
|
||||
return writeCultivateOperation(txCtx, tx, tenantID, operatorID, "report."+in.Action, "feed_report", in.Id, before, data, in.HandleResult, now)
|
||||
})
|
||||
}
|
||||
|
||||
func (s *sSysCultivateContent) LogList(ctx context.Context, in *sysin.CultivateOperationLogListInp) (list []*sysin.CultivateOperationLogListModel, totalCount int, err error) {
|
||||
columns := dao.AdminOperationLog.Columns()
|
||||
mod := dao.AdminOperationLog.Ctx(ctx).Where(columns.TenantId, cultivateTenantID(ctx))
|
||||
if in.OperatorId != "" {
|
||||
mod = mod.Where(columns.OperatorId, in.OperatorId)
|
||||
}
|
||||
if in.OperationType != "" {
|
||||
mod = mod.WhereLike(columns.OperationType, "%"+strings.TrimSpace(in.OperationType)+"%")
|
||||
}
|
||||
if in.TargetType != "" {
|
||||
mod = mod.Where(columns.TargetType, in.TargetType)
|
||||
}
|
||||
if len(in.CreatedAt) == 2 {
|
||||
mod = mod.WhereBetween(columns.CreatedAt, in.CreatedAt[0], in.CreatedAt[1])
|
||||
}
|
||||
var rows []*entity.AdminOperationLog
|
||||
if err = mod.Page(in.Page, in.PerPage).OrderDesc(columns.Id).ScanAndCount(&rows, &totalCount, false); err != nil {
|
||||
return nil, 0, gerror.Wrap(err, "获取操作日志失败")
|
||||
}
|
||||
list = make([]*sysin.CultivateOperationLogListModel, 0, len(rows))
|
||||
for _, row := range rows {
|
||||
list = append(list, &sysin.CultivateOperationLogListModel{Id: strconv.FormatUint(row.Id, 10), OperatorId: strconv.FormatUint(row.OperatorId, 10), OperationType: row.OperationType, TargetType: row.TargetType, TargetId: row.TargetId, RequestId: row.RequestId, BeforeSnapshot: jsonValue(row.BeforeSnapshot), AfterSnapshot: jsonValue(row.AfterSnapshot), Reason: row.Reason, CreatedAt: row.CreatedAt})
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func optionalUint(value uint64) string {
|
||||
if value == 0 {
|
||||
return ""
|
||||
}
|
||||
return strconv.FormatUint(value, 10)
|
||||
}
|
||||
func jsonValue(value *gjson.Json) any {
|
||||
if value == nil {
|
||||
return nil
|
||||
}
|
||||
return value
|
||||
}
|
||||
@@ -0,0 +1,191 @@
|
||||
package sys
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gogf/gf/v2/database/gdb"
|
||||
"github.com/gogf/gf/v2/encoding/gjson"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gctx"
|
||||
|
||||
"hotgo/internal/dao"
|
||||
"hotgo/internal/library/contexts"
|
||||
"hotgo/internal/library/imtenant"
|
||||
"hotgo/internal/model/entity"
|
||||
"hotgo/internal/model/input/sysin"
|
||||
"hotgo/internal/service"
|
||||
)
|
||||
|
||||
type sSysCultivateFlower struct{}
|
||||
|
||||
func NewSysCultivateFlower() *sSysCultivateFlower { return &sSysCultivateFlower{} }
|
||||
func init() { service.RegisterSysCultivateFlower(NewSysCultivateFlower()) }
|
||||
|
||||
func cultivateTenantID(ctx context.Context) int64 {
|
||||
id := contexts.GetTenantId(ctx)
|
||||
if id <= 0 {
|
||||
id = g.Cfg().MustGet(ctx, "cultivate.defaultTenantId", 1).Int64()
|
||||
}
|
||||
return id
|
||||
}
|
||||
|
||||
func (s *sSysCultivateFlower) List(ctx context.Context, in *sysin.CultivateFlowerListInp) (list []*sysin.CultivateFlowerListModel, totalCount int, err error) {
|
||||
c := dao.FlowerCatalog.Columns()
|
||||
mod := dao.FlowerCatalog.Ctx(ctx).Fields("cv_flower_catalog.*, COUNT(cv_flower_stage_rule.id) AS stage_count").LeftJoin(dao.FlowerStageRule.Table(), "cv_flower_stage_rule.flower_catalog_id=cv_flower_catalog.id AND cv_flower_stage_rule.tenant_id=cv_flower_catalog.tenant_id").Where("cv_flower_catalog."+c.TenantId, cultivateTenantID(ctx)).Group("cv_flower_catalog." + c.Id)
|
||||
if in.FlowerCode != "" {
|
||||
mod = mod.WhereLike("cv_flower_catalog."+c.FlowerCode, "%"+strings.TrimSpace(in.FlowerCode)+"%")
|
||||
}
|
||||
if in.FlowerName != "" {
|
||||
mod = mod.WhereLike("cv_flower_catalog."+c.FlowerName, "%"+strings.TrimSpace(in.FlowerName)+"%")
|
||||
}
|
||||
if in.Status != "" {
|
||||
mod = mod.Where("cv_flower_catalog."+c.Status, in.Status)
|
||||
}
|
||||
if in.ConfigVersion != "" {
|
||||
mod = mod.Where("cv_flower_catalog."+c.ConfigVersion, in.ConfigVersion)
|
||||
}
|
||||
if len(in.CreatedAt) == 2 {
|
||||
mod = mod.WhereBetween("cv_flower_catalog."+c.CreatedAt, in.CreatedAt[0], in.CreatedAt[1])
|
||||
}
|
||||
mod = mod.Page(in.Page, in.PerPage).OrderAsc("cv_flower_catalog." + c.SortNo).OrderDesc("cv_flower_catalog." + c.Id)
|
||||
if err = mod.ScanAndCount(&list, &totalCount, false); err != nil {
|
||||
err = gerror.Wrap(err, "获取花种列表失败")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (s *sSysCultivateFlower) View(ctx context.Context, in *sysin.CultivateFlowerViewInp) (res *sysin.CultivateFlowerViewModel, err error) {
|
||||
c := dao.FlowerCatalog.Columns()
|
||||
var catalog entity.FlowerCatalog
|
||||
if err = dao.FlowerCatalog.Ctx(ctx).Where(g.Map{c.Id: in.Id, c.TenantId: cultivateTenantID(ctx)}).Scan(&catalog); err != nil {
|
||||
return
|
||||
}
|
||||
if catalog.Id == 0 {
|
||||
return nil, gerror.New("花种不存在")
|
||||
}
|
||||
res = &sysin.CultivateFlowerViewModel{CultivateFlowerEditInp: sysin.CultivateFlowerEditInp{Id: catalog.Id, FlowerCode: catalog.FlowerCode, FlowerName: catalog.FlowerName, FlowerDesc: catalog.FlowerDesc, IconFileId: catalog.IconFileId, Status: catalog.Status, DailyWaterLimit: catalog.DailyWaterLimit, DailyFertilizeLimit: catalog.DailyFertilizeLimit, ShareConfig: catalog.ShareConfig, SortNo: catalog.SortNo}, ConfigVersion: catalog.ConfigVersion, CreatedAt: catalog.CreatedAt, UpdatedAt: catalog.UpdatedAt}
|
||||
rc := dao.FlowerStageRule.Columns()
|
||||
var rules []*entity.FlowerStageRule
|
||||
if err = dao.FlowerStageRule.Ctx(ctx).Where(g.Map{rc.TenantId: cultivateTenantID(ctx), rc.FlowerCatalogId: catalog.Id}).OrderAsc(rc.SortNo).OrderAsc(rc.Id).Scan(&rules); err != nil {
|
||||
return
|
||||
}
|
||||
for _, rule := range rules {
|
||||
actions := []string{}
|
||||
if rule.AllowedActions != nil {
|
||||
_ = json.Unmarshal(rule.AllowedActions.MustToJson(), &actions)
|
||||
}
|
||||
res.StageRules = append(res.StageRules, &sysin.CultivateStageRuleEditInp{Id: rule.Id, Stage: rule.Stage, NextStage: rule.NextStage, RequiredPoints: rule.RequiredPoints, WaterPoints: rule.WaterPoints, FertilizePoints: rule.FertilizePoints, AllowedActions: actions, ImageFileId: rule.ImageFileId, AnimationFileId: rule.AnimationFileId, ProgressTextTemplate: rule.ProgressTextTemplate, CompletionText: rule.CompletionText, SortNo: rule.SortNo})
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (s *sSysCultivateFlower) Edit(ctx context.Context, in *sysin.CultivateFlowerEditInp) (err error) {
|
||||
tenantID := cultivateTenantID(ctx)
|
||||
operatorID := contexts.GetUserId(ctx)
|
||||
now := time.Now().UTC()
|
||||
version := "cat_" + now.Format("20060102_150405")
|
||||
return dao.FlowerCatalog.Transaction(ctx, func(txCtx context.Context, tx gdb.TX) error {
|
||||
c := dao.FlowerCatalog.Columns()
|
||||
var before entity.FlowerCatalog
|
||||
if in.Id > 0 {
|
||||
if e := tx.Model(dao.FlowerCatalog.Table()).Where(g.Map{c.Id: in.Id, c.TenantId: tenantID}).LockUpdate().Scan(&before); e != nil {
|
||||
return e
|
||||
}
|
||||
if before.Id == 0 {
|
||||
return gerror.New("花种不存在")
|
||||
}
|
||||
if before.FlowerCode != in.FlowerCode {
|
||||
return gerror.New("花种编码创建后不可修改")
|
||||
}
|
||||
}
|
||||
shareJSON := "{}"
|
||||
if in.ShareConfig != nil {
|
||||
shareJSON = in.ShareConfig.MustToJsonString()
|
||||
}
|
||||
data := g.Map{c.FlowerName: in.FlowerName, c.FlowerDesc: in.FlowerDesc, c.IconFileId: in.IconFileId, c.Status: in.Status, c.ConfigVersion: version, c.DailyWaterLimit: in.DailyWaterLimit, c.DailyFertilizeLimit: in.DailyFertilizeLimit, c.ShareConfig: shareJSON, c.SortNo: in.SortNo, c.UpdatedAt: now}
|
||||
if in.Status == "online" {
|
||||
data[c.OnlineAt] = now
|
||||
data[c.OfflineAt] = nil
|
||||
} else if in.Status == "offline" {
|
||||
data[c.OfflineAt] = now
|
||||
}
|
||||
if in.Id == 0 {
|
||||
id, e := imtenant.NextSnowflakeID(txCtx)
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
in.Id = uint64(id)
|
||||
data[c.Id] = id
|
||||
data[c.TenantId] = tenantID
|
||||
data[c.FlowerCode] = in.FlowerCode
|
||||
data[c.CreatedAt] = now
|
||||
if _, e = tx.Model(dao.FlowerCatalog.Table()).Data(data).Insert(); e != nil {
|
||||
return gerror.Wrap(e, "新增花种失败")
|
||||
}
|
||||
} else {
|
||||
if _, e := tx.Model(dao.FlowerCatalog.Table()).Where(g.Map{c.Id: in.Id, c.TenantId: tenantID}).Data(data).Update(); e != nil {
|
||||
return gerror.Wrap(e, "修改花种失败")
|
||||
}
|
||||
}
|
||||
rc := dao.FlowerStageRule.Columns()
|
||||
if _, e := tx.Model(dao.FlowerStageRule.Table()).Where(g.Map{rc.TenantId: tenantID, rc.FlowerCatalogId: in.Id}).Delete(); e != nil {
|
||||
return e
|
||||
}
|
||||
for _, rule := range in.StageRules {
|
||||
id, e := imtenant.NextSnowflakeID(txCtx)
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
actions, _ := json.Marshal(rule.AllowedActions)
|
||||
_, e = tx.Model(dao.FlowerStageRule.Table()).Data(g.Map{rc.Id: id, rc.TenantId: tenantID, rc.FlowerCatalogId: in.Id, rc.Stage: rule.Stage, rc.NextStage: rule.NextStage, rc.RequiredPoints: rule.RequiredPoints, rc.WaterPoints: rule.WaterPoints, rc.FertilizePoints: rule.FertilizePoints, rc.AllowedActions: string(actions), rc.ImageFileId: rule.ImageFileId, rc.AnimationFileId: rule.AnimationFileId, rc.ProgressTextTemplate: rule.ProgressTextTemplate, rc.CompletionText: rule.CompletionText, rc.SortNo: rule.SortNo, rc.CreatedAt: now, rc.UpdatedAt: now}).Insert()
|
||||
if e != nil {
|
||||
return gerror.Wrap(e, "保存成长阶段失败")
|
||||
}
|
||||
}
|
||||
return writeCultivateOperation(txCtx, tx, tenantID, operatorID, map[bool]string{true: "flower.edit", false: "flower.create"}[before.Id > 0], "flower", fmt.Sprint(in.Id), before, in, "", now)
|
||||
})
|
||||
}
|
||||
|
||||
func (s *sSysCultivateFlower) Status(ctx context.Context, in *sysin.CultivateFlowerStatusInp) error {
|
||||
tenantID := cultivateTenantID(ctx)
|
||||
operatorID := contexts.GetUserId(ctx)
|
||||
now := time.Now().UTC()
|
||||
return dao.FlowerCatalog.Transaction(ctx, func(txCtx context.Context, tx gdb.TX) error {
|
||||
c := dao.FlowerCatalog.Columns()
|
||||
var before entity.FlowerCatalog
|
||||
if e := tx.Model(dao.FlowerCatalog.Table()).Where(g.Map{c.Id: in.Id, c.TenantId: tenantID}).LockUpdate().Scan(&before); e != nil {
|
||||
return e
|
||||
}
|
||||
if before.Id == 0 {
|
||||
return gerror.New("花种不存在")
|
||||
}
|
||||
data := g.Map{c.Status: in.Status, c.ConfigVersion: "cat_" + now.Format("20060102_150405"), c.UpdatedAt: now}
|
||||
if in.Status == "online" {
|
||||
data[c.OnlineAt] = now
|
||||
data[c.OfflineAt] = nil
|
||||
} else if in.Status == "offline" {
|
||||
data[c.OfflineAt] = now
|
||||
}
|
||||
if _, e := tx.Model(dao.FlowerCatalog.Table()).Where(c.Id, in.Id).Data(data).Update(); e != nil {
|
||||
return e
|
||||
}
|
||||
return writeCultivateOperation(txCtx, tx, tenantID, operatorID, "flower.status", "flower", fmt.Sprint(in.Id), before, data, in.Reason, now)
|
||||
})
|
||||
}
|
||||
|
||||
func writeCultivateOperation(ctx context.Context, tx gdb.TX, tenantID, operatorID int64, operation, targetType, targetID string, before, after any, reason string, now time.Time) error {
|
||||
id, e := imtenant.NextSnowflakeID(ctx)
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
beforeJSON, _ := json.Marshal(before)
|
||||
afterJSON, _ := json.Marshal(after)
|
||||
c := dao.AdminOperationLog.Columns()
|
||||
_, e = tx.Model(dao.AdminOperationLog.Table()).Data(g.Map{c.Id: id, c.TenantId: tenantID, c.OperatorId: operatorID, c.OperationType: operation, c.TargetType: targetType, c.TargetId: targetID, c.RequestId: gctx.CtxId(ctx), c.BeforeSnapshot: gjson.New(beforeJSON).MustToJsonString(), c.AfterSnapshot: gjson.New(afterJSON).MustToJsonString(), c.Reason: reason, c.IpAddress: "", c.UserAgent: "", c.CreatedAt: now}).Insert()
|
||||
return e
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
// =================================================================================
|
||||
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
|
||||
// =================================================================================
|
||||
|
||||
package do
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/encoding/gjson"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
)
|
||||
|
||||
// AdminOperationLog is the golang structure of table cv_admin_operation_log for DAO operations like Where/Data.
|
||||
type AdminOperationLog struct {
|
||||
g.Meta `orm:"table:cv_admin_operation_log, do:true"`
|
||||
Id any //
|
||||
TenantId any //
|
||||
OperatorId any //
|
||||
OperationType any //
|
||||
TargetType any //
|
||||
TargetId any //
|
||||
RequestId any //
|
||||
BeforeSnapshot *gjson.Json //
|
||||
AfterSnapshot *gjson.Json //
|
||||
Reason any //
|
||||
IpAddress any //
|
||||
UserAgent any //
|
||||
CreatedAt *gtime.Time //
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
// =================================================================================
|
||||
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
|
||||
// =================================================================================
|
||||
|
||||
package do
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/encoding/gjson"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
)
|
||||
|
||||
// ContentAuditLog is the golang structure of table cv_content_audit_log for DAO operations like Where/Data.
|
||||
type ContentAuditLog struct {
|
||||
g.Meta `orm:"table:cv_content_audit_log, do:true"`
|
||||
Id any //
|
||||
TenantId any //
|
||||
ObjectType any //
|
||||
ObjectId any //
|
||||
AuditRequestId any //
|
||||
AuditSource any //
|
||||
StatusBefore any //
|
||||
StatusAfter any //
|
||||
ResultCode any //
|
||||
RiskLabels *gjson.Json //
|
||||
OperatorId any //
|
||||
OccurredAt *gtime.Time //
|
||||
CreatedAt *gtime.Time //
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
// =================================================================================
|
||||
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
|
||||
// =================================================================================
|
||||
|
||||
package do
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
)
|
||||
|
||||
// FeedComment is the golang structure of table cv_feed_comment for DAO operations like Where/Data.
|
||||
type FeedComment struct {
|
||||
g.Meta `orm:"table:cv_feed_comment, do:true"`
|
||||
Id any //
|
||||
TenantId any //
|
||||
PostId any //
|
||||
AuthorId any //
|
||||
ContentText any //
|
||||
Status any //
|
||||
AuditStatus any //
|
||||
AuditRequestId any //
|
||||
DeletedBy any //
|
||||
DeleteReason any //
|
||||
PublishedAt *gtime.Time //
|
||||
DeletedAt *gtime.Time //
|
||||
CreatedAt *gtime.Time //
|
||||
UpdatedAt *gtime.Time //
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
// =================================================================================
|
||||
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
|
||||
// =================================================================================
|
||||
|
||||
package do
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
)
|
||||
|
||||
// FeedMedia is the golang structure of table cv_feed_media for DAO operations like Where/Data.
|
||||
type FeedMedia struct {
|
||||
g.Meta `orm:"table:cv_feed_media, do:true"`
|
||||
Id any //
|
||||
TenantId any //
|
||||
PostId any //
|
||||
UserId any //
|
||||
MediaType any //
|
||||
FileId any //
|
||||
ThumbnailFileId any //
|
||||
Width any //
|
||||
Height any //
|
||||
SortNo any //
|
||||
AuditStatus any //
|
||||
AuditRequestId any //
|
||||
CreatedAt *gtime.Time //
|
||||
UpdatedAt *gtime.Time //
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
// =================================================================================
|
||||
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
|
||||
// =================================================================================
|
||||
|
||||
package do
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
)
|
||||
|
||||
// FeedPost is the golang structure of table cv_feed_post for DAO operations like Where/Data.
|
||||
type FeedPost struct {
|
||||
g.Meta `orm:"table:cv_feed_post, do:true"`
|
||||
Id any //
|
||||
TenantId any //
|
||||
AuthorId any //
|
||||
ContentText any //
|
||||
FlowerCode any //
|
||||
SourceType any //
|
||||
SourceId any //
|
||||
Visibility any //
|
||||
Status any //
|
||||
AuditStatus any //
|
||||
AuditRequestId any //
|
||||
RejectReasonCode any //
|
||||
LikeCount any //
|
||||
CommentCount any //
|
||||
Version any //
|
||||
PublishedAt *gtime.Time //
|
||||
DeletedAt *gtime.Time //
|
||||
TakenDownAt *gtime.Time //
|
||||
CreatedAt *gtime.Time //
|
||||
UpdatedAt *gtime.Time //
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
// =================================================================================
|
||||
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
|
||||
// =================================================================================
|
||||
|
||||
package do
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/encoding/gjson"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
)
|
||||
|
||||
// FeedReport is the golang structure of table cv_feed_report for DAO operations like Where/Data.
|
||||
type FeedReport struct {
|
||||
g.Meta `orm:"table:cv_feed_report, do:true"`
|
||||
Id any //
|
||||
TenantId any //
|
||||
ReporterId any //
|
||||
ReportedUserId any //
|
||||
ObjectType any //
|
||||
ObjectId any //
|
||||
ReasonCode any //
|
||||
Description any //
|
||||
EvidenceFileIds *gjson.Json //
|
||||
SourcePage any //
|
||||
Status any //
|
||||
HandlerId any //
|
||||
HandleResult any //
|
||||
HandledAt *gtime.Time //
|
||||
CreatedAt *gtime.Time //
|
||||
UpdatedAt *gtime.Time //
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
// =================================================================================
|
||||
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
|
||||
// =================================================================================
|
||||
|
||||
package do
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/encoding/gjson"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
)
|
||||
|
||||
// FlowerCatalog is the golang structure of table cv_flower_catalog for DAO operations like Where/Data.
|
||||
type FlowerCatalog struct {
|
||||
g.Meta `orm:"table:cv_flower_catalog, do:true"`
|
||||
Id any //
|
||||
TenantId any //
|
||||
FlowerCode any //
|
||||
FlowerName any //
|
||||
FlowerDesc any //
|
||||
IconFileId any //
|
||||
Status any //
|
||||
ConfigVersion any //
|
||||
DailyWaterLimit any //
|
||||
DailyFertilizeLimit any //
|
||||
ShareConfig *gjson.Json //
|
||||
SortNo any //
|
||||
OnlineAt *gtime.Time //
|
||||
OfflineAt *gtime.Time //
|
||||
CreatedAt *gtime.Time //
|
||||
UpdatedAt *gtime.Time //
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
// =================================================================================
|
||||
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
|
||||
// =================================================================================
|
||||
|
||||
package do
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/encoding/gjson"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
)
|
||||
|
||||
// FlowerStageRule is the golang structure of table cv_flower_stage_rule for DAO operations like Where/Data.
|
||||
type FlowerStageRule struct {
|
||||
g.Meta `orm:"table:cv_flower_stage_rule, do:true"`
|
||||
Id any //
|
||||
TenantId any //
|
||||
FlowerCatalogId any //
|
||||
Stage any //
|
||||
NextStage any //
|
||||
RequiredPoints any //
|
||||
WaterPoints any //
|
||||
FertilizePoints any //
|
||||
AllowedActions *gjson.Json //
|
||||
ImageFileId any //
|
||||
AnimationFileId any //
|
||||
ProgressTextTemplate any //
|
||||
CompletionText any //
|
||||
SortNo any //
|
||||
CreatedAt *gtime.Time //
|
||||
UpdatedAt *gtime.Time //
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
// =================================================================================
|
||||
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
|
||||
// =================================================================================
|
||||
|
||||
package entity
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/encoding/gjson"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
)
|
||||
|
||||
// AdminOperationLog is the golang structure for table admin_operation_log.
|
||||
type AdminOperationLog struct {
|
||||
Id uint64 `json:"id" orm:"id" description:""`
|
||||
TenantId uint64 `json:"tenantId" orm:"tenant_id" description:""`
|
||||
OperatorId uint64 `json:"operatorId" orm:"operator_id" description:""`
|
||||
OperationType string `json:"operationType" orm:"operation_type" description:""`
|
||||
TargetType string `json:"targetType" orm:"target_type" description:""`
|
||||
TargetId string `json:"targetId" orm:"target_id" description:""`
|
||||
RequestId string `json:"requestId" orm:"request_id" description:""`
|
||||
BeforeSnapshot *gjson.Json `json:"beforeSnapshot" orm:"before_snapshot" description:""`
|
||||
AfterSnapshot *gjson.Json `json:"afterSnapshot" orm:"after_snapshot" description:""`
|
||||
Reason string `json:"reason" orm:"reason" description:""`
|
||||
IpAddress string `json:"ipAddress" orm:"ip_address" description:""`
|
||||
UserAgent string `json:"userAgent" orm:"user_agent" description:""`
|
||||
CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:""`
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
// =================================================================================
|
||||
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
|
||||
// =================================================================================
|
||||
|
||||
package entity
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/encoding/gjson"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
)
|
||||
|
||||
// ContentAuditLog is the golang structure for table content_audit_log.
|
||||
type ContentAuditLog struct {
|
||||
Id uint64 `json:"id" orm:"id" description:""`
|
||||
TenantId uint64 `json:"tenantId" orm:"tenant_id" description:""`
|
||||
ObjectType string `json:"objectType" orm:"object_type" description:""`
|
||||
ObjectId uint64 `json:"objectId" orm:"object_id" description:""`
|
||||
AuditRequestId string `json:"auditRequestId" orm:"audit_request_id" description:""`
|
||||
AuditSource string `json:"auditSource" orm:"audit_source" description:""`
|
||||
StatusBefore string `json:"statusBefore" orm:"status_before" description:""`
|
||||
StatusAfter string `json:"statusAfter" orm:"status_after" description:""`
|
||||
ResultCode string `json:"resultCode" orm:"result_code" description:""`
|
||||
RiskLabels *gjson.Json `json:"riskLabels" orm:"risk_labels" description:""`
|
||||
OperatorId uint64 `json:"operatorId" orm:"operator_id" description:""`
|
||||
OccurredAt *gtime.Time `json:"occurredAt" orm:"occurred_at" description:""`
|
||||
CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:""`
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
// =================================================================================
|
||||
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
|
||||
// =================================================================================
|
||||
|
||||
package entity
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
)
|
||||
|
||||
// FeedComment is the golang structure for table feed_comment.
|
||||
type FeedComment struct {
|
||||
Id uint64 `json:"id" orm:"id" description:""`
|
||||
TenantId uint64 `json:"tenantId" orm:"tenant_id" description:""`
|
||||
PostId uint64 `json:"postId" orm:"post_id" description:""`
|
||||
AuthorId uint64 `json:"authorId" orm:"author_id" description:""`
|
||||
ContentText string `json:"contentText" orm:"content_text" description:""`
|
||||
Status string `json:"status" orm:"status" description:""`
|
||||
AuditStatus string `json:"auditStatus" orm:"audit_status" description:""`
|
||||
AuditRequestId string `json:"auditRequestId" orm:"audit_request_id" description:""`
|
||||
DeletedBy uint64 `json:"deletedBy" orm:"deleted_by" description:""`
|
||||
DeleteReason string `json:"deleteReason" orm:"delete_reason" description:""`
|
||||
PublishedAt *gtime.Time `json:"publishedAt" orm:"published_at" description:""`
|
||||
DeletedAt *gtime.Time `json:"deletedAt" orm:"deleted_at" description:""`
|
||||
CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:""`
|
||||
UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:""`
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
// =================================================================================
|
||||
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
|
||||
// =================================================================================
|
||||
|
||||
package entity
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
)
|
||||
|
||||
// FeedMedia is the golang structure for table feed_media.
|
||||
type FeedMedia struct {
|
||||
Id uint64 `json:"id" orm:"id" description:""`
|
||||
TenantId uint64 `json:"tenantId" orm:"tenant_id" description:""`
|
||||
PostId uint64 `json:"postId" orm:"post_id" description:""`
|
||||
UserId uint64 `json:"userId" orm:"user_id" description:""`
|
||||
MediaType string `json:"mediaType" orm:"media_type" description:""`
|
||||
FileId string `json:"fileId" orm:"file_id" description:""`
|
||||
ThumbnailFileId string `json:"thumbnailFileId" orm:"thumbnail_file_id" description:""`
|
||||
Width uint `json:"width" orm:"width" description:""`
|
||||
Height uint `json:"height" orm:"height" description:""`
|
||||
SortNo uint `json:"sortNo" orm:"sort_no" description:""`
|
||||
AuditStatus string `json:"auditStatus" orm:"audit_status" description:""`
|
||||
AuditRequestId string `json:"auditRequestId" orm:"audit_request_id" description:""`
|
||||
CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:""`
|
||||
UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:""`
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
// =================================================================================
|
||||
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
|
||||
// =================================================================================
|
||||
|
||||
package entity
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
)
|
||||
|
||||
// FeedPost is the golang structure for table feed_post.
|
||||
type FeedPost struct {
|
||||
Id uint64 `json:"id" orm:"id" description:""`
|
||||
TenantId uint64 `json:"tenantId" orm:"tenant_id" description:""`
|
||||
AuthorId uint64 `json:"authorId" orm:"author_id" description:""`
|
||||
ContentText string `json:"contentText" orm:"content_text" description:""`
|
||||
FlowerCode string `json:"flowerCode" orm:"flower_code" description:""`
|
||||
SourceType string `json:"sourceType" orm:"source_type" description:""`
|
||||
SourceId uint64 `json:"sourceId" orm:"source_id" description:""`
|
||||
Visibility string `json:"visibility" orm:"visibility" description:""`
|
||||
Status string `json:"status" orm:"status" description:""`
|
||||
AuditStatus string `json:"auditStatus" orm:"audit_status" description:""`
|
||||
AuditRequestId string `json:"auditRequestId" orm:"audit_request_id" description:""`
|
||||
RejectReasonCode string `json:"rejectReasonCode" orm:"reject_reason_code" description:""`
|
||||
LikeCount uint `json:"likeCount" orm:"like_count" description:""`
|
||||
CommentCount uint `json:"commentCount" orm:"comment_count" description:""`
|
||||
Version uint `json:"version" orm:"version" description:""`
|
||||
PublishedAt *gtime.Time `json:"publishedAt" orm:"published_at" description:""`
|
||||
DeletedAt *gtime.Time `json:"deletedAt" orm:"deleted_at" description:""`
|
||||
TakenDownAt *gtime.Time `json:"takenDownAt" orm:"taken_down_at" description:""`
|
||||
CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:""`
|
||||
UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:""`
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
// =================================================================================
|
||||
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
|
||||
// =================================================================================
|
||||
|
||||
package entity
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/encoding/gjson"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
)
|
||||
|
||||
// FeedReport is the golang structure for table feed_report.
|
||||
type FeedReport struct {
|
||||
Id uint64 `json:"id" orm:"id" description:""`
|
||||
TenantId uint64 `json:"tenantId" orm:"tenant_id" description:""`
|
||||
ReporterId uint64 `json:"reporterId" orm:"reporter_id" description:""`
|
||||
ReportedUserId uint64 `json:"reportedUserId" orm:"reported_user_id" description:""`
|
||||
ObjectType string `json:"objectType" orm:"object_type" description:""`
|
||||
ObjectId string `json:"objectId" orm:"object_id" description:""`
|
||||
ReasonCode string `json:"reasonCode" orm:"reason_code" description:""`
|
||||
Description string `json:"description" orm:"description" description:""`
|
||||
EvidenceFileIds *gjson.Json `json:"evidenceFileIds" orm:"evidence_file_ids" description:""`
|
||||
SourcePage string `json:"sourcePage" orm:"source_page" description:""`
|
||||
Status string `json:"status" orm:"status" description:""`
|
||||
HandlerId uint64 `json:"handlerId" orm:"handler_id" description:""`
|
||||
HandleResult string `json:"handleResult" orm:"handle_result" description:""`
|
||||
HandledAt *gtime.Time `json:"handledAt" orm:"handled_at" description:""`
|
||||
CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:""`
|
||||
UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:""`
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
// =================================================================================
|
||||
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
|
||||
// =================================================================================
|
||||
|
||||
package entity
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/encoding/gjson"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
)
|
||||
|
||||
// FlowerCatalog is the golang structure for table flower_catalog.
|
||||
type FlowerCatalog struct {
|
||||
Id uint64 `json:"id" orm:"id" description:""`
|
||||
TenantId uint64 `json:"tenantId" orm:"tenant_id" description:""`
|
||||
FlowerCode string `json:"flowerCode" orm:"flower_code" description:""`
|
||||
FlowerName string `json:"flowerName" orm:"flower_name" description:""`
|
||||
FlowerDesc string `json:"flowerDesc" orm:"flower_desc" description:""`
|
||||
IconFileId string `json:"iconFileId" orm:"icon_file_id" description:""`
|
||||
Status string `json:"status" orm:"status" description:""`
|
||||
ConfigVersion string `json:"configVersion" orm:"config_version" description:""`
|
||||
DailyWaterLimit uint `json:"dailyWaterLimit" orm:"daily_water_limit" description:""`
|
||||
DailyFertilizeLimit uint `json:"dailyFertilizeLimit" orm:"daily_fertilize_limit" description:""`
|
||||
ShareConfig *gjson.Json `json:"shareConfig" orm:"share_config" description:""`
|
||||
SortNo int `json:"sortNo" orm:"sort_no" description:""`
|
||||
OnlineAt *gtime.Time `json:"onlineAt" orm:"online_at" description:""`
|
||||
OfflineAt *gtime.Time `json:"offlineAt" orm:"offline_at" description:""`
|
||||
CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:""`
|
||||
UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:""`
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
// =================================================================================
|
||||
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
|
||||
// =================================================================================
|
||||
|
||||
package entity
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/encoding/gjson"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
)
|
||||
|
||||
// FlowerStageRule is the golang structure for table flower_stage_rule.
|
||||
type FlowerStageRule struct {
|
||||
Id uint64 `json:"id" orm:"id" description:""`
|
||||
TenantId uint64 `json:"tenantId" orm:"tenant_id" description:""`
|
||||
FlowerCatalogId uint64 `json:"flowerCatalogId" orm:"flower_catalog_id" description:""`
|
||||
Stage string `json:"stage" orm:"stage" description:""`
|
||||
NextStage string `json:"nextStage" orm:"next_stage" description:""`
|
||||
RequiredPoints uint `json:"requiredPoints" orm:"required_points" description:""`
|
||||
WaterPoints uint `json:"waterPoints" orm:"water_points" description:""`
|
||||
FertilizePoints uint `json:"fertilizePoints" orm:"fertilize_points" description:""`
|
||||
AllowedActions *gjson.Json `json:"allowedActions" orm:"allowed_actions" description:""`
|
||||
ImageFileId string `json:"imageFileId" orm:"image_file_id" description:""`
|
||||
AnimationFileId string `json:"animationFileId" orm:"animation_file_id" description:""`
|
||||
ProgressTextTemplate string `json:"progressTextTemplate" orm:"progress_text_template" description:""`
|
||||
CompletionText string `json:"completionText" orm:"completion_text" description:""`
|
||||
SortNo int `json:"sortNo" orm:"sort_no" description:""`
|
||||
CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:""`
|
||||
UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:""`
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
package sysin
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
|
||||
"hotgo/internal/model/input/form"
|
||||
)
|
||||
|
||||
type CultivateContentListInp struct {
|
||||
form.PageReq
|
||||
ObjectType string `json:"objectType" d:"feed_post"`
|
||||
AuthorId string `json:"authorId"`
|
||||
Status string `json:"status"`
|
||||
Keyword string `json:"keyword"`
|
||||
CreatedAt []*gtime.Time `json:"createdAt"`
|
||||
}
|
||||
|
||||
func (in *CultivateContentListInp) Filter(context.Context) error {
|
||||
in.ObjectType = strings.TrimSpace(in.ObjectType)
|
||||
if in.ObjectType != "feed_post" && in.ObjectType != "feed_comment" {
|
||||
return gerror.New("内容类型不正确")
|
||||
}
|
||||
if in.AuthorId != "" {
|
||||
if _, err := strconv.ParseUint(in.AuthorId, 10, 64); err != nil {
|
||||
return gerror.New("作者ID不正确")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type CultivateContentListModel struct {
|
||||
Id string `json:"id"`
|
||||
ObjectType string `json:"objectType"`
|
||||
PostId string `json:"postId"`
|
||||
AuthorId string `json:"authorId"`
|
||||
ContentText string `json:"contentText"`
|
||||
FlowerCode string `json:"flowerCode"`
|
||||
Visibility string `json:"visibility"`
|
||||
Status string `json:"status"`
|
||||
AuditStatus string `json:"auditStatus"`
|
||||
RejectReason string `json:"rejectReason"`
|
||||
LikeCount uint `json:"likeCount"`
|
||||
CommentCount uint `json:"commentCount"`
|
||||
CreatedAt *gtime.Time `json:"createdAt"`
|
||||
UpdatedAt *gtime.Time `json:"updatedAt"`
|
||||
}
|
||||
|
||||
type CultivateContentReviewInp struct {
|
||||
ObjectType string `json:"objectType" v:"required|in:feed_post,feed_comment#内容类型不能为空|内容类型不正确"`
|
||||
Id string `json:"id" v:"required#内容ID不能为空"`
|
||||
Action string `json:"action" v:"required|in:approve,reject,take_down,restore#审核动作不能为空|审核动作不正确"`
|
||||
Reason string `json:"reason"`
|
||||
ObjectId uint64 `json:"-"`
|
||||
}
|
||||
|
||||
func (in *CultivateContentReviewInp) Filter(context.Context) error {
|
||||
id, err := strconv.ParseUint(strings.TrimSpace(in.Id), 10, 64)
|
||||
if err != nil || id == 0 {
|
||||
return gerror.New("内容ID不正确")
|
||||
}
|
||||
in.ObjectId = id
|
||||
in.Reason = strings.TrimSpace(in.Reason)
|
||||
if (in.Action == "reject" || in.Action == "take_down") && in.Reason == "" {
|
||||
return gerror.New("拒绝或下架时必须填写原因")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type CultivateReportListInp struct {
|
||||
form.PageReq
|
||||
ObjectType string `json:"objectType"`
|
||||
Status string `json:"status"`
|
||||
ReporterId string `json:"reporterId"`
|
||||
CreatedAt []*gtime.Time `json:"createdAt"`
|
||||
}
|
||||
|
||||
func (in *CultivateReportListInp) Filter(context.Context) error {
|
||||
if in.ReporterId != "" {
|
||||
if _, err := strconv.ParseUint(in.ReporterId, 10, 64); err != nil {
|
||||
return gerror.New("举报人ID不正确")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type CultivateReportListModel struct {
|
||||
Id string `json:"id"`
|
||||
ReporterId string `json:"reporterId"`
|
||||
ReportedUserId string `json:"reportedUserId"`
|
||||
ObjectType string `json:"objectType"`
|
||||
ObjectId string `json:"objectId"`
|
||||
ReasonCode string `json:"reasonCode"`
|
||||
Description string `json:"description"`
|
||||
EvidenceFileIds any `json:"evidenceFileIds"`
|
||||
SourcePage string `json:"sourcePage"`
|
||||
Status string `json:"status"`
|
||||
HandlerId string `json:"handlerId"`
|
||||
HandleResult string `json:"handleResult"`
|
||||
HandledAt *gtime.Time `json:"handledAt"`
|
||||
CreatedAt *gtime.Time `json:"createdAt"`
|
||||
}
|
||||
|
||||
type CultivateReportHandleInp struct {
|
||||
Id string `json:"id" v:"required#举报ID不能为空"`
|
||||
Action string `json:"action" v:"required|in:processing,resolve,reject#处理动作不能为空|处理动作不正确"`
|
||||
HandleResult string `json:"handleResult"`
|
||||
ReportId uint64 `json:"-"`
|
||||
}
|
||||
|
||||
func (in *CultivateReportHandleInp) Filter(context.Context) error {
|
||||
id, err := strconv.ParseUint(strings.TrimSpace(in.Id), 10, 64)
|
||||
if err != nil || id == 0 {
|
||||
return gerror.New("举报ID不正确")
|
||||
}
|
||||
in.ReportId = id
|
||||
in.HandleResult = strings.TrimSpace(in.HandleResult)
|
||||
if in.Action != "processing" && in.HandleResult == "" {
|
||||
return gerror.New("办结举报时必须填写处理结果")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type CultivateOperationLogListInp struct {
|
||||
form.PageReq
|
||||
OperatorId string `json:"operatorId"`
|
||||
OperationType string `json:"operationType"`
|
||||
TargetType string `json:"targetType"`
|
||||
CreatedAt []*gtime.Time `json:"createdAt"`
|
||||
}
|
||||
|
||||
func (*CultivateOperationLogListInp) Filter(context.Context) error { return nil }
|
||||
|
||||
type CultivateOperationLogListModel struct {
|
||||
Id string `json:"id"`
|
||||
OperatorId string `json:"operatorId"`
|
||||
OperationType string `json:"operationType"`
|
||||
TargetType string `json:"targetType"`
|
||||
TargetId string `json:"targetId"`
|
||||
RequestId string `json:"requestId"`
|
||||
BeforeSnapshot any `json:"beforeSnapshot"`
|
||||
AfterSnapshot any `json:"afterSnapshot"`
|
||||
Reason string `json:"reason"`
|
||||
CreatedAt *gtime.Time `json:"createdAt"`
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
package sysin
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
"github.com/gogf/gf/v2/encoding/gjson"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
|
||||
"hotgo/internal/model/input/form"
|
||||
)
|
||||
|
||||
type CultivateStageRuleEditInp struct {
|
||||
Id uint64 `json:"id"`
|
||||
Stage string `json:"stage"`
|
||||
NextStage string `json:"nextStage"`
|
||||
RequiredPoints uint `json:"requiredPoints"`
|
||||
WaterPoints uint `json:"waterPoints"`
|
||||
FertilizePoints uint `json:"fertilizePoints"`
|
||||
AllowedActions []string `json:"allowedActions"`
|
||||
ImageFileId string `json:"imageFileId"`
|
||||
AnimationFileId string `json:"animationFileId"`
|
||||
ProgressTextTemplate string `json:"progressTextTemplate"`
|
||||
CompletionText string `json:"completionText"`
|
||||
SortNo int `json:"sortNo"`
|
||||
}
|
||||
|
||||
type CultivateFlowerEditInp struct {
|
||||
Id uint64 `json:"id"`
|
||||
FlowerCode string `json:"flowerCode"`
|
||||
FlowerName string `json:"flowerName"`
|
||||
FlowerDesc string `json:"flowerDesc"`
|
||||
IconFileId string `json:"iconFileId"`
|
||||
Status string `json:"status"`
|
||||
DailyWaterLimit uint `json:"dailyWaterLimit"`
|
||||
DailyFertilizeLimit uint `json:"dailyFertilizeLimit"`
|
||||
ShareConfig *gjson.Json `json:"shareConfig"`
|
||||
SortNo int `json:"sortNo"`
|
||||
StageRules []*CultivateStageRuleEditInp `json:"stageRules"`
|
||||
}
|
||||
|
||||
func (in *CultivateFlowerEditInp) Filter(ctx context.Context) error {
|
||||
in.FlowerCode = strings.TrimSpace(in.FlowerCode)
|
||||
in.FlowerName = strings.TrimSpace(in.FlowerName)
|
||||
if in.FlowerCode == "" || in.FlowerName == "" {
|
||||
return gerror.New("花种编码和名称不能为空")
|
||||
}
|
||||
validStatus := map[string]bool{"online": true, "offline": true, "activity_only": true, "maintenance": true}
|
||||
if !validStatus[in.Status] {
|
||||
return gerror.New("花种状态不正确")
|
||||
}
|
||||
if len(in.StageRules) == 0 {
|
||||
return gerror.New("至少配置一个成长阶段")
|
||||
}
|
||||
validStage := map[string]bool{"seed": true, "sprout": true, "bud": true, "bloom": true}
|
||||
validAction := map[string]bool{"water": true, "fertilize": true}
|
||||
seen := map[string]bool{}
|
||||
for _, rule := range in.StageRules {
|
||||
if rule == nil || !validStage[rule.Stage] {
|
||||
return gerror.New("成长阶段不正确")
|
||||
}
|
||||
if seen[rule.Stage] {
|
||||
return gerror.New("成长阶段不能重复")
|
||||
}
|
||||
seen[rule.Stage] = true
|
||||
if rule.Stage != "bloom" && rule.RequiredPoints == 0 {
|
||||
return gerror.New("非开花阶段升级阈值必须大于0")
|
||||
}
|
||||
if rule.NextStage != "" && !validStage[rule.NextStage] {
|
||||
return gerror.New("下一阶段不正确")
|
||||
}
|
||||
if rule.Stage != "bloom" && len(rule.AllowedActions) == 0 {
|
||||
return gerror.New("非开花阶段至少允许一种成长动作")
|
||||
}
|
||||
for _, action := range rule.AllowedActions {
|
||||
if !validAction[action] {
|
||||
return gerror.New("成长动作不正确")
|
||||
}
|
||||
}
|
||||
}
|
||||
stage := "seed"
|
||||
visited := map[string]bool{}
|
||||
for stage != "" {
|
||||
if visited[stage] {
|
||||
return gerror.New("成长阶段链不能形成循环")
|
||||
}
|
||||
visited[stage] = true
|
||||
var next string
|
||||
found := false
|
||||
for _, r := range in.StageRules {
|
||||
if r.Stage == stage {
|
||||
next = r.NextStage
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
return gerror.New("成长阶段链必须从 seed 连续配置")
|
||||
}
|
||||
stage = next
|
||||
}
|
||||
if !visited["bloom"] {
|
||||
return gerror.New("成长阶段链必须以 bloom 结束")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type CultivateFlowerListInp struct {
|
||||
form.PageReq
|
||||
FlowerCode string `json:"flowerCode"`
|
||||
FlowerName string `json:"flowerName"`
|
||||
Status string `json:"status"`
|
||||
ConfigVersion string `json:"configVersion"`
|
||||
CreatedAt []*gtime.Time `json:"createdAt"`
|
||||
}
|
||||
|
||||
func (*CultivateFlowerListInp) Filter(context.Context) error { return nil }
|
||||
|
||||
type CultivateFlowerListModel struct {
|
||||
Id uint64 `json:"id"`
|
||||
FlowerCode string `json:"flowerCode"`
|
||||
FlowerName string `json:"flowerName"`
|
||||
FlowerDesc string `json:"flowerDesc"`
|
||||
IconFileId string `json:"iconFileId"`
|
||||
Status string `json:"status"`
|
||||
ConfigVersion string `json:"configVersion"`
|
||||
DailyWaterLimit uint `json:"dailyWaterLimit"`
|
||||
DailyFertilizeLimit uint `json:"dailyFertilizeLimit"`
|
||||
SortNo int `json:"sortNo"`
|
||||
StageCount int `json:"stageCount"`
|
||||
CreatedAt *gtime.Time `json:"createdAt"`
|
||||
UpdatedAt *gtime.Time `json:"updatedAt"`
|
||||
}
|
||||
|
||||
type CultivateFlowerViewInp struct {
|
||||
Id uint64 `json:"id" v:"required#ID不能为空"`
|
||||
}
|
||||
|
||||
func (*CultivateFlowerViewInp) Filter(context.Context) error { return nil }
|
||||
|
||||
type CultivateFlowerViewModel struct {
|
||||
CultivateFlowerEditInp
|
||||
ConfigVersion string `json:"configVersion"`
|
||||
CreatedAt *gtime.Time `json:"createdAt"`
|
||||
UpdatedAt *gtime.Time `json:"updatedAt"`
|
||||
}
|
||||
|
||||
type CultivateFlowerStatusInp struct {
|
||||
Id uint64 `json:"id" v:"required#ID不能为空"`
|
||||
Status string `json:"status" v:"required|in:online,offline,activity_only,maintenance#状态不能为空|状态不正确"`
|
||||
Reason string `json:"reason"`
|
||||
}
|
||||
|
||||
func (*CultivateFlowerStatusInp) Filter(context.Context) error { return nil }
|
||||
@@ -0,0 +1,5 @@
|
||||
package genrouter
|
||||
|
||||
import "hotgo/internal/controller/admin/sys"
|
||||
|
||||
func init() { LoginRequiredRouter = append(LoginRequiredRouter, sys.CultivateContent) }
|
||||
@@ -0,0 +1,5 @@
|
||||
package genrouter
|
||||
|
||||
import "hotgo/internal/controller/admin/sys"
|
||||
|
||||
func init() { LoginRequiredRouter = append(LoginRequiredRouter, sys.CultivateFlower) }
|
||||
@@ -172,6 +172,19 @@ type (
|
||||
// Switch 更新CURD列表开关
|
||||
Switch(ctx context.Context, in *sysin.CurdDemoSwitchInp) (err error)
|
||||
}
|
||||
ISysCultivateFlower interface {
|
||||
List(ctx context.Context, in *sysin.CultivateFlowerListInp) (list []*sysin.CultivateFlowerListModel, totalCount int, err error)
|
||||
View(ctx context.Context, in *sysin.CultivateFlowerViewInp) (res *sysin.CultivateFlowerViewModel, err error)
|
||||
Edit(ctx context.Context, in *sysin.CultivateFlowerEditInp) (err error)
|
||||
Status(ctx context.Context, in *sysin.CultivateFlowerStatusInp) (err error)
|
||||
}
|
||||
ISysCultivateContent interface {
|
||||
List(ctx context.Context, in *sysin.CultivateContentListInp) (list []*sysin.CultivateContentListModel, totalCount int, err error)
|
||||
Review(ctx context.Context, in *sysin.CultivateContentReviewInp) error
|
||||
ReportList(ctx context.Context, in *sysin.CultivateReportListInp) (list []*sysin.CultivateReportListModel, totalCount int, err error)
|
||||
ReportHandle(ctx context.Context, in *sysin.CultivateReportHandleInp) error
|
||||
LogList(ctx context.Context, in *sysin.CultivateOperationLogListInp) (list []*sysin.CultivateOperationLogListModel, totalCount int, err error)
|
||||
}
|
||||
ISysImTenant interface {
|
||||
// Model IM租户ORM模型
|
||||
Model(ctx context.Context, option ...*handler.Option) *gdb.Model
|
||||
@@ -767,6 +780,8 @@ var (
|
||||
localSysCron ISysCron
|
||||
localSysCronGroup ISysCronGroup
|
||||
localSysCurdDemo ISysCurdDemo
|
||||
localSysCultivateFlower ISysCultivateFlower
|
||||
localSysCultivateContent ISysCultivateContent
|
||||
localSysImTenant ISysImTenant
|
||||
localSysImRegistration ISysImRegistration
|
||||
localSysImInvite ISysImInvite
|
||||
@@ -901,6 +916,26 @@ func RegisterSysCurdDemo(i ISysCurdDemo) {
|
||||
localSysCurdDemo = i
|
||||
}
|
||||
|
||||
func SysCultivateFlower() ISysCultivateFlower {
|
||||
if localSysCultivateFlower == nil {
|
||||
panic("implement not found for interface ISysCultivateFlower, forgot register?")
|
||||
}
|
||||
return localSysCultivateFlower
|
||||
}
|
||||
|
||||
func RegisterSysCultivateFlower(i ISysCultivateFlower) {
|
||||
localSysCultivateFlower = i
|
||||
}
|
||||
|
||||
func SysCultivateContent() ISysCultivateContent {
|
||||
if localSysCultivateContent == nil {
|
||||
panic("implement not found for interface ISysCultivateContent, forgot register?")
|
||||
}
|
||||
return localSysCultivateContent
|
||||
}
|
||||
|
||||
func RegisterSysCultivateContent(i ISysCultivateContent) { localSysCultivateContent = i }
|
||||
|
||||
func SysImTenant() ISysImTenant {
|
||||
if localSysImTenant == nil {
|
||||
panic("implement not found for interface ISysImTenant, forgot register?")
|
||||
|
||||
@@ -240,6 +240,9 @@ database:
|
||||
link: "mysql:root:${MYSQL_PASSWORD}@tcp(mysql.118im.com:30306)/hotgo?loc=Local&parseTime=true&charset=utf8mb4"
|
||||
debug: true
|
||||
Prefix: "hg_"
|
||||
cultivate:
|
||||
link: "mysql:root:${MYSQL_PASSWORD}@tcp(127.0.0.1:3306)/cultivate?loc=Local&parseTime=true&charset=utf8mb4"
|
||||
debug: true
|
||||
imRegistry:
|
||||
link: "mysql:root:${MYSQL_PASSWORD}@tcp(mysql.118im.com:30306)/hotgo?loc=Local&parseTime=true&charset=utf8mb4"
|
||||
debug: true
|
||||
|
||||
@@ -240,8 +240,14 @@ database:
|
||||
link: "$MYSQL_DSN"
|
||||
debug: true
|
||||
Prefix: "hg_"
|
||||
cultivate:
|
||||
link: "$CULTIVATE_MYSQL_DSN"
|
||||
debug: true
|
||||
|
||||
|
||||
cultivate:
|
||||
defaultTenantId: 1
|
||||
|
||||
# 链路追踪
|
||||
jaeger:
|
||||
switch: false # 链路追踪开关,可选:true|false,默认为false
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
-- 养成管理菜单与首期花种配置权限(可重复执行)
|
||||
SET NAMES utf8mb4;
|
||||
SET @now := NOW();
|
||||
|
||||
INSERT INTO hg_admin_menu (pid,level,tree,title,name,path,icon,type,redirect,permissions,permission_name,component,always_show,active_menu,is_root,is_frame,frame_src,keep_alive,hidden,affix,sort,remark,status,created_at,updated_at)
|
||||
SELECT 0,1,'','养成管理','cultivateManager','/cultivate','ExperimentOutlined',1,'/cultivate/flowers','','','LAYOUT',1,'',0,0,'',0,0,0,124,'后院养成与物友动态管理',1,@now,@now
|
||||
WHERE NOT EXISTS (SELECT 1 FROM hg_admin_menu WHERE name='cultivateManager');
|
||||
SET @cultivateId := (SELECT id FROM hg_admin_menu WHERE name='cultivateManager' LIMIT 1);
|
||||
|
||||
INSERT INTO hg_admin_menu (pid,level,tree,title,name,path,icon,type,redirect,permissions,permission_name,component,always_show,active_menu,is_root,is_frame,frame_src,keep_alive,hidden,affix,sort,remark,status,created_at,updated_at)
|
||||
SELECT @cultivateId,2,CONCAT('tr_',@cultivateId,' '),'花种配置','cultivateFlowers','flowers','',2,'','/cultivate/flowers/list','','/cultivate/flowers/index',1,'cultivateFlowers',0,0,'',1,0,0,40,'花种、成长阶段、每日限额与素材配置',1,@now,@now
|
||||
WHERE NOT EXISTS (SELECT 1 FROM hg_admin_menu WHERE name='cultivateFlowers');
|
||||
SET @flowersId := (SELECT id FROM hg_admin_menu WHERE name='cultivateFlowers' LIMIT 1);
|
||||
|
||||
INSERT INTO hg_admin_menu (pid,level,tree,title,name,path,icon,type,redirect,permissions,permission_name,component,always_show,active_menu,is_root,is_frame,frame_src,keep_alive,hidden,affix,sort,remark,status,created_at,updated_at)
|
||||
SELECT @flowersId,3,CONCAT('tr_',@cultivateId,' tr_',@flowersId,' '),'查看花种','cultivateFlowersView','','',3,'','/cultivate/flowers/view','','',1,'',0,0,'',0,1,0,30,'',1,@now,@now
|
||||
WHERE NOT EXISTS (SELECT 1 FROM hg_admin_menu WHERE name='cultivateFlowersView');
|
||||
|
||||
INSERT INTO hg_admin_menu (pid,level,tree,title,name,path,icon,type,redirect,permissions,permission_name,component,always_show,active_menu,is_root,is_frame,frame_src,keep_alive,hidden,affix,sort,remark,status,created_at,updated_at)
|
||||
SELECT @flowersId,3,CONCAT('tr_',@cultivateId,' tr_',@flowersId,' '),'编辑花种','cultivateFlowersEdit','','',3,'','/cultivate/flowers/edit','','',1,'',0,0,'',0,1,0,20,'',1,@now,@now
|
||||
WHERE NOT EXISTS (SELECT 1 FROM hg_admin_menu WHERE name='cultivateFlowersEdit');
|
||||
|
||||
INSERT INTO hg_admin_menu (pid,level,tree,title,name,path,icon,type,redirect,permissions,permission_name,component,always_show,active_menu,is_root,is_frame,frame_src,keep_alive,hidden,affix,sort,remark,status,created_at,updated_at)
|
||||
SELECT @flowersId,3,CONCAT('tr_',@cultivateId,' tr_',@flowersId,' '),'上下架花种','cultivateFlowersStatus','','',3,'','/cultivate/flowers/status','','',1,'',0,0,'',0,1,0,10,'',1,@now,@now
|
||||
WHERE NOT EXISTS (SELECT 1 FROM hg_admin_menu WHERE name='cultivateFlowersStatus');
|
||||
|
||||
INSERT INTO hg_admin_menu (pid,level,tree,title,name,path,icon,type,redirect,permissions,permission_name,component,always_show,active_menu,is_root,is_frame,frame_src,keep_alive,hidden,affix,sort,remark,status,created_at,updated_at)
|
||||
SELECT @cultivateId,2,CONCAT('tr_',@cultivateId,' '),'内容审核','cultivateContent','content','',2,'','/cultivate/content/list','','/cultivate/content/index',1,'cultivateContent',0,0,'',1,0,0,30,'物友动态与评论审核管理',1,@now,@now
|
||||
WHERE NOT EXISTS (SELECT 1 FROM hg_admin_menu WHERE name='cultivateContent');
|
||||
SET @contentId := (SELECT id FROM hg_admin_menu WHERE name='cultivateContent' LIMIT 1);
|
||||
|
||||
INSERT INTO hg_admin_menu (pid,level,tree,title,name,path,icon,type,redirect,permissions,permission_name,component,always_show,active_menu,is_root,is_frame,frame_src,keep_alive,hidden,affix,sort,remark,status,created_at,updated_at)
|
||||
SELECT @contentId,3,CONCAT('tr_',@cultivateId,' tr_',@contentId,' '),'审核内容','cultivateContentReview','','',3,'','/cultivate/content/review','','',1,'',0,0,'',0,1,0,20,'',1,@now,@now
|
||||
WHERE NOT EXISTS (SELECT 1 FROM hg_admin_menu WHERE name='cultivateContentReview');
|
||||
|
||||
INSERT INTO hg_admin_menu (pid,level,tree,title,name,path,icon,type,redirect,permissions,permission_name,component,always_show,active_menu,is_root,is_frame,frame_src,keep_alive,hidden,affix,sort,remark,status,created_at,updated_at)
|
||||
SELECT @cultivateId,2,CONCAT('tr_',@cultivateId,' '),'举报处理','cultivateReports','reports','',2,'','/cultivate/reports/list','','/cultivate/reports/index',1,'cultivateReports',0,0,'',1,0,0,20,'物友内容与用户举报处理',1,@now,@now
|
||||
WHERE NOT EXISTS (SELECT 1 FROM hg_admin_menu WHERE name='cultivateReports');
|
||||
SET @reportsId := (SELECT id FROM hg_admin_menu WHERE name='cultivateReports' LIMIT 1);
|
||||
|
||||
INSERT INTO hg_admin_menu (pid,level,tree,title,name,path,icon,type,redirect,permissions,permission_name,component,always_show,active_menu,is_root,is_frame,frame_src,keep_alive,hidden,affix,sort,remark,status,created_at,updated_at)
|
||||
SELECT @reportsId,3,CONCAT('tr_',@cultivateId,' tr_',@reportsId,' '),'处理举报','cultivateReportsHandle','','',3,'','/cultivate/reports/handle','','',1,'',0,0,'',0,1,0,20,'',1,@now,@now
|
||||
WHERE NOT EXISTS (SELECT 1 FROM hg_admin_menu WHERE name='cultivateReportsHandle');
|
||||
|
||||
INSERT INTO hg_admin_menu (pid,level,tree,title,name,path,icon,type,redirect,permissions,permission_name,component,always_show,active_menu,is_root,is_frame,frame_src,keep_alive,hidden,affix,sort,remark,status,created_at,updated_at)
|
||||
SELECT @cultivateId,2,CONCAT('tr_',@cultivateId,' '),'操作日志','cultivateLogs','logs','',2,'','/cultivate/logs/list','','/cultivate/logs/index',1,'cultivateLogs',0,0,'',1,0,0,10,'养成管理操作审计日志',1,@now,@now
|
||||
WHERE NOT EXISTS (SELECT 1 FROM hg_admin_menu WHERE name='cultivateLogs');
|
||||
@@ -0,0 +1,7 @@
|
||||
import { http } from '@/utils/http/axios';
|
||||
|
||||
export function ContentList(params) { return http.request({ url: '/cultivate/content/list', method: 'get', params }); }
|
||||
export function ContentReview(params) { return http.request({ url: '/cultivate/content/review', method: 'POST', params }); }
|
||||
export function ReportList(params) { return http.request({ url: '/cultivate/reports/list', method: 'get', params }); }
|
||||
export function ReportHandle(params) { return http.request({ url: '/cultivate/reports/handle', method: 'POST', params }); }
|
||||
export function OperationLogList(params) { return http.request({ url: '/cultivate/logs/list', method: 'get', params }); }
|
||||
@@ -0,0 +1,6 @@
|
||||
import { http } from '@/utils/http/axios';
|
||||
|
||||
export function List(params) { return http.request({ url: '/cultivate/flowers/list', method: 'get', params }); }
|
||||
export function View(params) { return http.request({ url: '/cultivate/flowers/view', method: 'get', params }); }
|
||||
export function Edit(params) { return http.request({ url: '/cultivate/flowers/edit', method: 'POST', params }); }
|
||||
export function Status(params) { return http.request({ url: '/cultivate/flowers/status', method: 'POST', params }); }
|
||||
@@ -0,0 +1,37 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="n-layout-page-header"><n-card :bordered="false" title="内容审核">审核物友动态与评论,支持拒绝、下架和恢复。</n-card></div>
|
||||
<n-card :bordered="false" class="proCard">
|
||||
<BasicForm ref="searchFormRef" @register="register" @submit="reloadTable" @reset="reloadTable" @keyup.enter="reloadTable" />
|
||||
<BasicTable ref="actionRef" :columns="columns" :request="loadDataTable" :row-key="(row) => row.id" :actionColumn="actionColumn" :scroll-x="1450" />
|
||||
</n-card>
|
||||
<n-modal v-model:show="showReview" preset="dialog" title="内容审核" positive-text="确认" negative-text="取消" @positive-click="submitReview">
|
||||
<n-space vertical>
|
||||
<n-select v-model:value="reviewForm.action" :options="reviewOptions" placeholder="请选择审核动作" />
|
||||
<n-input v-model:value="reviewForm.reason" type="textarea" placeholder="拒绝或下架时必须填写原因" />
|
||||
</n-space>
|
||||
</n-modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { h, onMounted, reactive, ref } from 'vue';
|
||||
import { useMessage } from 'naive-ui';
|
||||
import { BasicTable, TableAction } from '@/components/Table';
|
||||
import { BasicForm, useForm } from '@/components/Form';
|
||||
import { usePermission } from '@/hooks/web/usePermission';
|
||||
import { ContentList, ContentReview } from '@/api/cultivate/content';
|
||||
import { columns, ContentState, loadOptions, schemas } from './model';
|
||||
|
||||
const actionRef = ref(); const searchFormRef = ref<any>({}); const showReview = ref(false); const selected = ref<ContentState>();
|
||||
const message = useMessage(); const { hasPermission } = usePermission();
|
||||
const reviewForm = reactive({ action: 'approve', reason: '' });
|
||||
const reviewOptions = [{ label: '审核通过', value: 'approve' }, { label: '审核拒绝', value: 'reject' }, { label: '下架', value: 'take_down' }, { label: '恢复发布', value: 'restore' }];
|
||||
const [register] = useForm({ gridProps: { cols: '1 s:1 m:2 l:4 xl:4 2xl:4' }, labelWidth: 90, schemas });
|
||||
const loadDataTable = (res) => ContentList({ ...searchFormRef.value?.formModel, ...res });
|
||||
const reloadTable = () => actionRef.value?.reload();
|
||||
function openReview(row: ContentState) { selected.value = row; reviewForm.action = row.status === 'reviewing' ? 'approve' : row.status === 'taken_down' ? 'restore' : 'take_down'; reviewForm.reason = ''; showReview.value = true; }
|
||||
async function submitReview() { if (!selected.value) return false; if ((reviewForm.action === 'reject' || reviewForm.action === 'take_down') && !reviewForm.reason.trim()) { message.warning('请填写原因'); return false; } await ContentReview({ objectType: selected.value.objectType, id: selected.value.id, ...reviewForm }); message.success('处理成功'); reloadTable(); return true; }
|
||||
const actionColumn = reactive({ width: 120, title: '操作', key: 'action', fixed: 'right', render(row: ContentState) { return h(TableAction as any, { style: 'button', actions: [{ label: '审核处理', onClick: () => openReview(row), auth: ['/cultivate/content/review'], disabled: !hasPermission(['/cultivate/content/review']) }] }); } });
|
||||
onMounted(loadOptions);
|
||||
</script>
|
||||
@@ -0,0 +1,43 @@
|
||||
import { computed, h, ref } from 'vue';
|
||||
import { NTag } from 'naive-ui';
|
||||
import { FormSchema } from '@/components/Form';
|
||||
import { useDictStore } from '@/store/modules/dict';
|
||||
|
||||
const dict = useDictStore();
|
||||
|
||||
export interface ContentState {
|
||||
id: string;
|
||||
objectType: string;
|
||||
postId: string;
|
||||
authorId: string;
|
||||
contentText: string;
|
||||
flowerCode: string;
|
||||
visibility: string;
|
||||
status: string;
|
||||
auditStatus: string;
|
||||
rejectReason: string;
|
||||
likeCount: number;
|
||||
commentCount: number;
|
||||
createdAt: string;
|
||||
}
|
||||
|
||||
export const schemas = ref<FormSchema[]>([
|
||||
{ field: 'objectType', component: 'NSelect', label: '内容类型', defaultValue: 'feed_post', componentProps: { options: computed(() => dict.getOptions('CultivateContentTypeOptions')) } },
|
||||
{ field: 'status', component: 'NSelect', label: '状态', componentProps: { options: computed(() => dict.getOptions('CultivateContentStatusOptions')), clearable: true } },
|
||||
{ field: 'authorId', component: 'NInput', label: '作者ID', componentProps: { placeholder: '请输入作者ID' } },
|
||||
{ field: 'keyword', component: 'NInput', label: '内容关键词', componentProps: { placeholder: '请输入正文关键词' } },
|
||||
]);
|
||||
|
||||
export const columns = [
|
||||
{ title: '内容ID', key: 'id', width: 190 },
|
||||
{ title: '类型', key: 'objectType', width: 90, render: (row: ContentState) => dict.getLabel('CultivateContentTypeOptions', row.objectType) },
|
||||
{ title: '作者ID', key: 'authorId', width: 150 },
|
||||
{ title: '正文', key: 'contentText', width: 300, ellipsis: { tooltip: true } },
|
||||
{ title: '可见范围', key: 'visibility', width: 100 },
|
||||
{ title: '状态', key: 'status', width: 110, render(row: ContentState) { return h(NTag, { type: row.status === 'published' ? 'success' : row.status === 'reviewing' ? 'warning' : row.status === 'rejected' ? 'error' : 'default' }, { default: () => dict.getLabel('CultivateContentStatusOptions', row.status) }); } },
|
||||
{ title: '点赞', key: 'likeCount', width: 80 },
|
||||
{ title: '评论', key: 'commentCount', width: 80 },
|
||||
{ title: '创建时间', key: 'createdAt', width: 180 },
|
||||
];
|
||||
|
||||
export function loadOptions() { dict.loadOptions(['CultivateContentTypeOptions', 'CultivateContentStatusOptions']); }
|
||||
@@ -0,0 +1,49 @@
|
||||
<template>
|
||||
<n-modal v-model:show="showModal" :mask-closable="false" preset="dialog" :title="formValue.id ? '编辑花种配置' : '新建花种配置'" class="flower-modal">
|
||||
<n-scrollbar class="flower-scroll"><n-spin :show="loading"><n-form ref="formRef" :model="formValue" :rules="rules" label-placement="left" :label-width="110">
|
||||
<n-grid cols="1 s:1 m:2" responsive="screen" :x-gap="16">
|
||||
<n-gi><n-form-item label="花种编码" path="flowerCode"><n-input v-model:value="formValue.flowerCode" :disabled="formValue.id > 0" placeholder="如 rose" /></n-form-item></n-gi>
|
||||
<n-gi><n-form-item label="花种名称" path="flowerName"><n-input v-model:value="formValue.flowerName" /></n-form-item></n-gi>
|
||||
<n-gi span="2"><n-form-item label="花语/简介"><n-input v-model:value="formValue.flowerDesc" type="textarea" /></n-form-item></n-gi>
|
||||
<n-gi><n-form-item label="图标文件ID"><n-input v-model:value="formValue.iconFileId" /></n-form-item></n-gi>
|
||||
<n-gi><n-form-item label="状态" path="status"><n-select v-model:value="formValue.status" :options="statusOptions" /></n-form-item></n-gi>
|
||||
<n-gi><n-form-item label="每日浇水上限"><n-input-number v-model:value="formValue.dailyWaterLimit" :min="0" /></n-form-item></n-gi>
|
||||
<n-gi><n-form-item label="每日施肥上限"><n-input-number v-model:value="formValue.dailyFertilizeLimit" :min="0" /></n-form-item></n-gi>
|
||||
<n-gi><n-form-item label="排序"><n-input-number v-model:value="formValue.sortNo" /></n-form-item></n-gi>
|
||||
<n-gi><n-form-item label="默认分享标签"><n-input v-model:value="formValue.shareConfig.default_tag" /></n-form-item></n-gi>
|
||||
</n-grid>
|
||||
<n-divider title-placement="left">成长阶段</n-divider>
|
||||
<n-card v-for="rule in formValue.stageRules" :key="rule.stage" size="small" class="stage-card" :title="rule.stage">
|
||||
<n-grid cols="1 s:1 m:3" responsive="screen" :x-gap="12">
|
||||
<n-gi><n-form-item label="下一阶段"><n-input v-model:value="rule.nextStage" disabled /></n-form-item></n-gi>
|
||||
<n-gi><n-form-item label="升级成长值"><n-input-number v-model:value="rule.requiredPoints" :min="0" /></n-form-item></n-gi>
|
||||
<n-gi><n-form-item label="允许动作"><n-select v-model:value="rule.allowedActions" multiple :options="actionOptions" /></n-form-item></n-gi>
|
||||
<n-gi><n-form-item label="浇水成长值"><n-input-number v-model:value="rule.waterPoints" :min="0" /></n-form-item></n-gi>
|
||||
<n-gi><n-form-item label="施肥成长值"><n-input-number v-model:value="rule.fertilizePoints" :min="0" /></n-form-item></n-gi>
|
||||
<n-gi><n-form-item label="排序"><n-input-number v-model:value="rule.sortNo" /></n-form-item></n-gi>
|
||||
<n-gi><n-form-item label="静态图文件ID"><n-input v-model:value="rule.imageFileId" /></n-form-item></n-gi>
|
||||
<n-gi><n-form-item label="动效文件ID"><n-input v-model:value="rule.animationFileId" /></n-form-item></n-gi>
|
||||
<n-gi><n-form-item label="进度文案"><n-input v-model:value="rule.progressTextTemplate" /></n-form-item></n-gi>
|
||||
</n-grid>
|
||||
</n-card>
|
||||
</n-form></n-spin></n-scrollbar>
|
||||
<template #action><n-space><n-button @click="showModal=false">取消</n-button><n-button type="primary" :loading="submitting" @click="submit">保存并发布配置</n-button></n-space></template>
|
||||
</n-modal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue';
|
||||
import { useMessage } from 'naive-ui';
|
||||
import { Edit, View } from '@/api/cultivate/flowers';
|
||||
import { actionOptions, newState, rules, State, statusOptions } from './model';
|
||||
const emit=defineEmits(['reloadTable']);const message=useMessage();const showModal=ref(false);const loading=ref(false);const submitting=ref(false);const formRef=ref();const formValue=ref<State>(newState(null));
|
||||
function openModal(state:State|null){showModal.value=true;formValue.value=newState(null);if(!state?.id)return;loading.value=true;View({id:state.id}).then((res)=>formValue.value=newState(res)).finally(()=>loading.value=false)}
|
||||
function submit(){formRef.value?.validate((errors)=>{if(errors){message.error('请检查配置内容');return}submitting.value=true;Edit(formValue.value).then(()=>{message.success('配置已保存');showModal.value=false;emit('reloadTable')}).finally(()=>submitting.value=false)})}
|
||||
defineExpose({openModal});
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.flower-modal { width: min(1080px, 92vw); }
|
||||
.flower-scroll { max-height: 78vh; padding-right: 16px; }
|
||||
.stage-card { margin-bottom: 12px; }
|
||||
</style>
|
||||
@@ -0,0 +1,36 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="n-layout-page-header"><n-card :bordered="false" title="花种与成长配置">维护花种、阶段链、成长值、每日限额和展示素材。</n-card></div>
|
||||
<n-card :bordered="false" class="proCard">
|
||||
<BasicForm ref="searchFormRef" @register="register" @submit="reloadTable" @reset="reloadTable" @keyup.enter="reloadTable" />
|
||||
<BasicTable ref="actionRef" :columns="columns" :request="loadDataTable" :row-key="(row) => row.id" :actionColumn="actionColumn" :scroll-x="1450">
|
||||
<template #tableTitle><n-button v-if="hasPermission(['/cultivate/flowers/edit'])" type="primary" @click="addTable"><template #icon><n-icon><PlusOutlined /></n-icon></template>新建花种</n-button></template>
|
||||
</BasicTable>
|
||||
</n-card>
|
||||
<Edit ref="editRef" @reloadTable="reloadTable" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { h, onMounted, reactive, ref } from 'vue';
|
||||
import { useDialog, useMessage } from 'naive-ui';
|
||||
import { PlusOutlined } from '@vicons/antd';
|
||||
import { BasicTable, TableAction } from '@/components/Table';
|
||||
import { BasicForm, useForm } from '@/components/Form';
|
||||
import { usePermission } from '@/hooks/web/usePermission';
|
||||
import { List, Status } from '@/api/cultivate/flowers';
|
||||
import { columns, loadOptions, schemas, State } from './model';
|
||||
import Edit from './edit.vue';
|
||||
|
||||
const actionRef = ref(); const searchFormRef = ref<any>({}); const editRef = ref();
|
||||
const dialog = useDialog(); const message = useMessage(); const { hasPermission } = usePermission();
|
||||
const [register] = useForm({ gridProps: { cols: '1 s:1 m:2 l:4 xl:4 2xl:4' }, labelWidth: 90, schemas });
|
||||
const loadDataTable = async (res) => List({ ...searchFormRef.value?.formModel, ...res });
|
||||
const reloadTable = () => actionRef.value?.reload(); const addTable = () => editRef.value.openModal(null);
|
||||
const actionColumn = reactive({ width: 220, title: '操作', key: 'action', fixed: 'right', render(record: State) { return h(TableAction as any, { style: 'button', actions: [
|
||||
{ label: '编辑配置', onClick: () => editRef.value.openModal(record), auth: ['/cultivate/flowers/edit'] },
|
||||
{ label: record.status === 'online' ? '下架' : '上架', onClick: () => changeStatus(record), auth: ['/cultivate/flowers/status'] },
|
||||
] }); } });
|
||||
function changeStatus(record: State) { const status = record.status === 'online' ? 'offline' : 'online'; dialog.warning({ title: '确认操作', content: `确定${status === 'online' ? '上架' : '下架'}“${record.flowerName}”吗?`, positiveText: '确定', negativeText: '取消', onPositiveClick: () => Status({ id: record.id, status }).then(() => { message.success('操作成功'); reloadTable(); }) }); }
|
||||
onMounted(loadOptions);
|
||||
</script>
|
||||
@@ -0,0 +1,83 @@
|
||||
import { computed, h, ref } from 'vue';
|
||||
import { NTag } from 'naive-ui';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
import { FormSchema } from '@/components/Form';
|
||||
import { useDictStore } from '@/store/modules/dict';
|
||||
|
||||
const dict = useDictStore();
|
||||
|
||||
export interface StageRule {
|
||||
id?: number;
|
||||
stage: string;
|
||||
nextStage: string;
|
||||
requiredPoints: number;
|
||||
waterPoints: number;
|
||||
fertilizePoints: number;
|
||||
allowedActions: string[];
|
||||
imageFileId: string;
|
||||
animationFileId: string;
|
||||
progressTextTemplate: string;
|
||||
completionText: string;
|
||||
sortNo: number;
|
||||
}
|
||||
|
||||
export class State {
|
||||
id = 0;
|
||||
flowerCode = '';
|
||||
flowerName = '';
|
||||
flowerDesc = '';
|
||||
iconFileId = '';
|
||||
status = 'offline';
|
||||
configVersion = '';
|
||||
dailyWaterLimit = 3;
|
||||
dailyFertilizeLimit = 1;
|
||||
shareConfig: Record<string, any> = { can_share_snapshot: true, default_tag: '' };
|
||||
sortNo = 0;
|
||||
stageRules: StageRule[] = defaultStageRules();
|
||||
createdAt = '';
|
||||
updatedAt = '';
|
||||
constructor(state?: Partial<State>) { if (state) Object.assign(this, state); }
|
||||
}
|
||||
|
||||
export function defaultStageRules(): StageRule[] {
|
||||
return [
|
||||
stageRule('seed', 'sprout', 12, 1, 0, ['water'], 10),
|
||||
stageRule('sprout', 'bud', 60, 1, 0, ['water'], 20),
|
||||
stageRule('bud', 'bloom', 90, 1, 5, ['water', 'fertilize'], 30),
|
||||
stageRule('bloom', '', 0, 0, 0, [], 40),
|
||||
];
|
||||
}
|
||||
function stageRule(stage: string, nextStage: string, requiredPoints: number, waterPoints: number, fertilizePoints: number, allowedActions: string[], sortNo: number): StageRule {
|
||||
return { stage, nextStage, requiredPoints, waterPoints, fertilizePoints, allowedActions, imageFileId: '', animationFileId: '', progressTextTemplate: '', completionText: '', sortNo };
|
||||
}
|
||||
export function newState(state: State | Record<string, any> | null): State { return state ? new State(cloneDeep(state)) : new State(); }
|
||||
|
||||
export const rules = {
|
||||
flowerCode: { required: true, trigger: ['blur', 'input'], message: '请输入花种编码' },
|
||||
flowerName: { required: true, trigger: ['blur', 'input'], message: '请输入花种名称' },
|
||||
status: { required: true, trigger: ['change'], message: '请选择状态' },
|
||||
};
|
||||
|
||||
export const schemas = ref<FormSchema[]>([
|
||||
{ field: 'flowerCode', component: 'NInput', label: '花种编码', componentProps: { placeholder: '请输入花种编码' } },
|
||||
{ field: 'flowerName', component: 'NInput', label: '花种名称', componentProps: { placeholder: '请输入花种名称' } },
|
||||
{ field: 'status', component: 'NSelect', label: '状态', componentProps: { options: computed(() => dict.getOptions('CultivateFlowerStatusOptions')), clearable: true } },
|
||||
{ field: 'configVersion', component: 'NInput', label: '配置版本', componentProps: { placeholder: '请输入配置版本' } },
|
||||
]);
|
||||
|
||||
export const columns = [
|
||||
{ title: '花种编码', key: 'flowerCode', width: 140 },
|
||||
{ title: '花种名称', key: 'flowerName', width: 140 },
|
||||
{ title: '花语/简介', key: 'flowerDesc', width: 240, ellipsis: { tooltip: true } },
|
||||
{ title: '成长阶段', key: 'stageCount', width: 100 },
|
||||
{ title: '浇水上限', key: 'dailyWaterLimit', width: 100 },
|
||||
{ title: '施肥上限', key: 'dailyFertilizeLimit', width: 100 },
|
||||
{ title: '配置版本', key: 'configVersion', width: 180 },
|
||||
{ title: '状态', key: 'status', width: 100, render(row: State) { return h(NTag, { type: row.status === 'online' ? 'success' : 'default' }, { default: () => dict.getLabel('CultivateFlowerStatusOptions', row.status) }); } },
|
||||
{ title: '排序', key: 'sortNo', width: 80 },
|
||||
{ title: '更新时间', key: 'updatedAt', width: 180 },
|
||||
];
|
||||
|
||||
export function loadOptions() { dict.loadOptions(['CultivateFlowerStatusOptions']); }
|
||||
export const statusOptions = computed(() => dict.getOptions('CultivateFlowerStatusOptions'));
|
||||
export const actionOptions = [{ label: '浇水', value: 'water' }, { label: '施肥', value: 'fertilize' }];
|
||||
@@ -0,0 +1,13 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="n-layout-page-header"><n-card :bordered="false" title="操作日志">留存花种配置、内容审核和举报处理的管理操作。</n-card></div>
|
||||
<n-card :bordered="false" class="proCard">
|
||||
<BasicForm ref="searchFormRef" @register="register" @submit="reloadTable" @reset="reloadTable" />
|
||||
<BasicTable ref="actionRef" :columns="columns" :request="loadDataTable" :row-key="(row) => row.id" :scroll-x="1500" />
|
||||
</n-card>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue'; import { BasicTable } from '@/components/Table'; import { BasicForm, useForm } from '@/components/Form'; import { OperationLogList } from '@/api/cultivate/content'; import { columns, schemas } from './model';
|
||||
const actionRef = ref(); const searchFormRef = ref<any>({}); const [register] = useForm({ gridProps: { cols: '1 s:1 m:2 l:4' }, labelWidth: 90, schemas }); const loadDataTable = (res) => OperationLogList({ ...searchFormRef.value?.formModel, ...res }); const reloadTable = () => actionRef.value?.reload();
|
||||
</script>
|
||||
@@ -0,0 +1,12 @@
|
||||
import { ref } from 'vue';
|
||||
import { FormSchema } from '@/components/Form';
|
||||
export const schemas = ref<FormSchema[]>([
|
||||
{ field: 'operatorId', component: 'NInput', label: '操作人ID', componentProps: { placeholder: '请输入操作人ID' } },
|
||||
{ field: 'operationType', component: 'NInput', label: '操作类型', componentProps: { placeholder: '如 content、report、flower' } },
|
||||
{ field: 'targetType', component: 'NInput', label: '对象类型', componentProps: { placeholder: '请输入对象类型' } },
|
||||
]);
|
||||
export const columns = [
|
||||
{ title: '日志ID', key: 'id', width: 190 }, { title: '操作人', key: 'operatorId', width: 150 }, { title: '操作类型', key: 'operationType', width: 160 },
|
||||
{ title: '对象类型', key: 'targetType', width: 130 }, { title: '对象ID', key: 'targetId', width: 190 }, { title: '原因/结果', key: 'reason', width: 260, ellipsis: { tooltip: true } },
|
||||
{ title: '请求ID', key: 'requestId', width: 220 }, { title: '操作时间', key: 'createdAt', width: 180 },
|
||||
];
|
||||
@@ -0,0 +1,25 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="n-layout-page-header"><n-card :bordered="false" title="举报处理">查看物友动态、评论及用户举报并记录处理结果。</n-card></div>
|
||||
<n-card :bordered="false" class="proCard">
|
||||
<BasicForm ref="searchFormRef" @register="register" @submit="reloadTable" @reset="reloadTable" />
|
||||
<BasicTable ref="actionRef" :columns="columns" :request="loadDataTable" :row-key="(row) => row.id" :actionColumn="actionColumn" :scroll-x="1650" />
|
||||
</n-card>
|
||||
<n-modal v-model:show="showHandle" preset="dialog" title="处理举报" positive-text="确认" negative-text="取消" @positive-click="submitHandle">
|
||||
<n-space vertical><n-select v-model:value="handleForm.action" :options="handleOptions" /><n-input v-model:value="handleForm.handleResult" type="textarea" placeholder="办结或驳回时必须填写处理结果" /></n-space>
|
||||
</n-modal>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { h, onMounted, reactive, ref } from 'vue';
|
||||
import { useMessage } from 'naive-ui';
|
||||
import { BasicTable, TableAction } from '@/components/Table'; import { BasicForm, useForm } from '@/components/Form';
|
||||
import { ReportHandle, ReportList } from '@/api/cultivate/content'; import { columns, loadOptions, ReportState, schemas } from './model';
|
||||
const actionRef = ref(); const searchFormRef = ref<any>({}); const showHandle = ref(false); const selected = ref<ReportState>(); const message = useMessage();
|
||||
const handleForm = reactive({ action: 'processing', handleResult: '' }); const handleOptions = [{ label: '标记处理中', value: 'processing' }, { label: '确认处理', value: 'resolve' }, { label: '驳回举报', value: 'reject' }];
|
||||
const [register] = useForm({ gridProps: { cols: '1 s:1 m:2 l:4' }, labelWidth: 90, schemas }); const loadDataTable = (res) => ReportList({ ...searchFormRef.value?.formModel, ...res }); const reloadTable = () => actionRef.value?.reload();
|
||||
function openHandle(row: ReportState) { selected.value = row; handleForm.action = row.status === 'submitted' ? 'processing' : 'resolve'; handleForm.handleResult = ''; showHandle.value = true; }
|
||||
async function submitHandle() { if (!selected.value) return false; if (handleForm.action !== 'processing' && !handleForm.handleResult.trim()) { message.warning('请填写处理结果'); return false; } await ReportHandle({ id: selected.value.id, ...handleForm }); message.success('处理成功'); reloadTable(); return true; }
|
||||
const actionColumn = reactive({ width: 110, title: '操作', key: 'action', fixed: 'right', render(row: ReportState) { return h(TableAction as any, { style: 'button', actions: [{ label: '处理', onClick: () => openHandle(row), auth: ['/cultivate/reports/handle'], disabled: row.status === 'resolved' || row.status === 'rejected' }] }); } });
|
||||
onMounted(loadOptions);
|
||||
</script>
|
||||
@@ -0,0 +1,20 @@
|
||||
import { computed, h, ref } from 'vue';
|
||||
import { NTag } from 'naive-ui';
|
||||
import { FormSchema } from '@/components/Form';
|
||||
import { useDictStore } from '@/store/modules/dict';
|
||||
|
||||
const dict = useDictStore();
|
||||
export interface ReportState { id: string; reporterId: string; reportedUserId: string; objectType: string; objectId: string; reasonCode: string; description: string; status: string; handlerId: string; handleResult: string; handledAt: string; createdAt: string; }
|
||||
export const schemas = ref<FormSchema[]>([
|
||||
{ field: 'objectType', component: 'NSelect', label: '对象类型', componentProps: { options: computed(() => dict.getOptions('CultivateReportObjectTypeOptions')), clearable: true } },
|
||||
{ field: 'status', component: 'NSelect', label: '处理状态', componentProps: { options: computed(() => dict.getOptions('CultivateReportStatusOptions')), clearable: true } },
|
||||
{ field: 'reporterId', component: 'NInput', label: '举报人ID', componentProps: { placeholder: '请输入举报人ID' } },
|
||||
]);
|
||||
export const columns = [
|
||||
{ title: '举报ID', key: 'id', width: 190 }, { title: '举报人', key: 'reporterId', width: 150 }, { title: '被举报人', key: 'reportedUserId', width: 150 },
|
||||
{ title: '对象', key: 'objectType', width: 90, render: (row: ReportState) => dict.getLabel('CultivateReportObjectTypeOptions', row.objectType) || row.objectType },
|
||||
{ title: '对象ID', key: 'objectId', width: 190 }, { title: '原因', key: 'reasonCode', width: 120 }, { title: '补充说明', key: 'description', width: 220, ellipsis: { tooltip: true } },
|
||||
{ title: '状态', key: 'status', width: 100, render(row: ReportState) { return h(NTag, { type: row.status === 'resolved' ? 'success' : row.status === 'submitted' ? 'warning' : 'default' }, { default: () => dict.getLabel('CultivateReportStatusOptions', row.status) }); } },
|
||||
{ title: '处理结果', key: 'handleResult', width: 220, ellipsis: { tooltip: true } }, { title: '提交时间', key: 'createdAt', width: 180 },
|
||||
];
|
||||
export function loadOptions() { dict.loadOptions(['CultivateReportObjectTypeOptions', 'CultivateReportStatusOptions']); }
|
||||
Reference in New Issue
Block a user