mirror of
https://github.com/0xJacky/nginx-ui.git
synced 2025-05-10 18:05:48 +02:00
feat: add Lark and Lark Custom notification support
This commit is contained in:
parent
e364353cd1
commit
7a0972495f
17 changed files with 174 additions and 38 deletions
|
@ -4,6 +4,12 @@
|
||||||
|
|
||||||
const notifications: Record<string, { title: () => string, content: (args: any) => string }> = {
|
const notifications: Record<string, { title: () => string, content: (args: any) => string }> = {
|
||||||
|
|
||||||
|
// user module notifications
|
||||||
|
'All Recovery Codes Have Been Used': {
|
||||||
|
title: () => $gettext('All Recovery Codes Have Been Used'),
|
||||||
|
content: (args: any) => $gettext('Please generate new recovery codes in the preferences immediately to prevent lockout.', args),
|
||||||
|
},
|
||||||
|
|
||||||
// cluster module notifications
|
// cluster module notifications
|
||||||
'Reload Remote Nginx Error': {
|
'Reload Remote Nginx Error': {
|
||||||
title: () => $gettext('Reload Remote Nginx Error'),
|
title: () => $gettext('Reload Remote Nginx Error'),
|
||||||
|
@ -149,12 +155,6 @@ const notifications: Record<string, { title: () => string, content: (args: any)
|
||||||
title: () => $gettext('Save Remote Stream Success'),
|
title: () => $gettext('Save Remote Stream Success'),
|
||||||
content: (args: any) => $gettext('Save stream %{name} to %{node} successfully', args),
|
content: (args: any) => $gettext('Save stream %{name} to %{node} successfully', args),
|
||||||
},
|
},
|
||||||
|
|
||||||
// user module notifications
|
|
||||||
'All Recovery Codes Have Been Used': {
|
|
||||||
title: () => $gettext('All Recovery Codes Have Been Used'),
|
|
||||||
content: (args: any) => $gettext('Please generate new recovery codes in the preferences immediately to prevent lockout.', args),
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default notifications
|
export default notifications
|
||||||
|
|
|
@ -26,7 +26,6 @@ const columns = computed<Column[]>(() => {
|
||||||
type: input,
|
type: input,
|
||||||
config: {
|
config: {
|
||||||
label: item.label,
|
label: item.label,
|
||||||
required: true,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}))
|
}))
|
||||||
|
|
|
@ -6,11 +6,11 @@ const BarkConfig: ExternalNotifyConfig = {
|
||||||
config: [
|
config: [
|
||||||
{
|
{
|
||||||
key: 'device_key',
|
key: 'device_key',
|
||||||
label: () => $gettext('Device Key'),
|
label: 'Device Key',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'server_url',
|
key: 'server_url',
|
||||||
label: () => $gettext('Server URL'),
|
label: 'Server URL',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,11 +6,11 @@ const DingTalkConfig: ExternalNotifyConfig = {
|
||||||
config: [
|
config: [
|
||||||
{
|
{
|
||||||
key: 'access_token',
|
key: 'access_token',
|
||||||
label: () => $gettext('Access Token'),
|
label: 'Access Token',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'secret',
|
key: 'secret',
|
||||||
label: () => $gettext('Secret (Optional)'),
|
label: 'Secret (Optional)',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,15 @@
|
||||||
// This file is auto-generated by notification generator. DO NOT EDIT.
|
// This file is auto-generated by notification generator. DO NOT EDIT.
|
||||||
import BarkConfig from './bark'
|
import BarkConfig from './bark'
|
||||||
import DingTalkConfig from './dingtalk'
|
import DingTalkConfig from './dingtalk'
|
||||||
|
import LarkConfig from './lark'
|
||||||
|
import LarkCustomConfig from './lark_custom'
|
||||||
import TelegramConfig from './telegram'
|
import TelegramConfig from './telegram'
|
||||||
|
|
||||||
const configMap = {
|
const configMap = {
|
||||||
bark: BarkConfig,
|
bark: BarkConfig,
|
||||||
dingtalk: DingTalkConfig,
|
dingtalk: DingTalkConfig,
|
||||||
|
lark: LarkConfig,
|
||||||
|
lark_custom: LarkCustomConfig,
|
||||||
telegram: TelegramConfig,
|
telegram: TelegramConfig,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
14
app/src/views/preference/components/ExternalNotify/lark.ts
Normal file
14
app/src/views/preference/components/ExternalNotify/lark.ts
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
// This file is auto-generated by notification generator. DO NOT EDIT.
|
||||||
|
import type { ExternalNotifyConfig } from './types'
|
||||||
|
|
||||||
|
const LarkConfig: ExternalNotifyConfig = {
|
||||||
|
name: () => $gettext('Lark'),
|
||||||
|
config: [
|
||||||
|
{
|
||||||
|
key: 'webhook_url',
|
||||||
|
label: 'Webhook URL',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
export default LarkConfig
|
|
@ -0,0 +1,38 @@
|
||||||
|
// This file is auto-generated by notification generator. DO NOT EDIT.
|
||||||
|
import type { ExternalNotifyConfig } from './types'
|
||||||
|
|
||||||
|
const LarkCustomConfig: ExternalNotifyConfig = {
|
||||||
|
name: () => $gettext('Lark Custom'),
|
||||||
|
config: [
|
||||||
|
{
|
||||||
|
key: 'app_id',
|
||||||
|
label: 'App ID',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'app_secret',
|
||||||
|
label: 'App Secret',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'open_id',
|
||||||
|
label: 'Open ID',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'user_id',
|
||||||
|
label: 'User ID',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'union_id',
|
||||||
|
label: 'Union ID',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'email',
|
||||||
|
label: 'Email',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'chat_id',
|
||||||
|
label: 'Chat ID',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
export default LarkCustomConfig
|
|
@ -6,11 +6,11 @@ const TelegramConfig: ExternalNotifyConfig = {
|
||||||
config: [
|
config: [
|
||||||
{
|
{
|
||||||
key: 'bot_token',
|
key: 'bot_token',
|
||||||
label: () => $gettext('Bot Token'),
|
label: 'Bot Token',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'chat_id',
|
key: 'chat_id',
|
||||||
label: () => $gettext('Chat ID'),
|
label: 'Chat ID',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
export interface ExternalNotifyConfigItem {
|
export interface ExternalNotifyConfigItem {
|
||||||
key: string
|
key: string
|
||||||
label: () => string
|
label: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ExternalNotifyConfig {
|
export interface ExternalNotifyConfig {
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
// This file is auto-generated by notification generator. DO NOT EDIT.
|
||||||
|
|
||||||
|
const configMap = {
|
||||||
|
}
|
||||||
|
|
||||||
|
export default configMap
|
|
@ -32,23 +32,23 @@ type FieldInfo struct {
|
||||||
const tsConfigTemplate = `// This file is auto-generated by notification generator. DO NOT EDIT.
|
const tsConfigTemplate = `// This file is auto-generated by notification generator. DO NOT EDIT.
|
||||||
import type { ExternalNotifyConfig } from './types'
|
import type { ExternalNotifyConfig } from './types'
|
||||||
|
|
||||||
const {{.Name}}Config: ExternalNotifyConfig = {
|
const {{.Name | replaceSpaces}}Config: ExternalNotifyConfig = {
|
||||||
name: () => $gettext('{{.Name}}'),
|
name: () => $gettext('{{.Name}}'),
|
||||||
config: [
|
config: [
|
||||||
{{- range .Fields}}
|
{{- range .Fields}}
|
||||||
{
|
{
|
||||||
key: '{{.Key}}',
|
key: '{{.Key}}',
|
||||||
label: () => $gettext('{{.Title}}'),
|
label: '{{.Title}}',
|
||||||
},
|
},
|
||||||
{{- end}}
|
{{- end}}
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
export default {{.Name}}Config
|
export default {{.Name | replaceSpaces}}Config
|
||||||
`
|
`
|
||||||
|
|
||||||
// Regular expression to extract @external_notifier annotation
|
// Regular expression to extract @external_notifier annotation
|
||||||
var externalNotifierRegex = regexp.MustCompile(`@external_notifier\((\w+)\)`)
|
var externalNotifierRegex = regexp.MustCompile(`@external_notifier\(([a-zA-Z0-9 _]+)\)`)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
if err := GenerateExternalNotifiers(); err != nil {
|
if err := GenerateExternalNotifiers(); err != nil {
|
||||||
|
@ -142,7 +142,7 @@ func extractNotifierInfo(filePath string) (NotifierInfo, bool) {
|
||||||
if len(matches) > 1 {
|
if len(matches) > 1 {
|
||||||
notifierInfo.Name = matches[1]
|
notifierInfo.Name = matches[1]
|
||||||
notifierInfo.ConfigKey = strings.ToLower(typeSpec.Name.Name)
|
notifierInfo.ConfigKey = strings.ToLower(typeSpec.Name.Name)
|
||||||
notifierInfo.FileName = strings.ToLower(matches[1])
|
notifierInfo.FileName = strings.ToLower(strings.ReplaceAll(matches[1], " ", "_"))
|
||||||
found = true
|
found = true
|
||||||
|
|
||||||
// Extract fields
|
// Extract fields
|
||||||
|
@ -205,8 +205,15 @@ func extractNotifierInfo(filePath string) (NotifierInfo, bool) {
|
||||||
|
|
||||||
// Generate TypeScript config file for a notifier
|
// Generate TypeScript config file for a notifier
|
||||||
func generateTSConfig(notifier NotifierInfo, outputDir string) error {
|
func generateTSConfig(notifier NotifierInfo, outputDir string) error {
|
||||||
// Create template
|
// Create function map for template
|
||||||
tmpl, err := template.New("tsConfig").Parse(tsConfigTemplate)
|
funcMap := template.FuncMap{
|
||||||
|
"replaceSpaces": func(s string) string {
|
||||||
|
return strings.ReplaceAll(s, " ", "")
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create template with function map
|
||||||
|
tmpl, err := template.New("tsConfig").Funcs(funcMap).Parse(tsConfigTemplate)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error creating template: %w", err)
|
return fmt.Errorf("error creating template: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -242,7 +249,7 @@ func updateIndexFile(notifiers []NotifierInfo, outputDir string) error {
|
||||||
|
|
||||||
for _, notifier := range notifiers {
|
for _, notifier := range notifiers {
|
||||||
fileName := notifier.FileName
|
fileName := notifier.FileName
|
||||||
configName := notifier.Name + "Config"
|
configName := strings.ReplaceAll(notifier.Name, " ", "") + "Config"
|
||||||
|
|
||||||
imports.WriteString(fmt.Sprintf("import %s from './%s'\n", configName, fileName))
|
imports.WriteString(fmt.Sprintf("import %s from './%s'\n", configName, fileName))
|
||||||
}
|
}
|
||||||
|
@ -250,7 +257,8 @@ func updateIndexFile(notifiers []NotifierInfo, outputDir string) error {
|
||||||
// Generate the map
|
// Generate the map
|
||||||
configMap.WriteString("const configMap = {\n")
|
configMap.WriteString("const configMap = {\n")
|
||||||
for _, notifier := range notifiers {
|
for _, notifier := range notifiers {
|
||||||
configMap.WriteString(fmt.Sprintf(" %s: %sConfig", strings.ToLower(notifier.Name), notifier.Name))
|
configKey := strings.ToLower(strings.ReplaceAll(notifier.Name, " ", "_"))
|
||||||
|
configMap.WriteString(fmt.Sprintf(" %s: %sConfig", configKey, strings.ReplaceAll(notifier.Name, " ", "")))
|
||||||
configMap.WriteString(",\n")
|
configMap.WriteString(",\n")
|
||||||
}
|
}
|
||||||
configMap.WriteString("}\n")
|
configMap.WriteString("}\n")
|
||||||
|
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/0xJacky/Nginx-UI/model"
|
"github.com/0xJacky/Nginx-UI/model"
|
||||||
"github.com/nikoksr/notify"
|
|
||||||
"github.com/nikoksr/notify/service/bark"
|
"github.com/nikoksr/notify/service/bark"
|
||||||
"github.com/uozi-tech/cosy/map2struct"
|
"github.com/uozi-tech/cosy/map2struct"
|
||||||
)
|
)
|
||||||
|
@ -26,8 +25,6 @@ func init() {
|
||||||
return ErrInvalidNotifierConfig
|
return ErrInvalidNotifierConfig
|
||||||
}
|
}
|
||||||
barkService := bark.NewWithServers(barkConfig.DeviceKey, barkConfig.ServerURL)
|
barkService := bark.NewWithServers(barkConfig.DeviceKey, barkConfig.ServerURL)
|
||||||
externalNotify := notify.New()
|
return barkService.Send(ctx, msg.GetTitle(n.Language), msg.GetContent(n.Language))
|
||||||
externalNotify.UseServices(barkService)
|
|
||||||
return externalNotify.Send(ctx, msg.GetTitle(n.Language), msg.GetContent(n.Language))
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/0xJacky/Nginx-UI/model"
|
"github.com/0xJacky/Nginx-UI/model"
|
||||||
"github.com/nikoksr/notify"
|
|
||||||
"github.com/nikoksr/notify/service/dingding"
|
"github.com/nikoksr/notify/service/dingding"
|
||||||
"github.com/uozi-tech/cosy/map2struct"
|
"github.com/uozi-tech/cosy/map2struct"
|
||||||
)
|
)
|
||||||
|
@ -31,9 +30,6 @@ func init() {
|
||||||
Token: dingTalkConfig.AccessToken,
|
Token: dingTalkConfig.AccessToken,
|
||||||
Secret: dingTalkConfig.Secret,
|
Secret: dingTalkConfig.Secret,
|
||||||
})
|
})
|
||||||
// Use the service
|
return dingTalkService.Send(ctx, msg.GetTitle(n.Language), msg.GetContent(n.Language))
|
||||||
externalNotify := notify.New()
|
|
||||||
externalNotify.UseServices(dingTalkService)
|
|
||||||
return externalNotify.Send(ctx, msg.GetTitle(n.Language), msg.GetContent(n.Language))
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
30
internal/notification/lark.go
Normal file
30
internal/notification/lark.go
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
package notification
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/0xJacky/Nginx-UI/model"
|
||||||
|
"github.com/nikoksr/notify/service/lark"
|
||||||
|
"github.com/uozi-tech/cosy/map2struct"
|
||||||
|
)
|
||||||
|
|
||||||
|
// @external_notifier(Lark)
|
||||||
|
type Lark struct {
|
||||||
|
WebhookURL string `json:"webhook_url" title:"Webhook URL"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
RegisterExternalNotifier("lark", func(ctx context.Context, n *model.ExternalNotify, msg *ExternalMessage) error {
|
||||||
|
larkConfig := &Lark{}
|
||||||
|
err := map2struct.WeakDecode(n.Config, larkConfig)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if larkConfig.WebhookURL == "" {
|
||||||
|
return ErrInvalidNotifierConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
larkService := lark.NewWebhookService(larkConfig.WebhookURL)
|
||||||
|
return larkService.Send(ctx, msg.GetTitle(n.Language), msg.GetContent(n.Language))
|
||||||
|
})
|
||||||
|
}
|
43
internal/notification/lark_custom.go
Normal file
43
internal/notification/lark_custom.go
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
package notification
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/0xJacky/Nginx-UI/model"
|
||||||
|
"github.com/nikoksr/notify/service/lark"
|
||||||
|
"github.com/uozi-tech/cosy/map2struct"
|
||||||
|
)
|
||||||
|
|
||||||
|
// @external_notifier(Lark Custom)
|
||||||
|
type LarkCustom struct {
|
||||||
|
AppID string `json:"app_id" title:"App ID"`
|
||||||
|
AppSecret string `json:"app_secret" title:"App Secret"`
|
||||||
|
OpenID string `json:"open_id" title:"Open ID"`
|
||||||
|
UserID string `json:"user_id" title:"User ID"`
|
||||||
|
UnionID string `json:"union_id" title:"Union ID"`
|
||||||
|
Email string `json:"email" title:"Email"`
|
||||||
|
ChatID string `json:"chat_id" title:"Chat ID"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
RegisterExternalNotifier("lark_custom", func(ctx context.Context, n *model.ExternalNotify, msg *ExternalMessage) error {
|
||||||
|
larkCustomConfig := &LarkCustom{}
|
||||||
|
err := map2struct.WeakDecode(n.Config, larkCustomConfig)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if larkCustomConfig.AppID == "" || larkCustomConfig.AppSecret == "" {
|
||||||
|
return ErrInvalidNotifierConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
larkCustomAppService := lark.NewCustomAppService(larkCustomConfig.AppID, larkCustomConfig.AppSecret)
|
||||||
|
larkCustomAppService.AddReceivers(
|
||||||
|
lark.OpenID(larkCustomConfig.OpenID),
|
||||||
|
lark.UserID(larkCustomConfig.UserID),
|
||||||
|
lark.UnionID(larkCustomConfig.UnionID),
|
||||||
|
lark.Email(larkCustomConfig.Email),
|
||||||
|
lark.ChatID(larkCustomConfig.ChatID),
|
||||||
|
)
|
||||||
|
return larkCustomAppService.Send(ctx, msg.GetTitle(n.Language), msg.GetContent(n.Language))
|
||||||
|
})
|
||||||
|
}
|
|
@ -7,7 +7,6 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/0xJacky/Nginx-UI/model"
|
"github.com/0xJacky/Nginx-UI/model"
|
||||||
"github.com/nikoksr/notify"
|
|
||||||
"github.com/nikoksr/notify/service/telegram"
|
"github.com/nikoksr/notify/service/telegram"
|
||||||
"github.com/uozi-tech/cosy/map2struct"
|
"github.com/uozi-tech/cosy/map2struct"
|
||||||
)
|
)
|
||||||
|
@ -46,9 +45,7 @@ func init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
telegramService.AddReceivers(chatIDInt)
|
telegramService.AddReceivers(chatIDInt)
|
||||||
|
|
||||||
externalNotify := notify.New()
|
return telegramService.Send(ctx, msg.GetTitle(n.Language), msg.GetContent(n.Language))
|
||||||
externalNotify.UseServices(telegramService)
|
|
||||||
return externalNotify.Send(ctx, msg.GetTitle(n.Language), msg.GetContent(n.Language))
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,7 @@ func newExternalNotify(db *gorm.DB, opts ...gen.DOOption) externalNotify {
|
||||||
_externalNotify.UpdatedAt = field.NewTime(tableName, "updated_at")
|
_externalNotify.UpdatedAt = field.NewTime(tableName, "updated_at")
|
||||||
_externalNotify.DeletedAt = field.NewField(tableName, "deleted_at")
|
_externalNotify.DeletedAt = field.NewField(tableName, "deleted_at")
|
||||||
_externalNotify.Type = field.NewString(tableName, "type")
|
_externalNotify.Type = field.NewString(tableName, "type")
|
||||||
|
_externalNotify.Language = field.NewString(tableName, "language")
|
||||||
_externalNotify.Config = field.NewField(tableName, "config")
|
_externalNotify.Config = field.NewField(tableName, "config")
|
||||||
|
|
||||||
_externalNotify.fillFieldMap()
|
_externalNotify.fillFieldMap()
|
||||||
|
@ -49,6 +50,7 @@ type externalNotify struct {
|
||||||
UpdatedAt field.Time
|
UpdatedAt field.Time
|
||||||
DeletedAt field.Field
|
DeletedAt field.Field
|
||||||
Type field.String
|
Type field.String
|
||||||
|
Language field.String
|
||||||
Config field.Field
|
Config field.Field
|
||||||
|
|
||||||
fieldMap map[string]field.Expr
|
fieldMap map[string]field.Expr
|
||||||
|
@ -71,6 +73,7 @@ func (e *externalNotify) updateTableName(table string) *externalNotify {
|
||||||
e.UpdatedAt = field.NewTime(table, "updated_at")
|
e.UpdatedAt = field.NewTime(table, "updated_at")
|
||||||
e.DeletedAt = field.NewField(table, "deleted_at")
|
e.DeletedAt = field.NewField(table, "deleted_at")
|
||||||
e.Type = field.NewString(table, "type")
|
e.Type = field.NewString(table, "type")
|
||||||
|
e.Language = field.NewString(table, "language")
|
||||||
e.Config = field.NewField(table, "config")
|
e.Config = field.NewField(table, "config")
|
||||||
|
|
||||||
e.fillFieldMap()
|
e.fillFieldMap()
|
||||||
|
@ -88,12 +91,13 @@ func (e *externalNotify) GetFieldByName(fieldName string) (field.OrderExpr, bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *externalNotify) fillFieldMap() {
|
func (e *externalNotify) fillFieldMap() {
|
||||||
e.fieldMap = make(map[string]field.Expr, 6)
|
e.fieldMap = make(map[string]field.Expr, 7)
|
||||||
e.fieldMap["id"] = e.ID
|
e.fieldMap["id"] = e.ID
|
||||||
e.fieldMap["created_at"] = e.CreatedAt
|
e.fieldMap["created_at"] = e.CreatedAt
|
||||||
e.fieldMap["updated_at"] = e.UpdatedAt
|
e.fieldMap["updated_at"] = e.UpdatedAt
|
||||||
e.fieldMap["deleted_at"] = e.DeletedAt
|
e.fieldMap["deleted_at"] = e.DeletedAt
|
||||||
e.fieldMap["type"] = e.Type
|
e.fieldMap["type"] = e.Type
|
||||||
|
e.fieldMap["language"] = e.Language
|
||||||
e.fieldMap["config"] = e.Config
|
e.fieldMap["config"] = e.Config
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue