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 }