github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/models/category.go (about)

     1  package models
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"log"
     7  	"os"
     8  	"strconv"
     9  	"time"
    10  	"github.com/insionng/yougam/helper"
    11  )
    12  
    13  type Category struct {
    14  	Id             int64
    15  	Pid            int64 `xorm:"index"` //小于等于0 代表分类本身是顶层分类, pid大于0 代表属于某分类id的下级
    16  	Nid            int64 `xorm:"index"` //小于等于0 代表本分类不属于某节点,大于0 代表属于某节点id的下级 本系统围绕node设计,分类亦可以是节点的下级
    17  	Uid            int64 `xorm:"index"`
    18  	Sort           int64
    19  	Ctype          int64   `xorm:"index"`
    20  	Title          string  `xorm:"index"`
    21  	Content        string  `xorm:"text"`
    22  	Attachment     string  `xorm:"text"`
    23  	Created        int64   `xorm:"created index"`
    24  	Updated        int64   `xorm:"updated"`
    25  	Hotness        float64 `xorm:"index"`
    26  	Confidence     float64 `xorm:"index"` //信任度数值
    27  	Hotup          int64   `xorm:"index"`
    28  	Hotdown        int64   `xorm:"index"`
    29  	Hotscore       int64   `xorm:"index"` //Hotup  -	Hotdown
    30  	Hotvote        int64   `xorm:"index"` //Hotup  + 	Hotdown
    31  	Views          int64
    32  	Author         string `xorm:"index"` //这里指本分类创建者
    33  	Parent         string `xorm:"index"` //父级分类名称
    34  	NodeTime       int64
    35  	NodeCount      int64
    36  	NodeLastUserId int64
    37  	Template       string `xorm:"index"`
    38  }
    39  
    40  func GetCategoriesCount(offset int, limit int) (int64, error) {
    41  	total, err := Engine.Limit(limit, offset).Count(&Category{})
    42  	return total, err
    43  }
    44  
    45  func SetCategory(cid int64, cat *Category) (int64, error) {
    46  	cat.Id = cid
    47  	return Engine.Insert(cat)
    48  }
    49  
    50  func PostCategory(cat *Category) (int64, error) {
    51  	return Engine.Insert(cat)
    52  }
    53  
    54  func AddCategory(title string, content string, attachment string, nid int64) (int64, error) {
    55  	cat := &Category{Pid: nid, Title: title, Content: content, Attachment: attachment, Created: time.Now().Unix()}
    56  	if _, err := Engine.Insert(cat); err == nil {
    57  		return cat.Id, err
    58  	} else {
    59  		return -1, err
    60  	}
    61  
    62  }
    63  
    64  func HasCategory(title string) (int64, bool) {
    65  	cat := new(Category)
    66  	if has, err := Engine.Where("title = ?", title).Get(cat); err != nil {
    67  		return -1, false
    68  	} else {
    69  		if has {
    70  			return cat.Id, true
    71  		}
    72  		return -1, false
    73  	}
    74  }
    75  
    76  func GetCategories(offset int, limit int, field string) (*[]*Category, error) {
    77  	catz := new([]*Category)
    78  	err := Engine.Table("category").Limit(limit, offset).Desc(field).Find(catz)
    79  	return catz, err
    80  }
    81  
    82  func GetCategoriesByNodeCount(offset int, limit int, nodecount int64, field string) (*[]*Category, error) {
    83  	catz := new([]*Category)
    84  	err := Engine.Table("category").Where("node_count > ?", nodecount).Limit(limit, offset).Desc(field).Find(catz)
    85  	return catz, err
    86  }
    87  
    88  func GetCategoriesViaPid(pid int64, offset int, limit int, ctype int64, field string) *[]*Category {
    89  	var objs = new([]*Category)
    90  	if pid <= 0 {
    91  		switch {
    92  		case field == "asc":
    93  			{
    94  				if ctype != 0 {
    95  					Engine.Where("pid <= ? and ctype = ?", 0, ctype).Limit(limit, offset).Asc("id").Find(objs)
    96  				} else {
    97  					Engine.Where("pid <= ?", 0).Limit(limit, offset).Asc("id").Find(objs)
    98  				}
    99  			}
   100  		default:
   101  			{
   102  				if ctype != 0 {
   103  					Engine.Where("pid <= ? and ctype = ?", 0, ctype).Limit(limit, offset).Desc(field).Find(objs)
   104  				} else {
   105  					Engine.Where("pid <= ?", 0).Limit(limit, offset).Desc(field).Find(objs)
   106  				}
   107  			}
   108  		}
   109  	} else {
   110  		switch {
   111  		case field == "asc":
   112  			{
   113  				if ctype != 0 {
   114  					Engine.Where("pid=? and ctype=?", pid, ctype).Limit(limit, offset).Asc("id").Find(objs)
   115  				} else {
   116  					Engine.Where("pid=?", pid).Limit(limit, offset).Asc("id").Find(objs)
   117  				}
   118  			}
   119  		default:
   120  			{
   121  				if ctype != 0 {
   122  					Engine.Where("pid=? and ctype=?", pid, ctype).Limit(limit, offset).Desc(field).Find(objs)
   123  				} else {
   124  					Engine.Where("pid=?", pid).Limit(limit, offset).Desc(field).Find(objs)
   125  				}
   126  			}
   127  		}
   128  	}
   129  	return objs
   130  }
   131  
   132  func GetCategoriesByPid(pid int64, offset int, limit int, ctype int64, field string) *[]*Category {
   133  	var objs = new([]*Category)
   134  	switch {
   135  	case field == "asc":
   136  		{
   137  			if ctype != 0 {
   138  				Engine.Where("(pid=? or id=?) and ctype=?", pid, pid, ctype).Limit(limit, offset).Asc("id").Find(objs)
   139  			} else {
   140  				Engine.Where("pid=? or id=?", pid, pid).Limit(limit, offset).Asc("id").Find(objs)
   141  			}
   142  		}
   143  	default:
   144  		{
   145  			if ctype != 0 {
   146  				Engine.Where("(pid=? or id=?) and ctype=?", pid, pid, ctype).Limit(limit, offset).Desc(field).Find(objs)
   147  			} else {
   148  				Engine.Where("pid=? or id=?", pid, pid).Limit(limit, offset).Desc(field).Find(objs)
   149  			}
   150  		}
   151  	}
   152  	return objs
   153  }
   154  
   155  func GetCategoriesByCtypeWithNid(offset int, limit int, ctype int64, nid int64, field string) (*[]*Category, error) {
   156  	objs := new([]*Category)
   157  	err := Engine.Table("category").Where("ctype = ? and nid = ?", ctype, nid).Limit(limit, offset).Desc(field).Find(objs)
   158  	return objs, err
   159  }
   160  
   161  func GetCategoriesByNid(nid int64, offset int, limit int, field string) (*[]*Category, error) {
   162  	nds := new([]*Category)
   163  	err := Engine.Where("nid=?", nid).Limit(limit, offset).Desc(field).Find(nds)
   164  	return nds, err
   165  }
   166  
   167  func GetCategoriesByCtype(offset int, limit int, ctype int64, field string) (*[]*Category, error) {
   168  	catz := new([]*Category)
   169  	err := Engine.Table("category").Where("ctype = ?", ctype).Limit(limit, offset).Desc(field).Find(catz)
   170  	return catz, err
   171  }
   172  
   173  func GetCategoriesByCtypeWithPid(offset int, limit int, ctype int64, pid int64, field string) (*[]*Category, error) {
   174  	catz := new([]*Category)
   175  	var err error
   176  	if pid <= 0 {
   177  		err = Engine.Table("category").Where("ctype = ? and pid <= ?", ctype, 0).Limit(limit, offset).Desc(field).Find(catz)
   178  	} else {
   179  		err = Engine.Table("category").Where("ctype = ? and pid = ?", ctype, pid).Limit(limit, offset).Desc(field).Find(catz)
   180  	}
   181  	return catz, err
   182  }
   183  
   184  func GetCategory(id int64) (*Category, error) {
   185  
   186  	cat := &Category{}
   187  	has, err := Engine.Id(id).Get(cat)
   188  
   189  	if has {
   190  		return cat, err
   191  	} else {
   192  		return nil, err
   193  	}
   194  }
   195  
   196  func GetCategoryByTitle(title string) (*Category, error) {
   197  	var cat = &Category{Title: title}
   198  	has, err := Engine.Get(cat)
   199  	if has {
   200  		return cat, err
   201  	} else {
   202  		return nil, err
   203  	}
   204  }
   205  
   206  func PutCategory(cid int64, cat *Category) (int64, error) {
   207  	//覆盖式更新
   208  	row, err := Engine.Update(cat, &Category{Id: cid})
   209  	return row, err
   210  }
   211  
   212  //map[string]interface{}{"ctype": ctype}
   213  func UpdateCategory(cid int64, catmap *map[string]interface{}) error {
   214  	cat := &Category{}
   215  	if row, err := Engine.Table(cat).Where("id=?", cid).Update(catmap); (err != nil) || (row <= 0) {
   216  		return errors.New(fmt.Sprint("UpdateCategory row:", row, "出现错误:", err))
   217  	} else {
   218  		return nil
   219  	}
   220  
   221  }
   222  
   223  func DelCategory(id int64, uid int64, role int64) error {
   224  	allow := false
   225  	if role < 0 {
   226  		allow = true
   227  	}
   228  
   229  	category := &Category{}
   230  
   231  	if has, err := Engine.Id(id).Get(category); has == true && err == nil {
   232  
   233  		if category.Uid == uid || allow {
   234  			//检查附件字段并尝试删除文件
   235  			if len(category.Attachment) > 0 {
   236  
   237  				if p := helper.URL2local(category.Attachment); helper.Exist(p) {
   238  					//验证是否管理员权限
   239  					if allow {
   240  						if err := os.Remove(p); err != nil {
   241  							//可以输出错误日志,但不要反回错误,以免陷入死循环无法删掉
   242  							log.Println("ROOT DEL CATEGORY Attachment, CATEGORY ID:", id, ",ERR:", err)
   243  						}
   244  					} else { //检查用户对本地文件的所有权
   245  						if helper.VerifyUserfile(p, strconv.FormatInt(uid, 10)) {
   246  							if err := os.Remove(p); err != nil {
   247  								log.Println("DEL CATEGORY Attachment, CATEGORY ID:", id, ",ERR:", err)
   248  							}
   249  						}
   250  					}
   251  
   252  				}
   253  			}
   254  
   255  			//检查内容字段并尝试删除文件
   256  			if len(category.Content) > 0 {
   257  				//若内容中存在图片则开始尝试删除图片
   258  				delfiles_local := []string{}
   259  
   260  				if m, n := helper.GetImages(category.Content); n > 0 {
   261  
   262  					for _, v := range m {
   263  						if helper.IsLocal(v) {
   264  							delfiles_local = append(delfiles_local, v)
   265  							//如果本地同时也存在banner缓存文件,则加入旧图集合中,等待后面一次性删除
   266  							if p := helper.URL2local(helper.SetSuffix(v, "_banner.jpg")); helper.Exist(p) {
   267  								delfiles_local = append(delfiles_local, p)
   268  							}
   269  							if p := helper.URL2local(helper.SetSuffix(v, "_large.jpg")); helper.Exist(p) {
   270  								delfiles_local = append(delfiles_local, p)
   271  							}
   272  							if p := helper.URL2local(helper.SetSuffix(v, "_medium.jpg")); helper.Exist(p) {
   273  								delfiles_local = append(delfiles_local, p)
   274  							}
   275  							if p := helper.URL2local(helper.SetSuffix(v, "_small.jpg")); helper.Exist(p) {
   276  								delfiles_local = append(delfiles_local, p)
   277  							}
   278  						}
   279  					}
   280  					for k, v := range delfiles_local {
   281  						if p := helper.URL2local(v); helper.Exist(p) { //如若文件存在,则处理,否则忽略
   282  							//先行判断是否缩略图  如果不是则执行删除image表记录的操作 因为缩略图是没有存到image表记录里面的
   283  							//isThumbnails := bool(true) //false代表不是缩略图 true代表是缩略图
   284  							/*
   285  								if (!strings.HasSuffix(v, "_large.jpg")) &&
   286  									(!strings.HasSuffix(v, "_medium.jpg")) &&
   287  									(!strings.HasSuffix(v, "_small.jpg")) {
   288  									isThumbnails = false
   289  
   290  								}
   291  							*/
   292  							//验证是否管理员权限
   293  							if allow {
   294  								if err := os.Remove(p); err != nil {
   295  									log.Println("#", k, ",ROOT DEL FILE ERROR:", err)
   296  								}
   297  
   298  							} else { //检查用户对文件的所有权
   299  								if helper.VerifyUserfile(p, strconv.FormatInt(uid, 10)) {
   300  									if err := os.Remove(p); err != nil {
   301  										log.Println("#", k, ",DEL FILE ERROR:", err)
   302  									}
   303  
   304  								}
   305  							}
   306  
   307  						}
   308  					}
   309  				}
   310  
   311  			}
   312  			//不管实际路径中是否存在文件均删除该数据库记录,以免数据库记录陷入死循环无法删掉
   313  			if category.Id == id {
   314  
   315  				if row, err := Engine.Id(id).Delete(new(Category)); err != nil || row == 0 {
   316  					return errors.New(fmt.Sprint("删除分类错误!", row, err)) //错误还要我自己构造?!
   317  				} else {
   318  					return nil
   319  				}
   320  
   321  			}
   322  		}
   323  		return errors.New("你无权删除此分类:" + strconv.FormatInt(id, 10))
   324  	}
   325  	return errors.New("无法删除不存在的CATEGORY ID:" + strconv.FormatInt(id, 10))
   326  }
   327  
   328  func GetCategoryCountByPid(pid int64) int64 {
   329  	n, _ := Engine.Where("pid=?", pid).Count(&Category{Pid: pid})
   330  	return n
   331  }