Files
yunzerwebsiteallinone/go/controllers/backend_product.go
T
2026-09-15 10:44:31 +08:00

495 lines
12 KiB
Go

package controllers
import (
"encoding/json"
"io"
"strings"
"time"
"server/models"
"server/pkg/jwtutil"
"github.com/beego/beego/v2/client/orm"
beego "github.com/beego/beego/v2/server/web"
)
// BackendProductController CMS 产品管理
type BackendProductController struct {
beego.Controller
}
// BackendProductCategoryController CMS 产品分类管理
type BackendProductCategoryController struct {
beego.Controller
}
func (c *BackendProductController) cmsClaims() (*jwtutil.Claims, error) {
return cmsBackendClaims(&c.Controller)
}
func (c *BackendProductCategoryController) cmsClaims() (*jwtutil.Claims, error) {
return cmsBackendClaims(&c.Controller)
}
func (c *BackendProductController) cmsJSONErr(httpStatus, bizCode int, msg string) {
c.Ctx.Output.SetStatus(httpStatus)
c.Data["json"] = map[string]interface{}{"code": bizCode, "msg": msg}
_ = c.ServeJSON()
}
func (c *BackendProductCategoryController) cmsJSONErr(httpStatus, bizCode int, msg string) {
c.Ctx.Output.SetStatus(httpStatus)
c.Data["json"] = map[string]interface{}{"code": bizCode, "msg": msg}
_ = c.ServeJSON()
}
func cmsProductToMap(row models.CmsProduct) map[string]interface{} {
return map[string]interface{}{
"id": row.ID,
"tid": row.Tid,
"title": row.Title,
"thumb": row.Thumb,
"desc": row.Desc,
"content": row.Content,
"url": row.URL,
"sort": row.Sort,
"status": row.Status,
"create_time": row.CreateTime.Format("2006-01-02 15:04:05"),
"update_time": models.CmsFormatTime(row.UpdateTime),
}
}
func cmsProductCateToMap(row models.CmsProductCategory) map[string]interface{} {
return map[string]interface{}{
"id": row.ID,
"tid": row.Tid,
"title": row.Title,
"pid": row.Pid,
"desc": row.Desc,
"sort": row.Sort,
"status": row.Status,
"create_time": row.CreateTime.Format("2006-01-02 15:04:05"),
"update_time": models.CmsFormatTime(row.UpdateTime),
}
}
// List GET /backend/productsList
func (c *BackendProductController) List() {
claims, err := c.cmsClaims()
if err != nil {
c.cmsJSONErr(401, 401, err.Error())
return
}
tid := cmsEffectiveTid(&c.Controller, claims)
if tid == 0 {
c.cmsJSONErr(400, 400, "tid不能为空")
return
}
page, _ := c.GetInt("page", 1)
limit, _ := c.GetInt("limit", 10)
if page < 1 {
page = 1
}
if limit < 1 || limit > 100 {
limit = 10
}
keyword := strings.TrimSpace(c.GetString("keyword"))
qs := models.Orm.QueryTable(new(models.CmsProduct)).
Filter("tid", tid).
Filter("delete_time__isnull", true)
if keyword != "" {
qs = qs.Filter("title__icontains", keyword)
}
if status, err := c.GetInt("status", -1); err == nil && status >= 0 {
qs = qs.Filter("status", status)
}
total, _ := qs.Count()
var rows []models.CmsProduct
offset := (page - 1) * limit
_, err = qs.OrderBy("sort", "-id").Limit(limit, offset).All(&rows)
if err != nil && err != orm.ErrNoRows {
c.cmsJSONErr(500, 500, "获取产品列表失败")
return
}
list := make([]map[string]interface{}, 0, len(rows))
for _, r := range rows {
list = append(list, cmsProductToMap(r))
}
c.Data["json"] = map[string]interface{}{
"code": 200,
"msg": "success",
"data": map[string]interface{}{"list": list, "total": total},
}
_ = c.ServeJSON()
}
type cmsProductPayload struct {
Title string `json:"title"`
Thumb string `json:"thumb"`
Desc string `json:"desc"`
Content string `json:"content"`
URL string `json:"url"`
Sort int `json:"sort"`
Status int8 `json:"status"`
}
// Create POST /backend/addProducts
func (c *BackendProductController) Create() {
claims, err := c.cmsClaims()
if err != nil {
c.cmsJSONErr(401, 401, err.Error())
return
}
tid := cmsEffectiveTid(&c.Controller, claims)
if tid == 0 {
c.cmsJSONErr(400, 400, "tid不能为空")
return
}
raw, err := io.ReadAll(c.Ctx.Request.Body)
if err != nil {
c.cmsJSONErr(400, 400, "参数错误")
return
}
var p cmsProductPayload
if err := json.Unmarshal(raw, &p); err != nil {
c.cmsJSONErr(400, 400, "参数错误")
return
}
title := strings.TrimSpace(p.Title)
if title == "" {
c.cmsJSONErr(400, 400, "产品名称不能为空")
return
}
now := time.Now()
row := models.CmsProduct{
Tid: tid,
Title: title,
Thumb: strings.TrimSpace(p.Thumb),
Desc: strings.TrimSpace(p.Desc),
Content: p.Content,
URL: strings.TrimSpace(p.URL),
Sort: p.Sort,
Status: p.Status,
CreateTime: now,
UpdateTime: &now,
}
id, err := models.Orm.Insert(&row)
if err != nil {
c.cmsJSONErr(500, 500, "添加失败")
return
}
c.Data["json"] = map[string]interface{}{"code": 200, "msg": "添加成功", "data": map[string]interface{}{"id": id}}
_ = c.ServeJSON()
}
// Update PUT /backend/editProducts/:id
func (c *BackendProductController) Update() {
claims, err := c.cmsClaims()
if err != nil {
c.cmsJSONErr(401, 401, err.Error())
return
}
tid := cmsEffectiveTid(&c.Controller, claims)
id, _ := c.GetUint64(":id")
if id == 0 {
c.cmsJSONErr(400, 400, "无效ID")
return
}
raw, err := io.ReadAll(c.Ctx.Request.Body)
if err != nil {
c.cmsJSONErr(400, 400, "参数错误")
return
}
var p cmsProductPayload
if err := json.Unmarshal(raw, &p); err != nil {
c.cmsJSONErr(400, 400, "参数错误")
return
}
title := strings.TrimSpace(p.Title)
if title == "" {
c.cmsJSONErr(400, 400, "产品名称不能为空")
return
}
now := time.Now()
n, err := models.Orm.QueryTable(new(models.CmsProduct)).
Filter("id", id).
Filter("tid", tid).
Filter("delete_time__isnull", true).
Update(orm.Params{
"title": title,
"thumb": strings.TrimSpace(p.Thumb),
"desc": strings.TrimSpace(p.Desc),
"content": p.Content,
"url": strings.TrimSpace(p.URL),
"sort": p.Sort,
"status": p.Status,
"update_time": now,
})
if err != nil {
c.cmsJSONErr(500, 500, "更新失败")
return
}
if n == 0 {
c.cmsJSONErr(404, 404, "产品不存在")
return
}
c.Data["json"] = map[string]interface{}{"code": 200, "msg": "更新成功"}
_ = c.ServeJSON()
}
// Delete DELETE /backend/deleteProducts/:id
func (c *BackendProductController) Delete() {
claims, err := c.cmsClaims()
if err != nil {
c.cmsJSONErr(401, 401, err.Error())
return
}
tid := cmsEffectiveTid(&c.Controller, claims)
id, _ := c.GetUint64(":id")
if id == 0 {
c.cmsJSONErr(400, 400, "无效ID")
return
}
now := time.Now()
n, err := models.Orm.QueryTable(new(models.CmsProduct)).
Filter("id", id).
Filter("tid", tid).
Filter("delete_time__isnull", true).
Update(orm.Params{"delete_time": now})
if err != nil {
c.cmsJSONErr(500, 500, "删除失败")
return
}
if n == 0 {
c.cmsJSONErr(404, 404, "产品不存在")
return
}
c.Data["json"] = map[string]interface{}{"code": 200, "msg": "删除成功"}
_ = c.ServeJSON()
}
// List GET /backend/productsTypesList
func (c *BackendProductCategoryController) List() {
claims, err := c.cmsClaims()
if err != nil {
c.cmsJSONErr(401, 401, err.Error())
return
}
tid := cmsEffectiveTid(&c.Controller, claims)
if tid == 0 {
c.cmsJSONErr(400, 400, "tid不能为空")
return
}
page, _ := c.GetInt("page", 1)
limit, _ := c.GetInt("limit", 10)
if page < 1 {
page = 1
}
if limit < 1 || limit > 1000 {
limit = 10
}
keyword := strings.TrimSpace(c.GetString("keyword"))
qs := models.Orm.QueryTable(new(models.CmsProductCategory)).
Filter("tid", tid).
Filter("delete_time__isnull", true)
if keyword != "" {
qs = qs.Filter("title__icontains", keyword)
}
total, _ := qs.Count()
var rows []models.CmsProductCategory
offset := (page - 1) * limit
_, err = qs.OrderBy("sort", "id").Limit(limit, offset).All(&rows)
if err != nil && err != orm.ErrNoRows {
c.cmsJSONErr(500, 500, "获取产品分类列表失败")
return
}
list := make([]map[string]interface{}, 0, len(rows))
for _, r := range rows {
list = append(list, cmsProductCateToMap(r))
}
c.Data["json"] = map[string]interface{}{
"code": 200,
"msg": "success",
"data": map[string]interface{}{"list": list, "total": total},
}
_ = c.ServeJSON()
}
type cmsProductCategoryPayload struct {
Title string `json:"title"`
Pid uint64 `json:"pid"`
Desc string `json:"desc"`
Sort int `json:"sort"`
}
// Create POST /backend/addProductsTypes
func (c *BackendProductCategoryController) Create() {
claims, err := c.cmsClaims()
if err != nil {
c.cmsJSONErr(401, 401, err.Error())
return
}
tid := cmsEffectiveTid(&c.Controller, claims)
if tid == 0 {
c.cmsJSONErr(400, 400, "tid不能为空")
return
}
raw, err := io.ReadAll(c.Ctx.Request.Body)
if err != nil {
c.cmsJSONErr(400, 400, "参数错误")
return
}
var p cmsProductCategoryPayload
if err := json.Unmarshal(raw, &p); err != nil {
c.cmsJSONErr(400, 400, "参数错误")
return
}
title := strings.TrimSpace(p.Title)
if title == "" {
c.cmsJSONErr(400, 400, "分类名称不能为空")
return
}
now := time.Now()
row := models.CmsProductCategory{
Tid: tid,
Title: title,
Pid: p.Pid,
Desc: strings.TrimSpace(p.Desc),
Sort: p.Sort,
Status: 1,
CreateTime: now,
UpdateTime: &now,
}
id, err := models.Orm.Insert(&row)
if err != nil {
c.cmsJSONErr(500, 500, "添加失败")
return
}
c.Data["json"] = map[string]interface{}{"code": 200, "msg": "添加成功", "data": map[string]interface{}{"id": id}}
_ = c.ServeJSON()
}
// Update PUT /backend/editProductsTypes/:id
func (c *BackendProductCategoryController) Update() {
claims, err := c.cmsClaims()
if err != nil {
c.cmsJSONErr(401, 401, err.Error())
return
}
tid := cmsEffectiveTid(&c.Controller, claims)
id, _ := c.GetUint64(":id")
if id == 0 {
c.cmsJSONErr(400, 400, "无效ID")
return
}
raw, err := io.ReadAll(c.Ctx.Request.Body)
if err != nil {
c.cmsJSONErr(400, 400, "参数错误")
return
}
var p cmsProductCategoryPayload
if err := json.Unmarshal(raw, &p); err != nil {
c.cmsJSONErr(400, 400, "参数错误")
return
}
title := strings.TrimSpace(p.Title)
if title == "" {
c.cmsJSONErr(400, 400, "分类名称不能为空")
return
}
if p.Pid == id {
c.cmsJSONErr(400, 400, "父级分类不能是自己")
return
}
now := time.Now()
n, err := models.Orm.QueryTable(new(models.CmsProductCategory)).
Filter("id", id).
Filter("tid", tid).
Filter("delete_time__isnull", true).
Update(orm.Params{
"title": title,
"pid": p.Pid,
"desc": strings.TrimSpace(p.Desc),
"sort": p.Sort,
"update_time": now,
})
if err != nil {
c.cmsJSONErr(500, 500, "更新失败")
return
}
if n == 0 {
c.cmsJSONErr(404, 404, "分类不存在")
return
}
c.Data["json"] = map[string]interface{}{"code": 200, "msg": "更新成功"}
_ = c.ServeJSON()
}
// Delete DELETE /backend/deleteProductsTypes/:id
func (c *BackendProductCategoryController) Delete() {
claims, err := c.cmsClaims()
if err != nil {
c.cmsJSONErr(401, 401, err.Error())
return
}
tid := cmsEffectiveTid(&c.Controller, claims)
id, _ := c.GetUint64(":id")
if id == 0 {
c.cmsJSONErr(400, 400, "无效ID")
return
}
// 存在子分类时不允许删除
childCnt, _ := models.Orm.QueryTable(new(models.CmsProductCategory)).
Filter("tid", tid).
Filter("pid", id).
Filter("delete_time__isnull", true).
Count()
if childCnt > 0 {
c.cmsJSONErr(400, 400, "该分类下存在子分类,请先删除子分类")
return
}
now := time.Now()
n, err := models.Orm.QueryTable(new(models.CmsProductCategory)).
Filter("id", id).
Filter("tid", tid).
Filter("delete_time__isnull", true).
Update(orm.Params{"delete_time": now})
if err != nil {
c.cmsJSONErr(500, 500, "删除失败")
return
}
if n == 0 {
c.cmsJSONErr(404, 404, "分类不存在")
return
}
c.Data["json"] = map[string]interface{}{"code": 200, "msg": "删除成功"}
_ = c.ServeJSON()
}