mirror of
https://github.com/casdoor/casdoor.git
synced 2025-07-01 18:40:18 +08:00
feat: provide a more complete Excel template for uploading users and fix any bugs (#3831)
This commit is contained in:
@ -81,62 +81,12 @@ func UploadUsers(owner string, path string) (bool, error) {
|
|||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
transUsers, err := StringArrayToUser(table)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
newUsers := []*User{}
|
newUsers := []*User{}
|
||||||
for index, line := range table {
|
for _, user := range transUsers {
|
||||||
line := line
|
|
||||||
if index == 0 || parseLineItem(&line, 0) == "" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
user := &User{
|
|
||||||
Owner: parseLineItem(&line, 0),
|
|
||||||
Name: parseLineItem(&line, 1),
|
|
||||||
CreatedTime: parseLineItem(&line, 2),
|
|
||||||
UpdatedTime: parseLineItem(&line, 3),
|
|
||||||
Id: parseLineItem(&line, 4),
|
|
||||||
Type: parseLineItem(&line, 5),
|
|
||||||
Password: parseLineItem(&line, 6),
|
|
||||||
PasswordSalt: parseLineItem(&line, 7),
|
|
||||||
DisplayName: parseLineItem(&line, 8),
|
|
||||||
FirstName: parseLineItem(&line, 9),
|
|
||||||
LastName: parseLineItem(&line, 10),
|
|
||||||
Avatar: parseLineItem(&line, 11),
|
|
||||||
PermanentAvatar: "",
|
|
||||||
Email: parseLineItem(&line, 12),
|
|
||||||
Phone: parseLineItem(&line, 13),
|
|
||||||
Location: parseLineItem(&line, 14),
|
|
||||||
Address: []string{parseLineItem(&line, 15)},
|
|
||||||
Affiliation: parseLineItem(&line, 16),
|
|
||||||
Title: parseLineItem(&line, 17),
|
|
||||||
IdCardType: parseLineItem(&line, 18),
|
|
||||||
IdCard: parseLineItem(&line, 19),
|
|
||||||
Homepage: parseLineItem(&line, 20),
|
|
||||||
Bio: parseLineItem(&line, 21),
|
|
||||||
Tag: parseLineItem(&line, 22),
|
|
||||||
Region: parseLineItem(&line, 23),
|
|
||||||
Language: parseLineItem(&line, 24),
|
|
||||||
Gender: parseLineItem(&line, 25),
|
|
||||||
Birthday: parseLineItem(&line, 26),
|
|
||||||
Education: parseLineItem(&line, 27),
|
|
||||||
Score: parseLineItemInt(&line, 28),
|
|
||||||
Karma: parseLineItemInt(&line, 29),
|
|
||||||
Ranking: parseLineItemInt(&line, 30),
|
|
||||||
IsDefaultAvatar: false,
|
|
||||||
IsOnline: parseLineItemBool(&line, 31),
|
|
||||||
IsAdmin: parseLineItemBool(&line, 32),
|
|
||||||
IsForbidden: parseLineItemBool(&line, 33),
|
|
||||||
IsDeleted: parseLineItemBool(&line, 34),
|
|
||||||
SignupApplication: parseLineItem(&line, 35),
|
|
||||||
Hash: "",
|
|
||||||
PreHash: "",
|
|
||||||
CreatedIp: parseLineItem(&line, 36),
|
|
||||||
LastSigninTime: parseLineItem(&line, 37),
|
|
||||||
LastSigninIp: parseLineItem(&line, 38),
|
|
||||||
Ldap: "",
|
|
||||||
Properties: map[string]string{},
|
|
||||||
DeletedTime: parseLineItem(&line, 39),
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, ok := oldUserMap[user.GetId()]; !ok {
|
if _, ok := oldUserMap[user.GetId()]; !ok {
|
||||||
newUsers = append(newUsers, user)
|
newUsers = append(newUsers, user)
|
||||||
}
|
}
|
||||||
|
@ -19,12 +19,14 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/casdoor/casdoor/conf"
|
"github.com/casdoor/casdoor/conf"
|
||||||
"github.com/casdoor/casdoor/i18n"
|
"github.com/casdoor/casdoor/i18n"
|
||||||
"github.com/casdoor/casdoor/idp"
|
"github.com/casdoor/casdoor/idp"
|
||||||
"github.com/casdoor/casdoor/util"
|
"github.com/casdoor/casdoor/util"
|
||||||
|
"github.com/go-webauthn/webauthn/webauthn"
|
||||||
jsoniter "github.com/json-iterator/go"
|
jsoniter "github.com/json-iterator/go"
|
||||||
"github.com/xorm-io/core"
|
"github.com/xorm-io/core"
|
||||||
)
|
)
|
||||||
@ -689,3 +691,103 @@ func IsAppUser(userId string) bool {
|
|||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func setReflectAttr[T any](fieldValue *reflect.Value, fieldString string) error {
|
||||||
|
unmarshalValue := new(T)
|
||||||
|
err := json.Unmarshal([]byte(fieldString), unmarshalValue)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
fvElem := fieldValue
|
||||||
|
fvElem.Set(reflect.ValueOf(*unmarshalValue))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func StringArrayToUser(stringArray [][]string) ([]*User, error) {
|
||||||
|
fieldNames := stringArray[0]
|
||||||
|
excelMap := []map[string]string{}
|
||||||
|
userFieldMap := map[string]int{}
|
||||||
|
|
||||||
|
reflectedUser := reflect.TypeOf(User{})
|
||||||
|
for i := 0; i < reflectedUser.NumField(); i++ {
|
||||||
|
userFieldMap[strings.ToLower(reflectedUser.Field(i).Name)] = i
|
||||||
|
}
|
||||||
|
|
||||||
|
for idx, field := range stringArray {
|
||||||
|
if idx == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
tempMap := map[string]string{}
|
||||||
|
for idx, val := range field {
|
||||||
|
tempMap[fieldNames[idx]] = val
|
||||||
|
}
|
||||||
|
excelMap = append(excelMap, tempMap)
|
||||||
|
}
|
||||||
|
|
||||||
|
users := []*User{}
|
||||||
|
var err error
|
||||||
|
|
||||||
|
for _, u := range excelMap {
|
||||||
|
user := User{}
|
||||||
|
reflectedUser := reflect.ValueOf(&user).Elem()
|
||||||
|
for k, v := range u {
|
||||||
|
if v == "" || v == "null" || v == "[]" || v == "{}" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
fName := strings.ToLower(strings.ReplaceAll(k, "_", ""))
|
||||||
|
fieldIdx, ok := userFieldMap[fName]
|
||||||
|
if !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
fv := reflectedUser.Field(fieldIdx)
|
||||||
|
if !fv.IsValid() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
switch fv.Kind() {
|
||||||
|
case reflect.String:
|
||||||
|
fv.SetString(v)
|
||||||
|
continue
|
||||||
|
case reflect.Bool:
|
||||||
|
fv.SetBool(v == "1")
|
||||||
|
continue
|
||||||
|
case reflect.Int:
|
||||||
|
intVal, err := strconv.Atoi(v)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
fv.SetInt(int64(intVal))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
switch fv.Type() {
|
||||||
|
case reflect.TypeOf([]string{}):
|
||||||
|
err = setReflectAttr[[]string](&fv, v)
|
||||||
|
case reflect.TypeOf([]*string{}):
|
||||||
|
err = setReflectAttr[[]*string](&fv, v)
|
||||||
|
case reflect.TypeOf([]*FaceId{}):
|
||||||
|
err = setReflectAttr[[]*FaceId](&fv, v)
|
||||||
|
case reflect.TypeOf([]*MfaProps{}):
|
||||||
|
err = setReflectAttr[[]*MfaProps](&fv, v)
|
||||||
|
case reflect.TypeOf([]*Role{}):
|
||||||
|
err = setReflectAttr[[]*Role](&fv, v)
|
||||||
|
case reflect.TypeOf([]*Permission{}):
|
||||||
|
err = setReflectAttr[[]*Permission](&fv, v)
|
||||||
|
case reflect.TypeOf([]ManagedAccount{}):
|
||||||
|
err = setReflectAttr[[]ManagedAccount](&fv, v)
|
||||||
|
case reflect.TypeOf([]MfaAccount{}):
|
||||||
|
err = setReflectAttr[[]MfaAccount](&fv, v)
|
||||||
|
case reflect.TypeOf([]webauthn.Credential{}):
|
||||||
|
err = setReflectAttr[[]webauthn.Credential](&fv, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
users = append(users, &user)
|
||||||
|
}
|
||||||
|
|
||||||
|
return users, nil
|
||||||
|
}
|
||||||
|
Binary file not shown.
Reference in New Issue
Block a user