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

@ -19,10 +19,10 @@ type Daemon struct {
func NewDaemon() *Daemon { func NewDaemon() *Daemon {
config := &service.Config{ config := &service.Config{
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,51 +111,53 @@ 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 {
return tables,err
}
for _,table := range lists {
var results []orm.Params
_,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)) for _, table := range lists {
} var results []orm.Params
break;
} _, err = o.Raw(fmt.Sprintf("show create table %s", table["TABLE_NAME"])).Values(&results)
case "sqlite3": { if err != nil {
var results []orm.Params return tables, err
_,err := o.Raw("SELECT sql FROM sqlite_master WHERE sql IS NOT NULL ORDER BY rootpage ASC").Values(&results) }
if err != nil { tables = append(tables, results[0]["Create Table"].(string))
return tables,err
}
for _,item := range results {
if sql,ok := item["sql"]; ok {
tables = append(tables,sql.(string))
} }
break
}
case "sqlite3":
{
var results []orm.Params
_, err := o.Raw("SELECT sql FROM sqlite_master WHERE sql IS NOT NULL ORDER BY rootpage ASC").Values(&results)
if err != nil {
return tables, err
}
for _, item := range results {
if sql, ok := item["sql"]; ok {
tables = append(tables, sql.(string))
}
}
break
} }
break
}
} }
return tables,nil return tables, nil
} }
func RegisterMigration() { func RegisterMigration() {
migrationList.items = list.New() migrationList.items = list.New()
migrationList.items.PushBack(NewMigrationVersion03()) migrationList.items.PushBack(NewMigrationVersion03())
} }

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,24 +83,24 @@ 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
} }
migration := models.NewMigration() migration := models.NewMigration()
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)
return err return err
} }
func (m *MigrationVersion03) MigrationCleanup() error { func (m *MigrationVersion03) MigrationCleanup() error {
return nil return nil
} }
@ -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 (
@ -44,23 +44,31 @@ const (
) )
const ( const (
LoggerOperate = "operate" LoggerOperate = "operate"
LoggerSystem = "system" LoggerSystem = "system"
LoggerException = "exception" LoggerException = "exception"
LoggerDocument = "document" LoggerDocument = "document"
) )
const ( const (
//本地账户校验 //本地账户校验
AuthMethodLocal = "local" AuthMethodLocal = "local"
//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,29 +110,30 @@ 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

@ -6,33 +6,33 @@ import (
) )
type SmtpConf struct { type SmtpConf struct {
EnableMail bool EnableMail bool
MailNumber int MailNumber int
SmtpUserName string SmtpUserName string
SmtpHost string SmtpHost string
SmtpPassword string SmtpPassword string
SmtpPort int SmtpPort int
FormUserName string FormUserName string
MailExpired int MailExpired int
} }
func GetMailConfig() *SmtpConf { 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,14 +33,17 @@ 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 {
if err := utils.Decode(cookie, &remember); err == nil { if err := utils.Decode(cookie, &remember); err == nil {
@ -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,53 +1,52 @@
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
Option map[string]string Option map[string]string
EnableAnonymous bool EnableAnonymous bool
EnableDocumentHistory bool EnableDocumentHistory bool
} }
// 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,28 +101,28 @@ 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
c.StopRun() c.StopRun()
} }

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")
@ -79,17 +78,17 @@ func (c *BookController) Dashboard() {
} }
// Setting 项目设置 . // Setting 项目设置 .
func (c *BookController) Setting() { func (c *BookController) Setting() {
c.Prepare() c.Prepare()
c.TplName = "book/setting.tpl" c.TplName = "book/setting.tpl"
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,225 +103,224 @@ 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
} }
//保存项目信息 //保存项目信息
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" {
editor = "markdown" editor = "markdown"
} }
book.BookName = book_name book.BookName = book_name
book.Description = description book.Description = description
book.CommentStatus = comment_status book.CommentStatus = comment_status
book.Label = tag book.Label = tag
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)
} }
//设置项目私有状态. //设置项目私有状态.
func (c *BookController) PrivatelyOwned() { 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 转让项目.
func (c *BookController) Transfer() { func (c *BookController) Transfer() {
c.Prepare() c.Prepare()
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)
width := int(w1) width := int(w1)
height := int(h1) height := int(h1)
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,39 +413,39 @@ 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
book.Description = description book.Description = description
book.CommentCount = 0 book.CommentCount = 0
book.PrivatelyOwned = privately_owned book.PrivatelyOwned = privately_owned
book.CommentStatus = comment_status book.CommentStatus = comment_status
book.Identify = identify book.Identify = identify
book.DocCount = 0 book.DocCount = 0
book.MemberId = c.Member.MemberId book.MemberId = c.Member.MemberId
book.CommentCount = 0 book.CommentCount = 0
book.Version = time.Now().Unix() book.Version = time.Now().Unix()
book.Cover = conf.GetDefaultCover() book.Cover = conf.GetDefaultCover()
book.Editor = "markdown" book.Editor = "markdown"
book.Theme = "default" book.Theme = "default"
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 {
@ -14,31 +14,31 @@ type BookMemberController struct {
} }
// AddMember 参加参与用户. // AddMember 参加参与用户.
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

@ -4,16 +4,16 @@ type CommentController struct {
BaseController BaseController
} }
func (c *CommentController) Lists() { 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() {
c.Prepare() c.Prepare()
c.TplName = "comment/index.tpl" c.TplName = "comment/index.tpl"
} }

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
@ -438,11 +433,10 @@ 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)
} }
@ -819,15 +813,13 @@ func (c *DocumentController) Content() {
beego.Error("DocumentHistory InsertOrUpdate => ", err) beego.Error("DocumentHistory InsertOrUpdate => ", err)
} }
} }
if auto_release { if auto_release {
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,64 +212,64 @@ 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
} }
//删除一个用户,并将该用户的所有信息转移到超级管理员上. //删除一个用户,并将该用户的所有信息转移到超级管理员上.
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)
@ -583,27 +582,27 @@ 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)
@ -612,43 +611,22 @@ 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,31 +1,31 @@
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 {
BaseController BaseController
} }
func (c *SearchController) Index() { func (c *SearchController) Index() {
c.Prepare() c.Prepare()
c.TplName = "search/index.tpl" c.TplName = "search/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"), 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,24 +3,23 @@ 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 {
BaseController BaseController
} }
func (c *SettingController) Index() { func (c *SettingController) Index() {
c.TplName = "setting/index.tpl" c.TplName = "setting/index.tpl"
if c.Ctx.Input.IsPost() { if c.Ctx.Input.IsPost() {
@ -43,131 +42,129 @@ func (c *SettingController) Index() {
} }
} }
func (c *SettingController) Password() { func (c *SettingController) Password() {
c.TplName = "setting/password.tpl" c.TplName = "setting/password.tpl"
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

@ -8,27 +8,27 @@ import (
type AttachmentResult struct { type AttachmentResult struct {
Attachment Attachment
IsExist bool IsExist bool
BookName string BookName string
DocumentName string DocumentName string
FileShortSize string FileShortSize string
Account string Account string
LocalHttpPath string LocalHttpPath string
} }
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

@ -4,9 +4,9 @@ import "time"
//博文表 //博文表
type Blog struct { type Blog struct {
BlogId int BlogId int
BlogTitle string BlogTitle string
MemberId int MemberId int
//文字摘要 //文字摘要
BlogExcerpt string BlogExcerpt string
//文章内容 //文章内容
@ -22,4 +22,4 @@ type Blog struct {
ModifyAt int ModifyAt int
//创建时间 //创建时间
Created time.Time Created time.Time
} }

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 .
@ -16,17 +19,15 @@ type Book struct {
// BookName 项目名称. // BookName 项目名称.
BookName string `orm:"column(book_name);size(500)" json:"book_name"` BookName string `orm:"column(book_name);size(500)" json:"book_name"`
// Identify 项目唯一标识. // Identify 项目唯一标识.
Identify string `orm:"column(identify);size(100);unique" json:"identify"` Identify string `orm:"column(identify);size(100);unique" json:"identify"`
//是否是自动发布 0 否/1 是 //是否是自动发布 0 否/1 是
AutoRelease int `orm:"column(auto_release);type(int);default(0)" json:"auto_release"` AutoRelease int `orm:"column(auto_release);type(int);default(0)" json:"auto_release"`
OrderIndex int `orm:"column(order_index);type(int);default(0)" json:"order_index"` OrderIndex int `orm:"column(order_index);type(int);default(0)" json:"order_index"`
// Description 项目描述. // Description 项目描述.
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 为不缓存 Label string `orm:"column(label);size(500)" json:"label"`
IsCacheEBook int `orm:"column(is_cache_ebook);type(int);default(0)" json:"is_cache_ebook"`
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"`
// 当项目是私有时的访问Token. // 当项目是私有时的访问Token.
@ -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,64 +1,64 @@
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 {
BookId int `json:"book_id"` BookId int `json:"book_id"`
BookName string `json:"book_name"` BookName string `json:"book_name"`
Identify string `json:"identify"` Identify string `json:"identify"`
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"` CommentStatus string `json:"comment_status"`
CommentStatus string `json:"comment_status"` CommentCount int `json:"comment_count"`
CommentCount int `json:"comment_count"` CreateTime time.Time `json:"create_time"`
CreateTime time.Time `json:"create_time"` CreateName string `json:"create_name"`
CreateName string `json:"create_name"` ModifyTime time.Time `json:"modify_time"`
ModifyTime time.Time `json:"modify_time"` Cover string `json:"cover"`
Cover string `json:"cover"` Theme string `json:"theme"`
Theme string `json:"theme"` Label string `json:"label"`
Label string `json:"label"` MemberId int `json:"member_id"`
MemberId int `json:"member_id"` Editor string `json:"editor"`
Editor string `json:"editor"` AutoRelease bool `json:"auto_release"`
AutoRelease bool `json:"auto_release"`
RelationshipId int `json:"relationship_id"` RelationshipId int `json:"relationship_id"`
RoleId int `json:"role_id"` RoleId int `json:"role_id"`
RoleName string `json:"role_name"` RoleName string `json:"role_name"`
Status int Status int
LastModifyText string `json:"last_modify_text"` LastModifyText string `json:"last_modify_text"`
IsDisplayComment bool `json:"is_display_comment"` IsDisplayComment bool `json:"is_display_comment"`
} }
func NewBookResult() *BookResult { 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()
@ -93,11 +93,10 @@ func (m *BookResult) FindByIdentify(identify string,member_id int) (*BookResult,
m = NewBookResult().ToBookResult(*book) m = NewBookResult().ToBookResult(*book)
m.CreateName = member.Account m.CreateName = member.Account
m.MemberId = relationship.MemberId m.MemberId = relationship.MemberId
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 = "创始人"
@ -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,128 +178,139 @@ 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
pdfpath := filepath.Join(outputPath, "book.pdf")
epubpath := filepath.Join(outputPath, "book.epub")
mobipath := filepath.Join(outputPath, "book.mobi")
docxpath := filepath.Join(outputPath, "book.docx")
//先将转换的文件储存到临时目录
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.MobiPath = mobipath
convertBookResult.PDFPath = pdfpath
convertBookResult.WordPath = docxpath
return convertBookResult, nil
} }
if m.IsCacheEBook {
pdfpath := filepath.Join(outputPath,"output","book.pdf")
epubpath := filepath.Join(outputPath,"output","book.epub")
mobipath := filepath.Join(outputPath,"output","book.mobi")
if utils.FileExists(pdfpath) && utils.FileExists(epubpath) && utils.FileExists(mobipath){
convertBookResult.EpubPath = epubpath
convertBookResult.MobiPath = mobipath
convertBookResult.PDFPath = pdfpath
return convertBookResult,nil
}
}
docs, err := NewDocument().FindListByBookId(m.BookId) docs, err := NewDocument().FindListByBookId(m.BookId)
if err != nil { if err != nil {
return convertBookResult,err return convertBookResult, err
} }
tocList := make([]converter.Toc,0) tocList := make([]converter.Toc, 0)
for _, item := range docs { for _, item := range docs {
if item.ParentId == 0 { if item.ParentId == 0 {
toc := converter.Toc{ toc := converter.Toc{
Id: item.DocumentId, Id: item.DocumentId,
Link: strconv.Itoa(item.DocumentId) + ".html", Link: strconv.Itoa(item.DocumentId) + ".html",
Pid: item.ParentId, Pid: item.ParentId,
Title: item.DocumentName, Title: item.DocumentName,
} }
tocList = append(tocList,toc) tocList = append(tocList, toc)
} }
} }
for _, item := range docs { for _, item := range docs {
if item.ParentId != 0 { if item.ParentId != 0 {
toc := converter.Toc{ toc := converter.Toc{
Id: item.DocumentId, Id: item.DocumentId,
Link: strconv.Itoa(item.DocumentId) + ".html", Link: strconv.Itoa(item.DocumentId) + ".html",
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,76 +1,77 @@
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
type Comment struct { type Comment struct {
CommentId int `orm:"pk;auto;unique;column(comment_id)" json:"comment_id"` CommentId int `orm:"pk;auto;unique;column(comment_id)" json:"comment_id"`
Floor int `orm:"column(floor);type(unsigned);default(0)" json:"floor"` Floor int `orm:"column(floor);type(unsigned);default(0)" json:"floor"`
BookId int `orm:"column(book_id);type(int)" json:"book_id"` BookId int `orm:"column(book_id);type(int)" json:"book_id"`
// DocumentId 评论所属的文档. // DocumentId 评论所属的文档.
DocumentId int `orm:"column(document_id);type(int)" json:"document_id"` DocumentId int `orm:"column(document_id);type(int)" json:"document_id"`
// Author 评论作者. // Author 评论作者.
Author string `orm:"column(author);size(100)" json:"author"` Author string `orm:"column(author);size(100)" json:"author"`
//MemberId 评论用户ID. //MemberId 评论用户ID.
MemberId int `orm:"column(member_id);type(int)" json:"member_id"` MemberId int `orm:"column(member_id);type(int)" json:"member_id"`
// IPAddress 评论者的IP地址 // IPAddress 评论者的IP地址
IPAddress string `orm:"column(ip_address);size(100)" json:"ip_address"` IPAddress string `orm:"column(ip_address);size(100)" json:"ip_address"`
// 评论日期. // 评论日期.
CommentDate time.Time `orm:"type(datetime);column(comment_date);auto_now_add" json:"comment_date"` CommentDate time.Time `orm:"type(datetime);column(comment_date);auto_now_add" json:"comment_date"`
//Content 评论内容. //Content 评论内容.
Content string `orm:"column(content);size(2000)" json:"content"` Content string `orm:"column(content);size(2000)" json:"content"`
// Approved 评论状态0 待审核/1 已审核/2 垃圾评论/ 3 已删除 // Approved 评论状态0 待审核/1 已审核/2 垃圾评论/ 3 已删除
Approved int `orm:"column(approved);type(int)" json:"approved"` Approved int `orm:"column(approved);type(int)" json:"approved"`
// UserAgent 评论者浏览器内容 // UserAgent 评论者浏览器内容
UserAgent string `orm:"column(user_agent);size(500)" json:"user_agent"` UserAgent string `orm:"column(user_agent);size(500)" json:"user_agent"`
// Parent 评论所属父级 // Parent 评论所属父级
ParentId int `orm:"column(parent_id);type(int);default(0)" json:"parent_id"` ParentId int `orm:"column(parent_id);type(int);default(0)" json:"parent_id"`
AgreeCount int `orm:"column(agree_count);type(int);default(0)" json:"agree_count"` AgreeCount int `orm:"column(agree_count);type(int);default(0)" json:"agree_count"`
AgainstCount int `orm:"column(against_count);type(int);default(0)" json:"against_count"` AgainstCount int `orm:"column(against_count);type(int);default(0)" json:"against_count"`
} }
// TableName 获取对应数据库表名. // TableName 获取对应数据库表名.
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"
} }
func (m *Comment) TableNameWithPrefix() string { func (m *Comment) TableNameWithPrefix() string {
return conf.GetDatabasePrefix() + m.TableName() return conf.GetDatabasePrefix() + m.TableName()
} }
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

@ -4,11 +4,11 @@ import "github.com/astaxie/beego/orm"
type CommentResult struct { type CommentResult struct {
Comment Comment
Author string `json:"author"` Author string `json:"author"`
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,30 +1,31 @@
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 {
VoteId int `orm:"column(vote_id);pk;auto;unique" json:"vote_id"` VoteId int `orm:"column(vote_id);pk;auto;unique" json:"vote_id"`
CommentId int `orm:"column(comment_id);type(int);index" json:"comment_id"` CommentId int `orm:"column(comment_id);type(int);index" json:"comment_id"`
CommentMemberId int `orm:"column(comment_member_id);type(int);index;default(0)" json:"comment_member_id"` CommentMemberId int `orm:"column(comment_member_id);type(int);index;default(0)" json:"comment_member_id"`
VoteMemberId int `orm:"column(vote_member_id);type(int);index" json:"vote_member_id"` VoteMemberId int `orm:"column(vote_member_id);type(int);index" json:"vote_member_id"`
VoteState int `orm:"column(vote_state);type(int)" json:"vote_state"` VoteState int `orm:"column(vote_state);type(int)" json:"vote_state"`
CreateTime time.Time `orm:"column(create_time);type(datetime);auto_now_add" json:"create_time"` CreateTime time.Time `orm:"column(create_time);type(datetime);auto_now_add" json:"create_time"`
} }
// TableName 获取对应数据库表名. // TableName 获取对应数据库表名.
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"
} }
func (m *CommentVote) TableNameWithPrefix() string { func (m *CommentVote) TableNameWithPrefix() string {
return conf.GetDatabasePrefix() + m.TableName() return conf.GetDatabasePrefix() + m.TableName()
} }
func (u *CommentVote) TableUnique() [][]string { func (u *CommentVote) TableUnique() [][]string {
@ -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

@ -2,7 +2,8 @@ package models
// 转换结果 // 转换结果
type ConvertBookResult struct { type ConvertBookResult struct {
PDFPath string PDFPath string
EpubPath string EpubPath string
MobiPath string MobiPath string
WordPath string
} }

View File

@ -3,34 +3,34 @@ package models
import "github.com/astaxie/beego/orm" import "github.com/astaxie/beego/orm"
type Dashboard struct { type Dashboard struct {
BookNumber int64 `json:"book_number"` BookNumber int64 `json:"book_number"`
DocumentNumber int64 `json:"document_number"` DocumentNumber int64 `json:"document_number"`
MemberNumber int64 `json:"member_number"` MemberNumber int64 `json:"member_number"`
CommentNumber int64 `json:"comment_number"` CommentNumber int64 `json:"comment_number"`
AttachmentNumber int64 `json:"attachment_number"` AttachmentNumber int64 `json:"attachment_number"`
} }
func NewDashboard() *Dashboard { 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

@ -23,14 +23,14 @@ type DocumentHistory struct {
} }
type DocumentHistorySimpleResult struct { type DocumentHistorySimpleResult struct {
HistoryId int `json:"history_id"` HistoryId int `json:"history_id"`
ActionName string `json:"action_name"` ActionName string `json:"action_name"`
MemberId int `json:"member_id"` MemberId int `json:"member_id"`
Account string `json:"account"` Account string `json:"account"`
ModifyAt int `json:"modify_at"` ModifyAt int `json:"modify_at"`
ModifyName string `json:"modify_name"` ModifyName string `json:"modify_name"`
ModifyTime time.Time `json:"modify_time"` ModifyTime time.Time `json:"modify_time"`
Version int64 `json:"version"` Version int64 `json:"version"`
} }
// TableName 获取对应数据库表名. // TableName 获取对应数据库表名.
@ -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,48 +1,49 @@
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 {
DocumentId int `json:"id"` DocumentId int `json:"id"`
DocumentName string `json:"text"` DocumentName string `json:"text"`
ParentId interface{} `json:"parent"` ParentId interface{} `json:"parent"`
Identify string `json:"identify"` Identify string `json:"identify"`
BookIdentify string `json:"-"` BookIdentify string `json:"-"`
Version int64 `json:"version"` Version int64 `json:"version"`
State *DocumentSelected `json:"state,omitempty"` State *DocumentSelected `json:"state,omitempty"`
} }
type DocumentSelected struct { type DocumentSelected struct {
Selected bool `json:"selected"` Selected bool `json:"selected"`
Opened bool `json:"opened"` Opened bool `json:"opened"`
} }
//获取项目的文档树状结构 //获取项目的文档树状结构
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

@ -5,16 +5,16 @@ import "errors"
var ( var (
// ErrMemberNoExist 用户不存在. // ErrMemberNoExist 用户不存在.
ErrMemberNoExist = errors.New("用户不存在") ErrMemberNoExist = errors.New("用户不存在")
ErrMemberExist = errors.New("用户已存在") ErrMemberExist = errors.New("用户已存在")
ErrMemberDisabled = errors.New("用户被禁用") ErrMemberDisabled = errors.New("用户被禁用")
ErrMemberEmailEmpty = errors.New("用户邮箱不能为空") ErrMemberEmailEmpty = errors.New("用户邮箱不能为空")
ErrMemberEmailExist = errors.New("用户邮箱已被使用") ErrMemberEmailExist = errors.New("用户邮箱已被使用")
ErrMemberDescriptionTooLong = errors.New("用户描述必须小于500字") ErrMemberDescriptionTooLong = errors.New("用户描述必须小于500字")
ErrMemberEmailFormatError = errors.New("邮箱格式不正确") ErrMemberEmailFormatError = errors.New("邮箱格式不正确")
ErrMemberPasswordFormatError = errors.New("密码必须在6-50个字符之间") ErrMemberPasswordFormatError = errors.New("密码必须在6-50个字符之间")
ErrMemberAccountFormatError = errors.New("账号只能由英文字母数字组成且在3-50个字符") ErrMemberAccountFormatError = errors.New("账号只能由英文字母数字组成且在3-50个字符")
ErrMemberRoleError = errors.New("用户权限不正确") ErrMemberRoleError = errors.New("用户权限不正确")
// ErrorMemberPasswordError 密码错误. // ErrorMemberPasswordError 密码错误.
ErrorMemberPasswordError = errors.New("用户密码错误") ErrorMemberPasswordError = errors.New("用户密码错误")
//ErrorMemberAuthMethodInvalid 不支持此认证方式 //ErrorMemberAuthMethodInvalid 不支持此认证方式

View File

@ -1,35 +1,36 @@
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"
) )
type Label struct { type Label struct {
LabelId int `orm:"column(label_id);pk;auto;unique;" json:"label_id"` LabelId int `orm:"column(label_id);pk;auto;unique;" json:"label_id"`
LabelName string `orm:"column(label_name);size(50);unique" json:"label_name"` LabelName string `orm:"column(label_name);size(50);unique" json:"label_name"`
BookNumber int `orm:"column(book_number)" json:"book_number"` BookNumber int `orm:"column(book_number)" json:"book_number"`
} }
// TableName 获取对应数据库表名. // TableName 获取对应数据库表名.
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()
} }
func NewLabel() *Label { 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,27 +42,27 @@ 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
} }
//批量插入或更新标签. //批量插入或更新标签.
func (m *Label) InsertOrUpdateMulti(labels string) { func (m *Label) InsertOrUpdateMulti(labels string) {
if labels != "" { if labels != "" {
labelArray := strings.Split(labels, ",") labelArray := strings.Split(labels, ",")
for _, label := range labelArray { for _, label := range labelArray {
@ -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,38 +1,39 @@
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
isRuning int32 isRuning int32
} }
// Logger struct . // Logger struct .
type Logger struct { type Logger struct {
LoggerId int64 `orm:"pk;auto;unique;column(log_id)" json:"log_id"` LoggerId int64 `orm:"pk;auto;unique;column(log_id)" json:"log_id"`
MemberId int `orm:"column(member_id);type(int)" json:"member_id"` MemberId int `orm:"column(member_id);type(int)" json:"member_id"`
// 日志类别operate 操作日志/ system 系统日志/ exception 异常日志 / document 文档操作日志 // 日志类别operate 操作日志/ system 系统日志/ exception 异常日志 / document 文档操作日志
Category string `orm:"column(category);size(255);default(operate)" json:"category"` Category string `orm:"column(category);size(255);default(operate)" json:"category"`
Content string `orm:"column(content);type(text)" json:"content"` Content string `orm:"column(content);type(text)" json:"content"`
OriginalData string `orm:"column(original_data);type(text)" json:"original_data"` OriginalData string `orm:"column(original_data);type(text)" json:"original_data"`
PresentData string `orm:"column(present_data);type(text)" json:"present_data"` PresentData string `orm:"column(present_data);type(text)" json:"present_data"`
CreateTime time.Time `orm:"type(datetime);column(create_time);auto_now_add" json:"create_time"` CreateTime time.Time `orm:"type(datetime);column(create_time);auto_now_add" json:"create_time"`
UserAgent string `orm:"column(user_agent);size(500)" json:"user_agent"` UserAgent string `orm:"column(user_agent);size(500)" json:"user_agent"`
IPAddress string `orm:"column(ip_address);size(255)" json:"ip_address"` IPAddress string `orm:"column(ip_address);size(255)" json:"ip_address"`
} }
// TableName 获取对应数据库表名. // TableName 获取对应数据库表名.
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,27 +1,27 @@
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 {
MemberId int `json:"member_id"` MemberId int `json:"member_id"`
Account string `json:"account"` Account string `json:"account"`
Description string `json:"description"` Description string `json:"description"`
Email string `json:"email"` Email string `json:"email"`
Phone string `json:"phone"` Phone string `json:"phone"`
Avatar string `json:"avatar"` Avatar string `json:"avatar"`
Role int `json:"role"` //用户角色0 管理员/ 1 普通用户 Role int `json:"role"` //用户角色0 管理员/ 1 普通用户
Status int `json:"status"` //用户状态0 正常/1 禁用 Status int `json:"status"` //用户状态0 正常/1 禁用
CreateTime time.Time `json:"create_time"` CreateTime time.Time `json:"create_time"`
CreateAt int `json:"create_at"` CreateAt int `json:"create_at"`
RelationshipId int `json:"relationship_id"` RelationshipId int `json:"relationship_id"`
BookId int `json:"book_id"` BookId int `json:"book_id"`
// RoleId 角色0 创始人(创始人不能被移除) / 1 管理员/2 编辑者/3 观察者 // RoleId 角色0 创始人(创始人不能被移除) / 1 管理员/2 编辑者/3 观察者
RoleId int `json:"role_id"` RoleId int `json:"role_id"`
RoleName string `json:"role_name"` RoleName string `json:"role_name"`
} }
func NewMemberRelationshipResult() *MemberRelationshipResult { func NewMemberRelationshipResult() *MemberRelationshipResult {
@ -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,66 +1,66 @@
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 {
TokenId int `orm:"column(token_id);pk;auto;unique" json:"token_id"` TokenId int `orm:"column(token_id);pk;auto;unique" json:"token_id"`
MemberId int `orm:"column(member_id);type(int)" json:"member_id"` MemberId int `orm:"column(member_id);type(int)" json:"member_id"`
Token string `orm:"column(token);size(150);index" json:"token"` Token string `orm:"column(token);size(150);index" json:"token"`
Email string `orm:"column(email);size(255)" json:"email"` Email string `orm:"column(email);size(255)" json:"email"`
IsValid bool `orm:"column(is_valid)" json:"is_valid"` IsValid bool `orm:"column(is_valid)" json:"is_valid"`
ValidTime time.Time `orm:"column(valid_time);null" json:"valid_time"` ValidTime time.Time `orm:"column(valid_time);null" json:"valid_time"`
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()
} }
func NewMemberToken() *MemberToken { 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,18 +1,18 @@
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 {
MigrationId int `orm:"column(migration_id);pk;auto;unique;" json:"migration_id"` MigrationId int `orm:"column(migration_id);pk;auto;unique;" json:"migration_id"`
Name string `orm:"column(name);size(500)" json:"name"` Name string `orm:"column(name);size(500)" json:"name"`
Statements string `orm:"column(statements);type(text);null" json:"statements"` Statements string `orm:"column(statements);type(text);null" json:"statements"`
Status string `orm:"column(status);default(update)" json:"status"` Status string `orm:"column(status);default(update)" json:"status"`
CreateTime time.Time `orm:"column(create_time);type(datetime);auto_now_add" json:"create_time"` CreateTime time.Time `orm:"column(create_time);type(datetime);auto_now_add" json:"create_time"`
Version int64 `orm:"type(bigint);column(version);unique" json:"version"` Version int64 `orm:"type(bigint);column(version);unique" json:"version"`
} }
// TableName 获取对应数据库表名. // TableName 获取对应数据库表名.
@ -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,147 +5,145 @@ 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"`
OptionTitle string `orm:"column(option_title);size(500)" json:"option_title"` OptionTitle string `orm:"column(option_title);size(500)" json:"option_title"`
OptionName string `orm:"column(option_name);unique;size(80)" json:"option_name"` OptionName string `orm:"column(option_name);unique;size(80)" json:"option_name"`
OptionValue string `orm:"column(option_value);type(text);null" json:"option_value"` OptionValue string `orm:"column(option_value);type(text);null" json:"option_value"`
Remark string `orm:"column(remark);type(text);null" json:"remark"` Remark string `orm:"column(remark);type(text);null" json:"remark"`
} }
// TableName 获取对应数据库表名. // TableName 获取对应数据库表名.
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
} }
func (p *Option) InsertOrUpdate() error { func (p *Option) InsertOrUpdate() error {
o := orm.NewOrm() o := orm.NewOrm()
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
} }
} }
return nil return nil
} }

View File

@ -1,21 +1,20 @@
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 {
RelationshipId int `orm:"pk;auto;unique;column(relationship_id)" json:"relationship_id"` RelationshipId int `orm:"pk;auto;unique;column(relationship_id)" json:"relationship_id"`
MemberId int `orm:"column(member_id);type(int)" json:"member_id"` MemberId int `orm:"column(member_id);type(int)" json:"member_id"`
BookId int `orm:"column(book_id);type(int)" json:"book_id"` BookId int `orm:"column(book_id);type(int)" json:"book_id"`
// RoleId 角色0 创始人(创始人不能被移除) / 1 管理员/2 编辑者/3 观察者 // RoleId 角色0 创始人(创始人不能被移除) / 1 管理员/2 编辑者/3 观察者
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,97 +39,97 @@ 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
} }
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,43 +1,45 @@
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() {
var FilterUser = func(ctx *context.Context) { var FilterUser = func(ctx *context.Context) {
_, ok := ctx.Input.Session(conf.LoginSessionName).(models.Member) _, ok := ctx.Input.Session(conf.LoginSessionName).(models.Member)
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,16 +1,15 @@
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 // 小写字母
KC_RAND_KIND_UPPER = 2 // 大写字母 KC_RAND_KIND_UPPER = 2 // 大写字母
KC_RAND_KIND_ALL = 3 // 数字、大小写字母 KC_RAND_KIND_ALL = 3 // 数字、大小写字母
) )
// 随机字符串 // 随机字符串
@ -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"
) )
@ -25,7 +25,7 @@ type PageOptions struct {
NextPageText string //下一页文字 默认"下一页" NextPageText string //下一页文字 默认"下一页"
EnableFirstLastLink bool //是否启用首尾连接 默认false 建议开启 EnableFirstLastLink bool //是否启用首尾连接 默认false 建议开启
EnablePreNexLink bool //是否启用上一页,下一页连接 默认false 建议开启 EnablePreNexLink bool //是否启用上一页,下一页连接 默认false 建议开启
TotalPages int TotalPages int
} }
/** /**
@ -42,7 +42,7 @@ func GetPagesInfo(tableName string, currentpage int, pagesize int, conditions st
} }
var rs orm.RawSeter var rs orm.RawSeter
o := orm.NewOrm() o := orm.NewOrm()
var totalItem, totalpages int = 0, 0 //总条数,总页数 var totalItem, totalpages int = 0, 0 //总条数,总页数
o.Raw("SELECT count(*) FROM " + tableName + " where 1 > 0 " + conditions).QueryRow(&totalItem) //获取总条数 o.Raw("SELECT count(*) FROM " + tableName + " where 1 > 0 " + conditions).QueryRow(&totalItem) //获取总条数
if totalItem <= pagesize { if totalItem <= pagesize {
totalpages = 1 totalpages = 1
@ -58,22 +58,22 @@ 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
po.EnableFirstLastLink = true po.EnableFirstLastLink = true
po.LinkItemCount = 7 po.LinkItemCount = 7
po.TableName = "help_topic" po.TableName = "help_topic"
cp, _ := this.GetInt("pno") cp, _ := this.GetInt("pno")
po.CurrentPage = int(cp) po.CurrentPage = int(cp)
_,_,_ pager := util.GetPagerLinks(&po, this.Ctx) _,_,_ pager := util.GetPagerLinks(&po, this.Ctx)
this.Data["Email"] = html.HTML(pager) this.Data["Email"] = html.HTML(pager)
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,16 +114,16 @@ 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,18 +211,18 @@ 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 {
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 {
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>"
} }
} }
} }
@ -239,7 +243,7 @@ func fun1(po *PageOptions, totalpages int) string {
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 {
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 += getFooter(po, totalpages) rs += getFooter(po, totalpages)
@ -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>"
} }
} }
@ -339,4 +343,4 @@ func judgeDisable(po *PageOptions, totalpages int, h_f int) string {
} }
} }
return rs return rs
} }

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,8 +45,9 @@ 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)
interation, _ := strconv.ParseInt(data["interation_string"], 10, 64) interation, _ := strconv.ParseInt(data["interation_string"], 10, 64)
@ -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
@ -134,4 +135,4 @@ func salt_secret() (string, error) {
func randInt(min int, max int) int { func randInt(min int, max int) int {
return min + mt.Intn(max-min) return min + mt.Intn(max-min)
} }

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>