529 lines
12 KiB
Go
529 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 cmsEnsureProductTables(c *beego.Controller) bool {
|
|
if err := models.EnsureCmsProductTables(); err != nil {
|
|
c.Ctx.Output.SetStatus(500)
|
|
c.Data["json"] = map[string]interface{}{"code": 500, "msg": "初始化产品表失败: " + err.Error()}
|
|
_ = c.ServeJSON()
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
|
|
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() {
|
|
if !cmsEnsureProductTables(&c.Controller) {
|
|
return
|
|
}
|
|
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() {
|
|
if !cmsEnsureProductTables(&c.Controller) {
|
|
return
|
|
}
|
|
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() {
|
|
if !cmsEnsureProductTables(&c.Controller) {
|
|
return
|
|
}
|
|
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() {
|
|
if !cmsEnsureProductTables(&c.Controller) {
|
|
return
|
|
}
|
|
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() {
|
|
if !cmsEnsureProductTables(&c.Controller) {
|
|
return
|
|
}
|
|
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() {
|
|
if !cmsEnsureProductTables(&c.Controller) {
|
|
return
|
|
}
|
|
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() {
|
|
if !cmsEnsureProductTables(&c.Controller) {
|
|
return
|
|
}
|
|
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() {
|
|
if !cmsEnsureProductTables(&c.Controller) {
|
|
return
|
|
}
|
|
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()
|
|
}
|