mirror of https://github.com/mindoc-org/mindoc.git
parent
e1ec6bb788
commit
882d93e7b0
|
@ -6,11 +6,12 @@ import (
|
|||
"net/url"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"log"
|
||||
"flag"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"encoding/json"
|
||||
"github.com/astaxie/beego"
|
||||
"github.com/astaxie/beego/logs"
|
||||
"github.com/astaxie/beego/orm"
|
||||
|
@ -19,14 +20,6 @@ import (
|
|||
"github.com/lifei6671/mindoc/conf"
|
||||
"github.com/lifei6671/mindoc/models"
|
||||
"github.com/lifei6671/mindoc/utils"
|
||||
"log"
|
||||
"encoding/json"
|
||||
)
|
||||
|
||||
var (
|
||||
ConfigurationFile = "./conf/app.conf"
|
||||
WorkingDirectory = "./"
|
||||
LogFile = "./logs"
|
||||
)
|
||||
|
||||
// RegisterDataBase 注册数据库
|
||||
|
@ -54,8 +47,8 @@ func RegisterDataBase() {
|
|||
}
|
||||
} else if adapter == "sqlite3" {
|
||||
database := beego.AppConfig.String("db_database")
|
||||
if strings.HasPrefix(database,"./") {
|
||||
database = filepath.Join(WorkingDirectory,string(database[1:]))
|
||||
if strings.HasPrefix(database, "./") {
|
||||
database = filepath.Join(conf.WorkingDirectory, string(database[1:]))
|
||||
}
|
||||
|
||||
dbPath := filepath.Dir(database)
|
||||
|
@ -99,11 +92,11 @@ func RegisterLogger(log string) {
|
|||
|
||||
if f, err := os.Create(logPath); err == nil {
|
||||
f.Close()
|
||||
config := make(map[string]interface{},1)
|
||||
config := make(map[string]interface{}, 1)
|
||||
|
||||
config["filename"] = logPath
|
||||
|
||||
b,_ := json.Marshal(config)
|
||||
b, _ := json.Marshal(config)
|
||||
|
||||
beego.SetLogger("file", string(b))
|
||||
}
|
||||
|
@ -133,7 +126,7 @@ func RegisterFunction() {
|
|||
|
||||
beego.AddFuncMap("cdn", func(p string) string {
|
||||
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
|
||||
}
|
||||
if strings.HasPrefix(p, "/") && strings.HasSuffix(cdn, "/") {
|
||||
|
@ -147,7 +140,7 @@ func RegisterFunction() {
|
|||
|
||||
beego.AddFuncMap("cdnjs", func(p string) string {
|
||||
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
|
||||
}
|
||||
if strings.HasPrefix(p, "/") && strings.HasSuffix(cdn, "/") {
|
||||
|
@ -160,7 +153,7 @@ func RegisterFunction() {
|
|||
})
|
||||
beego.AddFuncMap("cdncss", func(p string) string {
|
||||
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
|
||||
}
|
||||
if strings.HasPrefix(p, "/") && strings.HasSuffix(cdn, "/") {
|
||||
|
@ -172,7 +165,7 @@ func RegisterFunction() {
|
|||
return cdn + p
|
||||
})
|
||||
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
|
||||
}
|
||||
cdn := beego.AppConfig.DefaultString("cdnimg", "")
|
||||
|
@ -188,62 +181,64 @@ func RegisterFunction() {
|
|||
|
||||
func ResolveCommand(args []string) {
|
||||
flagSet := flag.NewFlagSet("MinDoc command: ", flag.ExitOnError)
|
||||
flagSet.StringVar(&ConfigurationFile, "config", "", "MinDoc configuration file.")
|
||||
flagSet.StringVar(&WorkingDirectory, "dir", "", "MinDoc working directory.")
|
||||
flagSet.StringVar(&LogFile, "log", "", "MinDoc log file path.")
|
||||
flagSet.StringVar(&conf.ConfigurationFile, "config", "", "MinDoc configuration file.")
|
||||
flagSet.StringVar(&conf.WorkingDirectory, "dir", "", "MinDoc working directory.")
|
||||
flagSet.StringVar(&conf.LogFile, "log", "", "MinDoc log file path.")
|
||||
|
||||
flagSet.Parse(args)
|
||||
|
||||
|
||||
if WorkingDirectory == "" {
|
||||
if conf.WorkingDirectory == "" {
|
||||
if p, err := filepath.Abs(os.Args[0]); err == nil {
|
||||
WorkingDirectory = filepath.Dir(p)
|
||||
conf.WorkingDirectory = filepath.Dir(p)
|
||||
}
|
||||
}
|
||||
if LogFile == "" {
|
||||
LogFile = filepath.Join(WorkingDirectory,"logs")
|
||||
if conf.LogFile == "" {
|
||||
conf.LogFile = filepath.Join(conf.WorkingDirectory, "logs")
|
||||
}
|
||||
if ConfigurationFile == "" {
|
||||
ConfigurationFile = filepath.Join(WorkingDirectory,"conf","app.conf")
|
||||
config := filepath.Join(WorkingDirectory,"conf","app.conf.example")
|
||||
if !utils.FileExists(ConfigurationFile) && utils.FileExists(config){
|
||||
utils.CopyFile(ConfigurationFile,config)
|
||||
if conf.ConfigurationFile == "" {
|
||||
conf.ConfigurationFile = filepath.Join(conf.WorkingDirectory, "conf", "app.conf")
|
||||
config := filepath.Join(conf.WorkingDirectory, "conf", "app.conf.example")
|
||||
if !utils.FileExists(conf.ConfigurationFile) && utils.FileExists(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 {
|
||||
log.Println("An error occurred:", err)
|
||||
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.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) {
|
||||
log.Fatal("Font path not exist.")
|
||||
}
|
||||
gocaptcha.ReadFonts(filepath.Join(WorkingDirectory, "static", "fonts"), ".ttf")
|
||||
gocaptcha.ReadFonts(filepath.Join(conf.WorkingDirectory, "static", "fonts"), ".ttf")
|
||||
|
||||
RegisterDataBase()
|
||||
RegisterModel()
|
||||
RegisterLogger(LogFile)
|
||||
RegisterLogger(conf.LogFile)
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
||||
if configPath ,err := filepath.Abs(conf.ConfigurationFile); err == nil {
|
||||
conf.ConfigurationFile = configPath
|
||||
}
|
||||
gocaptcha.ReadFonts("./static/fonts", ".ttf")
|
||||
gob.Register(models.Member{})
|
||||
|
||||
if p,err := filepath.Abs(os.Args[0]);err == nil{
|
||||
WorkingDirectory = filepath.Dir(p)
|
||||
if p, err := filepath.Abs(os.Args[0]); err == nil {
|
||||
conf.WorkingDirectory = filepath.Dir(p)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,10 +19,10 @@ type Daemon struct {
|
|||
func NewDaemon() *Daemon {
|
||||
|
||||
config := &service.Config{
|
||||
Name: "mindocd", //服务显示名称
|
||||
Name: "mindocd", //服务显示名称
|
||||
DisplayName: "MinDoc service", //服务名称
|
||||
Description: "A document online management program.", //服务描述
|
||||
WorkingDirectory: commands.WorkingDirectory,
|
||||
WorkingDirectory: conf.WorkingDirectory,
|
||||
Arguments: os.Args[1:],
|
||||
}
|
||||
|
||||
|
|
|
@ -16,19 +16,18 @@ package migrate
|
|||
import (
|
||||
"os"
|
||||
|
||||
"log"
|
||||
"github.com/lifei6671/mindoc/models"
|
||||
"container/list"
|
||||
"fmt"
|
||||
"github.com/astaxie/beego"
|
||||
"github.com/astaxie/beego/orm"
|
||||
"github.com/lifei6671/mindoc/models"
|
||||
"log"
|
||||
)
|
||||
|
||||
var (
|
||||
migrationList = &migrationCache{ }
|
||||
migrationList = &migrationCache{}
|
||||
)
|
||||
|
||||
|
||||
type MigrationDatabase interface {
|
||||
//获取当前的版本
|
||||
Version() int64
|
||||
|
@ -58,7 +57,7 @@ func RunMigration() {
|
|||
|
||||
if len(os.Args) >= 2 && os.Args[1] == "migrate" {
|
||||
|
||||
migrate,err := models.NewMigration().FindFirst()
|
||||
migrate, err := models.NewMigration().FindFirst()
|
||||
|
||||
if err != nil {
|
||||
//log.Fatalf("migrations table %s", err)
|
||||
|
@ -66,10 +65,10 @@ func RunMigration() {
|
|||
}
|
||||
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)
|
||||
if err != nil {
|
||||
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_database := beego.AppConfig.String("db_database")
|
||||
tables := make([]string,0)
|
||||
tables := make([]string, 0)
|
||||
|
||||
o := orm.NewOrm()
|
||||
switch db_adapter {
|
||||
case "mysql":{
|
||||
var lists []orm.Params
|
||||
case "mysql":
|
||||
{
|
||||
var lists []orm.Params
|
||||
|
||||
_,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)
|
||||
_, 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
|
||||
return tables, err
|
||||
}
|
||||
tables = append(tables,results[0]["Create Table"].(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))
|
||||
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 {
|
||||
return tables, err
|
||||
}
|
||||
tables = append(tables, results[0]["Create Table"].(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.PushBack(NewMigrationVersion03())
|
||||
}
|
||||
migrationList.items.PushBack(NewMigrationVersion03())
|
||||
}
|
||||
|
|
|
@ -2,21 +2,20 @@ package migrate
|
|||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/astaxie/beego/orm"
|
||||
"github.com/lifei6671/mindoc/models"
|
||||
"time"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type MigrationVersion03 struct {
|
||||
isValid bool
|
||||
tables []string
|
||||
|
||||
tables []string
|
||||
}
|
||||
|
||||
func NewMigrationVersion03() *MigrationVersion03 {
|
||||
return &MigrationVersion03{ isValid: false, tables: make([]string,0)}
|
||||
return &MigrationVersion03{isValid: false, tables: make([]string, 0)}
|
||||
}
|
||||
|
||||
func (m *MigrationVersion03) Version() int64 {
|
||||
|
@ -37,8 +36,7 @@ func (m *MigrationVersion03) ValidForBackupTableSchema() error {
|
|||
return errors.New("The current version failed to verify.")
|
||||
}
|
||||
var err error
|
||||
m.tables,err = ExportDatabaseTable()
|
||||
|
||||
m.tables, err = ExportDatabaseTable()
|
||||
|
||||
return err
|
||||
}
|
||||
|
@ -72,11 +70,11 @@ func (m *MigrationVersion03) MigrationNewTableData() error {
|
|||
}
|
||||
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 {
|
||||
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 {
|
||||
return err
|
||||
}
|
||||
|
@ -85,24 +83,24 @@ func (m *MigrationVersion03) MigrationNewTableData() error {
|
|||
|
||||
func (m *MigrationVersion03) AddMigrationRecord(version int64) error {
|
||||
o := orm.NewOrm()
|
||||
tables,err := ExportDatabaseTable()
|
||||
tables, err := ExportDatabaseTable()
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
return err
|
||||
}
|
||||
migration := models.NewMigration()
|
||||
migration.Version = version
|
||||
migration.Status = "update"
|
||||
migration.CreateTime = time.Now()
|
||||
migration.Name = fmt.Sprintf("update_%d",version)
|
||||
migration.Statements = strings.Join(tables,"\r\n")
|
||||
migration.Name = fmt.Sprintf("update_%d", version)
|
||||
migration.Statements = strings.Join(tables, "\r\n")
|
||||
|
||||
_, err = o.Insert(migration)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (m *MigrationVersion03) MigrationCleanup() error {
|
||||
func (m *MigrationVersion03) MigrationCleanup() error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -112,16 +110,16 @@ func (m *MigrationVersion03) RollbackMigration() error {
|
|||
return errors.New("The current version failed to verify.")
|
||||
}
|
||||
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 {
|
||||
return err
|
||||
}
|
||||
|
||||
_,err = o.Raw("DROP TABLE md_document_history").Exec()
|
||||
_, err = o.Raw("DROP TABLE md_document_history").Exec()
|
||||
if err != nil {
|
||||
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 {
|
||||
return err
|
||||
|
@ -129,11 +127,3 @@ func (m *MigrationVersion03) RollbackMigration() error {
|
|||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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}$`
|
||||
|
||||
// PageSize 默认分页条数.
|
||||
const PageSize = 15
|
||||
const PageSize = 10
|
||||
|
||||
// 用户权限
|
||||
const (
|
||||
|
@ -44,23 +44,31 @@ const (
|
|||
)
|
||||
|
||||
const (
|
||||
LoggerOperate = "operate"
|
||||
LoggerSystem = "system"
|
||||
LoggerOperate = "operate"
|
||||
LoggerSystem = "system"
|
||||
LoggerException = "exception"
|
||||
LoggerDocument = "document"
|
||||
LoggerDocument = "document"
|
||||
)
|
||||
const (
|
||||
//本地账户校验
|
||||
AuthMethodLocal = "local"
|
||||
//LDAP用户校验
|
||||
AuthMethodLDAP = "ldap"
|
||||
AuthMethodLDAP = "ldap"
|
||||
)
|
||||
|
||||
var (
|
||||
VERSION string
|
||||
BUILD_TIME string
|
||||
GO_VERSION string
|
||||
)
|
||||
|
||||
var (
|
||||
ConfigurationFile = "./conf/app.conf"
|
||||
WorkingDirectory = "./"
|
||||
LogFile = "./logs"
|
||||
BaseUrl = ""
|
||||
)
|
||||
|
||||
// app_key
|
||||
func GetAppKey() string {
|
||||
return beego.AppConfig.DefaultString("app_key", "godoc")
|
||||
|
@ -102,29 +110,30 @@ func GetUploadFileExt() []string {
|
|||
}
|
||||
return exts
|
||||
}
|
||||
|
||||
// 获取上传文件允许的最大值
|
||||
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 s,e := strconv.ParseInt(size[0:len(size) - 2], 10, 64);e == nil {
|
||||
if strings.HasSuffix(size, "MB") {
|
||||
if s, e := strconv.ParseInt(size[0:len(size)-2], 10, 64); e == nil {
|
||||
return s * 1024 * 1024
|
||||
}
|
||||
}
|
||||
if strings.HasSuffix(size,"GB") {
|
||||
if s,e := strconv.ParseInt(size[0:len(size) - 2], 10, 64);e == nil {
|
||||
if strings.HasSuffix(size, "GB") {
|
||||
if s, e := strconv.ParseInt(size[0:len(size)-2], 10, 64); e == nil {
|
||||
return s * 1024 * 1024 * 1024
|
||||
}
|
||||
}
|
||||
if strings.HasSuffix(size,"KB") {
|
||||
if s,e := strconv.ParseInt(size[0:len(size) - 2], 10, 64);e == nil {
|
||||
if strings.HasSuffix(size, "KB") {
|
||||
if s, e := strconv.ParseInt(size[0:len(size)-2], 10, 64); e == nil {
|
||||
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 0
|
||||
return 0
|
||||
}
|
||||
|
||||
//判断是否是允许商城的文件类型.
|
||||
|
|
30
conf/mail.go
30
conf/mail.go
|
@ -6,33 +6,33 @@ import (
|
|||
)
|
||||
|
||||
type SmtpConf struct {
|
||||
EnableMail bool
|
||||
MailNumber int
|
||||
EnableMail bool
|
||||
MailNumber int
|
||||
SmtpUserName string
|
||||
SmtpHost string
|
||||
SmtpHost string
|
||||
SmtpPassword string
|
||||
SmtpPort int
|
||||
SmtpPort int
|
||||
FormUserName string
|
||||
MailExpired int
|
||||
MailExpired int
|
||||
}
|
||||
|
||||
func GetMailConfig() *SmtpConf {
|
||||
user_name := beego.AppConfig.String("smtp_user_name")
|
||||
password := beego.AppConfig.String("smtp_password")
|
||||
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")
|
||||
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{
|
||||
EnableMail : strings.EqualFold(enable_mail,"true"),
|
||||
MailNumber: mail_number,
|
||||
SmtpUserName:user_name,
|
||||
SmtpHost:smtp_host,
|
||||
SmtpPassword:password,
|
||||
FormUserName:form_user_name,
|
||||
SmtpPort:smtp_port,
|
||||
EnableMail: strings.EqualFold(enable_mail, "true"),
|
||||
MailNumber: mail_number,
|
||||
SmtpUserName: user_name,
|
||||
SmtpHost: smtp_host,
|
||||
SmtpPassword: password,
|
||||
FormUserName: form_user_name,
|
||||
SmtpPort: smtp_port,
|
||||
}
|
||||
return c
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ import (
|
|||
"github.com/lifei6671/mindoc/conf"
|
||||
"github.com/lifei6671/mindoc/models"
|
||||
"github.com/lifei6671/mindoc/utils"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
// AccountController 用户登录与注册
|
||||
|
@ -32,14 +33,17 @@ func (c *AccountController) Login() {
|
|||
Time time.Time
|
||||
}
|
||||
|
||||
// 显式指定的 URL 参数优先;为了统一处理,将之更新到 Session 中
|
||||
turl := c.GetString("turl", "")
|
||||
if turl != "" {
|
||||
c.SetSession("turl", turl)
|
||||
if member, ok := c.GetSession(conf.LoginSessionName).(models.Member); ok && member.MemberId > 0 {
|
||||
u := c.GetString("url")
|
||||
if u == "" {
|
||||
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 中存在登录信息
|
||||
if cookie, ok := c.GetSecureCookie(conf.GetAppKey(), "login"); ok {
|
||||
if err := utils.Decode(cookie, &remember); err == nil {
|
||||
|
@ -81,26 +85,35 @@ func (c *AccountController) Login() {
|
|||
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", data)
|
||||
c.JsonResult(0, "ok", u)
|
||||
} else {
|
||||
logs.Error("用户登录 =>", err)
|
||||
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{} {
|
||||
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 {
|
||||
// 检查是否存在 turl 参数,如果有则重定向至 turl 处,否则进入 Home 页面
|
||||
|
@ -111,7 +124,7 @@ func (c *AccountController) LoggedIn(isPost bool) interface{} {
|
|||
return nil
|
||||
} else {
|
||||
var data struct {
|
||||
TURL string `json:"turl"`
|
||||
TURL string `json:"url"`
|
||||
}
|
||||
data.TURL = turl
|
||||
return data
|
||||
|
@ -369,7 +382,9 @@ func (c *AccountController) Logout() {
|
|||
|
||||
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)
|
||||
}
|
||||
|
||||
// 验证码
|
||||
|
|
|
@ -1,53 +1,52 @@
|
|||
package controllers
|
||||
|
||||
import (
|
||||
|
||||
"bytes"
|
||||
|
||||
"github.com/lifei6671/mindoc/models"
|
||||
"github.com/lifei6671/mindoc/conf"
|
||||
"github.com/astaxie/beego"
|
||||
"strings"
|
||||
"encoding/json"
|
||||
"github.com/astaxie/beego"
|
||||
"github.com/lifei6671/mindoc/conf"
|
||||
"github.com/lifei6671/mindoc/models"
|
||||
"io"
|
||||
"strings"
|
||||
)
|
||||
|
||||
|
||||
type BaseController struct {
|
||||
beego.Controller
|
||||
Member *models.Member
|
||||
Option map[string]string
|
||||
EnableAnonymous bool
|
||||
Member *models.Member
|
||||
Option map[string]string
|
||||
EnableAnonymous bool
|
||||
EnableDocumentHistory bool
|
||||
}
|
||||
|
||||
// Prepare 预处理.
|
||||
func (c *BaseController) Prepare (){
|
||||
func (c *BaseController) Prepare() {
|
||||
c.Data["SiteName"] = "MinDoc"
|
||||
c.Data["Member"] = models.Member{}
|
||||
c.EnableAnonymous = 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.Data["Member"] = c.Member
|
||||
}else{
|
||||
} else {
|
||||
//c.Member = models.NewMember()
|
||||
//c.Member.Find(1)
|
||||
//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 {
|
||||
c.Option = make(map[string]string,len(options))
|
||||
for _,item := range options {
|
||||
if options, err := models.NewOption().All(); err == nil {
|
||||
c.Option = make(map[string]string, len(options))
|
||||
for _, item := range options {
|
||||
c.Data[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
|
||||
}
|
||||
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
|
||||
}
|
||||
}
|
||||
|
@ -68,13 +67,13 @@ func (c *BaseController) SetMember(member models.Member) {
|
|||
}
|
||||
|
||||
// JsonResult 响应 json 结果
|
||||
func (c *BaseController) JsonResult(errCode int,errMsg string,data ...interface{}){
|
||||
jsonData := make(map[string]interface{},3)
|
||||
func (c *BaseController) JsonResult(errCode int, errMsg string, data ...interface{}) {
|
||||
jsonData := make(map[string]interface{}, 3)
|
||||
|
||||
jsonData["errcode"] = errCode
|
||||
jsonData["message"] = errMsg
|
||||
|
||||
if len(data) > 0 && data[0] != nil{
|
||||
if len(data) > 0 && data[0] != nil {
|
||||
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")
|
||||
|
||||
io.WriteString(c.Ctx.ResponseWriter,string(returnJSON))
|
||||
io.WriteString(c.Ctx.ResponseWriter, string(returnJSON))
|
||||
|
||||
c.StopRun()
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
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 {
|
||||
return "",err
|
||||
if err := beego.ExecuteViewPathTemplate(&buf, tplName, viewPath, data); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return buf.String(),nil
|
||||
return buf.String(), nil
|
||||
}
|
||||
|
||||
func (c *BaseController) BaseUrl() string {
|
||||
baseUrl := beego.AppConfig.DefaultString("baseurl","")
|
||||
baseUrl := beego.AppConfig.DefaultString("baseurl", "")
|
||||
if baseUrl != "" {
|
||||
if strings.HasSuffix(baseUrl,"/"){
|
||||
baseUrl = strings.TrimSuffix(baseUrl,"/")
|
||||
if strings.HasSuffix(baseUrl, "/") {
|
||||
baseUrl = strings.TrimSuffix(baseUrl, "/")
|
||||
}
|
||||
}else{
|
||||
} else {
|
||||
baseUrl = c.Ctx.Input.Scheme() + "://" + c.Ctx.Request.Host
|
||||
}
|
||||
return baseUrl
|
||||
}
|
||||
|
||||
//显示错误信息页面.
|
||||
func (c *BaseController) ShowErrorPage(errCode int,errMsg string) {
|
||||
func (c *BaseController) ShowErrorPage(errCode int, errMsg string) {
|
||||
c.TplName = "errors/error.tpl"
|
||||
c.Data["ErrorMessage"] = errMsg
|
||||
c.Data["ErrorCode"] = errCode
|
||||
c.StopRun()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,25 +1,24 @@
|
|||
package controllers
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"time"
|
||||
"encoding/json"
|
||||
"html/template"
|
||||
"errors"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"html/template"
|
||||
"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/orm"
|
||||
"github.com/astaxie/beego/logs"
|
||||
"github.com/astaxie/beego/orm"
|
||||
"github.com/lifei6671/mindoc/conf"
|
||||
"github.com/lifei6671/mindoc/graphics"
|
||||
"github.com/lifei6671/mindoc/commands"
|
||||
"github.com/lifei6671/mindoc/models"
|
||||
"github.com/lifei6671/mindoc/utils"
|
||||
)
|
||||
|
||||
type BookController struct {
|
||||
|
@ -32,10 +31,10 @@ func (c *BookController) Index() {
|
|||
|
||||
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 {
|
||||
logs.Error("BookController.Index => ",err)
|
||||
logs.Error("BookController.Index => ", err)
|
||||
c.Abort("500")
|
||||
}
|
||||
|
||||
|
@ -43,14 +42,14 @@ func (c *BookController) Index() {
|
|||
html := utils.GetPagerHtml(c.Ctx.Request.RequestURI, pageIndex, conf.PageSize, totalCount)
|
||||
|
||||
c.Data["PageHtml"] = html
|
||||
}else {
|
||||
} else {
|
||||
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("[]")
|
||||
}else{
|
||||
} else {
|
||||
c.Data["Result"] = template.JS(string(b))
|
||||
}
|
||||
}
|
||||
|
@ -62,11 +61,11 @@ func (c *BookController) Dashboard() {
|
|||
|
||||
key := c.Ctx.Input.Param(":key")
|
||||
|
||||
if key == ""{
|
||||
if key == "" {
|
||||
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 == models.ErrPermissionDenied {
|
||||
c.Abort("403")
|
||||
|
@ -79,17 +78,17 @@ func (c *BookController) Dashboard() {
|
|||
}
|
||||
|
||||
// Setting 项目设置 .
|
||||
func (c *BookController) Setting() {
|
||||
func (c *BookController) Setting() {
|
||||
c.Prepare()
|
||||
c.TplName = "book/setting.tpl"
|
||||
|
||||
key := c.Ctx.Input.Param(":key")
|
||||
|
||||
if key == ""{
|
||||
if key == "" {
|
||||
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 == orm.ErrNoRows {
|
||||
c.Abort("404")
|
||||
|
@ -104,225 +103,224 @@ func (c *BookController) Setting() {
|
|||
c.Abort("403")
|
||||
}
|
||||
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
|
||||
|
||||
}
|
||||
|
||||
//保存项目信息
|
||||
func (c *BookController) SaveBook() {
|
||||
bookResult,err := c.IsPermission()
|
||||
func (c *BookController) SaveBook() {
|
||||
bookResult, err := c.IsPermission()
|
||||
|
||||
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 {
|
||||
logs.Error("SaveBook => ",err)
|
||||
c.JsonResult(6002,err.Error())
|
||||
logs.Error("SaveBook => ", err)
|
||||
c.JsonResult(6002, err.Error())
|
||||
}
|
||||
|
||||
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")
|
||||
tag := strings.TrimSpace(c.GetString("label"))
|
||||
editor := strings.TrimSpace(c.GetString("editor"))
|
||||
auto_release := strings.TrimSpace(c.GetString("auto_release")) == "on"
|
||||
|
||||
if strings.Count(description,"") > 500 {
|
||||
c.JsonResult(6004,"项目描述不能大于500字")
|
||||
if strings.Count(description, "") > 500 {
|
||||
c.JsonResult(6004, "项目描述不能大于500字")
|
||||
}
|
||||
if comment_status != "open" && comment_status != "closed" && comment_status != "group_only" && comment_status != "registered_only" {
|
||||
comment_status = "closed"
|
||||
}
|
||||
if tag != ""{
|
||||
tags := strings.Split(tag,",")
|
||||
if tag != "" {
|
||||
tags := strings.Split(tag, ",")
|
||||
if len(tags) > 10 {
|
||||
c.JsonResult(6005,"最多允许添加10个标签")
|
||||
c.JsonResult(6005, "最多允许添加10个标签")
|
||||
}
|
||||
}
|
||||
if editor != "markdown" && editor != "html" {
|
||||
editor = "markdown"
|
||||
}
|
||||
|
||||
book.BookName = book_name
|
||||
book.Description = description
|
||||
book.CommentStatus = comment_status
|
||||
book.Label = tag
|
||||
book.Editor = editor
|
||||
book.BookName = book_name
|
||||
book.Description = description
|
||||
book.CommentStatus = comment_status
|
||||
book.Label = tag
|
||||
book.Editor = editor
|
||||
if auto_release {
|
||||
book.AutoRelease = 1
|
||||
}else{
|
||||
} else {
|
||||
book.AutoRelease = 0
|
||||
}
|
||||
|
||||
|
||||
if err := book.Update();err != nil {
|
||||
c.JsonResult(6006,"保存失败")
|
||||
if err := book.Update(); err != nil {
|
||||
c.JsonResult(6006, "保存失败")
|
||||
}
|
||||
bookResult.BookName = book_name
|
||||
bookResult.Description = description
|
||||
bookResult.CommentStatus = comment_status
|
||||
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")
|
||||
|
||||
if status != "open" && status != "close" {
|
||||
c.JsonResult(6003,"参数错误")
|
||||
c.JsonResult(6003, "参数错误")
|
||||
}
|
||||
state := 0
|
||||
if status == "open" {
|
||||
state = 0
|
||||
}else{
|
||||
} else {
|
||||
state = 1
|
||||
}
|
||||
|
||||
bookResult,err := c.IsPermission()
|
||||
bookResult, err := c.IsPermission()
|
||||
|
||||
if err != nil {
|
||||
c.JsonResult(6001,err.Error())
|
||||
c.JsonResult(6001, err.Error())
|
||||
}
|
||||
//只有创始人才能变更私有状态
|
||||
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 {
|
||||
c.JsonResult(6005,"项目不存在")
|
||||
c.JsonResult(6005, "项目不存在")
|
||||
}
|
||||
book.PrivatelyOwned = state
|
||||
|
||||
err = book.Update()
|
||||
|
||||
if err != nil {
|
||||
logs.Error("PrivatelyOwned => ",err)
|
||||
c.JsonResult(6004,"保存失败")
|
||||
logs.Error("PrivatelyOwned => ", err)
|
||||
c.JsonResult(6004, "保存失败")
|
||||
}
|
||||
c.JsonResult(0,"ok")
|
||||
c.JsonResult(0, "ok")
|
||||
}
|
||||
|
||||
// Transfer 转让项目.
|
||||
func (c *BookController) Transfer() {
|
||||
func (c *BookController) Transfer() {
|
||||
c.Prepare()
|
||||
account := c.GetString("account")
|
||||
|
||||
if account == "" {
|
||||
c.JsonResult(6004,"接受者账号不能为空")
|
||||
c.JsonResult(6004, "接受者账号不能为空")
|
||||
}
|
||||
member,err := models.NewMember().FindByAccount(account)
|
||||
member, err := models.NewMember().FindByAccount(account)
|
||||
|
||||
if err != nil {
|
||||
logs.Error("FindByAccount => ",err)
|
||||
c.JsonResult(6005,"接受用户不存在")
|
||||
logs.Error("FindByAccount => ", err)
|
||||
c.JsonResult(6005, "接受用户不存在")
|
||||
}
|
||||
if member.Status != 0 {
|
||||
c.JsonResult(6006,"接受用户已被禁用")
|
||||
c.JsonResult(6006, "接受用户已被禁用")
|
||||
}
|
||||
if member.MemberId == c.Member.MemberId {
|
||||
c.JsonResult(6007,"不能转让给自己")
|
||||
c.JsonResult(6007, "不能转让给自己")
|
||||
}
|
||||
bookResult,err := c.IsPermission()
|
||||
bookResult, err := c.IsPermission()
|
||||
|
||||
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 {
|
||||
logs.Error("Transfer => ",err)
|
||||
c.JsonResult(6008,err.Error())
|
||||
logs.Error("Transfer => ", err)
|
||||
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 {
|
||||
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 {
|
||||
logs.Error("SaveBook => ",err)
|
||||
c.JsonResult(6002,err.Error())
|
||||
logs.Error("SaveBook => ", err)
|
||||
c.JsonResult(6002, err.Error())
|
||||
}
|
||||
|
||||
file,moreFile,err := c.GetFile("image-file")
|
||||
file, moreFile, err := c.GetFile("image-file")
|
||||
defer file.Close()
|
||||
|
||||
if err != nil {
|
||||
logs.Error("",err.Error())
|
||||
c.JsonResult(500,"读取文件异常")
|
||||
logs.Error("", err.Error())
|
||||
c.JsonResult(500, "读取文件异常")
|
||||
}
|
||||
|
||||
ext := filepath.Ext(moreFile.Filename)
|
||||
|
||||
if !strings.EqualFold(ext,".png") && !strings.EqualFold(ext,".jpg") && !strings.EqualFold(ext,".gif") && !strings.EqualFold(ext,".jpeg") {
|
||||
c.JsonResult(500,"不支持的图片格式")
|
||||
if !strings.EqualFold(ext, ".png") && !strings.EqualFold(ext, ".jpg") && !strings.EqualFold(ext, ".gif") && !strings.EqualFold(ext, ".jpeg") {
|
||||
c.JsonResult(500, "不支持的图片格式")
|
||||
}
|
||||
|
||||
|
||||
x1 ,_ := strconv.ParseFloat(c.GetString("x"),10)
|
||||
y1 ,_ := strconv.ParseFloat(c.GetString("y"),10)
|
||||
w1 ,_ := strconv.ParseFloat(c.GetString("width"),10)
|
||||
h1 ,_ := strconv.ParseFloat(c.GetString("height"),10)
|
||||
x1, _ := strconv.ParseFloat(c.GetString("x"), 10)
|
||||
y1, _ := strconv.ParseFloat(c.GetString("y"), 10)
|
||||
w1, _ := strconv.ParseFloat(c.GetString("width"), 10)
|
||||
h1, _ := strconv.ParseFloat(c.GetString("height"), 10)
|
||||
|
||||
x := int(x1)
|
||||
y := int(y1)
|
||||
width := int(w1)
|
||||
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)
|
||||
|
||||
os.MkdirAll(path, os.ModePerm)
|
||||
|
||||
err = c.SaveToFile("image-file",filePath)
|
||||
err = c.SaveToFile("image-file", filePath)
|
||||
|
||||
if err != nil {
|
||||
logs.Error("",err)
|
||||
c.JsonResult(500,"图片保存失败")
|
||||
logs.Error("", err)
|
||||
c.JsonResult(500, "图片保存失败")
|
||||
}
|
||||
defer func(filePath string) {
|
||||
os.Remove(filePath)
|
||||
}(filePath)
|
||||
|
||||
//剪切图片
|
||||
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)
|
||||
subImg, err := graphics.ImageCopyFromFile(filePath, x, y, width, height)
|
||||
|
||||
if err != nil {
|
||||
logs.Error("ImageResizeSaveFile => ",err.Error())
|
||||
c.JsonResult(500,"保存图片失败")
|
||||
logs.Error("graphics.ImageCopyFromFile => ", err)
|
||||
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:])
|
||||
}
|
||||
|
||||
|
@ -330,15 +328,15 @@ func (c *BookController) UploadCover() {
|
|||
|
||||
book.Cover = url
|
||||
|
||||
if err := book.Update() ; err != nil {
|
||||
c.JsonResult(6001,"保存图片失败")
|
||||
if err := book.Update(); err != nil {
|
||||
c.JsonResult(6001, "保存图片失败")
|
||||
}
|
||||
//如果原封面不是默认封面则删除
|
||||
if old_cover != conf.GetDefaultCover() {
|
||||
os.Remove("." + old_cover)
|
||||
}
|
||||
|
||||
c.JsonResult(0,"ok",url)
|
||||
c.JsonResult(0, "ok", url)
|
||||
}
|
||||
|
||||
// Users 用户列表.
|
||||
|
@ -347,13 +345,13 @@ func (c *BookController) Users() {
|
|||
c.TplName = "book/users.tpl"
|
||||
|
||||
key := c.Ctx.Input.Param(":key")
|
||||
pageIndex,_ := c.GetInt("page",1)
|
||||
pageIndex, _ := c.GetInt("page", 1)
|
||||
|
||||
if key == ""{
|
||||
if key == "" {
|
||||
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 == models.ErrPermissionDenied {
|
||||
c.Abort("403")
|
||||
|
@ -363,20 +361,20 @@ func (c *BookController) Users() {
|
|||
|
||||
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 {
|
||||
html := utils.GetPagerHtml(c.Ctx.Request.RequestURI, pageIndex, 10, totalCount)
|
||||
|
||||
c.Data["PageHtml"] = html
|
||||
}else{
|
||||
} else {
|
||||
c.Data["PageHtml"] = ""
|
||||
}
|
||||
b,err := json.Marshal(members)
|
||||
b, err := json.Marshal(members)
|
||||
|
||||
if err != nil {
|
||||
c.Data["Result"] = template.JS("[]")
|
||||
}else{
|
||||
} else {
|
||||
c.Data["Result"] = template.JS(string(b))
|
||||
}
|
||||
}
|
||||
|
@ -385,28 +383,28 @@ func (c *BookController) Users() {
|
|||
func (c *BookController) Create() {
|
||||
|
||||
if c.Ctx.Input.IsPost() {
|
||||
book_name := strings.TrimSpace(c.GetString("book_name",""))
|
||||
identify := strings.TrimSpace(c.GetString("identify",""))
|
||||
description := strings.TrimSpace(c.GetString("description",""))
|
||||
privately_owned,_ := strconv.Atoi(c.GetString("privately_owned"))
|
||||
book_name := strings.TrimSpace(c.GetString("book_name", ""))
|
||||
identify := strings.TrimSpace(c.GetString("identify", ""))
|
||||
description := strings.TrimSpace(c.GetString("description", ""))
|
||||
privately_owned, _ := strconv.Atoi(c.GetString("privately_owned"))
|
||||
comment_status := c.GetString("comment_status")
|
||||
|
||||
if book_name == "" {
|
||||
c.JsonResult(6001,"项目名称不能为空")
|
||||
c.JsonResult(6001, "项目名称不能为空")
|
||||
}
|
||||
if identify == "" {
|
||||
c.JsonResult(6002,"项目标识不能为空")
|
||||
c.JsonResult(6002, "项目标识不能为空")
|
||||
}
|
||||
if ok,err := regexp.MatchString(`^[a-z]+[a-zA-Z0-9_\-]*$`,identify); !ok || err != nil {
|
||||
c.JsonResult(6003,"项目标识只能包含小写字母、数字,以及“-”和“_”符号,并且只能小写字母开头")
|
||||
if ok, err := regexp.MatchString(`^[a-z]+[a-zA-Z0-9_\-]*$`, identify); !ok || err != nil {
|
||||
c.JsonResult(6003, "项目标识只能包含小写字母、数字,以及“-”和“_”符号,并且只能小写字母开头")
|
||||
}
|
||||
if strings.Count(identify,"") > 50 {
|
||||
c.JsonResult(6004,"文档标识不能超过50字")
|
||||
if strings.Count(identify, "") > 50 {
|
||||
c.JsonResult(6004, "文档标识不能超过50字")
|
||||
}
|
||||
if strings.Count(description,"") > 500 {
|
||||
c.JsonResult(6004,"项目描述不能大于500字")
|
||||
if strings.Count(description, "") > 500 {
|
||||
c.JsonResult(6004, "项目描述不能大于500字")
|
||||
}
|
||||
if privately_owned !=0 && privately_owned != 1 {
|
||||
if privately_owned != 0 && privately_owned != 1 {
|
||||
privately_owned = 1
|
||||
}
|
||||
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()
|
||||
|
||||
if books,_ := book.FindByField("identify",identify); len(books) > 0 {
|
||||
c.JsonResult(6006,"项目标识已存在")
|
||||
if books, _ := book.FindByField("identify", identify); len(books) > 0 {
|
||||
c.JsonResult(6006, "项目标识已存在")
|
||||
}
|
||||
|
||||
book.BookName = book_name
|
||||
book.BookName = book_name
|
||||
book.Description = description
|
||||
book.CommentCount = 0
|
||||
book.PrivatelyOwned = privately_owned
|
||||
book.CommentStatus = comment_status
|
||||
book.Identify = identify
|
||||
book.DocCount = 0
|
||||
book.MemberId = c.Member.MemberId
|
||||
book.Identify = identify
|
||||
book.DocCount = 0
|
||||
book.MemberId = c.Member.MemberId
|
||||
book.CommentCount = 0
|
||||
book.Version = time.Now().Unix()
|
||||
book.Cover = conf.GetDefaultCover()
|
||||
book.Editor = "markdown"
|
||||
book.Theme = "default"
|
||||
book.Version = time.Now().Unix()
|
||||
book.Cover = conf.GetDefaultCover()
|
||||
book.Editor = "markdown"
|
||||
book.Theme = "default"
|
||||
|
||||
err := book.Insert()
|
||||
|
||||
if err != nil {
|
||||
logs.Error("Insert => ",err)
|
||||
c.JsonResult(6005,"保存项目失败")
|
||||
logs.Error("Insert => ", err)
|
||||
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 {
|
||||
beego.Error(err)
|
||||
}
|
||||
|
||||
c.JsonResult(0,"ok",bookResult)
|
||||
c.JsonResult(0, "ok", bookResult)
|
||||
}
|
||||
c.JsonResult(6001,"error")
|
||||
c.JsonResult(6001, "error")
|
||||
}
|
||||
|
||||
// CreateToken 创建访问来令牌.
|
||||
|
@ -455,22 +453,22 @@ func (c *BookController) CreateToken() {
|
|||
|
||||
action := c.GetString("action")
|
||||
|
||||
bookResult ,err := c.IsPermission()
|
||||
bookResult, err := c.IsPermission()
|
||||
|
||||
if err != nil {
|
||||
if err == models.ErrPermissionDenied {
|
||||
c.JsonResult(403,"权限不足")
|
||||
c.JsonResult(403, "权限不足")
|
||||
}
|
||||
if err == orm.ErrNoRows {
|
||||
c.JsonResult(404,"项目不存在")
|
||||
c.JsonResult(404, "项目不存在")
|
||||
}
|
||||
logs.Error("生成阅读令牌失败 =>",err)
|
||||
c.JsonResult(6002,err.Error())
|
||||
logs.Error("生成阅读令牌失败 =>", err)
|
||||
c.JsonResult(6002, err.Error())
|
||||
}
|
||||
book := models.NewBook()
|
||||
|
||||
if _,err := book.Find(bookResult.BookId);err != nil {
|
||||
c.JsonResult(6001,"项目不存在")
|
||||
if _, err := book.Find(bookResult.BookId); err != nil {
|
||||
c.JsonResult(6001, "项目不存在")
|
||||
}
|
||||
if action == "create" {
|
||||
if bookResult.PrivatelyOwned == 0 {
|
||||
|
@ -482,14 +480,14 @@ func (c *BookController) CreateToken() {
|
|||
logs.Error("生成阅读令牌失败 => ", err)
|
||||
c.JsonResult(6003, "生成阅读令牌失败")
|
||||
}
|
||||
c.JsonResult(0, "ok", c.BaseUrl() + beego.URLFor("DocumentController.Index",":key",book.Identify,"token",book.PrivateToken))
|
||||
}else{
|
||||
c.JsonResult(0, "ok", c.BaseUrl()+beego.URLFor("DocumentController.Index", ":key", book.Identify, "token", book.PrivateToken))
|
||||
} else {
|
||||
book.PrivateToken = ""
|
||||
if err := book.Update();err != nil {
|
||||
logs.Error("CreateToken => ",err)
|
||||
c.JsonResult(6004,"删除令牌失败")
|
||||
if err := book.Update(); err != nil {
|
||||
logs.Error("CreateToken => ", err)
|
||||
c.JsonResult(6004, "删除令牌失败")
|
||||
}
|
||||
c.JsonResult(0,"ok","")
|
||||
c.JsonResult(0, "ok", "")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -497,25 +495,25 @@ func (c *BookController) CreateToken() {
|
|||
func (c *BookController) Delete() {
|
||||
c.Prepare()
|
||||
|
||||
bookResult ,err := c.IsPermission()
|
||||
bookResult, err := c.IsPermission()
|
||||
|
||||
if err != nil {
|
||||
c.JsonResult(6001,err.Error())
|
||||
c.JsonResult(6001, err.Error())
|
||||
}
|
||||
|
||||
if bookResult.RoleId != conf.BookFounder {
|
||||
c.JsonResult(6002,"只有创始人才能删除项目")
|
||||
c.JsonResult(6002, "只有创始人才能删除项目")
|
||||
}
|
||||
err = models.NewBook().ThoroughDeleteBook(bookResult.BookId)
|
||||
|
||||
if err == orm.ErrNoRows {
|
||||
c.JsonResult(6002,"项目不存在")
|
||||
c.JsonResult(6002, "项目不存在")
|
||||
}
|
||||
if err != nil {
|
||||
logs.Error("删除项目 => ",err)
|
||||
c.JsonResult(6003,"删除失败")
|
||||
logs.Error("删除项目 => ", err)
|
||||
c.JsonResult(6003, "删除失败")
|
||||
}
|
||||
c.JsonResult(0,"ok")
|
||||
c.JsonResult(0, "ok")
|
||||
}
|
||||
|
||||
//发布项目.
|
||||
|
@ -524,15 +522,15 @@ func (c *BookController) Release() {
|
|||
|
||||
identify := c.GetString("identify")
|
||||
|
||||
book_id := 0
|
||||
bookId := 0
|
||||
|
||||
if c.Member.IsAdministrator() {
|
||||
book,err := models.NewBook().FindByFieldFirst("identify",identify)
|
||||
book, err := models.NewBook().FindByFieldFirst("identify", identify)
|
||||
if err != nil {
|
||||
|
||||
}
|
||||
book_id = book.BookId
|
||||
}else {
|
||||
bookId = book.BookId
|
||||
} else {
|
||||
book, err := models.NewBookResult().FindByIdentify(identify, c.Member.MemberId)
|
||||
|
||||
if err != nil {
|
||||
|
@ -548,15 +546,18 @@ func (c *BookController) Release() {
|
|||
if book.RoleId != conf.BookAdmin && book.RoleId != conf.BookFounder && book.RoleId != conf.BookEditor {
|
||||
c.JsonResult(6003, "权限不足")
|
||||
}
|
||||
book_id = book.BookId
|
||||
bookId = book.BookId
|
||||
}
|
||||
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)
|
||||
|
||||
c.JsonResult(0,"发布任务已推送到任务队列,稍后将在后台执行。")
|
||||
c.JsonResult(0, "发布任务已推送到任务队列,稍后将在后台执行。")
|
||||
}
|
||||
|
||||
//文档排序.
|
||||
|
@ -570,94 +571,91 @@ func (c *BookController) SaveSort() {
|
|||
|
||||
book_id := 0
|
||||
if c.Member.IsAdministrator() {
|
||||
book,err := models.NewBook().FindByFieldFirst("identify",identify)
|
||||
book, err := models.NewBook().FindByFieldFirst("identify", identify)
|
||||
if err != nil {
|
||||
|
||||
}
|
||||
book_id = book.BookId
|
||||
}else{
|
||||
bookResult,err := models.NewBookResult().FindByIdentify(identify,c.Member.MemberId)
|
||||
} else {
|
||||
bookResult, err := models.NewBookResult().FindByIdentify(identify, c.Member.MemberId)
|
||||
if err != nil {
|
||||
beego.Error("DocumentController.Edit => ",err)
|
||||
beego.Error("DocumentController.Edit => ", err)
|
||||
|
||||
c.Abort("403")
|
||||
}
|
||||
if bookResult.RoleId == conf.BookObserver {
|
||||
c.JsonResult(6002,"项目不存在或权限不足")
|
||||
c.JsonResult(6002, "项目不存在或权限不足")
|
||||
}
|
||||
book_id = bookResult.BookId
|
||||
}
|
||||
|
||||
|
||||
content := c.Ctx.Input.RequestBody
|
||||
|
||||
var docs []map[string]interface{}
|
||||
|
||||
err := json.Unmarshal(content,&docs)
|
||||
err := json.Unmarshal(content, &docs)
|
||||
|
||||
if err != nil {
|
||||
beego.Error(err)
|
||||
c.JsonResult(6003,"数据错误")
|
||||
c.JsonResult(6003, "数据错误")
|
||||
}
|
||||
|
||||
for _,item := range docs {
|
||||
if doc_id,ok := item["id"].(float64);ok {
|
||||
doc,err := models.NewDocument().Find(int(doc_id));
|
||||
for _, item := range docs {
|
||||
if doc_id, ok := item["id"].(float64); ok {
|
||||
doc, err := models.NewDocument().Find(int(doc_id))
|
||||
if err != nil {
|
||||
beego.Error(err)
|
||||
continue;
|
||||
}
|
||||
if doc.BookId != book_id {
|
||||
logs.Info("%s","权限错误")
|
||||
continue;
|
||||
}
|
||||
sort,ok := item["sort"].(float64);
|
||||
if !ok {
|
||||
beego.Info("排序数字转换失败 => ",item)
|
||||
continue
|
||||
}
|
||||
parent_id,ok := item["parent"].(float64)
|
||||
if doc.BookId != book_id {
|
||||
logs.Info("%s", "权限错误")
|
||||
continue
|
||||
}
|
||||
sort, ok := item["sort"].(float64)
|
||||
if !ok {
|
||||
beego.Info("父分类转换失败 => ",item)
|
||||
beego.Info("排序数字转换失败 => ", item)
|
||||
continue
|
||||
}
|
||||
parent_id, ok := item["parent"].(float64)
|
||||
if !ok {
|
||||
beego.Info("父分类转换失败 => ", item)
|
||||
continue
|
||||
}
|
||||
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
|
||||
}
|
||||
}
|
||||
doc.OrderSort = int(sort)
|
||||
doc.ParentId = int(parent_id)
|
||||
if err := doc.InsertOrUpdate(); err != nil {
|
||||
fmt.Printf("%s",err.Error())
|
||||
fmt.Printf("%s", err.Error())
|
||||
beego.Error(err)
|
||||
}
|
||||
}else{
|
||||
fmt.Printf("文档ID转换失败 => %+v",item)
|
||||
} else {
|
||||
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")
|
||||
|
||||
book ,err := models.NewBookResult().FindByIdentify(identify,c.Member.MemberId)
|
||||
book, err := models.NewBookResult().FindByIdentify(identify, c.Member.MemberId)
|
||||
|
||||
if err != nil {
|
||||
if err == models.ErrPermissionDenied {
|
||||
return book,errors.New("权限不足")
|
||||
return book, errors.New("权限不足")
|
||||
}
|
||||
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 {
|
||||
return book,errors.New("权限不足")
|
||||
return book, errors.New("权限不足")
|
||||
}
|
||||
return book,nil
|
||||
return book, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -3,10 +3,10 @@ package controllers
|
|||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/lifei6671/mindoc/models"
|
||||
"github.com/astaxie/beego/orm"
|
||||
"github.com/astaxie/beego/logs"
|
||||
"github.com/astaxie/beego/orm"
|
||||
"github.com/lifei6671/mindoc/conf"
|
||||
"github.com/lifei6671/mindoc/models"
|
||||
)
|
||||
|
||||
type BookMemberController struct {
|
||||
|
@ -14,31 +14,31 @@ type BookMemberController struct {
|
|||
}
|
||||
|
||||
// AddMember 参加参与用户.
|
||||
func (c *BookMemberController) AddMember() {
|
||||
func (c *BookMemberController) AddMember() {
|
||||
identify := c.GetString("identify")
|
||||
account := c.GetString("account")
|
||||
role_id,_ := c.GetInt("role_id",3)
|
||||
role_id, _ := c.GetInt("role_id", 3)
|
||||
|
||||
if identify == "" || account == ""{
|
||||
c.JsonResult(6001,"参数错误")
|
||||
if identify == "" || account == "" {
|
||||
c.JsonResult(6001, "参数错误")
|
||||
}
|
||||
book ,err := c.IsPermission()
|
||||
book, err := c.IsPermission()
|
||||
|
||||
if err != nil {
|
||||
c.JsonResult(6001,err.Error())
|
||||
c.JsonResult(6001, err.Error())
|
||||
}
|
||||
|
||||
member := models.NewMember()
|
||||
|
||||
if _,err := member.FindByAccount(account) ; err != nil {
|
||||
c.JsonResult(404,"用户不存在")
|
||||
if _, err := member.FindByAccount(account); err != nil {
|
||||
c.JsonResult(404, "用户不存在")
|
||||
}
|
||||
if member.Status == 1 {
|
||||
c.JsonResult(6003,"用户已被禁用")
|
||||
c.JsonResult(6003, "用户已被禁用")
|
||||
}
|
||||
|
||||
if _,err := models.NewRelationship().FindForRoleId(book.BookId,member.MemberId);err == nil {
|
||||
c.JsonResult(6003,"用户已存在该项目中")
|
||||
if _, err := models.NewRelationship().FindForRoleId(book.BookId, member.MemberId); err == nil {
|
||||
c.JsonResult(6003, "用户已存在该项目中")
|
||||
}
|
||||
|
||||
relationship := models.NewRelationship()
|
||||
|
@ -53,53 +53,52 @@ func (c *BookMemberController) AddMember() {
|
|||
memberRelationshipResult.BookId = book.BookId
|
||||
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() {
|
||||
identify := c.GetString("identify")
|
||||
member_id,_ := c.GetInt("member_id",0)
|
||||
role,_ := c.GetInt("role_id",0)
|
||||
member_id, _ := c.GetInt("member_id", 0)
|
||||
role, _ := c.GetInt("role_id", 0)
|
||||
|
||||
if identify == "" || member_id <=0 {
|
||||
c.JsonResult(6001,"参数错误")
|
||||
if identify == "" || member_id <= 0 {
|
||||
c.JsonResult(6001, "参数错误")
|
||||
}
|
||||
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 == models.ErrPermissionDenied {
|
||||
c.JsonResult(403,"权限不足")
|
||||
c.JsonResult(403, "权限不足")
|
||||
}
|
||||
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 {
|
||||
c.JsonResult(403,"权限不足")
|
||||
c.JsonResult(403, "权限不足")
|
||||
}
|
||||
|
||||
member := models.NewMember()
|
||||
|
||||
if _,err := member.Find(member_id); err != nil {
|
||||
c.JsonResult(6003,"用户不存在")
|
||||
if _, err := member.Find(member_id); err != nil {
|
||||
c.JsonResult(6003, "用户不存在")
|
||||
}
|
||||
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 {
|
||||
logs.Error("变更用户在项目中的权限 => ",err)
|
||||
c.JsonResult(6005,err.Error())
|
||||
logs.Error("变更用户在项目中的权限 => ", err)
|
||||
c.JsonResult(6005, err.Error())
|
||||
}
|
||||
|
||||
memberRelationshipResult := models.NewMemberRelationshipResult().FromMember(member)
|
||||
|
@ -108,58 +107,58 @@ func (c *BookMemberController) ChangeRole() {
|
|||
memberRelationshipResult.BookId = book.BookId
|
||||
memberRelationshipResult.ResolveRoleName()
|
||||
|
||||
c.JsonResult(0,"ok",memberRelationshipResult)
|
||||
c.JsonResult(0, "ok", memberRelationshipResult)
|
||||
}
|
||||
|
||||
// 删除参与者.
|
||||
func (c *BookMemberController) RemoveMember() {
|
||||
func (c *BookMemberController) RemoveMember() {
|
||||
identify := c.GetString("identify")
|
||||
member_id,_ := c.GetInt("member_id",0)
|
||||
member_id, _ := c.GetInt("member_id", 0)
|
||||
|
||||
if identify == "" || member_id <=0 {
|
||||
c.JsonResult(6001,"参数错误")
|
||||
if identify == "" || member_id <= 0 {
|
||||
c.JsonResult(6001, "参数错误")
|
||||
}
|
||||
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 == models.ErrPermissionDenied {
|
||||
c.JsonResult(403,"权限不足")
|
||||
c.JsonResult(403, "权限不足")
|
||||
}
|
||||
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 {
|
||||
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 {
|
||||
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")
|
||||
book ,err := models.NewBookResult().FindByIdentify(identify,c.Member.MemberId)
|
||||
book, err := models.NewBookResult().FindByIdentify(identify, c.Member.MemberId)
|
||||
|
||||
if err != nil {
|
||||
if err == models.ErrPermissionDenied {
|
||||
return book,errors.New("权限不足")
|
||||
return book, errors.New("权限不足")
|
||||
}
|
||||
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 {
|
||||
return book,errors.New("权限不足")
|
||||
return book, errors.New("权限不足")
|
||||
}
|
||||
return book,nil
|
||||
}
|
||||
return book, nil
|
||||
}
|
||||
|
|
|
@ -4,16 +4,16 @@ type CommentController struct {
|
|||
BaseController
|
||||
}
|
||||
|
||||
func (c *CommentController) Lists() {
|
||||
|
||||
func (c *CommentController) Lists() {
|
||||
|
||||
}
|
||||
|
||||
func (c *CommentController) Create() {
|
||||
|
||||
c.JsonResult(0,"ok")
|
||||
c.JsonResult(0, "ok")
|
||||
}
|
||||
|
||||
func (c *CommentController) Index() {
|
||||
func (c *CommentController) Index() {
|
||||
c.Prepare()
|
||||
c.TplName = "comment/index.tpl"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"net/url"
|
||||
"image/png"
|
||||
|
||||
"bytes"
|
||||
|
@ -21,7 +21,6 @@ import (
|
|||
"github.com/astaxie/beego/orm"
|
||||
"github.com/boombuler/barcode"
|
||||
"github.com/boombuler/barcode/qr"
|
||||
"github.com/lifei6671/mindoc/commands"
|
||||
"github.com/lifei6671/mindoc/conf"
|
||||
"github.com/lifei6671/mindoc/models"
|
||||
"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 will be redirected to login page(SessionId: " + c.CruSession.SessionID() + ").")
|
||||
|
||||
c.SetSession("turl", c.Ctx.Request.URL.RequestURI())
|
||||
|
||||
if c.IsAjax() {
|
||||
c.JsonResult(6000, "需要[重]登录。")
|
||||
c.JsonResult(6000, "请重新登录。")
|
||||
} 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")
|
||||
id := c.GetString(":id")
|
||||
|
||||
c.Data["DocumentId"] = id // added by dandycheung, 2017-12-08, for exporting
|
||||
beego.Info("DocumentController.Read(): c.Data[\"DocumentId\"] = ", id, ", IsAjax = ", c.IsAjax())
|
||||
c.Data["DocumentId"] = id
|
||||
|
||||
if identify == "" || id == "" {
|
||||
c.Abort("404")
|
||||
|
@ -393,7 +389,6 @@ func (c *DocumentController) Create() {
|
|||
|
||||
document.Identify = doc_identify
|
||||
|
||||
|
||||
document.Version = time.Now().Unix()
|
||||
document.DocumentName = doc_name
|
||||
document.ParentId = parent_id
|
||||
|
@ -438,11 +433,10 @@ func (c *DocumentController) Upload() {
|
|||
}
|
||||
beego.Info(conf.GetUploadFileSize())
|
||||
beego.Info(moreFile.Size)
|
||||
if conf.GetUploadFileSize() > 0 && moreFile.Size > conf.GetUploadFileSize() {
|
||||
c.JsonResult(6009,"查过文件允许的上传最大值")
|
||||
if conf.GetUploadFileSize() > 0 && moreFile.Size > conf.GetUploadFileSize() {
|
||||
c.JsonResult(6009, "查过文件允许的上传最大值")
|
||||
}
|
||||
|
||||
|
||||
ext := filepath.Ext(moreFile.Filename)
|
||||
|
||||
if ext == "" {
|
||||
|
@ -498,7 +492,7 @@ func (c *DocumentController) Upload() {
|
|||
}
|
||||
|
||||
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)
|
||||
|
||||
os.MkdirAll(path, os.ModePerm)
|
||||
|
@ -515,7 +509,7 @@ func (c *DocumentController) Upload() {
|
|||
attachment.FileName = moreFile.Filename
|
||||
attachment.CreateAt = c.Member.MemberId
|
||||
attachment.FileExt = ext
|
||||
attachment.FilePath = strings.TrimPrefix(filePath, commands.WorkingDirectory)
|
||||
attachment.FilePath = strings.TrimPrefix(filePath, conf.WorkingDirectory)
|
||||
attachment.DocumentId = doc_id
|
||||
|
||||
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") {
|
||||
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, "//") {
|
||||
attachment.HttpPath = string(attachment.HttpPath[1:])
|
||||
}
|
||||
|
@ -621,7 +615,7 @@ func (c *DocumentController) DownloadAttachment() {
|
|||
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()
|
||||
}
|
||||
|
||||
|
@ -666,7 +660,7 @@ func (c *DocumentController) RemoveAttachment() {
|
|||
c.JsonResult(6005, "删除失败")
|
||||
}
|
||||
|
||||
os.Remove(filepath.Join(commands.WorkingDirectory, attach.FilePath))
|
||||
os.Remove(filepath.Join(conf.WorkingDirectory, attach.FilePath))
|
||||
|
||||
c.JsonResult(0, "ok", attach)
|
||||
}
|
||||
|
@ -819,15 +813,13 @@ func (c *DocumentController) Content() {
|
|||
beego.Error("DocumentHistory InsertOrUpdate => ", err)
|
||||
}
|
||||
}
|
||||
if auto_release {
|
||||
if auto_release {
|
||||
go func(identify string) {
|
||||
models.NewDocument().ReleaseContent(book_id)
|
||||
|
||||
|
||||
}(identify)
|
||||
}
|
||||
|
||||
|
||||
c.JsonResult(0, "ok", doc)
|
||||
}
|
||||
|
||||
|
@ -844,7 +836,6 @@ func (c *DocumentController) Content() {
|
|||
c.JsonResult(0, "ok", doc)
|
||||
}
|
||||
|
||||
|
||||
func (c *DocumentController) GetDocumentById(id string) (doc *models.Document, err error) {
|
||||
doc = models.NewDocument()
|
||||
if doc_id, err := strconv.Atoi(id); err == nil {
|
||||
|
@ -894,55 +885,33 @@ func (c *DocumentController) Export() {
|
|||
bookResult = isReadable(identify, token, c)
|
||||
}
|
||||
|
||||
if bookResult.PrivatelyOwned == 0 {
|
||||
// TODO: 私有项目禁止导出
|
||||
}
|
||||
|
||||
if !strings.HasPrefix(bookResult.Cover,"http:://") && !strings.HasPrefix(bookResult.Cover,"https:://"){
|
||||
if !strings.HasPrefix(bookResult.Cover, "http:://") && !strings.HasPrefix(bookResult.Cover, "https:://") {
|
||||
bookResult.Cover = c.BaseUrl() + bookResult.Cover
|
||||
}
|
||||
|
||||
eBookResult,err := bookResult.Converter(c.CruSession.SessionID())
|
||||
eBookResult, err := bookResult.Converter(c.CruSession.SessionID())
|
||||
|
||||
if err != nil {
|
||||
beego.Error("转换文档失败:" + bookResult.BookName + " -> " + err.Error())
|
||||
c.Abort("500")
|
||||
}
|
||||
|
||||
|
||||
if output == "pdf" {
|
||||
c.Ctx.Output.Download(eBookResult.PDFPath, identify + ".pdf")
|
||||
c.Ctx.Output.Download(eBookResult.PDFPath, bookResult.BookName+".pdf")
|
||||
|
||||
//如果没有开启缓存,则10分钟后删除
|
||||
if !bookResult.IsCacheEBook {
|
||||
defer func(pdfpath string) {
|
||||
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")
|
||||
c.Abort("200")
|
||||
} else if output == "epub" {
|
||||
c.Ctx.Output.Download(eBookResult.EpubPath, bookResult.BookName+".epub")
|
||||
|
||||
//如果没有开启缓存,则10分钟后删除
|
||||
if !bookResult.IsCacheEBook {
|
||||
defer func(pdfpath string) {
|
||||
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")
|
||||
c.Abort("200")
|
||||
} else if output == "mobi" {
|
||||
c.Ctx.Output.Download(eBookResult.MobiPath, bookResult.BookName+".epub")
|
||||
|
||||
//如果没有开启缓存,则10分钟后删除
|
||||
if !bookResult.IsCacheEBook {
|
||||
defer func(pdfpath string) {
|
||||
time.Sleep(time.Minute * 10)
|
||||
os.Remove(filepath.Dir(pdfpath))
|
||||
}(eBookResult.MobiPath)
|
||||
}
|
||||
c.StopRun()
|
||||
c.Abort("200")
|
||||
} else if output == "docx" {
|
||||
c.Ctx.Output.Download(eBookResult.WordPath, bookResult.BookName+".epub")
|
||||
|
||||
c.Abort("200")
|
||||
}
|
||||
|
||||
c.Abort("404")
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
package controllers
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"github.com/astaxie/beego"
|
||||
"github.com/lifei6671/mindoc/models"
|
||||
"github.com/lifei6671/mindoc/utils"
|
||||
"math"
|
||||
"github.com/lifei6671/mindoc/conf"
|
||||
)
|
||||
|
||||
type HomeController struct {
|
||||
|
@ -16,9 +18,9 @@ func (c *HomeController) Index() {
|
|||
c.TplName = "home/index.tpl"
|
||||
//如果没有开启匿名访问,则跳转到登录页面
|
||||
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
|
||||
|
||||
member_id := 0
|
||||
|
@ -26,7 +28,7 @@ func (c *HomeController) Index() {
|
|||
if c.Member != nil {
|
||||
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 {
|
||||
beego.Error(err)
|
||||
|
@ -36,18 +38,18 @@ func (c *HomeController) Index() {
|
|||
html := utils.GetPagerHtml(c.Ctx.Request.RequestURI, pageIndex, pageSize, totalCount)
|
||||
|
||||
c.Data["PageHtml"] = html
|
||||
}else {
|
||||
} else {
|
||||
c.Data["PageHtml"] = ""
|
||||
}
|
||||
c.Data["TotalPages"] = int(math.Ceil(float64(totalCount) / float64(pageSize)))
|
||||
|
||||
c.Data["Lists"] = books
|
||||
|
||||
labels ,totalCount,err := models.NewLabel().FindToPager(1,10)
|
||||
labels, totalCount, err := models.NewLabel().FindToPager(1, 10)
|
||||
|
||||
if err != nil {
|
||||
c.Data["Labels"] = make([]*models.Label,0)
|
||||
}else{
|
||||
c.Data["Labels"] = make([]*models.Label, 0)
|
||||
} else {
|
||||
c.Data["Labels"] = labels
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
package controllers
|
||||
|
||||
import (
|
||||
"github.com/lifei6671/mindoc/models"
|
||||
"github.com/astaxie/beego/orm"
|
||||
"github.com/astaxie/beego"
|
||||
"github.com/astaxie/beego/orm"
|
||||
"github.com/lifei6671/mindoc/conf"
|
||||
"github.com/lifei6671/mindoc/models"
|
||||
"github.com/lifei6671/mindoc/utils"
|
||||
"math"
|
||||
)
|
||||
|
@ -18,7 +18,7 @@ func (c *LabelController) Prepare() {
|
|||
|
||||
//如果没有开启你们访问则跳转到登录
|
||||
if !c.EnableAnonymous && c.Member == nil {
|
||||
c.Redirect(beego.URLFor("AccountController.Login"),302)
|
||||
c.Redirect(beego.URLFor("AccountController.Login"), 302)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
@ -29,16 +29,16 @@ func (c *LabelController) Index() {
|
|||
c.TplName = "label/index.tpl"
|
||||
|
||||
labelName := c.Ctx.Input.Param(":key")
|
||||
pageIndex,_ := c.GetInt("page",1)
|
||||
pageIndex, _ := c.GetInt("page", 1)
|
||||
if labelName == "" {
|
||||
c.Abort("404")
|
||||
}
|
||||
_,err := models.NewLabel().FindFirst("label_name",labelName)
|
||||
_, err := models.NewLabel().FindFirst("label_name", labelName)
|
||||
|
||||
if err != nil {
|
||||
if err == orm.ErrNoRows {
|
||||
c.Abort("404")
|
||||
}else{
|
||||
} else {
|
||||
beego.Error(err)
|
||||
c.Abort("500")
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ func (c *LabelController) Index() {
|
|||
if c.Member != nil {
|
||||
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 {
|
||||
beego.Error(err)
|
||||
|
@ -57,7 +57,7 @@ func (c *LabelController) Index() {
|
|||
html := utils.GetPagerHtml(c.Ctx.Request.RequestURI, pageIndex, conf.PageSize, totalCount)
|
||||
|
||||
c.Data["PageHtml"] = html
|
||||
}else {
|
||||
} else {
|
||||
c.Data["PageHtml"] = ""
|
||||
}
|
||||
c.Data["Lists"] = search_result
|
||||
|
@ -69,25 +69,22 @@ func (c *LabelController) List() {
|
|||
c.Prepare()
|
||||
c.TplName = "label/list.tpl"
|
||||
|
||||
pageIndex,_ := c.GetInt("page",1)
|
||||
pageIndex, _ := c.GetInt("page", 1)
|
||||
pageSize := 200
|
||||
|
||||
labels ,totalCount,err := models.NewLabel().FindToPager(pageIndex,pageSize)
|
||||
labels, totalCount, err := models.NewLabel().FindToPager(pageIndex, pageSize)
|
||||
|
||||
if err != nil {
|
||||
c.ShowErrorPage(50001,err.Error())
|
||||
c.ShowErrorPage(50001, err.Error())
|
||||
}
|
||||
if totalCount > 0 {
|
||||
html := utils.GetPagerHtml(c.Ctx.Request.RequestURI, pageIndex, pageSize, totalCount)
|
||||
|
||||
c.Data["PageHtml"] = html
|
||||
}else {
|
||||
} else {
|
||||
c.Data["PageHtml"] = ""
|
||||
}
|
||||
c.Data["TotalPages"] = int(math.Ceil(float64(totalCount) / float64(pageSize)))
|
||||
|
||||
c.Data["Labels"] = labels
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -13,7 +13,6 @@ import (
|
|||
"github.com/lifei6671/mindoc/models"
|
||||
"github.com/lifei6671/mindoc/utils"
|
||||
"path/filepath"
|
||||
"github.com/lifei6671/mindoc/commands"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
|
@ -21,7 +20,7 @@ type ManagerController struct {
|
|||
BaseController
|
||||
}
|
||||
|
||||
func (c *ManagerController) Prepare (){
|
||||
func (c *ManagerController) Prepare() {
|
||||
c.BaseController.Prepare()
|
||||
|
||||
if !c.Member.IsAdministrator() {
|
||||
|
@ -42,7 +41,7 @@ func (c *ManagerController) Users() {
|
|||
|
||||
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 {
|
||||
c.Data["ErrorMessage"] = err.Error()
|
||||
|
@ -50,7 +49,7 @@ func (c *ManagerController) Users() {
|
|||
}
|
||||
|
||||
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
|
||||
} else {
|
||||
|
@ -139,10 +138,10 @@ func (c *ManagerController) UpdateMemberStatus() {
|
|||
c.JsonResult(6002, "用户不存在")
|
||||
}
|
||||
if member.MemberId == c.Member.MemberId {
|
||||
c.JsonResult(6004,"不能变更自己的状态")
|
||||
c.JsonResult(6004, "不能变更自己的状态")
|
||||
}
|
||||
if member.Role == conf.MemberSuperRole {
|
||||
c.JsonResult(6005,"不能变更超级管理员的状态")
|
||||
c.JsonResult(6005, "不能变更超级管理员的状态")
|
||||
}
|
||||
member.Status = status
|
||||
|
||||
|
@ -171,10 +170,10 @@ func (c *ManagerController) ChangeMemberRole() {
|
|||
c.JsonResult(6002, "用户不存在")
|
||||
}
|
||||
if member.MemberId == c.Member.MemberId {
|
||||
c.JsonResult(6004,"不能变更自己的权限")
|
||||
c.JsonResult(6004, "不能变更自己的权限")
|
||||
}
|
||||
if member.Role == conf.MemberSuperRole {
|
||||
c.JsonResult(6005,"不能变更超级管理员的权限")
|
||||
c.JsonResult(6005, "不能变更超级管理员的权限")
|
||||
}
|
||||
member.Role = role
|
||||
|
||||
|
@ -191,13 +190,13 @@ func (c *ManagerController) EditMember() {
|
|||
c.Prepare()
|
||||
c.TplName = "manager/edit_users.tpl"
|
||||
|
||||
member_id,_ := c.GetInt(":id",0)
|
||||
member_id, _ := c.GetInt(":id", 0)
|
||||
|
||||
if member_id <= 0 {
|
||||
c.Abort("404")
|
||||
}
|
||||
|
||||
member ,err := models.NewMember().Find(member_id)
|
||||
member, err := models.NewMember().Find(member_id)
|
||||
|
||||
if err != nil {
|
||||
beego.Error(err)
|
||||
|
@ -213,64 +212,64 @@ func (c *ManagerController) EditMember() {
|
|||
member.Phone = phone
|
||||
member.Description = description
|
||||
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
|
||||
}
|
||||
if err := member.Valid(password1 == "");err != nil {
|
||||
c.JsonResult(6002,err.Error())
|
||||
if err := member.Valid(password1 == ""); err != nil {
|
||||
c.JsonResult(6002, err.Error())
|
||||
}
|
||||
if password1 != "" {
|
||||
password,err := utils.PasswordHash(password1)
|
||||
password, err := utils.PasswordHash(password1)
|
||||
if err != nil {
|
||||
beego.Error(err)
|
||||
c.JsonResult(6003,"对用户密码加密时出错")
|
||||
c.JsonResult(6003, "对用户密码加密时出错")
|
||||
}
|
||||
member.Password = password
|
||||
}
|
||||
if err := member.Update();err != nil {
|
||||
if err := member.Update(); err != nil {
|
||||
beego.Error(err)
|
||||
c.JsonResult(6004,"保存失败")
|
||||
c.JsonResult(6004, "保存失败")
|
||||
}
|
||||
c.JsonResult(0,"ok")
|
||||
c.JsonResult(0, "ok")
|
||||
}
|
||||
|
||||
c.Data["Model"] = member
|
||||
}
|
||||
|
||||
//删除一个用户,并将该用户的所有信息转移到超级管理员上.
|
||||
func (c *ManagerController) DeleteMember() {
|
||||
func (c *ManagerController) DeleteMember() {
|
||||
c.Prepare()
|
||||
member_id,_ := c.GetInt("id",0)
|
||||
member_id, _ := c.GetInt("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 {
|
||||
beego.Error(err)
|
||||
c.JsonResult(500,"用户不存在")
|
||||
c.JsonResult(500, "用户不存在")
|
||||
}
|
||||
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 {
|
||||
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 {
|
||||
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"] = ""
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
|
@ -583,27 +582,27 @@ func (c *ManagerController) AttachList() {
|
|||
}
|
||||
|
||||
//附件详情.
|
||||
func (c *ManagerController) AttachDetailed() {
|
||||
func (c *ManagerController) AttachDetailed() {
|
||||
c.Prepare()
|
||||
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 {
|
||||
c.Abort("404")
|
||||
}
|
||||
|
||||
attach,err := models.NewAttachmentResult().Find(attach_id)
|
||||
attach, err := models.NewAttachmentResult().Find(attach_id)
|
||||
|
||||
if err != nil {
|
||||
beego.Error("AttachDetailed => ",err)
|
||||
beego.Error("AttachDetailed => ", err)
|
||||
if err == orm.ErrNoRows {
|
||||
c.Abort("404")
|
||||
}else{
|
||||
} else {
|
||||
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.IsExist = utils.FileExists(attach.FilePath)
|
||||
|
@ -612,43 +611,22 @@ func (c *ManagerController) AttachDetailed() {
|
|||
}
|
||||
|
||||
//删除附件.
|
||||
func (c *ManagerController) AttachDelete() {
|
||||
func (c *ManagerController) AttachDelete() {
|
||||
c.Prepare()
|
||||
attach_id,_ := c.GetInt("attach_id")
|
||||
attach_id, _ := c.GetInt("attach_id")
|
||||
|
||||
if attach_id <= 0 {
|
||||
c.Abort("404")
|
||||
}
|
||||
attach,err := models.NewAttachment().Find(attach_id)
|
||||
attach, err := models.NewAttachment().Find(attach_id)
|
||||
|
||||
if err != nil {
|
||||
beego.Error("AttachDelete => ",err)
|
||||
c.JsonResult(6001,err.Error())
|
||||
beego.Error("AttachDelete => ", err)
|
||||
c.JsonResult(6001, err.Error())
|
||||
}
|
||||
if err := attach.Delete();err != nil {
|
||||
beego.Error("AttachDelete => ",err)
|
||||
c.JsonResult(6002,err.Error())
|
||||
if err := attach.Delete(); err != nil {
|
||||
beego.Error("AttachDelete => ", err)
|
||||
c.JsonResult(6002, err.Error())
|
||||
}
|
||||
c.JsonResult(0,"ok")
|
||||
c.JsonResult(0, "ok")
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,31 +1,31 @@
|
|||
package controllers
|
||||
|
||||
import (
|
||||
"github.com/lifei6671/mindoc/models"
|
||||
"github.com/lifei6671/mindoc/conf"
|
||||
"github.com/lifei6671/mindoc/utils"
|
||||
"github.com/astaxie/beego"
|
||||
"strings"
|
||||
"github.com/lifei6671/mindoc/conf"
|
||||
"github.com/lifei6671/mindoc/models"
|
||||
"github.com/lifei6671/mindoc/utils"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type SearchController struct {
|
||||
BaseController
|
||||
}
|
||||
|
||||
func (c *SearchController) Index() {
|
||||
func (c *SearchController) Index() {
|
||||
c.Prepare()
|
||||
c.TplName = "search/index.tpl"
|
||||
|
||||
//如果没有开启你们访问则跳转到登录
|
||||
if !c.EnableAnonymous && c.Member == nil {
|
||||
c.Redirect(beego.URLFor("AccountController.Login"),302)
|
||||
c.Redirect(beego.URLFor("AccountController.Login"), 302)
|
||||
return
|
||||
}
|
||||
|
||||
keyword := c.GetString("keyword")
|
||||
pageIndex,_ := c.GetInt("page",1)
|
||||
pageIndex, _ := c.GetInt("page", 1)
|
||||
|
||||
c.Data["BaseUrl"] = c.BaseUrl()
|
||||
|
||||
|
@ -35,7 +35,7 @@ func (c *SearchController) Index() {
|
|||
if c.Member != nil {
|
||||
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 {
|
||||
beego.Error(err)
|
||||
|
@ -45,12 +45,12 @@ func (c *SearchController) Index() {
|
|||
html := utils.GetPagerHtml(c.Ctx.Request.RequestURI, pageIndex, conf.PageSize, totalCount)
|
||||
|
||||
c.Data["PageHtml"] = html
|
||||
}else {
|
||||
} else {
|
||||
c.Data["PageHtml"] = ""
|
||||
}
|
||||
if len(search_result) > 0 {
|
||||
for _,item := range search_result {
|
||||
item.DocumentName = strings.Replace(item.DocumentName,keyword,"<em>" + keyword + "</em>",-1)
|
||||
for _, item := range search_result {
|
||||
item.DocumentName = strings.Replace(item.DocumentName, keyword, "<em>"+keyword+"</em>", -1)
|
||||
|
||||
if item.Description != "" {
|
||||
src := item.Description
|
||||
|
@ -79,13 +79,13 @@ func (c *SearchController) Index() {
|
|||
|
||||
if len(r) > 100 {
|
||||
src = string(r[:100])
|
||||
}else{
|
||||
} else {
|
||||
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)
|
||||
}
|
||||
if item.ModifyTime.IsZero() {
|
||||
|
|
|
@ -3,24 +3,23 @@ package controllers
|
|||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/astaxie/beego/logs"
|
||||
"github.com/lifei6671/mindoc/conf"
|
||||
"github.com/lifei6671/mindoc/graphics"
|
||||
"github.com/lifei6671/mindoc/models"
|
||||
"github.com/lifei6671/mindoc/utils"
|
||||
"github.com/lifei6671/mindoc/graphics"
|
||||
"github.com/lifei6671/mindoc/conf"
|
||||
"github.com/lifei6671/mindoc/commands"
|
||||
)
|
||||
|
||||
type SettingController struct {
|
||||
BaseController
|
||||
}
|
||||
|
||||
func (c *SettingController) Index() {
|
||||
func (c *SettingController) Index() {
|
||||
c.TplName = "setting/index.tpl"
|
||||
|
||||
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"
|
||||
|
||||
if c.Ctx.Input.IsPost() {
|
||||
if c.Member.AuthMethod == conf.AuthMethodLDAP {
|
||||
c.JsonResult(6009,"当前用户不支持修改密码")
|
||||
c.JsonResult(6009, "当前用户不支持修改密码")
|
||||
}
|
||||
password1 := c.GetString("password1")
|
||||
password2 := c.GetString("password2")
|
||||
password3 := c.GetString("password3")
|
||||
|
||||
if password1 == "" {
|
||||
c.JsonResult(6003,"原密码不能为空")
|
||||
c.JsonResult(6003, "原密码不能为空")
|
||||
}
|
||||
|
||||
if password2 == "" {
|
||||
c.JsonResult(6004,"新密码不能为空")
|
||||
c.JsonResult(6004, "新密码不能为空")
|
||||
}
|
||||
if count := strings.Count(password2,""); count < 6 || count > 18 {
|
||||
c.JsonResult(6009,"密码必须在6-18字之间")
|
||||
if count := strings.Count(password2, ""); count < 6 || count > 18 {
|
||||
c.JsonResult(6009, "密码必须在6-18字之间")
|
||||
}
|
||||
if password2 != password3 {
|
||||
c.JsonResult(6003,"确认密码不正确")
|
||||
c.JsonResult(6003, "确认密码不正确")
|
||||
}
|
||||
if ok,_ := utils.PasswordVerify(c.Member.Password,password1) ; !ok {
|
||||
c.JsonResult(6005,"原始密码不正确")
|
||||
if ok, _ := utils.PasswordVerify(c.Member.Password, password1); !ok {
|
||||
c.JsonResult(6005, "原始密码不正确")
|
||||
}
|
||||
if password1 == password2 {
|
||||
c.JsonResult(6006,"新密码不能和原始密码相同")
|
||||
c.JsonResult(6006, "新密码不能和原始密码相同")
|
||||
}
|
||||
pwd,err := utils.PasswordHash(password2)
|
||||
pwd, err := utils.PasswordHash(password2)
|
||||
if err != nil {
|
||||
c.JsonResult(6007,"密码加密失败")
|
||||
c.JsonResult(6007, "密码加密失败")
|
||||
}
|
||||
c.Member.Password = pwd
|
||||
if err := c.Member.Update();err != nil {
|
||||
c.JsonResult(6008,err.Error())
|
||||
if err := c.Member.Update(); err != nil {
|
||||
c.JsonResult(6008, err.Error())
|
||||
}
|
||||
c.JsonResult(0,"ok")
|
||||
c.JsonResult(0, "ok")
|
||||
}
|
||||
}
|
||||
|
||||
// Upload 上传图片
|
||||
func (c *SettingController) Upload() {
|
||||
file,moreFile,err := c.GetFile("image-file")
|
||||
file, moreFile, err := c.GetFile("image-file")
|
||||
defer file.Close()
|
||||
|
||||
if err != nil {
|
||||
logs.Error("",err.Error())
|
||||
c.JsonResult(500,"读取文件异常")
|
||||
logs.Error("", err.Error())
|
||||
c.JsonResult(500, "读取文件异常")
|
||||
}
|
||||
|
||||
ext := filepath.Ext(moreFile.Filename)
|
||||
|
||||
if !strings.EqualFold(ext,".png") && !strings.EqualFold(ext,".jpg") && !strings.EqualFold(ext,".gif") && !strings.EqualFold(ext,".jpeg") {
|
||||
c.JsonResult(500,"不支持的图片格式")
|
||||
if !strings.EqualFold(ext, ".png") && !strings.EqualFold(ext, ".jpg") && !strings.EqualFold(ext, ".gif") && !strings.EqualFold(ext, ".jpeg") {
|
||||
c.JsonResult(500, "不支持的图片格式")
|
||||
}
|
||||
|
||||
|
||||
x1 ,_ := strconv.ParseFloat(c.GetString("x"),10)
|
||||
y1 ,_ := strconv.ParseFloat(c.GetString("y"),10)
|
||||
w1 ,_ := strconv.ParseFloat(c.GetString("width"),10)
|
||||
h1 ,_ := strconv.ParseFloat(c.GetString("height"),10)
|
||||
x1, _ := strconv.ParseFloat(c.GetString("x"), 10)
|
||||
y1, _ := strconv.ParseFloat(c.GetString("y"), 10)
|
||||
w1, _ := strconv.ParseFloat(c.GetString("width"), 10)
|
||||
h1, _ := strconv.ParseFloat(c.GetString("height"), 10)
|
||||
|
||||
x := int(x1)
|
||||
y := int(y1)
|
||||
width := int(w1)
|
||||
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)
|
||||
|
||||
os.MkdirAll(path, os.ModePerm)
|
||||
|
||||
err = c.SaveToFile("image-file",filePath)
|
||||
err = c.SaveToFile("image-file", filePath)
|
||||
|
||||
if err != nil {
|
||||
logs.Error("",err)
|
||||
c.JsonResult(500,"图片保存失败")
|
||||
logs.Error("", err)
|
||||
c.JsonResult(500, "图片保存失败")
|
||||
}
|
||||
|
||||
|
||||
//剪切图片
|
||||
subImg,err := graphics.ImageCopyFromFile(filePath,x,y,width,height)
|
||||
subImg, err := graphics.ImageCopyFromFile(filePath, x, y, width, height)
|
||||
|
||||
if err != nil {
|
||||
logs.Error("ImageCopyFromFile => ",err)
|
||||
c.JsonResult(6001,"头像剪切失败")
|
||||
logs.Error("ImageCopyFromFile => ", err)
|
||||
c.JsonResult(6001, "头像剪切失败")
|
||||
}
|
||||
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)
|
||||
|
||||
if err != nil {
|
||||
logs.Error("保存文件失败 => ",err.Error())
|
||||
c.JsonResult(500,"保存文件失败")
|
||||
logs.Error("保存文件失败 => ", err.Error())
|
||||
c.JsonResult(500, "保存文件失败")
|
||||
}
|
||||
|
||||
url := "/" + strings.Replace(strings.TrimPrefix(filePath,commands.WorkingDirectory),"\\","/",-1)
|
||||
if strings.HasPrefix(url,"//") {
|
||||
url := "/" + strings.Replace(strings.TrimPrefix(filePath, conf.WorkingDirectory), "\\", "/", -1)
|
||||
if strings.HasPrefix(url, "//") {
|
||||
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
|
||||
|
||||
member.Avatar = url
|
||||
err := member.Update();
|
||||
err := member.Update()
|
||||
if err == nil {
|
||||
if strings.HasPrefix(avater,"/uploads/") {
|
||||
os.Remove(filepath.Join(commands.WorkingDirectory,avater))
|
||||
if strings.HasPrefix(avater, "/uploads/") {
|
||||
os.Remove(filepath.Join(conf.WorkingDirectory, avater))
|
||||
}
|
||||
c.SetMember(*member)
|
||||
}else{
|
||||
c.JsonResult(60001,"保存头像失败")
|
||||
} else {
|
||||
c.JsonResult(60001, "保存头像失败")
|
||||
}
|
||||
}
|
||||
|
||||
c.JsonResult(0,"ok",url)
|
||||
}
|
||||
c.JsonResult(0, "ok", url)
|
||||
}
|
||||
|
|
|
@ -11,14 +11,12 @@ import (
|
|||
"strings"
|
||||
|
||||
"time"
|
||||
|
||||
"os/exec"
|
||||
|
||||
"errors"
|
||||
|
||||
"github.com/TruthHun/gotil/cryptil"
|
||||
"github.com/TruthHun/gotil/filetil"
|
||||
"github.com/TruthHun/gotil/ziptil"
|
||||
"github.com/lifei6671/mindoc/utils/filetil"
|
||||
"github.com/lifei6671/mindoc/utils/ziptil"
|
||||
"github.com/lifei6671/mindoc/utils/cryptil"
|
||||
)
|
||||
|
||||
type Converter struct {
|
||||
|
@ -67,6 +65,7 @@ var (
|
|||
output = "output" //文档导出文件夹
|
||||
ebookConvert = "ebook-convert"
|
||||
)
|
||||
|
||||
// 接口文档 https://manual.calibre-ebook.com/generated/en/ebook-convert.html#table-of-contents
|
||||
//根据json配置文件,创建文档转化对象
|
||||
func NewConverter(configFile string, debug ...bool) (converter *Converter, err error) {
|
||||
|
@ -124,7 +123,8 @@ func (this *Converter) Convert() (err error) {
|
|||
}
|
||||
|
||||
//将当前文件夹下的所有文件压缩成zip包,然后直接改名成content.epub
|
||||
f := this.BasePath + "/content.epub"
|
||||
f := filepath.Join(this.BasePath, "content.epub")
|
||||
fmt.Println("epub目录 " + f)
|
||||
os.Remove(f) //如果原文件存在了,则删除;
|
||||
if err = ziptil.Zip(f, this.BasePath); err == nil {
|
||||
//创建导出文件夹
|
||||
|
@ -144,6 +144,12 @@ func (this *Converter) Convert() (err error) {
|
|||
}
|
||||
case "pdf":
|
||||
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())
|
||||
}
|
||||
}
|
||||
|
@ -157,6 +163,8 @@ func (this *Converter) Convert() (err error) {
|
|||
fmt.Println(err)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
fmt.Println("压缩目录出错" + err.Error())
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -164,13 +172,13 @@ func (this *Converter) Convert() (err error) {
|
|||
//删除生成导出文档而创建的文件
|
||||
func (this *Converter) converterDefer() {
|
||||
//删除不必要的文件
|
||||
os.RemoveAll(this.BasePath + "/META-INF")
|
||||
os.RemoveAll(this.BasePath + "/content.epub")
|
||||
os.RemoveAll(this.BasePath + "/mimetype")
|
||||
os.RemoveAll(this.BasePath + "/toc.ncx")
|
||||
os.RemoveAll(this.BasePath + "/content.opf")
|
||||
os.RemoveAll(this.BasePath + "/titlepage.xhtml") //封面图片待优化
|
||||
os.RemoveAll(this.BasePath + "/summary.html") //文档目录
|
||||
os.RemoveAll(filepath.Join(this.BasePath, "META-INF"))
|
||||
os.RemoveAll(filepath.Join(this.BasePath, "content.epub"))
|
||||
os.RemoveAll(filepath.Join(this.BasePath, "mimetype"))
|
||||
os.RemoveAll(filepath.Join(this.BasePath, "toc.ncx"))
|
||||
os.RemoveAll(filepath.Join(this.BasePath, "content.opf"))
|
||||
os.RemoveAll(filepath.Join(this.BasePath, "titlepage.xhtml")) //封面图片待优化
|
||||
os.RemoveAll(filepath.Join(this.BasePath, "summary.html")) //文档目录
|
||||
}
|
||||
|
||||
//生成metainfo
|
||||
|
@ -182,15 +190,15 @@ func (this *Converter) generateMetaInfo() (err error) {
|
|||
</rootfiles>
|
||||
</container>
|
||||
`
|
||||
folder := this.BasePath + "/META-INF"
|
||||
folder := filepath.Join(this.BasePath, "META-INF")
|
||||
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
|
||||
}
|
||||
|
||||
//形成mimetyppe
|
||||
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>
|
||||
</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"
|
||||
}
|
||||
}
|
||||
|
@ -241,7 +249,7 @@ func (this *Converter) generateTocNcx() (err error) {
|
|||
`
|
||||
codes, _ := this.tocToXml(0, 1)
|
||||
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
|
||||
|
@ -263,7 +271,7 @@ func (this *Converter) generateSummary() (err error) {
|
|||
</body>
|
||||
</html>`
|
||||
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文件
|
||||
|
@ -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))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
fmt.Println(file.Path)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -415,14 +425,14 @@ func (this *Converter) generateContentOpf() (err error) {
|
|||
guide = `<guide>` + guide + `</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
|
||||
func (this *Converter) convertToEpub() (err error) {
|
||||
args := []string{
|
||||
this.BasePath + "/content.epub",
|
||||
this.BasePath + "/" + output + "/book.epub",
|
||||
filepath.Join(this.BasePath, "content.epub"),
|
||||
filepath.Join(this.BasePath, output, "book.epub"),
|
||||
}
|
||||
cmd := exec.Command(ebookConvert, args...)
|
||||
|
||||
|
@ -435,8 +445,8 @@ func (this *Converter) convertToEpub() (err error) {
|
|||
//转成mobi
|
||||
func (this *Converter) convertToMobi() (err error) {
|
||||
args := []string{
|
||||
this.BasePath + "/content.epub",
|
||||
this.BasePath + "/" + output + "/book.mobi",
|
||||
filepath.Join(this.BasePath, "content.epub"),
|
||||
filepath.Join(this.BasePath, output, "book.mobi"),
|
||||
}
|
||||
cmd := exec.Command(ebookConvert, args...)
|
||||
if this.Debug {
|
||||
|
@ -449,8 +459,8 @@ func (this *Converter) convertToMobi() (err error) {
|
|||
//转成pdf
|
||||
func (this *Converter) convertToPdf() (err error) {
|
||||
args := []string{
|
||||
this.BasePath + "/content.epub",
|
||||
this.BasePath + "/" + output + "/book.pdf",
|
||||
filepath.Join(this.BasePath, "content.epub"),
|
||||
filepath.Join(this.BasePath, output, "book.pdf"),
|
||||
}
|
||||
//页面大小
|
||||
if len(this.Config.PaperSize) > 0 {
|
||||
|
@ -490,6 +500,40 @@ func (this *Converter) convertToPdf() (err error) {
|
|||
}
|
||||
|
||||
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 {
|
||||
fmt.Println(cmd.Args)
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ import (
|
|||
// 将图片保存到指定的路径
|
||||
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)
|
||||
|
||||
|
|
|
@ -127,7 +127,7 @@ func (m *Attachment) FindToPager(pageIndex, pageSize int) (attachList []*Attachm
|
|||
} else {
|
||||
attach.DocumentName = "[不存在]"
|
||||
}
|
||||
attach.LocalHttpPath = strings.Replace(item.FilePath,"\\","/",-1)
|
||||
attach.LocalHttpPath = strings.Replace(item.FilePath, "\\", "/", -1)
|
||||
|
||||
attachList = append(attachList, attach)
|
||||
}
|
||||
|
|
|
@ -8,27 +8,27 @@ import (
|
|||
|
||||
type AttachmentResult struct {
|
||||
Attachment
|
||||
IsExist bool
|
||||
BookName string
|
||||
DocumentName string
|
||||
IsExist bool
|
||||
BookName string
|
||||
DocumentName string
|
||||
FileShortSize string
|
||||
Account string
|
||||
Account string
|
||||
LocalHttpPath string
|
||||
}
|
||||
|
||||
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()
|
||||
|
||||
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 {
|
||||
return m,err
|
||||
return m, err
|
||||
}
|
||||
|
||||
m.Attachment = *attach
|
||||
|
@ -50,12 +50,12 @@ func (m *AttachmentResult) Find(id int) (*AttachmentResult,error) {
|
|||
|
||||
if attach.CreateAt > 0 {
|
||||
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.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
|
||||
}
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
package models
|
||||
|
||||
type Model struct {
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -4,9 +4,9 @@ import "time"
|
|||
|
||||
//博文表
|
||||
type Blog struct {
|
||||
BlogId int
|
||||
BlogId int
|
||||
BlogTitle string
|
||||
MemberId int
|
||||
MemberId int
|
||||
//文字摘要
|
||||
BlogExcerpt string
|
||||
//文章内容
|
||||
|
@ -22,4 +22,4 @@ type Blog struct {
|
|||
ModifyAt int
|
||||
//创建时间
|
||||
Created time.Time
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,11 +3,14 @@ package models
|
|||
import (
|
||||
"time"
|
||||
|
||||
"fmt"
|
||||
"github.com/astaxie/beego"
|
||||
"github.com/astaxie/beego/logs"
|
||||
"github.com/astaxie/beego/orm"
|
||||
"github.com/lifei6671/mindoc/conf"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// Book struct .
|
||||
|
@ -16,17 +19,15 @@ type Book struct {
|
|||
// BookName 项目名称.
|
||||
BookName string `orm:"column(book_name);size(500)" json:"book_name"`
|
||||
// Identify 项目唯一标识.
|
||||
Identify string `orm:"column(identify);size(100);unique" json:"identify"`
|
||||
Identify string `orm:"column(identify);size(100);unique" json:"identify"`
|
||||
//是否是自动发布 0 否/1 是
|
||||
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 string `orm:"column(description);size(2000)" json:"description"`
|
||||
//发行公司
|
||||
Publisher string `orm:"column(publisher);size(500)" json:"publisher"`
|
||||
//是否缓存导出的电子书,如果缓存可能会出现导出的文件不是最新的。 0 为不缓存
|
||||
IsCacheEBook int `orm:"column(is_cache_ebook);type(int);default(0)" json:"is_cache_ebook"`
|
||||
Label string `orm:"column(label);size(500)" json:"label"`
|
||||
Publisher string `orm:"column(publisher);size(500)" json:"publisher"`
|
||||
Label string `orm:"column(label);size(500)" json:"label"`
|
||||
// PrivatelyOwned 项目私有: 0 公开/ 1 私有
|
||||
PrivatelyOwned int `orm:"column(privately_owned);type(int);default(0)" json:"privately_owned"`
|
||||
// 当项目是私有时的访问Token.
|
||||
|
@ -122,7 +123,7 @@ func (m *Book) Update(cols ...string) error {
|
|||
temp := NewBook()
|
||||
temp.BookId = m.BookId
|
||||
|
||||
if err := o.Read(temp);err != nil {
|
||||
if err := o.Read(temp); err != nil {
|
||||
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 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 " +
|
||||
" 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)
|
||||
if err != nil {
|
||||
|
@ -261,6 +262,8 @@ func (m *Book) ThoroughDeleteBook(id int) error {
|
|||
NewLabel().InsertOrUpdateMulti(m.Label)
|
||||
}
|
||||
|
||||
os.RemoveAll(filepath.Join(conf.WorkingDirectory,"uploads","books",strconv.Itoa(id)))
|
||||
|
||||
return o.Commit()
|
||||
|
||||
}
|
||||
|
@ -320,7 +323,7 @@ func (m *Book) FindForLabelToPager(keyword string, pageIndex, pageSize, member_i
|
|||
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 ?"
|
||||
|
||||
err = o.Raw(sql1, member_id,keyword).QueryRow(&totalCount)
|
||||
err = o.Raw(sql1, member_id, keyword).QueryRow(&totalCount)
|
||||
if err != nil {
|
||||
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
|
||||
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
|
||||
|
||||
} 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 {
|
||||
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
|
||||
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
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//重置文档数量
|
||||
func (m *Book) ResetDocumentNumber(book_id int) {
|
||||
o := orm.NewOrm()
|
||||
|
|
|
@ -1,64 +1,64 @@
|
|||
package models
|
||||
|
||||
import (
|
||||
"time"
|
||||
"bytes"
|
||||
|
||||
"github.com/astaxie/beego/orm"
|
||||
"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"
|
||||
"time"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"encoding/base64"
|
||||
"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/russross/blackfriday"
|
||||
)
|
||||
|
||||
type BookResult struct {
|
||||
BookId int `json:"book_id"`
|
||||
BookName string `json:"book_name"`
|
||||
Identify string `json:"identify"`
|
||||
OrderIndex int `json:"order_index"`
|
||||
Description string `json:"description"`
|
||||
Publisher string `json:"publisher"`
|
||||
IsCacheEBook bool `json:"is_cache_ebook"`
|
||||
PrivatelyOwned int `json:"privately_owned"`
|
||||
PrivateToken string `json:"private_token"`
|
||||
DocCount int `json:"doc_count"`
|
||||
CommentStatus string `json:"comment_status"`
|
||||
CommentCount int `json:"comment_count"`
|
||||
CreateTime time.Time `json:"create_time"`
|
||||
CreateName string `json:"create_name"`
|
||||
ModifyTime time.Time `json:"modify_time"`
|
||||
Cover string `json:"cover"`
|
||||
Theme string `json:"theme"`
|
||||
Label string `json:"label"`
|
||||
MemberId int `json:"member_id"`
|
||||
Editor string `json:"editor"`
|
||||
AutoRelease bool `json:"auto_release"`
|
||||
BookId int `json:"book_id"`
|
||||
BookName string `json:"book_name"`
|
||||
Identify string `json:"identify"`
|
||||
OrderIndex int `json:"order_index"`
|
||||
Description string `json:"description"`
|
||||
Publisher string `json:"publisher"`
|
||||
PrivatelyOwned int `json:"privately_owned"`
|
||||
PrivateToken string `json:"private_token"`
|
||||
DocCount int `json:"doc_count"`
|
||||
CommentStatus string `json:"comment_status"`
|
||||
CommentCount int `json:"comment_count"`
|
||||
CreateTime time.Time `json:"create_time"`
|
||||
CreateName string `json:"create_name"`
|
||||
ModifyTime time.Time `json:"modify_time"`
|
||||
Cover string `json:"cover"`
|
||||
Theme string `json:"theme"`
|
||||
Label string `json:"label"`
|
||||
MemberId int `json:"member_id"`
|
||||
Editor string `json:"editor"`
|
||||
AutoRelease bool `json:"auto_release"`
|
||||
|
||||
RelationshipId int `json:"relationship_id"`
|
||||
RoleId int `json:"role_id"`
|
||||
RoleName string `json:"role_name"`
|
||||
Status int
|
||||
RelationshipId int `json:"relationship_id"`
|
||||
RoleId int `json:"role_id"`
|
||||
RoleName string `json:"role_name"`
|
||||
Status int
|
||||
|
||||
LastModifyText string `json:"last_modify_text"`
|
||||
IsDisplayComment bool `json:"is_display_comment"`
|
||||
LastModifyText string `json:"last_modify_text"`
|
||||
IsDisplayComment bool `json:"is_display_comment"`
|
||||
}
|
||||
|
||||
func NewBookResult() *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 {
|
||||
return m,ErrInvalidParameter
|
||||
return m, ErrInvalidParameter
|
||||
}
|
||||
o := orm.NewOrm()
|
||||
|
||||
|
@ -93,11 +93,10 @@ func (m *BookResult) FindByIdentify(identify string,member_id int) (*BookResult,
|
|||
|
||||
m = NewBookResult().ToBookResult(*book)
|
||||
|
||||
m.CreateName = member.Account
|
||||
m.MemberId = relationship.MemberId
|
||||
m.RoleId = relationship.RoleId
|
||||
m.RelationshipId = relationship.RelationshipId
|
||||
|
||||
m.CreateName = member.Account
|
||||
m.MemberId = relationship.MemberId
|
||||
m.RoleId = relationship.RoleId
|
||||
m.RelationshipId = relationship.RelationshipId
|
||||
|
||||
if m.RoleId == conf.BookFounder {
|
||||
m.RoleName = "创始人"
|
||||
|
@ -123,10 +122,10 @@ func (m *BookResult) FindByIdentify(identify string,member_id int) (*BookResult,
|
|||
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()
|
||||
|
||||
count,err := o.QueryTable(NewBook().TableNameWithPrefix()).Count()
|
||||
count, err := o.QueryTable(NewBook().TableNameWithPrefix()).Count()
|
||||
|
||||
if err != nil {
|
||||
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
|
||||
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
|
||||
}
|
||||
|
@ -169,7 +168,6 @@ func (m *BookResult) ToBookResult(book Book) *BookResult {
|
|||
m.Theme = book.Theme
|
||||
m.AutoRelease = book.AutoRelease == 1
|
||||
m.Publisher = book.Publisher
|
||||
m.IsCacheEBook = book.IsCacheEBook == 1
|
||||
|
||||
if book.Theme == "" {
|
||||
m.Theme = "default"
|
||||
|
@ -180,128 +178,139 @@ func (m *BookResult) ToBookResult(book Book) *BookResult {
|
|||
return m
|
||||
}
|
||||
|
||||
func (m *BookResult) Converter(sessionId string) (ConvertBookResult,error) {
|
||||
func (m *BookResult) Converter(sessionId string) (ConvertBookResult, error) {
|
||||
|
||||
convertBookResult := ConvertBookResult{}
|
||||
outputPath := filepath.Join(beego.AppConfig.DefaultString("book_output_path","cache"),sessionId,strconv.Itoa(m.BookId))
|
||||
|
||||
if m.IsCacheEBook {
|
||||
outputPath = filepath.Join(beego.AppConfig.DefaultString("book_output_path","cache"),strconv.Itoa(m.BookId))
|
||||
outputPath := filepath.Join(conf.WorkingDirectory,"uploads","books", 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)
|
||||
if err != nil {
|
||||
return convertBookResult,err
|
||||
return convertBookResult, err
|
||||
}
|
||||
|
||||
tocList := make([]converter.Toc,0)
|
||||
tocList := make([]converter.Toc, 0)
|
||||
|
||||
for _, item := range docs {
|
||||
if item.ParentId == 0 {
|
||||
toc := converter.Toc{
|
||||
Id: item.DocumentId,
|
||||
Link: strconv.Itoa(item.DocumentId) + ".html",
|
||||
Pid: item.ParentId,
|
||||
Id: item.DocumentId,
|
||||
Link: strconv.Itoa(item.DocumentId) + ".html",
|
||||
Pid: item.ParentId,
|
||||
Title: item.DocumentName,
|
||||
}
|
||||
|
||||
tocList = append(tocList,toc)
|
||||
tocList = append(tocList, toc)
|
||||
}
|
||||
}
|
||||
for _, item := range docs {
|
||||
if item.ParentId != 0 {
|
||||
toc := converter.Toc{
|
||||
Id: item.DocumentId,
|
||||
Link: strconv.Itoa(item.DocumentId) + ".html",
|
||||
Pid: item.ParentId,
|
||||
Id: item.DocumentId,
|
||||
Link: strconv.Itoa(item.DocumentId) + ".html",
|
||||
Pid: item.ParentId,
|
||||
Title: item.DocumentName,
|
||||
}
|
||||
tocList = append(tocList,toc)
|
||||
tocList = append(tocList, toc)
|
||||
}
|
||||
}
|
||||
|
||||
ebookConfig := converter.Config{
|
||||
Charset : "utf-8",
|
||||
Cover : m.Cover,
|
||||
Timestamp : time.Now().Format("2006-01-02 15:04:05"),
|
||||
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>",
|
||||
Header : "<p style='color:#8E8E8E;font-size:12px;'>_SECTION_</p>",
|
||||
Identifier : "",
|
||||
Language : "zh-CN",
|
||||
Creator : m.CreateName,
|
||||
Publisher : m.Publisher,
|
||||
Contributor : m.Publisher,
|
||||
Title : m.BookName,
|
||||
Format: []string{"epub", "mobi", "pdf"},
|
||||
FontSize : "14",
|
||||
PaperSize : "a4",
|
||||
MarginLeft : "72",
|
||||
MarginRight : "72",
|
||||
MarginTop : "72",
|
||||
MarginBottom : "72",
|
||||
Toc : tocList,
|
||||
More : []string{},
|
||||
|
||||
Charset: "utf-8",
|
||||
Cover: m.Cover,
|
||||
Timestamp: time.Now().Format("2006-01-02 15:04:05"),
|
||||
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>",
|
||||
Header: "<p style='color:#8E8E8E;font-size:12px;'>_SECTION_</p>",
|
||||
Identifier: "",
|
||||
Language: "zh-CN",
|
||||
Creator: m.CreateName,
|
||||
Publisher: m.Publisher,
|
||||
Contributor: m.Publisher,
|
||||
Title: m.BookName,
|
||||
Format: []string{"epub", "mobi", "pdf", "docx"},
|
||||
FontSize: "14",
|
||||
PaperSize: "a4",
|
||||
MarginLeft: "72",
|
||||
MarginRight: "72",
|
||||
MarginTop: "72",
|
||||
MarginBottom: "72",
|
||||
Toc: tocList,
|
||||
More: []string{},
|
||||
}
|
||||
|
||||
|
||||
os.MkdirAll(outputPath, 0766)
|
||||
if outputPath, err = filepath.Abs(outputPath); err != nil {
|
||||
if tempOutputPath, err = filepath.Abs(tempOutputPath); err != nil {
|
||||
beego.Error("导出目录配置错误:" + err.Error())
|
||||
return convertBookResult,err
|
||||
return convertBookResult, err
|
||||
}
|
||||
|
||||
viewPath := beego.BConfig.WebConfig.ViewsPath
|
||||
baseUrl := beego.AppConfig.DefaultString("baseurl","")
|
||||
|
||||
for _,item := range docs {
|
||||
for _, item := range docs {
|
||||
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)
|
||||
if err != nil {
|
||||
return convertBookResult,err
|
||||
return convertBookResult, err
|
||||
}
|
||||
var buf bytes.Buffer
|
||||
|
||||
if err := beego.ExecuteViewPathTemplate(&buf,"document/export.tpl",viewPath,map[string]interface{}{"Model": m, "Lists": item, "BaseUrl": baseUrl}); err != nil {
|
||||
return convertBookResult,err
|
||||
if err := beego.ExecuteViewPathTemplate(&buf, "document/export.tpl", viewPath, map[string]interface{}{"Model": m, "Lists": item, "BaseUrl": conf.BaseUrl}); err != nil {
|
||||
return convertBookResult, err
|
||||
}
|
||||
html := buf.String()
|
||||
|
||||
|
||||
if err != nil {
|
||||
|
||||
f.Close()
|
||||
return convertBookResult,err
|
||||
return convertBookResult, err
|
||||
}
|
||||
|
||||
bufio := bytes.NewReader(buf.Bytes())
|
||||
|
||||
doc, err := goquery.NewDocumentFromReader(bufio)
|
||||
doc.Find("img").Each(func(i int, contentSelection *goquery.Selection) {
|
||||
if src, ok := contentSelection.Attr("src"); ok && strings.HasPrefix(src, "/uploads/") {
|
||||
contentSelection.SetAttr("src", baseUrl + src)
|
||||
if src, ok := contentSelection.Attr("src"); ok && strings.HasPrefix(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()
|
||||
if err != nil {
|
||||
f.Close()
|
||||
return convertBookResult,err
|
||||
return convertBookResult, err
|
||||
}
|
||||
|
||||
// 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()
|
||||
}
|
||||
eBookConverter := &converter.Converter{
|
||||
BasePath : outputPath,
|
||||
Config : ebookConfig,
|
||||
Debug : false,
|
||||
BasePath: tempOutputPath,
|
||||
Config: ebookConfig,
|
||||
Debug: true,
|
||||
}
|
||||
|
||||
if err := eBookConverter.Convert();err != nil {
|
||||
beego.Error("转换文件错误:" + m.BookName +" => "+ err.Error())
|
||||
return convertBookResult,err
|
||||
if err := eBookConverter.Convert(); err != nil {
|
||||
beego.Error("转换文件错误:" + m.BookName + " => " + err.Error())
|
||||
return convertBookResult, err
|
||||
}
|
||||
convertBookResult.MobiPath = filepath.Join(outputPath,"output","book.mobi")
|
||||
convertBookResult.PDFPath = filepath.Join(outputPath,"output","book.pdf")
|
||||
convertBookResult.EpubPath = filepath.Join(outputPath,"output","book.epub")
|
||||
return convertBookResult,nil
|
||||
beego.Info("文档转换完成:" + m.BookName)
|
||||
defer func(p string) {
|
||||
os.RemoveAll(p)
|
||||
}(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
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,76 +1,77 @@
|
|||
package models
|
||||
|
||||
import (
|
||||
"time"
|
||||
"github.com/lifei6671/mindoc/conf"
|
||||
"github.com/astaxie/beego/orm"
|
||||
"errors"
|
||||
"github.com/astaxie/beego/orm"
|
||||
"github.com/lifei6671/mindoc/conf"
|
||||
"time"
|
||||
)
|
||||
|
||||
//Comment struct
|
||||
type Comment struct {
|
||||
CommentId int `orm:"pk;auto;unique;column(comment_id)" json:"comment_id"`
|
||||
Floor int `orm:"column(floor);type(unsigned);default(0)" json:"floor"`
|
||||
BookId int `orm:"column(book_id);type(int)" json:"book_id"`
|
||||
CommentId int `orm:"pk;auto;unique;column(comment_id)" json:"comment_id"`
|
||||
Floor int `orm:"column(floor);type(unsigned);default(0)" json:"floor"`
|
||||
BookId int `orm:"column(book_id);type(int)" json:"book_id"`
|
||||
// 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 string `orm:"column(author);size(100)" json:"author"`
|
||||
Author string `orm:"column(author);size(100)" json:"author"`
|
||||
//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 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 string `orm:"column(content);size(2000)" json:"content"`
|
||||
Content string `orm:"column(content);size(2000)" json:"content"`
|
||||
// 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 string `orm:"column(user_agent);size(500)" json:"user_agent"`
|
||||
UserAgent string `orm:"column(user_agent);size(500)" json:"user_agent"`
|
||||
// Parent 评论所属父级
|
||||
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"`
|
||||
AgainstCount int `orm:"column(against_count);type(int);default(0)" json:"against_count"`
|
||||
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"`
|
||||
AgainstCount int `orm:"column(against_count);type(int);default(0)" json:"against_count"`
|
||||
}
|
||||
|
||||
// TableName 获取对应数据库表名.
|
||||
func (m *Comment) TableName() string {
|
||||
return "comments"
|
||||
}
|
||||
|
||||
// TableEngine 获取数据使用的引擎.
|
||||
func (m *Comment) TableEngine() string {
|
||||
return "INNODB"
|
||||
}
|
||||
|
||||
func (m *Comment) TableNameWithPrefix() string {
|
||||
func (m *Comment) TableNameWithPrefix() string {
|
||||
return conf.GetDatabasePrefix() + m.TableName()
|
||||
}
|
||||
|
||||
func NewComment() *Comment {
|
||||
return &Comment{}
|
||||
}
|
||||
func (m *Comment) Find(id int) (*Comment,error) {
|
||||
func (m *Comment) Find(id int) (*Comment, error) {
|
||||
if id <= 0 {
|
||||
return m,ErrInvalidParameter
|
||||
return m, ErrInvalidParameter
|
||||
}
|
||||
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()
|
||||
|
||||
_,err := o.Update(m,cols...)
|
||||
_, err := o.Update(m, cols...)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
//Insert 添加一条评论.
|
||||
func (m *Comment) Insert() error {
|
||||
if m.DocumentId <= 0{
|
||||
if m.DocumentId <= 0 {
|
||||
return errors.New("评论文档不存在")
|
||||
}
|
||||
if m.Content == "" {
|
||||
|
@ -89,28 +90,28 @@ func (m *Comment) Insert() error {
|
|||
|
||||
document := NewDocument()
|
||||
//如果评论的文档不存在
|
||||
if _,err := document.Find(m.DocumentId); err != nil {
|
||||
if _, err := document.Find(m.DocumentId); err != nil {
|
||||
return err
|
||||
}
|
||||
book ,err := NewBook().Find(document.BookId);
|
||||
book, err := NewBook().Find(document.BookId)
|
||||
//如果评论的项目不存在
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
//如果已关闭评论
|
||||
if book.CommentStatus == "closed"{
|
||||
if book.CommentStatus == "closed" {
|
||||
return ErrCommentClosed
|
||||
}
|
||||
if book.CommentStatus == "registered_only" && m.MemberId <= 0{
|
||||
if book.CommentStatus == "registered_only" && m.MemberId <= 0 {
|
||||
return ErrPermissionDenied
|
||||
}
|
||||
//如果仅参与者评论
|
||||
if book.CommentStatus == "group_only" {
|
||||
if m.MemberId <= 0{
|
||||
if m.MemberId <= 0 {
|
||||
return ErrPermissionDenied
|
||||
}
|
||||
rel := NewRelationship()
|
||||
if _,err := rel.FindForRoleId(book.BookId,m.MemberId);err != nil {
|
||||
if _, err := rel.FindForRoleId(book.BookId, m.MemberId); err != nil {
|
||||
return ErrPermissionDenied
|
||||
}
|
||||
}
|
||||
|
@ -118,51 +119,18 @@ func (m *Comment) Insert() error {
|
|||
if m.MemberId > 0 {
|
||||
member := NewMember()
|
||||
//如果用户不存在
|
||||
if _,err := member.Find(m.MemberId) ; err != nil {
|
||||
if _, err := member.Find(m.MemberId); err != nil {
|
||||
return ErrMemberNoExist
|
||||
}
|
||||
//如果用户被禁用
|
||||
if member.Status == 1 {
|
||||
return ErrMemberDisabled
|
||||
}
|
||||
}else if m.Author == "" {
|
||||
} else if m.Author == "" {
|
||||
m.Author = "[匿名用户]"
|
||||
}
|
||||
m.BookId = book.BookId
|
||||
_,err = o.Insert(m)
|
||||
_, err = o.Insert(m)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -4,11 +4,11 @@ import "github.com/astaxie/beego/orm"
|
|||
|
||||
type CommentResult struct {
|
||||
Comment
|
||||
Author string `json:"author"`
|
||||
ReplyAccount string `json:"reply_account"`
|
||||
Author string `json:"author"`
|
||||
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()
|
||||
|
||||
|
@ -25,12 +25,11 @@ FROM md_comments AS comment
|
|||
|
||||
WHERE comment.document_id = ? ORDER BY comment.comment_id DESC LIMIT 0,10`
|
||||
|
||||
|
||||
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 {
|
||||
totalCount = int(v)
|
||||
|
@ -38,4 +37,3 @@ WHERE comment.document_id = ? ORDER BY comment.comment_id DESC LIMIT 0,10`
|
|||
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -1,30 +1,31 @@
|
|||
package models
|
||||
|
||||
import (
|
||||
"time"
|
||||
"github.com/lifei6671/mindoc/conf"
|
||||
"github.com/astaxie/beego/orm"
|
||||
"github.com/lifei6671/mindoc/conf"
|
||||
"time"
|
||||
)
|
||||
|
||||
type CommentVote struct {
|
||||
VoteId int `orm:"column(vote_id);pk;auto;unique" json:"vote_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"`
|
||||
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"`
|
||||
CreateTime time.Time `orm:"column(create_time);type(datetime);auto_now_add" json:"create_time"`
|
||||
VoteId int `orm:"column(vote_id);pk;auto;unique" json:"vote_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"`
|
||||
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"`
|
||||
CreateTime time.Time `orm:"column(create_time);type(datetime);auto_now_add" json:"create_time"`
|
||||
}
|
||||
|
||||
// TableName 获取对应数据库表名.
|
||||
func (m *CommentVote) TableName() string {
|
||||
return "comment_votes"
|
||||
}
|
||||
|
||||
// TableEngine 获取数据使用的引擎.
|
||||
func (m *CommentVote) TableEngine() string {
|
||||
return "INNODB"
|
||||
}
|
||||
|
||||
func (m *CommentVote) TableNameWithPrefix() string {
|
||||
func (m *CommentVote) TableNameWithPrefix() string {
|
||||
return conf.GetDatabasePrefix() + m.TableName()
|
||||
}
|
||||
func (u *CommentVote) TableUnique() [][]string {
|
||||
|
@ -35,15 +36,15 @@ func (u *CommentVote) TableUnique() [][]string {
|
|||
func NewCommentVote() *CommentVote {
|
||||
return &CommentVote{}
|
||||
}
|
||||
func (m *CommentVote) InsertOrUpdate() (*CommentVote,error) {
|
||||
func (m *CommentVote) InsertOrUpdate() (*CommentVote, error) {
|
||||
o := orm.NewOrm()
|
||||
|
||||
if m.VoteId > 0 {
|
||||
_,err := o.Update(m)
|
||||
return m,err
|
||||
}else{
|
||||
_,err := o.Insert(m)
|
||||
_, err := o.Update(m)
|
||||
return m, err
|
||||
} else {
|
||||
_, err := o.Insert(m)
|
||||
|
||||
return m,err
|
||||
return m, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,8 @@ package models
|
|||
|
||||
// 转换结果
|
||||
type ConvertBookResult struct {
|
||||
PDFPath string
|
||||
PDFPath string
|
||||
EpubPath string
|
||||
MobiPath string
|
||||
WordPath string
|
||||
}
|
||||
|
|
|
@ -3,34 +3,34 @@ package models
|
|||
import "github.com/astaxie/beego/orm"
|
||||
|
||||
type Dashboard struct {
|
||||
BookNumber int64 `json:"book_number"`
|
||||
DocumentNumber int64 `json:"document_number"`
|
||||
MemberNumber int64 `json:"member_number"`
|
||||
CommentNumber int64 `json:"comment_number"`
|
||||
AttachmentNumber int64 `json:"attachment_number"`
|
||||
BookNumber int64 `json:"book_number"`
|
||||
DocumentNumber int64 `json:"document_number"`
|
||||
MemberNumber int64 `json:"member_number"`
|
||||
CommentNumber int64 `json:"comment_number"`
|
||||
AttachmentNumber int64 `json:"attachment_number"`
|
||||
}
|
||||
|
||||
func NewDashboard() *Dashboard {
|
||||
return &Dashboard{}
|
||||
}
|
||||
|
||||
func (m *Dashboard) Query() (*Dashboard) {
|
||||
func (m *Dashboard) Query() *Dashboard {
|
||||
o := orm.NewOrm()
|
||||
|
||||
book_number,_ := o.QueryTable(NewBook().TableNameWithPrefix()).Count()
|
||||
book_number, _ := o.QueryTable(NewBook().TableNameWithPrefix()).Count()
|
||||
|
||||
m.BookNumber = book_number
|
||||
|
||||
document_count,_ := o.QueryTable(NewDocument().TableNameWithPrefix()).Count()
|
||||
document_count, _ := o.QueryTable(NewDocument().TableNameWithPrefix()).Count()
|
||||
m.DocumentNumber = document_count
|
||||
|
||||
member_number,_ := o.QueryTable(NewMember().TableNameWithPrefix()).Count()
|
||||
member_number, _ := o.QueryTable(NewMember().TableNameWithPrefix()).Count()
|
||||
m.MemberNumber = member_number
|
||||
|
||||
//comment_number,_ := o.QueryTable(NewComment().TableNameWithPrefix()).Count()
|
||||
m.CommentNumber = 0
|
||||
|
||||
attachment_number,_ := o.QueryTable(NewAttachment().TableNameWithPrefix()).Count()
|
||||
attachment_number, _ := o.QueryTable(NewAttachment().TableNameWithPrefix()).Count()
|
||||
|
||||
m.AttachmentNumber = attachment_number
|
||||
|
||||
|
|
|
@ -9,6 +9,9 @@ import (
|
|||
"github.com/astaxie/beego/orm"
|
||||
"github.com/lifei6671/mindoc/conf"
|
||||
"strings"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// 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()
|
||||
|
||||
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 {
|
||||
beego.Error("发布失败 => ", err)
|
||||
|
@ -134,12 +137,12 @@ func (m *Document) ReleaseContent(book_id int) {
|
|||
}
|
||||
for _, item := range docs {
|
||||
item.Release = item.Content
|
||||
attach_list, err := NewAttachment().FindListByDocumentId(item.DocumentId)
|
||||
if err == nil && len(attach_list) > 0 {
|
||||
attachList, err := NewAttachment().FindListByDocumentId(item.DocumentId)
|
||||
if err == nil && len(attachList) > 0 {
|
||||
content := bytes.NewBufferString("<div class=\"attach-list\"><strong>附件</strong><ul>")
|
||||
for _, attach := range attach_list {
|
||||
if strings.HasPrefix(attach.HttpPath,"/"){
|
||||
attach.HttpPath = strings.TrimSuffix(beego.AppConfig.DefaultString("baseurl",""),"/") + attach.HttpPath
|
||||
for _, attach := range attachList {
|
||||
if strings.HasPrefix(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)
|
||||
|
||||
|
@ -151,6 +154,8 @@ func (m *Document) ReleaseContent(book_id int) {
|
|||
_, err = o.Update(item, "release")
|
||||
if err != nil {
|
||||
beego.Error(fmt.Sprintf("发布失败 => %+v", item), err)
|
||||
}else {
|
||||
os.RemoveAll(filepath.Join(conf.WorkingDirectory,"uploads","books",strconv.Itoa(bookId)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,14 +23,14 @@ type DocumentHistory struct {
|
|||
}
|
||||
|
||||
type DocumentHistorySimpleResult struct {
|
||||
HistoryId int `json:"history_id"`
|
||||
ActionName string `json:"action_name"`
|
||||
MemberId int `json:"member_id"`
|
||||
Account string `json:"account"`
|
||||
ModifyAt int `json:"modify_at"`
|
||||
ModifyName string `json:"modify_name"`
|
||||
ModifyTime time.Time `json:"modify_time"`
|
||||
Version int64 `json:"version"`
|
||||
HistoryId int `json:"history_id"`
|
||||
ActionName string `json:"action_name"`
|
||||
MemberId int `json:"member_id"`
|
||||
Account string `json:"account"`
|
||||
ModifyAt int `json:"modify_at"`
|
||||
ModifyName string `json:"modify_name"`
|
||||
ModifyTime time.Time `json:"modify_time"`
|
||||
Version int64 `json:"version"`
|
||||
}
|
||||
|
||||
// TableName 获取对应数据库表名.
|
||||
|
@ -50,12 +50,13 @@ func (m *DocumentHistory) TableNameWithPrefix() string {
|
|||
func NewDocumentHistory() *DocumentHistory {
|
||||
return &DocumentHistory{}
|
||||
}
|
||||
func (m *DocumentHistory) Find(id int) (*DocumentHistory,error) {
|
||||
func (m *DocumentHistory) Find(id int) (*DocumentHistory, error) {
|
||||
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 {
|
||||
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()
|
||||
|
||||
_, 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
|
||||
}
|
||||
|
||||
//恢复指定历史的文档.
|
||||
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()
|
||||
|
||||
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 {
|
||||
return err
|
||||
|
@ -113,17 +114,18 @@ func (m *DocumentHistory) Restore(history_id,doc_id,uid int) error {
|
|||
return err
|
||||
}
|
||||
|
||||
func (m *DocumentHistory) InsertOrUpdate() (history *DocumentHistory,err error) {
|
||||
func (m *DocumentHistory) InsertOrUpdate() (history *DocumentHistory, err error) {
|
||||
o := orm.NewOrm()
|
||||
history = m
|
||||
|
||||
if m.HistoryId > 0 {
|
||||
_,err = o.Update(m)
|
||||
}else{
|
||||
_,err = o.Insert(m)
|
||||
_, err = o.Update(m)
|
||||
} else {
|
||||
_, err = o.Insert(m)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//分页查询指定文档的历史.
|
||||
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
|
||||
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 {
|
||||
return
|
||||
|
|
|
@ -1,48 +1,49 @@
|
|||
package models
|
||||
|
||||
import (
|
||||
"github.com/astaxie/beego/orm"
|
||||
"bytes"
|
||||
"strconv"
|
||||
"github.com/astaxie/beego"
|
||||
"github.com/astaxie/beego/orm"
|
||||
"html/template"
|
||||
"math"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type DocumentTree struct {
|
||||
DocumentId int `json:"id"`
|
||||
DocumentName string `json:"text"`
|
||||
ParentId interface{} `json:"parent"`
|
||||
Identify string `json:"identify"`
|
||||
BookIdentify string `json:"-"`
|
||||
Version int64 `json:"version"`
|
||||
State *DocumentSelected `json:"state,omitempty"`
|
||||
DocumentId int `json:"id"`
|
||||
DocumentName string `json:"text"`
|
||||
ParentId interface{} `json:"parent"`
|
||||
Identify string `json:"identify"`
|
||||
BookIdentify string `json:"-"`
|
||||
Version int64 `json:"version"`
|
||||
State *DocumentSelected `json:"state,omitempty"`
|
||||
}
|
||||
type DocumentSelected struct {
|
||||
Selected bool `json:"selected"`
|
||||
Opened bool `json:"opened"`
|
||||
Selected bool `json:"selected"`
|
||||
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()
|
||||
|
||||
trees := make([]*DocumentTree,0)
|
||||
trees := make([]*DocumentTree, 0)
|
||||
|
||||
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 {
|
||||
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{}
|
||||
if index == 0{
|
||||
tree.State = &DocumentSelected{ Selected: true, Opened: true }
|
||||
if index == 0 {
|
||||
tree.State = &DocumentSelected{Selected: true, Opened: true}
|
||||
}
|
||||
tree.DocumentId = item.DocumentId
|
||||
tree.Identify = item.Identify
|
||||
|
@ -50,7 +51,7 @@ func (m *Document) FindDocumentTree(book_id int) ([]*DocumentTree,error){
|
|||
tree.BookIdentify = book.Identify
|
||||
if item.ParentId > 0 {
|
||||
tree.ParentId = item.ParentId
|
||||
}else{
|
||||
} else {
|
||||
tree.ParentId = "#"
|
||||
}
|
||||
|
||||
|
@ -59,41 +60,41 @@ func (m *Document) FindDocumentTree(book_id int) ([]*DocumentTree,error){
|
|||
trees[index] = tree
|
||||
}
|
||||
|
||||
return trees,nil
|
||||
return trees, nil
|
||||
}
|
||||
|
||||
func (m *Document) CreateDocumentTreeForHtml(book_id, selected_id int) (string,error) {
|
||||
trees,err := m.FindDocumentTree(book_id)
|
||||
func (m *Document) CreateDocumentTreeForHtml(book_id, selected_id int) (string, error) {
|
||||
trees, err := m.FindDocumentTree(book_id)
|
||||
if err != nil {
|
||||
return "",err
|
||||
return "", err
|
||||
}
|
||||
parent_id := getSelectedNode(trees,selected_id)
|
||||
parent_id := getSelectedNode(trees, selected_id)
|
||||
|
||||
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
|
||||
func getSelectedNode(array []*DocumentTree, parent_id int) int {
|
||||
|
||||
for _,item := range array {
|
||||
if _,ok := item.ParentId.(string); ok && item.DocumentId == parent_id {
|
||||
for _, item := range array {
|
||||
if _, ok := item.ParentId.(string); ok && item.DocumentId == parent_id {
|
||||
return item.DocumentId
|
||||
}else if pid,ok := item.ParentId.(int); ok && item.DocumentId == parent_id{
|
||||
return getSelectedNode(array,pid)
|
||||
} else if pid, ok := item.ParentId.(int); ok && item.DocumentId == parent_id {
|
||||
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>")
|
||||
|
||||
for _,item := range array {
|
||||
for _, item := range array {
|
||||
pid := 0
|
||||
|
||||
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>")
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -5,16 +5,16 @@ import "errors"
|
|||
|
||||
var (
|
||||
// ErrMemberNoExist 用户不存在.
|
||||
ErrMemberNoExist = errors.New("用户不存在")
|
||||
ErrMemberExist = errors.New("用户已存在")
|
||||
ErrMemberDisabled = errors.New("用户被禁用")
|
||||
ErrMemberEmailEmpty = errors.New("用户邮箱不能为空")
|
||||
ErrMemberEmailExist = errors.New("用户邮箱已被使用")
|
||||
ErrMemberDescriptionTooLong = errors.New("用户描述必须小于500字")
|
||||
ErrMemberEmailFormatError = errors.New("邮箱格式不正确")
|
||||
ErrMemberNoExist = errors.New("用户不存在")
|
||||
ErrMemberExist = errors.New("用户已存在")
|
||||
ErrMemberDisabled = errors.New("用户被禁用")
|
||||
ErrMemberEmailEmpty = errors.New("用户邮箱不能为空")
|
||||
ErrMemberEmailExist = errors.New("用户邮箱已被使用")
|
||||
ErrMemberDescriptionTooLong = errors.New("用户描述必须小于500字")
|
||||
ErrMemberEmailFormatError = errors.New("邮箱格式不正确")
|
||||
ErrMemberPasswordFormatError = errors.New("密码必须在6-50个字符之间")
|
||||
ErrMemberAccountFormatError = errors.New("账号只能由英文字母数字组成,且在3-50个字符")
|
||||
ErrMemberRoleError = errors.New("用户权限不正确")
|
||||
ErrMemberAccountFormatError = errors.New("账号只能由英文字母数字组成,且在3-50个字符")
|
||||
ErrMemberRoleError = errors.New("用户权限不正确")
|
||||
// ErrorMemberPasswordError 密码错误.
|
||||
ErrorMemberPasswordError = errors.New("用户密码错误")
|
||||
//ErrorMemberAuthMethodInvalid 不支持此认证方式
|
||||
|
|
|
@ -1,35 +1,36 @@
|
|||
package models
|
||||
|
||||
import (
|
||||
"github.com/lifei6671/mindoc/conf"
|
||||
"github.com/astaxie/beego/orm"
|
||||
"github.com/lifei6671/mindoc/conf"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Label struct {
|
||||
LabelId int `orm:"column(label_id);pk;auto;unique;" json:"label_id"`
|
||||
LabelName string `orm:"column(label_name);size(50);unique" json:"label_name"`
|
||||
BookNumber int `orm:"column(book_number)" json:"book_number"`
|
||||
LabelId int `orm:"column(label_id);pk;auto;unique;" json:"label_id"`
|
||||
LabelName string `orm:"column(label_name);size(50);unique" json:"label_name"`
|
||||
BookNumber int `orm:"column(book_number)" json:"book_number"`
|
||||
}
|
||||
|
||||
// TableName 获取对应数据库表名.
|
||||
func (m *Label) TableName() string {
|
||||
return "label"
|
||||
}
|
||||
|
||||
// TableEngine 获取数据使用的引擎.
|
||||
func (m *Label) TableEngine() string {
|
||||
return "INNODB"
|
||||
}
|
||||
|
||||
func (m *Label)TableNameWithPrefix() string {
|
||||
return conf.GetDatabasePrefix() + m.TableName()
|
||||
func (m *Label) TableNameWithPrefix() string {
|
||||
return conf.GetDatabasePrefix() + m.TableName()
|
||||
}
|
||||
|
||||
func NewLabel() *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()
|
||||
|
||||
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 {
|
||||
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 {
|
||||
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.LabelName = labelName
|
||||
|
||||
if err == orm.ErrNoRows {
|
||||
err = nil
|
||||
m.LabelName = labelName
|
||||
_,err = o.Insert(m)
|
||||
}else{
|
||||
_,err = o.Update(m)
|
||||
_, err = o.Insert(m)
|
||||
} else {
|
||||
_, err = o.Update(m)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
//批量插入或更新标签.
|
||||
func (m *Label) InsertOrUpdateMulti(labels string) {
|
||||
if labels != "" {
|
||||
func (m *Label) InsertOrUpdateMulti(labels string) {
|
||||
if labels != "" {
|
||||
labelArray := strings.Split(labels, ",")
|
||||
|
||||
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()
|
||||
|
||||
count,err := o.QueryTable(m.TableNameWithPrefix()).Count()
|
||||
count, err := o.QueryTable(m.TableNameWithPrefix()).Count()
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
|
@ -85,8 +86,7 @@ func (m *Label) FindToPager(pageIndex, pageSize int) (labels []*Label,totalCount
|
|||
|
||||
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
|
||||
}
|
||||
|
||||
|
|
|
@ -1,38 +1,39 @@
|
|||
package models
|
||||
|
||||
import (
|
||||
"time"
|
||||
"errors"
|
||||
"github.com/astaxie/beego/orm"
|
||||
"github.com/lifei6671/mindoc/conf"
|
||||
"sync/atomic"
|
||||
"github.com/astaxie/beego/orm"
|
||||
"errors"
|
||||
"time"
|
||||
)
|
||||
|
||||
var loggerQueue = &logQueue{ channel : make(chan *Logger,100),isRuning : 0 }
|
||||
var loggerQueue = &logQueue{channel: make(chan *Logger, 100), isRuning: 0}
|
||||
|
||||
type logQueue struct {
|
||||
channel chan *Logger
|
||||
channel chan *Logger
|
||||
isRuning int32
|
||||
}
|
||||
|
||||
// Logger struct .
|
||||
type Logger struct {
|
||||
LoggerId int64 `orm:"pk;auto;unique;column(log_id)" json:"log_id"`
|
||||
MemberId int `orm:"column(member_id);type(int)" json:"member_id"`
|
||||
LoggerId int64 `orm:"pk;auto;unique;column(log_id)" json:"log_id"`
|
||||
MemberId int `orm:"column(member_id);type(int)" json:"member_id"`
|
||||
// 日志类别:operate 操作日志/ system 系统日志/ exception 异常日志 / document 文档操作日志
|
||||
Category string `orm:"column(category);size(255);default(operate)" json:"category"`
|
||||
Content string `orm:"column(content);type(text)" json:"content"`
|
||||
OriginalData string `orm:"column(original_data);type(text)" json:"original_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"`
|
||||
UserAgent string `orm:"column(user_agent);size(500)" json:"user_agent"`
|
||||
IPAddress string `orm:"column(ip_address);size(255)" json:"ip_address"`
|
||||
Category string `orm:"column(category);size(255);default(operate)" json:"category"`
|
||||
Content string `orm:"column(content);type(text)" json:"content"`
|
||||
OriginalData string `orm:"column(original_data);type(text)" json:"original_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"`
|
||||
UserAgent string `orm:"column(user_agent);size(500)" json:"user_agent"`
|
||||
IPAddress string `orm:"column(ip_address);size(255)" json:"ip_address"`
|
||||
}
|
||||
|
||||
// TableName 获取对应数据库表名.
|
||||
func (m *Logger) TableName() string {
|
||||
return "logs"
|
||||
}
|
||||
|
||||
// TableEngine 获取数据使用的引擎.
|
||||
func (m *Logger) TableEngine() string {
|
||||
return "INNODB"
|
||||
|
@ -57,32 +58,19 @@ func (m *Logger) Add() error {
|
|||
}
|
||||
loggerQueue.channel <- m
|
||||
if atomic.LoadInt32(&(loggerQueue.isRuning)) <= 0 {
|
||||
atomic.AddInt32(&(loggerQueue.isRuning),1)
|
||||
atomic.AddInt32(&(loggerQueue.isRuning), 1)
|
||||
go addLoggerAsync()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func addLoggerAsync() {
|
||||
defer atomic.AddInt32(&(loggerQueue.isRuning),-1)
|
||||
func addLoggerAsync() {
|
||||
defer atomic.AddInt32(&(loggerQueue.isRuning), -1)
|
||||
o := orm.NewOrm()
|
||||
|
||||
for{
|
||||
logger := <- loggerQueue.channel
|
||||
for {
|
||||
logger := <-loggerQueue.channel
|
||||
|
||||
o.Insert(logger)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ import (
|
|||
"github.com/astaxie/beego/orm"
|
||||
"github.com/lifei6671/mindoc/conf"
|
||||
"github.com/lifei6671/mindoc/utils"
|
||||
"math"
|
||||
)
|
||||
|
||||
type Member struct {
|
||||
|
@ -108,7 +109,7 @@ func (m *Member) ldapLogin(account string, password string) (*Member, error) {
|
|||
beego.AppConfig.String("ldap_base"),
|
||||
ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false,
|
||||
//修改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"},
|
||||
nil,
|
||||
)
|
||||
|
@ -279,7 +280,7 @@ func (m *Member) Valid(is_hash_password bool) error {
|
|||
return ErrMemberEmailEmpty
|
||||
}
|
||||
//用户描述必须小于500字
|
||||
if strings.Count(m.Description,"") > 500 {
|
||||
if strings.Count(m.Description, "") > 500 {
|
||||
return ErrMemberDescriptionTooLong
|
||||
}
|
||||
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
|
||||
}
|
||||
//邮箱格式校验
|
||||
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
|
||||
}
|
||||
//如果是未加密密码,需要校验密码格式
|
||||
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
|
||||
}
|
||||
}
|
||||
//校验邮箱是否呗使用
|
||||
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 {
|
||||
return ErrMemberEmailExist
|
||||
}
|
||||
if m.MemberId <= 0{
|
||||
return ErrMemberEmailExist
|
||||
if m.MemberId <= 0 {
|
||||
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
|
||||
}
|
||||
}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
|
||||
}
|
||||
//校验账号是否被使用
|
||||
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 nil
|
||||
}
|
||||
|
||||
//删除一个用户.
|
||||
|
||||
func (m *Member) Delete(oldId int,newId int) error {
|
||||
func (m *Member) Delete(oldId int, newId int) error {
|
||||
o := orm.NewOrm()
|
||||
|
||||
err := o.Begin()
|
||||
|
@ -339,39 +339,39 @@ func (m *Member) Delete(oldId int,newId int) error {
|
|||
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 {
|
||||
o.Rollback()
|
||||
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 {
|
||||
o.Rollback()
|
||||
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 {
|
||||
o.Rollback()
|
||||
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 {
|
||||
o.Rollback()
|
||||
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 {
|
||||
o.Rollback()
|
||||
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 {
|
||||
o.Rollback()
|
||||
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 {
|
||||
o.Rollback()
|
||||
return err
|
||||
|
@ -386,53 +386,37 @@ func (m *Member) Delete(oldId int,newId int) error {
|
|||
//}
|
||||
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 {
|
||||
for _,relationship := range relationship_list {
|
||||
for _, relationship := range relationship_list {
|
||||
//如果存在创始人,则删除
|
||||
if relationship.RoleId == 0 {
|
||||
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 := o.Delete(relationship) ; err != nil{
|
||||
if _, err := o.Delete(relationship); err != nil {
|
||||
beego.Error(err)
|
||||
}
|
||||
relationship.RelationshipId = rel.RelationshipId
|
||||
}
|
||||
relationship.MemberId = newId
|
||||
relationship.RoleId = 0
|
||||
if _,err := o.Update(relationship) ; err != nil{
|
||||
if _, err := o.Update(relationship); err != nil {
|
||||
beego.Error(err)
|
||||
}
|
||||
}else{
|
||||
if _,err := o.Delete(relationship) ; err != nil{
|
||||
} else {
|
||||
if _, err := o.Delete(relationship); err != nil {
|
||||
beego.Error(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err = o.Commit();err != nil {
|
||||
if err = o.Commit(); err != nil {
|
||||
o.Rollback()
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,27 +1,27 @@
|
|||
package models
|
||||
|
||||
import (
|
||||
"time"
|
||||
"github.com/astaxie/beego/orm"
|
||||
"github.com/lifei6671/mindoc/conf"
|
||||
"time"
|
||||
)
|
||||
|
||||
type MemberRelationshipResult struct {
|
||||
MemberId int `json:"member_id"`
|
||||
Account string `json:"account"`
|
||||
Description string `json:"description"`
|
||||
Email string `json:"email"`
|
||||
Phone string `json:"phone"`
|
||||
Avatar string `json:"avatar"`
|
||||
Role int `json:"role"` //用户角色:0 管理员/ 1 普通用户
|
||||
Status int `json:"status"` //用户状态:0 正常/1 禁用
|
||||
CreateTime time.Time `json:"create_time"`
|
||||
CreateAt int `json:"create_at"`
|
||||
RelationshipId int `json:"relationship_id"`
|
||||
BookId int `json:"book_id"`
|
||||
MemberId int `json:"member_id"`
|
||||
Account string `json:"account"`
|
||||
Description string `json:"description"`
|
||||
Email string `json:"email"`
|
||||
Phone string `json:"phone"`
|
||||
Avatar string `json:"avatar"`
|
||||
Role int `json:"role"` //用户角色:0 管理员/ 1 普通用户
|
||||
Status int `json:"status"` //用户状态:0 正常/1 禁用
|
||||
CreateTime time.Time `json:"create_time"`
|
||||
CreateAt int `json:"create_at"`
|
||||
RelationshipId int `json:"relationship_id"`
|
||||
BookId int `json:"book_id"`
|
||||
// RoleId 角色:0 创始人(创始人不能被移除) / 1 管理员/2 编辑者/3 观察者
|
||||
RoleId int `json:"role_id"`
|
||||
RoleName string `json:"role_name"`
|
||||
RoleId int `json:"role_id"`
|
||||
RoleName string `json:"role_name"`
|
||||
}
|
||||
|
||||
func NewMemberRelationshipResult() *MemberRelationshipResult {
|
||||
|
@ -43,18 +43,18 @@ func (m *MemberRelationshipResult) FromMember(member *Member) *MemberRelationshi
|
|||
return m
|
||||
}
|
||||
|
||||
func (m *MemberRelationshipResult) ResolveRoleName () *MemberRelationshipResult {
|
||||
func (m *MemberRelationshipResult) ResolveRoleName() *MemberRelationshipResult {
|
||||
if m.RoleId == conf.BookAdmin {
|
||||
m.RoleName = "管理者"
|
||||
}else if m.RoleId == conf.BookEditor {
|
||||
} else if m.RoleId == conf.BookEditor {
|
||||
m.RoleName = "编辑者"
|
||||
}else if m.RoleId == conf.BookObserver {
|
||||
} else if m.RoleId == conf.BookObserver {
|
||||
m.RoleName = "观察者"
|
||||
}
|
||||
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()
|
||||
|
||||
var members []*MemberRelationshipResult
|
||||
|
@ -65,28 +65,22 @@ func (m *MemberRelationshipResult) FindForUsersByBookId(book_id ,pageIndex, page
|
|||
|
||||
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 {
|
||||
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 {
|
||||
return members,0,err
|
||||
return members, 0, err
|
||||
}
|
||||
|
||||
for _,item := range members {
|
||||
for _, item := range members {
|
||||
item.ResolveRoleName()
|
||||
}
|
||||
return members,total_count,nil
|
||||
return members, total_count, nil
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,66 +1,66 @@
|
|||
package models
|
||||
|
||||
import (
|
||||
"time"
|
||||
"github.com/lifei6671/mindoc/conf"
|
||||
"github.com/astaxie/beego/orm"
|
||||
"github.com/lifei6671/mindoc/conf"
|
||||
"time"
|
||||
)
|
||||
|
||||
type MemberToken struct {
|
||||
TokenId int `orm:"column(token_id);pk;auto;unique" json:"token_id"`
|
||||
MemberId int `orm:"column(member_id);type(int)" json:"member_id"`
|
||||
Token string `orm:"column(token);size(150);index" json:"token"`
|
||||
Email string `orm:"column(email);size(255)" json:"email"`
|
||||
IsValid bool `orm:"column(is_valid)" json:"is_valid"`
|
||||
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"`
|
||||
TokenId int `orm:"column(token_id);pk;auto;unique" json:"token_id"`
|
||||
MemberId int `orm:"column(member_id);type(int)" json:"member_id"`
|
||||
Token string `orm:"column(token);size(150);index" json:"token"`
|
||||
Email string `orm:"column(email);size(255)" json:"email"`
|
||||
IsValid bool `orm:"column(is_valid)" json:"is_valid"`
|
||||
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"`
|
||||
}
|
||||
|
||||
|
||||
// TableName 获取对应数据库表名.
|
||||
func (m *MemberToken) TableName() string {
|
||||
return "member_token"
|
||||
}
|
||||
|
||||
// TableEngine 获取数据使用的引擎.
|
||||
func (m *MemberToken) TableEngine() string {
|
||||
return "INNODB"
|
||||
}
|
||||
|
||||
func (m *MemberToken)TableNameWithPrefix() string {
|
||||
return conf.GetDatabasePrefix() + m.TableName()
|
||||
func (m *MemberToken) TableNameWithPrefix() string {
|
||||
return conf.GetDatabasePrefix() + m.TableName()
|
||||
}
|
||||
|
||||
func NewMemberToken() *MemberToken {
|
||||
return &MemberToken{}
|
||||
}
|
||||
|
||||
func (m *MemberToken) InsertOrUpdate() (*MemberToken,error){
|
||||
func (m *MemberToken) InsertOrUpdate() (*MemberToken, error) {
|
||||
o := orm.NewOrm()
|
||||
|
||||
if m.TokenId > 0 {
|
||||
_,err := o.Update(m)
|
||||
return m,err
|
||||
_, err := o.Update(m)
|
||||
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()
|
||||
|
||||
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()
|
||||
|
||||
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 {
|
||||
return 0,err
|
||||
return 0, err
|
||||
}
|
||||
return int(c),nil
|
||||
}
|
||||
return int(c), nil
|
||||
}
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
package models
|
||||
|
||||
import (
|
||||
"time"
|
||||
"github.com/lifei6671/mindoc/conf"
|
||||
"github.com/astaxie/beego/orm"
|
||||
"github.com/lifei6671/mindoc/conf"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Migration struct {
|
||||
MigrationId int `orm:"column(migration_id);pk;auto;unique;" json:"migration_id"`
|
||||
Name string `orm:"column(name);size(500)" json:"name"`
|
||||
Statements string `orm:"column(statements);type(text);null" json:"statements"`
|
||||
Status string `orm:"column(status);default(update)" json:"status"`
|
||||
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"`
|
||||
MigrationId int `orm:"column(migration_id);pk;auto;unique;" json:"migration_id"`
|
||||
Name string `orm:"column(name);size(500)" json:"name"`
|
||||
Statements string `orm:"column(statements);type(text);null" json:"statements"`
|
||||
Status string `orm:"column(status);default(update)" json:"status"`
|
||||
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"`
|
||||
}
|
||||
|
||||
// TableName 获取对应数据库表名.
|
||||
|
@ -33,10 +33,10 @@ func NewMigration() *Migration {
|
|||
return &Migration{}
|
||||
}
|
||||
|
||||
func (m *Migration) FindFirst() (*Migration,error) {
|
||||
func (m *Migration) FindFirst() (*Migration, error) {
|
||||
o := orm.NewOrm()
|
||||
|
||||
err := o.QueryTable(m.TableNameWithPrefix()).OrderBy("-migration_id").One(m)
|
||||
|
||||
return m,err
|
||||
}
|
||||
return m, err
|
||||
}
|
||||
|
|
|
@ -5,147 +5,145 @@ import (
|
|||
"github.com/lifei6671/mindoc/conf"
|
||||
)
|
||||
|
||||
|
||||
// Option struct .
|
||||
type Option struct {
|
||||
OptionId int `orm:"column(option_id);pk;auto;unique;" json:"option_id"`
|
||||
OptionTitle string `orm:"column(option_title);size(500)" json:"option_title"`
|
||||
OptionName string `orm:"column(option_name);unique;size(80)" json:"option_name"`
|
||||
OptionValue string `orm:"column(option_value);type(text);null" json:"option_value"`
|
||||
Remark string `orm:"column(remark);type(text);null" json:"remark"`
|
||||
OptionId int `orm:"column(option_id);pk;auto;unique;" json:"option_id"`
|
||||
OptionTitle string `orm:"column(option_title);size(500)" json:"option_title"`
|
||||
OptionName string `orm:"column(option_name);unique;size(80)" json:"option_name"`
|
||||
OptionValue string `orm:"column(option_value);type(text);null" json:"option_value"`
|
||||
Remark string `orm:"column(remark);type(text);null" json:"remark"`
|
||||
}
|
||||
|
||||
// TableName 获取对应数据库表名.
|
||||
func (m *Option) TableName() string {
|
||||
return "options"
|
||||
}
|
||||
|
||||
// TableEngine 获取数据使用的引擎.
|
||||
func (m *Option) TableEngine() string {
|
||||
return "INNODB"
|
||||
}
|
||||
|
||||
func (m *Option)TableNameWithPrefix() string {
|
||||
return conf.GetDatabasePrefix() + m.TableName()
|
||||
func (m *Option) TableNameWithPrefix() string {
|
||||
return conf.GetDatabasePrefix() + m.TableName()
|
||||
}
|
||||
|
||||
|
||||
func NewOption() *Option {
|
||||
func NewOption() *Option {
|
||||
return &Option{}
|
||||
}
|
||||
|
||||
func (p *Option) Find(id int) (*Option,error) {
|
||||
func (p *Option) Find(id int) (*Option, error) {
|
||||
o := orm.NewOrm()
|
||||
|
||||
p.OptionId = id
|
||||
|
||||
if err := o.Read(p);err != nil {
|
||||
return p,err
|
||||
if err := o.Read(p); err != nil {
|
||||
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()
|
||||
|
||||
p.OptionName = key
|
||||
if err := o.Read(p);err != nil {
|
||||
return p,err
|
||||
if err := o.Read(p); err != nil {
|
||||
return p, err
|
||||
}
|
||||
return p,nil
|
||||
return p, nil
|
||||
}
|
||||
|
||||
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 def
|
||||
}
|
||||
|
||||
func (p *Option) InsertOrUpdate() error {
|
||||
func (p *Option) InsertOrUpdate() error {
|
||||
|
||||
o := orm.NewOrm()
|
||||
|
||||
var err error
|
||||
|
||||
|
||||
if p.OptionId > 0 || o.QueryTable(p.TableNameWithPrefix()).Filter("option_name",p.OptionName).Exist() {
|
||||
_,err = o.Update(p)
|
||||
}else{
|
||||
_,err = o.Insert(p)
|
||||
if p.OptionId > 0 || o.QueryTable(p.TableNameWithPrefix()).Filter("option_name", p.OptionName).Exist() {
|
||||
_, err = o.Update(p)
|
||||
} else {
|
||||
_, err = o.Insert(p)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (p *Option) InsertMulti(option... Option ) (error){
|
||||
func (p *Option) InsertMulti(option ...Option) error {
|
||||
|
||||
o := orm.NewOrm()
|
||||
|
||||
_,err := o.InsertMulti(len(option),option)
|
||||
_, err := o.InsertMulti(len(option), option)
|
||||
return err
|
||||
}
|
||||
|
||||
func (p *Option) All() ([]*Option,error) {
|
||||
func (p *Option) All() ([]*Option, error) {
|
||||
o := orm.NewOrm()
|
||||
var options []*Option
|
||||
|
||||
_,err := o.QueryTable(p.TableNameWithPrefix()).All(&options)
|
||||
_, err := o.QueryTable(p.TableNameWithPrefix()).All(&options)
|
||||
|
||||
if err != nil {
|
||||
return options,err
|
||||
return options, err
|
||||
}
|
||||
return options,nil
|
||||
return options, nil
|
||||
}
|
||||
|
||||
func (m *Option) Init() error {
|
||||
|
||||
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.OptionValue = "false"
|
||||
option.OptionName = "ENABLED_REGISTER"
|
||||
option.OptionTitle = "是否启用注册"
|
||||
if _,err := o.Insert(option);err != nil {
|
||||
if _, err := o.Insert(option); err != nil {
|
||||
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.OptionValue = "true"
|
||||
option.OptionName = "ENABLE_DOCUMENT_HISTORY"
|
||||
option.OptionTitle = "是否启用文档历史"
|
||||
if _,err := o.Insert(option);err != nil {
|
||||
if _, err := o.Insert(option); err != nil {
|
||||
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.OptionValue = "true"
|
||||
option.OptionName = "ENABLED_CAPTCHA"
|
||||
option.OptionTitle = "是否启用验证码"
|
||||
if _,err := o.Insert(option);err != nil {
|
||||
if _, err := o.Insert(option); err != nil {
|
||||
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.OptionValue = "false"
|
||||
option.OptionName = "ENABLE_ANONYMOUS"
|
||||
option.OptionTitle = "启用匿名访问"
|
||||
if _,err := o.Insert(option);err != nil {
|
||||
if _, err := o.Insert(option); err != nil {
|
||||
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.OptionValue = "MinDoc"
|
||||
option.OptionName = "SITE_NAME"
|
||||
option.OptionTitle = "站点名称"
|
||||
if _,err := o.Insert(option);err != nil {
|
||||
if _, err := o.Insert(option); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,21 +1,20 @@
|
|||
package models
|
||||
|
||||
import (
|
||||
"github.com/lifei6671/mindoc/conf"
|
||||
"github.com/astaxie/beego/orm"
|
||||
"errors"
|
||||
"github.com/astaxie/beego/logs"
|
||||
"github.com/astaxie/beego/orm"
|
||||
"github.com/lifei6671/mindoc/conf"
|
||||
)
|
||||
|
||||
type Relationship struct {
|
||||
RelationshipId int `orm:"pk;auto;unique;column(relationship_id)" json:"relationship_id"`
|
||||
MemberId int `orm:"column(member_id);type(int)" json:"member_id"`
|
||||
BookId int `orm:"column(book_id);type(int)" json:"book_id"`
|
||||
RelationshipId int `orm:"pk;auto;unique;column(relationship_id)" json:"relationship_id"`
|
||||
MemberId int `orm:"column(member_id);type(int)" json:"member_id"`
|
||||
BookId int `orm:"column(book_id);type(int)" json:"book_id"`
|
||||
// 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 获取对应数据库表名.
|
||||
func (m *Relationship) TableName() string {
|
||||
return "relationship"
|
||||
|
@ -40,97 +39,97 @@ func NewRelationship() *Relationship {
|
|||
return &Relationship{}
|
||||
}
|
||||
|
||||
func (m *Relationship) Find(id int) (*Relationship,error) {
|
||||
func (m *Relationship) Find(id int) (*Relationship, error) {
|
||||
o := orm.NewOrm()
|
||||
|
||||
err := o.QueryTable(m.TableNameWithPrefix()).Filter("relationship_id",id).One(m)
|
||||
return m,err
|
||||
err := o.QueryTable(m.TableNameWithPrefix()).Filter("relationship_id", id).One(m)
|
||||
return m, err
|
||||
}
|
||||
|
||||
//查询指定项目的创始人.
|
||||
func (m *Relationship) FindFounder(book_id int) (*Relationship,error) {
|
||||
func (m *Relationship) FindFounder(book_id int) (*Relationship, error) {
|
||||
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()
|
||||
book := NewBook()
|
||||
book.BookId = book_id
|
||||
|
||||
if err := o.Read(book); err != nil {
|
||||
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 {
|
||||
m = NewRelationship()
|
||||
m.BookId = book_id
|
||||
m.MemberId = member_id
|
||||
m.RoleId = role_id
|
||||
}else if err != nil {
|
||||
return m,err
|
||||
}else if m.RoleId == conf.BookFounder{
|
||||
return m,errors.New("不能变更创始人的权限")
|
||||
} else if err != nil {
|
||||
return m, err
|
||||
} else if m.RoleId == conf.BookFounder {
|
||||
return m, errors.New("不能变更创始人的权限")
|
||||
}
|
||||
m.RoleId = role_id
|
||||
|
||||
if m.RelationshipId > 0 {
|
||||
_,err = o.Update(m)
|
||||
}else{
|
||||
_,err = o.Insert(m)
|
||||
_, err = o.Update(m)
|
||||
} else {
|
||||
_, 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()
|
||||
|
||||
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 {
|
||||
|
||||
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()
|
||||
|
||||
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()
|
||||
|
||||
_,err := o.Insert(m)
|
||||
_, err := o.Insert(m)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (m *Relationship) Update() error {
|
||||
func (m *Relationship) Update() error {
|
||||
o := orm.NewOrm()
|
||||
|
||||
_,err := o.Update(m)
|
||||
_, err := o.Update(m)
|
||||
|
||||
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()
|
||||
|
||||
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 {
|
||||
return errors.New("用户未参与该项目")
|
||||
|
@ -138,22 +137,22 @@ func (m *Relationship) DeleteByBookIdAndMemberId(book_id,member_id int) error {
|
|||
if m.RoleId == conf.BookFounder {
|
||||
return errors.New("不能删除创始人")
|
||||
}
|
||||
_,err = o.Delete(m)
|
||||
_, err = o.Delete(m)
|
||||
|
||||
if err != nil {
|
||||
logs.Error("删除项目参与者 => ",err)
|
||||
logs.Error("删除项目参与者 => ", err)
|
||||
return errors.New("删除失败")
|
||||
}
|
||||
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()
|
||||
|
||||
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 {
|
||||
return err
|
||||
|
@ -163,7 +162,7 @@ func (m *Relationship) Transfer(book_id,founder_id,receive_id int) error {
|
|||
}
|
||||
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 {
|
||||
return err
|
||||
|
@ -176,17 +175,17 @@ func (m *Relationship) Transfer(book_id,founder_id,receive_id int) error {
|
|||
receive.RoleId = conf.BookFounder
|
||||
receive.BookId = book_id
|
||||
|
||||
if err := founder.Update();err != nil {
|
||||
if err := founder.Update(); err != nil {
|
||||
o.Rollback()
|
||||
return err
|
||||
}
|
||||
if receive.RelationshipId > 0 {
|
||||
if _,err := o.Update(receive);err != nil {
|
||||
if _, err := o.Update(receive); err != nil {
|
||||
o.Rollback()
|
||||
return err
|
||||
}
|
||||
}else{
|
||||
if _,err := o.Insert(receive);err != nil {
|
||||
} else {
|
||||
if _, err := o.Insert(receive); err != nil {
|
||||
o.Rollback()
|
||||
return err
|
||||
}
|
||||
|
@ -194,24 +193,3 @@ func (m *Relationship) Transfer(book_id,founder_id,receive_id int) error {
|
|||
|
||||
return o.Commit()
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,43 +1,45 @@
|
|||
package routers
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/astaxie/beego"
|
||||
"github.com/astaxie/beego/context"
|
||||
"github.com/lifei6671/mindoc/conf"
|
||||
"github.com/lifei6671/mindoc/models"
|
||||
"encoding/json"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
func init() {
|
||||
func init() {
|
||||
var FilterUser = func(ctx *context.Context) {
|
||||
_, ok := ctx.Input.Session(conf.LoginSessionName).(models.Member)
|
||||
|
||||
if !ok {
|
||||
if ctx.Input.IsAjax() {
|
||||
jsonData := make(map[string]interface{},3)
|
||||
jsonData := make(map[string]interface{}, 3)
|
||||
|
||||
jsonData["errcode"] = 403
|
||||
jsonData["message"] = "请登录后再操作"
|
||||
|
||||
returnJSON, _ := json.Marshal(jsonData)
|
||||
|
||||
ctx.ResponseWriter.Write(returnJSON)
|
||||
}else{
|
||||
ctx.Redirect(302, beego.URLFor("AccountController.Login"))
|
||||
} else {
|
||||
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("/setting",beego.BeforeRouter,FilterUser)
|
||||
beego.InsertFilter("/setting/*",beego.BeforeRouter,FilterUser)
|
||||
beego.InsertFilter("/book",beego.BeforeRouter,FilterUser)
|
||||
beego.InsertFilter("/book/*",beego.BeforeRouter,FilterUser)
|
||||
beego.InsertFilter("/api/*",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("/book", beego.BeforeRouter, FilterUser)
|
||||
beego.InsertFilter("/book/*", beego.BeforeRouter, FilterUser)
|
||||
beego.InsertFilter("/api/*", beego.BeforeRouter, FilterUser)
|
||||
|
||||
var FinishRouter = func(ctx *context.Context) {
|
||||
ctx.ResponseWriter.Header().Add("MinDoc-Version",conf.VERSION)
|
||||
ctx.ResponseWriter.Header().Add("MinDoc-Site","http://www.iminho.me")
|
||||
ctx.ResponseWriter.Header().Add("MinDoc-Version", conf.VERSION)
|
||||
ctx.ResponseWriter.Header().Add("MinDoc-Site", "https://www.iminho.me")
|
||||
}
|
||||
|
||||
beego.InsertFilter("/*",beego.BeforeRouter ,FinishRouter, false)
|
||||
beego.InsertFilter("/*", beego.BeforeRouter, FinishRouter, false)
|
||||
}
|
||||
|
|
|
@ -141,7 +141,6 @@ $(function () {
|
|||
$.get(window.editURL + $node.node.id ).done(function (res) {
|
||||
layer.close(index);
|
||||
|
||||
resetEditor();
|
||||
if (res.errcode === 0) {
|
||||
window.isLoad = true;
|
||||
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 };
|
||||
pushDocumentCategory(node);
|
||||
console.log(node);
|
||||
window.selectNode = node;
|
||||
pushVueLists(res.data.attach);
|
||||
} else {
|
||||
|
|
|
@ -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)))
|
||||
}
|
|
@ -1,15 +1,15 @@
|
|||
package utils
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"os"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"io"
|
||||
"math"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func AbsolutePath(p string) (string,error) {
|
||||
func AbsolutePath(p string) (string, error) {
|
||||
|
||||
if strings.HasPrefix(p, "~") {
|
||||
home := os.Getenv("HOME")
|
||||
|
@ -21,9 +21,9 @@ func AbsolutePath(p string) (string,error) {
|
|||
s, err := filepath.Abs(p)
|
||||
|
||||
if nil != err {
|
||||
return "",err
|
||||
return "", err
|
||||
}
|
||||
return s,nil
|
||||
return s, nil
|
||||
}
|
||||
|
||||
// FileExists reports whether the named file or directory exists.
|
||||
|
@ -58,18 +58,13 @@ func FormatBytes(size int64) string {
|
|||
|
||||
i := 0
|
||||
|
||||
for ; s >= 1024 && i < 4 ; i ++ {
|
||||
for ; s >= 1024 && i < 4; i++ {
|
||||
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 {
|
||||
var t float64
|
||||
f := math.Pow10(places)
|
||||
|
@ -97,12 +92,3 @@ func Round(val float64, places int) float64 {
|
|||
|
||||
return t
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
18
utils/gob.go
18
utils/gob.go
|
@ -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)
|
||||
|
||||
return dec.Decode(r);
|
||||
return dec.Decode(r)
|
||||
}
|
||||
|
||||
//编码
|
||||
func Encode(value interface{}) (string,error) {
|
||||
network:= bytes.NewBuffer(nil);
|
||||
func Encode(value interface{}) (string, error) {
|
||||
network := bytes.NewBuffer(nil)
|
||||
|
||||
enc := gob.NewEncoder(network)
|
||||
|
||||
err := enc.Encode(value);
|
||||
err := enc.Encode(value)
|
||||
if err != nil {
|
||||
return "",err;
|
||||
return "", err
|
||||
}
|
||||
|
||||
return network.String(),nil;
|
||||
}
|
||||
return network.String(), nil
|
||||
}
|
||||
|
|
|
@ -1,16 +1,15 @@
|
|||
package utils
|
||||
|
||||
import (
|
||||
"time"
|
||||
"math/rand"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
||||
const (
|
||||
KC_RAND_KIND_NUM = 0 // 纯数字
|
||||
KC_RAND_KIND_LOWER = 1 // 小写字母
|
||||
KC_RAND_KIND_UPPER = 2 // 大写字母
|
||||
KC_RAND_KIND_ALL = 3 // 数字、大小写字母
|
||||
KC_RAND_KIND_NUM = 0 // 纯数字
|
||||
KC_RAND_KIND_LOWER = 1 // 小写字母
|
||||
KC_RAND_KIND_UPPER = 2 // 大写字母
|
||||
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)
|
||||
is_all := kind > 2 || kind < 0
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
for i :=0; i < size; i++ {
|
||||
for i := 0; i < size; i++ {
|
||||
if is_all { // random ikind
|
||||
ikind = rand.Intn(3)
|
||||
}
|
||||
scope, base := kinds[ikind][0], kinds[ikind][1]
|
||||
result[i] = uint8(base+rand.Intn(scope))
|
||||
result[i] = uint8(base + rand.Intn(scope))
|
||||
}
|
||||
|
||||
return result
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
package utils
|
||||
|
||||
import (
|
||||
"gopkg.in/ldap.v2"
|
||||
"fmt"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/astaxie/beego"
|
||||
"gopkg.in/ldap.v2"
|
||||
)
|
||||
|
||||
/*
|
||||
对应的config
|
||||
ldap:
|
||||
|
@ -23,20 +24,20 @@ func ValidLDAPLogin(password string) (result bool, err error) {
|
|||
err = nil
|
||||
lc, err := ldap.Dial("tcp", fmt.Sprintf("%s:%d", "192.168.3.104", 389))
|
||||
if err != nil {
|
||||
beego.Error("Dial => ",err)
|
||||
beego.Error("Dial => ", err)
|
||||
return
|
||||
}
|
||||
|
||||
defer lc.Close()
|
||||
err = lc.Bind("cn=admin,dc=minho,dc=com", "123456")
|
||||
if err != nil {
|
||||
beego.Error("Bind => ",err)
|
||||
beego.Error("Bind => ", err)
|
||||
return
|
||||
}
|
||||
searchRequest := ldap.NewSearchRequest(
|
||||
"DC=minho,DC=com",
|
||||
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"},
|
||||
nil,
|
||||
)
|
||||
|
@ -49,7 +50,7 @@ func ValidLDAPLogin(password string) (result bool, err error) {
|
|||
err = errors.New("ldap.no_user_found_or_many_users_found")
|
||||
return
|
||||
}
|
||||
fmt.Printf("%+v = %d",searchResult.Entries,len(searchResult.Entries))
|
||||
fmt.Printf("%+v = %d", searchResult.Entries, len(searchResult.Entries))
|
||||
|
||||
userdn := searchResult.Entries[0].DN
|
||||
|
||||
|
@ -57,7 +58,7 @@ func ValidLDAPLogin(password string) (result bool, err error) {
|
|||
if err == nil {
|
||||
result = true
|
||||
} else {
|
||||
beego.Error("Bind2 => ",err)
|
||||
beego.Error("Bind2 => ", err)
|
||||
err = nil
|
||||
}
|
||||
return
|
||||
|
@ -66,12 +67,12 @@ func ValidLDAPLogin(password string) (result bool, err error) {
|
|||
func AddMember(account, password string) error {
|
||||
lc, err := ldap.Dial("tcp", fmt.Sprintf("%s:%d", "192.168.3.104", 389))
|
||||
if err != nil {
|
||||
beego.Error("Dial => ",err)
|
||||
beego.Error("Dial => ", err)
|
||||
return err
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
|
@ -81,35 +82,35 @@ func AddMember(account, password string) error {
|
|||
|
||||
if err == nil {
|
||||
|
||||
err = lc.Bind(user,"")
|
||||
err = lc.Bind(user, "")
|
||||
if err != nil {
|
||||
beego.Error("Bind => ",err)
|
||||
beego.Error("Bind => ", err)
|
||||
return err
|
||||
}
|
||||
passwordModifyRequest := ldap.NewPasswordModifyRequest(user, "", "1q2w3e__ABC")
|
||||
_, err = lc.PasswordModify(passwordModifyRequest)
|
||||
|
||||
if err != nil {
|
||||
beego.Error("PasswordModify => ",err)
|
||||
beego.Error("PasswordModify => ", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
beego.Error("Add => ",err)
|
||||
beego.Error("Add => ", err)
|
||||
return err
|
||||
}
|
||||
|
||||
func ModifyPassword(account, old_password, new_password string) error {
|
||||
l, err := ldap.Dial("tcp", fmt.Sprintf("%s:%d", "192.168.3.104", 389))
|
||||
if err != nil {
|
||||
beego.Error("Dial => ",err)
|
||||
beego.Error("Dial => ", err)
|
||||
}
|
||||
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)
|
||||
if err != nil {
|
||||
beego.Error("Bind => ",err)
|
||||
beego.Error("Bind => ", err)
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -122,15 +123,3 @@ func ModifyPassword(account, old_password, new_password string) error {
|
|||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
108
utils/pager.go
108
utils/pager.go
|
@ -6,8 +6,8 @@ import (
|
|||
con "strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/astaxie/beego/orm"
|
||||
"fmt"
|
||||
"github.com/astaxie/beego/orm"
|
||||
"math"
|
||||
)
|
||||
|
||||
|
@ -25,7 +25,7 @@ type PageOptions struct {
|
|||
NextPageText string //下一页文字 默认"下一页"
|
||||
EnableFirstLastLink 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
|
||||
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) //获取总条数
|
||||
if totalItem <= pagesize {
|
||||
totalpages = 1
|
||||
|
@ -58,22 +58,22 @@ func GetPagesInfo(tableName string, currentpage int, pagesize int, conditions st
|
|||
}
|
||||
|
||||
/**
|
||||
* 返回总记录条数,总页数,当前页面数据,分页html
|
||||
* 根据分页选项,生成分页连接 下面是一个实例:
|
||||
func (this *MainController) Test() {
|
||||
var po util.PageOptions
|
||||
po.EnablePreNexLink = true
|
||||
po.EnableFirstLastLink = true
|
||||
po.LinkItemCount = 7
|
||||
po.TableName = "help_topic"
|
||||
cp, _ := this.GetInt("pno")
|
||||
po.CurrentPage = int(cp)
|
||||
_,_,_ pager := util.GetPagerLinks(&po, this.Ctx)
|
||||
this.Data["Email"] = html.HTML(pager)
|
||||
this.TplName = "test.html"
|
||||
}
|
||||
* 返回总记录条数,总页数,当前页面数据,分页html
|
||||
* 根据分页选项,生成分页连接 下面是一个实例:
|
||||
func (this *MainController) Test() {
|
||||
var po util.PageOptions
|
||||
po.EnablePreNexLink = true
|
||||
po.EnableFirstLastLink = true
|
||||
po.LinkItemCount = 7
|
||||
po.TableName = "help_topic"
|
||||
cp, _ := this.GetInt("pno")
|
||||
po.CurrentPage = int(cp)
|
||||
_,_,_ pager := util.GetPagerLinks(&po, this.Ctx)
|
||||
this.Data["Email"] = html.HTML(pager)
|
||||
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 := ""
|
||||
totalItem, totalpages, rs := GetPagesInfo(po.TableName, po.CurrentPage, po.PageSize, po.Conditions)
|
||||
po = setDefault(po, totalpages)
|
||||
|
@ -84,7 +84,7 @@ func GetPagerLinks(po *PageOptions,requestURI string) (int, int, orm.RawSeter, h
|
|||
if po.CurrentPage < po.LinkItemCount {
|
||||
str = fun2(po, totalpages) //123456789...200
|
||||
} else {
|
||||
if po.CurrentPage + po.LinkItemCount < totalpages {
|
||||
if po.CurrentPage+po.LinkItemCount < totalpages {
|
||||
str = fun3(po, totalpages)
|
||||
} else {
|
||||
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)
|
||||
}
|
||||
|
||||
func GetPagerHtml(requestURI string,pageIndex, pageSize,totalCount int) (html.HTML){
|
||||
func GetPagerHtml(requestURI string, pageIndex, pageSize, totalCount int) html.HTML {
|
||||
po := &PageOptions{
|
||||
CurrentPage: pageIndex,
|
||||
PageSize: pageSize,
|
||||
EnableFirstLastLink : true,
|
||||
ParamName : "page",
|
||||
TotalPages:int(math.Ceil(float64(totalCount) / float64(pageSize))),
|
||||
CurrentPage: pageIndex,
|
||||
PageSize: pageSize,
|
||||
EnableFirstLastLink: true,
|
||||
ParamName: "page",
|
||||
TotalPages: int(math.Ceil(float64(totalCount) / float64(pageSize))),
|
||||
LinkItemCount: pageSize,
|
||||
}
|
||||
totalPages := int(math.Ceil(float64(totalCount) / float64(pageSize)))
|
||||
|
||||
setDefault(po,totalPages)
|
||||
DealUri(po,requestURI)
|
||||
setDefault(po, totalPages)
|
||||
DealUri(po, requestURI)
|
||||
str := ""
|
||||
if totalPages <= po.LinkItemCount {
|
||||
str = fun1(po, totalPages) //显示完全 12345678910
|
||||
|
@ -113,16 +114,16 @@ func GetPagerHtml(requestURI string,pageIndex, pageSize,totalCount int) (html.HT
|
|||
if po.CurrentPage < po.LinkItemCount {
|
||||
str = fun2(po, totalPages) //123456789...200
|
||||
} else {
|
||||
if po.CurrentPage + po.LinkItemCount < totalPages {
|
||||
if po.CurrentPage+po.LinkItemCount < totalPages {
|
||||
str = fun3(po, totalPages)
|
||||
} else {
|
||||
str = fun4(po, totalPages)
|
||||
}
|
||||
}
|
||||
}
|
||||
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], "&")
|
||||
for _, v := range arr2 {
|
||||
if !strings.Contains(v, po.ParamName) {
|
||||
if strings.HasSuffix(rs,"&") {
|
||||
rs += v
|
||||
}else{
|
||||
rs += v + "&"
|
||||
if strings.HasSuffix(rs, "&") {
|
||||
rs += v
|
||||
} else {
|
||||
rs += v + "&"
|
||||
}
|
||||
//rs += "&" + v
|
||||
}
|
||||
}
|
||||
if strings.HasPrefix(rs,"&") {
|
||||
if strings.HasPrefix(rs, "&") {
|
||||
rs = string(rs[1:])
|
||||
}
|
||||
if strings.HasSuffix(rs,"&"){
|
||||
rs = string(rs[0:strings.Count(rs,"")-1])
|
||||
if strings.HasSuffix(rs, "&") {
|
||||
rs = string(rs[0 : strings.Count(rs, "")-1])
|
||||
}
|
||||
rs = arr[0] + "?" + rs
|
||||
fmt.Println(rs)
|
||||
|
@ -167,8 +168,11 @@ func fun4(po *PageOptions, totalPages int) string {
|
|||
rs := ""
|
||||
rs += getHeader(po, totalPages)
|
||||
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 {
|
||||
rs += "<li><a href='" + po.Href + "&" + po.ParamName + "=" + con.Itoa(i) + "'>" + con.Itoa(i) + "</a></li>"
|
||||
} else {
|
||||
|
@ -187,15 +191,15 @@ func fun3(po *PageOptions, totalpages int) string {
|
|||
var rs string = ""
|
||||
rs += getHeader(po, totalpages)
|
||||
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++ {
|
||||
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 {
|
||||
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 += getFooter(po, totalpages)
|
||||
return rs
|
||||
|
@ -207,18 +211,18 @@ func fun3(po *PageOptions, totalpages int) string {
|
|||
* 123456789...200
|
||||
*/
|
||||
func fun2(po *PageOptions, totalpages int) string {
|
||||
var rs string = ""
|
||||
rs := ""
|
||||
rs += getHeader(po, totalpages)
|
||||
for i := 1; i <= po.LinkItemCount+1; i++ {
|
||||
if i == po.LinkItemCount {
|
||||
rs += "<li><a href=\"" + po.Href + "&" + po.ParamName + "=" + con.Itoa(i) + "\">...</a></li>"
|
||||
for i := 1; i <= po.LinkItemCount+2; i++ {
|
||||
if i == po.LinkItemCount+2 {
|
||||
rs += "<li class=\"@4\"><a href=\"" + po.Href + "&" + po.ParamName + "=" + con.Itoa(i) + "\">...</a></li>"
|
||||
} else if i == po.LinkItemCount+1 {
|
||||
rs += "<li><a href=\"" + po.Href + "&" + po.ParamName + "=" + con.Itoa(totalpages) + "\">" + con.Itoa(totalpages) + "</a></li>"
|
||||
} else {
|
||||
if po.CurrentPage != i {
|
||||
rs += "<li><a href='" + po.Href + "&" + po.ParamName + "=" + con.Itoa(i) + "'>" + con.Itoa(i) + "</a></li>"
|
||||
} 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>"
|
||||
} 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)
|
||||
|
@ -255,7 +259,7 @@ func getHeader(po *PageOptions, totalpages int) string {
|
|||
if po.EnableFirstLastLink { //当首页,尾页都设定的时候,就显示
|
||||
if po.CurrentPage == 1 {
|
||||
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>"
|
||||
}
|
||||
}
|
||||
|
@ -281,7 +285,7 @@ func getFooter(po *PageOptions, totalpages int) string {
|
|||
if po.EnableFirstLastLink { //当首页,尾页都设定的时候,就显示
|
||||
if po.CurrentPage == totalpages {
|
||||
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>"
|
||||
}
|
||||
}
|
||||
|
@ -339,4 +343,4 @@ func judgeDisable(po *PageOptions, totalpages int, h_f int) string {
|
|||
}
|
||||
}
|
||||
return rs
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
package utils
|
||||
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
mt "math/rand"
|
||||
"crypto/md5"
|
||||
"crypto/rand"
|
||||
"crypto/sha256"
|
||||
"crypto/sha512"
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
"io"
|
||||
mt "math/rand"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
@ -20,6 +19,7 @@ const (
|
|||
stretching_password = 500
|
||||
salt_local_secret = "ahfw*&TGdsfnbi*^Wt"
|
||||
)
|
||||
|
||||
//加密密码
|
||||
func PasswordHash(pass string) (string, error) {
|
||||
|
||||
|
@ -45,8 +45,9 @@ func PasswordHash(pass string) (string, error) {
|
|||
return password, nil
|
||||
|
||||
}
|
||||
|
||||
//校验密码是否有效
|
||||
func PasswordVerify(hashing string, pass string) (bool, error) {
|
||||
func PasswordVerify(hashing string, pass string) (bool, error) {
|
||||
data := trim_salt_hash(hashing)
|
||||
|
||||
interation, _ := strconv.ParseInt(data["interation_string"], 10, 64)
|
||||
|
@ -56,7 +57,7 @@ func PasswordVerify(hashing string, pass string) (bool, error) {
|
|||
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
|
||||
} else {
|
||||
return false, nil
|
||||
|
@ -110,7 +111,7 @@ func trim_salt_hash(hash string) map[string]string {
|
|||
}
|
||||
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)
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
@ -134,4 +135,4 @@ func salt_secret() (string, error) {
|
|||
|
||||
func randInt(min int, max int) int {
|
||||
return min + mt.Intn(max-min)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
package utils
|
||||
|
||||
func Asset(p string,cdn string) string {
|
||||
return cdn + p;
|
||||
func Asset(p string, cdn string) string {
|
||||
return cdn + p
|
||||
}
|
||||
|
|
12
utils/url.go
12
utils/url.go
|
@ -8,17 +8,17 @@ func JoinURI(elem ...string) string {
|
|||
}
|
||||
uri := ""
|
||||
|
||||
for i,u := range elem {
|
||||
u = strings.Replace(u,"\\","/",-1)
|
||||
for i, u := range elem {
|
||||
u = strings.Replace(u, "\\", "/", -1)
|
||||
|
||||
if i == 0 {
|
||||
if !strings.HasSuffix(u,"/") {
|
||||
if !strings.HasSuffix(u, "/") {
|
||||
u = u + "/"
|
||||
}
|
||||
uri = u
|
||||
}else{
|
||||
u = strings.Replace(u,"//","/",-1)
|
||||
if strings.HasPrefix(u,"/") {
|
||||
} else {
|
||||
u = strings.Replace(u, "//", "/", -1)
|
||||
if strings.HasPrefix(u, "/") {
|
||||
u = string(u[1:])
|
||||
}
|
||||
uri += u
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -131,7 +131,7 @@
|
|||
return false;
|
||||
} else {
|
||||
$.ajax({
|
||||
url: "{{urlfor "AccountController.Login"}}",
|
||||
url: "{{urlfor "AccountController.Login" "url" .url}}",
|
||||
data: $("form").serializeArray(),
|
||||
dataType: "json",
|
||||
type: "POST",
|
||||
|
@ -142,7 +142,7 @@
|
|||
layer.msg(res.message);
|
||||
$btn.button('reset');
|
||||
} else {
|
||||
turl = res.data.turl;
|
||||
turl = res.data;
|
||||
if (turl === "") {
|
||||
turl = "/";
|
||||
}
|
||||
|
|
|
@ -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" "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" "docx"}}" target="_blank">Word</a> </li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
|
Loading…
Reference in New Issue