github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/models/link.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 Link struct {
    14  	Id             int64
    15  	Pid            int64 `xorm:"index"` //小于等于0 代表链接本身是顶层链接, pid大于0 代表属于某节点id的下级 本系统围绕node设计,链接亦可以是节点的下级
    16  	Uid            int64 `xorm:"index"`
    17  	Sort           int64
    18  	Ctype          int64   `xorm:"index"`
    19  	Title          string  `xorm:"index"`
    20  	Content        string  `xorm:"text"`
    21  	Attachment     string  `xorm:"text"`
    22  	Created        int64   `xorm:"created index"`
    23  	Updated        int64   `xorm:"updated"`
    24  	Hotness        float64 `xorm:"index"`
    25  	Hotup          int64   `xorm:"index"`
    26  	Hotdown        int64   `xorm:"index"`
    27  	Hotscore       int64   `xorm:"index"` //Hotup  -	Hotdown
    28  	Hotvote        int64   `xorm:"index"` //Hotup  + 	Hotdown
    29  	Views          int64
    30  	Author         string `xorm:"index"` //这里指本链接创建者
    31  	Parent         string `xorm:"index"` //父级节点名称
    32  	NodeTime       int64
    33  	NodeCount      int64
    34  	NodeLastUserId int64
    35  }
    36  
    37  func AddLink(title string, content string, attachment string, nid int64, parent string) (int64, error) {
    38  	cat := &Link{Pid: nid, Parent: parent, Title: title, Content: content, Attachment: attachment, Created: time.Now().Unix()}
    39  
    40  	if _, err := Engine.Insert(cat); err == nil {
    41  
    42  		return cat.Id, err
    43  	} else {
    44  		return -1, err
    45  	}
    46  
    47  }
    48  
    49  func GetLinks(offset int, limit int, field string) (*[]*Link, error) {
    50  	linkz := new([]*Link)
    51  	err := Engine.Table("link").Limit(limit, offset).Desc(field).Find(linkz)
    52  	return linkz, err
    53  }
    54  
    55  func GetLinksByNodeCount(offset int, limit int, nodecount int64, field string) (*[]*Link, error) {
    56  	linkz := new([]*Link)
    57  	err := Engine.Table("link").Where("node_count > ?", nodecount).Limit(limit, offset).Desc(field).Find(linkz)
    58  	return linkz, err
    59  }
    60  
    61  func GetLink(id int64) (*Link, error) {
    62  
    63  	cat := &Link{}
    64  	has, err := Engine.Id(id).Get(cat)
    65  
    66  	if has {
    67  		return cat, err
    68  	} else {
    69  
    70  		return nil, err
    71  	}
    72  }
    73  
    74  func GetLinkByTitle(title string) (*Link, error) {
    75  	cat := &Link{}
    76  	cat.Title = title
    77  	has, err := Engine.Get(cat)
    78  	if has {
    79  		return cat, err
    80  	} else {
    81  
    82  		return nil, err
    83  	}
    84  }
    85  
    86  func PutLink(cid int64, cat *Link) (int64, error) {
    87  	//覆盖式更新
    88  	row, err := Engine.Update(cat, &Link{Id: cid})
    89  	return row, err
    90  
    91  }
    92  
    93  //map[string]interface{}{"ctype": ctype}
    94  func UpdateLink(cid int64, catmap *map[string]interface{}) error {
    95  	cat := &Link{}
    96  	if row, err := Engine.Table(cat).Where("id=?", cid).Update(catmap); err != nil || row == 0 {
    97  		return errors.New(fmt.Sprint("UpdateLink row:", row, "出现错误:", err))
    98  	} else {
    99  		return nil
   100  	}
   101  
   102  }
   103  
   104  func DelLink(id int64, uid int64, role int64) error {
   105  	allow := false
   106  	if role < 0 {
   107  		allow = true
   108  	}
   109  
   110  	link := &Link{}
   111  
   112  	if has, err := Engine.Id(id).Get(link); has == true && err == nil {
   113  
   114  		if link.Uid == uid || allow {
   115  			//检查附件字段并尝试删除文件
   116  			if len(link.Attachment) > 0 {
   117  
   118  				if p := helper.URL2local(link.Attachment); helper.Exist(p) {
   119  					//验证是否管理员权限
   120  					if allow {
   121  						if err := os.Remove(p); err != nil {
   122  							//可以输出错误日志,但不要反回错误,以免陷入死循环无法删掉
   123  							fmt.Println("ROOT DEL LINK Attachment, LINK ID:", id, ",ERR:", err)
   124  						}
   125  					} else { //检查用户对本地文件的所有权
   126  						if helper.VerifyUserfile(p, strconv.FormatInt(uid, 10)) {
   127  							if err := os.Remove(p); err != nil {
   128  								fmt.Println("DEL LINK Attachment, LINK ID:", id, ",ERR:", err)
   129  							}
   130  						}
   131  					}
   132  
   133  				}
   134  			}
   135  
   136  			//检查内容字段并尝试删除文件
   137  			if len(link.Content) > 0 {
   138  				//若内容中存在图片则开始尝试删除图片
   139  				delfiles_local := []string{}
   140  
   141  				if m, n := helper.GetImages(link.Content); n > 0 {
   142  
   143  					for _, v := range m {
   144  						if helper.IsLocal(v) {
   145  							delfiles_local = append(delfiles_local, v)
   146  							//如果本地同时也存在banner缓存文件,则加入旧图集合中,等待后面一次性删除
   147  							if p := helper.URL2local(helper.SetSuffix(v, "_banner.jpg")); helper.Exist(p) {
   148  								delfiles_local = append(delfiles_local, p)
   149  							}
   150  							if p := helper.URL2local(helper.SetSuffix(v, "_large.jpg")); helper.Exist(p) {
   151  								delfiles_local = append(delfiles_local, p)
   152  							}
   153  							if p := helper.URL2local(helper.SetSuffix(v, "_medium.jpg")); helper.Exist(p) {
   154  								delfiles_local = append(delfiles_local, p)
   155  							}
   156  							if p := helper.URL2local(helper.SetSuffix(v, "_small.jpg")); helper.Exist(p) {
   157  								delfiles_local = append(delfiles_local, p)
   158  							}
   159  						}
   160  					}
   161  					for k, v := range delfiles_local {
   162  						if p := helper.URL2local(v); helper.Exist(p) { //如若文件存在,则处理,否则忽略
   163  							//先行判断是否缩略图  如果不是则执行删除image表记录的操作 因为缩略图是没有存到image表记录里面的
   164  							//isThumbnails := bool(true) //false代表不是缩略图 true代表是缩略图
   165  							/*
   166  								if (!strings.HasSuffix(v, "_large.jpg")) &&
   167  									(!strings.HasSuffix(v, "_medium.jpg")) &&
   168  									(!strings.HasSuffix(v, "_small.jpg")) {
   169  									isThumbnails = false
   170  
   171  								}
   172  							*/
   173  							//验证是否管理员权限
   174  							if allow {
   175  								if err := os.Remove(p); err != nil {
   176  									log.Println("#", k, ",ROOT DEL FILE ERROR:", err)
   177  								}
   178  
   179  							} else { //检查用户对文件的所有权
   180  								if helper.VerifyUserfile(p, strconv.FormatInt(uid, 10)) {
   181  									if err := os.Remove(p); err != nil {
   182  										log.Println("#", k, ",DEL FILE ERROR:", err)
   183  									}
   184  
   185  								}
   186  							}
   187  
   188  						}
   189  					}
   190  				}
   191  
   192  			}
   193  			//不管实际路径中是否存在文件均删除该数据库记录,以免数据库记录陷入死循环无法删掉
   194  			if link.Id == id {
   195  
   196  				if row, err := Engine.Id(id).Delete(new(Link)); err != nil || row == 0 {
   197  					return errors.New(fmt.Sprint("删除链接错误!", row, err))
   198  				} else {
   199  					return nil
   200  				}
   201  
   202  			}
   203  		}
   204  		return errors.New("你无权删除此链接:" + strconv.FormatInt(id, 10))
   205  	}
   206  	return errors.New("无法删除不存在的LINK ID:" + strconv.FormatInt(id, 10))
   207  }
   208  
   209  func GetLinkCountByPid(pid int64) int64 {
   210  	n, _ := Engine.Where("pid=?", pid).Count(&Link{Pid: pid})
   211  	return n
   212  }