1、实现富文本编辑器

2、实现文档转换为PDF、MOBI、EPUB、Word格式
3、实现登录后跳转到来源地址
pull/219/head
Minho 2018-01-26 17:17:38 +08:00
parent e1ec6bb788
commit 882d93e7b0
57 changed files with 1572 additions and 1475 deletions

View File

@ -6,11 +6,12 @@ import (
"net/url" "net/url"
"os" "os"
"time" "time"
"log"
"flag" "flag"
"path/filepath" "path/filepath"
"strings" "strings"
"encoding/json"
"github.com/astaxie/beego" "github.com/astaxie/beego"
"github.com/astaxie/beego/logs" "github.com/astaxie/beego/logs"
"github.com/astaxie/beego/orm" "github.com/astaxie/beego/orm"
@ -19,14 +20,6 @@ import (
"github.com/lifei6671/mindoc/conf" "github.com/lifei6671/mindoc/conf"
"github.com/lifei6671/mindoc/models" "github.com/lifei6671/mindoc/models"
"github.com/lifei6671/mindoc/utils" "github.com/lifei6671/mindoc/utils"
"log"
"encoding/json"
)
var (
ConfigurationFile = "./conf/app.conf"
WorkingDirectory = "./"
LogFile = "./logs"
) )
// RegisterDataBase 注册数据库 // RegisterDataBase 注册数据库
@ -54,8 +47,8 @@ func RegisterDataBase() {
} }
} else if adapter == "sqlite3" { } else if adapter == "sqlite3" {
database := beego.AppConfig.String("db_database") database := beego.AppConfig.String("db_database")
if strings.HasPrefix(database,"./") { if strings.HasPrefix(database, "./") {
database = filepath.Join(WorkingDirectory,string(database[1:])) database = filepath.Join(conf.WorkingDirectory, string(database[1:]))
} }
dbPath := filepath.Dir(database) dbPath := filepath.Dir(database)
@ -99,11 +92,11 @@ func RegisterLogger(log string) {
if f, err := os.Create(logPath); err == nil { if f, err := os.Create(logPath); err == nil {
f.Close() f.Close()
config := make(map[string]interface{},1) config := make(map[string]interface{}, 1)
config["filename"] = logPath config["filename"] = logPath
b,_ := json.Marshal(config) b, _ := json.Marshal(config)
beego.SetLogger("file", string(b)) beego.SetLogger("file", string(b))
} }
@ -133,7 +126,7 @@ func RegisterFunction() {
beego.AddFuncMap("cdn", func(p string) string { beego.AddFuncMap("cdn", func(p string) string {
cdn := beego.AppConfig.DefaultString("cdn", "") cdn := beego.AppConfig.DefaultString("cdn", "")
if strings.HasPrefix(p,"http://") || strings.HasPrefix(p,"https://") { if strings.HasPrefix(p, "http://") || strings.HasPrefix(p, "https://") {
return p return p
} }
if strings.HasPrefix(p, "/") && strings.HasSuffix(cdn, "/") { if strings.HasPrefix(p, "/") && strings.HasSuffix(cdn, "/") {
@ -147,7 +140,7 @@ func RegisterFunction() {
beego.AddFuncMap("cdnjs", func(p string) string { beego.AddFuncMap("cdnjs", func(p string) string {
cdn := beego.AppConfig.DefaultString("cdnjs", "") cdn := beego.AppConfig.DefaultString("cdnjs", "")
if strings.HasPrefix(p,"http://") || strings.HasPrefix(p,"https://") { if strings.HasPrefix(p, "http://") || strings.HasPrefix(p, "https://") {
return p return p
} }
if strings.HasPrefix(p, "/") && strings.HasSuffix(cdn, "/") { if strings.HasPrefix(p, "/") && strings.HasSuffix(cdn, "/") {
@ -160,7 +153,7 @@ func RegisterFunction() {
}) })
beego.AddFuncMap("cdncss", func(p string) string { beego.AddFuncMap("cdncss", func(p string) string {
cdn := beego.AppConfig.DefaultString("cdncss", "") cdn := beego.AppConfig.DefaultString("cdncss", "")
if strings.HasPrefix(p,"http://") || strings.HasPrefix(p,"https://") { if strings.HasPrefix(p, "http://") || strings.HasPrefix(p, "https://") {
return p return p
} }
if strings.HasPrefix(p, "/") && strings.HasSuffix(cdn, "/") { if strings.HasPrefix(p, "/") && strings.HasSuffix(cdn, "/") {
@ -172,7 +165,7 @@ func RegisterFunction() {
return cdn + p return cdn + p
}) })
beego.AddFuncMap("cdnimg", func(p string) string { beego.AddFuncMap("cdnimg", func(p string) string {
if strings.HasPrefix(p,"http://") || strings.HasPrefix(p,"https://") { if strings.HasPrefix(p, "http://") || strings.HasPrefix(p, "https://") {
return p return p
} }
cdn := beego.AppConfig.DefaultString("cdnimg", "") cdn := beego.AppConfig.DefaultString("cdnimg", "")
@ -188,62 +181,64 @@ func RegisterFunction() {
func ResolveCommand(args []string) { func ResolveCommand(args []string) {
flagSet := flag.NewFlagSet("MinDoc command: ", flag.ExitOnError) flagSet := flag.NewFlagSet("MinDoc command: ", flag.ExitOnError)
flagSet.StringVar(&ConfigurationFile, "config", "", "MinDoc configuration file.") flagSet.StringVar(&conf.ConfigurationFile, "config", "", "MinDoc configuration file.")
flagSet.StringVar(&WorkingDirectory, "dir", "", "MinDoc working directory.") flagSet.StringVar(&conf.WorkingDirectory, "dir", "", "MinDoc working directory.")
flagSet.StringVar(&LogFile, "log", "", "MinDoc log file path.") flagSet.StringVar(&conf.LogFile, "log", "", "MinDoc log file path.")
flagSet.Parse(args) flagSet.Parse(args)
if conf.WorkingDirectory == "" {
if WorkingDirectory == "" {
if p, err := filepath.Abs(os.Args[0]); err == nil { if p, err := filepath.Abs(os.Args[0]); err == nil {
WorkingDirectory = filepath.Dir(p) conf.WorkingDirectory = filepath.Dir(p)
} }
} }
if LogFile == "" { if conf.LogFile == "" {
LogFile = filepath.Join(WorkingDirectory,"logs") conf.LogFile = filepath.Join(conf.WorkingDirectory, "logs")
} }
if ConfigurationFile == "" { if conf.ConfigurationFile == "" {
ConfigurationFile = filepath.Join(WorkingDirectory,"conf","app.conf") conf.ConfigurationFile = filepath.Join(conf.WorkingDirectory, "conf", "app.conf")
config := filepath.Join(WorkingDirectory,"conf","app.conf.example") config := filepath.Join(conf.WorkingDirectory, "conf", "app.conf.example")
if !utils.FileExists(ConfigurationFile) && utils.FileExists(config){ if !utils.FileExists(conf.ConfigurationFile) && utils.FileExists(config) {
utils.CopyFile(ConfigurationFile,config) utils.CopyFile(conf.ConfigurationFile, config)
} }
} }
gocaptcha.ReadFonts(filepath.Join(WorkingDirectory,"static","fonts"), ".ttf") gocaptcha.ReadFonts(filepath.Join(conf.WorkingDirectory, "static", "fonts"), ".ttf")
err := beego.LoadAppConfig("ini", ConfigurationFile) err := beego.LoadAppConfig("ini", conf.ConfigurationFile)
if err != nil { if err != nil {
log.Println("An error occurred:", err) log.Println("An error occurred:", err)
os.Exit(1) os.Exit(1)
} }
uploads := filepath.Join(WorkingDirectory, "uploads") uploads := filepath.Join(conf.WorkingDirectory, "uploads")
os.MkdirAll(uploads,0666) os.MkdirAll(uploads, 0666)
beego.BConfig.WebConfig.StaticDir["/static"] = filepath.Join(WorkingDirectory, "static") beego.BConfig.WebConfig.StaticDir["/static"] = filepath.Join(conf.WorkingDirectory, "static")
beego.BConfig.WebConfig.StaticDir["/uploads"] = uploads beego.BConfig.WebConfig.StaticDir["/uploads"] = uploads
beego.BConfig.WebConfig.ViewsPath = filepath.Join(WorkingDirectory, "views") beego.BConfig.WebConfig.ViewsPath = filepath.Join(conf.WorkingDirectory, "views")
fonts := filepath.Join(WorkingDirectory, "static", "fonts") fonts := filepath.Join(conf.WorkingDirectory, "static", "fonts")
if !utils.FileExists(fonts) { if !utils.FileExists(fonts) {
log.Fatal("Font path not exist.") log.Fatal("Font path not exist.")
} }
gocaptcha.ReadFonts(filepath.Join(WorkingDirectory, "static", "fonts"), ".ttf") gocaptcha.ReadFonts(filepath.Join(conf.WorkingDirectory, "static", "fonts"), ".ttf")
RegisterDataBase() RegisterDataBase()
RegisterModel() RegisterModel()
RegisterLogger(LogFile) RegisterLogger(conf.LogFile)
} }
func init() { func init() {
if configPath ,err := filepath.Abs(conf.ConfigurationFile); err == nil {
conf.ConfigurationFile = configPath
}
gocaptcha.ReadFonts("./static/fonts", ".ttf") gocaptcha.ReadFonts("./static/fonts", ".ttf")
gob.Register(models.Member{}) gob.Register(models.Member{})
if p,err := filepath.Abs(os.Args[0]);err == nil{ if p, err := filepath.Abs(os.Args[0]); err == nil {
WorkingDirectory = filepath.Dir(p) conf.WorkingDirectory = filepath.Dir(p)
} }
} }

View File

@ -22,7 +22,7 @@ func NewDaemon() *Daemon {
Name: "mindocd", //服务显示名称 Name: "mindocd", //服务显示名称
DisplayName: "MinDoc service", //服务名称 DisplayName: "MinDoc service", //服务名称
Description: "A document online management program.", //服务描述 Description: "A document online management program.", //服务描述
WorkingDirectory: commands.WorkingDirectory, WorkingDirectory: conf.WorkingDirectory,
Arguments: os.Args[1:], Arguments: os.Args[1:],
} }

View File

@ -16,19 +16,18 @@ package migrate
import ( import (
"os" "os"
"log"
"github.com/lifei6671/mindoc/models"
"container/list" "container/list"
"fmt" "fmt"
"github.com/astaxie/beego" "github.com/astaxie/beego"
"github.com/astaxie/beego/orm" "github.com/astaxie/beego/orm"
"github.com/lifei6671/mindoc/models"
"log"
) )
var ( var (
migrationList = &migrationCache{ } migrationList = &migrationCache{}
) )
type MigrationDatabase interface { type MigrationDatabase interface {
//获取当前的版本 //获取当前的版本
Version() int64 Version() int64
@ -58,7 +57,7 @@ func RunMigration() {
if len(os.Args) >= 2 && os.Args[1] == "migrate" { if len(os.Args) >= 2 && os.Args[1] == "migrate" {
migrate,err := models.NewMigration().FindFirst() migrate, err := models.NewMigration().FindFirst()
if err != nil { if err != nil {
//log.Fatalf("migrations table %s", err) //log.Fatalf("migrations table %s", err)
@ -66,10 +65,10 @@ func RunMigration() {
} }
fmt.Println("Start migration databae... ") fmt.Println("Start migration databae... ")
for el := migrationList.items.Front(); el != nil ; el = el.Next() { for el := migrationList.items.Front(); el != nil; el = el.Next() {
//如果存在比当前版本大的版本,则依次升级 //如果存在比当前版本大的版本,则依次升级
if item,ok := el.Value.(MigrationDatabase); ok && item.Version() > migrate.Version { if item, ok := el.Value.(MigrationDatabase); ok && item.Version() > migrate.Version {
err := item.ValidUpdate(migrate.Version) err := item.ValidUpdate(migrate.Version)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
@ -112,47 +111,49 @@ func RunMigration() {
} }
//导出数据库的表结构 //导出数据库的表结构
func ExportDatabaseTable() ([]string,error) { func ExportDatabaseTable() ([]string, error) {
db_adapter := beego.AppConfig.String("db_adapter") db_adapter := beego.AppConfig.String("db_adapter")
db_database := beego.AppConfig.String("db_database") db_database := beego.AppConfig.String("db_database")
tables := make([]string,0) tables := make([]string, 0)
o := orm.NewOrm() o := orm.NewOrm()
switch db_adapter { switch db_adapter {
case "mysql":{ case "mysql":
{
var lists []orm.Params var lists []orm.Params
_,err := o.Raw(fmt.Sprintf("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = '%s'",db_database)).Values(&lists) _, err := o.Raw(fmt.Sprintf("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = '%s'", db_database)).Values(&lists)
if err != nil { if err != nil {
return tables,err return tables, err
} }
for _,table := range lists { for _, table := range lists {
var results []orm.Params var results []orm.Params
_,err = o.Raw(fmt.Sprintf("show create table %s",table["TABLE_NAME"])).Values(&results) _, err = o.Raw(fmt.Sprintf("show create table %s", table["TABLE_NAME"])).Values(&results)
if err != nil { if err != nil {
return tables,err return tables, err
} }
tables = append(tables,results[0]["Create Table"].(string)) tables = append(tables, results[0]["Create Table"].(string))
} }
break; break
} }
case "sqlite3": { case "sqlite3":
{
var results []orm.Params var results []orm.Params
_,err := o.Raw("SELECT sql FROM sqlite_master WHERE sql IS NOT NULL ORDER BY rootpage ASC").Values(&results) _, err := o.Raw("SELECT sql FROM sqlite_master WHERE sql IS NOT NULL ORDER BY rootpage ASC").Values(&results)
if err != nil { if err != nil {
return tables,err return tables, err
} }
for _,item := range results { for _, item := range results {
if sql,ok := item["sql"]; ok { if sql, ok := item["sql"]; ok {
tables = append(tables,sql.(string)) tables = append(tables, sql.(string))
} }
} }
break break
} }
} }
return tables,nil return tables, nil
} }
func RegisterMigration() { func RegisterMigration() {

View File

@ -2,21 +2,20 @@ package migrate
import ( import (
"errors" "errors"
"fmt"
"github.com/astaxie/beego/orm" "github.com/astaxie/beego/orm"
"github.com/lifei6671/mindoc/models" "github.com/lifei6671/mindoc/models"
"time"
"fmt"
"strings" "strings"
"time"
) )
type MigrationVersion03 struct { type MigrationVersion03 struct {
isValid bool isValid bool
tables []string tables []string
} }
func NewMigrationVersion03() *MigrationVersion03 { func NewMigrationVersion03() *MigrationVersion03 {
return &MigrationVersion03{ isValid: false, tables: make([]string,0)} return &MigrationVersion03{isValid: false, tables: make([]string, 0)}
} }
func (m *MigrationVersion03) Version() int64 { func (m *MigrationVersion03) Version() int64 {
@ -37,8 +36,7 @@ func (m *MigrationVersion03) ValidForBackupTableSchema() error {
return errors.New("The current version failed to verify.") return errors.New("The current version failed to verify.")
} }
var err error var err error
m.tables,err = ExportDatabaseTable() m.tables, err = ExportDatabaseTable()
return err return err
} }
@ -72,11 +70,11 @@ func (m *MigrationVersion03) MigrationNewTableData() error {
} }
o := orm.NewOrm() o := orm.NewOrm()
_,err := o.Raw("UPDATE md_members SET auth_method = 'local'").Exec() _, err := o.Raw("UPDATE md_members SET auth_method = 'local'").Exec()
if err != nil { if err != nil {
return err return err
} }
_,err = o.Raw("INSERT INTO md_options (option_title, option_name, option_value) SELECT '是否启用文档历史','ENABLE_DOCUMENT_HISTORY','true' WHERE NOT exists(SELECT * FROM md_options WHERE option_name = 'ENABLE_DOCUMENT_HISTORY');").Exec() _, err = o.Raw("INSERT INTO md_options (option_title, option_name, option_value) SELECT '是否启用文档历史','ENABLE_DOCUMENT_HISTORY','true' WHERE NOT exists(SELECT * FROM md_options WHERE option_name = 'ENABLE_DOCUMENT_HISTORY');").Exec()
if err != nil { if err != nil {
return err return err
} }
@ -85,7 +83,7 @@ func (m *MigrationVersion03) MigrationNewTableData() error {
func (m *MigrationVersion03) AddMigrationRecord(version int64) error { func (m *MigrationVersion03) AddMigrationRecord(version int64) error {
o := orm.NewOrm() o := orm.NewOrm()
tables,err := ExportDatabaseTable() tables, err := ExportDatabaseTable()
if err != nil { if err != nil {
return err return err
@ -94,8 +92,8 @@ func (m *MigrationVersion03) AddMigrationRecord(version int64) error {
migration.Version = version migration.Version = version
migration.Status = "update" migration.Status = "update"
migration.CreateTime = time.Now() migration.CreateTime = time.Now()
migration.Name = fmt.Sprintf("update_%d",version) migration.Name = fmt.Sprintf("update_%d", version)
migration.Statements = strings.Join(tables,"\r\n") migration.Statements = strings.Join(tables, "\r\n")
_, err = o.Insert(migration) _, err = o.Insert(migration)
@ -112,16 +110,16 @@ func (m *MigrationVersion03) RollbackMigration() error {
return errors.New("The current version failed to verify.") return errors.New("The current version failed to verify.")
} }
o := orm.NewOrm() o := orm.NewOrm()
_,err := o.Raw("ALTER TABLE md_members DROP COLUMN auth_method").Exec() _, err := o.Raw("ALTER TABLE md_members DROP COLUMN auth_method").Exec()
if err != nil { if err != nil {
return err return err
} }
_,err = o.Raw("DROP TABLE md_document_history").Exec() _, err = o.Raw("DROP TABLE md_document_history").Exec()
if err != nil { if err != nil {
return err return err
} }
_,err = o.Raw("DELETE md_options WHERE option_name = 'ENABLE_DOCUMENT_HISTORY'").Exec() _, err = o.Raw("DELETE md_options WHERE option_name = 'ENABLE_DOCUMENT_HISTORY'").Exec()
if err != nil { if err != nil {
return err return err
@ -129,11 +127,3 @@ func (m *MigrationVersion03) RollbackMigration() error {
return nil return nil
} }

View File

@ -20,7 +20,7 @@ const RegexpEmail = "^[a-zA-Z0-9.!#$%&'*+\\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-
const RegexpAccount = `^[a-zA-Z][a-zA-z0-9\.]{2,50}$` const RegexpAccount = `^[a-zA-Z][a-zA-z0-9\.]{2,50}$`
// PageSize 默认分页条数. // PageSize 默认分页条数.
const PageSize = 15 const PageSize = 10
// 用户权限 // 用户权限
const ( const (
@ -55,12 +55,20 @@ const (
//LDAP用户校验 //LDAP用户校验
AuthMethodLDAP = "ldap" AuthMethodLDAP = "ldap"
) )
var ( var (
VERSION string VERSION string
BUILD_TIME string BUILD_TIME string
GO_VERSION string GO_VERSION string
) )
var (
ConfigurationFile = "./conf/app.conf"
WorkingDirectory = "./"
LogFile = "./logs"
BaseUrl = ""
)
// app_key // app_key
func GetAppKey() string { func GetAppKey() string {
return beego.AppConfig.DefaultString("app_key", "godoc") return beego.AppConfig.DefaultString("app_key", "godoc")
@ -102,26 +110,27 @@ func GetUploadFileExt() []string {
} }
return exts return exts
} }
// 获取上传文件允许的最大值 // 获取上传文件允许的最大值
func GetUploadFileSize() int64 { func GetUploadFileSize() int64 {
size := beego.AppConfig.DefaultString("upload_file_size","0") size := beego.AppConfig.DefaultString("upload_file_size", "0")
if strings.HasSuffix(size,"MB") { if strings.HasSuffix(size, "MB") {
if s,e := strconv.ParseInt(size[0:len(size) - 2], 10, 64);e == nil { if s, e := strconv.ParseInt(size[0:len(size)-2], 10, 64); e == nil {
return s * 1024 * 1024 return s * 1024 * 1024
} }
} }
if strings.HasSuffix(size,"GB") { if strings.HasSuffix(size, "GB") {
if s,e := strconv.ParseInt(size[0:len(size) - 2], 10, 64);e == nil { if s, e := strconv.ParseInt(size[0:len(size)-2], 10, 64); e == nil {
return s * 1024 * 1024 * 1024 return s * 1024 * 1024 * 1024
} }
} }
if strings.HasSuffix(size,"KB") { if strings.HasSuffix(size, "KB") {
if s,e := strconv.ParseInt(size[0:len(size) - 2], 10, 64);e == nil { if s, e := strconv.ParseInt(size[0:len(size)-2], 10, 64); e == nil {
return s * 1024 return s * 1024
} }
} }
if s,e := strconv.ParseInt(size, 10, 64);e == nil { if s, e := strconv.ParseInt(size, 10, 64); e == nil {
return s * 1024 return s * 1024
} }
return 0 return 0

View File

@ -20,19 +20,19 @@ func GetMailConfig() *SmtpConf {
user_name := beego.AppConfig.String("smtp_user_name") user_name := beego.AppConfig.String("smtp_user_name")
password := beego.AppConfig.String("smtp_password") password := beego.AppConfig.String("smtp_password")
smtp_host := beego.AppConfig.String("smtp_host") smtp_host := beego.AppConfig.String("smtp_host")
smtp_port := beego.AppConfig.DefaultInt("smtp_port",25) smtp_port := beego.AppConfig.DefaultInt("smtp_port", 25)
form_user_name := beego.AppConfig.String("form_user_name") form_user_name := beego.AppConfig.String("form_user_name")
enable_mail := beego.AppConfig.String("enable_mail") enable_mail := beego.AppConfig.String("enable_mail")
mail_number := beego.AppConfig.DefaultInt("mail_number",5) mail_number := beego.AppConfig.DefaultInt("mail_number", 5)
c := &SmtpConf{ c := &SmtpConf{
EnableMail : strings.EqualFold(enable_mail,"true"), EnableMail: strings.EqualFold(enable_mail, "true"),
MailNumber: mail_number, MailNumber: mail_number,
SmtpUserName:user_name, SmtpUserName: user_name,
SmtpHost:smtp_host, SmtpHost: smtp_host,
SmtpPassword:password, SmtpPassword: password,
FormUserName:form_user_name, FormUserName: form_user_name,
SmtpPort:smtp_port, SmtpPort: smtp_port,
} }
return c return c
} }

View File

@ -14,6 +14,7 @@ import (
"github.com/lifei6671/mindoc/conf" "github.com/lifei6671/mindoc/conf"
"github.com/lifei6671/mindoc/models" "github.com/lifei6671/mindoc/models"
"github.com/lifei6671/mindoc/utils" "github.com/lifei6671/mindoc/utils"
"net/url"
) )
// AccountController 用户登录与注册 // AccountController 用户登录与注册
@ -32,13 +33,16 @@ func (c *AccountController) Login() {
Time time.Time Time time.Time
} }
// 显式指定的 URL 参数优先;为了统一处理,将之更新到 Session 中 if member, ok := c.GetSession(conf.LoginSessionName).(models.Member); ok && member.MemberId > 0 {
turl := c.GetString("turl", "") u := c.GetString("url")
if turl != "" { if u == "" {
c.SetSession("turl", turl) u = c.Ctx.Request.Header.Get("Referer")
}
if u == "" {
u = beego.URLFor("HomeController.Index")
}
c.Redirect(u,302)
} }
beego.Info("AccountController.Login(): turl is: " + turl)
// 如果 Cookie 中存在登录信息 // 如果 Cookie 中存在登录信息
if cookie, ok := c.GetSecureCookie(conf.GetAppKey(), "login"); ok { if cookie, ok := c.GetSecureCookie(conf.GetAppKey(), "login"); ok {
@ -81,26 +85,35 @@ func (c *AccountController) Login() {
c.SetSecureCookie(conf.GetAppKey(), "login", v) c.SetSecureCookie(conf.GetAppKey(), "login", v)
} }
} }
u,_ := url.PathUnescape(c.GetString("url"))
if u == "" {
u = c.Ctx.Request.Header.Get("Referer")
}
if u == "" {
u = beego.URLFor("HomeController.Index")
}
data := c.LoggedIn(true) c.JsonResult(0, "ok", u)
c.JsonResult(0, "ok", data)
} else { } else {
logs.Error("用户登录 =>", err) logs.Error("用户登录 =>", err)
c.JsonResult(500, "账号或密码错误", nil) c.JsonResult(500, "账号或密码错误", nil)
} }
}else{
u,_ := url.PathUnescape(c.GetString("url"))
if u == "" {
u = c.Ctx.Request.Header.Get("Referer")
}
if u == "" {
u = beego.URLFor("HomeController.Index")
}
c.Data["url"] = url.PathEscape(u)
} }
} }
// 登录成功后的操作,如重定向到原始请求页面 // 登录成功后的操作,如重定向到原始请求页面
func (c *AccountController) LoggedIn(isPost bool) interface{} { func (c *AccountController) LoggedIn(isPost bool) interface{} {
turl := ""
value := c.GetSession("turl")
if value != nil {
turl = value.(string)
}
c.DelSession("turl")
beego.Info("AccountController.LoggedIn(): turl is: " + turl) turl := c.GetString("url")
if !isPost { if !isPost {
// 检查是否存在 turl 参数,如果有则重定向至 turl 处,否则进入 Home 页面 // 检查是否存在 turl 参数,如果有则重定向至 turl 处,否则进入 Home 页面
@ -111,7 +124,7 @@ func (c *AccountController) LoggedIn(isPost bool) interface{} {
return nil return nil
} else { } else {
var data struct { var data struct {
TURL string `json:"turl"` TURL string `json:"url"`
} }
data.TURL = turl data.TURL = turl
return data return data
@ -369,7 +382,9 @@ func (c *AccountController) Logout() {
c.SetSecureCookie(conf.GetAppKey(), "login", "", -3600) c.SetSecureCookie(conf.GetAppKey(), "login", "", -3600)
c.Redirect(beego.URLFor("AccountController.Login"), 302) u := c.Ctx.Request.Header.Get("Referer")
c.Redirect(beego.URLFor("AccountController.Login","url",u), 302)
} }
// 验证码 // 验证码

View File

@ -1,18 +1,16 @@
package controllers package controllers
import ( import (
"bytes" "bytes"
"github.com/lifei6671/mindoc/models"
"github.com/lifei6671/mindoc/conf"
"github.com/astaxie/beego"
"strings"
"encoding/json" "encoding/json"
"github.com/astaxie/beego"
"github.com/lifei6671/mindoc/conf"
"github.com/lifei6671/mindoc/models"
"io" "io"
"strings"
) )
type BaseController struct { type BaseController struct {
beego.Controller beego.Controller
Member *models.Member Member *models.Member
@ -22,32 +20,33 @@ type BaseController struct {
} }
// Prepare 预处理. // Prepare 预处理.
func (c *BaseController) Prepare (){ func (c *BaseController) Prepare() {
c.Data["SiteName"] = "MinDoc" c.Data["SiteName"] = "MinDoc"
c.Data["Member"] = models.Member{} c.Data["Member"] = models.Member{}
c.EnableAnonymous = false c.EnableAnonymous = false
c.EnableDocumentHistory = false c.EnableDocumentHistory = false
if member,ok := c.GetSession(conf.LoginSessionName).(models.Member); ok && member.MemberId > 0{ if member, ok := c.GetSession(conf.LoginSessionName).(models.Member); ok && member.MemberId > 0 {
c.Member = &member c.Member = &member
c.Data["Member"] = c.Member c.Data["Member"] = c.Member
}else{ } else {
//c.Member = models.NewMember() //c.Member = models.NewMember()
//c.Member.Find(1) //c.Member.Find(1)
//c.Data["Member"] = *c.Member //c.Data["Member"] = *c.Member
} }
c.Data["BaseUrl"] = c.Ctx.Input.Scheme() + "://" + c.Ctx.Request.Host conf.BaseUrl = c.BaseUrl()
c.Data["BaseUrl"] = c.BaseUrl()
if options,err := models.NewOption().All();err == nil { if options, err := models.NewOption().All(); err == nil {
c.Option = make(map[string]string,len(options)) c.Option = make(map[string]string, len(options))
for _,item := range options { for _, item := range options {
c.Data[item.OptionName] = item.OptionValue c.Data[item.OptionName] = item.OptionValue
c.Option[item.OptionName] = item.OptionValue c.Option[item.OptionName] = item.OptionValue
if strings.EqualFold(item.OptionName,"ENABLE_ANONYMOUS") && item.OptionValue == "true" { if strings.EqualFold(item.OptionName, "ENABLE_ANONYMOUS") && item.OptionValue == "true" {
c.EnableAnonymous = true c.EnableAnonymous = true
} }
if strings.EqualFold(item.OptionName,"ENABLE_DOCUMENT_HISTORY") && item.OptionValue == "true" { if strings.EqualFold(item.OptionName, "ENABLE_DOCUMENT_HISTORY") && item.OptionValue == "true" {
c.EnableDocumentHistory = true c.EnableDocumentHistory = true
} }
} }
@ -68,13 +67,13 @@ func (c *BaseController) SetMember(member models.Member) {
} }
// JsonResult 响应 json 结果 // JsonResult 响应 json 结果
func (c *BaseController) JsonResult(errCode int,errMsg string,data ...interface{}){ func (c *BaseController) JsonResult(errCode int, errMsg string, data ...interface{}) {
jsonData := make(map[string]interface{},3) jsonData := make(map[string]interface{}, 3)
jsonData["errcode"] = errCode jsonData["errcode"] = errCode
jsonData["message"] = errMsg jsonData["message"] = errMsg
if len(data) > 0 && data[0] != nil{ if len(data) > 0 && data[0] != nil {
jsonData["data"] = data[0] jsonData["data"] = data[0]
} }
@ -86,13 +85,13 @@ func (c *BaseController) JsonResult(errCode int,errMsg string,data ...interface{
c.Ctx.ResponseWriter.Header().Set("Content-Type", "application/json; charset=utf-8") c.Ctx.ResponseWriter.Header().Set("Content-Type", "application/json; charset=utf-8")
io.WriteString(c.Ctx.ResponseWriter,string(returnJSON)) io.WriteString(c.Ctx.ResponseWriter, string(returnJSON))
c.StopRun() c.StopRun()
} }
// ExecuteViewPathTemplate 执行指定的模板并返回执行结果. // ExecuteViewPathTemplate 执行指定的模板并返回执行结果.
func (c *BaseController) ExecuteViewPathTemplate(tplName string,data interface{}) (string,error){ func (c *BaseController) ExecuteViewPathTemplate(tplName string, data interface{}) (string, error) {
var buf bytes.Buffer var buf bytes.Buffer
viewPath := c.ViewPath viewPath := c.ViewPath
@ -102,26 +101,26 @@ func (c *BaseController) ExecuteViewPathTemplate(tplName string,data interface{}
} }
if err := beego.ExecuteViewPathTemplate(&buf,tplName,viewPath,data); err != nil { if err := beego.ExecuteViewPathTemplate(&buf, tplName, viewPath, data); err != nil {
return "",err return "", err
} }
return buf.String(),nil return buf.String(), nil
} }
func (c *BaseController) BaseUrl() string { func (c *BaseController) BaseUrl() string {
baseUrl := beego.AppConfig.DefaultString("baseurl","") baseUrl := beego.AppConfig.DefaultString("baseurl", "")
if baseUrl != "" { if baseUrl != "" {
if strings.HasSuffix(baseUrl,"/"){ if strings.HasSuffix(baseUrl, "/") {
baseUrl = strings.TrimSuffix(baseUrl,"/") baseUrl = strings.TrimSuffix(baseUrl, "/")
} }
}else{ } else {
baseUrl = c.Ctx.Input.Scheme() + "://" + c.Ctx.Request.Host baseUrl = c.Ctx.Input.Scheme() + "://" + c.Ctx.Request.Host
} }
return baseUrl return baseUrl
} }
//显示错误信息页面. //显示错误信息页面.
func (c *BaseController) ShowErrorPage(errCode int,errMsg string) { func (c *BaseController) ShowErrorPage(errCode int, errMsg string) {
c.TplName = "errors/error.tpl" c.TplName = "errors/error.tpl"
c.Data["ErrorMessage"] = errMsg c.Data["ErrorMessage"] = errMsg
c.Data["ErrorCode"] = errCode c.Data["ErrorCode"] = errCode

View File

@ -1,25 +1,24 @@
package controllers package controllers
import ( import (
"strings"
"regexp"
"strconv"
"time"
"encoding/json" "encoding/json"
"html/template"
"errors" "errors"
"fmt" "fmt"
"path/filepath" "html/template"
"os" "os"
"path/filepath"
"regexp"
"strconv"
"strings"
"time"
"github.com/lifei6671/mindoc/models"
"github.com/lifei6671/mindoc/utils"
"github.com/astaxie/beego" "github.com/astaxie/beego"
"github.com/astaxie/beego/orm"
"github.com/astaxie/beego/logs" "github.com/astaxie/beego/logs"
"github.com/astaxie/beego/orm"
"github.com/lifei6671/mindoc/conf" "github.com/lifei6671/mindoc/conf"
"github.com/lifei6671/mindoc/graphics" "github.com/lifei6671/mindoc/graphics"
"github.com/lifei6671/mindoc/commands" "github.com/lifei6671/mindoc/models"
"github.com/lifei6671/mindoc/utils"
) )
type BookController struct { type BookController struct {
@ -32,10 +31,10 @@ func (c *BookController) Index() {
pageIndex, _ := c.GetInt("page", 1) pageIndex, _ := c.GetInt("page", 1)
books,totalCount,err := models.NewBook().FindToPager(pageIndex,conf.PageSize,c.Member.MemberId) books, totalCount, err := models.NewBook().FindToPager(pageIndex, conf.PageSize, c.Member.MemberId)
if err != nil { if err != nil {
logs.Error("BookController.Index => ",err) logs.Error("BookController.Index => ", err)
c.Abort("500") c.Abort("500")
} }
@ -43,14 +42,14 @@ func (c *BookController) Index() {
html := utils.GetPagerHtml(c.Ctx.Request.RequestURI, pageIndex, conf.PageSize, totalCount) html := utils.GetPagerHtml(c.Ctx.Request.RequestURI, pageIndex, conf.PageSize, totalCount)
c.Data["PageHtml"] = html c.Data["PageHtml"] = html
}else { } else {
c.Data["PageHtml"] = "" c.Data["PageHtml"] = ""
} }
b,err := json.Marshal(books) b, err := json.Marshal(books)
if err != nil || len(books) <= 0{ if err != nil || len(books) <= 0 {
c.Data["Result"] = template.JS("[]") c.Data["Result"] = template.JS("[]")
}else{ } else {
c.Data["Result"] = template.JS(string(b)) c.Data["Result"] = template.JS(string(b))
} }
} }
@ -62,11 +61,11 @@ func (c *BookController) Dashboard() {
key := c.Ctx.Input.Param(":key") key := c.Ctx.Input.Param(":key")
if key == ""{ if key == "" {
c.Abort("404") c.Abort("404")
} }
book,err := models.NewBookResult().FindByIdentify(key,c.Member.MemberId) book, err := models.NewBookResult().FindByIdentify(key, c.Member.MemberId)
if err != nil { if err != nil {
if err == models.ErrPermissionDenied { if err == models.ErrPermissionDenied {
c.Abort("403") c.Abort("403")
@ -85,11 +84,11 @@ func (c *BookController) Setting() {
key := c.Ctx.Input.Param(":key") key := c.Ctx.Input.Param(":key")
if key == ""{ if key == "" {
c.Abort("404") c.Abort("404")
} }
book,err := models.NewBookResult().FindByIdentify(key,c.Member.MemberId) book, err := models.NewBookResult().FindByIdentify(key, c.Member.MemberId)
if err != nil { if err != nil {
if err == orm.ErrNoRows { if err == orm.ErrNoRows {
c.Abort("404") c.Abort("404")
@ -104,7 +103,7 @@ func (c *BookController) Setting() {
c.Abort("403") c.Abort("403")
} }
if book.PrivateToken != "" { if book.PrivateToken != "" {
book.PrivateToken = c.BaseUrl() + beego.URLFor("DocumentController.Index",":key",book.Identify,"token",book.PrivateToken) book.PrivateToken = c.BaseUrl() + beego.URLFor("DocumentController.Index", ":key", book.Identify, "token", book.PrivateToken)
} }
c.Data["Model"] = book c.Data["Model"] = book
@ -112,35 +111,35 @@ func (c *BookController) Setting() {
//保存项目信息 //保存项目信息
func (c *BookController) SaveBook() { func (c *BookController) SaveBook() {
bookResult,err := c.IsPermission() bookResult, err := c.IsPermission()
if err != nil { if err != nil {
c.JsonResult(6001,err.Error()) c.JsonResult(6001, err.Error())
} }
book,err := models.NewBook().Find(bookResult.BookId) book, err := models.NewBook().Find(bookResult.BookId)
if err != nil { if err != nil {
logs.Error("SaveBook => ",err) logs.Error("SaveBook => ", err)
c.JsonResult(6002,err.Error()) c.JsonResult(6002, err.Error())
} }
book_name := strings.TrimSpace(c.GetString("book_name")) book_name := strings.TrimSpace(c.GetString("book_name"))
description := strings.TrimSpace(c.GetString("description","")) description := strings.TrimSpace(c.GetString("description", ""))
comment_status := c.GetString("comment_status") comment_status := c.GetString("comment_status")
tag := strings.TrimSpace(c.GetString("label")) tag := strings.TrimSpace(c.GetString("label"))
editor := strings.TrimSpace(c.GetString("editor")) editor := strings.TrimSpace(c.GetString("editor"))
auto_release := strings.TrimSpace(c.GetString("auto_release")) == "on" auto_release := strings.TrimSpace(c.GetString("auto_release")) == "on"
if strings.Count(description,"") > 500 { if strings.Count(description, "") > 500 {
c.JsonResult(6004,"项目描述不能大于500字") c.JsonResult(6004, "项目描述不能大于500字")
} }
if comment_status != "open" && comment_status != "closed" && comment_status != "group_only" && comment_status != "registered_only" { if comment_status != "open" && comment_status != "closed" && comment_status != "group_only" && comment_status != "registered_only" {
comment_status = "closed" comment_status = "closed"
} }
if tag != ""{ if tag != "" {
tags := strings.Split(tag,",") tags := strings.Split(tag, ",")
if len(tags) > 10 { if len(tags) > 10 {
c.JsonResult(6005,"最多允许添加10个标签") c.JsonResult(6005, "最多允许添加10个标签")
} }
} }
if editor != "markdown" && editor != "html" { if editor != "markdown" && editor != "html" {
@ -154,19 +153,18 @@ func (c *BookController) SaveBook() {
book.Editor = editor book.Editor = editor
if auto_release { if auto_release {
book.AutoRelease = 1 book.AutoRelease = 1
}else{ } else {
book.AutoRelease = 0 book.AutoRelease = 0
} }
if err := book.Update(); err != nil {
if err := book.Update();err != nil { c.JsonResult(6006, "保存失败")
c.JsonResult(6006,"保存失败")
} }
bookResult.BookName = book_name bookResult.BookName = book_name
bookResult.Description = description bookResult.Description = description
bookResult.CommentStatus = comment_status bookResult.CommentStatus = comment_status
bookResult.Label = tag bookResult.Label = tag
c.JsonResult(0,"ok",bookResult) c.JsonResult(0, "ok", bookResult)
} }
//设置项目私有状态. //设置项目私有状态.
@ -175,39 +173,39 @@ func (c *BookController) PrivatelyOwned() {
status := c.GetString("status") status := c.GetString("status")
if status != "open" && status != "close" { if status != "open" && status != "close" {
c.JsonResult(6003,"参数错误") c.JsonResult(6003, "参数错误")
} }
state := 0 state := 0
if status == "open" { if status == "open" {
state = 0 state = 0
}else{ } else {
state = 1 state = 1
} }
bookResult,err := c.IsPermission() bookResult, err := c.IsPermission()
if err != nil { if err != nil {
c.JsonResult(6001,err.Error()) c.JsonResult(6001, err.Error())
} }
//只有创始人才能变更私有状态 //只有创始人才能变更私有状态
if bookResult.RoleId != conf.BookFounder { if bookResult.RoleId != conf.BookFounder {
c.JsonResult(6002,"权限不足") c.JsonResult(6002, "权限不足")
} }
book,err := models.NewBook().Find(bookResult.BookId) book, err := models.NewBook().Find(bookResult.BookId)
if err != nil { if err != nil {
c.JsonResult(6005,"项目不存在") c.JsonResult(6005, "项目不存在")
} }
book.PrivatelyOwned = state book.PrivatelyOwned = state
err = book.Update() err = book.Update()
if err != nil { if err != nil {
logs.Error("PrivatelyOwned => ",err) logs.Error("PrivatelyOwned => ", err)
c.JsonResult(6004,"保存失败") c.JsonResult(6004, "保存失败")
} }
c.JsonResult(0,"ok") c.JsonResult(0, "ok")
} }
// Transfer 转让项目. // Transfer 转让项目.
@ -216,68 +214,68 @@ func (c *BookController) Transfer() {
account := c.GetString("account") account := c.GetString("account")
if account == "" { if account == "" {
c.JsonResult(6004,"接受者账号不能为空") c.JsonResult(6004, "接受者账号不能为空")
} }
member,err := models.NewMember().FindByAccount(account) member, err := models.NewMember().FindByAccount(account)
if err != nil { if err != nil {
logs.Error("FindByAccount => ",err) logs.Error("FindByAccount => ", err)
c.JsonResult(6005,"接受用户不存在") c.JsonResult(6005, "接受用户不存在")
} }
if member.Status != 0 { if member.Status != 0 {
c.JsonResult(6006,"接受用户已被禁用") c.JsonResult(6006, "接受用户已被禁用")
} }
if member.MemberId == c.Member.MemberId { if member.MemberId == c.Member.MemberId {
c.JsonResult(6007,"不能转让给自己") c.JsonResult(6007, "不能转让给自己")
} }
bookResult,err := c.IsPermission() bookResult, err := c.IsPermission()
if err != nil { if err != nil {
c.JsonResult(6001,err.Error()) c.JsonResult(6001, err.Error())
} }
err = models.NewRelationship().Transfer(bookResult.BookId,c.Member.MemberId,member.MemberId) err = models.NewRelationship().Transfer(bookResult.BookId, c.Member.MemberId, member.MemberId)
if err != nil { if err != nil {
logs.Error("Transfer => ",err) logs.Error("Transfer => ", err)
c.JsonResult(6008,err.Error()) c.JsonResult(6008, err.Error())
} }
c.JsonResult(0,"ok") c.JsonResult(0, "ok")
} }
//上传项目封面. //上传项目封面.
func (c *BookController) UploadCover() { func (c *BookController) UploadCover() {
bookResult,err := c.IsPermission() bookResult, err := c.IsPermission()
if err != nil { if err != nil {
c.JsonResult(6001,err.Error()) c.JsonResult(6001, err.Error())
} }
book,err := models.NewBook().Find(bookResult.BookId) book, err := models.NewBook().Find(bookResult.BookId)
if err != nil { if err != nil {
logs.Error("SaveBook => ",err) logs.Error("SaveBook => ", err)
c.JsonResult(6002,err.Error()) c.JsonResult(6002, err.Error())
} }
file,moreFile,err := c.GetFile("image-file") file, moreFile, err := c.GetFile("image-file")
defer file.Close() defer file.Close()
if err != nil { if err != nil {
logs.Error("",err.Error()) logs.Error("", err.Error())
c.JsonResult(500,"读取文件异常") c.JsonResult(500, "读取文件异常")
} }
ext := filepath.Ext(moreFile.Filename) ext := filepath.Ext(moreFile.Filename)
if !strings.EqualFold(ext,".png") && !strings.EqualFold(ext,".jpg") && !strings.EqualFold(ext,".gif") && !strings.EqualFold(ext,".jpeg") { if !strings.EqualFold(ext, ".png") && !strings.EqualFold(ext, ".jpg") && !strings.EqualFold(ext, ".gif") && !strings.EqualFold(ext, ".jpeg") {
c.JsonResult(500,"不支持的图片格式") c.JsonResult(500, "不支持的图片格式")
} }
x1, _ := strconv.ParseFloat(c.GetString("x"), 10)
x1 ,_ := strconv.ParseFloat(c.GetString("x"),10) y1, _ := strconv.ParseFloat(c.GetString("y"), 10)
y1 ,_ := strconv.ParseFloat(c.GetString("y"),10) w1, _ := strconv.ParseFloat(c.GetString("width"), 10)
w1 ,_ := strconv.ParseFloat(c.GetString("width"),10) h1, _ := strconv.ParseFloat(c.GetString("height"), 10)
h1 ,_ := strconv.ParseFloat(c.GetString("height"),10)
x := int(x1) x := int(x1)
y := int(y1) y := int(y1)
@ -286,43 +284,43 @@ func (c *BookController) UploadCover() {
fileName := "cover_" + strconv.FormatInt(time.Now().UnixNano(), 16) fileName := "cover_" + strconv.FormatInt(time.Now().UnixNano(), 16)
filePath := filepath.Join("uploads",time.Now().Format("200601"),fileName + ext) filePath := filepath.Join("uploads", time.Now().Format("200601"), fileName+ext)
path := filepath.Dir(filePath) path := filepath.Dir(filePath)
os.MkdirAll(path, os.ModePerm) os.MkdirAll(path, os.ModePerm)
err = c.SaveToFile("image-file",filePath) err = c.SaveToFile("image-file", filePath)
if err != nil { if err != nil {
logs.Error("",err) logs.Error("", err)
c.JsonResult(500,"图片保存失败") c.JsonResult(500, "图片保存失败")
} }
defer func(filePath string) { defer func(filePath string) {
os.Remove(filePath) os.Remove(filePath)
}(filePath) }(filePath)
//剪切图片 //剪切图片
subImg,err := graphics.ImageCopyFromFile(filePath,x,y,width,height) subImg, err := graphics.ImageCopyFromFile(filePath, x, y, width, height)
if err != nil{
logs.Error("graphics.ImageCopyFromFile => ",err)
c.JsonResult(500,"图片剪切")
}
filePath = filepath.Join(commands.WorkingDirectory,"uploads",time.Now().Format("200601"),fileName + "_small" + ext)
//生成缩略图并保存到磁盘
err = graphics.ImageResizeSaveFile(subImg,175,230,filePath)
if err != nil { if err != nil {
logs.Error("ImageResizeSaveFile => ",err.Error()) logs.Error("graphics.ImageCopyFromFile => ", err)
c.JsonResult(500,"保存图片失败") c.JsonResult(500, "图片剪切")
} }
url := "/" + strings.Replace(strings.TrimPrefix(filePath,commands.WorkingDirectory),"\\","/",-1) filePath = filepath.Join(conf.WorkingDirectory, "uploads", time.Now().Format("200601"), fileName+"_small"+ext)
if strings.HasPrefix(url,"//") { //生成缩略图并保存到磁盘
err = graphics.ImageResizeSaveFile(subImg, 175, 230, filePath)
if err != nil {
logs.Error("ImageResizeSaveFile => ", err.Error())
c.JsonResult(500, "保存图片失败")
}
url := "/" + strings.Replace(strings.TrimPrefix(filePath, conf.WorkingDirectory), "\\", "/", -1)
if strings.HasPrefix(url, "//") {
url = string(url[1:]) url = string(url[1:])
} }
@ -330,15 +328,15 @@ func (c *BookController) UploadCover() {
book.Cover = url book.Cover = url
if err := book.Update() ; err != nil { if err := book.Update(); err != nil {
c.JsonResult(6001,"保存图片失败") c.JsonResult(6001, "保存图片失败")
} }
//如果原封面不是默认封面则删除 //如果原封面不是默认封面则删除
if old_cover != conf.GetDefaultCover() { if old_cover != conf.GetDefaultCover() {
os.Remove("." + old_cover) os.Remove("." + old_cover)
} }
c.JsonResult(0,"ok",url) c.JsonResult(0, "ok", url)
} }
// Users 用户列表. // Users 用户列表.
@ -347,13 +345,13 @@ func (c *BookController) Users() {
c.TplName = "book/users.tpl" c.TplName = "book/users.tpl"
key := c.Ctx.Input.Param(":key") key := c.Ctx.Input.Param(":key")
pageIndex,_ := c.GetInt("page",1) pageIndex, _ := c.GetInt("page", 1)
if key == ""{ if key == "" {
c.Abort("404") c.Abort("404")
} }
book,err := models.NewBookResult().FindByIdentify(key,c.Member.MemberId) book, err := models.NewBookResult().FindByIdentify(key, c.Member.MemberId)
if err != nil { if err != nil {
if err == models.ErrPermissionDenied { if err == models.ErrPermissionDenied {
c.Abort("403") c.Abort("403")
@ -363,20 +361,20 @@ func (c *BookController) Users() {
c.Data["Model"] = *book c.Data["Model"] = *book
members,totalCount,err := models.NewMemberRelationshipResult().FindForUsersByBookId(book.BookId,pageIndex,15) members, totalCount, err := models.NewMemberRelationshipResult().FindForUsersByBookId(book.BookId, pageIndex, 15)
if totalCount > 0 { if totalCount > 0 {
html := utils.GetPagerHtml(c.Ctx.Request.RequestURI, pageIndex, 10, totalCount) html := utils.GetPagerHtml(c.Ctx.Request.RequestURI, pageIndex, 10, totalCount)
c.Data["PageHtml"] = html c.Data["PageHtml"] = html
}else{ } else {
c.Data["PageHtml"] = "" c.Data["PageHtml"] = ""
} }
b,err := json.Marshal(members) b, err := json.Marshal(members)
if err != nil { if err != nil {
c.Data["Result"] = template.JS("[]") c.Data["Result"] = template.JS("[]")
}else{ } else {
c.Data["Result"] = template.JS(string(b)) c.Data["Result"] = template.JS(string(b))
} }
} }
@ -385,28 +383,28 @@ func (c *BookController) Users() {
func (c *BookController) Create() { func (c *BookController) Create() {
if c.Ctx.Input.IsPost() { if c.Ctx.Input.IsPost() {
book_name := strings.TrimSpace(c.GetString("book_name","")) book_name := strings.TrimSpace(c.GetString("book_name", ""))
identify := strings.TrimSpace(c.GetString("identify","")) identify := strings.TrimSpace(c.GetString("identify", ""))
description := strings.TrimSpace(c.GetString("description","")) description := strings.TrimSpace(c.GetString("description", ""))
privately_owned,_ := strconv.Atoi(c.GetString("privately_owned")) privately_owned, _ := strconv.Atoi(c.GetString("privately_owned"))
comment_status := c.GetString("comment_status") comment_status := c.GetString("comment_status")
if book_name == "" { if book_name == "" {
c.JsonResult(6001,"项目名称不能为空") c.JsonResult(6001, "项目名称不能为空")
} }
if identify == "" { if identify == "" {
c.JsonResult(6002,"项目标识不能为空") c.JsonResult(6002, "项目标识不能为空")
} }
if ok,err := regexp.MatchString(`^[a-z]+[a-zA-Z0-9_\-]*$`,identify); !ok || err != nil { if ok, err := regexp.MatchString(`^[a-z]+[a-zA-Z0-9_\-]*$`, identify); !ok || err != nil {
c.JsonResult(6003,"项目标识只能包含小写字母、数字,以及“-”和“_”符号,并且只能小写字母开头") c.JsonResult(6003, "项目标识只能包含小写字母、数字,以及“-”和“_”符号,并且只能小写字母开头")
} }
if strings.Count(identify,"") > 50 { if strings.Count(identify, "") > 50 {
c.JsonResult(6004,"文档标识不能超过50字") c.JsonResult(6004, "文档标识不能超过50字")
} }
if strings.Count(description,"") > 500 { if strings.Count(description, "") > 500 {
c.JsonResult(6004,"项目描述不能大于500字") c.JsonResult(6004, "项目描述不能大于500字")
} }
if privately_owned !=0 && privately_owned != 1 { if privately_owned != 0 && privately_owned != 1 {
privately_owned = 1 privately_owned = 1
} }
if comment_status != "open" && comment_status != "closed" && comment_status != "group_only" && comment_status != "registered_only" { if comment_status != "open" && comment_status != "closed" && comment_status != "group_only" && comment_status != "registered_only" {
@ -415,8 +413,8 @@ func (c *BookController) Create() {
book := models.NewBook() book := models.NewBook()
if books,_ := book.FindByField("identify",identify); len(books) > 0 { if books, _ := book.FindByField("identify", identify); len(books) > 0 {
c.JsonResult(6006,"项目标识已存在") c.JsonResult(6006, "项目标识已存在")
} }
book.BookName = book_name book.BookName = book_name
@ -436,18 +434,18 @@ func (c *BookController) Create() {
err := book.Insert() err := book.Insert()
if err != nil { if err != nil {
logs.Error("Insert => ",err) logs.Error("Insert => ", err)
c.JsonResult(6005,"保存项目失败") c.JsonResult(6005, "保存项目失败")
} }
bookResult,err := models.NewBookResult().FindByIdentify(book.Identify,c.Member.MemberId) bookResult, err := models.NewBookResult().FindByIdentify(book.Identify, c.Member.MemberId)
if err != nil { if err != nil {
beego.Error(err) beego.Error(err)
} }
c.JsonResult(0,"ok",bookResult) c.JsonResult(0, "ok", bookResult)
} }
c.JsonResult(6001,"error") c.JsonResult(6001, "error")
} }
// CreateToken 创建访问来令牌. // CreateToken 创建访问来令牌.
@ -455,22 +453,22 @@ func (c *BookController) CreateToken() {
action := c.GetString("action") action := c.GetString("action")
bookResult ,err := c.IsPermission() bookResult, err := c.IsPermission()
if err != nil { if err != nil {
if err == models.ErrPermissionDenied { if err == models.ErrPermissionDenied {
c.JsonResult(403,"权限不足") c.JsonResult(403, "权限不足")
} }
if err == orm.ErrNoRows { if err == orm.ErrNoRows {
c.JsonResult(404,"项目不存在") c.JsonResult(404, "项目不存在")
} }
logs.Error("生成阅读令牌失败 =>",err) logs.Error("生成阅读令牌失败 =>", err)
c.JsonResult(6002,err.Error()) c.JsonResult(6002, err.Error())
} }
book := models.NewBook() book := models.NewBook()
if _,err := book.Find(bookResult.BookId);err != nil { if _, err := book.Find(bookResult.BookId); err != nil {
c.JsonResult(6001,"项目不存在") c.JsonResult(6001, "项目不存在")
} }
if action == "create" { if action == "create" {
if bookResult.PrivatelyOwned == 0 { if bookResult.PrivatelyOwned == 0 {
@ -482,14 +480,14 @@ func (c *BookController) CreateToken() {
logs.Error("生成阅读令牌失败 => ", err) logs.Error("生成阅读令牌失败 => ", err)
c.JsonResult(6003, "生成阅读令牌失败") c.JsonResult(6003, "生成阅读令牌失败")
} }
c.JsonResult(0, "ok", c.BaseUrl() + beego.URLFor("DocumentController.Index",":key",book.Identify,"token",book.PrivateToken)) c.JsonResult(0, "ok", c.BaseUrl()+beego.URLFor("DocumentController.Index", ":key", book.Identify, "token", book.PrivateToken))
}else{ } else {
book.PrivateToken = "" book.PrivateToken = ""
if err := book.Update();err != nil { if err := book.Update(); err != nil {
logs.Error("CreateToken => ",err) logs.Error("CreateToken => ", err)
c.JsonResult(6004,"删除令牌失败") c.JsonResult(6004, "删除令牌失败")
} }
c.JsonResult(0,"ok","") c.JsonResult(0, "ok", "")
} }
} }
@ -497,25 +495,25 @@ func (c *BookController) CreateToken() {
func (c *BookController) Delete() { func (c *BookController) Delete() {
c.Prepare() c.Prepare()
bookResult ,err := c.IsPermission() bookResult, err := c.IsPermission()
if err != nil { if err != nil {
c.JsonResult(6001,err.Error()) c.JsonResult(6001, err.Error())
} }
if bookResult.RoleId != conf.BookFounder { if bookResult.RoleId != conf.BookFounder {
c.JsonResult(6002,"只有创始人才能删除项目") c.JsonResult(6002, "只有创始人才能删除项目")
} }
err = models.NewBook().ThoroughDeleteBook(bookResult.BookId) err = models.NewBook().ThoroughDeleteBook(bookResult.BookId)
if err == orm.ErrNoRows { if err == orm.ErrNoRows {
c.JsonResult(6002,"项目不存在") c.JsonResult(6002, "项目不存在")
} }
if err != nil { if err != nil {
logs.Error("删除项目 => ",err) logs.Error("删除项目 => ", err)
c.JsonResult(6003,"删除失败") c.JsonResult(6003, "删除失败")
} }
c.JsonResult(0,"ok") c.JsonResult(0, "ok")
} }
//发布项目. //发布项目.
@ -524,15 +522,15 @@ func (c *BookController) Release() {
identify := c.GetString("identify") identify := c.GetString("identify")
book_id := 0 bookId := 0
if c.Member.IsAdministrator() { if c.Member.IsAdministrator() {
book,err := models.NewBook().FindByFieldFirst("identify",identify) book, err := models.NewBook().FindByFieldFirst("identify", identify)
if err != nil { if err != nil {
} }
book_id = book.BookId bookId = book.BookId
}else { } else {
book, err := models.NewBookResult().FindByIdentify(identify, c.Member.MemberId) book, err := models.NewBookResult().FindByIdentify(identify, c.Member.MemberId)
if err != nil { if err != nil {
@ -548,15 +546,18 @@ func (c *BookController) Release() {
if book.RoleId != conf.BookAdmin && book.RoleId != conf.BookFounder && book.RoleId != conf.BookEditor { if book.RoleId != conf.BookAdmin && book.RoleId != conf.BookFounder && book.RoleId != conf.BookEditor {
c.JsonResult(6003, "权限不足") c.JsonResult(6003, "权限不足")
} }
book_id = book.BookId bookId = book.BookId
} }
go func(identify string) { go func(identify string) {
models.NewDocument().ReleaseContent(book_id) models.NewDocument().ReleaseContent(bookId)
//当文档发布后,需要删除已缓存的转换项目
outputPath := filepath.Join(beego.AppConfig.DefaultString("book_output_path", "cache"), strconv.Itoa(bookId))
os.RemoveAll(outputPath)
}(identify) }(identify)
c.JsonResult(0,"发布任务已推送到任务队列,稍后将在后台执行。") c.JsonResult(0, "发布任务已推送到任务队列,稍后将在后台执行。")
} }
//文档排序. //文档排序.
@ -570,94 +571,91 @@ func (c *BookController) SaveSort() {
book_id := 0 book_id := 0
if c.Member.IsAdministrator() { if c.Member.IsAdministrator() {
book,err := models.NewBook().FindByFieldFirst("identify",identify) book, err := models.NewBook().FindByFieldFirst("identify", identify)
if err != nil { if err != nil {
} }
book_id = book.BookId book_id = book.BookId
}else{ } else {
bookResult,err := models.NewBookResult().FindByIdentify(identify,c.Member.MemberId) bookResult, err := models.NewBookResult().FindByIdentify(identify, c.Member.MemberId)
if err != nil { if err != nil {
beego.Error("DocumentController.Edit => ",err) beego.Error("DocumentController.Edit => ", err)
c.Abort("403") c.Abort("403")
} }
if bookResult.RoleId == conf.BookObserver { if bookResult.RoleId == conf.BookObserver {
c.JsonResult(6002,"项目不存在或权限不足") c.JsonResult(6002, "项目不存在或权限不足")
} }
book_id = bookResult.BookId book_id = bookResult.BookId
} }
content := c.Ctx.Input.RequestBody content := c.Ctx.Input.RequestBody
var docs []map[string]interface{} var docs []map[string]interface{}
err := json.Unmarshal(content,&docs) err := json.Unmarshal(content, &docs)
if err != nil { if err != nil {
beego.Error(err) beego.Error(err)
c.JsonResult(6003,"数据错误") c.JsonResult(6003, "数据错误")
} }
for _,item := range docs { for _, item := range docs {
if doc_id,ok := item["id"].(float64);ok { if doc_id, ok := item["id"].(float64); ok {
doc,err := models.NewDocument().Find(int(doc_id)); doc, err := models.NewDocument().Find(int(doc_id))
if err != nil { if err != nil {
beego.Error(err) beego.Error(err)
continue;
}
if doc.BookId != book_id {
logs.Info("%s","权限错误")
continue;
}
sort,ok := item["sort"].(float64);
if !ok {
beego.Info("排序数字转换失败 => ",item)
continue continue
} }
parent_id,ok := item["parent"].(float64) if doc.BookId != book_id {
logs.Info("%s", "权限错误")
continue
}
sort, ok := item["sort"].(float64)
if !ok { if !ok {
beego.Info("父分类转换失败 => ",item) beego.Info("排序数字转换失败 => ", item)
continue
}
parent_id, ok := item["parent"].(float64)
if !ok {
beego.Info("父分类转换失败 => ", item)
continue continue
} }
if parent_id > 0 { if parent_id > 0 {
if parent,err := models.NewDocument().Find(int(parent_id)); err != nil || parent.BookId != book_id { if parent, err := models.NewDocument().Find(int(parent_id)); err != nil || parent.BookId != book_id {
continue continue
} }
} }
doc.OrderSort = int(sort) doc.OrderSort = int(sort)
doc.ParentId = int(parent_id) doc.ParentId = int(parent_id)
if err := doc.InsertOrUpdate(); err != nil { if err := doc.InsertOrUpdate(); err != nil {
fmt.Printf("%s",err.Error()) fmt.Printf("%s", err.Error())
beego.Error(err) beego.Error(err)
} }
}else{ } else {
fmt.Printf("文档ID转换失败 => %+v",item) fmt.Printf("文档ID转换失败 => %+v", item)
} }
} }
c.JsonResult(0,"ok") c.JsonResult(0, "ok")
} }
func (c *BookController) IsPermission() (*models.BookResult, error) {
func (c *BookController) IsPermission() (*models.BookResult,error) {
identify := c.GetString("identify") identify := c.GetString("identify")
book ,err := models.NewBookResult().FindByIdentify(identify,c.Member.MemberId) book, err := models.NewBookResult().FindByIdentify(identify, c.Member.MemberId)
if err != nil { if err != nil {
if err == models.ErrPermissionDenied { if err == models.ErrPermissionDenied {
return book,errors.New("权限不足") return book, errors.New("权限不足")
} }
if err == orm.ErrNoRows { if err == orm.ErrNoRows {
return book,errors.New("项目不存在") return book, errors.New("项目不存在")
} }
return book,err return book, err
} }
if book.RoleId != conf.BookAdmin && book.RoleId != conf.BookFounder { if book.RoleId != conf.BookAdmin && book.RoleId != conf.BookFounder {
return book,errors.New("权限不足") return book, errors.New("权限不足")
} }
return book,nil return book, nil
} }

View File

@ -3,10 +3,10 @@ package controllers
import ( import (
"errors" "errors"
"github.com/lifei6671/mindoc/models"
"github.com/astaxie/beego/orm"
"github.com/astaxie/beego/logs" "github.com/astaxie/beego/logs"
"github.com/astaxie/beego/orm"
"github.com/lifei6671/mindoc/conf" "github.com/lifei6671/mindoc/conf"
"github.com/lifei6671/mindoc/models"
) )
type BookMemberController struct { type BookMemberController struct {
@ -17,28 +17,28 @@ type BookMemberController struct {
func (c *BookMemberController) AddMember() { func (c *BookMemberController) AddMember() {
identify := c.GetString("identify") identify := c.GetString("identify")
account := c.GetString("account") account := c.GetString("account")
role_id,_ := c.GetInt("role_id",3) role_id, _ := c.GetInt("role_id", 3)
if identify == "" || account == ""{ if identify == "" || account == "" {
c.JsonResult(6001,"参数错误") c.JsonResult(6001, "参数错误")
} }
book ,err := c.IsPermission() book, err := c.IsPermission()
if err != nil { if err != nil {
c.JsonResult(6001,err.Error()) c.JsonResult(6001, err.Error())
} }
member := models.NewMember() member := models.NewMember()
if _,err := member.FindByAccount(account) ; err != nil { if _, err := member.FindByAccount(account); err != nil {
c.JsonResult(404,"用户不存在") c.JsonResult(404, "用户不存在")
} }
if member.Status == 1 { if member.Status == 1 {
c.JsonResult(6003,"用户已被禁用") c.JsonResult(6003, "用户已被禁用")
} }
if _,err := models.NewRelationship().FindForRoleId(book.BookId,member.MemberId);err == nil { if _, err := models.NewRelationship().FindForRoleId(book.BookId, member.MemberId); err == nil {
c.JsonResult(6003,"用户已存在该项目中") c.JsonResult(6003, "用户已存在该项目中")
} }
relationship := models.NewRelationship() relationship := models.NewRelationship()
@ -53,53 +53,52 @@ func (c *BookMemberController) AddMember() {
memberRelationshipResult.BookId = book.BookId memberRelationshipResult.BookId = book.BookId
memberRelationshipResult.ResolveRoleName() memberRelationshipResult.ResolveRoleName()
c.JsonResult(0, "ok", memberRelationshipResult)
c.JsonResult(0,"ok",memberRelationshipResult)
} }
c.JsonResult(500,err.Error()) c.JsonResult(500, err.Error())
} }
// 变更指定用户在指定项目中的权限 // 变更指定用户在指定项目中的权限
func (c *BookMemberController) ChangeRole() { func (c *BookMemberController) ChangeRole() {
identify := c.GetString("identify") identify := c.GetString("identify")
member_id,_ := c.GetInt("member_id",0) member_id, _ := c.GetInt("member_id", 0)
role,_ := c.GetInt("role_id",0) role, _ := c.GetInt("role_id", 0)
if identify == "" || member_id <=0 { if identify == "" || member_id <= 0 {
c.JsonResult(6001,"参数错误") c.JsonResult(6001, "参数错误")
} }
if member_id == c.Member.MemberId { if member_id == c.Member.MemberId {
c.JsonResult(6006,"不能变更自己的权限") c.JsonResult(6006, "不能变更自己的权限")
} }
book ,err := models.NewBookResult().FindByIdentify(identify,c.Member.MemberId) book, err := models.NewBookResult().FindByIdentify(identify, c.Member.MemberId)
if err != nil { if err != nil {
if err == models.ErrPermissionDenied { if err == models.ErrPermissionDenied {
c.JsonResult(403,"权限不足") c.JsonResult(403, "权限不足")
} }
if err == orm.ErrNoRows { if err == orm.ErrNoRows {
c.JsonResult(404,"项目不存在") c.JsonResult(404, "项目不存在")
} }
c.JsonResult(6002,err.Error()) c.JsonResult(6002, err.Error())
} }
if book.RoleId != 0 && book.RoleId != 1 { if book.RoleId != 0 && book.RoleId != 1 {
c.JsonResult(403,"权限不足") c.JsonResult(403, "权限不足")
} }
member := models.NewMember() member := models.NewMember()
if _,err := member.Find(member_id); err != nil { if _, err := member.Find(member_id); err != nil {
c.JsonResult(6003,"用户不存在") c.JsonResult(6003, "用户不存在")
} }
if member.Status == 1 { if member.Status == 1 {
c.JsonResult(6004,"用户已被禁用") c.JsonResult(6004, "用户已被禁用")
} }
relationship,err := models.NewRelationship().UpdateRoleId(book.BookId,member_id,role); relationship, err := models.NewRelationship().UpdateRoleId(book.BookId, member_id, role)
if err != nil { if err != nil {
logs.Error("变更用户在项目中的权限 => ",err) logs.Error("变更用户在项目中的权限 => ", err)
c.JsonResult(6005,err.Error()) c.JsonResult(6005, err.Error())
} }
memberRelationshipResult := models.NewMemberRelationshipResult().FromMember(member) memberRelationshipResult := models.NewMemberRelationshipResult().FromMember(member)
@ -108,58 +107,58 @@ func (c *BookMemberController) ChangeRole() {
memberRelationshipResult.BookId = book.BookId memberRelationshipResult.BookId = book.BookId
memberRelationshipResult.ResolveRoleName() memberRelationshipResult.ResolveRoleName()
c.JsonResult(0,"ok",memberRelationshipResult) c.JsonResult(0, "ok", memberRelationshipResult)
} }
// 删除参与者. // 删除参与者.
func (c *BookMemberController) RemoveMember() { func (c *BookMemberController) RemoveMember() {
identify := c.GetString("identify") identify := c.GetString("identify")
member_id,_ := c.GetInt("member_id",0) member_id, _ := c.GetInt("member_id", 0)
if identify == "" || member_id <=0 { if identify == "" || member_id <= 0 {
c.JsonResult(6001,"参数错误") c.JsonResult(6001, "参数错误")
} }
if member_id == c.Member.MemberId { if member_id == c.Member.MemberId {
c.JsonResult(6006,"不能删除自己") c.JsonResult(6006, "不能删除自己")
} }
book ,err := models.NewBookResult().FindByIdentify(identify,c.Member.MemberId) book, err := models.NewBookResult().FindByIdentify(identify, c.Member.MemberId)
if err != nil { if err != nil {
if err == models.ErrPermissionDenied { if err == models.ErrPermissionDenied {
c.JsonResult(403,"权限不足") c.JsonResult(403, "权限不足")
} }
if err == orm.ErrNoRows { if err == orm.ErrNoRows {
c.JsonResult(404,"项目不存在") c.JsonResult(404, "项目不存在")
} }
c.JsonResult(6002,err.Error()) c.JsonResult(6002, err.Error())
} }
//如果不是创始人也不是管理员则不能操作 //如果不是创始人也不是管理员则不能操作
if book.RoleId != conf.BookFounder && book.RoleId != conf.BookAdmin { if book.RoleId != conf.BookFounder && book.RoleId != conf.BookAdmin {
c.JsonResult(403,"权限不足") c.JsonResult(403, "权限不足")
} }
err = models.NewRelationship().DeleteByBookIdAndMemberId(book.BookId,member_id) err = models.NewRelationship().DeleteByBookIdAndMemberId(book.BookId, member_id)
if err != nil { if err != nil {
c.JsonResult(6007,err.Error()) c.JsonResult(6007, err.Error())
} }
c.JsonResult(0,"ok") c.JsonResult(0, "ok")
} }
func (c *BookMemberController) IsPermission() (*models.BookResult,error) { func (c *BookMemberController) IsPermission() (*models.BookResult, error) {
identify := c.GetString("identify") identify := c.GetString("identify")
book ,err := models.NewBookResult().FindByIdentify(identify,c.Member.MemberId) book, err := models.NewBookResult().FindByIdentify(identify, c.Member.MemberId)
if err != nil { if err != nil {
if err == models.ErrPermissionDenied { if err == models.ErrPermissionDenied {
return book,errors.New("权限不足") return book, errors.New("权限不足")
} }
if err == orm.ErrNoRows { if err == orm.ErrNoRows {
return book,errors.New("项目不存在") return book, errors.New("项目不存在")
} }
return book,err return book, err
} }
if book.RoleId != conf.BookAdmin && book.RoleId != conf.BookFounder { if book.RoleId != conf.BookAdmin && book.RoleId != conf.BookFounder {
return book,errors.New("权限不足") return book, errors.New("权限不足")
} }
return book,nil return book, nil
} }

View File

@ -10,7 +10,7 @@ func (c *CommentController) Lists() {
func (c *CommentController) Create() { func (c *CommentController) Create() {
c.JsonResult(0,"ok") c.JsonResult(0, "ok")
} }
func (c *CommentController) Index() { func (c *CommentController) Index() {

View File

@ -11,7 +11,7 @@ import (
"strconv" "strconv"
"strings" "strings"
"time" "time"
"net/url"
"image/png" "image/png"
"bytes" "bytes"
@ -21,7 +21,6 @@ import (
"github.com/astaxie/beego/orm" "github.com/astaxie/beego/orm"
"github.com/boombuler/barcode" "github.com/boombuler/barcode"
"github.com/boombuler/barcode/qr" "github.com/boombuler/barcode/qr"
"github.com/lifei6671/mindoc/commands"
"github.com/lifei6671/mindoc/conf" "github.com/lifei6671/mindoc/conf"
"github.com/lifei6671/mindoc/models" "github.com/lifei6671/mindoc/models"
"github.com/lifei6671/mindoc/utils" "github.com/lifei6671/mindoc/utils"
@ -101,12 +100,10 @@ func promptUserToLogIn(c *DocumentController) {
beego.Info("Access " + c.Ctx.Request.URL.RequestURI() + " not permitted.") beego.Info("Access " + c.Ctx.Request.URL.RequestURI() + " not permitted.")
beego.Info(" Access will be redirected to login page(SessionId: " + c.CruSession.SessionID() + ").") beego.Info(" Access will be redirected to login page(SessionId: " + c.CruSession.SessionID() + ").")
c.SetSession("turl", c.Ctx.Request.URL.RequestURI())
if c.IsAjax() { if c.IsAjax() {
c.JsonResult(6000, "需要[重]登录。") c.JsonResult(6000, "请重新登录。")
} else { } else {
c.Redirect(beego.URLFor("AccountController.Login"), 302) c.Redirect(beego.URLFor("AccountController.Login")+ "?url=" + url.PathEscape(conf.BaseUrl+ c.Ctx.Request.URL.RequestURI()), 302)
} }
} }
@ -156,8 +153,7 @@ func (c *DocumentController) Read() {
token := c.GetString("token") token := c.GetString("token")
id := c.GetString(":id") id := c.GetString(":id")
c.Data["DocumentId"] = id // added by dandycheung, 2017-12-08, for exporting c.Data["DocumentId"] = id
beego.Info("DocumentController.Read(): c.Data[\"DocumentId\"] = ", id, ", IsAjax = ", c.IsAjax())
if identify == "" || id == "" { if identify == "" || id == "" {
c.Abort("404") c.Abort("404")
@ -393,7 +389,6 @@ func (c *DocumentController) Create() {
document.Identify = doc_identify document.Identify = doc_identify
document.Version = time.Now().Unix() document.Version = time.Now().Unix()
document.DocumentName = doc_name document.DocumentName = doc_name
document.ParentId = parent_id document.ParentId = parent_id
@ -439,10 +434,9 @@ func (c *DocumentController) Upload() {
beego.Info(conf.GetUploadFileSize()) beego.Info(conf.GetUploadFileSize())
beego.Info(moreFile.Size) beego.Info(moreFile.Size)
if conf.GetUploadFileSize() > 0 && moreFile.Size > conf.GetUploadFileSize() { if conf.GetUploadFileSize() > 0 && moreFile.Size > conf.GetUploadFileSize() {
c.JsonResult(6009,"查过文件允许的上传最大值") c.JsonResult(6009, "查过文件允许的上传最大值")
} }
ext := filepath.Ext(moreFile.Filename) ext := filepath.Ext(moreFile.Filename)
if ext == "" { if ext == "" {
@ -498,7 +492,7 @@ func (c *DocumentController) Upload() {
} }
fileName := "attach_" + strconv.FormatInt(time.Now().UnixNano(), 16) fileName := "attach_" + strconv.FormatInt(time.Now().UnixNano(), 16)
filePath := filepath.Join(commands.WorkingDirectory, "uploads", time.Now().Format("200601"), fileName+ext) filePath := filepath.Join(conf.WorkingDirectory, "uploads", time.Now().Format("200601"), fileName+ext)
path := filepath.Dir(filePath) path := filepath.Dir(filePath)
os.MkdirAll(path, os.ModePerm) os.MkdirAll(path, os.ModePerm)
@ -515,7 +509,7 @@ func (c *DocumentController) Upload() {
attachment.FileName = moreFile.Filename attachment.FileName = moreFile.Filename
attachment.CreateAt = c.Member.MemberId attachment.CreateAt = c.Member.MemberId
attachment.FileExt = ext attachment.FileExt = ext
attachment.FilePath = strings.TrimPrefix(filePath, commands.WorkingDirectory) attachment.FilePath = strings.TrimPrefix(filePath, conf.WorkingDirectory)
attachment.DocumentId = doc_id attachment.DocumentId = doc_id
if fileInfo, err := os.Stat(filePath); err == nil { if fileInfo, err := os.Stat(filePath); err == nil {
@ -527,7 +521,7 @@ func (c *DocumentController) Upload() {
} }
if strings.EqualFold(ext, ".jpg") || strings.EqualFold(ext, ".jpeg") || strings.EqualFold(ext, ".png") || strings.EqualFold(ext, ".gif") { if strings.EqualFold(ext, ".jpg") || strings.EqualFold(ext, ".jpeg") || strings.EqualFold(ext, ".png") || strings.EqualFold(ext, ".gif") {
attachment.HttpPath = "/" + strings.Replace(strings.TrimPrefix(filePath, commands.WorkingDirectory), "\\", "/", -1) attachment.HttpPath = "/" + strings.Replace(strings.TrimPrefix(filePath, conf.WorkingDirectory), "\\", "/", -1)
if strings.HasPrefix(attachment.HttpPath, "//") { if strings.HasPrefix(attachment.HttpPath, "//") {
attachment.HttpPath = string(attachment.HttpPath[1:]) attachment.HttpPath = string(attachment.HttpPath[1:])
} }
@ -621,7 +615,7 @@ func (c *DocumentController) DownloadAttachment() {
c.Abort("404") c.Abort("404")
} }
c.Ctx.Output.Download(filepath.Join(commands.WorkingDirectory, attachment.FilePath), attachment.FileName) c.Ctx.Output.Download(filepath.Join(conf.WorkingDirectory, attachment.FilePath), attachment.FileName)
c.StopRun() c.StopRun()
} }
@ -666,7 +660,7 @@ func (c *DocumentController) RemoveAttachment() {
c.JsonResult(6005, "删除失败") c.JsonResult(6005, "删除失败")
} }
os.Remove(filepath.Join(commands.WorkingDirectory, attach.FilePath)) os.Remove(filepath.Join(conf.WorkingDirectory, attach.FilePath))
c.JsonResult(0, "ok", attach) c.JsonResult(0, "ok", attach)
} }
@ -823,11 +817,9 @@ func (c *DocumentController) Content() {
go func(identify string) { go func(identify string) {
models.NewDocument().ReleaseContent(book_id) models.NewDocument().ReleaseContent(book_id)
}(identify) }(identify)
} }
c.JsonResult(0, "ok", doc) c.JsonResult(0, "ok", doc)
} }
@ -844,7 +836,6 @@ func (c *DocumentController) Content() {
c.JsonResult(0, "ok", doc) c.JsonResult(0, "ok", doc)
} }
func (c *DocumentController) GetDocumentById(id string) (doc *models.Document, err error) { func (c *DocumentController) GetDocumentById(id string) (doc *models.Document, err error) {
doc = models.NewDocument() doc = models.NewDocument()
if doc_id, err := strconv.Atoi(id); err == nil { if doc_id, err := strconv.Atoi(id); err == nil {
@ -894,55 +885,33 @@ func (c *DocumentController) Export() {
bookResult = isReadable(identify, token, c) bookResult = isReadable(identify, token, c)
} }
if bookResult.PrivatelyOwned == 0 { if !strings.HasPrefix(bookResult.Cover, "http:://") && !strings.HasPrefix(bookResult.Cover, "https:://") {
// TODO: 私有项目禁止导出
}
if !strings.HasPrefix(bookResult.Cover,"http:://") && !strings.HasPrefix(bookResult.Cover,"https:://"){
bookResult.Cover = c.BaseUrl() + bookResult.Cover bookResult.Cover = c.BaseUrl() + bookResult.Cover
} }
eBookResult,err := bookResult.Converter(c.CruSession.SessionID()) eBookResult, err := bookResult.Converter(c.CruSession.SessionID())
if err != nil { if err != nil {
beego.Error("转换文档失败:" + bookResult.BookName + " -> " + err.Error()) beego.Error("转换文档失败:" + bookResult.BookName + " -> " + err.Error())
c.Abort("500") c.Abort("500")
} }
if output == "pdf" { if output == "pdf" {
c.Ctx.Output.Download(eBookResult.PDFPath, identify + ".pdf") c.Ctx.Output.Download(eBookResult.PDFPath, bookResult.BookName+".pdf")
//如果没有开启缓存则10分钟后删除 c.Abort("200")
if !bookResult.IsCacheEBook { } else if output == "epub" {
defer func(pdfpath string) { c.Ctx.Output.Download(eBookResult.EpubPath, bookResult.BookName+".epub")
time.Sleep(time.Minute * 10)
os.Remove(filepath.Dir(pdfpath))
}(eBookResult.PDFPath)
}
c.StopRun()
}else if output == "epub" {
c.Ctx.Output.Download(eBookResult.PDFPath, identify + ".epub")
//如果没有开启缓存则10分钟后删除 c.Abort("200")
if !bookResult.IsCacheEBook { } else if output == "mobi" {
defer func(pdfpath string) { c.Ctx.Output.Download(eBookResult.MobiPath, bookResult.BookName+".epub")
time.Sleep(time.Minute * 10)
os.Remove(filepath.Dir(pdfpath))
}(eBookResult.EpubPath)
}
c.StopRun()
}else if output == "mobi" {
c.Ctx.Output.Download(eBookResult.PDFPath, identify + ".epub")
//如果没有开启缓存则10分钟后删除 c.Abort("200")
if !bookResult.IsCacheEBook { } else if output == "docx" {
defer func(pdfpath string) { c.Ctx.Output.Download(eBookResult.WordPath, bookResult.BookName+".epub")
time.Sleep(time.Minute * 10)
os.Remove(filepath.Dir(pdfpath)) c.Abort("200")
}(eBookResult.MobiPath)
}
c.StopRun()
} }
c.Abort("404") c.Abort("404")

View File

@ -1,10 +1,12 @@
package controllers package controllers
import ( import (
"net/url"
"github.com/astaxie/beego" "github.com/astaxie/beego"
"github.com/lifei6671/mindoc/models" "github.com/lifei6671/mindoc/models"
"github.com/lifei6671/mindoc/utils" "github.com/lifei6671/mindoc/utils"
"math" "math"
"github.com/lifei6671/mindoc/conf"
) )
type HomeController struct { type HomeController struct {
@ -16,9 +18,9 @@ func (c *HomeController) Index() {
c.TplName = "home/index.tpl" c.TplName = "home/index.tpl"
//如果没有开启匿名访问,则跳转到登录页面 //如果没有开启匿名访问,则跳转到登录页面
if !c.EnableAnonymous && c.Member == nil { if !c.EnableAnonymous && c.Member == nil {
c.Redirect(beego.URLFor("AccountController.Login"),302) c.Redirect(beego.URLFor("AccountController.Login") + "?url=" + url.PathEscape(conf.BaseUrl + c.Ctx.Request.URL.RequestURI()), 302)
} }
pageIndex,_ := c.GetInt("page",1) pageIndex, _ := c.GetInt("page", 1)
pageSize := 18 pageSize := 18
member_id := 0 member_id := 0
@ -26,7 +28,7 @@ func (c *HomeController) Index() {
if c.Member != nil { if c.Member != nil {
member_id = c.Member.MemberId member_id = c.Member.MemberId
} }
books,totalCount,err := models.NewBook().FindForHomeToPager(pageIndex,pageSize,member_id) books, totalCount, err := models.NewBook().FindForHomeToPager(pageIndex, pageSize, member_id)
if err != nil { if err != nil {
beego.Error(err) beego.Error(err)
@ -36,18 +38,18 @@ func (c *HomeController) Index() {
html := utils.GetPagerHtml(c.Ctx.Request.RequestURI, pageIndex, pageSize, totalCount) html := utils.GetPagerHtml(c.Ctx.Request.RequestURI, pageIndex, pageSize, totalCount)
c.Data["PageHtml"] = html c.Data["PageHtml"] = html
}else { } else {
c.Data["PageHtml"] = "" c.Data["PageHtml"] = ""
} }
c.Data["TotalPages"] = int(math.Ceil(float64(totalCount) / float64(pageSize))) c.Data["TotalPages"] = int(math.Ceil(float64(totalCount) / float64(pageSize)))
c.Data["Lists"] = books c.Data["Lists"] = books
labels ,totalCount,err := models.NewLabel().FindToPager(1,10) labels, totalCount, err := models.NewLabel().FindToPager(1, 10)
if err != nil { if err != nil {
c.Data["Labels"] = make([]*models.Label,0) c.Data["Labels"] = make([]*models.Label, 0)
}else{ } else {
c.Data["Labels"] = labels c.Data["Labels"] = labels
} }
} }

View File

@ -1,10 +1,10 @@
package controllers package controllers
import ( import (
"github.com/lifei6671/mindoc/models"
"github.com/astaxie/beego/orm"
"github.com/astaxie/beego" "github.com/astaxie/beego"
"github.com/astaxie/beego/orm"
"github.com/lifei6671/mindoc/conf" "github.com/lifei6671/mindoc/conf"
"github.com/lifei6671/mindoc/models"
"github.com/lifei6671/mindoc/utils" "github.com/lifei6671/mindoc/utils"
"math" "math"
) )
@ -18,7 +18,7 @@ func (c *LabelController) Prepare() {
//如果没有开启你们访问则跳转到登录 //如果没有开启你们访问则跳转到登录
if !c.EnableAnonymous && c.Member == nil { if !c.EnableAnonymous && c.Member == nil {
c.Redirect(beego.URLFor("AccountController.Login"),302) c.Redirect(beego.URLFor("AccountController.Login"), 302)
return return
} }
} }
@ -29,16 +29,16 @@ func (c *LabelController) Index() {
c.TplName = "label/index.tpl" c.TplName = "label/index.tpl"
labelName := c.Ctx.Input.Param(":key") labelName := c.Ctx.Input.Param(":key")
pageIndex,_ := c.GetInt("page",1) pageIndex, _ := c.GetInt("page", 1)
if labelName == "" { if labelName == "" {
c.Abort("404") c.Abort("404")
} }
_,err := models.NewLabel().FindFirst("label_name",labelName) _, err := models.NewLabel().FindFirst("label_name", labelName)
if err != nil { if err != nil {
if err == orm.ErrNoRows { if err == orm.ErrNoRows {
c.Abort("404") c.Abort("404")
}else{ } else {
beego.Error(err) beego.Error(err)
c.Abort("500") c.Abort("500")
} }
@ -47,7 +47,7 @@ func (c *LabelController) Index() {
if c.Member != nil { if c.Member != nil {
member_id = c.Member.MemberId member_id = c.Member.MemberId
} }
search_result,totalCount,err := models.NewBook().FindForLabelToPager(labelName,pageIndex,conf.PageSize,member_id) search_result, totalCount, err := models.NewBook().FindForLabelToPager(labelName, pageIndex, conf.PageSize, member_id)
if err != nil { if err != nil {
beego.Error(err) beego.Error(err)
@ -57,7 +57,7 @@ func (c *LabelController) Index() {
html := utils.GetPagerHtml(c.Ctx.Request.RequestURI, pageIndex, conf.PageSize, totalCount) html := utils.GetPagerHtml(c.Ctx.Request.RequestURI, pageIndex, conf.PageSize, totalCount)
c.Data["PageHtml"] = html c.Data["PageHtml"] = html
}else { } else {
c.Data["PageHtml"] = "" c.Data["PageHtml"] = ""
} }
c.Data["Lists"] = search_result c.Data["Lists"] = search_result
@ -69,25 +69,22 @@ func (c *LabelController) List() {
c.Prepare() c.Prepare()
c.TplName = "label/list.tpl" c.TplName = "label/list.tpl"
pageIndex,_ := c.GetInt("page",1) pageIndex, _ := c.GetInt("page", 1)
pageSize := 200 pageSize := 200
labels ,totalCount,err := models.NewLabel().FindToPager(pageIndex,pageSize) labels, totalCount, err := models.NewLabel().FindToPager(pageIndex, pageSize)
if err != nil { if err != nil {
c.ShowErrorPage(50001,err.Error()) c.ShowErrorPage(50001, err.Error())
} }
if totalCount > 0 { if totalCount > 0 {
html := utils.GetPagerHtml(c.Ctx.Request.RequestURI, pageIndex, pageSize, totalCount) html := utils.GetPagerHtml(c.Ctx.Request.RequestURI, pageIndex, pageSize, totalCount)
c.Data["PageHtml"] = html c.Data["PageHtml"] = html
}else { } else {
c.Data["PageHtml"] = "" c.Data["PageHtml"] = ""
} }
c.Data["TotalPages"] = int(math.Ceil(float64(totalCount) / float64(pageSize))) c.Data["TotalPages"] = int(math.Ceil(float64(totalCount) / float64(pageSize)))
c.Data["Labels"] = labels c.Data["Labels"] = labels
} }

View File

@ -13,7 +13,6 @@ import (
"github.com/lifei6671/mindoc/models" "github.com/lifei6671/mindoc/models"
"github.com/lifei6671/mindoc/utils" "github.com/lifei6671/mindoc/utils"
"path/filepath" "path/filepath"
"github.com/lifei6671/mindoc/commands"
"strconv" "strconv"
) )
@ -21,7 +20,7 @@ type ManagerController struct {
BaseController BaseController
} }
func (c *ManagerController) Prepare (){ func (c *ManagerController) Prepare() {
c.BaseController.Prepare() c.BaseController.Prepare()
if !c.Member.IsAdministrator() { if !c.Member.IsAdministrator() {
@ -42,7 +41,7 @@ func (c *ManagerController) Users() {
pageIndex, _ := c.GetInt("page", 0) pageIndex, _ := c.GetInt("page", 0)
members, totalCount, err := models.NewMember().FindToPager(pageIndex, 15) members, totalCount, err := models.NewMember().FindToPager(pageIndex, conf.PageSize)
if err != nil { if err != nil {
c.Data["ErrorMessage"] = err.Error() c.Data["ErrorMessage"] = err.Error()
@ -50,7 +49,7 @@ func (c *ManagerController) Users() {
} }
if totalCount > 0 { if totalCount > 0 {
html := utils.GetPagerHtml(c.Ctx.Request.RequestURI, pageIndex, 10, int(totalCount)) html := utils.GetPagerHtml(c.Ctx.Request.RequestURI, pageIndex, conf.PageSize, int(totalCount))
c.Data["PageHtml"] = html c.Data["PageHtml"] = html
} else { } else {
@ -139,10 +138,10 @@ func (c *ManagerController) UpdateMemberStatus() {
c.JsonResult(6002, "用户不存在") c.JsonResult(6002, "用户不存在")
} }
if member.MemberId == c.Member.MemberId { if member.MemberId == c.Member.MemberId {
c.JsonResult(6004,"不能变更自己的状态") c.JsonResult(6004, "不能变更自己的状态")
} }
if member.Role == conf.MemberSuperRole { if member.Role == conf.MemberSuperRole {
c.JsonResult(6005,"不能变更超级管理员的状态") c.JsonResult(6005, "不能变更超级管理员的状态")
} }
member.Status = status member.Status = status
@ -171,10 +170,10 @@ func (c *ManagerController) ChangeMemberRole() {
c.JsonResult(6002, "用户不存在") c.JsonResult(6002, "用户不存在")
} }
if member.MemberId == c.Member.MemberId { if member.MemberId == c.Member.MemberId {
c.JsonResult(6004,"不能变更自己的权限") c.JsonResult(6004, "不能变更自己的权限")
} }
if member.Role == conf.MemberSuperRole { if member.Role == conf.MemberSuperRole {
c.JsonResult(6005,"不能变更超级管理员的权限") c.JsonResult(6005, "不能变更超级管理员的权限")
} }
member.Role = role member.Role = role
@ -191,13 +190,13 @@ func (c *ManagerController) EditMember() {
c.Prepare() c.Prepare()
c.TplName = "manager/edit_users.tpl" c.TplName = "manager/edit_users.tpl"
member_id,_ := c.GetInt(":id",0) member_id, _ := c.GetInt(":id", 0)
if member_id <= 0 { if member_id <= 0 {
c.Abort("404") c.Abort("404")
} }
member ,err := models.NewMember().Find(member_id) member, err := models.NewMember().Find(member_id)
if err != nil { if err != nil {
beego.Error(err) beego.Error(err)
@ -213,27 +212,27 @@ func (c *ManagerController) EditMember() {
member.Phone = phone member.Phone = phone
member.Description = description member.Description = description
if password1 != "" && password2 != password1 { if password1 != "" && password2 != password1 {
c.JsonResult(6001,"确认密码不正确") c.JsonResult(6001, "确认密码不正确")
} }
if password1 != "" && member.AuthMethod != conf.AuthMethodLDAP{ if password1 != "" && member.AuthMethod != conf.AuthMethodLDAP {
member.Password = password1 member.Password = password1
} }
if err := member.Valid(password1 == "");err != nil { if err := member.Valid(password1 == ""); err != nil {
c.JsonResult(6002,err.Error()) c.JsonResult(6002, err.Error())
} }
if password1 != "" { if password1 != "" {
password,err := utils.PasswordHash(password1) password, err := utils.PasswordHash(password1)
if err != nil { if err != nil {
beego.Error(err) beego.Error(err)
c.JsonResult(6003,"对用户密码加密时出错") c.JsonResult(6003, "对用户密码加密时出错")
} }
member.Password = password member.Password = password
} }
if err := member.Update();err != nil { if err := member.Update(); err != nil {
beego.Error(err) beego.Error(err)
c.JsonResult(6004,"保存失败") c.JsonResult(6004, "保存失败")
} }
c.JsonResult(0,"ok") c.JsonResult(0, "ok")
} }
c.Data["Model"] = member c.Data["Model"] = member
@ -242,35 +241,35 @@ func (c *ManagerController) EditMember() {
//删除一个用户,并将该用户的所有信息转移到超级管理员上. //删除一个用户,并将该用户的所有信息转移到超级管理员上.
func (c *ManagerController) DeleteMember() { func (c *ManagerController) DeleteMember() {
c.Prepare() c.Prepare()
member_id,_ := c.GetInt("id",0) member_id, _ := c.GetInt("id", 0)
if member_id <= 0 { if member_id <= 0 {
c.JsonResult(404,"参数错误") c.JsonResult(404, "参数错误")
} }
member ,err := models.NewMember().Find(member_id) member, err := models.NewMember().Find(member_id)
if err != nil { if err != nil {
beego.Error(err) beego.Error(err)
c.JsonResult(500,"用户不存在") c.JsonResult(500, "用户不存在")
} }
if member.Role == conf.MemberSuperRole { if member.Role == conf.MemberSuperRole {
c.JsonResult(500,"不能删除超级管理员") c.JsonResult(500, "不能删除超级管理员")
} }
superMember,err := models.NewMember().FindByFieldFirst("role",0) superMember, err := models.NewMember().FindByFieldFirst("role", 0)
if err != nil { if err != nil {
beego.Error(err) beego.Error(err)
c.JsonResult(5001,"未能找到超级管理员") c.JsonResult(5001, "未能找到超级管理员")
} }
err = models.NewMember().Delete(member_id,superMember.MemberId) err = models.NewMember().Delete(member_id, superMember.MemberId)
if err != nil { if err != nil {
beego.Error(err) beego.Error(err)
c.JsonResult(5002,"删除失败") c.JsonResult(5002, "删除失败")
} }
c.JsonResult(0,"ok") c.JsonResult(0, "ok")
} }
//项目列表. //项目列表.
@ -572,9 +571,9 @@ func (c *ManagerController) AttachList() {
c.Data["PageHtml"] = "" c.Data["PageHtml"] = ""
} }
for _,item := range attachList { for _, item := range attachList {
p := filepath.Join(commands.WorkingDirectory,item.FilePath) p := filepath.Join(conf.WorkingDirectory, item.FilePath)
item.IsExist = utils.FileExists(p) item.IsExist = utils.FileExists(p)
@ -586,24 +585,24 @@ func (c *ManagerController) AttachList() {
func (c *ManagerController) AttachDetailed() { func (c *ManagerController) AttachDetailed() {
c.Prepare() c.Prepare()
c.TplName = "manager/attach_detailed.tpl" c.TplName = "manager/attach_detailed.tpl"
attach_id,_ := strconv.Atoi(c.Ctx.Input.Param(":id")) attach_id, _ := strconv.Atoi(c.Ctx.Input.Param(":id"))
if attach_id <= 0 { if attach_id <= 0 {
c.Abort("404") c.Abort("404")
} }
attach,err := models.NewAttachmentResult().Find(attach_id) attach, err := models.NewAttachmentResult().Find(attach_id)
if err != nil { if err != nil {
beego.Error("AttachDetailed => ",err) beego.Error("AttachDetailed => ", err)
if err == orm.ErrNoRows { if err == orm.ErrNoRows {
c.Abort("404") c.Abort("404")
}else{ } else {
c.Abort("500") c.Abort("500")
} }
} }
attach.FilePath = filepath.Join(commands.WorkingDirectory,attach.FilePath) attach.FilePath = filepath.Join(conf.WorkingDirectory, attach.FilePath)
attach.HttpPath = c.BaseUrl() + attach.HttpPath attach.HttpPath = c.BaseUrl() + attach.HttpPath
attach.IsExist = utils.FileExists(attach.FilePath) attach.IsExist = utils.FileExists(attach.FilePath)
@ -614,41 +613,20 @@ func (c *ManagerController) AttachDetailed() {
//删除附件. //删除附件.
func (c *ManagerController) AttachDelete() { func (c *ManagerController) AttachDelete() {
c.Prepare() c.Prepare()
attach_id,_ := c.GetInt("attach_id") attach_id, _ := c.GetInt("attach_id")
if attach_id <= 0 { if attach_id <= 0 {
c.Abort("404") c.Abort("404")
} }
attach,err := models.NewAttachment().Find(attach_id) attach, err := models.NewAttachment().Find(attach_id)
if err != nil { if err != nil {
beego.Error("AttachDelete => ",err) beego.Error("AttachDelete => ", err)
c.JsonResult(6001,err.Error()) c.JsonResult(6001, err.Error())
} }
if err := attach.Delete();err != nil { if err := attach.Delete(); err != nil {
beego.Error("AttachDelete => ",err) beego.Error("AttachDelete => ", err)
c.JsonResult(6002,err.Error()) c.JsonResult(6002, err.Error())
} }
c.JsonResult(0,"ok") c.JsonResult(0, "ok")
} }

View File

@ -1,13 +1,13 @@
package controllers package controllers
import ( import (
"github.com/lifei6671/mindoc/models"
"github.com/lifei6671/mindoc/conf"
"github.com/lifei6671/mindoc/utils"
"github.com/astaxie/beego" "github.com/astaxie/beego"
"strings" "github.com/lifei6671/mindoc/conf"
"github.com/lifei6671/mindoc/models"
"github.com/lifei6671/mindoc/utils"
"regexp" "regexp"
"strconv" "strconv"
"strings"
) )
type SearchController struct { type SearchController struct {
@ -20,12 +20,12 @@ func (c *SearchController) Index() {
//如果没有开启你们访问则跳转到登录 //如果没有开启你们访问则跳转到登录
if !c.EnableAnonymous && c.Member == nil { if !c.EnableAnonymous && c.Member == nil {
c.Redirect(beego.URLFor("AccountController.Login"),302) c.Redirect(beego.URLFor("AccountController.Login"), 302)
return return
} }
keyword := c.GetString("keyword") keyword := c.GetString("keyword")
pageIndex,_ := c.GetInt("page",1) pageIndex, _ := c.GetInt("page", 1)
c.Data["BaseUrl"] = c.BaseUrl() c.Data["BaseUrl"] = c.BaseUrl()
@ -35,7 +35,7 @@ func (c *SearchController) Index() {
if c.Member != nil { if c.Member != nil {
member_id = c.Member.MemberId member_id = c.Member.MemberId
} }
search_result,totalCount,err := models.NewDocumentSearchResult().FindToPager(keyword,pageIndex,conf.PageSize,member_id) search_result, totalCount, err := models.NewDocumentSearchResult().FindToPager(keyword, pageIndex, conf.PageSize, member_id)
if err != nil { if err != nil {
beego.Error(err) beego.Error(err)
@ -45,12 +45,12 @@ func (c *SearchController) Index() {
html := utils.GetPagerHtml(c.Ctx.Request.RequestURI, pageIndex, conf.PageSize, totalCount) html := utils.GetPagerHtml(c.Ctx.Request.RequestURI, pageIndex, conf.PageSize, totalCount)
c.Data["PageHtml"] = html c.Data["PageHtml"] = html
}else { } else {
c.Data["PageHtml"] = "" c.Data["PageHtml"] = ""
} }
if len(search_result) > 0 { if len(search_result) > 0 {
for _,item := range search_result { for _, item := range search_result {
item.DocumentName = strings.Replace(item.DocumentName,keyword,"<em>" + keyword + "</em>",-1) item.DocumentName = strings.Replace(item.DocumentName, keyword, "<em>"+keyword+"</em>", -1)
if item.Description != "" { if item.Description != "" {
src := item.Description src := item.Description
@ -79,13 +79,13 @@ func (c *SearchController) Index() {
if len(r) > 100 { if len(r) > 100 {
src = string(r[:100]) src = string(r[:100])
}else{ } else {
src = string(r) src = string(r)
} }
item.Description = strings.Replace(src, keyword, "<em>" + keyword + "</em>", -1) item.Description = strings.Replace(src, keyword, "<em>"+keyword+"</em>", -1)
} }
if item.Identify == ""{ if item.Identify == "" {
item.Identify = strconv.Itoa(item.DocumentId) item.Identify = strconv.Itoa(item.DocumentId)
} }
if item.ModifyTime.IsZero() { if item.ModifyTime.IsZero() {

View File

@ -3,17 +3,16 @@ package controllers
import ( import (
"fmt" "fmt"
"os" "os"
"strings"
"path/filepath" "path/filepath"
"strconv" "strconv"
"strings"
"time" "time"
"github.com/astaxie/beego/logs" "github.com/astaxie/beego/logs"
"github.com/lifei6671/mindoc/conf"
"github.com/lifei6671/mindoc/graphics"
"github.com/lifei6671/mindoc/models" "github.com/lifei6671/mindoc/models"
"github.com/lifei6671/mindoc/utils" "github.com/lifei6671/mindoc/utils"
"github.com/lifei6671/mindoc/graphics"
"github.com/lifei6671/mindoc/conf"
"github.com/lifei6671/mindoc/commands"
) )
type SettingController struct { type SettingController struct {
@ -48,126 +47,124 @@ func (c *SettingController) Password() {
if c.Ctx.Input.IsPost() { if c.Ctx.Input.IsPost() {
if c.Member.AuthMethod == conf.AuthMethodLDAP { if c.Member.AuthMethod == conf.AuthMethodLDAP {
c.JsonResult(6009,"当前用户不支持修改密码") c.JsonResult(6009, "当前用户不支持修改密码")
} }
password1 := c.GetString("password1") password1 := c.GetString("password1")
password2 := c.GetString("password2") password2 := c.GetString("password2")
password3 := c.GetString("password3") password3 := c.GetString("password3")
if password1 == "" { if password1 == "" {
c.JsonResult(6003,"原密码不能为空") c.JsonResult(6003, "原密码不能为空")
} }
if password2 == "" { if password2 == "" {
c.JsonResult(6004,"新密码不能为空") c.JsonResult(6004, "新密码不能为空")
} }
if count := strings.Count(password2,""); count < 6 || count > 18 { if count := strings.Count(password2, ""); count < 6 || count > 18 {
c.JsonResult(6009,"密码必须在6-18字之间") c.JsonResult(6009, "密码必须在6-18字之间")
} }
if password2 != password3 { if password2 != password3 {
c.JsonResult(6003,"确认密码不正确") c.JsonResult(6003, "确认密码不正确")
} }
if ok,_ := utils.PasswordVerify(c.Member.Password,password1) ; !ok { if ok, _ := utils.PasswordVerify(c.Member.Password, password1); !ok {
c.JsonResult(6005,"原始密码不正确") c.JsonResult(6005, "原始密码不正确")
} }
if password1 == password2 { if password1 == password2 {
c.JsonResult(6006,"新密码不能和原始密码相同") c.JsonResult(6006, "新密码不能和原始密码相同")
} }
pwd,err := utils.PasswordHash(password2) pwd, err := utils.PasswordHash(password2)
if err != nil { if err != nil {
c.JsonResult(6007,"密码加密失败") c.JsonResult(6007, "密码加密失败")
} }
c.Member.Password = pwd c.Member.Password = pwd
if err := c.Member.Update();err != nil { if err := c.Member.Update(); err != nil {
c.JsonResult(6008,err.Error()) c.JsonResult(6008, err.Error())
} }
c.JsonResult(0,"ok") c.JsonResult(0, "ok")
} }
} }
// Upload 上传图片 // Upload 上传图片
func (c *SettingController) Upload() { func (c *SettingController) Upload() {
file,moreFile,err := c.GetFile("image-file") file, moreFile, err := c.GetFile("image-file")
defer file.Close() defer file.Close()
if err != nil { if err != nil {
logs.Error("",err.Error()) logs.Error("", err.Error())
c.JsonResult(500,"读取文件异常") c.JsonResult(500, "读取文件异常")
} }
ext := filepath.Ext(moreFile.Filename) ext := filepath.Ext(moreFile.Filename)
if !strings.EqualFold(ext,".png") && !strings.EqualFold(ext,".jpg") && !strings.EqualFold(ext,".gif") && !strings.EqualFold(ext,".jpeg") { if !strings.EqualFold(ext, ".png") && !strings.EqualFold(ext, ".jpg") && !strings.EqualFold(ext, ".gif") && !strings.EqualFold(ext, ".jpeg") {
c.JsonResult(500,"不支持的图片格式") c.JsonResult(500, "不支持的图片格式")
} }
x1, _ := strconv.ParseFloat(c.GetString("x"), 10)
x1 ,_ := strconv.ParseFloat(c.GetString("x"),10) y1, _ := strconv.ParseFloat(c.GetString("y"), 10)
y1 ,_ := strconv.ParseFloat(c.GetString("y"),10) w1, _ := strconv.ParseFloat(c.GetString("width"), 10)
w1 ,_ := strconv.ParseFloat(c.GetString("width"),10) h1, _ := strconv.ParseFloat(c.GetString("height"), 10)
h1 ,_ := strconv.ParseFloat(c.GetString("height"),10)
x := int(x1) x := int(x1)
y := int(y1) y := int(y1)
width := int(w1) width := int(w1)
height := int(h1) height := int(h1)
fmt.Println(x,x1,y,y1) fmt.Println(x, x1, y, y1)
fileName := "avatar_" + strconv.FormatInt(time.Now().UnixNano(), 16) fileName := "avatar_" + strconv.FormatInt(time.Now().UnixNano(), 16)
filePath := filepath.Join(commands.WorkingDirectory,"uploads" , time.Now().Format("200601") , fileName + ext) filePath := filepath.Join(conf.WorkingDirectory, "uploads", time.Now().Format("200601"), fileName+ext)
path := filepath.Dir(filePath) path := filepath.Dir(filePath)
os.MkdirAll(path, os.ModePerm) os.MkdirAll(path, os.ModePerm)
err = c.SaveToFile("image-file",filePath) err = c.SaveToFile("image-file", filePath)
if err != nil { if err != nil {
logs.Error("",err) logs.Error("", err)
c.JsonResult(500,"图片保存失败") c.JsonResult(500, "图片保存失败")
} }
//剪切图片 //剪切图片
subImg,err := graphics.ImageCopyFromFile(filePath,x,y,width,height) subImg, err := graphics.ImageCopyFromFile(filePath, x, y, width, height)
if err != nil { if err != nil {
logs.Error("ImageCopyFromFile => ",err) logs.Error("ImageCopyFromFile => ", err)
c.JsonResult(6001,"头像剪切失败") c.JsonResult(6001, "头像剪切失败")
} }
os.Remove(filePath) os.Remove(filePath)
filePath = filepath.Join(commands.WorkingDirectory,"uploads" , time.Now().Format("200601") , fileName + "_small" + ext) filePath = filepath.Join(conf.WorkingDirectory, "uploads", time.Now().Format("200601"), fileName+"_small"+ext)
err = graphics.ImageResizeSaveFile(subImg,120,120,filePath) err = graphics.ImageResizeSaveFile(subImg, 120, 120, filePath)
//err = graphics.SaveImage(filePath,subImg) //err = graphics.SaveImage(filePath,subImg)
if err != nil { if err != nil {
logs.Error("保存文件失败 => ",err.Error()) logs.Error("保存文件失败 => ", err.Error())
c.JsonResult(500,"保存文件失败") c.JsonResult(500, "保存文件失败")
} }
url := "/" + strings.Replace(strings.TrimPrefix(filePath,commands.WorkingDirectory),"\\","/",-1) url := "/" + strings.Replace(strings.TrimPrefix(filePath, conf.WorkingDirectory), "\\", "/", -1)
if strings.HasPrefix(url,"//") { if strings.HasPrefix(url, "//") {
url = string(url[1:]) url = string(url[1:])
} }
if member,err := models.NewMember().Find(c.Member.MemberId);err == nil { if member, err := models.NewMember().Find(c.Member.MemberId); err == nil {
avater := member.Avatar avater := member.Avatar
member.Avatar = url member.Avatar = url
err := member.Update(); err := member.Update()
if err == nil { if err == nil {
if strings.HasPrefix(avater,"/uploads/") { if strings.HasPrefix(avater, "/uploads/") {
os.Remove(filepath.Join(commands.WorkingDirectory,avater)) os.Remove(filepath.Join(conf.WorkingDirectory, avater))
} }
c.SetMember(*member) c.SetMember(*member)
}else{ } else {
c.JsonResult(60001,"保存头像失败") c.JsonResult(60001, "保存头像失败")
} }
} }
c.JsonResult(0,"ok",url) c.JsonResult(0, "ok", url)
} }

View File

@ -11,14 +11,12 @@ import (
"strings" "strings"
"time" "time"
"os/exec" "os/exec"
"errors" "errors"
"github.com/TruthHun/gotil/cryptil" "github.com/lifei6671/mindoc/utils/filetil"
"github.com/TruthHun/gotil/filetil" "github.com/lifei6671/mindoc/utils/ziptil"
"github.com/TruthHun/gotil/ziptil" "github.com/lifei6671/mindoc/utils/cryptil"
) )
type Converter struct { type Converter struct {
@ -67,6 +65,7 @@ var (
output = "output" //文档导出文件夹 output = "output" //文档导出文件夹
ebookConvert = "ebook-convert" ebookConvert = "ebook-convert"
) )
// 接口文档 https://manual.calibre-ebook.com/generated/en/ebook-convert.html#table-of-contents // 接口文档 https://manual.calibre-ebook.com/generated/en/ebook-convert.html#table-of-contents
//根据json配置文件创建文档转化对象 //根据json配置文件创建文档转化对象
func NewConverter(configFile string, debug ...bool) (converter *Converter, err error) { func NewConverter(configFile string, debug ...bool) (converter *Converter, err error) {
@ -124,7 +123,8 @@ func (this *Converter) Convert() (err error) {
} }
//将当前文件夹下的所有文件压缩成zip包然后直接改名成content.epub //将当前文件夹下的所有文件压缩成zip包然后直接改名成content.epub
f := this.BasePath + "/content.epub" f := filepath.Join(this.BasePath, "content.epub")
fmt.Println("epub目录 " + f)
os.Remove(f) //如果原文件存在了,则删除; os.Remove(f) //如果原文件存在了,则删除;
if err = ziptil.Zip(f, this.BasePath); err == nil { if err = ziptil.Zip(f, this.BasePath); err == nil {
//创建导出文件夹 //创建导出文件夹
@ -144,6 +144,12 @@ func (this *Converter) Convert() (err error) {
} }
case "pdf": case "pdf":
if err = this.convertToPdf(); err != nil { if err = this.convertToPdf(); err != nil {
fmt.Println(err)
errs = append(errs, err.Error())
}
case "docx":
if err = this.convertToDocx(); err != nil {
fmt.Println(err)
errs = append(errs, err.Error()) errs = append(errs, err.Error())
} }
} }
@ -157,6 +163,8 @@ func (this *Converter) Convert() (err error) {
fmt.Println(err) fmt.Println(err)
} }
} }
} else {
fmt.Println("压缩目录出错" + err.Error())
} }
return return
} }
@ -164,13 +172,13 @@ func (this *Converter) Convert() (err error) {
//删除生成导出文档而创建的文件 //删除生成导出文档而创建的文件
func (this *Converter) converterDefer() { func (this *Converter) converterDefer() {
//删除不必要的文件 //删除不必要的文件
os.RemoveAll(this.BasePath + "/META-INF") os.RemoveAll(filepath.Join(this.BasePath, "META-INF"))
os.RemoveAll(this.BasePath + "/content.epub") os.RemoveAll(filepath.Join(this.BasePath, "content.epub"))
os.RemoveAll(this.BasePath + "/mimetype") os.RemoveAll(filepath.Join(this.BasePath, "mimetype"))
os.RemoveAll(this.BasePath + "/toc.ncx") os.RemoveAll(filepath.Join(this.BasePath, "toc.ncx"))
os.RemoveAll(this.BasePath + "/content.opf") os.RemoveAll(filepath.Join(this.BasePath, "content.opf"))
os.RemoveAll(this.BasePath + "/titlepage.xhtml") //封面图片待优化 os.RemoveAll(filepath.Join(this.BasePath, "titlepage.xhtml")) //封面图片待优化
os.RemoveAll(this.BasePath + "/summary.html") //文档目录 os.RemoveAll(filepath.Join(this.BasePath, "summary.html")) //文档目录
} }
//生成metainfo //生成metainfo
@ -182,15 +190,15 @@ func (this *Converter) generateMetaInfo() (err error) {
</rootfiles> </rootfiles>
</container> </container>
` `
folder := this.BasePath + "/META-INF" folder := filepath.Join(this.BasePath, "META-INF")
os.MkdirAll(folder, os.ModePerm) os.MkdirAll(folder, os.ModePerm)
err = ioutil.WriteFile(folder+"/container.xml", []byte(xml), os.ModePerm) err = ioutil.WriteFile(filepath.Join(folder, "container.xml"), []byte(xml), os.ModePerm)
return return
} }
//形成mimetyppe //形成mimetyppe
func (this *Converter) generateMimeType() (err error) { func (this *Converter) generateMimeType() (err error) {
return ioutil.WriteFile(this.BasePath+"/mimetype", []byte("application/epub+zip"), os.ModePerm) return ioutil.WriteFile(filepath.Join(this.BasePath, "mimetype"), []byte("application/epub+zip"), os.ModePerm)
} }
//生成封面 //生成封面
@ -216,7 +224,7 @@ func (this *Converter) generateTitlePage() (err error) {
</body> </body>
</html> </html>
` `
if err = ioutil.WriteFile(this.BasePath+"/titlepage.xhtml", []byte(xml), os.ModePerm); err == nil { if err = ioutil.WriteFile(filepath.Join(this.BasePath, "titlepage.xhtml"), []byte(xml), os.ModePerm); err == nil {
this.GeneratedCover = "titlepage.xhtml" this.GeneratedCover = "titlepage.xhtml"
} }
} }
@ -241,7 +249,7 @@ func (this *Converter) generateTocNcx() (err error) {
` `
codes, _ := this.tocToXml(0, 1) codes, _ := this.tocToXml(0, 1)
ncx = fmt.Sprintf(ncx, this.Config.Language, this.Config.Title, strings.Join(codes, "")) ncx = fmt.Sprintf(ncx, this.Config.Language, this.Config.Title, strings.Join(codes, ""))
return ioutil.WriteFile(this.BasePath+"/toc.ncx", []byte(ncx), os.ModePerm) return ioutil.WriteFile(filepath.Join(this.BasePath, "toc.ncx"), []byte(ncx), os.ModePerm)
} }
//生成文档目录即summary.html //生成文档目录即summary.html
@ -263,7 +271,7 @@ func (this *Converter) generateSummary() (err error) {
</body> </body>
</html>` </html>`
summary = fmt.Sprintf(summary, strings.Join(this.tocToSummary(0), "")) summary = fmt.Sprintf(summary, strings.Join(this.tocToSummary(0), ""))
return ioutil.WriteFile(this.BasePath+"/summary.html", []byte(summary), os.ModePerm) return ioutil.WriteFile(filepath.Join(this.BasePath, "summary.html"), []byte(summary), os.ModePerm)
} }
//将toc转成toc.ncx文件 //将toc转成toc.ncx文件
@ -380,6 +388,8 @@ func (this *Converter) generateContentOpf() (err error) {
manifestArr = append(manifestArr, fmt.Sprintf(`<item href="%v" id="%v" media-type="%v"/>`, sourcefile, id, mt)) manifestArr = append(manifestArr, fmt.Sprintf(`<item href="%v" id="%v" media-type="%v"/>`, sourcefile, id, mt))
} }
} }
} else {
fmt.Println(file.Path)
} }
} }
@ -415,14 +425,14 @@ func (this *Converter) generateContentOpf() (err error) {
guide = `<guide>` + guide + `</guide>` guide = `<guide>` + guide + `</guide>`
} }
pkg = fmt.Sprintf(pkg, meta, manifest, spine, guide) pkg = fmt.Sprintf(pkg, meta, manifest, spine, guide)
return ioutil.WriteFile(this.BasePath+"/content.opf", []byte(pkg), os.ModePerm) return ioutil.WriteFile(filepath.Join(this.BasePath, "content.opf"), []byte(pkg), os.ModePerm)
} }
//转成epub //转成epub
func (this *Converter) convertToEpub() (err error) { func (this *Converter) convertToEpub() (err error) {
args := []string{ args := []string{
this.BasePath + "/content.epub", filepath.Join(this.BasePath, "content.epub"),
this.BasePath + "/" + output + "/book.epub", filepath.Join(this.BasePath, output, "book.epub"),
} }
cmd := exec.Command(ebookConvert, args...) cmd := exec.Command(ebookConvert, args...)
@ -435,8 +445,8 @@ func (this *Converter) convertToEpub() (err error) {
//转成mobi //转成mobi
func (this *Converter) convertToMobi() (err error) { func (this *Converter) convertToMobi() (err error) {
args := []string{ args := []string{
this.BasePath + "/content.epub", filepath.Join(this.BasePath, "content.epub"),
this.BasePath + "/" + output + "/book.mobi", filepath.Join(this.BasePath, output, "book.mobi"),
} }
cmd := exec.Command(ebookConvert, args...) cmd := exec.Command(ebookConvert, args...)
if this.Debug { if this.Debug {
@ -449,8 +459,8 @@ func (this *Converter) convertToMobi() (err error) {
//转成pdf //转成pdf
func (this *Converter) convertToPdf() (err error) { func (this *Converter) convertToPdf() (err error) {
args := []string{ args := []string{
this.BasePath + "/content.epub", filepath.Join(this.BasePath, "content.epub"),
this.BasePath + "/" + output + "/book.pdf", filepath.Join(this.BasePath, output, "book.pdf"),
} }
//页面大小 //页面大小
if len(this.Config.PaperSize) > 0 { if len(this.Config.PaperSize) > 0 {
@ -490,6 +500,40 @@ func (this *Converter) convertToPdf() (err error) {
} }
cmd := exec.Command(ebookConvert, args...) cmd := exec.Command(ebookConvert, args...)
if this.Debug {
fmt.Println(cmd.Args)
}
return cmd.Run()
}
// 转成word
func (this *Converter) convertToDocx() (err error) {
args := []string{
this.BasePath + "/content.epub",
this.BasePath + "/" + output + "/book.docx",
}
args = append(args, "--docx-no-toc")
//页面大小
if len(this.Config.PaperSize) > 0 {
args = append(args, "--docx-page-size", this.Config.PaperSize)
}
if len(this.Config.MarginLeft) > 0 {
args = append(args, "--docx-page-margin-left", this.Config.MarginLeft)
}
if len(this.Config.MarginTop) > 0 {
args = append(args, "--docx-page-margin-top", this.Config.MarginTop)
}
if len(this.Config.MarginRight) > 0 {
args = append(args, "--docx-page-margin-right", this.Config.MarginRight)
}
if len(this.Config.MarginBottom) > 0 {
args = append(args, "--docx-page-margin-bottom", this.Config.MarginBottom)
}
cmd := exec.Command(ebookConvert, args...)
if this.Debug { if this.Debug {
fmt.Println(cmd.Args) fmt.Println(cmd.Args)
} }

View File

@ -13,7 +13,7 @@ import (
// 将图片保存到指定的路径 // 将图片保存到指定的路径
func SaveImage(p string, src image.Image) error { func SaveImage(p string, src image.Image) error {
os.MkdirAll(filepath.Dir(p),0666) os.MkdirAll(filepath.Dir(p), 0666)
f, err := os.OpenFile(p, os.O_SYNC|os.O_RDWR|os.O_CREATE, 0666) f, err := os.OpenFile(p, os.O_SYNC|os.O_RDWR|os.O_CREATE, 0666)

View File

@ -127,7 +127,7 @@ func (m *Attachment) FindToPager(pageIndex, pageSize int) (attachList []*Attachm
} else { } else {
attach.DocumentName = "[不存在]" attach.DocumentName = "[不存在]"
} }
attach.LocalHttpPath = strings.Replace(item.FilePath,"\\","/",-1) attach.LocalHttpPath = strings.Replace(item.FilePath, "\\", "/", -1)
attachList = append(attachList, attach) attachList = append(attachList, attach)
} }

View File

@ -17,18 +17,18 @@ type AttachmentResult struct {
} }
func NewAttachmentResult() *AttachmentResult { func NewAttachmentResult() *AttachmentResult {
return &AttachmentResult{ IsExist : false } return &AttachmentResult{IsExist: false}
} }
func (m *AttachmentResult) Find(id int) (*AttachmentResult,error) { func (m *AttachmentResult) Find(id int) (*AttachmentResult, error) {
o := orm.NewOrm() o := orm.NewOrm()
attach := NewAttachment() attach := NewAttachment()
err := o.QueryTable(m.TableNameWithPrefix()).Filter("attachment_id",id).One(attach) err := o.QueryTable(m.TableNameWithPrefix()).Filter("attachment_id", id).One(attach)
if err != nil { if err != nil {
return m,err return m, err
} }
m.Attachment = *attach m.Attachment = *attach
@ -50,12 +50,12 @@ func (m *AttachmentResult) Find(id int) (*AttachmentResult,error) {
if attach.CreateAt > 0 { if attach.CreateAt > 0 {
member := NewMember() member := NewMember()
if e := o.QueryTable(member.TableNameWithPrefix()).Filter("member_id",attach.CreateAt).One(member,"account");e == nil { if e := o.QueryTable(member.TableNameWithPrefix()).Filter("member_id", attach.CreateAt).One(member, "account"); e == nil {
m.Account = member.Account m.Account = member.Account
} }
} }
m.FileShortSize = utils.FormatBytes(int64(attach.FileSize)) m.FileShortSize = utils.FormatBytes(int64(attach.FileSize))
m.LocalHttpPath = strings.Replace(m.FilePath,"\\","/",-1) m.LocalHttpPath = strings.Replace(m.FilePath, "\\", "/", -1)
return m,nil return m, nil
} }

View File

@ -1,6 +1,4 @@
package models package models
type Model struct { type Model struct {
} }

View File

@ -3,11 +3,14 @@ package models
import ( import (
"time" "time"
"fmt"
"github.com/astaxie/beego" "github.com/astaxie/beego"
"github.com/astaxie/beego/logs" "github.com/astaxie/beego/logs"
"github.com/astaxie/beego/orm" "github.com/astaxie/beego/orm"
"github.com/lifei6671/mindoc/conf" "github.com/lifei6671/mindoc/conf"
"fmt" "os"
"path/filepath"
"strconv"
) )
// Book struct . // Book struct .
@ -24,8 +27,6 @@ type Book struct {
Description string `orm:"column(description);size(2000)" json:"description"` Description string `orm:"column(description);size(2000)" json:"description"`
//发行公司 //发行公司
Publisher string `orm:"column(publisher);size(500)" json:"publisher"` Publisher string `orm:"column(publisher);size(500)" json:"publisher"`
//是否缓存导出的电子书,如果缓存可能会出现导出的文件不是最新的。 0 为不缓存
IsCacheEBook int `orm:"column(is_cache_ebook);type(int);default(0)" json:"is_cache_ebook"`
Label string `orm:"column(label);size(500)" json:"label"` Label string `orm:"column(label);size(500)" json:"label"`
// PrivatelyOwned 项目私有: 0 公开/ 1 私有 // PrivatelyOwned 项目私有: 0 公开/ 1 私有
PrivatelyOwned int `orm:"column(privately_owned);type(int);default(0)" json:"privately_owned"` PrivatelyOwned int `orm:"column(privately_owned);type(int);default(0)" json:"privately_owned"`
@ -122,7 +123,7 @@ func (m *Book) Update(cols ...string) error {
temp := NewBook() temp := NewBook()
temp.BookId = m.BookId temp.BookId = m.BookId
if err := o.Read(temp);err != nil { if err := o.Read(temp); err != nil {
return err return err
} }
@ -185,7 +186,7 @@ func (m *Book) FindToPager(pageIndex, pageSize, memberId int) (books []*BookResu
" LEFT JOIN " + relationship.TableNameWithPrefix() + " AS rel ON book.book_id=rel.book_id AND rel.member_id = ?" + " LEFT JOIN " + relationship.TableNameWithPrefix() + " AS rel ON book.book_id=rel.book_id AND rel.member_id = ?" +
" LEFT JOIN " + relationship.TableNameWithPrefix() + " AS rel1 ON book.book_id=rel1.book_id AND rel1.role_id=0" + " LEFT JOIN " + relationship.TableNameWithPrefix() + " AS rel1 ON book.book_id=rel1.book_id AND rel1.role_id=0" +
" LEFT JOIN " + NewMember().TableNameWithPrefix() + " AS m ON rel1.member_id=m.member_id " + " LEFT JOIN " + NewMember().TableNameWithPrefix() + " AS m ON rel1.member_id=m.member_id " +
" WHERE rel.relationship_id > 0 ORDER BY book.order_index DESC,book.book_id DESC LIMIT " + fmt.Sprintf("%d,%d",offset,pageSize) " WHERE rel.relationship_id > 0 ORDER BY book.order_index DESC,book.book_id DESC LIMIT " + fmt.Sprintf("%d,%d", offset, pageSize)
_, err = o.Raw(sql2, memberId).QueryRows(&books) _, err = o.Raw(sql2, memberId).QueryRows(&books)
if err != nil { if err != nil {
@ -261,6 +262,8 @@ func (m *Book) ThoroughDeleteBook(id int) error {
NewLabel().InsertOrUpdateMulti(m.Label) NewLabel().InsertOrUpdateMulti(m.Label)
} }
os.RemoveAll(filepath.Join(conf.WorkingDirectory,"uploads","books",strconv.Itoa(id)))
return o.Commit() return o.Commit()
} }
@ -320,7 +323,7 @@ func (m *Book) FindForLabelToPager(keyword string, pageIndex, pageSize, member_i
if member_id > 0 { if member_id > 0 {
sql1 := "SELECT COUNT(*) FROM md_books AS book LEFT JOIN md_relationship AS rel ON rel.book_id = book.book_id AND rel.member_id = ? WHERE (relationship_id > 0 OR book.privately_owned = 0) AND book.label LIKE ?" sql1 := "SELECT COUNT(*) FROM md_books AS book LEFT JOIN md_relationship AS rel ON rel.book_id = book.book_id AND rel.member_id = ? WHERE (relationship_id > 0 OR book.privately_owned = 0) AND book.label LIKE ?"
err = o.Raw(sql1, member_id,keyword).QueryRow(&totalCount) err = o.Raw(sql1, member_id, keyword).QueryRow(&totalCount)
if err != nil { if err != nil {
return return
} }
@ -330,12 +333,12 @@ func (m *Book) FindForLabelToPager(keyword string, pageIndex, pageSize, member_i
LEFT JOIN md_members AS member ON rel1.member_id = member.member_id LEFT JOIN md_members AS member ON rel1.member_id = member.member_id
WHERE (rel.relationship_id > 0 OR book.privately_owned = 0) AND book.label LIKE ? ORDER BY order_index DESC ,book.book_id DESC LIMIT ?,?` WHERE (rel.relationship_id > 0 OR book.privately_owned = 0) AND book.label LIKE ? ORDER BY order_index DESC ,book.book_id DESC LIMIT ?,?`
_, err = o.Raw(sql2, member_id,keyword, offset, pageSize).QueryRows(&books) _, err = o.Raw(sql2, member_id, keyword, offset, pageSize).QueryRows(&books)
return return
} else { } else {
count, err1 := o.QueryTable(NewBook().TableNameWithPrefix()).Filter("privately_owned", 0).Filter("label__icontains",keyword).Count() count, err1 := o.QueryTable(NewBook().TableNameWithPrefix()).Filter("privately_owned", 0).Filter("label__icontains", keyword).Count()
if err1 != nil { if err1 != nil {
err = err1 err = err1
@ -348,14 +351,13 @@ func (m *Book) FindForLabelToPager(keyword string, pageIndex, pageSize, member_i
LEFT JOIN md_members AS member ON rel.member_id = member.member_id LEFT JOIN md_members AS member ON rel.member_id = member.member_id
WHERE book.privately_owned = 0 AND book.label LIKE ? ORDER BY order_index DESC ,book.book_id DESC LIMIT ?,?` WHERE book.privately_owned = 0 AND book.label LIKE ? ORDER BY order_index DESC ,book.book_id DESC LIMIT ?,?`
_, err = o.Raw(sql,keyword, offset, pageSize).QueryRows(&books) _, err = o.Raw(sql, keyword, offset, pageSize).QueryRows(&books)
return return
} }
} }
//重置文档数量 //重置文档数量
func (m *Book) ResetDocumentNumber(book_id int) { func (m *Book) ResetDocumentNumber(book_id int) {
o := orm.NewOrm() o := orm.NewOrm()

View File

@ -1,21 +1,23 @@
package models package models
import ( import (
"time"
"bytes" "bytes"
"time"
"github.com/astaxie/beego/orm" "io/ioutil"
"github.com/astaxie/beego/logs"
"github.com/lifei6671/mindoc/conf"
"strings"
"github.com/lifei6671/mindoc/converter"
"strconv"
"github.com/russross/blackfriday"
"path/filepath"
"github.com/astaxie/beego"
"os" "os"
"path/filepath"
"strconv"
"strings"
"encoding/base64"
"github.com/PuerkitoBio/goquery" "github.com/PuerkitoBio/goquery"
"github.com/astaxie/beego"
"github.com/astaxie/beego/logs"
"github.com/astaxie/beego/orm"
"github.com/lifei6671/mindoc/conf"
"github.com/lifei6671/mindoc/converter"
"github.com/lifei6671/mindoc/utils" "github.com/lifei6671/mindoc/utils"
"github.com/russross/blackfriday"
) )
type BookResult struct { type BookResult struct {
@ -25,7 +27,6 @@ type BookResult struct {
OrderIndex int `json:"order_index"` OrderIndex int `json:"order_index"`
Description string `json:"description"` Description string `json:"description"`
Publisher string `json:"publisher"` Publisher string `json:"publisher"`
IsCacheEBook bool `json:"is_cache_ebook"`
PrivatelyOwned int `json:"privately_owned"` PrivatelyOwned int `json:"privately_owned"`
PrivateToken string `json:"private_token"` PrivateToken string `json:"private_token"`
DocCount int `json:"doc_count"` DocCount int `json:"doc_count"`
@ -54,11 +55,10 @@ func NewBookResult() *BookResult {
return &BookResult{} return &BookResult{}
} }
// 根据项目标识查询项目以及指定用户权限的信息. // 根据项目标识查询项目以及指定用户权限的信息.
func (m *BookResult) FindByIdentify(identify string,member_id int) (*BookResult,error) { func (m *BookResult) FindByIdentify(identify string, member_id int) (*BookResult, error) {
if identify == "" || member_id <= 0 { if identify == "" || member_id <= 0 {
return m,ErrInvalidParameter return m, ErrInvalidParameter
} }
o := orm.NewOrm() o := orm.NewOrm()
@ -98,7 +98,6 @@ func (m *BookResult) FindByIdentify(identify string,member_id int) (*BookResult,
m.RoleId = relationship.RoleId m.RoleId = relationship.RoleId
m.RelationshipId = relationship.RelationshipId m.RelationshipId = relationship.RelationshipId
if m.RoleId == conf.BookFounder { if m.RoleId == conf.BookFounder {
m.RoleName = "创始人" m.RoleName = "创始人"
} else if m.RoleId == conf.BookAdmin { } else if m.RoleId == conf.BookAdmin {
@ -123,10 +122,10 @@ func (m *BookResult) FindByIdentify(identify string,member_id int) (*BookResult,
return m, nil return m, nil
} }
func (m *BookResult) FindToPager(pageIndex, pageSize int) (books []*BookResult,totalCount int,err error) { func (m *BookResult) FindToPager(pageIndex, pageSize int) (books []*BookResult, totalCount int, err error) {
o := orm.NewOrm() o := orm.NewOrm()
count,err := o.QueryTable(NewBook().TableNameWithPrefix()).Count() count, err := o.QueryTable(NewBook().TableNameWithPrefix()).Count()
if err != nil { if err != nil {
return return
@ -140,9 +139,9 @@ func (m *BookResult) FindToPager(pageIndex, pageSize int) (books []*BookResult,t
LEFT JOIN md_members AS m ON rel.member_id = m.member_id LEFT JOIN md_members AS m ON rel.member_id = m.member_id
ORDER BY book.order_index DESC ,book.book_id DESC LIMIT ?,?` ORDER BY book.order_index DESC ,book.book_id DESC LIMIT ?,?`
offset := (pageIndex -1 )* pageSize offset := (pageIndex - 1) * pageSize
_,err = o.Raw(sql,offset,pageSize).QueryRows(&books) _, err = o.Raw(sql, offset, pageSize).QueryRows(&books)
return return
} }
@ -169,7 +168,6 @@ func (m *BookResult) ToBookResult(book Book) *BookResult {
m.Theme = book.Theme m.Theme = book.Theme
m.AutoRelease = book.AutoRelease == 1 m.AutoRelease = book.AutoRelease == 1
m.Publisher = book.Publisher m.Publisher = book.Publisher
m.IsCacheEBook = book.IsCacheEBook == 1
if book.Theme == "" { if book.Theme == "" {
m.Theme = "default" m.Theme = "default"
@ -180,33 +178,40 @@ func (m *BookResult) ToBookResult(book Book) *BookResult {
return m return m
} }
func (m *BookResult) Converter(sessionId string) (ConvertBookResult,error) { func (m *BookResult) Converter(sessionId string) (ConvertBookResult, error) {
convertBookResult := ConvertBookResult{} convertBookResult := ConvertBookResult{}
outputPath := filepath.Join(beego.AppConfig.DefaultString("book_output_path","cache"),sessionId,strconv.Itoa(m.BookId))
if m.IsCacheEBook { outputPath := filepath.Join(conf.WorkingDirectory,"uploads","books", strconv.Itoa(m.BookId))
outputPath = filepath.Join(beego.AppConfig.DefaultString("book_output_path","cache"),strconv.Itoa(m.BookId)) viewPath := beego.BConfig.WebConfig.ViewsPath
}
if m.IsCacheEBook { pdfpath := filepath.Join(outputPath, "book.pdf")
pdfpath := filepath.Join(outputPath,"output","book.pdf") epubpath := filepath.Join(outputPath, "book.epub")
epubpath := filepath.Join(outputPath,"output","book.epub") mobipath := filepath.Join(outputPath, "book.mobi")
mobipath := filepath.Join(outputPath,"output","book.mobi") docxpath := filepath.Join(outputPath, "book.docx")
if utils.FileExists(pdfpath) && utils.FileExists(epubpath) && utils.FileExists(mobipath){ //先将转换的文件储存到临时目录
tempOutputPath := filepath.Join(os.TempDir(),"sessionId") //filepath.Abs(filepath.Join("cache", sessionId))
os.MkdirAll(outputPath, 0766)
os.MkdirAll(tempOutputPath, 0766)
if utils.FileExists(pdfpath) && utils.FileExists(epubpath) && utils.FileExists(mobipath) && utils.FileExists(docxpath) {
convertBookResult.EpubPath = epubpath convertBookResult.EpubPath = epubpath
convertBookResult.MobiPath = mobipath convertBookResult.MobiPath = mobipath
convertBookResult.PDFPath = pdfpath convertBookResult.PDFPath = pdfpath
return convertBookResult,nil convertBookResult.WordPath = docxpath
} return convertBookResult, nil
}
docs, err := NewDocument().FindListByBookId(m.BookId)
if err != nil {
return convertBookResult,err
} }
tocList := make([]converter.Toc,0)
docs, err := NewDocument().FindListByBookId(m.BookId)
if err != nil {
return convertBookResult, err
}
tocList := make([]converter.Toc, 0)
for _, item := range docs { for _, item := range docs {
if item.ParentId == 0 { if item.ParentId == 0 {
@ -217,7 +222,7 @@ func (m *BookResult) Converter(sessionId string) (ConvertBookResult,error) {
Title: item.DocumentName, Title: item.DocumentName,
} }
tocList = append(tocList,toc) tocList = append(tocList, toc)
} }
} }
for _, item := range docs { for _, item := range docs {
@ -228,80 +233,84 @@ func (m *BookResult) Converter(sessionId string) (ConvertBookResult,error) {
Pid: item.ParentId, Pid: item.ParentId,
Title: item.DocumentName, Title: item.DocumentName,
} }
tocList = append(tocList,toc) tocList = append(tocList, toc)
} }
} }
ebookConfig := converter.Config{ ebookConfig := converter.Config{
Charset : "utf-8", Charset: "utf-8",
Cover : m.Cover, Cover: m.Cover,
Timestamp : time.Now().Format("2006-01-02 15:04:05"), Timestamp: time.Now().Format("2006-01-02 15:04:05"),
Description : string(blackfriday.MarkdownBasic([]byte(m.Description))), Description: string(blackfriday.MarkdownBasic([]byte(m.Description))),
Footer : "<p style='color:#8E8E8E;font-size:12px;'>本文档使用 <a href='https://www.iminho.me' style='text-decoration:none;color:#1abc9c;font-weight:bold;'>MinDoc</a> 构建 <span style='float:right'>- _PAGENUM_ -</span></p>", Footer: "<p style='color:#8E8E8E;font-size:12px;'>本文档使用 <a href='https://www.iminho.me' style='text-decoration:none;color:#1abc9c;font-weight:bold;'>MinDoc</a> 构建 <span style='float:right'>- _PAGENUM_ -</span></p>",
Header : "<p style='color:#8E8E8E;font-size:12px;'>_SECTION_</p>", Header: "<p style='color:#8E8E8E;font-size:12px;'>_SECTION_</p>",
Identifier : "", Identifier: "",
Language : "zh-CN", Language: "zh-CN",
Creator : m.CreateName, Creator: m.CreateName,
Publisher : m.Publisher, Publisher: m.Publisher,
Contributor : m.Publisher, Contributor: m.Publisher,
Title : m.BookName, Title: m.BookName,
Format: []string{"epub", "mobi", "pdf"}, Format: []string{"epub", "mobi", "pdf", "docx"},
FontSize : "14", FontSize: "14",
PaperSize : "a4", PaperSize: "a4",
MarginLeft : "72", MarginLeft: "72",
MarginRight : "72", MarginRight: "72",
MarginTop : "72", MarginTop: "72",
MarginBottom : "72", MarginBottom: "72",
Toc : tocList, Toc: tocList,
More : []string{}, More: []string{},
} }
if tempOutputPath, err = filepath.Abs(tempOutputPath); err != nil {
os.MkdirAll(outputPath, 0766)
if outputPath, err = filepath.Abs(outputPath); err != nil {
beego.Error("导出目录配置错误:" + err.Error()) beego.Error("导出目录配置错误:" + err.Error())
return convertBookResult,err return convertBookResult, err
} }
viewPath := beego.BConfig.WebConfig.ViewsPath for _, item := range docs {
baseUrl := beego.AppConfig.DefaultString("baseurl","")
for _,item := range docs {
name := strconv.Itoa(item.DocumentId) name := strconv.Itoa(item.DocumentId)
fpath := filepath.Join(outputPath,name + ".html") fpath := filepath.Join(tempOutputPath, name+".html")
f, err := os.OpenFile(fpath, os.O_CREATE|os.O_RDWR, 0777) f, err := os.OpenFile(fpath, os.O_CREATE|os.O_RDWR, 0777)
if err != nil { if err != nil {
return convertBookResult,err return convertBookResult, err
} }
var buf bytes.Buffer var buf bytes.Buffer
if err := beego.ExecuteViewPathTemplate(&buf,"document/export.tpl",viewPath,map[string]interface{}{"Model": m, "Lists": item, "BaseUrl": baseUrl}); err != nil { if err := beego.ExecuteViewPathTemplate(&buf, "document/export.tpl", viewPath, map[string]interface{}{"Model": m, "Lists": item, "BaseUrl": conf.BaseUrl}); err != nil {
return convertBookResult,err return convertBookResult, err
} }
html := buf.String() html := buf.String()
if err != nil { if err != nil {
f.Close() f.Close()
return convertBookResult,err return convertBookResult, err
} }
bufio := bytes.NewReader(buf.Bytes()) bufio := bytes.NewReader(buf.Bytes())
doc, err := goquery.NewDocumentFromReader(bufio) doc, err := goquery.NewDocumentFromReader(bufio)
doc.Find("img").Each(func(i int, contentSelection *goquery.Selection) { doc.Find("img").Each(func(i int, contentSelection *goquery.Selection) {
if src, ok := contentSelection.Attr("src"); ok && strings.HasPrefix(src, "/uploads/") { if src, ok := contentSelection.Attr("src"); ok && strings.HasPrefix(src, "/") {
contentSelection.SetAttr("src", baseUrl + src) //contentSelection.SetAttr("src", baseUrl + src)
spath := filepath.Join(conf.WorkingDirectory, src)
if ff, e := ioutil.ReadFile(spath); e == nil {
encodeString := base64.StdEncoding.EncodeToString(ff)
src = "data:image/" + filepath.Ext(src) + ";base64," + encodeString
contentSelection.SetAttr("src", src)
}
} }
}) })
html, err = doc.Html() html, err = doc.Html()
if err != nil { if err != nil {
f.Close() f.Close()
return convertBookResult,err return convertBookResult, err
} }
// html = strings.Replace(html, "<img src=\"/uploads", "<img src=\"" + c.BaseUrl() + "/uploads", -1) // html = strings.Replace(html, "<img src=\"/uploads", "<img src=\"" + c.BaseUrl() + "/uploads", -1)
@ -310,35 +319,29 @@ func (m *BookResult) Converter(sessionId string) (ConvertBookResult,error) {
f.Close() f.Close()
} }
eBookConverter := &converter.Converter{ eBookConverter := &converter.Converter{
BasePath : outputPath, BasePath: tempOutputPath,
Config : ebookConfig, Config: ebookConfig,
Debug : false, Debug: true,
} }
if err := eBookConverter.Convert();err != nil { if err := eBookConverter.Convert(); err != nil {
beego.Error("转换文件错误:" + m.BookName +" => "+ err.Error()) beego.Error("转换文件错误:" + m.BookName + " => " + err.Error())
return convertBookResult,err return convertBookResult, err
} }
convertBookResult.MobiPath = filepath.Join(outputPath,"output","book.mobi") beego.Info("文档转换完成:" + m.BookName)
convertBookResult.PDFPath = filepath.Join(outputPath,"output","book.pdf") defer func(p string) {
convertBookResult.EpubPath = filepath.Join(outputPath,"output","book.epub") os.RemoveAll(p)
return convertBookResult,nil }(tempOutputPath)
utils.CopyFile(mobipath, filepath.Join(tempOutputPath, "output", "book.mobi"))
utils.CopyFile(pdfpath, filepath.Join(tempOutputPath, "output", "book.pdf"))
utils.CopyFile(epubpath, filepath.Join(tempOutputPath, "output", "book.epub"))
utils.CopyFile(docxpath, filepath.Join(tempOutputPath, "output", "book.docx"))
convertBookResult.MobiPath = mobipath
convertBookResult.PDFPath = pdfpath
convertBookResult.EpubPath = epubpath
convertBookResult.WordPath = docxpath
return convertBookResult, nil
} }

View File

@ -1,10 +1,10 @@
package models package models
import ( import (
"time"
"github.com/lifei6671/mindoc/conf"
"github.com/astaxie/beego/orm"
"errors" "errors"
"github.com/astaxie/beego/orm"
"github.com/lifei6671/mindoc/conf"
"time"
) )
//Comment struct //Comment struct
@ -38,6 +38,7 @@ type Comment struct {
func (m *Comment) TableName() string { func (m *Comment) TableName() string {
return "comments" return "comments"
} }
// TableEngine 获取数据使用的引擎. // TableEngine 获取数据使用的引擎.
func (m *Comment) TableEngine() string { func (m *Comment) TableEngine() string {
return "INNODB" return "INNODB"
@ -50,27 +51,27 @@ func (m *Comment) TableNameWithPrefix() string {
func NewComment() *Comment { func NewComment() *Comment {
return &Comment{} return &Comment{}
} }
func (m *Comment) Find(id int) (*Comment,error) { func (m *Comment) Find(id int) (*Comment, error) {
if id <= 0 { if id <= 0 {
return m,ErrInvalidParameter return m, ErrInvalidParameter
} }
o := orm.NewOrm() o := orm.NewOrm()
err := o.Read(m) err := o.Read(m)
return m,err return m, err
} }
func (m *Comment) Update(cols... string) error { func (m *Comment) Update(cols ...string) error {
o := orm.NewOrm() o := orm.NewOrm()
_,err := o.Update(m,cols...) _, err := o.Update(m, cols...)
return err return err
} }
//Insert 添加一条评论. //Insert 添加一条评论.
func (m *Comment) Insert() error { func (m *Comment) Insert() error {
if m.DocumentId <= 0{ if m.DocumentId <= 0 {
return errors.New("评论文档不存在") return errors.New("评论文档不存在")
} }
if m.Content == "" { if m.Content == "" {
@ -89,28 +90,28 @@ func (m *Comment) Insert() error {
document := NewDocument() document := NewDocument()
//如果评论的文档不存在 //如果评论的文档不存在
if _,err := document.Find(m.DocumentId); err != nil { if _, err := document.Find(m.DocumentId); err != nil {
return err return err
} }
book ,err := NewBook().Find(document.BookId); book, err := NewBook().Find(document.BookId)
//如果评论的项目不存在 //如果评论的项目不存在
if err != nil { if err != nil {
return err return err
} }
//如果已关闭评论 //如果已关闭评论
if book.CommentStatus == "closed"{ if book.CommentStatus == "closed" {
return ErrCommentClosed return ErrCommentClosed
} }
if book.CommentStatus == "registered_only" && m.MemberId <= 0{ if book.CommentStatus == "registered_only" && m.MemberId <= 0 {
return ErrPermissionDenied return ErrPermissionDenied
} }
//如果仅参与者评论 //如果仅参与者评论
if book.CommentStatus == "group_only" { if book.CommentStatus == "group_only" {
if m.MemberId <= 0{ if m.MemberId <= 0 {
return ErrPermissionDenied return ErrPermissionDenied
} }
rel := NewRelationship() rel := NewRelationship()
if _,err := rel.FindForRoleId(book.BookId,m.MemberId);err != nil { if _, err := rel.FindForRoleId(book.BookId, m.MemberId); err != nil {
return ErrPermissionDenied return ErrPermissionDenied
} }
} }
@ -118,51 +119,18 @@ func (m *Comment) Insert() error {
if m.MemberId > 0 { if m.MemberId > 0 {
member := NewMember() member := NewMember()
//如果用户不存在 //如果用户不存在
if _,err := member.Find(m.MemberId) ; err != nil { if _, err := member.Find(m.MemberId); err != nil {
return ErrMemberNoExist return ErrMemberNoExist
} }
//如果用户被禁用 //如果用户被禁用
if member.Status == 1 { if member.Status == 1 {
return ErrMemberDisabled return ErrMemberDisabled
} }
}else if m.Author == "" { } else if m.Author == "" {
m.Author = "[匿名用户]" m.Author = "[匿名用户]"
} }
m.BookId = book.BookId m.BookId = book.BookId
_,err = o.Insert(m) _, err = o.Insert(m)
return err return err
} }

View File

@ -8,7 +8,7 @@ type CommentResult struct {
ReplyAccount string `json:"reply_account"` ReplyAccount string `json:"reply_account"`
} }
func (m *CommentResult) FindForDocumentToPager(doc_id, page_index,page_size int) (comments []*CommentResult,totalCount int,err error) { func (m *CommentResult) FindForDocumentToPager(doc_id, page_index, page_size int) (comments []*CommentResult, totalCount int, err error) {
o := orm.NewOrm() o := orm.NewOrm()
@ -25,12 +25,11 @@ FROM md_comments AS comment
WHERE comment.document_id = ? ORDER BY comment.comment_id DESC LIMIT 0,10` WHERE comment.document_id = ? ORDER BY comment.comment_id DESC LIMIT 0,10`
offset := (page_index - 1) * page_size offset := (page_index - 1) * page_size
_,err = o.Raw(sql1,doc_id,offset, page_size).QueryRows(&comments) _, err = o.Raw(sql1, doc_id, offset, page_size).QueryRows(&comments)
v,err := o.QueryTable(m.TableNameWithPrefix()).Filter("document_id",doc_id).Count() v, err := o.QueryTable(m.TableNameWithPrefix()).Filter("document_id", doc_id).Count()
if err == nil { if err == nil {
totalCount = int(v) totalCount = int(v)
@ -38,4 +37,3 @@ WHERE comment.document_id = ? ORDER BY comment.comment_id DESC LIMIT 0,10`
return return
} }

View File

@ -1,9 +1,9 @@
package models package models
import ( import (
"time"
"github.com/lifei6671/mindoc/conf"
"github.com/astaxie/beego/orm" "github.com/astaxie/beego/orm"
"github.com/lifei6671/mindoc/conf"
"time"
) )
type CommentVote struct { type CommentVote struct {
@ -19,6 +19,7 @@ type CommentVote struct {
func (m *CommentVote) TableName() string { func (m *CommentVote) TableName() string {
return "comment_votes" return "comment_votes"
} }
// TableEngine 获取数据使用的引擎. // TableEngine 获取数据使用的引擎.
func (m *CommentVote) TableEngine() string { func (m *CommentVote) TableEngine() string {
return "INNODB" return "INNODB"
@ -35,15 +36,15 @@ func (u *CommentVote) TableUnique() [][]string {
func NewCommentVote() *CommentVote { func NewCommentVote() *CommentVote {
return &CommentVote{} return &CommentVote{}
} }
func (m *CommentVote) InsertOrUpdate() (*CommentVote,error) { func (m *CommentVote) InsertOrUpdate() (*CommentVote, error) {
o := orm.NewOrm() o := orm.NewOrm()
if m.VoteId > 0 { if m.VoteId > 0 {
_,err := o.Update(m) _, err := o.Update(m)
return m,err return m, err
}else{ } else {
_,err := o.Insert(m) _, err := o.Insert(m)
return m,err return m, err
} }
} }

View File

@ -5,4 +5,5 @@ type ConvertBookResult struct {
PDFPath string PDFPath string
EpubPath string EpubPath string
MobiPath string MobiPath string
WordPath string
} }

View File

@ -14,23 +14,23 @@ func NewDashboard() *Dashboard {
return &Dashboard{} return &Dashboard{}
} }
func (m *Dashboard) Query() (*Dashboard) { func (m *Dashboard) Query() *Dashboard {
o := orm.NewOrm() o := orm.NewOrm()
book_number,_ := o.QueryTable(NewBook().TableNameWithPrefix()).Count() book_number, _ := o.QueryTable(NewBook().TableNameWithPrefix()).Count()
m.BookNumber = book_number m.BookNumber = book_number
document_count,_ := o.QueryTable(NewDocument().TableNameWithPrefix()).Count() document_count, _ := o.QueryTable(NewDocument().TableNameWithPrefix()).Count()
m.DocumentNumber = document_count m.DocumentNumber = document_count
member_number,_ := o.QueryTable(NewMember().TableNameWithPrefix()).Count() member_number, _ := o.QueryTable(NewMember().TableNameWithPrefix()).Count()
m.MemberNumber = member_number m.MemberNumber = member_number
//comment_number,_ := o.QueryTable(NewComment().TableNameWithPrefix()).Count() //comment_number,_ := o.QueryTable(NewComment().TableNameWithPrefix()).Count()
m.CommentNumber = 0 m.CommentNumber = 0
attachment_number,_ := o.QueryTable(NewAttachment().TableNameWithPrefix()).Count() attachment_number, _ := o.QueryTable(NewAttachment().TableNameWithPrefix()).Count()
m.AttachmentNumber = attachment_number m.AttachmentNumber = attachment_number

View File

@ -9,6 +9,9 @@ import (
"github.com/astaxie/beego/orm" "github.com/astaxie/beego/orm"
"github.com/lifei6671/mindoc/conf" "github.com/lifei6671/mindoc/conf"
"strings" "strings"
"os"
"path/filepath"
"strconv"
) )
// Document struct. // Document struct.
@ -121,12 +124,12 @@ func (m *Document) RecursiveDocument(doc_id int) error {
} }
//发布文档 //发布文档
func (m *Document) ReleaseContent(book_id int) { func (m *Document) ReleaseContent(bookId int) {
o := orm.NewOrm() o := orm.NewOrm()
var docs []*Document var docs []*Document
_, err := o.QueryTable(m.TableNameWithPrefix()).Filter("book_id", book_id).All(&docs, "document_id", "content") _, err := o.QueryTable(m.TableNameWithPrefix()).Filter("book_id", bookId).All(&docs, "document_id", "content")
if err != nil { if err != nil {
beego.Error("发布失败 => ", err) beego.Error("发布失败 => ", err)
@ -134,12 +137,12 @@ func (m *Document) ReleaseContent(book_id int) {
} }
for _, item := range docs { for _, item := range docs {
item.Release = item.Content item.Release = item.Content
attach_list, err := NewAttachment().FindListByDocumentId(item.DocumentId) attachList, err := NewAttachment().FindListByDocumentId(item.DocumentId)
if err == nil && len(attach_list) > 0 { if err == nil && len(attachList) > 0 {
content := bytes.NewBufferString("<div class=\"attach-list\"><strong>附件</strong><ul>") content := bytes.NewBufferString("<div class=\"attach-list\"><strong>附件</strong><ul>")
for _, attach := range attach_list { for _, attach := range attachList {
if strings.HasPrefix(attach.HttpPath,"/"){ if strings.HasPrefix(attach.HttpPath, "/") {
attach.HttpPath = strings.TrimSuffix(beego.AppConfig.DefaultString("baseurl",""),"/") + attach.HttpPath attach.HttpPath = strings.TrimSuffix(beego.AppConfig.DefaultString("baseurl", ""), "/") + attach.HttpPath
} }
li := fmt.Sprintf("<li><a href=\"%s\" target=\"_blank\" title=\"%s\">%s</a></li>", attach.HttpPath, attach.FileName, attach.FileName) li := fmt.Sprintf("<li><a href=\"%s\" target=\"_blank\" title=\"%s\">%s</a></li>", attach.HttpPath, attach.FileName, attach.FileName)
@ -151,6 +154,8 @@ func (m *Document) ReleaseContent(book_id int) {
_, err = o.Update(item, "release") _, err = o.Update(item, "release")
if err != nil { if err != nil {
beego.Error(fmt.Sprintf("发布失败 => %+v", item), err) beego.Error(fmt.Sprintf("发布失败 => %+v", item), err)
}else {
os.RemoveAll(filepath.Join(conf.WorkingDirectory,"uploads","books",strconv.Itoa(bookId)))
} }
} }
} }

View File

@ -50,12 +50,13 @@ func (m *DocumentHistory) TableNameWithPrefix() string {
func NewDocumentHistory() *DocumentHistory { func NewDocumentHistory() *DocumentHistory {
return &DocumentHistory{} return &DocumentHistory{}
} }
func (m *DocumentHistory) Find(id int) (*DocumentHistory,error) { func (m *DocumentHistory) Find(id int) (*DocumentHistory, error) {
o := orm.NewOrm() o := orm.NewOrm()
err := o.QueryTable(m.TableNameWithPrefix()).Filter("history_id",id).One(m) err := o.QueryTable(m.TableNameWithPrefix()).Filter("history_id", id).One(m)
return m,err return m, err
} }
//清空指定文档的历史. //清空指定文档的历史.
func (m *DocumentHistory) Clear(doc_id int) error { func (m *DocumentHistory) Clear(doc_id int) error {
o := orm.NewOrm() o := orm.NewOrm()
@ -66,19 +67,19 @@ func (m *DocumentHistory) Clear(doc_id int) error {
} }
//删除历史. //删除历史.
func (m *DocumentHistory) Delete(history_id,doc_id int) error { func (m *DocumentHistory) Delete(history_id, doc_id int) error {
o := orm.NewOrm() o := orm.NewOrm()
_, err := o.QueryTable(m.TableNameWithPrefix()).Filter("history_id",history_id).Filter("document_id",doc_id).Delete() _, err := o.QueryTable(m.TableNameWithPrefix()).Filter("history_id", history_id).Filter("document_id", doc_id).Delete()
return err return err
} }
//恢复指定历史的文档. //恢复指定历史的文档.
func (m *DocumentHistory) Restore(history_id,doc_id,uid int) error { func (m *DocumentHistory) Restore(history_id, doc_id, uid int) error {
o := orm.NewOrm() o := orm.NewOrm()
err := o.QueryTable(m.TableNameWithPrefix()).Filter("history_id", history_id).Filter("document_id",doc_id).One(m) err := o.QueryTable(m.TableNameWithPrefix()).Filter("history_id", history_id).Filter("document_id", doc_id).One(m)
if err != nil { if err != nil {
return err return err
@ -113,17 +114,18 @@ func (m *DocumentHistory) Restore(history_id,doc_id,uid int) error {
return err return err
} }
func (m *DocumentHistory) InsertOrUpdate() (history *DocumentHistory,err error) { func (m *DocumentHistory) InsertOrUpdate() (history *DocumentHistory, err error) {
o := orm.NewOrm() o := orm.NewOrm()
history = m history = m
if m.HistoryId > 0 { if m.HistoryId > 0 {
_,err = o.Update(m) _, err = o.Update(m)
}else{ } else {
_,err = o.Insert(m) _, err = o.Insert(m)
} }
return return
} }
//分页查询指定文档的历史. //分页查询指定文档的历史.
func (m *DocumentHistory) FindToPager(doc_id, page_index, page_size int) (docs []*DocumentHistorySimpleResult, totalCount int, err error) { func (m *DocumentHistory) FindToPager(doc_id, page_index, page_size int) (docs []*DocumentHistorySimpleResult, totalCount int, err error) {
@ -139,7 +141,7 @@ LEFT JOIN md_members AS m1 ON history.member_id = m1.member_id
LEFT JOIN md_members AS m2 ON history.modify_at = m2.member_id LEFT JOIN md_members AS m2 ON history.modify_at = m2.member_id
WHERE history.document_id = ? ORDER BY history.history_id DESC LIMIT ?,?;` WHERE history.document_id = ? ORDER BY history.history_id DESC LIMIT ?,?;`
_, err = o.Raw(sql,doc_id,offset,page_size).QueryRows(&docs) _, err = o.Raw(sql, doc_id, offset, page_size).QueryRows(&docs)
if err != nil { if err != nil {
return return

View File

@ -1,11 +1,12 @@
package models package models
import ( import (
"github.com/astaxie/beego/orm"
"bytes" "bytes"
"strconv"
"github.com/astaxie/beego" "github.com/astaxie/beego"
"github.com/astaxie/beego/orm"
"html/template" "html/template"
"math"
"strconv"
) )
type DocumentTree struct { type DocumentTree struct {
@ -23,26 +24,26 @@ type DocumentSelected struct {
} }
//获取项目的文档树状结构 //获取项目的文档树状结构
func (m *Document) FindDocumentTree(book_id int) ([]*DocumentTree,error){ func (m *Document) FindDocumentTree(book_id int) ([]*DocumentTree, error) {
o := orm.NewOrm() o := orm.NewOrm()
trees := make([]*DocumentTree,0) trees := make([]*DocumentTree, 0)
var docs []*Document var docs []*Document
count ,err := o.QueryTable(m).Filter("book_id",book_id).OrderBy("order_sort","document_id").All(&docs,"document_id","version","document_name","parent_id","identify") count, err := o.QueryTable(m).Filter("book_id", book_id).OrderBy("order_sort", "document_id").Limit(math.MaxInt32).All(&docs, "document_id", "version", "document_name", "parent_id", "identify")
if err != nil { if err != nil {
return trees,err return trees, err
} }
book,_ := NewBook().Find(book_id) book, _ := NewBook().Find(book_id)
trees = make([]*DocumentTree,count) trees = make([]*DocumentTree, count)
for index,item := range docs { for index, item := range docs {
tree := &DocumentTree{} tree := &DocumentTree{}
if index == 0{ if index == 0 {
tree.State = &DocumentSelected{ Selected: true, Opened: true } tree.State = &DocumentSelected{Selected: true, Opened: true}
} }
tree.DocumentId = item.DocumentId tree.DocumentId = item.DocumentId
tree.Identify = item.Identify tree.Identify = item.Identify
@ -50,7 +51,7 @@ func (m *Document) FindDocumentTree(book_id int) ([]*DocumentTree,error){
tree.BookIdentify = book.Identify tree.BookIdentify = book.Identify
if item.ParentId > 0 { if item.ParentId > 0 {
tree.ParentId = item.ParentId tree.ParentId = item.ParentId
}else{ } else {
tree.ParentId = "#" tree.ParentId = "#"
} }
@ -59,41 +60,41 @@ func (m *Document) FindDocumentTree(book_id int) ([]*DocumentTree,error){
trees[index] = tree trees[index] = tree
} }
return trees,nil return trees, nil
} }
func (m *Document) CreateDocumentTreeForHtml(book_id, selected_id int) (string,error) { func (m *Document) CreateDocumentTreeForHtml(book_id, selected_id int) (string, error) {
trees,err := m.FindDocumentTree(book_id) trees, err := m.FindDocumentTree(book_id)
if err != nil { if err != nil {
return "",err return "", err
} }
parent_id := getSelectedNode(trees,selected_id) parent_id := getSelectedNode(trees, selected_id)
buf := bytes.NewBufferString("") buf := bytes.NewBufferString("")
getDocumentTree(trees,0,selected_id,parent_id,buf) getDocumentTree(trees, 0, selected_id, parent_id, buf)
return buf.String(),nil return buf.String(), nil
} }
//使用递归的方式获取指定ID的顶级ID //使用递归的方式获取指定ID的顶级ID
func getSelectedNode(array []*DocumentTree, parent_id int) int { func getSelectedNode(array []*DocumentTree, parent_id int) int {
for _,item := range array { for _, item := range array {
if _,ok := item.ParentId.(string); ok && item.DocumentId == parent_id { if _, ok := item.ParentId.(string); ok && item.DocumentId == parent_id {
return item.DocumentId return item.DocumentId
}else if pid,ok := item.ParentId.(int); ok && item.DocumentId == parent_id{ } else if pid, ok := item.ParentId.(int); ok && item.DocumentId == parent_id {
return getSelectedNode(array,pid) return getSelectedNode(array, pid)
} }
} }
return 0 return 0
} }
func getDocumentTree(array []*DocumentTree,parent_id int,selected_id int,selected_parent_id int,buf *bytes.Buffer) { func getDocumentTree(array []*DocumentTree, parent_id int, selected_id int, selected_parent_id int, buf *bytes.Buffer) {
buf.WriteString("<ul>") buf.WriteString("<ul>")
for _,item := range array { for _, item := range array {
pid := 0 pid := 0
if p, ok := item.ParentId.(int); ok { if p, ok := item.ParentId.(int); ok {
@ -138,14 +139,3 @@ func getDocumentTree(array []*DocumentTree,parent_id int,selected_id int,selecte
} }
buf.WriteString("</ul>") buf.WriteString("</ul>")
} }

View File

@ -1,8 +1,8 @@
package models package models
import ( import (
"github.com/lifei6671/mindoc/conf"
"github.com/astaxie/beego/orm" "github.com/astaxie/beego/orm"
"github.com/lifei6671/mindoc/conf"
"strings" "strings"
) )
@ -16,12 +16,13 @@ type Label struct {
func (m *Label) TableName() string { func (m *Label) TableName() string {
return "label" return "label"
} }
// TableEngine 获取数据使用的引擎. // TableEngine 获取数据使用的引擎.
func (m *Label) TableEngine() string { func (m *Label) TableEngine() string {
return "INNODB" return "INNODB"
} }
func (m *Label)TableNameWithPrefix() string { func (m *Label) TableNameWithPrefix() string {
return conf.GetDatabasePrefix() + m.TableName() return conf.GetDatabasePrefix() + m.TableName()
} }
@ -29,7 +30,7 @@ func NewLabel() *Label {
return &Label{} return &Label{}
} }
func (m *Label) FindFirst(field string, value interface{}) (*Label,error){ func (m *Label) FindFirst(field string, value interface{}) (*Label, error) {
o := orm.NewOrm() o := orm.NewOrm()
err := o.QueryTable(m.TableNameWithPrefix()).Filter(field, value).One(m) err := o.QueryTable(m.TableNameWithPrefix()).Filter(field, value).One(m)
@ -41,20 +42,20 @@ func (m *Label) FindFirst(field string, value interface{}) (*Label,error){
func (m *Label) InsertOrUpdate(labelName string) error { func (m *Label) InsertOrUpdate(labelName string) error {
o := orm.NewOrm() o := orm.NewOrm()
err := o.QueryTable(m.TableNameWithPrefix()).Filter("label_name",labelName).One(m) err := o.QueryTable(m.TableNameWithPrefix()).Filter("label_name", labelName).One(m)
if err != nil && err != orm.ErrNoRows { if err != nil && err != orm.ErrNoRows {
return err return err
} }
count,_ := o.QueryTable(NewBook().TableNameWithPrefix()).Filter("label__icontains",labelName).Count() count, _ := o.QueryTable(NewBook().TableNameWithPrefix()).Filter("label__icontains", labelName).Count()
m.BookNumber = int(count) m.BookNumber = int(count)
m.LabelName = labelName m.LabelName = labelName
if err == orm.ErrNoRows { if err == orm.ErrNoRows {
err = nil err = nil
m.LabelName = labelName m.LabelName = labelName
_,err = o.Insert(m) _, err = o.Insert(m)
}else{ } else {
_,err = o.Update(m) _, err = o.Update(m)
} }
return err return err
} }
@ -73,10 +74,10 @@ func (m *Label) InsertOrUpdateMulti(labels string) {
} }
//分页查找标签. //分页查找标签.
func (m *Label) FindToPager(pageIndex, pageSize int) (labels []*Label,totalCount int,err error) { func (m *Label) FindToPager(pageIndex, pageSize int) (labels []*Label, totalCount int, err error) {
o := orm.NewOrm() o := orm.NewOrm()
count,err := o.QueryTable(m.TableNameWithPrefix()).Count() count, err := o.QueryTable(m.TableNameWithPrefix()).Count()
if err != nil { if err != nil {
return return
@ -85,8 +86,7 @@ func (m *Label) FindToPager(pageIndex, pageSize int) (labels []*Label,totalCount
offset := (pageIndex - 1) * pageSize offset := (pageIndex - 1) * pageSize
_,err = o.QueryTable(m.TableNameWithPrefix()).OrderBy("-book_number").Offset(offset).Limit(pageSize).All(&labels) _, err = o.QueryTable(m.TableNameWithPrefix()).OrderBy("-book_number").Offset(offset).Limit(pageSize).All(&labels)
return return
} }

View File

@ -1,14 +1,14 @@
package models package models
import ( import (
"time" "errors"
"github.com/astaxie/beego/orm"
"github.com/lifei6671/mindoc/conf" "github.com/lifei6671/mindoc/conf"
"sync/atomic" "sync/atomic"
"github.com/astaxie/beego/orm" "time"
"errors"
) )
var loggerQueue = &logQueue{ channel : make(chan *Logger,100),isRuning : 0 } var loggerQueue = &logQueue{channel: make(chan *Logger, 100), isRuning: 0}
type logQueue struct { type logQueue struct {
channel chan *Logger channel chan *Logger
@ -33,6 +33,7 @@ type Logger struct {
func (m *Logger) TableName() string { func (m *Logger) TableName() string {
return "logs" return "logs"
} }
// TableEngine 获取数据使用的引擎. // TableEngine 获取数据使用的引擎.
func (m *Logger) TableEngine() string { func (m *Logger) TableEngine() string {
return "INNODB" return "INNODB"
@ -57,32 +58,19 @@ func (m *Logger) Add() error {
} }
loggerQueue.channel <- m loggerQueue.channel <- m
if atomic.LoadInt32(&(loggerQueue.isRuning)) <= 0 { if atomic.LoadInt32(&(loggerQueue.isRuning)) <= 0 {
atomic.AddInt32(&(loggerQueue.isRuning),1) atomic.AddInt32(&(loggerQueue.isRuning), 1)
go addLoggerAsync() go addLoggerAsync()
} }
return nil return nil
} }
func addLoggerAsync() { func addLoggerAsync() {
defer atomic.AddInt32(&(loggerQueue.isRuning),-1) defer atomic.AddInt32(&(loggerQueue.isRuning), -1)
o := orm.NewOrm() o := orm.NewOrm()
for{ for {
logger := <- loggerQueue.channel logger := <-loggerQueue.channel
o.Insert(logger) o.Insert(logger)
} }
} }

View File

@ -15,6 +15,7 @@ import (
"github.com/astaxie/beego/orm" "github.com/astaxie/beego/orm"
"github.com/lifei6671/mindoc/conf" "github.com/lifei6671/mindoc/conf"
"github.com/lifei6671/mindoc/utils" "github.com/lifei6671/mindoc/utils"
"math"
) )
type Member struct { type Member struct {
@ -108,7 +109,7 @@ func (m *Member) ldapLogin(account string, password string) (*Member, error) {
beego.AppConfig.String("ldap_base"), beego.AppConfig.String("ldap_base"),
ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false,
//修改objectClass通过配置文件获取值 //修改objectClass通过配置文件获取值
fmt.Sprintf("(&(%s)(%s=%s))",beego.AppConfig.String("ldap_filter"), beego.AppConfig.String("ldap_attribute"), account), fmt.Sprintf("(&(%s)(%s=%s))", beego.AppConfig.String("ldap_filter"), beego.AppConfig.String("ldap_attribute"), account),
[]string{"dn", "mail"}, []string{"dn", "mail"},
nil, nil,
) )
@ -279,7 +280,7 @@ func (m *Member) Valid(is_hash_password bool) error {
return ErrMemberEmailEmpty return ErrMemberEmailEmpty
} }
//用户描述必须小于500字 //用户描述必须小于500字
if strings.Count(m.Description,"") > 500 { if strings.Count(m.Description, "") > 500 {
return ErrMemberDescriptionTooLong return ErrMemberDescriptionTooLong
} }
if m.Role != conf.MemberGeneralRole && m.Role != conf.MemberSuperRole && m.Role != conf.MemberAdminRole { if m.Role != conf.MemberGeneralRole && m.Role != conf.MemberSuperRole && m.Role != conf.MemberAdminRole {
@ -289,48 +290,47 @@ func (m *Member) Valid(is_hash_password bool) error {
m.Status = 0 m.Status = 0
} }
//邮箱格式校验 //邮箱格式校验
if ok,err := regexp.MatchString(conf.RegexpEmail,m.Email); !ok || err != nil || m.Email == "" { if ok, err := regexp.MatchString(conf.RegexpEmail, m.Email); !ok || err != nil || m.Email == "" {
return ErrMemberEmailFormatError return ErrMemberEmailFormatError
} }
//如果是未加密密码,需要校验密码格式 //如果是未加密密码,需要校验密码格式
if !is_hash_password { if !is_hash_password {
if l := strings.Count(m.Password,"") ; m.Password == "" || l > 50 || l < 6{ if l := strings.Count(m.Password, ""); m.Password == "" || l > 50 || l < 6 {
return ErrMemberPasswordFormatError return ErrMemberPasswordFormatError
} }
} }
//校验邮箱是否呗使用 //校验邮箱是否呗使用
if member,err := NewMember().FindByFieldFirst("email",m.Account); err == nil && member.MemberId > 0 { if member, err := NewMember().FindByFieldFirst("email", m.Account); err == nil && member.MemberId > 0 {
if m.MemberId > 0 && m.MemberId != member.MemberId { if m.MemberId > 0 && m.MemberId != member.MemberId {
return ErrMemberEmailExist return ErrMemberEmailExist
} }
if m.MemberId <= 0{ if m.MemberId <= 0 {
return ErrMemberEmailExist return ErrMemberEmailExist
} }
} }
if m.MemberId > 0{ if m.MemberId > 0 {
//校验用户是否存在 //校验用户是否存在
if _,err := NewMember().Find(m.MemberId);err != nil { if _, err := NewMember().Find(m.MemberId); err != nil {
return err return err
} }
}else{ } else {
//校验账号格式是否正确 //校验账号格式是否正确
if ok,err := regexp.MatchString(conf.RegexpAccount,m.Account); m.Account == "" || !ok || err != nil { if ok, err := regexp.MatchString(conf.RegexpAccount, m.Account); m.Account == "" || !ok || err != nil {
return ErrMemberAccountFormatError return ErrMemberAccountFormatError
} }
//校验账号是否被使用 //校验账号是否被使用
if member,err := NewMember().FindByAccount(m.Account); err == nil && member.MemberId > 0 { if member, err := NewMember().FindByAccount(m.Account); err == nil && member.MemberId > 0 {
return ErrMemberExist return ErrMemberExist
} }
} }
return nil return nil
} }
//删除一个用户. //删除一个用户.
func (m *Member) Delete(oldId int,newId int) error { func (m *Member) Delete(oldId int, newId int) error {
o := orm.NewOrm() o := orm.NewOrm()
err := o.Begin() err := o.Begin()
@ -339,39 +339,39 @@ func (m *Member) Delete(oldId int,newId int) error {
return err return err
} }
_,err = o.Raw("DELETE FROM md_members WHERE member_id = ?",oldId).Exec() _, err = o.Raw("DELETE FROM md_members WHERE member_id = ?", oldId).Exec()
if err != nil { if err != nil {
o.Rollback() o.Rollback()
return err return err
} }
_,err = o.Raw("UPDATE md_attachment SET `create_at` = ? WHERE `create_at` = ?",newId,oldId).Exec() _, err = o.Raw("UPDATE md_attachment SET `create_at` = ? WHERE `create_at` = ?", newId, oldId).Exec()
if err != nil { if err != nil {
o.Rollback() o.Rollback()
return err return err
} }
_,err = o.Raw("UPDATE md_books SET member_id = ? WHERE member_id = ?",newId,oldId).Exec() _, err = o.Raw("UPDATE md_books SET member_id = ? WHERE member_id = ?", newId, oldId).Exec()
if err != nil { if err != nil {
o.Rollback() o.Rollback()
return err return err
} }
_,err = o.Raw("UPDATE md_document_history SET member_id=? WHERE member_id = ?",newId,oldId).Exec() _, err = o.Raw("UPDATE md_document_history SET member_id=? WHERE member_id = ?", newId, oldId).Exec()
if err != nil { if err != nil {
o.Rollback() o.Rollback()
return err return err
} }
_,err = o.Raw("UPDATE md_document_history SET modify_at=? WHERE modify_at = ?",newId,oldId).Exec() _, err = o.Raw("UPDATE md_document_history SET modify_at=? WHERE modify_at = ?", newId, oldId).Exec()
if err != nil { if err != nil {
o.Rollback() o.Rollback()
return err return err
} }
_,err = o.Raw("UPDATE md_documents SET member_id = ? WHERE member_id = ?;",newId,oldId).Exec() _, err = o.Raw("UPDATE md_documents SET member_id = ? WHERE member_id = ?;", newId, oldId).Exec()
if err != nil { if err != nil {
o.Rollback() o.Rollback()
return err return err
} }
_,err = o.Raw("UPDATE md_documents SET modify_at = ? WHERE modify_at = ?",newId,oldId).Exec() _, err = o.Raw("UPDATE md_documents SET modify_at = ? WHERE modify_at = ?", newId, oldId).Exec()
if err != nil { if err != nil {
o.Rollback() o.Rollback()
return err return err
@ -386,53 +386,37 @@ func (m *Member) Delete(oldId int,newId int) error {
//} //}
var relationship_list []*Relationship var relationship_list []*Relationship
_,err = o.QueryTable(NewRelationship().TableNameWithPrefix()).Filter("member_id",oldId).All(&relationship_list) _, err = o.QueryTable(NewRelationship().TableNameWithPrefix()).Filter("member_id", oldId).Limit(math.MaxInt32).All(&relationship_list)
if err == nil { if err == nil {
for _,relationship := range relationship_list { for _, relationship := range relationship_list {
//如果存在创始人,则删除 //如果存在创始人,则删除
if relationship.RoleId == 0 { if relationship.RoleId == 0 {
rel := NewRelationship() rel := NewRelationship()
err = o.QueryTable(relationship.TableNameWithPrefix()).Filter("book_id",relationship.BookId).Filter("member_id",newId).One(rel) err = o.QueryTable(relationship.TableNameWithPrefix()).Filter("book_id", relationship.BookId).Filter("member_id", newId).One(rel)
if err == nil { if err == nil {
if _,err := o.Delete(relationship) ; err != nil{ if _, err := o.Delete(relationship); err != nil {
beego.Error(err) beego.Error(err)
} }
relationship.RelationshipId = rel.RelationshipId relationship.RelationshipId = rel.RelationshipId
} }
relationship.MemberId = newId relationship.MemberId = newId
relationship.RoleId = 0 relationship.RoleId = 0
if _,err := o.Update(relationship) ; err != nil{ if _, err := o.Update(relationship); err != nil {
beego.Error(err) beego.Error(err)
} }
}else{ } else {
if _,err := o.Delete(relationship) ; err != nil{ if _, err := o.Delete(relationship); err != nil {
beego.Error(err) beego.Error(err)
} }
} }
} }
} }
if err = o.Commit();err != nil { if err = o.Commit(); err != nil {
o.Rollback() o.Rollback()
return err return err
} }
return nil return nil
} }

View File

@ -1,9 +1,9 @@
package models package models
import ( import (
"time"
"github.com/astaxie/beego/orm" "github.com/astaxie/beego/orm"
"github.com/lifei6671/mindoc/conf" "github.com/lifei6671/mindoc/conf"
"time"
) )
type MemberRelationshipResult struct { type MemberRelationshipResult struct {
@ -43,18 +43,18 @@ func (m *MemberRelationshipResult) FromMember(member *Member) *MemberRelationshi
return m return m
} }
func (m *MemberRelationshipResult) ResolveRoleName () *MemberRelationshipResult { func (m *MemberRelationshipResult) ResolveRoleName() *MemberRelationshipResult {
if m.RoleId == conf.BookAdmin { if m.RoleId == conf.BookAdmin {
m.RoleName = "管理者" m.RoleName = "管理者"
}else if m.RoleId == conf.BookEditor { } else if m.RoleId == conf.BookEditor {
m.RoleName = "编辑者" m.RoleName = "编辑者"
}else if m.RoleId == conf.BookObserver { } else if m.RoleId == conf.BookObserver {
m.RoleName = "观察者" m.RoleName = "观察者"
} }
return m return m
} }
func (m *MemberRelationshipResult) FindForUsersByBookId(book_id ,pageIndex, pageSize int) ([]*MemberRelationshipResult,int,error) { func (m *MemberRelationshipResult) FindForUsersByBookId(book_id, pageIndex, pageSize int) ([]*MemberRelationshipResult, int, error) {
o := orm.NewOrm() o := orm.NewOrm()
var members []*MemberRelationshipResult var members []*MemberRelationshipResult
@ -65,28 +65,22 @@ func (m *MemberRelationshipResult) FindForUsersByBookId(book_id ,pageIndex, page
var total_count int var total_count int
err := o.Raw(sql2,book_id).QueryRow(&total_count) err := o.Raw(sql2, book_id).QueryRow(&total_count)
if err != nil { if err != nil {
return members,0,err return members, 0, err
} }
offset := (pageIndex-1) * pageSize offset := (pageIndex - 1) * pageSize
_,err = o.Raw(sql1,book_id,offset,pageSize).QueryRows(&members) _, err = o.Raw(sql1, book_id, offset, pageSize).QueryRows(&members)
if err != nil { if err != nil {
return members,0,err return members, 0, err
} }
for _,item := range members { for _, item := range members {
item.ResolveRoleName() item.ResolveRoleName()
} }
return members,total_count,nil return members, total_count, nil
} }

View File

@ -1,9 +1,9 @@
package models package models
import ( import (
"time"
"github.com/lifei6671/mindoc/conf"
"github.com/astaxie/beego/orm" "github.com/astaxie/beego/orm"
"github.com/lifei6671/mindoc/conf"
"time"
) )
type MemberToken struct { type MemberToken struct {
@ -16,17 +16,17 @@ type MemberToken struct {
SendTime time.Time `orm:"column(send_time);auto_now_add;type(datetime)" json:"send_time"` SendTime time.Time `orm:"column(send_time);auto_now_add;type(datetime)" json:"send_time"`
} }
// TableName 获取对应数据库表名. // TableName 获取对应数据库表名.
func (m *MemberToken) TableName() string { func (m *MemberToken) TableName() string {
return "member_token" return "member_token"
} }
// TableEngine 获取数据使用的引擎. // TableEngine 获取数据使用的引擎.
func (m *MemberToken) TableEngine() string { func (m *MemberToken) TableEngine() string {
return "INNODB" return "INNODB"
} }
func (m *MemberToken)TableNameWithPrefix() string { func (m *MemberToken) TableNameWithPrefix() string {
return conf.GetDatabasePrefix() + m.TableName() return conf.GetDatabasePrefix() + m.TableName()
} }
@ -34,33 +34,33 @@ func NewMemberToken() *MemberToken {
return &MemberToken{} return &MemberToken{}
} }
func (m *MemberToken) InsertOrUpdate() (*MemberToken,error){ func (m *MemberToken) InsertOrUpdate() (*MemberToken, error) {
o := orm.NewOrm() o := orm.NewOrm()
if m.TokenId > 0 { if m.TokenId > 0 {
_,err := o.Update(m) _, err := o.Update(m)
return m,err return m, err
} }
_,err := o.Insert(m) _, err := o.Insert(m)
return m,err return m, err
} }
func (m *MemberToken) FindByFieldFirst(field string,value interface{}) (*MemberToken,error) { func (m *MemberToken) FindByFieldFirst(field string, value interface{}) (*MemberToken, error) {
o := orm.NewOrm() o := orm.NewOrm()
err := o.QueryTable(m.TableNameWithPrefix()).Filter(field,value).OrderBy("-token_id").One(m) err := o.QueryTable(m.TableNameWithPrefix()).Filter(field, value).OrderBy("-token_id").One(m)
return m,err return m, err
} }
func (m *MemberToken) FindSendCount(mail string,start_time time.Time,end_time time.Time) (int ,error) { func (m *MemberToken) FindSendCount(mail string, start_time time.Time, end_time time.Time) (int, error) {
o := orm.NewOrm() o := orm.NewOrm()
c,err := o.QueryTable(m.TableNameWithPrefix()).Filter("send_time__gte",start_time.Format("2006-01-02 15:04:05")).Filter("send_time__lte",end_time.Format("2006-01-02 15:04:05")).Count() c, err := o.QueryTable(m.TableNameWithPrefix()).Filter("send_time__gte", start_time.Format("2006-01-02 15:04:05")).Filter("send_time__lte", end_time.Format("2006-01-02 15:04:05")).Count()
if err != nil { if err != nil {
return 0,err return 0, err
} }
return int(c),nil return int(c), nil
} }

View File

@ -1,9 +1,9 @@
package models package models
import ( import (
"time"
"github.com/lifei6671/mindoc/conf"
"github.com/astaxie/beego/orm" "github.com/astaxie/beego/orm"
"github.com/lifei6671/mindoc/conf"
"time"
) )
type Migration struct { type Migration struct {
@ -33,10 +33,10 @@ func NewMigration() *Migration {
return &Migration{} return &Migration{}
} }
func (m *Migration) FindFirst() (*Migration,error) { func (m *Migration) FindFirst() (*Migration, error) {
o := orm.NewOrm() o := orm.NewOrm()
err := o.QueryTable(m.TableNameWithPrefix()).OrderBy("-migration_id").One(m) err := o.QueryTable(m.TableNameWithPrefix()).OrderBy("-migration_id").One(m)
return m,err return m, err
} }

View File

@ -5,7 +5,6 @@ import (
"github.com/lifei6671/mindoc/conf" "github.com/lifei6671/mindoc/conf"
) )
// Option struct . // Option struct .
type Option struct { type Option struct {
OptionId int `orm:"column(option_id);pk;auto;unique;" json:"option_id"` OptionId int `orm:"column(option_id);pk;auto;unique;" json:"option_id"`
@ -19,44 +18,44 @@ type Option struct {
func (m *Option) TableName() string { func (m *Option) TableName() string {
return "options" return "options"
} }
// TableEngine 获取数据使用的引擎. // TableEngine 获取数据使用的引擎.
func (m *Option) TableEngine() string { func (m *Option) TableEngine() string {
return "INNODB" return "INNODB"
} }
func (m *Option)TableNameWithPrefix() string { func (m *Option) TableNameWithPrefix() string {
return conf.GetDatabasePrefix() + m.TableName() return conf.GetDatabasePrefix() + m.TableName()
} }
func NewOption() *Option { func NewOption() *Option {
return &Option{} return &Option{}
} }
func (p *Option) Find(id int) (*Option,error) { func (p *Option) Find(id int) (*Option, error) {
o := orm.NewOrm() o := orm.NewOrm()
p.OptionId = id p.OptionId = id
if err := o.Read(p);err != nil { if err := o.Read(p); err != nil {
return p,err return p, err
} }
return p,nil return p, nil
} }
func (p *Option) FindByKey(key string) (*Option,error) { func (p *Option) FindByKey(key string) (*Option, error) {
o := orm.NewOrm() o := orm.NewOrm()
p.OptionName = key p.OptionName = key
if err := o.Read(p);err != nil { if err := o.Read(p); err != nil {
return p,err return p, err
} }
return p,nil return p, nil
} }
func GetOptionValue(key, def string) string { func GetOptionValue(key, def string) string {
if option,err := NewOption().FindByKey(key); err == nil { if option, err := NewOption().FindByKey(key); err == nil {
return option.OptionValue return option.OptionValue
} }
return def return def
@ -68,81 +67,80 @@ func (p *Option) InsertOrUpdate() error {
var err error var err error
if p.OptionId > 0 || o.QueryTable(p.TableNameWithPrefix()).Filter("option_name", p.OptionName).Exist() {
if p.OptionId > 0 || o.QueryTable(p.TableNameWithPrefix()).Filter("option_name",p.OptionName).Exist() { _, err = o.Update(p)
_,err = o.Update(p) } else {
}else{ _, err = o.Insert(p)
_,err = o.Insert(p)
} }
return err return err
} }
func (p *Option) InsertMulti(option... Option ) (error){ func (p *Option) InsertMulti(option ...Option) error {
o := orm.NewOrm() o := orm.NewOrm()
_,err := o.InsertMulti(len(option),option) _, err := o.InsertMulti(len(option), option)
return err return err
} }
func (p *Option) All() ([]*Option,error) { func (p *Option) All() ([]*Option, error) {
o := orm.NewOrm() o := orm.NewOrm()
var options []*Option var options []*Option
_,err := o.QueryTable(p.TableNameWithPrefix()).All(&options) _, err := o.QueryTable(p.TableNameWithPrefix()).All(&options)
if err != nil { if err != nil {
return options,err return options, err
} }
return options,nil return options, nil
} }
func (m *Option) Init() error { func (m *Option) Init() error {
o := orm.NewOrm() o := orm.NewOrm()
if !o.QueryTable(m.TableNameWithPrefix()).Filter("option_name","ENABLED_REGISTER").Exist() { if !o.QueryTable(m.TableNameWithPrefix()).Filter("option_name", "ENABLED_REGISTER").Exist() {
option := NewOption() option := NewOption()
option.OptionValue = "false" option.OptionValue = "false"
option.OptionName = "ENABLED_REGISTER" option.OptionName = "ENABLED_REGISTER"
option.OptionTitle = "是否启用注册" option.OptionTitle = "是否启用注册"
if _,err := o.Insert(option);err != nil { if _, err := o.Insert(option); err != nil {
return err return err
} }
} }
if !o.QueryTable(m.TableNameWithPrefix()).Filter("option_name","ENABLE_DOCUMENT_HISTORY").Exist() { if !o.QueryTable(m.TableNameWithPrefix()).Filter("option_name", "ENABLE_DOCUMENT_HISTORY").Exist() {
option := NewOption() option := NewOption()
option.OptionValue = "true" option.OptionValue = "true"
option.OptionName = "ENABLE_DOCUMENT_HISTORY" option.OptionName = "ENABLE_DOCUMENT_HISTORY"
option.OptionTitle = "是否启用文档历史" option.OptionTitle = "是否启用文档历史"
if _,err := o.Insert(option);err != nil { if _, err := o.Insert(option); err != nil {
return err return err
} }
} }
if !o.QueryTable(m.TableNameWithPrefix()).Filter("option_name","ENABLED_CAPTCHA").Exist() { if !o.QueryTable(m.TableNameWithPrefix()).Filter("option_name", "ENABLED_CAPTCHA").Exist() {
option := NewOption() option := NewOption()
option.OptionValue = "true" option.OptionValue = "true"
option.OptionName = "ENABLED_CAPTCHA" option.OptionName = "ENABLED_CAPTCHA"
option.OptionTitle = "是否启用验证码" option.OptionTitle = "是否启用验证码"
if _,err := o.Insert(option);err != nil { if _, err := o.Insert(option); err != nil {
return err return err
} }
} }
if !o.QueryTable(m.TableNameWithPrefix()).Filter("option_name","ENABLE_ANONYMOUS").Exist() { if !o.QueryTable(m.TableNameWithPrefix()).Filter("option_name", "ENABLE_ANONYMOUS").Exist() {
option := NewOption() option := NewOption()
option.OptionValue = "false" option.OptionValue = "false"
option.OptionName = "ENABLE_ANONYMOUS" option.OptionName = "ENABLE_ANONYMOUS"
option.OptionTitle = "启用匿名访问" option.OptionTitle = "启用匿名访问"
if _,err := o.Insert(option);err != nil { if _, err := o.Insert(option); err != nil {
return err return err
} }
} }
if !o.QueryTable(m.TableNameWithPrefix()).Filter("option_name","SITE_NAME").Exist() { if !o.QueryTable(m.TableNameWithPrefix()).Filter("option_name", "SITE_NAME").Exist() {
option := NewOption() option := NewOption()
option.OptionValue = "MinDoc" option.OptionValue = "MinDoc"
option.OptionName = "SITE_NAME" option.OptionName = "SITE_NAME"
option.OptionTitle = "站点名称" option.OptionTitle = "站点名称"
if _,err := o.Insert(option);err != nil { if _, err := o.Insert(option); err != nil {
return err return err
} }
} }

View File

@ -1,10 +1,10 @@
package models package models
import ( import (
"github.com/lifei6671/mindoc/conf"
"github.com/astaxie/beego/orm"
"errors" "errors"
"github.com/astaxie/beego/logs" "github.com/astaxie/beego/logs"
"github.com/astaxie/beego/orm"
"github.com/lifei6671/mindoc/conf"
) )
type Relationship struct { type Relationship struct {
@ -15,7 +15,6 @@ type Relationship struct {
RoleId int `orm:"column(role_id);type(int)" json:"role_id"` RoleId int `orm:"column(role_id);type(int)" json:"role_id"`
} }
// TableName 获取对应数据库表名. // TableName 获取对应数据库表名.
func (m *Relationship) TableName() string { func (m *Relationship) TableName() string {
return "relationship" return "relationship"
@ -40,81 +39,81 @@ func NewRelationship() *Relationship {
return &Relationship{} return &Relationship{}
} }
func (m *Relationship) Find(id int) (*Relationship,error) { func (m *Relationship) Find(id int) (*Relationship, error) {
o := orm.NewOrm() o := orm.NewOrm()
err := o.QueryTable(m.TableNameWithPrefix()).Filter("relationship_id",id).One(m) err := o.QueryTable(m.TableNameWithPrefix()).Filter("relationship_id", id).One(m)
return m,err return m, err
} }
//查询指定项目的创始人. //查询指定项目的创始人.
func (m *Relationship) FindFounder(book_id int) (*Relationship,error) { func (m *Relationship) FindFounder(book_id int) (*Relationship, error) {
o := orm.NewOrm() o := orm.NewOrm()
err := o.QueryTable(m.TableNameWithPrefix()).Filter("book_id",book_id).Filter("role_id",0).One(m) err := o.QueryTable(m.TableNameWithPrefix()).Filter("book_id", book_id).Filter("role_id", 0).One(m)
return m,err return m, err
} }
func (m *Relationship) UpdateRoleId(book_id,member_id, role_id int) (*Relationship,error) { func (m *Relationship) UpdateRoleId(book_id, member_id, role_id int) (*Relationship, error) {
o := orm.NewOrm() o := orm.NewOrm()
book := NewBook() book := NewBook()
book.BookId = book_id book.BookId = book_id
if err := o.Read(book); err != nil { if err := o.Read(book); err != nil {
logs.Error("UpdateRoleId => ", err) logs.Error("UpdateRoleId => ", err)
return m,errors.New("项目不存在") return m, errors.New("项目不存在")
} }
err := o.QueryTable(m.TableNameWithPrefix()).Filter("member_id",member_id).Filter("book_id",book_id).One(m) err := o.QueryTable(m.TableNameWithPrefix()).Filter("member_id", member_id).Filter("book_id", book_id).One(m)
if err == orm.ErrNoRows { if err == orm.ErrNoRows {
m = NewRelationship() m = NewRelationship()
m.BookId = book_id m.BookId = book_id
m.MemberId = member_id m.MemberId = member_id
m.RoleId = role_id m.RoleId = role_id
}else if err != nil { } else if err != nil {
return m,err return m, err
}else if m.RoleId == conf.BookFounder{ } else if m.RoleId == conf.BookFounder {
return m,errors.New("不能变更创始人的权限") return m, errors.New("不能变更创始人的权限")
} }
m.RoleId = role_id m.RoleId = role_id
if m.RelationshipId > 0 { if m.RelationshipId > 0 {
_,err = o.Update(m) _, err = o.Update(m)
}else{ } else {
_,err = o.Insert(m) _, err = o.Insert(m)
} }
return m,err return m, err
} }
func (m *Relationship) FindForRoleId(book_id ,member_id int) (int,error) { func (m *Relationship) FindForRoleId(book_id, member_id int) (int, error) {
o := orm.NewOrm() o := orm.NewOrm()
relationship := NewRelationship() relationship := NewRelationship()
err := o.QueryTable(m.TableNameWithPrefix()).Filter("book_id",book_id).Filter("member_id",member_id).One(relationship) err := o.QueryTable(m.TableNameWithPrefix()).Filter("book_id", book_id).Filter("member_id", member_id).One(relationship)
if err != nil { if err != nil {
return 0,err return 0, err
} }
return relationship.RoleId,nil return relationship.RoleId, nil
} }
func (m *Relationship) FindByBookIdAndMemberId(book_id ,member_id int) (*Relationship,error) { func (m *Relationship) FindByBookIdAndMemberId(book_id, member_id int) (*Relationship, error) {
o := orm.NewOrm() o := orm.NewOrm()
err := o.QueryTable(m.TableNameWithPrefix()).Filter("book_id",book_id).Filter("member_id",member_id).One(m) err := o.QueryTable(m.TableNameWithPrefix()).Filter("book_id", book_id).Filter("member_id", member_id).One(m)
return m,err return m, err
} }
func (m *Relationship) Insert() error { func (m *Relationship) Insert() error {
o := orm.NewOrm() o := orm.NewOrm()
_,err := o.Insert(m) _, err := o.Insert(m)
return err return err
} }
@ -122,15 +121,15 @@ func (m *Relationship) Insert() error {
func (m *Relationship) Update() error { func (m *Relationship) Update() error {
o := orm.NewOrm() o := orm.NewOrm()
_,err := o.Update(m) _, err := o.Update(m)
return err return err
} }
func (m *Relationship) DeleteByBookIdAndMemberId(book_id,member_id int) error { func (m *Relationship) DeleteByBookIdAndMemberId(book_id, member_id int) error {
o := orm.NewOrm() o := orm.NewOrm()
err := o.QueryTable(m.TableNameWithPrefix()).Filter("book_id",book_id).Filter("member_id",member_id).One(m) err := o.QueryTable(m.TableNameWithPrefix()).Filter("book_id", book_id).Filter("member_id", member_id).One(m)
if err == orm.ErrNoRows { if err == orm.ErrNoRows {
return errors.New("用户未参与该项目") return errors.New("用户未参与该项目")
@ -138,22 +137,22 @@ func (m *Relationship) DeleteByBookIdAndMemberId(book_id,member_id int) error {
if m.RoleId == conf.BookFounder { if m.RoleId == conf.BookFounder {
return errors.New("不能删除创始人") return errors.New("不能删除创始人")
} }
_,err = o.Delete(m) _, err = o.Delete(m)
if err != nil { if err != nil {
logs.Error("删除项目参与者 => ",err) logs.Error("删除项目参与者 => ", err)
return errors.New("删除失败") return errors.New("删除失败")
} }
return nil return nil
} }
func (m *Relationship) Transfer(book_id,founder_id,receive_id int) error { func (m *Relationship) Transfer(book_id, founder_id, receive_id int) error {
o := orm.NewOrm() o := orm.NewOrm()
founder := NewRelationship() founder := NewRelationship()
err := o.QueryTable(m.TableNameWithPrefix()).Filter("book_id",book_id).Filter("member_id",founder_id).One(founder) err := o.QueryTable(m.TableNameWithPrefix()).Filter("book_id", book_id).Filter("member_id", founder_id).One(founder)
if err != nil { if err != nil {
return err return err
@ -163,7 +162,7 @@ func (m *Relationship) Transfer(book_id,founder_id,receive_id int) error {
} }
receive := NewRelationship() receive := NewRelationship()
err = o.QueryTable(m.TableNameWithPrefix()).Filter("book_id",book_id).Filter("member_id",receive_id).One(receive) err = o.QueryTable(m.TableNameWithPrefix()).Filter("book_id", book_id).Filter("member_id", receive_id).One(receive)
if err != orm.ErrNoRows && err != nil { if err != orm.ErrNoRows && err != nil {
return err return err
@ -176,17 +175,17 @@ func (m *Relationship) Transfer(book_id,founder_id,receive_id int) error {
receive.RoleId = conf.BookFounder receive.RoleId = conf.BookFounder
receive.BookId = book_id receive.BookId = book_id
if err := founder.Update();err != nil { if err := founder.Update(); err != nil {
o.Rollback() o.Rollback()
return err return err
} }
if receive.RelationshipId > 0 { if receive.RelationshipId > 0 {
if _,err := o.Update(receive);err != nil { if _, err := o.Update(receive); err != nil {
o.Rollback() o.Rollback()
return err return err
} }
}else{ } else {
if _,err := o.Insert(receive);err != nil { if _, err := o.Insert(receive); err != nil {
o.Rollback() o.Rollback()
return err return err
} }
@ -194,24 +193,3 @@ func (m *Relationship) Transfer(book_id,founder_id,receive_id int) error {
return o.Commit() return o.Commit()
} }

View File

@ -1,11 +1,12 @@
package routers package routers
import ( import (
"encoding/json"
"github.com/astaxie/beego" "github.com/astaxie/beego"
"github.com/astaxie/beego/context" "github.com/astaxie/beego/context"
"github.com/lifei6671/mindoc/conf" "github.com/lifei6671/mindoc/conf"
"github.com/lifei6671/mindoc/models" "github.com/lifei6671/mindoc/models"
"encoding/json" "net/url"
) )
func init() { func init() {
@ -14,30 +15,31 @@ func init() {
if !ok { if !ok {
if ctx.Input.IsAjax() { if ctx.Input.IsAjax() {
jsonData := make(map[string]interface{},3) jsonData := make(map[string]interface{}, 3)
jsonData["errcode"] = 403 jsonData["errcode"] = 403
jsonData["message"] = "请登录后再操作" jsonData["message"] = "请登录后再操作"
returnJSON, _ := json.Marshal(jsonData) returnJSON, _ := json.Marshal(jsonData)
ctx.ResponseWriter.Write(returnJSON) ctx.ResponseWriter.Write(returnJSON)
}else{ } else {
ctx.Redirect(302, beego.URLFor("AccountController.Login")) ctx.Redirect(302, beego.URLFor("AccountController.Login") + "?url=" + url.PathEscape(ctx.Request.URL.RequestURI()))
} }
} }
} }
beego.InsertFilter("/manager",beego.BeforeRouter,FilterUser) beego.InsertFilter("/manager", beego.BeforeRouter, FilterUser)
beego.InsertFilter("/manager/*",beego.BeforeRouter,FilterUser) beego.InsertFilter("/manager/*", beego.BeforeRouter, FilterUser)
beego.InsertFilter("/setting",beego.BeforeRouter,FilterUser) beego.InsertFilter("/setting", beego.BeforeRouter, FilterUser)
beego.InsertFilter("/setting/*",beego.BeforeRouter,FilterUser) beego.InsertFilter("/setting/*", beego.BeforeRouter, FilterUser)
beego.InsertFilter("/book",beego.BeforeRouter,FilterUser) beego.InsertFilter("/book", beego.BeforeRouter, FilterUser)
beego.InsertFilter("/book/*",beego.BeforeRouter,FilterUser) beego.InsertFilter("/book/*", beego.BeforeRouter, FilterUser)
beego.InsertFilter("/api/*",beego.BeforeRouter,FilterUser) beego.InsertFilter("/api/*", beego.BeforeRouter, FilterUser)
var FinishRouter = func(ctx *context.Context) { var FinishRouter = func(ctx *context.Context) {
ctx.ResponseWriter.Header().Add("MinDoc-Version",conf.VERSION) ctx.ResponseWriter.Header().Add("MinDoc-Version", conf.VERSION)
ctx.ResponseWriter.Header().Add("MinDoc-Site","http://www.iminho.me") ctx.ResponseWriter.Header().Add("MinDoc-Site", "https://www.iminho.me")
} }
beego.InsertFilter("/*",beego.BeforeRouter ,FinishRouter, false) beego.InsertFilter("/*", beego.BeforeRouter, FinishRouter, false)
} }

View File

@ -141,7 +141,6 @@ $(function () {
$.get(window.editURL + $node.node.id ).done(function (res) { $.get(window.editURL + $node.node.id ).done(function (res) {
layer.close(index); layer.close(index);
resetEditor();
if (res.errcode === 0) { if (res.errcode === 0) {
window.isLoad = true; window.isLoad = true;
try { try {
@ -153,7 +152,6 @@ $(function () {
} }
var node = { "id": res.data.doc_id, 'parent': res.data.parent_id === 0 ? '#' : res.data.parent_id, "text": res.data.doc_name, "identify": res.data.identify, "version": res.data.version }; var node = { "id": res.data.doc_id, 'parent': res.data.parent_id === 0 ? '#' : res.data.parent_id, "text": res.data.doc_name, "identify": res.data.identify, "version": res.data.version };
pushDocumentCategory(node); pushDocumentCategory(node);
console.log(node);
window.selectNode = node; window.selectNode = node;
pushVueLists(res.data.attach); pushVueLists(res.data.attach);
} else { } else {

View File

@ -0,0 +1,70 @@
package cryptil
import (
"crypto/hmac"
"crypto/md5"
"crypto/sha1"
"encoding/base64"
"fmt"
"strconv"
"strings"
"time"
)
//对称加密与解密之加密【从Beego中提取出来的】
//@param value 需要加密的字符串
//@param secret 加密密钥
//@return encrypt 返回的加密后的字符串
func Encrypt(value, secret string) (encrypt string) {
vs := base64.URLEncoding.EncodeToString([]byte(value))
timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
h := hmac.New(sha1.New, []byte(secret))
fmt.Fprintf(h, "%s%s", vs, timestamp)
sig := fmt.Sprintf("%02x", h.Sum(nil))
return strings.Join([]string{vs, timestamp, sig}, ".")
}
//对称加密与解密之解密【从Beego中提取出来的】
//@param value 需要解密的字符串
//@param secret 密钥
//@return decrypt 返回解密后的字符串
func Decrypt(value, secret string) (decrypt string) {
parts := strings.SplitN(value, ".", 3)
if len(parts) != 3 {
return ""
}
vs := parts[0]
timestamp := parts[1]
sig := parts[2]
h := hmac.New(sha1.New, []byte(secret))
fmt.Fprintf(h, "%s%s", vs, timestamp)
if fmt.Sprintf("%02x", h.Sum(nil)) != sig {
return ""
}
res, _ := base64.URLEncoding.DecodeString(vs)
return string(res)
}
//MD5加密
//@param str 需要加密的字符串
//@param salt 盐值
//@return CryptStr 加密后返回的字符串
func Md5Crypt(str string, salt ...interface{}) (CryptStr string) {
if l := len(salt); l > 0 {
slice := make([]string, l+1)
str = fmt.Sprintf(str+strings.Join(slice, "%v"), salt...)
}
return fmt.Sprintf("%x", md5.Sum([]byte(str)))
}
//SHA1加密
//@param str 需要加密的字符串
//@param salt 盐值
//@return CryptStr 加密后返回的字符串
func Sha1Crypt(str string, salt ...interface{}) (CryptStr string) {
if l := len(salt); l > 0 {
slice := make([]string, l+1)
str = fmt.Sprintf(str+strings.Join(slice, "%v"), salt...)
}
return fmt.Sprintf("%x", sha1.Sum([]byte(str)))
}

View File

@ -1,15 +1,15 @@
package utils package utils
import ( import (
"strings"
"os"
"fmt" "fmt"
"path/filepath"
"io" "io"
"math" "math"
"os"
"path/filepath"
"strings"
) )
func AbsolutePath(p string) (string,error) { func AbsolutePath(p string) (string, error) {
if strings.HasPrefix(p, "~") { if strings.HasPrefix(p, "~") {
home := os.Getenv("HOME") home := os.Getenv("HOME")
@ -21,9 +21,9 @@ func AbsolutePath(p string) (string,error) {
s, err := filepath.Abs(p) s, err := filepath.Abs(p)
if nil != err { if nil != err {
return "",err return "", err
} }
return s,nil return s, nil
} }
// FileExists reports whether the named file or directory exists. // FileExists reports whether the named file or directory exists.
@ -58,18 +58,13 @@ func FormatBytes(size int64) string {
i := 0 i := 0
for ; s >= 1024 && i < 4 ; i ++ { for ; s >= 1024 && i < 4; i++ {
s /= 1024 s /= 1024
} }
return fmt.Sprintf("%.2f%s", s, units[i])
return fmt.Sprintf("%.2f%s",s,units[i])
} }
func Round(val float64, places int) float64 { func Round(val float64, places int) float64 {
var t float64 var t float64
f := math.Pow10(places) f := math.Pow10(places)
@ -97,12 +92,3 @@ func Round(val float64, places int) float64 {
return t return t
} }

View File

@ -0,0 +1,43 @@
package filetil
import (
"os"
"path/filepath"
"strings"
)
//==================================
//更多文件和目录的操作使用filepath包和os包
//==================================
//返回的目录扫描结果
type FileList struct {
IsDir bool //是否是目录
Path string //文件路径
Ext string //文件扩展名
Name string //文件名
Size int64 //文件大小
ModTime int64 //文件修改时间戳
}
//目录扫描
//@param dir 需要扫描的目录
//@return fl 文件列表
//@return err 错误
func ScanFiles(dir string) (fl []FileList, err error) {
err = filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
if err == nil {
path = strings.Replace(path, "\\", "/", -1) //文件路径处理
fl = append(fl, FileList{
IsDir: info.IsDir(),
Path: path,
Ext: strings.ToLower(filepath.Ext(path)),
Name: info.Name(),
Size: info.Size(),
ModTime: info.ModTime().Unix(),
})
}
return err
})
return
}

View File

@ -6,25 +6,25 @@ import (
) )
//解码 //解码
func Decode(value string,r interface{}) (error) { func Decode(value string, r interface{}) error {
network := bytes.NewBuffer([]byte(value)); network := bytes.NewBuffer([]byte(value))
dec := gob.NewDecoder(network) dec := gob.NewDecoder(network)
return dec.Decode(r); return dec.Decode(r)
} }
//编码 //编码
func Encode(value interface{}) (string,error) { func Encode(value interface{}) (string, error) {
network:= bytes.NewBuffer(nil); network := bytes.NewBuffer(nil)
enc := gob.NewEncoder(network) enc := gob.NewEncoder(network)
err := enc.Encode(value); err := enc.Encode(value)
if err != nil { if err != nil {
return "",err; return "", err
} }
return network.String(),nil; return network.String(), nil
} }

View File

@ -1,11 +1,10 @@
package utils package utils
import ( import (
"time"
"math/rand" "math/rand"
"time"
) )
const ( const (
KC_RAND_KIND_NUM = 0 // 纯数字 KC_RAND_KIND_NUM = 0 // 纯数字
KC_RAND_KIND_LOWER = 1 // 小写字母 KC_RAND_KIND_LOWER = 1 // 小写字母
@ -18,12 +17,12 @@ func Krand(size int, kind int) []byte {
ikind, kinds, result := kind, [][]int{[]int{10, 48}, []int{26, 97}, []int{26, 65}}, make([]byte, size) ikind, kinds, result := kind, [][]int{[]int{10, 48}, []int{26, 97}, []int{26, 65}}, make([]byte, size)
is_all := kind > 2 || kind < 0 is_all := kind > 2 || kind < 0
rand.Seed(time.Now().UnixNano()) rand.Seed(time.Now().UnixNano())
for i :=0; i < size; i++ { for i := 0; i < size; i++ {
if is_all { // random ikind if is_all { // random ikind
ikind = rand.Intn(3) ikind = rand.Intn(3)
} }
scope, base := kinds[ikind][0], kinds[ikind][1] scope, base := kinds[ikind][0], kinds[ikind][1]
result[i] = uint8(base+rand.Intn(scope)) result[i] = uint8(base + rand.Intn(scope))
} }
return result return result

View File

@ -1,11 +1,12 @@
package utils package utils
import ( import (
"gopkg.in/ldap.v2"
"fmt"
"errors" "errors"
"fmt"
"github.com/astaxie/beego" "github.com/astaxie/beego"
"gopkg.in/ldap.v2"
) )
/* /*
config config
ldap: ldap:
@ -23,20 +24,20 @@ func ValidLDAPLogin(password string) (result bool, err error) {
err = nil err = nil
lc, err := ldap.Dial("tcp", fmt.Sprintf("%s:%d", "192.168.3.104", 389)) lc, err := ldap.Dial("tcp", fmt.Sprintf("%s:%d", "192.168.3.104", 389))
if err != nil { if err != nil {
beego.Error("Dial => ",err) beego.Error("Dial => ", err)
return return
} }
defer lc.Close() defer lc.Close()
err = lc.Bind("cn=admin,dc=minho,dc=com", "123456") err = lc.Bind("cn=admin,dc=minho,dc=com", "123456")
if err != nil { if err != nil {
beego.Error("Bind => ",err) beego.Error("Bind => ", err)
return return
} }
searchRequest := ldap.NewSearchRequest( searchRequest := ldap.NewSearchRequest(
"DC=minho,DC=com", "DC=minho,DC=com",
ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false,
fmt.Sprintf("(&(objectClass=User)(%s=%s))","mail", "longfei6671@163.com"), fmt.Sprintf("(&(objectClass=User)(%s=%s))", "mail", "longfei6671@163.com"),
[]string{"dn"}, []string{"dn"},
nil, nil,
) )
@ -49,7 +50,7 @@ func ValidLDAPLogin(password string) (result bool, err error) {
err = errors.New("ldap.no_user_found_or_many_users_found") err = errors.New("ldap.no_user_found_or_many_users_found")
return return
} }
fmt.Printf("%+v = %d",searchResult.Entries,len(searchResult.Entries)) fmt.Printf("%+v = %d", searchResult.Entries, len(searchResult.Entries))
userdn := searchResult.Entries[0].DN userdn := searchResult.Entries[0].DN
@ -57,7 +58,7 @@ func ValidLDAPLogin(password string) (result bool, err error) {
if err == nil { if err == nil {
result = true result = true
} else { } else {
beego.Error("Bind2 => ",err) beego.Error("Bind2 => ", err)
err = nil err = nil
} }
return return
@ -66,12 +67,12 @@ func ValidLDAPLogin(password string) (result bool, err error) {
func AddMember(account, password string) error { func AddMember(account, password string) error {
lc, err := ldap.Dial("tcp", fmt.Sprintf("%s:%d", "192.168.3.104", 389)) lc, err := ldap.Dial("tcp", fmt.Sprintf("%s:%d", "192.168.3.104", 389))
if err != nil { if err != nil {
beego.Error("Dial => ",err) beego.Error("Dial => ", err)
return err return err
} }
defer lc.Close() defer lc.Close()
user := fmt.Sprintf("cn=%s,dc=minho,dc=com",account) user := fmt.Sprintf("cn=%s,dc=minho,dc=com", account)
member := ldap.NewAddRequest(user) member := ldap.NewAddRequest(user)
@ -81,35 +82,35 @@ func AddMember(account, password string) error {
if err == nil { if err == nil {
err = lc.Bind(user,"") err = lc.Bind(user, "")
if err != nil { if err != nil {
beego.Error("Bind => ",err) beego.Error("Bind => ", err)
return err return err
} }
passwordModifyRequest := ldap.NewPasswordModifyRequest(user, "", "1q2w3e__ABC") passwordModifyRequest := ldap.NewPasswordModifyRequest(user, "", "1q2w3e__ABC")
_, err = lc.PasswordModify(passwordModifyRequest) _, err = lc.PasswordModify(passwordModifyRequest)
if err != nil { if err != nil {
beego.Error("PasswordModify => ",err) beego.Error("PasswordModify => ", err)
return err return err
} }
return nil return nil
} }
beego.Error("Add => ",err) beego.Error("Add => ", err)
return err return err
} }
func ModifyPassword(account, old_password, new_password string) error { func ModifyPassword(account, old_password, new_password string) error {
l, err := ldap.Dial("tcp", fmt.Sprintf("%s:%d", "192.168.3.104", 389)) l, err := ldap.Dial("tcp", fmt.Sprintf("%s:%d", "192.168.3.104", 389))
if err != nil { if err != nil {
beego.Error("Dial => ",err) beego.Error("Dial => ", err)
} }
defer l.Close() defer l.Close()
user := fmt.Sprintf("cn=%s,dc=minho,dc=com",account) user := fmt.Sprintf("cn=%s,dc=minho,dc=com", account)
err = l.Bind(user, old_password) err = l.Bind(user, old_password)
if err != nil { if err != nil {
beego.Error("Bind => ",err) beego.Error("Bind => ", err)
return err return err
} }
@ -122,15 +123,3 @@ func ModifyPassword(account, old_password, new_password string) error {
} }
return nil return nil
} }

View File

@ -6,8 +6,8 @@ import (
con "strconv" con "strconv"
"strings" "strings"
"github.com/astaxie/beego/orm"
"fmt" "fmt"
"github.com/astaxie/beego/orm"
"math" "math"
) )
@ -58,8 +58,8 @@ func GetPagesInfo(tableName string, currentpage int, pagesize int, conditions st
} }
/** /**
* ,,,html * ,,,html
* , : * , :
func (this *MainController) Test() { func (this *MainController) Test() {
var po util.PageOptions var po util.PageOptions
po.EnablePreNexLink = true po.EnablePreNexLink = true
@ -73,7 +73,7 @@ func GetPagesInfo(tableName string, currentpage int, pagesize int, conditions st
this.TplName = "test.html" this.TplName = "test.html"
} }
*/ */
func GetPagerLinks(po *PageOptions,requestURI string) (int, int, orm.RawSeter, html.HTML) { func GetPagerLinks(po *PageOptions, requestURI string) (int, int, orm.RawSeter, html.HTML) {
str := "" str := ""
totalItem, totalpages, rs := GetPagesInfo(po.TableName, po.CurrentPage, po.PageSize, po.Conditions) totalItem, totalpages, rs := GetPagesInfo(po.TableName, po.CurrentPage, po.PageSize, po.Conditions)
po = setDefault(po, totalpages) po = setDefault(po, totalpages)
@ -84,7 +84,7 @@ func GetPagerLinks(po *PageOptions,requestURI string) (int, int, orm.RawSeter, h
if po.CurrentPage < po.LinkItemCount { if po.CurrentPage < po.LinkItemCount {
str = fun2(po, totalpages) //123456789...200 str = fun2(po, totalpages) //123456789...200
} else { } else {
if po.CurrentPage + po.LinkItemCount < totalpages { if po.CurrentPage+po.LinkItemCount < totalpages {
str = fun3(po, totalpages) str = fun3(po, totalpages)
} else { } else {
str = fun4(po, totalpages) str = fun4(po, totalpages)
@ -94,18 +94,19 @@ func GetPagerLinks(po *PageOptions,requestURI string) (int, int, orm.RawSeter, h
return totalItem, totalpages, rs, html.HTML(str) return totalItem, totalpages, rs, html.HTML(str)
} }
func GetPagerHtml(requestURI string,pageIndex, pageSize,totalCount int) (html.HTML){ func GetPagerHtml(requestURI string, pageIndex, pageSize, totalCount int) html.HTML {
po := &PageOptions{ po := &PageOptions{
CurrentPage: pageIndex, CurrentPage: pageIndex,
PageSize: pageSize, PageSize: pageSize,
EnableFirstLastLink : true, EnableFirstLastLink: true,
ParamName : "page", ParamName: "page",
TotalPages:int(math.Ceil(float64(totalCount) / float64(pageSize))), TotalPages: int(math.Ceil(float64(totalCount) / float64(pageSize))),
LinkItemCount: pageSize,
} }
totalPages := int(math.Ceil(float64(totalCount) / float64(pageSize))) totalPages := int(math.Ceil(float64(totalCount) / float64(pageSize)))
setDefault(po,totalPages) setDefault(po, totalPages)
DealUri(po,requestURI) DealUri(po, requestURI)
str := "" str := ""
if totalPages <= po.LinkItemCount { if totalPages <= po.LinkItemCount {
str = fun1(po, totalPages) //显示完全 12345678910 str = fun1(po, totalPages) //显示完全 12345678910
@ -113,14 +114,14 @@ func GetPagerHtml(requestURI string,pageIndex, pageSize,totalCount int) (html.HT
if po.CurrentPage < po.LinkItemCount { if po.CurrentPage < po.LinkItemCount {
str = fun2(po, totalPages) //123456789...200 str = fun2(po, totalPages) //123456789...200
} else { } else {
if po.CurrentPage + po.LinkItemCount < totalPages { if po.CurrentPage+po.LinkItemCount < totalPages {
str = fun3(po, totalPages) str = fun3(po, totalPages)
} else { } else {
str = fun4(po, totalPages) str = fun4(po, totalPages)
} }
} }
} }
str = strings.Replace(str,"?&","?",-1) str = strings.Replace(str, "?&", "?", -1)
//str = strings.Replace(str,"&&","&",-1) //str = strings.Replace(str,"&&","&",-1)
return html.HTML(str) return html.HTML(str)
} }
@ -136,19 +137,19 @@ func DealUri(po *PageOptions, requestURI string) {
arr2 := strings.Split(arr[1], "&") arr2 := strings.Split(arr[1], "&")
for _, v := range arr2 { for _, v := range arr2 {
if !strings.Contains(v, po.ParamName) { if !strings.Contains(v, po.ParamName) {
if strings.HasSuffix(rs,"&") { if strings.HasSuffix(rs, "&") {
rs += v rs += v
}else{ } else {
rs += v + "&" rs += v + "&"
} }
//rs += "&" + v //rs += "&" + v
} }
} }
if strings.HasPrefix(rs,"&") { if strings.HasPrefix(rs, "&") {
rs = string(rs[1:]) rs = string(rs[1:])
} }
if strings.HasSuffix(rs,"&"){ if strings.HasSuffix(rs, "&") {
rs = string(rs[0:strings.Count(rs,"")-1]) rs = string(rs[0 : strings.Count(rs, "")-1])
} }
rs = arr[0] + "?" + rs rs = arr[0] + "?" + rs
fmt.Println(rs) fmt.Println(rs)
@ -167,8 +168,11 @@ func fun4(po *PageOptions, totalPages int) string {
rs := "" rs := ""
rs += getHeader(po, totalPages) rs += getHeader(po, totalPages)
rs += "<li><a href='" + po.Href + "&" + po.ParamName + "=" + con.Itoa(1) + "'>" + con.Itoa(1) + "</a></li>" rs += "<li><a href='" + po.Href + "&" + po.ParamName + "=" + con.Itoa(1) + "'>" + con.Itoa(1) + "</a></li>"
rs += "<li><a href=''>...</a></li>"
for i := totalPages - po.LinkItemCount; i <= totalPages; i++ { rs += "<li><a href=\"#\" class=\"@3\">...</a></li>"
for i := totalPages - po.LinkItemCount-1; i <= totalPages; i++ {
if po.CurrentPage != i { if po.CurrentPage != i {
rs += "<li><a href='" + po.Href + "&" + po.ParamName + "=" + con.Itoa(i) + "'>" + con.Itoa(i) + "</a></li>" rs += "<li><a href='" + po.Href + "&" + po.ParamName + "=" + con.Itoa(i) + "'>" + con.Itoa(i) + "</a></li>"
} else { } else {
@ -187,15 +191,15 @@ func fun3(po *PageOptions, totalpages int) string {
var rs string = "" var rs string = ""
rs += getHeader(po, totalpages) rs += getHeader(po, totalpages)
rs += "<li><a href='" + po.Href + "&" + po.ParamName + "=" + con.Itoa(1) + "'>" + con.Itoa(1) + "</a></li>" rs += "<li><a href='" + po.Href + "&" + po.ParamName + "=" + con.Itoa(1) + "'>" + con.Itoa(1) + "</a></li>"
rs += "<a href=''>...</a>" rs += "<li><a href=\"#\" class=\"@1\">...</a></li>"
for i := po.CurrentPage - po.LinkItemCount/2 + 1; i <= po.CurrentPage+po.LinkItemCount/2-1; i++ { for i := po.CurrentPage - po.LinkItemCount/2 + 1; i <= po.CurrentPage+po.LinkItemCount/2-1; i++ {
if po.CurrentPage != i { if po.CurrentPage != i {
rs += "<a href='" + po.Href + "&" + po.ParamName + "=" + con.Itoa(i) + "'>" + con.Itoa(i) + "</a>" rs += "<li><a href='" + po.Href + "&" + po.ParamName + "=" + con.Itoa(i) + "'>" + con.Itoa(i) + "</a></li>"
} else { } else {
rs += "<li class=\"active\"><a href=\"###\">" + con.Itoa(i) + " <span class=\"sr-only\">(current)</span></a></li>" rs += "<li class=\"active\"><a href=\"###\">" + con.Itoa(i) + " <span class=\"sr-only\">(current)</span></a></li>"
} }
} }
rs += "<a href=''>...</a>" rs += "<li><a href=\"#\" class=\"@2\">...</a></li>"
rs += "<li><a href='" + po.Href + "&" + po.ParamName + "=" + con.Itoa(totalpages) + "'>" + con.Itoa(totalpages) + "</a></li>" rs += "<li><a href='" + po.Href + "&" + po.ParamName + "=" + con.Itoa(totalpages) + "'>" + con.Itoa(totalpages) + "</a></li>"
rs += getFooter(po, totalpages) rs += getFooter(po, totalpages)
return rs return rs
@ -207,11 +211,11 @@ func fun3(po *PageOptions, totalpages int) string {
* 123456789...200 * 123456789...200
*/ */
func fun2(po *PageOptions, totalpages int) string { func fun2(po *PageOptions, totalpages int) string {
var rs string = "" rs := ""
rs += getHeader(po, totalpages) rs += getHeader(po, totalpages)
for i := 1; i <= po.LinkItemCount+1; i++ { for i := 1; i <= po.LinkItemCount+2; i++ {
if i == po.LinkItemCount { if i == po.LinkItemCount+2 {
rs += "<li><a href=\"" + po.Href + "&" + po.ParamName + "=" + con.Itoa(i) + "\">...</a></li>" rs += "<li class=\"@4\"><a href=\"" + po.Href + "&" + po.ParamName + "=" + con.Itoa(i) + "\">...</a></li>"
} else if i == po.LinkItemCount+1 { } else if i == po.LinkItemCount+1 {
rs += "<li><a href=\"" + po.Href + "&" + po.ParamName + "=" + con.Itoa(totalpages) + "\">" + con.Itoa(totalpages) + "</a></li>" rs += "<li><a href=\"" + po.Href + "&" + po.ParamName + "=" + con.Itoa(totalpages) + "\">" + con.Itoa(totalpages) + "</a></li>"
} else { } else {
@ -255,7 +259,7 @@ func getHeader(po *PageOptions, totalpages int) string {
if po.EnableFirstLastLink { //当首页,尾页都设定的时候,就显示 if po.EnableFirstLastLink { //当首页,尾页都设定的时候,就显示
if po.CurrentPage == 1 { if po.CurrentPage == 1 {
rs += "<li" + judgeDisable(po, totalpages, 0) + " class=\"disabled\"><a href=\"###\">" + po.FirstPageText + "</a></li>" rs += "<li" + judgeDisable(po, totalpages, 0) + " class=\"disabled\"><a href=\"###\">" + po.FirstPageText + "</a></li>"
}else{ } else {
rs += "<li" + judgeDisable(po, totalpages, 0) + " ><a href='" + po.Href + "&" + po.ParamName + "=" + con.Itoa(1) + "'>" + po.FirstPageText + "</a></li>" rs += "<li" + judgeDisable(po, totalpages, 0) + " ><a href='" + po.Href + "&" + po.ParamName + "=" + con.Itoa(1) + "'>" + po.FirstPageText + "</a></li>"
} }
} }
@ -281,7 +285,7 @@ func getFooter(po *PageOptions, totalpages int) string {
if po.EnableFirstLastLink { //当首页,尾页都设定的时候,就显示 if po.EnableFirstLastLink { //当首页,尾页都设定的时候,就显示
if po.CurrentPage == totalpages { if po.CurrentPage == totalpages {
rs += "<li " + judgeDisable(po, totalpages, 1) + " class=\"disabled\"><a href=\"###\">" + po.LastPageText + "</a></li>" rs += "<li " + judgeDisable(po, totalpages, 1) + " class=\"disabled\"><a href=\"###\">" + po.LastPageText + "</a></li>"
}else{ } else {
rs += "<li " + judgeDisable(po, totalpages, 1) + " ><a href=\"" + po.Href + "&" + po.ParamName + "=" + con.Itoa(totalpages) + "\">" + po.LastPageText + "</a></li>" rs += "<li " + judgeDisable(po, totalpages, 1) + " ><a href=\"" + po.Href + "&" + po.ParamName + "=" + con.Itoa(totalpages) + "\">" + po.LastPageText + "</a></li>"
} }
} }

View File

@ -1,15 +1,14 @@
package utils package utils
import ( import (
"crypto/rand"
mt "math/rand"
"crypto/md5" "crypto/md5"
"crypto/rand"
"crypto/sha256" "crypto/sha256"
"crypto/sha512" "crypto/sha512"
"encoding/base64" "encoding/base64"
"encoding/hex" "encoding/hex"
"io" "io"
mt "math/rand"
"strconv" "strconv"
"strings" "strings"
) )
@ -20,6 +19,7 @@ const (
stretching_password = 500 stretching_password = 500
salt_local_secret = "ahfw*&TGdsfnbi*^Wt" salt_local_secret = "ahfw*&TGdsfnbi*^Wt"
) )
//加密密码 //加密密码
func PasswordHash(pass string) (string, error) { func PasswordHash(pass string) (string, error) {
@ -45,6 +45,7 @@ func PasswordHash(pass string) (string, error) {
return password, nil return password, nil
} }
//校验密码是否有效 //校验密码是否有效
func PasswordVerify(hashing string, pass string) (bool, error) { func PasswordVerify(hashing string, pass string) (bool, error) {
data := trim_salt_hash(hashing) data := trim_salt_hash(hashing)
@ -56,7 +57,7 @@ func PasswordVerify(hashing string, pass string) (bool, error) {
return false, err return false, err
} }
if (data["salt_secret"]+delmiter+data["interation_string"]+delmiter+has+delmiter+data["salt"]) == hashing { if (data["salt_secret"] + delmiter + data["interation_string"] + delmiter + has + delmiter + data["salt"]) == hashing {
return true, nil return true, nil
} else { } else {
return false, nil return false, nil
@ -110,7 +111,7 @@ func trim_salt_hash(hash string) map[string]string {
} }
func salt(secret string) (string, error) { func salt(secret string) (string, error) {
buf := make([]byte, saltSize, saltSize + md5.Size) buf := make([]byte, saltSize, saltSize+md5.Size)
_, err := io.ReadFull(rand.Reader, buf) _, err := io.ReadFull(rand.Reader, buf)
if err != nil { if err != nil {
return "", err return "", err

View File

@ -1,5 +1,5 @@
package utils package utils
func Asset(p string,cdn string) string { func Asset(p string, cdn string) string {
return cdn + p; return cdn + p
} }

View File

@ -8,17 +8,17 @@ func JoinURI(elem ...string) string {
} }
uri := "" uri := ""
for i,u := range elem { for i, u := range elem {
u = strings.Replace(u,"\\","/",-1) u = strings.Replace(u, "\\", "/", -1)
if i == 0 { if i == 0 {
if !strings.HasSuffix(u,"/") { if !strings.HasSuffix(u, "/") {
u = u + "/" u = u + "/"
} }
uri = u uri = u
}else{ } else {
u = strings.Replace(u,"//","/",-1) u = strings.Replace(u, "//", "/", -1)
if strings.HasPrefix(u,"/") { if strings.HasPrefix(u, "/") {
u = string(u[1:]) u = string(u[1:])
} }
uri += u uri += u

View File

@ -0,0 +1,101 @@
package ziptil
import (
"archive/zip"
"errors"
"io"
"io/ioutil"
"os"
"path/filepath"
"strings"
"github.com/lifei6671/mindoc/utils/filetil"
)
//解压zip文件
//@param zipFile 需要解压的zip文件
//@param dest 需要解压到的目录
//@return err 返回错误
func Unzip(zipFile, dest string) (err error) {
dest = strings.TrimSuffix(dest, "/") + "/"
// 打开一个zip格式文件
r, err := zip.OpenReader(zipFile)
if err != nil {
return err
}
defer r.Close()
// 迭代压缩文件中的文件,打印出文件中的内容
for _, f := range r.File {
if !f.FileInfo().IsDir() { //非目录且不包含__MACOSX
if folder := dest + filepath.Dir(f.Name); !strings.Contains(folder, "__MACOSX") {
os.MkdirAll(folder, 0777)
if fcreate, err := os.Create(dest + strings.TrimPrefix(f.Name, "./")); err == nil {
if rc, err := f.Open(); err == nil {
io.Copy(fcreate, rc)
rc.Close() //不要用defer来关闭如果文件太多的话会报too many open files 的错误
fcreate.Close()
} else {
fcreate.Close()
return err
}
} else {
return err
}
}
}
}
return nil
}
//压缩指定文件或文件夹
//@param dest 压缩后的zip文件目标如/usr/local/hello.zip
//@param filepath 需要压缩的文件或者文件夹
//@return err 错误。如果返回错误则会删除dest文件
func Zip(dest string, filepath ...string) (err error) {
if len(filepath) == 0 {
return errors.New("lack of file")
}
//创建文件
fzip, err := os.Create(dest)
if err != nil {
return err
}
defer fzip.Close()
var filelist []filetil.FileList
for _, file := range filepath {
if info, err := os.Stat(file); err == nil {
if info.IsDir() { //目录,则扫描文件
if f, _ := filetil.ScanFiles(file); len(f) > 0 {
filelist = append(filelist, f...)
}
} else { //文件
filelist = append(filelist, filetil.FileList{
IsDir: false,
Name: info.Name(),
Path: file,
})
}
} else {
return err
}
}
w := zip.NewWriter(fzip)
defer w.Close()
for _, file := range filelist {
if !file.IsDir {
if fw, err := w.Create(strings.TrimLeft(file.Path, "./")); err != nil {
return err
} else {
if filecontent, err := ioutil.ReadFile(file.Path); err != nil {
return err
} else {
if _, err = fw.Write(filecontent); err != nil {
return err
}
}
}
}
}
return
}

View File

@ -131,7 +131,7 @@
return false; return false;
} else { } else {
$.ajax({ $.ajax({
url: "{{urlfor "AccountController.Login"}}", url: "{{urlfor "AccountController.Login" "url" .url}}",
data: $("form").serializeArray(), data: $("form").serializeArray(),
dataType: "json", dataType: "json",
type: "POST", type: "POST",
@ -142,7 +142,7 @@
layer.msg(res.message); layer.msg(res.message);
$btn.button('reset'); $btn.button('reset');
} else { } else {
turl = res.data.turl; turl = res.data;
if (turl === "") { if (turl === "") {
turl = "/"; turl = "/";
} }

View File

@ -65,6 +65,7 @@
<li><a href="{{urlfor "DocumentController.Export" ":key" .Model.Identify "output" "pdf"}}" target="_blank">PDF</a> </li> <li><a href="{{urlfor "DocumentController.Export" ":key" .Model.Identify "output" "pdf"}}" target="_blank">PDF</a> </li>
<li><a href="{{urlfor "DocumentController.Export" ":key" .Model.Identify "output" "epub"}}" target="_blank">EPUB</a> </li> <li><a href="{{urlfor "DocumentController.Export" ":key" .Model.Identify "output" "epub"}}" target="_blank">EPUB</a> </li>
<li><a href="{{urlfor "DocumentController.Export" ":key" .Model.Identify "output" "mobi"}}" target="_blank">MOBI</a> </li> <li><a href="{{urlfor "DocumentController.Export" ":key" .Model.Identify "output" "mobi"}}" target="_blank">MOBI</a> </li>
<li><a href="{{urlfor "DocumentController.Export" ":key" .Model.Identify "output" "docx"}}" target="_blank">Word</a> </li>
</ul> </ul>
</div> </div>