chore: seed migration objects batch 5
This commit is contained in:
@@ -0,0 +1,258 @@
|
||||
package sys
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"hotgo/internal/dao"
|
||||
"hotgo/internal/library/imadmin"
|
||||
"hotgo/internal/library/imtenant"
|
||||
"hotgo/internal/model/entity"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
)
|
||||
|
||||
type imAdminQueryPage struct {
|
||||
Items []map[string]any `json:"items"`
|
||||
Total int `json:"total"`
|
||||
Page int `json:"page"`
|
||||
PerPage int `json:"per_page"`
|
||||
}
|
||||
|
||||
func resolveImAdminTenant(ctx context.Context, selectedTenantId int64) (tenant *entity.ImTenant, err error) {
|
||||
scope, err := resolveImAdminScope(ctx, selectedTenantId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = imtenant.RegistryDB().Model(dao.ImTenant.Table()).Safe().Ctx(ctx).WherePri(scope.TenantId).Scan(&tenant); err != nil {
|
||||
return nil, gerror.Wrap(err, "获取IM租户失败")
|
||||
}
|
||||
if tenant == nil || tenant.Id <= 0 || tenant.Code == "" {
|
||||
return nil, gerror.New("IM租户不存在或编码为空")
|
||||
}
|
||||
return tenant, nil
|
||||
}
|
||||
|
||||
func imAdminQueryList[T any](ctx context.Context, tenant *entity.ImTenant, path string, values url.Values, aliases map[string]string) (list []*T, totalCount int, err error) {
|
||||
if values == nil {
|
||||
values = url.Values{}
|
||||
}
|
||||
query := values.Encode()
|
||||
if query != "" {
|
||||
path += "?" + query
|
||||
}
|
||||
var page imAdminQueryPage
|
||||
if err = imadmin.DefaultClient(ctx).InternalGet(ctx, path, &page); err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
normalizeImAdminRows(page.Items, aliases)
|
||||
if len(page.Items) == 0 {
|
||||
return []*T{}, page.Total, nil
|
||||
}
|
||||
raw, err := json.Marshal(page.Items)
|
||||
if err != nil {
|
||||
return nil, 0, gerror.Wrap(err, "转换IM内部查询列表失败")
|
||||
}
|
||||
if err = json.Unmarshal(raw, &list); err != nil {
|
||||
return nil, 0, gerror.Wrap(err, "解析IM内部查询列表失败")
|
||||
}
|
||||
fillImTenantFields(tenant, &list)
|
||||
return list, page.Total, nil
|
||||
}
|
||||
|
||||
func imAdminQueryOne[T any](ctx context.Context, tenant *entity.ImTenant, path string, aliases map[string]string) (res *T, err error) {
|
||||
row := map[string]any{}
|
||||
if err = imadmin.DefaultClient(ctx).InternalGet(ctx, path, &row); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
normalizeImAdminRow(row, aliases)
|
||||
raw, err := json.Marshal(row)
|
||||
if err != nil {
|
||||
return nil, gerror.Wrap(err, "转换IM内部查询详情失败")
|
||||
}
|
||||
if err = json.Unmarshal(raw, &res); err != nil {
|
||||
return nil, gerror.Wrap(err, "解析IM内部查询详情失败")
|
||||
}
|
||||
fillImTenantFields(tenant, res)
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func normalizeImAdminRows(rows []map[string]any, aliases map[string]string) {
|
||||
for _, row := range rows {
|
||||
normalizeImAdminRow(row, aliases)
|
||||
}
|
||||
}
|
||||
|
||||
func normalizeImAdminRow(row map[string]any, aliases map[string]string) {
|
||||
for key, value := range row {
|
||||
target := snakeToLowerCamel(key)
|
||||
if aliases != nil {
|
||||
if alias := aliases[key]; alias != "" {
|
||||
target = alias
|
||||
}
|
||||
}
|
||||
value = normalizeImAdminValue(target, value)
|
||||
if target == key {
|
||||
row[key] = value
|
||||
continue
|
||||
}
|
||||
row[target] = value
|
||||
delete(row, key)
|
||||
}
|
||||
if _, ok := row["authNames"]; !ok {
|
||||
username, _ := row["username"].(string)
|
||||
phone, _ := row["phone"].(string)
|
||||
authNames := username
|
||||
if phone != "" && phone != username {
|
||||
if authNames != "" {
|
||||
authNames += ", "
|
||||
}
|
||||
authNames += phone
|
||||
}
|
||||
if authNames != "" {
|
||||
row["authNames"] = authNames
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func normalizeImAdminValue(target string, value any) any {
|
||||
switch target {
|
||||
case "credentials":
|
||||
items, ok := value.([]any)
|
||||
if !ok {
|
||||
return value
|
||||
}
|
||||
parts := make([]string, 0, len(items))
|
||||
for _, item := range items {
|
||||
m, ok := item.(map[string]any)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
method, _ := m["method"].(string)
|
||||
val, _ := m["value"].(string)
|
||||
if method == "" && val == "" {
|
||||
continue
|
||||
}
|
||||
text := method
|
||||
if val != "" {
|
||||
if text != "" {
|
||||
text += ":"
|
||||
}
|
||||
text += val
|
||||
}
|
||||
if done, ok := m["done"].(bool); ok && !done {
|
||||
text += "(未验证)"
|
||||
}
|
||||
parts = append(parts, text)
|
||||
}
|
||||
return strings.Join(parts, ", ")
|
||||
case "profileJson", "trustedJson", "accessJson", "head", "content", "metadata", "atUsers":
|
||||
return normalizeImAdminJSONString(value)
|
||||
default:
|
||||
return value
|
||||
}
|
||||
}
|
||||
|
||||
func normalizeImAdminJSONString(value any) string {
|
||||
switch v := value.(type) {
|
||||
case nil:
|
||||
return ""
|
||||
case string:
|
||||
return v
|
||||
default:
|
||||
encoded, err := json.Marshal(v)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return string(encoded)
|
||||
}
|
||||
}
|
||||
|
||||
func snakeToLowerCamel(s string) string {
|
||||
if !strings.Contains(s, "_") {
|
||||
return s
|
||||
}
|
||||
parts := strings.Split(s, "_")
|
||||
var b strings.Builder
|
||||
for i, part := range parts {
|
||||
if part == "" {
|
||||
continue
|
||||
}
|
||||
if i == 0 {
|
||||
b.WriteString(part)
|
||||
continue
|
||||
}
|
||||
b.WriteString(strings.ToUpper(part[:1]))
|
||||
if len(part) > 1 {
|
||||
b.WriteString(part[1:])
|
||||
}
|
||||
}
|
||||
return b.String()
|
||||
}
|
||||
|
||||
func fillImTenantFields(tenant *entity.ImTenant, target any) {
|
||||
raw, err := json.Marshal(target)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
var rows []map[string]any
|
||||
if err = json.Unmarshal(raw, &rows); err == nil {
|
||||
for _, row := range rows {
|
||||
row["tenantId"] = tenant.Id
|
||||
row["tenantName"] = tenant.Name
|
||||
}
|
||||
updated, _ := json.Marshal(rows)
|
||||
_ = json.Unmarshal(updated, target)
|
||||
return
|
||||
}
|
||||
var row map[string]any
|
||||
if err = json.Unmarshal(raw, &row); err == nil {
|
||||
row["tenantId"] = tenant.Id
|
||||
row["tenantName"] = tenant.Name
|
||||
updated, _ := json.Marshal(row)
|
||||
_ = json.Unmarshal(updated, target)
|
||||
}
|
||||
}
|
||||
|
||||
func addPageQuery(values url.Values, page int, perPage int) url.Values {
|
||||
if values == nil {
|
||||
values = url.Values{}
|
||||
}
|
||||
if page <= 0 {
|
||||
page = 1
|
||||
}
|
||||
if perPage <= 0 {
|
||||
perPage = 20
|
||||
}
|
||||
values.Set("page", intToString(page))
|
||||
values.Set("per_page", intToString(perPage))
|
||||
return values
|
||||
}
|
||||
|
||||
func addTimeRangeQuery(values url.Values, prefix string, times []*gtime.Time) {
|
||||
if len(times) != 2 {
|
||||
return
|
||||
}
|
||||
if times[0] != nil {
|
||||
values.Set(prefix+"_start", times[0].Time.UTC().Format(time.RFC3339Nano))
|
||||
}
|
||||
if times[1] != nil {
|
||||
values.Set(prefix+"_end", times[1].Time.UTC().Format(time.RFC3339Nano))
|
||||
}
|
||||
}
|
||||
|
||||
func intToString(v int) string {
|
||||
return strconvFormatInt(int64(v))
|
||||
}
|
||||
|
||||
func int64ToString(v int64) string {
|
||||
return strconvFormatInt(v)
|
||||
}
|
||||
|
||||
func strconvFormatInt(v int64) string {
|
||||
return strconv.FormatInt(v, 10)
|
||||
}
|
||||
Reference in New Issue
Block a user