858 lines
21 KiB
Go
858 lines
21 KiB
Go
package controllers
|
||
|
||
import (
|
||
"encoding/json"
|
||
"fmt"
|
||
"io"
|
||
"strconv"
|
||
"strings"
|
||
"time"
|
||
|
||
"server/models"
|
||
"server/pkg/jwtutil"
|
||
|
||
"github.com/beego/beego/v2/client/orm"
|
||
beego "github.com/beego/beego/v2/server/web"
|
||
)
|
||
|
||
// BackendBannerController 官网 Banner 管理(租户端,tid 严格隔离)
|
||
type BackendBannerController struct {
|
||
beego.Controller
|
||
}
|
||
|
||
// BackendFriendlinkController 官网友情链接管理(租户端)
|
||
type BackendFriendlinkController struct {
|
||
beego.Controller
|
||
}
|
||
|
||
// BackendOnepageController 官网单页管理(租户端)
|
||
type BackendOnepageController struct {
|
||
beego.Controller
|
||
}
|
||
|
||
func (c *BackendBannerController) cmsClaims() (*jwtutil.Claims, error) {
|
||
return cmsBackendClaims(&c.Controller)
|
||
}
|
||
|
||
func (c *BackendFriendlinkController) cmsClaims() (*jwtutil.Claims, error) {
|
||
return cmsBackendClaims(&c.Controller)
|
||
}
|
||
|
||
func (c *BackendOnepageController) cmsClaims() (*jwtutil.Claims, error) {
|
||
return cmsBackendClaims(&c.Controller)
|
||
}
|
||
|
||
func (c *BackendBannerController) 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 *BackendFriendlinkController) 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 *BackendOnepageController) cmsJSONErr(httpStatus, bizCode int, msg string) {
|
||
c.Ctx.Output.SetStatus(httpStatus)
|
||
c.Data["json"] = map[string]interface{}{"code": bizCode, "msg": msg}
|
||
_ = c.ServeJSON()
|
||
}
|
||
|
||
func cmsBannerToMap(row models.CmsFrontendBanner) map[string]interface{} {
|
||
return map[string]interface{}{
|
||
"id": row.ID,
|
||
"title": row.Title,
|
||
"desc": row.Desc,
|
||
"image": row.Image,
|
||
"url": row.Url,
|
||
"sort": row.Sort,
|
||
"status": row.Status,
|
||
"create_time": row.CreateTime.Unix(),
|
||
}
|
||
}
|
||
|
||
func cmsFriendlinkToMap(row models.CmsFrontendFriendlink) map[string]interface{} {
|
||
return map[string]interface{}{
|
||
"id": row.ID,
|
||
"link_name": row.LinkName,
|
||
"link_url": row.LinkUrl,
|
||
"link_logo": row.LinkLogo,
|
||
"description": row.Description,
|
||
"sort": row.Sort,
|
||
"status": row.Status,
|
||
"create_time": row.CreateTime.Format("2006-01-02 15:04:05"),
|
||
}
|
||
}
|
||
|
||
func cmsOnepageToMap(row models.CmsFrontendOnepage) map[string]interface{} {
|
||
return map[string]interface{}{
|
||
"id": row.ID,
|
||
"title": row.Title,
|
||
"path": row.Path,
|
||
"content": row.Content,
|
||
"sort": row.Sort,
|
||
"status": row.Status,
|
||
"create_time": row.CreateTime.Unix(),
|
||
}
|
||
}
|
||
|
||
// ---------------- Banner ----------------
|
||
|
||
type cmsBannerPayload struct {
|
||
Title string `json:"title"`
|
||
Desc string `json:"desc"`
|
||
Image string `json:"image"`
|
||
Url string `json:"url"`
|
||
Sort int `json:"sort"`
|
||
Status int8 `json:"status"`
|
||
}
|
||
|
||
// readBannerPayload 兼容 JSON 与 multipart/form-data 两种请求体
|
||
// (前端 createbanner 以 multipart 头发送,实际可能是 JSON 体)
|
||
func (c *BackendBannerController) readBannerPayload() (*cmsBannerPayload, error) {
|
||
ct := c.Ctx.Request.Header.Get("Content-Type")
|
||
if strings.HasPrefix(ct, "multipart/form-data") {
|
||
// cmsEffectiveTid 已触发 ParseForm,表单字段可直接读取
|
||
sort, _ := c.GetInt("sort")
|
||
status, _ := c.GetInt8("status", 1)
|
||
return &cmsBannerPayload{
|
||
Title: strings.TrimSpace(c.GetString("title")),
|
||
Desc: strings.TrimSpace(c.GetString("desc")),
|
||
Image: strings.TrimSpace(c.GetString("image")),
|
||
Url: strings.TrimSpace(c.GetString("url")),
|
||
Sort: sort,
|
||
Status: status,
|
||
}, nil
|
||
}
|
||
raw, err := io.ReadAll(c.Ctx.Request.Body)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
var p cmsBannerPayload
|
||
p.Status = 1
|
||
if len(raw) > 0 {
|
||
if err := json.Unmarshal(raw, &p); err != nil {
|
||
return nil, fmt.Errorf("参数错误")
|
||
}
|
||
}
|
||
return &p, nil
|
||
}
|
||
|
||
// ListAll GET /backend/allbanners
|
||
func (c *BackendBannerController) ListAll() {
|
||
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
|
||
}
|
||
|
||
var rows []models.CmsFrontendBanner
|
||
_, err = models.Orm.QueryTable(new(models.CmsFrontendBanner)).
|
||
Filter("tid", tid).
|
||
Filter("delete_time__isnull", true).
|
||
OrderBy("sort", "id").
|
||
All(&rows)
|
||
if err != nil && err != orm.ErrNoRows {
|
||
c.cmsJSONErr(500, 500, "获取Banner列表失败")
|
||
return
|
||
}
|
||
|
||
list := make([]map[string]interface{}, 0, len(rows))
|
||
for _, r := range rows {
|
||
list = append(list, cmsBannerToMap(r))
|
||
}
|
||
|
||
c.Data["json"] = map[string]interface{}{"code": 200, "msg": "success", "data": list}
|
||
_ = c.ServeJSON()
|
||
}
|
||
|
||
// Create POST /backend/createbanner
|
||
func (c *BackendBannerController) 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
|
||
}
|
||
|
||
p, err := c.readBannerPayload()
|
||
if err != nil {
|
||
c.cmsJSONErr(400, 400, err.Error())
|
||
return
|
||
}
|
||
if strings.TrimSpace(p.Title) == "" && strings.TrimSpace(p.Image) == "" {
|
||
c.cmsJSONErr(400, 400, "标题与图片不能都为空")
|
||
return
|
||
}
|
||
|
||
now := time.Now()
|
||
row := models.CmsFrontendBanner{
|
||
Tid: tid,
|
||
Title: strings.TrimSpace(p.Title),
|
||
Desc: strings.TrimSpace(p.Desc),
|
||
Image: strings.TrimSpace(p.Image),
|
||
Url: strings.TrimSpace(p.Url),
|
||
Sort: p.Sort,
|
||
Status: p.Status,
|
||
CreateTime: now,
|
||
UpdateTime: &now,
|
||
}
|
||
if row.Status == 0 {
|
||
row.Status = 1
|
||
}
|
||
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 POST /backend/editbanner/:id
|
||
func (c *BackendBannerController) 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 cmsBannerPayload
|
||
if err := json.Unmarshal(raw, &p); err != nil {
|
||
c.cmsJSONErr(400, 400, "参数错误")
|
||
return
|
||
}
|
||
|
||
now := time.Now()
|
||
fields := map[string]interface{}{
|
||
"title": strings.TrimSpace(p.Title),
|
||
"desc": strings.TrimSpace(p.Desc),
|
||
"image": strings.TrimSpace(p.Image),
|
||
"url": strings.TrimSpace(p.Url),
|
||
"sort": p.Sort,
|
||
"update_time": now,
|
||
}
|
||
if p.Status > 0 {
|
||
fields["status"] = p.Status
|
||
}
|
||
n, err := models.Orm.QueryTable(new(models.CmsFrontendBanner)).
|
||
Filter("id", id).
|
||
Filter("tid", tid).
|
||
Filter("delete_time__isnull", true).
|
||
Update(fields)
|
||
if err != nil {
|
||
c.cmsJSONErr(500, 500, "更新失败")
|
||
return
|
||
}
|
||
if n == 0 {
|
||
c.cmsJSONErr(404, 404, "Banner不存在")
|
||
return
|
||
}
|
||
|
||
c.Data["json"] = map[string]interface{}{"code": 200, "msg": "更新成功"}
|
||
_ = c.ServeJSON()
|
||
}
|
||
|
||
// Delete DELETE /backend/deletebanner/:id
|
||
func (c *BackendBannerController) 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.CmsFrontendBanner)).
|
||
Filter("id", id).
|
||
Filter("tid", tid).
|
||
Filter("delete_time__isnull", true).
|
||
Update(map[string]interface{}{"delete_time": now, "update_time": now})
|
||
if err != nil {
|
||
c.cmsJSONErr(500, 500, "删除失败")
|
||
return
|
||
}
|
||
if n == 0 {
|
||
c.cmsJSONErr(404, 404, "Banner不存在")
|
||
return
|
||
}
|
||
|
||
c.Data["json"] = map[string]interface{}{"code": 200, "msg": "删除成功"}
|
||
_ = c.ServeJSON()
|
||
}
|
||
|
||
// ---------------- 友情链接 ----------------
|
||
|
||
// List GET /backend/friendlinks(分页:page/limit/keyword/status)
|
||
func (c *BackendFriendlinkController) 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 = 10
|
||
}
|
||
if limit > 200 {
|
||
limit = 200
|
||
}
|
||
|
||
qs := models.Orm.QueryTable(new(models.CmsFrontendFriendlink)).
|
||
Filter("tid", tid).
|
||
Filter("delete_time__isnull", true)
|
||
if kw := strings.TrimSpace(c.GetString("keyword")); kw != "" {
|
||
qs = qs.Filter("link_name__icontains", kw)
|
||
}
|
||
if st := strings.TrimSpace(c.GetString("status")); st != "" {
|
||
if v, e := strconv.Atoi(st); e == nil {
|
||
qs = qs.Filter("status", v)
|
||
}
|
||
}
|
||
|
||
total, _ := qs.Count()
|
||
var rows []models.CmsFrontendFriendlink
|
||
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, cmsFriendlinkToMap(r))
|
||
}
|
||
|
||
c.Data["json"] = map[string]interface{}{
|
||
"code": 200,
|
||
"msg": "success",
|
||
"data": map[string]interface{}{"list": list, "total": total},
|
||
}
|
||
_ = c.ServeJSON()
|
||
}
|
||
|
||
// ListAll GET /backend/friendlinks/all
|
||
func (c *BackendFriendlinkController) ListAll() {
|
||
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
|
||
}
|
||
|
||
var rows []models.CmsFrontendFriendlink
|
||
_, err = models.Orm.QueryTable(new(models.CmsFrontendFriendlink)).
|
||
Filter("tid", tid).
|
||
Filter("status", 1).
|
||
Filter("delete_time__isnull", true).
|
||
OrderBy("sort", "id").
|
||
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, cmsFriendlinkToMap(r))
|
||
}
|
||
|
||
c.Data["json"] = map[string]interface{}{"code": 200, "msg": "success", "data": list}
|
||
_ = c.ServeJSON()
|
||
}
|
||
|
||
type cmsFriendlinkPayload struct {
|
||
LinkName string `json:"link_name"`
|
||
LinkUrl string `json:"link_url"`
|
||
LinkLogo string `json:"link_logo"`
|
||
Description string `json:"description"`
|
||
Sort int `json:"sort"`
|
||
Status int8 `json:"status"`
|
||
}
|
||
|
||
// Create POST /backend/friendlinks
|
||
func (c *BackendFriendlinkController) 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 cmsFriendlinkPayload
|
||
if err := json.Unmarshal(raw, &p); err != nil {
|
||
c.cmsJSONErr(400, 400, "参数错误")
|
||
return
|
||
}
|
||
if strings.TrimSpace(p.LinkName) == "" {
|
||
c.cmsJSONErr(400, 400, "链接名称不能为空")
|
||
return
|
||
}
|
||
if strings.TrimSpace(p.LinkUrl) == "" {
|
||
c.cmsJSONErr(400, 400, "链接地址不能为空")
|
||
return
|
||
}
|
||
|
||
now := time.Now()
|
||
row := models.CmsFrontendFriendlink{
|
||
Tid: tid,
|
||
LinkName: strings.TrimSpace(p.LinkName),
|
||
LinkUrl: strings.TrimSpace(p.LinkUrl),
|
||
LinkLogo: strings.TrimSpace(p.LinkLogo),
|
||
Description: strings.TrimSpace(p.Description),
|
||
Sort: p.Sort,
|
||
Status: p.Status,
|
||
CreateTime: now,
|
||
UpdateTime: &now,
|
||
}
|
||
if row.Status == 0 {
|
||
row.Status = 1
|
||
}
|
||
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/friendlinks/:id(支持只传部分字段,如 {status:1})
|
||
func (c *BackendFriendlinkController) 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 body map[string]interface{}
|
||
if err := json.Unmarshal(raw, &body); err != nil {
|
||
c.cmsJSONErr(400, 400, "参数错误")
|
||
return
|
||
}
|
||
|
||
fields := map[string]interface{}{}
|
||
if v, ok := body["link_name"]; ok {
|
||
fields["link_name"] = strings.TrimSpace(fmt.Sprintf("%v", v))
|
||
}
|
||
if v, ok := body["link_url"]; ok {
|
||
fields["link_url"] = strings.TrimSpace(fmt.Sprintf("%v", v))
|
||
}
|
||
if v, ok := body["link_logo"]; ok {
|
||
fields["link_logo"] = strings.TrimSpace(fmt.Sprintf("%v", v))
|
||
}
|
||
if v, ok := body["description"]; ok {
|
||
fields["description"] = strings.TrimSpace(fmt.Sprintf("%v", v))
|
||
}
|
||
if v, ok := body["sort"]; ok {
|
||
if n, e := strconv.Atoi(fmt.Sprintf("%.0f", toFloat(v))); e == nil {
|
||
fields["sort"] = n
|
||
}
|
||
}
|
||
if v, ok := body["status"]; ok {
|
||
fields["status"] = int8(toFloat(v))
|
||
}
|
||
if len(fields) == 0 {
|
||
c.cmsJSONErr(400, 400, "没有可更新的字段")
|
||
return
|
||
}
|
||
fields["update_time"] = time.Now()
|
||
|
||
n, err := models.Orm.QueryTable(new(models.CmsFrontendFriendlink)).
|
||
Filter("id", id).
|
||
Filter("tid", tid).
|
||
Filter("delete_time__isnull", true).
|
||
Update(fields)
|
||
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()
|
||
}
|
||
|
||
// toFloat 宽松地把 JSON 值转成数字(兼容字符串数字)
|
||
func toFloat(v interface{}) float64 {
|
||
switch x := v.(type) {
|
||
case float64:
|
||
return x
|
||
case string:
|
||
if n, err := strconv.ParseFloat(strings.TrimSpace(x), 64); err == nil {
|
||
return n
|
||
}
|
||
}
|
||
return 0
|
||
}
|
||
|
||
// Delete DELETE /backend/friendlinks/:id
|
||
func (c *BackendFriendlinkController) 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.CmsFrontendFriendlink)).
|
||
Filter("id", id).
|
||
Filter("tid", tid).
|
||
Filter("delete_time__isnull", true).
|
||
Update(map[string]interface{}{"delete_time": now, "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()
|
||
}
|
||
|
||
// BatchDelete POST /backend/friendlinks/batchdelete
|
||
func (c *BackendFriendlinkController) BatchDelete() {
|
||
claims, err := c.cmsClaims()
|
||
if err != nil {
|
||
c.cmsJSONErr(401, 401, err.Error())
|
||
return
|
||
}
|
||
tid := cmsEffectiveTid(&c.Controller, claims)
|
||
|
||
raw, err := io.ReadAll(c.Ctx.Request.Body)
|
||
if err != nil {
|
||
c.cmsJSONErr(400, 400, "参数错误")
|
||
return
|
||
}
|
||
var body struct {
|
||
IDs []interface{} `json:"ids"`
|
||
}
|
||
if err := json.Unmarshal(raw, &body); err != nil || len(body.IDs) == 0 {
|
||
c.cmsJSONErr(400, 400, "参数错误")
|
||
return
|
||
}
|
||
|
||
ids := make([]uint64, 0, len(body.IDs))
|
||
for _, v := range body.IDs {
|
||
if n := cmsParseUintArg(v); n > 0 {
|
||
ids = append(ids, n)
|
||
}
|
||
}
|
||
if len(ids) == 0 {
|
||
c.cmsJSONErr(400, 400, "参数错误")
|
||
return
|
||
}
|
||
|
||
now := time.Now()
|
||
_, err = models.Orm.QueryTable(new(models.CmsFrontendFriendlink)).
|
||
Filter("tid", tid).
|
||
Filter("id__in", ids).
|
||
Filter("delete_time__isnull", true).
|
||
Update(map[string]interface{}{"delete_time": now, "update_time": now})
|
||
if err != nil {
|
||
c.cmsJSONErr(500, 500, "删除失败")
|
||
return
|
||
}
|
||
|
||
c.Data["json"] = map[string]interface{}{"code": 200, "msg": "删除成功"}
|
||
_ = c.ServeJSON()
|
||
}
|
||
|
||
// ---------------- 单页 ----------------
|
||
|
||
type cmsOnepagePayload struct {
|
||
Title string `json:"title"`
|
||
Path string `json:"path"`
|
||
Content string `json:"content"`
|
||
Sort int `json:"sort"`
|
||
Status int8 `json:"status"`
|
||
}
|
||
|
||
// ListAll GET /backend/allonepages
|
||
func (c *BackendOnepageController) ListAll() {
|
||
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
|
||
}
|
||
|
||
var rows []models.CmsFrontendOnepage
|
||
_, err = models.Orm.QueryTable(new(models.CmsFrontendOnepage)).
|
||
Filter("tid", tid).
|
||
Filter("delete_time__isnull", true).
|
||
OrderBy("sort", "id").
|
||
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, cmsOnepageToMap(r))
|
||
}
|
||
|
||
c.Data["json"] = map[string]interface{}{"code": 200, "msg": "success", "data": list}
|
||
_ = c.ServeJSON()
|
||
}
|
||
|
||
// Create POST /backend/createonepage
|
||
func (c *BackendOnepageController) 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 cmsOnepagePayload
|
||
if err := json.Unmarshal(raw, &p); err != nil {
|
||
c.cmsJSONErr(400, 400, "参数错误")
|
||
return
|
||
}
|
||
title := strings.TrimSpace(p.Title)
|
||
path := strings.TrimSpace(p.Path)
|
||
if title == "" {
|
||
c.cmsJSONErr(400, 400, "标题不能为空")
|
||
return
|
||
}
|
||
if path == "" {
|
||
c.cmsJSONErr(400, 400, "路径标识不能为空")
|
||
return
|
||
}
|
||
if strings.ContainsAny(path, "/\\ ") {
|
||
c.cmsJSONErr(400, 400, "路径标识只能包含字母数字与下划线")
|
||
return
|
||
}
|
||
|
||
// path 租户内唯一
|
||
cnt, _ := models.Orm.QueryTable(new(models.CmsFrontendOnepage)).
|
||
Filter("tid", tid).
|
||
Filter("path", path).
|
||
Filter("delete_time__isnull", true).
|
||
Count()
|
||
if cnt > 0 {
|
||
c.cmsJSONErr(400, 400, "该路径标识已存在")
|
||
return
|
||
}
|
||
|
||
now := time.Now()
|
||
row := models.CmsFrontendOnepage{
|
||
Tid: tid,
|
||
Title: title,
|
||
Path: path,
|
||
Content: p.Content,
|
||
Sort: p.Sort,
|
||
Status: p.Status,
|
||
CreateTime: now,
|
||
UpdateTime: &now,
|
||
}
|
||
if row.Status == 0 {
|
||
row.Status = 1
|
||
}
|
||
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 POST /backend/editonepage/:id
|
||
func (c *BackendOnepageController) 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 cmsOnepagePayload
|
||
if err := json.Unmarshal(raw, &p); err != nil {
|
||
c.cmsJSONErr(400, 400, "参数错误")
|
||
return
|
||
}
|
||
path := strings.TrimSpace(p.Path)
|
||
if path != "" && strings.ContainsAny(path, "/\\ ") {
|
||
c.cmsJSONErr(400, 400, "路径标识只能包含字母数字与下划线")
|
||
return
|
||
}
|
||
if path != "" {
|
||
dup, _ := models.Orm.QueryTable(new(models.CmsFrontendOnepage)).
|
||
Filter("tid", tid).
|
||
Filter("path", path).
|
||
Filter("delete_time__isnull", true).
|
||
Exclude("id", id).
|
||
Count()
|
||
if dup > 0 {
|
||
c.cmsJSONErr(400, 400, "该路径标识已存在")
|
||
return
|
||
}
|
||
}
|
||
|
||
now := time.Now()
|
||
fields := map[string]interface{}{
|
||
"title": strings.TrimSpace(p.Title),
|
||
"content": p.Content,
|
||
"sort": p.Sort,
|
||
"update_time": now,
|
||
}
|
||
if path != "" {
|
||
fields["path"] = path
|
||
}
|
||
if p.Status > 0 {
|
||
fields["status"] = p.Status
|
||
}
|
||
n, err := models.Orm.QueryTable(new(models.CmsFrontendOnepage)).
|
||
Filter("id", id).
|
||
Filter("tid", tid).
|
||
Filter("delete_time__isnull", true).
|
||
Update(fields)
|
||
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/deleteonepage/:id
|
||
func (c *BackendOnepageController) 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.CmsFrontendOnepage)).
|
||
Filter("id", id).
|
||
Filter("tid", tid).
|
||
Filter("delete_time__isnull", true).
|
||
Update(map[string]interface{}{"delete_time": now, "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()
|
||
}
|