mirror of
https://github.com/fumiama/paper-manager.git
synced 2026-06-25 13:26:26 +08:00
split global.user
This commit is contained in:
352
backend/global/message.go
Normal file
352
backend/global/message.go
Normal file
@@ -0,0 +1,352 @@
|
|||||||
|
package global
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
MessageNormal MessageType = iota
|
||||||
|
MessageRegister
|
||||||
|
MessageUserAdded
|
||||||
|
MessageContactChange
|
||||||
|
MessagePasswordChange
|
||||||
|
MessageResetPassword
|
||||||
|
MessageOperator
|
||||||
|
)
|
||||||
|
|
||||||
|
type MessageType uint8
|
||||||
|
|
||||||
|
// Message is shown in the workbench
|
||||||
|
type Message struct {
|
||||||
|
ID *int
|
||||||
|
ToID int // ToID user's ID
|
||||||
|
Date int64
|
||||||
|
Text string // Text is the message content
|
||||||
|
Name string // Name is the user's name to add in register message
|
||||||
|
Cont string // Cont is the user's phone number to add in register message or an operator's name in add user message
|
||||||
|
Pswd string // Pswd is the user's password to add in register message
|
||||||
|
}
|
||||||
|
|
||||||
|
// Type decide message type by fields Name, Cont and Pswd.
|
||||||
|
func (m *Message) Type() MessageType {
|
||||||
|
switch {
|
||||||
|
case m.Name != "" && m.Cont != "" && m.Pswd != "":
|
||||||
|
return MessageRegister
|
||||||
|
case m.Name == "" && m.Cont != "" && m.Pswd == "":
|
||||||
|
return MessageUserAdded
|
||||||
|
case m.Name != "" && m.Cont != "" && m.Pswd == "":
|
||||||
|
return MessageContactChange
|
||||||
|
case m.Name != "" && m.Cont == "" && m.Pswd != "":
|
||||||
|
return MessagePasswordChange
|
||||||
|
case m.Name != "" && m.Cont == "" && m.Pswd == "":
|
||||||
|
return MessageResetPassword
|
||||||
|
case m.Name == "" && m.Cont != "" && m.Pswd != "":
|
||||||
|
return MessageOperator
|
||||||
|
default:
|
||||||
|
return MessageNormal
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SendMessage will send a normal message to id
|
||||||
|
func (u *UserDatabase) SendMessage(text, opname string, to int) error {
|
||||||
|
if !u.IsIDExists(to) {
|
||||||
|
return ErrInvalidUserID
|
||||||
|
}
|
||||||
|
m := Message{ToID: to, Date: time.Now().Unix(), Text: text, Cont: opname, Pswd: "opname"}
|
||||||
|
u.mu.Lock()
|
||||||
|
defer u.mu.Unlock()
|
||||||
|
return u.db.InsertUnique(UserTableMessage, &m)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NotifyRegister will send register notification to all supers
|
||||||
|
func (u *UserDatabase) NotifyRegister(ip, name, cont, pswd string) error {
|
||||||
|
if name == "" {
|
||||||
|
return ErrEmptyName
|
||||||
|
}
|
||||||
|
if cont == "" {
|
||||||
|
return ErrEmptyContact
|
||||||
|
}
|
||||||
|
if pswd == "" {
|
||||||
|
return ErrEmptyPassword
|
||||||
|
}
|
||||||
|
for _, c := range name {
|
||||||
|
if !(c >= '0' && c <= '9') && !(c >= 'A' && c <= 'Z') && !(c >= 'a' && c <= 'z') {
|
||||||
|
return ErrInvalidName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if u.IsNameExists(name) {
|
||||||
|
return ErrInvalidName
|
||||||
|
}
|
||||||
|
|
||||||
|
tos, err := u.GetSuperIDs()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
m := Message{
|
||||||
|
Date: time.Now().Unix(),
|
||||||
|
Text: "收到来自 " + ip + ", 用户名 " + name + " 的注册请求, 联系方式: " + cont,
|
||||||
|
Name: name,
|
||||||
|
Cont: cont,
|
||||||
|
Pswd: pswd,
|
||||||
|
}
|
||||||
|
u.mu.Lock()
|
||||||
|
defer u.mu.Unlock()
|
||||||
|
for _, to := range tos {
|
||||||
|
m.ToID = to
|
||||||
|
err = u.db.InsertUnique(UserTableMessage, &m)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// NotifyResetPassword will send notification to all supers
|
||||||
|
func (u *UserDatabase) NotifyResetPassword(ip, name, cont string) error {
|
||||||
|
if name == "" {
|
||||||
|
return ErrEmptyName
|
||||||
|
}
|
||||||
|
if cont == "" {
|
||||||
|
return ErrEmptyContact
|
||||||
|
}
|
||||||
|
for _, c := range name {
|
||||||
|
if !(c >= '0' && c <= '9') && !(c >= 'A' && c <= 'Z') && !(c >= 'a' && c <= 'z') {
|
||||||
|
return ErrInvalidName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
user, err := u.GetUserByName(name)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if cont != user.Cont {
|
||||||
|
return ErrInvalidContact
|
||||||
|
}
|
||||||
|
|
||||||
|
tos, err := u.GetSuperIDs()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = u.SendMessage("发送重置密码请求", user.Name, *user.ID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
m := Message{
|
||||||
|
Date: time.Now().Unix(),
|
||||||
|
Text: "收到来自 " + ip + ", 用户名 " + user.Name + " 的重置密码请求, 联系方式: " + user.Cont,
|
||||||
|
Name: user.Name,
|
||||||
|
}
|
||||||
|
u.mu.Lock()
|
||||||
|
defer u.mu.Unlock()
|
||||||
|
for _, to := range tos {
|
||||||
|
m.ToID = to
|
||||||
|
err = u.db.InsertUnique(UserTableMessage, &m)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// notifyUserAdded will send notification to all supers
|
||||||
|
func (u *UserDatabase) notifyUserAdded(opname, name string, nuid int) error {
|
||||||
|
if opname == "" || name == "" {
|
||||||
|
return ErrEmptyName
|
||||||
|
}
|
||||||
|
|
||||||
|
tos, err := u.GetSuperIDs()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
m := Message{
|
||||||
|
Date: time.Now().Unix(),
|
||||||
|
Text: opname + " 添加了用户 " + name,
|
||||||
|
Cont: opname,
|
||||||
|
}
|
||||||
|
u.mu.Lock()
|
||||||
|
defer u.mu.Unlock()
|
||||||
|
for _, to := range tos {
|
||||||
|
if nuid == to {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
m.ToID = to
|
||||||
|
err = u.db.InsertUnique(UserTableMessage, &m)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// notifyContactChange will send notification to all supers
|
||||||
|
func (u *UserDatabase) notifyContactChange(name, cont string, id int) error {
|
||||||
|
if name == "" {
|
||||||
|
return ErrEmptyName
|
||||||
|
}
|
||||||
|
if cont == "" {
|
||||||
|
return ErrEmptyContact
|
||||||
|
}
|
||||||
|
|
||||||
|
tos, err := u.GetSuperIDs()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
m := Message{
|
||||||
|
Date: time.Now().Unix(),
|
||||||
|
Text: "用户 " + name + " 更改联系方式为: " + cont,
|
||||||
|
Name: name,
|
||||||
|
Cont: cont,
|
||||||
|
}
|
||||||
|
u.mu.Lock()
|
||||||
|
defer u.mu.Unlock()
|
||||||
|
for _, to := range tos {
|
||||||
|
if id == to {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
m.ToID = to
|
||||||
|
err = u.db.InsertUnique(UserTableMessage, &m)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// notifyPasswordChange will send notification to all supers
|
||||||
|
func (u *UserDatabase) notifyPasswordChange(name, npwd, opname string, id int) error {
|
||||||
|
if name == "" {
|
||||||
|
return ErrEmptyName
|
||||||
|
}
|
||||||
|
|
||||||
|
tos, err := u.GetSuperIDs()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
m := Message{
|
||||||
|
Date: time.Now().Unix(),
|
||||||
|
Text: "用户 " + name + " 被 " + opname + " 更改了密码",
|
||||||
|
Name: name,
|
||||||
|
Pswd: npwd,
|
||||||
|
}
|
||||||
|
u.mu.Lock()
|
||||||
|
defer u.mu.Unlock()
|
||||||
|
for _, to := range tos {
|
||||||
|
if id == to {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
m.ToID = to
|
||||||
|
err = u.db.InsertUnique(UserTableMessage, &m)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// notifyPasswordChange will send notification to all supers
|
||||||
|
func (u *UserDatabase) notifyUpdateUserRole(name, opname string, role UserRole, id int) error {
|
||||||
|
if name == "" || opname == "" {
|
||||||
|
return ErrEmptyName
|
||||||
|
}
|
||||||
|
|
||||||
|
tos, err := u.GetSuperIDs()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
m := Message{
|
||||||
|
Date: time.Now().Unix(),
|
||||||
|
Text: name + " 的权限被 " + opname + " 变更为 " + role.Nick(),
|
||||||
|
Cont: opname,
|
||||||
|
Pswd: "opname",
|
||||||
|
}
|
||||||
|
u.mu.Lock()
|
||||||
|
defer u.mu.Unlock()
|
||||||
|
for _, to := range tos {
|
||||||
|
if id == to {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
m.ToID = to
|
||||||
|
err = u.db.InsertUnique(UserTableMessage, &m)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// notifyPasswordChange will send notification to all supers
|
||||||
|
func (u *UserDatabase) notifyDisableUser(name, opname string, id int) error {
|
||||||
|
if name == "" || opname == "" {
|
||||||
|
return ErrEmptyName
|
||||||
|
}
|
||||||
|
|
||||||
|
tos, err := u.GetSuperIDs()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
m := Message{
|
||||||
|
Date: time.Now().Unix(),
|
||||||
|
Text: name + " 的账户被 " + opname + " 禁用",
|
||||||
|
Cont: opname,
|
||||||
|
Pswd: "opname",
|
||||||
|
}
|
||||||
|
u.mu.Lock()
|
||||||
|
defer u.mu.Unlock()
|
||||||
|
for _, to := range tos {
|
||||||
|
if id == to {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
m.ToID = to
|
||||||
|
err = u.db.InsertUnique(UserTableMessage, &m)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetMessagesOfUser will change non-empty Pswd field to "-"
|
||||||
|
func (u *UserDatabase) GetMessagesOfUser(to int) (ms []Message, err error) {
|
||||||
|
u.mu.RLock()
|
||||||
|
defer u.mu.RUnlock()
|
||||||
|
n, err := u.db.Count(UserTableMessage)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ms = make([]Message, 0, n)
|
||||||
|
m := Message{}
|
||||||
|
err = u.db.FindFor(UserTableMessage, &m, "WHERE ToID="+strconv.Itoa(to)+" ORDER BY Date DESC", func() error {
|
||||||
|
if m.Pswd != "" {
|
||||||
|
m.Pswd = "-"
|
||||||
|
}
|
||||||
|
ms = append(ms, m)
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetMessageByID ...
|
||||||
|
func (u *UserDatabase) GetMessageByID(id int) (m Message, err error) {
|
||||||
|
u.mu.RLock()
|
||||||
|
err = u.db.Find(UserTableMessage, &m, "WHERE ID="+strconv.Itoa(id))
|
||||||
|
u.mu.RUnlock()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// DelMessageByID ...
|
||||||
|
func (u *UserDatabase) DelMessageByID(id int) (err error) {
|
||||||
|
u.mu.Lock()
|
||||||
|
err = u.db.Del(UserTableMessage, "WHERE ID="+strconv.Itoa(id))
|
||||||
|
u.mu.Unlock()
|
||||||
|
return
|
||||||
|
}
|
||||||
81
backend/global/regex.go
Normal file
81
backend/global/regex.go
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
package global
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"regexp"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Regex stores user's config of splitting docx file
|
||||||
|
type Regex struct {
|
||||||
|
ID int // ID is User(ID)
|
||||||
|
Title string // Title default `.*(\d{4})\s*-.*学年.*(\d).*([中末]).*([AB])\s*卷`
|
||||||
|
Class string // Class default `考试科目:\s*(\S+)\s*`
|
||||||
|
OpenCl string // OpenCl default `考试形式:\s*(\S+)\s*`
|
||||||
|
Date string // Date default `考试日期:\s*(\d+)\s*年\s*(\d+)\s*月\s*(\d+)\s*日`
|
||||||
|
Time string // Time default `考试时长:\s*(\d+)\s*分钟`
|
||||||
|
Rate string // Rate default `成绩构成比例:\s*(.*%)\s*`
|
||||||
|
Major string // Major default `([一二三四五六七八九十]+)、\s*(.*)\s*(.*([空题]?)\s*(\d*).*共\s*(\d+)\s*分.*)`
|
||||||
|
Sub string // Sub default `(\d+)、`
|
||||||
|
}
|
||||||
|
|
||||||
|
func newRegex() (reg Regex) {
|
||||||
|
reg.Title = `.*(\d{4})\s*-.*学年.*(\d).*([中末]).*([AB])\s*卷`
|
||||||
|
reg.Class = `考试科目:\s*(\S+)\s*`
|
||||||
|
reg.OpenCl = `考试形式:\s*(\S+)\s*`
|
||||||
|
reg.Date = `考试日期:\s*(\d+)\s*年\s*(\d+)\s*月\s*(\d+)\s*日`
|
||||||
|
reg.Time = `考试时长:\s*(\d+)\s*分钟`
|
||||||
|
reg.Rate = `成绩构成比例:\s*(.*%)\s*`
|
||||||
|
reg.Major = `([一二三四五六七八九十]+)、\s*(.*)\s*(.*([空题]?)\s*(\d*).*共\s*(\d+)\s*分.*)`
|
||||||
|
reg.Sub = `(\d+)、`
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetUserRegex set Regex.name = re
|
||||||
|
func (u *UserDatabase) SetUserRegex(id int, name, re string) error {
|
||||||
|
if name == "" || name == "ID" {
|
||||||
|
return ErrInvalidFieldName
|
||||||
|
}
|
||||||
|
if re == "" {
|
||||||
|
return ErrEmptyRegex
|
||||||
|
}
|
||||||
|
user, err := UserDB.GetUserByID(id)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !user.IsFileManager() {
|
||||||
|
return ErrInvalidRole
|
||||||
|
}
|
||||||
|
_, err = regexp.Compile(re)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
reg := newRegex()
|
||||||
|
rreg := reflect.ValueOf(®).Elem()
|
||||||
|
f := rreg.FieldByName(name)
|
||||||
|
if !f.IsValid() {
|
||||||
|
return ErrNoSuchFieldName
|
||||||
|
}
|
||||||
|
u.mu.Lock()
|
||||||
|
defer u.mu.Unlock()
|
||||||
|
_ = u.db.Find(UserTableRegex, ®, "WHERE ID="+strconv.Itoa(id))
|
||||||
|
reg.ID = id
|
||||||
|
f.SetString(re)
|
||||||
|
return u.db.Insert(UserTableRegex, ®)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetUserRegex default newRegex()
|
||||||
|
func (u *UserDatabase) GetUserRegex(id int) (*Regex, error) {
|
||||||
|
user, err := UserDB.GetUserByID(id)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if !user.IsFileManager() {
|
||||||
|
return nil, ErrInvalidRole
|
||||||
|
}
|
||||||
|
reg := newRegex()
|
||||||
|
u.mu.RLock()
|
||||||
|
_ = u.db.Find(UserTableRegex, ®, "WHERE ID="+strconv.Itoa(id))
|
||||||
|
u.mu.RUnlock()
|
||||||
|
return ®, nil
|
||||||
|
}
|
||||||
62
backend/global/role.go
Normal file
62
backend/global/role.go
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
package global
|
||||||
|
|
||||||
|
const (
|
||||||
|
RoleNil UserRole = iota
|
||||||
|
RoleSuper
|
||||||
|
RoleFileManager
|
||||||
|
RoleUser
|
||||||
|
RoleTop
|
||||||
|
)
|
||||||
|
|
||||||
|
type UserRole uint8
|
||||||
|
|
||||||
|
func (r UserRole) IsVaild() bool {
|
||||||
|
return r > RoleNil && r < RoleTop
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r UserRole) String() string {
|
||||||
|
switch r {
|
||||||
|
case RoleSuper:
|
||||||
|
return "super"
|
||||||
|
case RoleFileManager:
|
||||||
|
return "filemgr"
|
||||||
|
case RoleUser:
|
||||||
|
return "user"
|
||||||
|
}
|
||||||
|
return "invalid"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r UserRole) Nick() string {
|
||||||
|
switch r {
|
||||||
|
case RoleSuper:
|
||||||
|
return "课程组长"
|
||||||
|
case RoleFileManager:
|
||||||
|
return "归档代理"
|
||||||
|
case RoleUser:
|
||||||
|
return "课程组员"
|
||||||
|
}
|
||||||
|
return "非法角色"
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateUserRole ...
|
||||||
|
func (u *UserDatabase) UpdateUserRole(id int, nr UserRole, opname string) error {
|
||||||
|
if nr == RoleNil || nr > RoleUser {
|
||||||
|
return ErrInvalidRole
|
||||||
|
}
|
||||||
|
user, err := u.GetUserByID(id)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if opname == user.Name {
|
||||||
|
return ErrInvalidName
|
||||||
|
}
|
||||||
|
user.Role = nr
|
||||||
|
u.mu.Lock()
|
||||||
|
err = u.db.Insert(UserTableUser, &user)
|
||||||
|
u.mu.Unlock()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_ = u.SendMessage("您的权限被 "+opname+" 变更为 "+user.Role.Nick(), opname, *user.ID)
|
||||||
|
return u.notifyUpdateUserRole(user.Name, opname, nr, *user.ID)
|
||||||
|
}
|
||||||
@@ -3,8 +3,6 @@ package global
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"os"
|
"os"
|
||||||
"reflect"
|
|
||||||
"regexp"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -12,56 +10,6 @@ import (
|
|||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
RoleNil UserRole = iota
|
|
||||||
RoleSuper
|
|
||||||
RoleFileManager
|
|
||||||
RoleUser
|
|
||||||
RoleTop
|
|
||||||
)
|
|
||||||
|
|
||||||
type UserRole uint8
|
|
||||||
|
|
||||||
func (r UserRole) IsVaild() bool {
|
|
||||||
return r > RoleNil && r < RoleTop
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r UserRole) String() string {
|
|
||||||
switch r {
|
|
||||||
case RoleSuper:
|
|
||||||
return "super"
|
|
||||||
case RoleFileManager:
|
|
||||||
return "filemgr"
|
|
||||||
case RoleUser:
|
|
||||||
return "user"
|
|
||||||
}
|
|
||||||
return "invalid"
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r UserRole) Nick() string {
|
|
||||||
switch r {
|
|
||||||
case RoleSuper:
|
|
||||||
return "课程组长"
|
|
||||||
case RoleFileManager:
|
|
||||||
return "归档代理"
|
|
||||||
case RoleUser:
|
|
||||||
return "课程组员"
|
|
||||||
}
|
|
||||||
return "非法角色"
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
MessageNormal MessageType = iota
|
|
||||||
MessageRegister
|
|
||||||
MessageUserAdded
|
|
||||||
MessageContactChange
|
|
||||||
MessagePasswordChange
|
|
||||||
MessageResetPassword
|
|
||||||
MessageOperator
|
|
||||||
)
|
|
||||||
|
|
||||||
type MessageType uint8
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
UserTableUser = "user"
|
UserTableUser = "user"
|
||||||
UserTableMessage = "msg"
|
UserTableMessage = "msg"
|
||||||
@@ -216,29 +164,6 @@ func (u *UserDatabase) UpdateUserInfo(id int, opname, nick, avtr, desc string) e
|
|||||||
return u.SendMessage("更新了个人信息", opname, *user.ID)
|
return u.SendMessage("更新了个人信息", opname, *user.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateUserRole ...
|
|
||||||
func (u *UserDatabase) UpdateUserRole(id int, nr UserRole, opname string) error {
|
|
||||||
if nr == RoleNil || nr > RoleUser {
|
|
||||||
return ErrInvalidRole
|
|
||||||
}
|
|
||||||
user, err := u.GetUserByID(id)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if opname == user.Name {
|
|
||||||
return ErrInvalidName
|
|
||||||
}
|
|
||||||
user.Role = nr
|
|
||||||
u.mu.Lock()
|
|
||||||
err = u.db.Insert(UserTableUser, &user)
|
|
||||||
u.mu.Unlock()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
_ = u.SendMessage("您的权限被 "+opname+" 变更为 "+user.Role.Nick(), opname, *user.ID)
|
|
||||||
return u.notifyUpdateUserRole(user.Name, opname, nr, *user.ID)
|
|
||||||
}
|
|
||||||
|
|
||||||
// DisableUser ...
|
// DisableUser ...
|
||||||
func (u *UserDatabase) DisableUser(id int, opname string) error {
|
func (u *UserDatabase) DisableUser(id int, opname string) error {
|
||||||
user, err := u.GetUserByID(id)
|
user, err := u.GetUserByID(id)
|
||||||
@@ -414,459 +339,3 @@ func (user *User) IsFileManager() bool {
|
|||||||
func (user *User) IsSuper() bool {
|
func (user *User) IsSuper() bool {
|
||||||
return user.Role == RoleSuper
|
return user.Role == RoleSuper
|
||||||
}
|
}
|
||||||
|
|
||||||
// Message is shown in the workbench
|
|
||||||
type Message struct {
|
|
||||||
ID *int
|
|
||||||
ToID int // ToID user's ID
|
|
||||||
Date int64
|
|
||||||
Text string // Text is the message content
|
|
||||||
Name string // Name is the user's name to add in register message
|
|
||||||
Cont string // Cont is the user's phone number to add in register message or an operator's name in add user message
|
|
||||||
Pswd string // Pswd is the user's password to add in register message
|
|
||||||
}
|
|
||||||
|
|
||||||
// Type decide message type by fields Name, Cont and Pswd.
|
|
||||||
func (m *Message) Type() MessageType {
|
|
||||||
switch {
|
|
||||||
case m.Name != "" && m.Cont != "" && m.Pswd != "":
|
|
||||||
return MessageRegister
|
|
||||||
case m.Name == "" && m.Cont != "" && m.Pswd == "":
|
|
||||||
return MessageUserAdded
|
|
||||||
case m.Name != "" && m.Cont != "" && m.Pswd == "":
|
|
||||||
return MessageContactChange
|
|
||||||
case m.Name != "" && m.Cont == "" && m.Pswd != "":
|
|
||||||
return MessagePasswordChange
|
|
||||||
case m.Name != "" && m.Cont == "" && m.Pswd == "":
|
|
||||||
return MessageResetPassword
|
|
||||||
case m.Name == "" && m.Cont != "" && m.Pswd != "":
|
|
||||||
return MessageOperator
|
|
||||||
default:
|
|
||||||
return MessageNormal
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// SendMessage will send a normal message to id
|
|
||||||
func (u *UserDatabase) SendMessage(text, opname string, to int) error {
|
|
||||||
if !u.IsIDExists(to) {
|
|
||||||
return ErrInvalidUserID
|
|
||||||
}
|
|
||||||
m := Message{ToID: to, Date: time.Now().Unix(), Text: text, Cont: opname, Pswd: "opname"}
|
|
||||||
u.mu.Lock()
|
|
||||||
defer u.mu.Unlock()
|
|
||||||
return u.db.InsertUnique(UserTableMessage, &m)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NotifyRegister will send register notification to all supers
|
|
||||||
func (u *UserDatabase) NotifyRegister(ip, name, cont, pswd string) error {
|
|
||||||
if name == "" {
|
|
||||||
return ErrEmptyName
|
|
||||||
}
|
|
||||||
if cont == "" {
|
|
||||||
return ErrEmptyContact
|
|
||||||
}
|
|
||||||
if pswd == "" {
|
|
||||||
return ErrEmptyPassword
|
|
||||||
}
|
|
||||||
for _, c := range name {
|
|
||||||
if !(c >= '0' && c <= '9') && !(c >= 'A' && c <= 'Z') && !(c >= 'a' && c <= 'z') {
|
|
||||||
return ErrInvalidName
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if u.IsNameExists(name) {
|
|
||||||
return ErrInvalidName
|
|
||||||
}
|
|
||||||
|
|
||||||
tos, err := u.GetSuperIDs()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
m := Message{
|
|
||||||
Date: time.Now().Unix(),
|
|
||||||
Text: "收到来自 " + ip + ", 用户名 " + name + " 的注册请求, 联系方式: " + cont,
|
|
||||||
Name: name,
|
|
||||||
Cont: cont,
|
|
||||||
Pswd: pswd,
|
|
||||||
}
|
|
||||||
u.mu.Lock()
|
|
||||||
defer u.mu.Unlock()
|
|
||||||
for _, to := range tos {
|
|
||||||
m.ToID = to
|
|
||||||
err = u.db.InsertUnique(UserTableMessage, &m)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// NotifyResetPassword will send notification to all supers
|
|
||||||
func (u *UserDatabase) NotifyResetPassword(ip, name, cont string) error {
|
|
||||||
if name == "" {
|
|
||||||
return ErrEmptyName
|
|
||||||
}
|
|
||||||
if cont == "" {
|
|
||||||
return ErrEmptyContact
|
|
||||||
}
|
|
||||||
for _, c := range name {
|
|
||||||
if !(c >= '0' && c <= '9') && !(c >= 'A' && c <= 'Z') && !(c >= 'a' && c <= 'z') {
|
|
||||||
return ErrInvalidName
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
user, err := u.GetUserByName(name)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if cont != user.Cont {
|
|
||||||
return ErrInvalidContact
|
|
||||||
}
|
|
||||||
|
|
||||||
tos, err := u.GetSuperIDs()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = u.SendMessage("发送重置密码请求", user.Name, *user.ID)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
m := Message{
|
|
||||||
Date: time.Now().Unix(),
|
|
||||||
Text: "收到来自 " + ip + ", 用户名 " + user.Name + " 的重置密码请求, 联系方式: " + user.Cont,
|
|
||||||
Name: user.Name,
|
|
||||||
}
|
|
||||||
u.mu.Lock()
|
|
||||||
defer u.mu.Unlock()
|
|
||||||
for _, to := range tos {
|
|
||||||
m.ToID = to
|
|
||||||
err = u.db.InsertUnique(UserTableMessage, &m)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// notifyUserAdded will send notification to all supers
|
|
||||||
func (u *UserDatabase) notifyUserAdded(opname, name string, nuid int) error {
|
|
||||||
if opname == "" || name == "" {
|
|
||||||
return ErrEmptyName
|
|
||||||
}
|
|
||||||
|
|
||||||
tos, err := u.GetSuperIDs()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
m := Message{
|
|
||||||
Date: time.Now().Unix(),
|
|
||||||
Text: opname + " 添加了用户 " + name,
|
|
||||||
Cont: opname,
|
|
||||||
}
|
|
||||||
u.mu.Lock()
|
|
||||||
defer u.mu.Unlock()
|
|
||||||
for _, to := range tos {
|
|
||||||
if nuid == to {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
m.ToID = to
|
|
||||||
err = u.db.InsertUnique(UserTableMessage, &m)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// notifyContactChange will send notification to all supers
|
|
||||||
func (u *UserDatabase) notifyContactChange(name, cont string, id int) error {
|
|
||||||
if name == "" {
|
|
||||||
return ErrEmptyName
|
|
||||||
}
|
|
||||||
if cont == "" {
|
|
||||||
return ErrEmptyContact
|
|
||||||
}
|
|
||||||
|
|
||||||
tos, err := u.GetSuperIDs()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
m := Message{
|
|
||||||
Date: time.Now().Unix(),
|
|
||||||
Text: "用户 " + name + " 更改联系方式为: " + cont,
|
|
||||||
Name: name,
|
|
||||||
Cont: cont,
|
|
||||||
}
|
|
||||||
u.mu.Lock()
|
|
||||||
defer u.mu.Unlock()
|
|
||||||
for _, to := range tos {
|
|
||||||
if id == to {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
m.ToID = to
|
|
||||||
err = u.db.InsertUnique(UserTableMessage, &m)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// notifyPasswordChange will send notification to all supers
|
|
||||||
func (u *UserDatabase) notifyPasswordChange(name, npwd, opname string, id int) error {
|
|
||||||
if name == "" {
|
|
||||||
return ErrEmptyName
|
|
||||||
}
|
|
||||||
|
|
||||||
tos, err := u.GetSuperIDs()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
m := Message{
|
|
||||||
Date: time.Now().Unix(),
|
|
||||||
Text: "用户 " + name + " 被 " + opname + " 更改了密码",
|
|
||||||
Name: name,
|
|
||||||
Pswd: npwd,
|
|
||||||
}
|
|
||||||
u.mu.Lock()
|
|
||||||
defer u.mu.Unlock()
|
|
||||||
for _, to := range tos {
|
|
||||||
if id == to {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
m.ToID = to
|
|
||||||
err = u.db.InsertUnique(UserTableMessage, &m)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// notifyPasswordChange will send notification to all supers
|
|
||||||
func (u *UserDatabase) notifyUpdateUserRole(name, opname string, role UserRole, id int) error {
|
|
||||||
if name == "" || opname == "" {
|
|
||||||
return ErrEmptyName
|
|
||||||
}
|
|
||||||
|
|
||||||
tos, err := u.GetSuperIDs()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
m := Message{
|
|
||||||
Date: time.Now().Unix(),
|
|
||||||
Text: name + " 的权限被 " + opname + " 变更为 " + role.Nick(),
|
|
||||||
Cont: opname,
|
|
||||||
Pswd: "opname",
|
|
||||||
}
|
|
||||||
u.mu.Lock()
|
|
||||||
defer u.mu.Unlock()
|
|
||||||
for _, to := range tos {
|
|
||||||
if id == to {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
m.ToID = to
|
|
||||||
err = u.db.InsertUnique(UserTableMessage, &m)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// notifyPasswordChange will send notification to all supers
|
|
||||||
func (u *UserDatabase) notifyDisableUser(name, opname string, id int) error {
|
|
||||||
if name == "" || opname == "" {
|
|
||||||
return ErrEmptyName
|
|
||||||
}
|
|
||||||
|
|
||||||
tos, err := u.GetSuperIDs()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
m := Message{
|
|
||||||
Date: time.Now().Unix(),
|
|
||||||
Text: name + " 的账户被 " + opname + " 禁用",
|
|
||||||
Cont: opname,
|
|
||||||
Pswd: "opname",
|
|
||||||
}
|
|
||||||
u.mu.Lock()
|
|
||||||
defer u.mu.Unlock()
|
|
||||||
for _, to := range tos {
|
|
||||||
if id == to {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
m.ToID = to
|
|
||||||
err = u.db.InsertUnique(UserTableMessage, &m)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetMessagesOfUser will change non-empty Pswd field to "-"
|
|
||||||
func (u *UserDatabase) GetMessagesOfUser(to int) (ms []Message, err error) {
|
|
||||||
u.mu.RLock()
|
|
||||||
defer u.mu.RUnlock()
|
|
||||||
n, err := u.db.Count(UserTableMessage)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ms = make([]Message, 0, n)
|
|
||||||
m := Message{}
|
|
||||||
err = u.db.FindFor(UserTableMessage, &m, "WHERE ToID="+strconv.Itoa(to)+" ORDER BY Date DESC", func() error {
|
|
||||||
if m.Pswd != "" {
|
|
||||||
m.Pswd = "-"
|
|
||||||
}
|
|
||||||
ms = append(ms, m)
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetMessageByID ...
|
|
||||||
func (u *UserDatabase) GetMessageByID(id int) (m Message, err error) {
|
|
||||||
u.mu.RLock()
|
|
||||||
err = u.db.Find(UserTableMessage, &m, "WHERE ID="+strconv.Itoa(id))
|
|
||||||
u.mu.RUnlock()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// DelMessageByID ...
|
|
||||||
func (u *UserDatabase) DelMessageByID(id int) (err error) {
|
|
||||||
u.mu.Lock()
|
|
||||||
err = u.db.Del(UserTableMessage, "WHERE ID="+strconv.Itoa(id))
|
|
||||||
u.mu.Unlock()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// MonthlyAPIVisit counts the api visit history
|
|
||||||
type MonthlyAPIVisit struct {
|
|
||||||
YM uint32 // YM is yyyymm
|
|
||||||
Count uint32 // visit count this mounth
|
|
||||||
}
|
|
||||||
|
|
||||||
// VisitAPI increases count of this mounth by 1
|
|
||||||
func (u *UserDatabase) VisitAPI() {
|
|
||||||
now := time.Now()
|
|
||||||
ym := uint32(now.Year())*100 + uint32(now.Month())
|
|
||||||
var v MonthlyAPIVisit
|
|
||||||
u.mu.Lock()
|
|
||||||
defer u.mu.Unlock()
|
|
||||||
_ = u.db.Find(UserTableMonthlyAPIVisit, &v, "WHERE YM="+strconv.FormatUint(uint64(ym), 10))
|
|
||||||
v.YM = ym
|
|
||||||
v.Count++
|
|
||||||
err := u.db.Insert(UserTableMonthlyAPIVisit, &v)
|
|
||||||
if err != nil {
|
|
||||||
logrus.Warnln("[global.user] insert visit error:", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetAnnualAPIVisitCount get the latest 12 mounths' count
|
|
||||||
func (u *UserDatabase) GetAnnualAPIVisitCount() (cnts [12]uint32) {
|
|
||||||
var v MonthlyAPIVisit
|
|
||||||
var yms [12]uint32
|
|
||||||
now := time.Now()
|
|
||||||
y100 := uint32(now.Year()) * 100
|
|
||||||
py100 := uint32(now.Year()-1) * 100
|
|
||||||
nm := int(now.Month())
|
|
||||||
for i := 0; i < nm; i++ {
|
|
||||||
yms[i] = y100 + uint32(i+1)
|
|
||||||
}
|
|
||||||
for i := nm; i < 12; i++ {
|
|
||||||
yms[i] = py100 + uint32(i+1)
|
|
||||||
}
|
|
||||||
u.mu.RLock()
|
|
||||||
defer u.mu.RUnlock()
|
|
||||||
i := 0
|
|
||||||
for _, ym := range yms {
|
|
||||||
_ = u.db.Find(UserTableMonthlyAPIVisit, &v, "WHERE YM="+strconv.FormatUint(uint64(ym), 10))
|
|
||||||
cnts[i] = v.Count
|
|
||||||
i++
|
|
||||||
v.Count = 0
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Regex stores user's config of splitting docx file
|
|
||||||
type Regex struct {
|
|
||||||
ID int // ID is User(ID)
|
|
||||||
Title string // Title default `.*(\d{4})\s*-.*学年.*(\d).*([中末]).*([AB])\s*卷`
|
|
||||||
Class string // Class default `考试科目:\s*(\S+)\s*`
|
|
||||||
OpenCl string // OpenCl default `考试形式:\s*(\S+)\s*`
|
|
||||||
Date string // Date default `考试日期:\s*(\d+)\s*年\s*(\d+)\s*月\s*(\d+)\s*日`
|
|
||||||
Time string // Time default `考试时长:\s*(\d+)\s*分钟`
|
|
||||||
Rate string // Rate default `成绩构成比例:\s*(.*%)\s*`
|
|
||||||
Major string // Major default `([一二三四五六七八九十]+)、\s*(.*)\s*(.*([空题]?)\s*(\d*).*共\s*(\d+)\s*分.*)`
|
|
||||||
Sub string // Sub default `(\d+)、`
|
|
||||||
}
|
|
||||||
|
|
||||||
func newRegex() (reg Regex) {
|
|
||||||
reg.Title = `.*(\d{4})\s*-.*学年.*(\d).*([中末]).*([AB])\s*卷`
|
|
||||||
reg.Class = `考试科目:\s*(\S+)\s*`
|
|
||||||
reg.OpenCl = `考试形式:\s*(\S+)\s*`
|
|
||||||
reg.Date = `考试日期:\s*(\d+)\s*年\s*(\d+)\s*月\s*(\d+)\s*日`
|
|
||||||
reg.Time = `考试时长:\s*(\d+)\s*分钟`
|
|
||||||
reg.Rate = `成绩构成比例:\s*(.*%)\s*`
|
|
||||||
reg.Major = `([一二三四五六七八九十]+)、\s*(.*)\s*(.*([空题]?)\s*(\d*).*共\s*(\d+)\s*分.*)`
|
|
||||||
reg.Sub = `(\d+)、`
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetUserRegex set Regex.name = re
|
|
||||||
func (u *UserDatabase) SetUserRegex(id int, name, re string) error {
|
|
||||||
if name == "" || name == "ID" {
|
|
||||||
return ErrInvalidFieldName
|
|
||||||
}
|
|
||||||
if re == "" {
|
|
||||||
return ErrEmptyRegex
|
|
||||||
}
|
|
||||||
user, err := UserDB.GetUserByID(id)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if !user.IsFileManager() {
|
|
||||||
return ErrInvalidRole
|
|
||||||
}
|
|
||||||
_, err = regexp.Compile(re)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
reg := newRegex()
|
|
||||||
rreg := reflect.ValueOf(®).Elem()
|
|
||||||
f := rreg.FieldByName(name)
|
|
||||||
if !f.IsValid() {
|
|
||||||
return ErrNoSuchFieldName
|
|
||||||
}
|
|
||||||
u.mu.Lock()
|
|
||||||
defer u.mu.Unlock()
|
|
||||||
_ = u.db.Find(UserTableRegex, ®, "WHERE ID="+strconv.Itoa(id))
|
|
||||||
reg.ID = id
|
|
||||||
f.SetString(re)
|
|
||||||
return u.db.Insert(UserTableRegex, ®)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetUserRegex default newRegex()
|
|
||||||
func (u *UserDatabase) GetUserRegex(id int) (*Regex, error) {
|
|
||||||
user, err := UserDB.GetUserByID(id)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if !user.IsFileManager() {
|
|
||||||
return nil, ErrInvalidRole
|
|
||||||
}
|
|
||||||
reg := newRegex()
|
|
||||||
u.mu.RLock()
|
|
||||||
_ = u.db.Find(UserTableRegex, ®, "WHERE ID="+strconv.Itoa(id))
|
|
||||||
u.mu.RUnlock()
|
|
||||||
return ®, nil
|
|
||||||
}
|
|
||||||
|
|||||||
56
backend/global/visit.go
Normal file
56
backend/global/visit.go
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
package global
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
// MonthlyAPIVisit counts the api visit history
|
||||||
|
type MonthlyAPIVisit struct {
|
||||||
|
YM uint32 // YM is yyyymm
|
||||||
|
Count uint32 // visit count this mounth
|
||||||
|
}
|
||||||
|
|
||||||
|
// VisitAPI increases count of this mounth by 1
|
||||||
|
func (u *UserDatabase) VisitAPI() {
|
||||||
|
now := time.Now()
|
||||||
|
ym := uint32(now.Year())*100 + uint32(now.Month())
|
||||||
|
var v MonthlyAPIVisit
|
||||||
|
u.mu.Lock()
|
||||||
|
defer u.mu.Unlock()
|
||||||
|
_ = u.db.Find(UserTableMonthlyAPIVisit, &v, "WHERE YM="+strconv.FormatUint(uint64(ym), 10))
|
||||||
|
v.YM = ym
|
||||||
|
v.Count++
|
||||||
|
err := u.db.Insert(UserTableMonthlyAPIVisit, &v)
|
||||||
|
if err != nil {
|
||||||
|
logrus.Warnln("[global.user] insert visit error:", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAnnualAPIVisitCount get the latest 12 mounths' count
|
||||||
|
func (u *UserDatabase) GetAnnualAPIVisitCount() (cnts [12]uint32) {
|
||||||
|
var v MonthlyAPIVisit
|
||||||
|
var yms [12]uint32
|
||||||
|
now := time.Now()
|
||||||
|
y100 := uint32(now.Year()) * 100
|
||||||
|
py100 := uint32(now.Year()-1) * 100
|
||||||
|
nm := int(now.Month())
|
||||||
|
for i := 0; i < nm; i++ {
|
||||||
|
yms[i] = y100 + uint32(i+1)
|
||||||
|
}
|
||||||
|
for i := nm; i < 12; i++ {
|
||||||
|
yms[i] = py100 + uint32(i+1)
|
||||||
|
}
|
||||||
|
u.mu.RLock()
|
||||||
|
defer u.mu.RUnlock()
|
||||||
|
i := 0
|
||||||
|
for _, ym := range yms {
|
||||||
|
_ = u.db.Find(UserTableMonthlyAPIVisit, &v, "WHERE YM="+strconv.FormatUint(uint64(ym), 10))
|
||||||
|
cnts[i] = v.Count
|
||||||
|
i++
|
||||||
|
v.Count = 0
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user