diff --git a/backend/api/api.go b/backend/api/api.go index cbf2c03..ebabc8e 100644 --- a/backend/api/api.go +++ b/backend/api/api.go @@ -157,6 +157,12 @@ func (a *APIHandler) getHandler(c *gin.Context) { level := c.Query("l") logs := a.ServerService.GetLogs(service, count, level) jsonObj(c, logs, nil) + case "changes": + actor := c.Query("a") + chngKey := c.Query("k") + count := c.Query("c") + changes := a.ConfigService.GetChanges(actor, chngKey, count) + jsonObj(c, changes, nil) default: jsonMsg(c, "API call", nil) } diff --git a/backend/cmd/migration.go b/backend/cmd/migration.go index 760856f..ad138e0 100644 --- a/backend/cmd/migration.go +++ b/backend/cmd/migration.go @@ -28,6 +28,13 @@ func migrateDb() { }() fmt.Println("Start migrating database...") err = migrateClientSchema(tx) + if err != nil { + log.Fatal(err) + } + err = changesObj(tx) + if err != nil { + log.Fatal(err) + } fmt.Println("Migration done!") } @@ -81,5 +88,10 @@ func migrateClientSchema(db *gorm.DB) error { } } } + db.AutoMigrate(model.Client{}) return nil } + +func changesObj(db *gorm.DB) error { + return db.Exec("UPDATE changes SET obj = CAST('\"' || CAST(obj AS TEXT) || '\"' AS BLOB) WHERE actor = ? and obj not like ?", "DepleteJob", "\"%\"").Error +} diff --git a/backend/service/client.go b/backend/service/client.go index ffa86d1..f66835d 100644 --- a/backend/service/client.go +++ b/backend/service/client.go @@ -70,7 +70,7 @@ func (s *ClientService) DepleteClients() ([]string, []string, error) { Actor: "DepleteJob", Key: "clients", Action: "disable", - Obj: json.RawMessage(client.Name), + Obj: json.RawMessage("\"" + client.Name + "\""), }) } diff --git a/backend/service/config.go b/backend/service/config.go index 2927d4f..d083deb 100644 --- a/backend/service/config.go +++ b/backend/service/config.go @@ -6,6 +6,7 @@ import ( "s-ui/config" "s-ui/database" "s-ui/database/model" + "s-ui/logger" "s-ui/singbox" "strconv" "time" @@ -342,3 +343,21 @@ func (s *ConfigService) contains(slice []string, item string) bool { } return false } + +func (s *ConfigService) GetChanges(actor string, chngKey string, count string) []model.Changes { + c, _ := strconv.Atoi(count) + whereString := "`id`>0" + if len(actor) > 0 { + whereString += " and `actor`='" + actor + "'" + } + if len(chngKey) > 0 { + whereString += " and `key`='" + chngKey + "'" + } + db := database.GetDB() + var chngs []model.Changes + err := db.Model(model.Changes{}).Where(whereString).Order("`id` desc").Limit(c).Scan(&chngs).Error + if err != nil { + logger.Warning(err) + } + return chngs +} diff --git a/frontend/src/layouts/modals/Changes.vue b/frontend/src/layouts/modals/Changes.vue new file mode 100644 index 0000000..9a5dab6 --- /dev/null +++ b/frontend/src/layouts/modals/Changes.vue @@ -0,0 +1,140 @@ + + + \ No newline at end of file diff --git a/frontend/src/locales/en.ts b/frontend/src/locales/en.ts index 18cb2a9..6291e2f 100644 --- a/frontend/src/locales/en.ts +++ b/frontend/src/locales/en.ts @@ -23,6 +23,7 @@ export default { version: "Version", email: "Email", commaSeparated: "(comma separated)", + count: "Count", error: { dplData: "Duplicate Data", }, @@ -85,11 +86,14 @@ export default { actions: { action: "Action", add: "Add", + new: "Add", edit: "Edit", del: "Delete", save: "Save", update: "Update", submit: "Submit", + set: "Set", + disable: "Disable", close: "Close", restartApp: "Restart App", }, @@ -111,6 +115,10 @@ export default { lastLogin: "Last login", date: "Date", time: "Time", + changes: "Changes", + actor: "Actor", + key: "Key", + action: "Action", }, setting: { interface: "Interface", diff --git a/frontend/src/locales/fa.ts b/frontend/src/locales/fa.ts index 1d8f063..ff5965e 100644 --- a/frontend/src/locales/fa.ts +++ b/frontend/src/locales/fa.ts @@ -23,6 +23,7 @@ export default { version: "نسخه", email: "ایمیل", commaSeparated: "(جداشده با کاما)", + count: "تعداد", error: { dplData: "داده تکراری", }, @@ -84,11 +85,14 @@ export default { actions: { action: "فرمان", add: "ایجاد", + new: "ایجاد", edit: "ویرایش", del: "حذف", save: "ذخیره", update: "بروزرسانی", submit: "ارسال", + set: "تنظیم", + disable: "غیرفعال", close: "بستن", restartApp: "ریستارت پنل", }, @@ -110,6 +114,10 @@ export default { lastLogin: "آخرین ورود", date: "تاریخ", time: "ساعت", + changes: "تغییرات", + actor: "مجری", + key: "کلید", + action: "عمل", }, setting: { interface: "نما", diff --git a/frontend/src/locales/vi.ts b/frontend/src/locales/vi.ts index 5cf95fb..9a59270 100644 --- a/frontend/src/locales/vi.ts +++ b/frontend/src/locales/vi.ts @@ -23,6 +23,7 @@ export default { version: "Phiên bản", email: "Email", commaSeparated: "(được phân tách bằng dấu phẩy)", + count: "Đếm", error: { dplData: "Dữ liệu trùng lặp", }, @@ -85,11 +86,14 @@ export default { actions: { action: "Hành động", add: "Thêm", + new: "Thêm", edit: "Chỉnh sửa", del: "Xóa", save: "Lưu", update: "Cập nhật", submit: "Gửi", + set: "Đặt", + disable: "Vô hiệu hóa", close: "Đóng", restartApp: "Khởi động lại ứng dụng", }, @@ -111,6 +115,10 @@ export default { lastLogin: "Lân đăng nhập cuôi", date: "Ngày", time: "Thời gian", + changes: "Thay đổi", + actor: "Diễn viên", + key: "Khóa", + action: "Hành động", }, setting: { interface: "Giao diện", diff --git a/frontend/src/locales/zhcn.ts b/frontend/src/locales/zhcn.ts index 30dcb18..d258b88 100644 --- a/frontend/src/locales/zhcn.ts +++ b/frontend/src/locales/zhcn.ts @@ -23,6 +23,7 @@ export default { version: "版本", email: "电子邮件", commaSeparated: "(逗号分隔)", + count: "计数", error: { dplData: "重复数据", }, @@ -85,11 +86,14 @@ export default { actions: { action: "操作", add: "添加", + new: "添加", edit: "编辑", del: "删除", save: "保存", update: "更新", submit: "提交", + set: "设置", + disable: "禁用", close: "关闭", restartApp: "重启面板", }, @@ -111,6 +115,10 @@ export default { lastLogin: "上次登录", date: "日期", time: "时间", + changes: "更改", + actor: "执行者", + key: "键", + action: "操作", }, setting: { interface: "界面", diff --git a/frontend/src/locales/zhtw.ts b/frontend/src/locales/zhtw.ts index 75bfbcf..862ba75 100644 --- a/frontend/src/locales/zhtw.ts +++ b/frontend/src/locales/zhtw.ts @@ -24,6 +24,7 @@ export default { version: "版本", email: "電子郵件", commaSeparated: "(逗號分隔)", + count: "計數", error: { dplData: "重複數據", }, @@ -86,11 +87,14 @@ export default { actions: { action: "操作", add: "添加", + new: "添加", edit: "編輯", del: "刪除", save: "保存", update: "更新", submit: "提交", + set: "設置", + disable: "禁用", close: "關閉", restartApp: "重啟面板", }, @@ -112,6 +116,10 @@ export default { lastLogin: "上次登入", date: "日期", time: "時間", + changes: "更改", + actor: "執行者", + key: "鍵", + action: "操作", }, setting: { interface: "界面", diff --git a/frontend/src/plugins/vuetify.ts b/frontend/src/plugins/vuetify.ts index 457cc92..78003ab 100644 --- a/frontend/src/plugins/vuetify.ts +++ b/frontend/src/plugins/vuetify.ts @@ -9,7 +9,7 @@ import '@mdi/font/css/materialdesignicons.css' import 'vuetify/styles' import colors from 'vuetify/util/colors' -import { fa, en } from 'vuetify/locale' +import { fa, en, vi, zhHans as zhcn, zhHant as zhtw } from 'vuetify/locale' // Composables import { createVuetify } from 'vuetify' @@ -53,6 +53,6 @@ export default createVuetify({ locale: { locale: localStorage.getItem("locale") ?? 'en', fallback: 'en', - messages: { en, fa }, + messages: { en, fa, vi, zhcn, zhtw }, }, }) diff --git a/frontend/src/views/Admins.vue b/frontend/src/views/Admins.vue index 2e16e57..bea2984 100644 --- a/frontend/src/views/Admins.vue +++ b/frontend/src/views/Admins.vue @@ -6,6 +6,18 @@ @close="closeEditModal" @save="saveEditModal" /> + + + + {{ $t('admin.changes') }} + + @@ -38,6 +50,10 @@ + + + + @@ -45,9 +61,10 @@ \ No newline at end of file