mirror of https://github.com/mindoc-org/mindoc.git
refactor and add i18n, to be continue
parent
782ea44388
commit
1239620f75
|
@ -163,40 +163,40 @@ func RegisterLogger(log string) {
|
|||
if level := beego.AppConfig.DefaultString("log_level", "Trace"); level != "" {
|
||||
switch level {
|
||||
case "Emergency":
|
||||
config["level"] = beego.LevelEmergency
|
||||
config["level"] = logs.LevelEmergency
|
||||
break
|
||||
case "Alert":
|
||||
config["level"] = beego.LevelAlert
|
||||
config["level"] = logs.LevelAlert
|
||||
break
|
||||
case "Critical":
|
||||
config["level"] = beego.LevelCritical
|
||||
config["level"] = logs.LevelCritical
|
||||
break
|
||||
case "Error":
|
||||
config["level"] = beego.LevelError
|
||||
config["level"] = logs.LevelError
|
||||
break
|
||||
case "Warning":
|
||||
config["level"] = beego.LevelWarning
|
||||
config["level"] = logs.LevelWarning
|
||||
break
|
||||
case "Notice":
|
||||
config["level"] = beego.LevelNotice
|
||||
config["level"] = logs.LevelNotice
|
||||
break
|
||||
case "Informational":
|
||||
config["level"] = beego.LevelInformational
|
||||
config["level"] = logs.LevelInformational
|
||||
break
|
||||
case "Debug":
|
||||
config["level"] = beego.LevelDebug
|
||||
config["level"] = logs.LevelDebug
|
||||
break
|
||||
}
|
||||
}
|
||||
b, err := json.Marshal(config)
|
||||
if err != nil {
|
||||
logs.Error("初始化文件日志时出错 ->", err)
|
||||
_ = beego.SetLogger("file", `{"filename":"`+logPath+`"}`)
|
||||
_ = logs.SetLogger("file", `{"filename":"`+logPath+`"}`)
|
||||
} else {
|
||||
_ = beego.SetLogger(logs.AdapterFile, string(b))
|
||||
_ = logs.SetLogger(logs.AdapterFile, string(b))
|
||||
}
|
||||
|
||||
beego.SetLogFuncCall(true)
|
||||
logs.SetLogFuncCall(true)
|
||||
}
|
||||
|
||||
// RunCommand 注册orm命令行工具
|
||||
|
@ -454,7 +454,7 @@ func RegisterCache() {
|
|||
|
||||
} else {
|
||||
cache.Init(&cache.NullCache{})
|
||||
beego.Warn("不支持的缓存管道,缓存将禁用 ->", cacheProvider)
|
||||
logs.Warn("不支持的缓存管道,缓存将禁用 ->", cacheProvider)
|
||||
return
|
||||
}
|
||||
logs.Info("缓存初始化完成.")
|
||||
|
|
|
@ -7,8 +7,58 @@ person_center = Persona Center
|
|||
my_project = My Project
|
||||
my_blog = My Article
|
||||
manage = Management
|
||||
login = Login
|
||||
logout = Logout
|
||||
login = Log In
|
||||
logout = Log Out
|
||||
official_website = Official Website
|
||||
feedback = Feedback
|
||||
source_code = Source Code
|
||||
manual = Manual
|
||||
username = Username
|
||||
email = Email
|
||||
password = Password
|
||||
captcha = Captcha
|
||||
keep_login = Stay signed in
|
||||
forgot_password = Forgot password?
|
||||
register = Create New Account
|
||||
dingtalk_login = DingTalk QrCode login
|
||||
account_recovery = Account recovery
|
||||
new_password = New password
|
||||
confirm_password = Confirm password
|
||||
|
||||
[message]
|
||||
keyword_placeholder = input keyword please...
|
||||
wrong_account_password = Incorrect username or password
|
||||
click_to_change = Click to change one
|
||||
logging_in = logging in...
|
||||
return_account_login = Return account password login
|
||||
no_account_yet = No account yet?
|
||||
account_empty = Account cannot be empty
|
||||
email_empty = Email cannot be empty
|
||||
password_empty = Password cannot be empty
|
||||
captcha_empty = Captcha cannot be empty
|
||||
system_error = System error
|
||||
processing = Processing...
|
||||
email_sent = The email is sent successfully, please log in to check it.
|
||||
password_empty = Confirm password cannot be empty
|
||||
incorrect_confirm_password = Incorrect confirm password
|
||||
illegal_request = Illegal request
|
||||
account_or_password_empty = Account or Password cannot be empty
|
||||
captcha_wrong = Incorrect captcha
|
||||
password_length_invalid = The password cannot be empty and must be between 6-50 characters
|
||||
mail_expired = Mail has expired
|
||||
captcha_expired = The verification code has expired, please try again.
|
||||
user_not_existed = User does not exist
|
||||
email_not_exist = Email does not exist
|
||||
failed_save_password = Failed to save password
|
||||
mail_service_not_enable = Mail service is not enabled
|
||||
account_disable = Account has been disabled
|
||||
failed_send_mail = Failed to send mail
|
||||
sent_too_many_times = Send too many times, please try again later
|
||||
account_not_support_retrieval = The current user does not support password retrieval
|
||||
username_invalid_format = The account number can only be composed of English alphanumerics and 3-50 characters
|
||||
email_invalid_format = Email format is incorrect
|
||||
account_existed = Username already existed
|
||||
failed_register = Registration failed, please contact the system administrator
|
||||
failed_obtain_user_info = Failed to obtain identity information
|
||||
dingtalk_auto_login_not_enable = DingTalk automatic login function is not enabled
|
||||
failed_auto_login = Automatic login failed
|
|
@ -9,6 +9,56 @@ my_blog = 我的文章
|
|||
manage = 管理后台
|
||||
login = 登录
|
||||
logout = 退出登录
|
||||
official_website = 官方网站
|
||||
feedback = 意见反馈
|
||||
source_code = 项目源码
|
||||
manual = 使用手册
|
||||
username = 用户名
|
||||
email = 邮箱
|
||||
password = 密码
|
||||
captcha = 验证码
|
||||
keep_login = 保持登录
|
||||
forgot_password = 忘记密码?
|
||||
register = 立即注册
|
||||
dingtalk_login = 扫码登录
|
||||
account_recovery = 找回密码
|
||||
new_password = 新密码
|
||||
confirm_password = 确认密码
|
||||
|
||||
[message]
|
||||
keyword_placeholder = 请输入关键词...
|
||||
wrong_account_password = 账号或密码错误
|
||||
click_to_change = 点击换一张
|
||||
logging_in = 正在登录...
|
||||
return_account_login = 返回账号密码登录
|
||||
no_account_yet = 还没有账号?
|
||||
account_empty = 账号不能为空
|
||||
email_empty = 邮箱不能为空
|
||||
password_empty = 密码不能为空
|
||||
captcha_empty = 验证码不能为空
|
||||
system_error = 系统错误
|
||||
processing = 正在处理...
|
||||
email_sent = 邮件发送成功,请登录邮箱查看。
|
||||
confirm_password_empty = 确认密码不能为空
|
||||
incorrect_confirm_password = 确认密码输入不正确
|
||||
illegal_request = 非法请求
|
||||
account_or_password_empty = 账号或密码不能为空
|
||||
captcha_wrong = 验证码不正确
|
||||
password_length_invalid = 密码不能为空且必须在6-50个字符之间
|
||||
mail_expired = 邮件已失效
|
||||
captcha_expired = 验证码已过期,请重新操作。
|
||||
user_not_existed = 用户不存在
|
||||
email_not_exist = 邮箱不存在
|
||||
failed_save_password = 保存密码失败
|
||||
mail_service_not_enable = 未启用邮件服务
|
||||
account_disable = 账号已被禁用
|
||||
failed_send_mail = 发送邮件失败
|
||||
sent_too_many_times = 发送次数太多,请稍候再试
|
||||
account_not_support_retrieval = 当前用户不支持找回密码
|
||||
username_invalid_format = 账号只能由英文字母数字组成,且在3-50个字符
|
||||
email_invalid_format = 邮箱格式不正确
|
||||
account_existed = 账号已存在
|
||||
failed_register = 注册失败,请联系管理员
|
||||
failed_obtain_user_info = 获取身份信息失败
|
||||
dingtalk_auto_login_not_enable = 未开启钉钉自动登录功能
|
||||
failed_auto_login = 自动登录失败
|
|
@ -54,17 +54,17 @@ func (c *AccountController) Prepare() {
|
|||
}
|
||||
if token == "" {
|
||||
if c.IsAjax() {
|
||||
c.JsonResult(403, "非法请求")
|
||||
c.JsonResult(403, i18n.Tr(c.Lang, "message.illegal_request"))
|
||||
} else {
|
||||
c.ShowErrorPage(403, "非法请求")
|
||||
c.ShowErrorPage(403, i18n.Tr(c.Lang, "message.illegal_request"))
|
||||
}
|
||||
}
|
||||
xsrfToken := c.XSRFToken()
|
||||
if xsrfToken != token {
|
||||
if c.IsAjax() {
|
||||
c.JsonResult(403, "非法请求")
|
||||
c.JsonResult(403, i18n.Tr(c.Lang, "message.illegal_request"))
|
||||
} else {
|
||||
c.ShowErrorPage(403, "非法请求")
|
||||
c.ShowErrorPage(403, i18n.Tr(c.Lang, "message.illegal_request"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -108,12 +108,12 @@ func (c *AccountController) Login() {
|
|||
if v, ok := c.Option["ENABLED_CAPTCHA"]; ok && strings.EqualFold(v, "true") {
|
||||
v, ok := c.GetSession(conf.CaptchaSessionName).(string)
|
||||
if !ok || !strings.EqualFold(v, captcha) {
|
||||
c.JsonResult(6001, "验证码不正确")
|
||||
c.JsonResult(6001, i18n.Tr(c.Lang, "message.captcha_wrong"))
|
||||
}
|
||||
}
|
||||
|
||||
if account == "" || password == "" {
|
||||
c.JsonResult(6002, "账号或密码不能为空")
|
||||
c.JsonResult(6002, i18n.Tr(c.Lang, "message.account_or_password_empty"))
|
||||
}
|
||||
|
||||
member, err := models.NewMember().Login(account, password)
|
||||
|
@ -149,7 +149,7 @@ func (c *AccountController) DingTalkLogin() {
|
|||
|
||||
code := c.GetString("dingtalk_code")
|
||||
if code == "" {
|
||||
c.JsonResult(500, "获取身份信息失败", nil)
|
||||
c.JsonResult(500, i18n.Tr(c.Lang, "message.failed_obtain_user_info"), nil)
|
||||
}
|
||||
|
||||
appKey := beego.AppConfig.String("dingtalk_app_key")
|
||||
|
@ -157,29 +157,29 @@ func (c *AccountController) DingTalkLogin() {
|
|||
tmpReader := beego.AppConfig.String("dingtalk_tmp_reader")
|
||||
|
||||
if appKey == "" || appSecret == "" || tmpReader == "" {
|
||||
c.JsonResult(500, "未开启钉钉自动登录功能", nil)
|
||||
c.JsonResult(500, i18n.Tr(c.Lang, "message.dingtalk_auto_login_not_enable"), nil)
|
||||
c.StopRun()
|
||||
}
|
||||
|
||||
dingtalkAgent := dingtalk.NewDingTalkAgent(appSecret, appKey)
|
||||
err := dingtalkAgent.GetAccesstoken()
|
||||
if err != nil {
|
||||
beego.Warn("获取钉钉临时Token失败 ->", err)
|
||||
c.JsonResult(500, "自动登录失败", nil)
|
||||
logs.Warn("获取钉钉临时Token失败 ->", err)
|
||||
c.JsonResult(500, i18n.Tr(c.Lang, "message.failed_auto_login"), nil)
|
||||
c.StopRun()
|
||||
}
|
||||
|
||||
userid, err := dingtalkAgent.GetUserIDByCode(code)
|
||||
if err != nil {
|
||||
beego.Warn("获取钉钉用户ID失败 ->", err)
|
||||
c.JsonResult(500, "自动登录失败", nil)
|
||||
logs.Warn("获取钉钉用户ID失败 ->", err)
|
||||
c.JsonResult(500, i18n.Tr(c.Lang, "message.failed_auto_login"), nil)
|
||||
c.StopRun()
|
||||
}
|
||||
|
||||
username, avatar, err := dingtalkAgent.GetUserNameAndAvatarByUserID(userid)
|
||||
if err != nil {
|
||||
beego.Warn("获取钉钉用户信息失败 ->", err)
|
||||
c.JsonResult(500, "自动登录失败", nil)
|
||||
logs.Warn("获取钉钉用户信息失败 ->", err)
|
||||
c.JsonResult(500, i18n.Tr(c.Lang, "message.failed_auto_login"), nil)
|
||||
c.StopRun()
|
||||
}
|
||||
|
||||
|
@ -218,7 +218,7 @@ func (c *AccountController) QRLogin() {
|
|||
qrDingtalk := dingtalk.NewDingtalkQRLogin(appSecret, appKey)
|
||||
unionID, err := qrDingtalk.GetUnionIDByCode(code)
|
||||
if err != nil {
|
||||
beego.Warn("获取钉钉临时UnionID失败 ->", err)
|
||||
logs.Warn("获取钉钉临时UnionID失败 ->", err)
|
||||
c.Redirect(conf.URLFor("AccountController.Login"), 302)
|
||||
c.StopRun()
|
||||
}
|
||||
|
@ -230,21 +230,21 @@ func (c *AccountController) QRLogin() {
|
|||
dingtalkAgent := dingtalk.NewDingTalkAgent(appSecret, appKey)
|
||||
err = dingtalkAgent.GetAccesstoken()
|
||||
if err != nil {
|
||||
beego.Warn("获取钉钉临时Token失败 ->", err)
|
||||
logs.Warn("获取钉钉临时Token失败 ->", err)
|
||||
c.Redirect(conf.URLFor("AccountController.Login"), 302)
|
||||
c.StopRun()
|
||||
}
|
||||
|
||||
userid, err := dingtalkAgent.GetUserIDByUnionID(unionID)
|
||||
if err != nil {
|
||||
beego.Warn("获取钉钉用户ID失败 ->", err)
|
||||
logs.Warn("获取钉钉用户ID失败 ->", err)
|
||||
c.Redirect(conf.URLFor("AccountController.Login"), 302)
|
||||
c.StopRun()
|
||||
}
|
||||
|
||||
username, avatar, err := dingtalkAgent.GetUserNameAndAvatarByUserID(userid)
|
||||
if err != nil {
|
||||
beego.Warn("获取钉钉用户信息失败 ->", err)
|
||||
logs.Warn("获取钉钉用户信息失败 ->", err)
|
||||
c.Redirect(conf.URLFor("AccountController.Login"), 302)
|
||||
c.StopRun()
|
||||
}
|
||||
|
@ -308,29 +308,29 @@ func (c *AccountController) Register() {
|
|||
captcha := c.GetString("code")
|
||||
|
||||
if ok, err := regexp.MatchString(conf.RegexpAccount, account); account == "" || !ok || err != nil {
|
||||
c.JsonResult(6001, "账号只能由英文字母数字组成,且在3-50个字符")
|
||||
c.JsonResult(6001, i18n.Tr(c.Lang, "message.username_invalid_format"))
|
||||
}
|
||||
if l := strings.Count(password1, ""); password1 == "" || l > 50 || l < 6 {
|
||||
c.JsonResult(6002, "密码必须在6-50个字符之间")
|
||||
c.JsonResult(6002, i18n.Tr(c.Lang, "message.password_length_invalid"))
|
||||
}
|
||||
if password1 != password2 {
|
||||
c.JsonResult(6003, "确认密码不正确")
|
||||
c.JsonResult(6003, i18n.Tr(c.Lang, "message.incorrect_confirm_password"))
|
||||
}
|
||||
if ok, err := regexp.MatchString(conf.RegexpEmail, email); !ok || err != nil || email == "" {
|
||||
c.JsonResult(6004, "邮箱格式不正确")
|
||||
c.JsonResult(6004, i18n.Tr(c.Lang, "message.email_invalid_format"))
|
||||
}
|
||||
// 如果开启了验证码
|
||||
if v, ok := c.Option["ENABLED_CAPTCHA"]; ok && strings.EqualFold(v, "true") {
|
||||
v, ok := c.GetSession(conf.CaptchaSessionName).(string)
|
||||
if !ok || !strings.EqualFold(v, captcha) {
|
||||
c.JsonResult(6001, "验证码不正确")
|
||||
c.JsonResult(6001, i18n.Tr(c.Lang, "message.captcha_wrong"))
|
||||
}
|
||||
}
|
||||
|
||||
member := models.NewMember()
|
||||
|
||||
if _, err := member.FindByAccount(account); err == nil && member.MemberId > 0 {
|
||||
c.JsonResult(6005, "账号已存在")
|
||||
c.JsonResult(6005, i18n.Tr(c.Lang, "message.account_existed"))
|
||||
}
|
||||
|
||||
member.Account = account
|
||||
|
@ -341,7 +341,7 @@ func (c *AccountController) Register() {
|
|||
member.Email = email
|
||||
member.Status = 0
|
||||
if err := member.Add(); err != nil {
|
||||
c.JsonResult(6006, "注册失败,请联系系统管理员处理")
|
||||
c.JsonResult(6006, i18n.Tr(c.Lang, "message.failed_register"))
|
||||
}
|
||||
|
||||
c.JsonResult(0, "ok", member)
|
||||
|
@ -359,39 +359,39 @@ func (c *AccountController) FindPassword() {
|
|||
captcha := c.GetString("code")
|
||||
|
||||
if email == "" {
|
||||
c.JsonResult(6005, "邮箱地址不能为空")
|
||||
c.JsonResult(6005, i18n.Tr(c.Lang, "message.email_empty"))
|
||||
}
|
||||
if !mailConf.EnableMail {
|
||||
c.JsonResult(6004, "未启用邮件服务")
|
||||
c.JsonResult(6004, i18n.Tr(c.Lang, "message.mail_service_not_enable"))
|
||||
}
|
||||
|
||||
// 如果开启了验证码
|
||||
if v, ok := c.Option["ENABLED_CAPTCHA"]; ok && strings.EqualFold(v, "true") {
|
||||
v, ok := c.GetSession(conf.CaptchaSessionName).(string)
|
||||
if !ok || !strings.EqualFold(v, captcha) {
|
||||
c.JsonResult(6001, "验证码不正确")
|
||||
c.JsonResult(6001, i18n.Tr(c.Lang, "message.captcha_wrong"))
|
||||
}
|
||||
}
|
||||
|
||||
member, err := models.NewMember().FindByFieldFirst("email", email)
|
||||
if err != nil {
|
||||
c.JsonResult(6006, "邮箱不存在")
|
||||
c.JsonResult(6006, i18n.Tr(c.Lang, "message.email_not_exist"))
|
||||
}
|
||||
if member.Status != 0 {
|
||||
c.JsonResult(6007, "账号已被禁用")
|
||||
if member == nil || member.Status != 0 {
|
||||
c.JsonResult(6007, i18n.Tr(c.Lang, "message.account_disable"))
|
||||
}
|
||||
if member.AuthMethod == conf.AuthMethodLDAP {
|
||||
c.JsonResult(6011, "当前用户不支持找回密码")
|
||||
if member == nil || member.AuthMethod == conf.AuthMethodLDAP {
|
||||
c.JsonResult(6011, i18n.Tr(c.Lang, "message.account_not_support_retrieval"))
|
||||
}
|
||||
|
||||
count, err := models.NewMemberToken().FindSendCount(email, time.Now().Add(-1*time.Hour), time.Now())
|
||||
|
||||
if err != nil {
|
||||
logs.Error(err)
|
||||
c.JsonResult(6008, "发送邮件失败")
|
||||
c.JsonResult(6008, i18n.Tr(c.Lang, "message.failed_send_mail"))
|
||||
}
|
||||
if count > mailConf.MailNumber {
|
||||
c.JsonResult(6008, "发送次数太多,请稍候再试")
|
||||
c.JsonResult(6008, i18n.Tr(c.Lang, "message.sent_too_many_times"))
|
||||
}
|
||||
|
||||
memberToken := models.NewMemberToken()
|
||||
|
@ -401,7 +401,7 @@ func (c *AccountController) FindPassword() {
|
|||
memberToken.MemberId = member.MemberId
|
||||
memberToken.IsValid = false
|
||||
if _, err := memberToken.InsertOrUpdate(); err != nil {
|
||||
c.JsonResult(6009, "邮件发送失败")
|
||||
c.JsonResult(6009, i18n.Tr(c.Lang, "message.failed_send_mail"))
|
||||
}
|
||||
|
||||
data := map[string]interface{}{
|
||||
|
@ -413,7 +413,7 @@ func (c *AccountController) FindPassword() {
|
|||
body, err := c.ExecuteViewPathTemplate("account/mail_template.tpl", data)
|
||||
if err != nil {
|
||||
logs.Error(err)
|
||||
c.JsonResult(6003, "邮件发送失败")
|
||||
c.JsonResult(6003, i18n.Tr(c.Lang, "message.failed_send_mail"))
|
||||
}
|
||||
|
||||
go func(mailConf *conf.SmtpConf, email string, body string) {
|
||||
|
@ -472,17 +472,16 @@ func (c *AccountController) FindPassword() {
|
|||
|
||||
if token != "" && email != "" {
|
||||
memberToken, err := models.NewMemberToken().FindByFieldFirst("token", token)
|
||||
|
||||
if err != nil {
|
||||
logs.Error(err)
|
||||
c.Data["ErrorMessage"] = "邮件已失效"
|
||||
c.Data["ErrorMessage"] = i18n.Tr(c.Lang, "message.mail_expired")
|
||||
c.TplName = "errors/error.tpl"
|
||||
return
|
||||
}
|
||||
subTime := memberToken.SendTime.Sub(time.Now())
|
||||
|
||||
if !strings.EqualFold(memberToken.Email, email) || subTime.Minutes() > float64(mailConf.MailExpired) || !memberToken.ValidTime.IsZero() {
|
||||
c.Data["ErrorMessage"] = "验证码已过期,请重新操作。"
|
||||
c.Data["ErrorMessage"] = i18n.Tr(c.Lang, "message.captcha_expired")
|
||||
c.TplName = "errors/error.tpl"
|
||||
return
|
||||
}
|
||||
|
@ -503,48 +502,46 @@ func (c *AccountController) ValidEmail() {
|
|||
email := c.GetString("mail")
|
||||
|
||||
if password1 == "" {
|
||||
c.JsonResult(6001, "密码不能为空")
|
||||
c.JsonResult(6001, i18n.Tr(c.Lang, "message.password_empty"))
|
||||
}
|
||||
if l := strings.Count(password1, ""); l < 6 || l > 50 {
|
||||
c.JsonResult(6001, "密码不能为空且必须在6-50个字符之间")
|
||||
c.JsonResult(6001, i18n.Tr(c.Lang, "message.password_length_invalid"))
|
||||
}
|
||||
if password2 == "" {
|
||||
c.JsonResult(6002, "确认密码不能为空")
|
||||
c.JsonResult(6002, i18n.Tr(c.Lang, "message.confirm_password_empty"))
|
||||
}
|
||||
if password1 != password2 {
|
||||
c.JsonResult(6003, "确认密码输入不正确")
|
||||
c.JsonResult(6003, i18n.Tr(c.Lang, "message.incorrect_confirm_password"))
|
||||
}
|
||||
if captcha == "" {
|
||||
c.JsonResult(6004, "验证码不能为空")
|
||||
c.JsonResult(6004, i18n.Tr(c.Lang, "message.captcha_empty"))
|
||||
}
|
||||
v, ok := c.GetSession(conf.CaptchaSessionName).(string)
|
||||
if !ok || !strings.EqualFold(v, captcha) {
|
||||
c.JsonResult(6001, "验证码不正确")
|
||||
c.JsonResult(6001, i18n.Tr(c.Lang, "message.captcha_wrong"))
|
||||
}
|
||||
|
||||
mailConf := conf.GetMailConfig()
|
||||
memberToken, err := models.NewMemberToken().FindByFieldFirst("token", token)
|
||||
|
||||
if err != nil {
|
||||
logs.Error(err)
|
||||
c.JsonResult(6007, "邮件已失效")
|
||||
c.JsonResult(6007, i18n.Tr(c.Lang, "message.mail_expired"))
|
||||
}
|
||||
subTime := memberToken.SendTime.Sub(time.Now())
|
||||
|
||||
if !strings.EqualFold(memberToken.Email, email) || subTime.Minutes() > float64(mailConf.MailExpired) || !memberToken.ValidTime.IsZero() {
|
||||
|
||||
c.JsonResult(6008, "验证码已过期,请重新操作。")
|
||||
c.JsonResult(6008, i18n.Tr(c.Lang, "message.captcha_expired"))
|
||||
}
|
||||
member, err := models.NewMember().Find(memberToken.MemberId)
|
||||
if err != nil {
|
||||
logs.Error(err)
|
||||
c.JsonResult(6005, "用户不存在")
|
||||
c.JsonResult(6005, i18n.Tr(c.Lang, "message.user_not_existed"))
|
||||
}
|
||||
hash, err := utils.PasswordHash(password1)
|
||||
|
||||
if err != nil {
|
||||
logs.Error(err)
|
||||
c.JsonResult(6006, "保存密码失败")
|
||||
c.JsonResult(6006, i18n.Tr(c.Lang, "message.failed_save_password"))
|
||||
}
|
||||
|
||||
member.Password = hash
|
||||
|
@ -556,7 +553,7 @@ func (c *AccountController) ValidEmail() {
|
|||
|
||||
if err != nil {
|
||||
logs.Error(err)
|
||||
c.JsonResult(6006, "保存密码失败")
|
||||
c.JsonResult(6006, i18n.Tr(c.Lang, "message.failed_save_password"))
|
||||
}
|
||||
c.JsonResult(0, "ok", conf.URLFor("AccountController.Login"))
|
||||
}
|
||||
|
@ -564,11 +561,8 @@ func (c *AccountController) ValidEmail() {
|
|||
// Logout 退出登录
|
||||
func (c *AccountController) Logout() {
|
||||
c.SetMember(models.Member{})
|
||||
|
||||
c.SetSecureCookie(conf.GetAppKey(), "login", "", -3600)
|
||||
|
||||
u := c.Ctx.Request.Header.Get("Referer")
|
||||
|
||||
c.Redirect(conf.URLFor("AccountController.Login", "url", u), 302)
|
||||
}
|
||||
|
||||
|
@ -578,11 +572,6 @@ func (c *AccountController) Captcha() {
|
|||
|
||||
captchaImage := gocaptcha.NewCaptchaImage(140, 40, gocaptcha.RandLightColor())
|
||||
|
||||
//if err != nil {
|
||||
// logs.Error(err)
|
||||
// c.Abort("500")
|
||||
//}
|
||||
|
||||
captchaImage.DrawNoise(gocaptcha.CaptchaComplexLower)
|
||||
|
||||
// captchaImage.DrawTextNoise(gocaptcha.CaptchaComplexHigh)
|
||||
|
|
|
@ -2,9 +2,9 @@ package controllers
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"github.com/beego/i18n"
|
||||
|
||||
"encoding/json"
|
||||
"github.com/astaxie/beego/logs"
|
||||
"github.com/beego/i18n"
|
||||
"io"
|
||||
"strings"
|
||||
"time"
|
||||
|
@ -24,6 +24,7 @@ type BaseController struct {
|
|||
Option map[string]string
|
||||
EnableAnonymous bool
|
||||
EnableDocumentHistory bool
|
||||
Lang string
|
||||
}
|
||||
|
||||
type CookieRemember struct {
|
||||
|
@ -45,7 +46,6 @@ func (c *BaseController) Prepare() {
|
|||
c.EnableDocumentHistory = false
|
||||
|
||||
if member, ok := c.GetSession(conf.LoginSessionName).(models.Member); ok && member.MemberId > 0 {
|
||||
|
||||
c.Member = &member
|
||||
c.Data["Member"] = c.Member
|
||||
} else {
|
||||
|
@ -78,13 +78,8 @@ func (c *BaseController) Prepare() {
|
|||
if b, err := ioutil.ReadFile(filepath.Join(beego.BConfig.WebConfig.ViewsPath, "widgets", "scripts.tpl")); err == nil {
|
||||
c.Data["Scripts"] = template.HTML(string(b))
|
||||
}
|
||||
lang := c.Input().Get("lang")
|
||||
if len(lang) == 0 ||
|
||||
!i18n.IsExist(lang) {
|
||||
lang = "zh-cn"
|
||||
}
|
||||
c.Data["Lang"] = lang
|
||||
|
||||
c.SetLang()
|
||||
}
|
||||
|
||||
//判断用户是否登录.
|
||||
|
@ -117,14 +112,16 @@ func (c *BaseController) JsonResult(errCode int, errMsg string, data ...interfac
|
|||
}
|
||||
|
||||
returnJSON, err := json.Marshal(jsonData)
|
||||
|
||||
if err != nil {
|
||||
beego.Error(err)
|
||||
logs.Error(err)
|
||||
}
|
||||
|
||||
c.Ctx.ResponseWriter.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||
c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache, no-store")
|
||||
io.WriteString(c.Ctx.ResponseWriter, string(returnJSON))
|
||||
_, err = io.WriteString(c.Ctx.ResponseWriter, string(returnJSON))
|
||||
if err != nil {
|
||||
logs.Error(err)
|
||||
}
|
||||
|
||||
c.StopRun()
|
||||
}
|
||||
|
@ -141,14 +138,16 @@ func (c *BaseController) CheckJsonError(code int, err error) {
|
|||
jsonData["message"] = err.Error()
|
||||
|
||||
returnJSON, err := json.Marshal(jsonData)
|
||||
|
||||
if err != nil {
|
||||
beego.Error(err)
|
||||
logs.Error(err)
|
||||
}
|
||||
|
||||
c.Ctx.ResponseWriter.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||
c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache, no-store")
|
||||
io.WriteString(c.Ctx.ResponseWriter, string(returnJSON))
|
||||
_, err = io.WriteString(c.Ctx.ResponseWriter, string(returnJSON))
|
||||
if err != nil {
|
||||
logs.Error(err)
|
||||
}
|
||||
|
||||
c.StopRun()
|
||||
}
|
||||
|
@ -201,9 +200,26 @@ func (c *BaseController) ShowErrorPage(errCode int, errMsg string) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
func (c *BaseController) CheckErrorResult(code int, err error) {
|
||||
if err != nil {
|
||||
c.ShowErrorPage(code, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func (c *BaseController) SetLang() {
|
||||
hasCookie := false
|
||||
lang := c.Input().Get("lang")
|
||||
if len(lang) == 0 {
|
||||
lang = c.Ctx.GetCookie("lang")
|
||||
hasCookie = true
|
||||
}
|
||||
if len(lang) == 0 ||
|
||||
!i18n.IsExist(lang) {
|
||||
lang = beego.AppConfig.String("default_lang")
|
||||
}
|
||||
if !hasCookie {
|
||||
c.Ctx.SetCookie("lang", lang, 1<<31-1, "/")
|
||||
}
|
||||
c.Data["Lang"] = lang
|
||||
c.Lang = lang
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<meta name="renderer" content="webkit" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="author" content="MinDoc" />
|
||||
<title>找回密码 - Powered by MinDoc</title>
|
||||
<title>{{i18n .Lang "common.account_recovery"}} - Powered by MinDoc</title>
|
||||
|
||||
<!-- Bootstrap -->
|
||||
<link href="{{cdncss "/static/bootstrap/css/bootstrap.min.css"}}" rel="stylesheet">
|
||||
|
@ -35,13 +35,13 @@
|
|||
<div class="login-body">
|
||||
<form role="form" method="post" id="findPasswordForm">
|
||||
{{ .xsrfdata }}
|
||||
<h3 class="text-center">找回密码</h3>
|
||||
<h3 class="text-center">{{i18n .Lang "common.account_recovery"}}</h3>
|
||||
<div class="form-group">
|
||||
<div class="input-group">
|
||||
<div class="input-group-addon">
|
||||
<i class="fa fa-at"></i>
|
||||
</div>
|
||||
<input type="text" class="form-control" placeholder="邮箱" name="email" id="email" autocomplete="off">
|
||||
<input type="text" class="form-control" placeholder="{{i18n .Lang "common.email"}}" name="email" id="email" autocomplete="off">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
|
@ -49,14 +49,14 @@
|
|||
<div class="input-group-addon">
|
||||
<i class="fa fa-check-square"></i>
|
||||
</div>
|
||||
<input type="text" name="code" id="code" class="form-control" style="width: 150px" maxlength="5" placeholder="验证码" autocomplete="off">
|
||||
<input type="text" name="code" id="code" class="form-control" style="width: 150px" maxlength="5" placeholder="{{i18n .Lang "common.captcha"}}" autocomplete="off">
|
||||
</div>
|
||||
<img id="captcha-img" style="width: 140px;height: 40px;display: inline-block;float: right" src="{{urlfor "AccountController.Captcha"}}" onclick="this.src='{{urlfor "AccountController.Captcha"}}?key=login&t='+(new Date()).getTime();" title="点击换一张">
|
||||
<img id="captcha-img" style="width: 140px;height: 40px;display: inline-block;float: right" src="{{urlfor "AccountController.Captcha"}}" onclick="this.src='{{urlfor "AccountController.Captcha"}}?key=login&t='+(new Date()).getTime();" title="{{i18n .Lang "message.click_to_change"}}">
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<button type="submit" id="btnSendMail" class="btn btn-success" style="width: 100%" data-loading-text="正在处理..." autocomplete="off">找回密码</button>
|
||||
<button type="submit" id="btnSendMail" class="btn btn-success" style="width: 100%" data-loading-text="{{i18n .Lang "message.processing"}}" autocomplete="off">{{i18n .Lang "common.account_recovery"}}</button>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
@ -88,7 +88,7 @@
|
|||
|
||||
var email = $.trim($("#email").val());
|
||||
if(email === ""){
|
||||
$("#email").tooltip({placement:"auto",title : "邮箱不能为空",trigger : 'manual'})
|
||||
$("#email").tooltip({placement:"auto",title : "{{i18n .Lang "message.email_empty"}}",trigger : 'manual'})
|
||||
.tooltip('show')
|
||||
.parents('.form-group').addClass('has-error');
|
||||
$btn.button('reset');
|
||||
|
@ -97,7 +97,7 @@
|
|||
}
|
||||
var code = $.trim($("#code").val());
|
||||
if(code === ""){
|
||||
$("#code").tooltip({title : '验证码不能为空',trigger : 'manual'})
|
||||
$("#code").tooltip({title : '{{i18n .Lang "message.captcha_empty"}}',trigger : 'manual'})
|
||||
.tooltip('show')
|
||||
.parents('.form-group').addClass('has-error');
|
||||
$btn.button('reset');
|
||||
|
@ -113,14 +113,14 @@
|
|||
layer.msg(res.message);
|
||||
$("#btnSendMail").button('reset');
|
||||
}else{
|
||||
alert("邮件发送成功,请登录邮箱查看。")
|
||||
alert("{{i18n .Lang "message.email_sent"}}")
|
||||
window.location = res.data;
|
||||
}
|
||||
},
|
||||
error :function () {
|
||||
$("#captcha-img").click();
|
||||
$("#code").val('');
|
||||
layer.msg('系统错误');
|
||||
layer.msg('{{i18n .Lang "message.system_error"}}');
|
||||
$("#btnSendMail").button('reset');
|
||||
}
|
||||
});
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
||||
<meta name="renderer" content="webkit" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="author" content="SmartWiki" />
|
||||
<title>找回密码 - Powered by MinDoc</title>
|
||||
<meta name="author" content="MinDoc" />
|
||||
<title>{{i18n .Lang "common.account_recovery"}} - Powered by MinDoc</title>
|
||||
|
||||
<!-- Bootstrap -->
|
||||
<link href="{{cdncss "/static/bootstrap/css/bootstrap.min.css"}}" rel="stylesheet">
|
||||
|
@ -37,14 +37,14 @@
|
|||
{{ .xsrfdata }}
|
||||
<input type="hidden" name="token" value="{{.Token}}">
|
||||
<input type="hidden" name="mail" value="{{.Email}}">
|
||||
<h3 class="text-center">找回密码</h3>
|
||||
<h3 class="text-center">{{i18n .Lang "common.account_recovery"}}</h3>
|
||||
<div class="form-group">
|
||||
<label for="newPasswd">新密码</label>
|
||||
<input type="password" class="form-control" name="password1" id="newPassword" maxlength="20" placeholder="新密码" autocomplete="off">
|
||||
<label for="newPasswd">{{i18n .Lang "common.new_password"}}</label>
|
||||
<input type="password" class="form-control" name="password1" id="newPassword" maxlength="20" placeholder="{{i18n .Lang "common.new_password"}}" autocomplete="off">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="configPasswd">确认密码</label>
|
||||
<input type="password" class="form-control" id="confirmPassword" name="password2" maxlength="20" placeholder="确认密码" autocomplete="off">
|
||||
<label for="configPasswd">{{i18n .Lang "common.confirm_password"}}</label>
|
||||
<input type="password" class="form-control" id="confirmPassword" name="password2" maxlength="20" placeholder="{{i18n .Lang "common.confirm_password"}}" autocomplete="off">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
|
@ -52,13 +52,13 @@
|
|||
<div class="input-group-addon">
|
||||
<i class="fa fa-check-square"></i>
|
||||
</div>
|
||||
<input type="text" name="code" id="code" class="form-control" style="width: 150px" maxlength="5" placeholder="验证码" autocomplete="off">
|
||||
<input type="text" name="code" id="code" class="form-control" style="width: 150px" maxlength="5" placeholder="{{i18n .Lang "common.captcha"}}" autocomplete="off">
|
||||
</div>
|
||||
<img id="captcha-img" style="width: 140px;height: 40px;display: inline-block;float: right" src="{{urlfor "AccountController.Captcha"}}" onclick="this.src='{{urlfor "AccountController.Captcha"}}?key=login&t='+(new Date()).getTime();" title="点击换一张">
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<button type="submit" id="btnSendMail" class="btn btn-success" style="width: 100%" data-loading-text="正在处理..." autocomplete="off">找回密码</button>
|
||||
<button type="submit" id="btnSendMail" class="btn btn-success" style="width: 100%" data-loading-text="{{i18n .Lang "message.processing"}}" autocomplete="off">{{i18n .Lang "common.account_recovery"}}</button>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
@ -92,26 +92,26 @@
|
|||
var code = $.trim($("#code").val());
|
||||
|
||||
if(newPassword === ""){
|
||||
$("#newPassword").tooltip({placement:"auto",title : "密码不能为空",trigger : 'manual'})
|
||||
$("#newPassword").tooltip({placement:"auto",title : "{{i18n .Lang "message.password_empty"}}",trigger : 'manual'})
|
||||
.tooltip('show')
|
||||
.parents('.form-group').addClass('has-error');
|
||||
|
||||
return false;
|
||||
|
||||
}else if(confirmPassword === ""){
|
||||
$("#confirmPassword").tooltip({placement:"auto",title : "确认密码不能为空",trigger : 'manual'})
|
||||
$("#confirmPassword").tooltip({placement:"auto",title : "{{i18n .Lang "message.confirm_password_empty"}}",trigger : 'manual'})
|
||||
.tooltip('show')
|
||||
.parents('.form-group').addClass('has-error');
|
||||
|
||||
return false;
|
||||
}else if(newPassword !== confirmPassword) {
|
||||
$("#confirmPassword").tooltip({placement:"auto",title : "确认密码输入不正确",trigger : 'manual'})
|
||||
$("#confirmPassword").tooltip({placement:"auto",title : "{{i18n .Lang "message.incorrect_confirm_password"}}",trigger : 'manual'})
|
||||
.tooltip('show')
|
||||
.parents('.form-group').addClass('has-error');
|
||||
|
||||
return false;
|
||||
}else if(code === ""){
|
||||
$("#code").tooltip({title : '验证码不能为空',trigger : 'manual'})
|
||||
$("#code").tooltip({title : '{{i18n .Lang "message.captcha_empty"}}',trigger : 'manual'})
|
||||
.tooltip('show')
|
||||
.parents('.form-group').addClass('has-error');
|
||||
|
||||
|
@ -134,7 +134,7 @@
|
|||
error :function () {
|
||||
$("#captcha-img").click();
|
||||
$("#code").val('');
|
||||
layer.msg('系统错误');
|
||||
layer.msg('{{i18n .Lang "message.system_error"}}');
|
||||
$("#btnSendMail").button('reset');
|
||||
}
|
||||
});
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<meta name="renderer" content="webkit" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="author" content="MinDoc" />
|
||||
<title>用户登录 - Powered by MinDoc</title>
|
||||
<title>{{i18n .Lang "common.login"}} - Powered by MinDoc</title>
|
||||
<meta name="keywords" content="MinDoc,文档在线管理系统,WIKI,wiki,wiki在线,文档在线管理,接口文档在线管理,接口文档管理">
|
||||
<meta name="description" content="MinDoc文档在线管理系统 {{.site_description}}">
|
||||
<!-- Bootstrap -->
|
||||
|
@ -30,13 +30,13 @@
|
|||
<div class="login-body">
|
||||
<form role="form" method="post">
|
||||
{{ .xsrfdata }}
|
||||
<h3 class="text-center">用户登录</h3>
|
||||
<h3 class="text-center">{{i18n .Lang "common.login"}}</h3>
|
||||
<div class="form-group">
|
||||
<div class="input-group">
|
||||
<div class="input-group-addon">
|
||||
<i class="fa fa-user"></i>
|
||||
</div>
|
||||
<input type="text" class="form-control" placeholder="邮箱 / 用户名" name="account" id="account" autocomplete="off">
|
||||
<input type="text" class="form-control" placeholder="{{i18n .Lang "common.email"}} / {{i18n .Lang "common.username"}}" name="account" id="account" autocomplete="off">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
|
@ -44,7 +44,7 @@
|
|||
<div class="input-group-addon">
|
||||
<i class="fa fa-lock"></i>
|
||||
</div>
|
||||
<input type="password" class="form-control" placeholder="密码" name="password" id="password" autocomplete="off">
|
||||
<input type="password" class="form-control" placeholder="{{i18n .Lang "common.password"}}" name="password" id="password" autocomplete="off">
|
||||
</div>
|
||||
</div>
|
||||
{{if .ENABLED_CAPTCHA }}
|
||||
|
@ -54,38 +54,38 @@
|
|||
<div class="input-group-addon">
|
||||
<i class="fa fa-check-square"></i>
|
||||
</div>
|
||||
<input type="text" name="code" id="code" class="form-control" style="width: 150px" maxlength="5" placeholder="验证码" autocomplete="off">
|
||||
<input type="text" name="code" id="code" class="form-control" style="width: 150px" maxlength="5" placeholder="{{i18n .Lang "common.captcha"}}" autocomplete="off">
|
||||
</div>
|
||||
<img id="captcha-img" style="width: 140px;height: 40px;display: inline-block;float: right" src="{{urlfor "AccountController.Captcha"}}" onclick="this.src='{{urlfor "AccountController.Captcha"}}?key=login&t='+(new Date()).getTime();" title="点击换一张">
|
||||
<img id="captcha-img" style="width: 140px;height: 40px;display: inline-block;float: right" src="{{urlfor "AccountController.Captcha"}}" onclick="this.src='{{urlfor "AccountController.Captcha"}}?key=login&t='+(new Date()).getTime();" title={{i18n .Lang "message.click_to_change"}}>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
{{end}}
|
||||
{{end}}
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input type="checkbox" name="is_remember" value="yes"> 保持登录
|
||||
<input type="checkbox" name="is_remember" value="yes"> {{i18n .Lang "common.keep_login"}}
|
||||
</label>
|
||||
<a href="{{urlfor "AccountController.FindPassword" }}" style="display: inline-block;float: right">忘记密码?</a>
|
||||
<a href="{{urlfor "AccountController.FindPassword" }}" style="display: inline-block;float: right">{{i18n .Lang "common.forgot_password"}}</a>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<button type="button" id="btn-login" class="btn btn-success" style="width: 100%" data-loading-text="正在登录..." autocomplete="off">立即登录</button>
|
||||
<button type="button" id="btn-login" class="btn btn-success" style="width: 100%" data-loading-text="{{i18n .Lang "common.logging_in"}}" autocomplete="off">{{i18n .Lang "common.login"}}</button>
|
||||
</div>
|
||||
{{if .ENABLE_QR_DINGTALK}}
|
||||
<div class="form-group">
|
||||
<a id="btn-dingtalk-qr" class="btn btn-default" style="width: 100%" data-loading-text="" autocomplete="off">钉钉扫码登录</a>
|
||||
<a id="btn-dingtalk-qr" class="btn btn-default" style="width: 100%" data-loading-text="" autocomplete="off">{{i18n .Lang "common.dingtalk_login"}}</a>
|
||||
</div>
|
||||
{{end}}
|
||||
{{if .ENABLED_REGISTER}}
|
||||
{{if ne .ENABLED_REGISTER "false"}}
|
||||
<div class="form-group">
|
||||
还没有账号?<a href="{{urlfor "AccountController.Register" }}" title="立即注册">立即注册</a>
|
||||
{{i18n .Lang "message.no_account_yet"}}<a href="{{urlfor "AccountController.Register" }}" title={{i18n .Lang "common.register"}}>{{i18n .Lang "common.register"}}</a>
|
||||
</div>
|
||||
{{end}}
|
||||
{{end}}
|
||||
</form>
|
||||
<div class="form-group dingtalk-container" style="display: none;">
|
||||
<div id="dingtalk-qr-container"></div>
|
||||
<a class="btn btn-default btn-dingtalk" style="width: 100%" data-loading-text="" autocomplete="off">返回账号密码登录</a>
|
||||
<a class="btn btn-default btn-dingtalk" style="width: 100%" data-loading-text="" autocomplete="off">{{i18n .Lang "message.return_account_login"}}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -196,19 +196,19 @@
|
|||
var code = $("#code").val();
|
||||
|
||||
if (account === "") {
|
||||
$("#account").tooltip({ placement: "auto", title: "账号不能为空", trigger: 'manual' })
|
||||
$("#account").tooltip({ placement: "auto", title: "{{i18n .Lang "message.account_empty"}}", trigger: 'manual' })
|
||||
.tooltip('show')
|
||||
.parents('.form-group').addClass('has-error');
|
||||
$btn.button('reset');
|
||||
return false;
|
||||
} else if (password === "") {
|
||||
$("#password").tooltip({ title: '密码不能为空', trigger: 'manual' })
|
||||
$("#password").tooltip({ title: '{{i18n .Lang "message.password_empty"}}', trigger: 'manual' })
|
||||
.tooltip('show')
|
||||
.parents('.form-group').addClass('has-error');
|
||||
$btn.button('reset');
|
||||
return false;
|
||||
} else if (code !== undefined && code === "") {
|
||||
$("#code").tooltip({ title: '验证码不能为空', trigger: 'manual' })
|
||||
$("#code").tooltip({ title: '{{i18n .Lang "message.captcha_empty"}}', trigger: 'manual' })
|
||||
.tooltip('show')
|
||||
.parents('.form-group').addClass('has-error');
|
||||
$btn.button('reset');
|
||||
|
@ -236,7 +236,7 @@
|
|||
error: function () {
|
||||
$("#captcha-img").click();
|
||||
$("#code").val('');
|
||||
layer.msg('系统错误');
|
||||
layer.msg('{{i18n .Lang "message.system_error"}}');
|
||||
$btn.button('reset');
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
<div class="footer">
|
||||
<div class="container">
|
||||
<div class="row text-center border-top">
|
||||
<span><a href="https://www.iminho.me" target="_blank">官方网站</a></span>
|
||||
<span><a href="https://www.iminho.me" target="_blank">{{i18n .Lang "common.official_website"}}</a></span>
|
||||
<span> · </span>
|
||||
<span><a href="https://github.com/mindoc-org/mindoc/issues" target="_blank">意见反馈</a></span>
|
||||
<span><a href="https://github.com/mindoc-org/mindoc/issues" target="_blank">{{i18n .Lang "common.feedback"}}</a></span>
|
||||
<span> · </span>
|
||||
<span><a href="https://github.com/mindoc-org/mindoc" target="_blank">项目源码</a></span>
|
||||
<span><a href="https://github.com/mindoc-org/mindoc" target="_blank">{{i18n .Lang "common.source_code"}}</a></span>
|
||||
<span> · </span>
|
||||
<span><a href="https://www.iminho.me/wiki/docs/mindoc/" target="_blank">使用手册</a></span>
|
||||
<span><a href="https://www.iminho.me/wiki/docs/mindoc/" target="_blank">{{i18n .Lang "common.manual"}}</a></span>
|
||||
</div>
|
||||
{{if .site_beian}}
|
||||
<div class="row text-center">
|
||||
|
|
Loading…
Reference in New Issue