diff --git a/api/go/handler/admin/api_key_handler.go b/api/go/handler/admin/api_key_handler.go index 4dd2d9c9..8cbe88a9 100644 --- a/api/go/handler/admin/api_key_handler.go +++ b/api/go/handler/admin/api_key_handler.go @@ -8,10 +8,9 @@ import ( "chatplus/store/vo" "chatplus/utils" "chatplus/utils/resp" - "net/http" - "github.com/gin-gonic/gin" "gorm.io/gorm" + "time" ) type ApiKeyHandler struct { @@ -25,38 +24,50 @@ func NewApiKeyHandler(app *core.AppServer, db *gorm.DB) *ApiKeyHandler { return &h } -func (h *ApiKeyHandler) Add(c *gin.Context) { +func (h *ApiKeyHandler) Save(c *gin.Context) { var data struct { - Key string + Id uint `json:"id"` + UserId uint `json:"user_id"` + Value string `json:"value"` + LastUsedAt string `json:"last_used_at"` + CreatedAt int64 `json:"created_at"` } if err := c.ShouldBindJSON(&data); err != nil { resp.ERROR(c, types.InvalidArgs) return } - // 获取当前登录用户 - var userId uint = 0 - user, err := utils.GetLoginUser(c, h.db) - if err == nil { - userId = user.Id + + apiKey := model.ApiKey{Value: data.Value, UserId: data.UserId, LastUsedAt: utils.Str2stamp(data.LastUsedAt)} + apiKey.Id = data.Id + if apiKey.Id > 0 { + apiKey.CreatedAt = time.Unix(data.CreatedAt, 0) } - var key = model.ApiKey{Value: data.Key, UserId: userId} - res := h.db.Create(&key) + res := h.db.Save(&apiKey) if res.Error != nil { - c.JSON(http.StatusOK, types.BizVo{Code: types.Failed, Message: "操作失败"}) + resp.ERROR(c, "更新数据库失败!") return } - resp.SUCCESS(c, key) + + var keyVo vo.ApiKey + err := utils.CopyObject(apiKey, &keyVo) + if err != nil { + resp.ERROR(c, "数据拷贝失败!") + return + } + keyVo.Id = apiKey.Id + keyVo.CreatedAt = apiKey.CreatedAt.Unix() + resp.SUCCESS(c, keyVo) } func (h *ApiKeyHandler) List(c *gin.Context) { - page := h.GetInt(c, "page", 1) - pageSize := h.GetInt(c, "page_size", 20) - offset := (page - 1) * pageSize + userId := h.GetInt(c, "user_id", -1) + query := h.db.Debug().Session(&gorm.Session{}) + if userId >= 0 { + query = query.Where("user_id", userId) + } var items []model.ApiKey var keys = make([]vo.ApiKey, 0) - var total int64 - h.db.Model(&model.ApiKey{}).Count(&total) - res := h.db.Offset(offset).Limit(pageSize).Find(&items) + res := query.Find(&items) if res.Error == nil { for _, item := range items { var key vo.ApiKey @@ -71,6 +82,18 @@ func (h *ApiKeyHandler) List(c *gin.Context) { } } } - pageVo := vo.NewPage(total, page, pageSize, keys) - resp.SUCCESS(c, pageVo) + resp.SUCCESS(c, keys) +} + +func (h *ApiKeyHandler) Remove(c *gin.Context) { + id := h.GetInt(c, "id", 0) + + if id > 0 { + res := h.db.Where("id = ?", id).Delete(&model.ApiKey{}) + if res.Error != nil { + resp.ERROR(c, "更新数据库失败!") + return + } + } + resp.SUCCESS(c) } diff --git a/api/go/handler/admin/chat_role_handler.go b/api/go/handler/admin/chat_role_handler.go index fc05f310..ca439cdc 100644 --- a/api/go/handler/admin/chat_role_handler.go +++ b/api/go/handler/admin/chat_role_handler.go @@ -24,8 +24,8 @@ func NewChatRoleHandler(app *core.AppServer, db *gorm.DB) *ChatRoleHandler { return &h } -// Update 更新某个聊天角色信息,这里只允许更改名称以及启用和禁用角色操作 -func (h *ChatRoleHandler) Update(c *gin.Context) { +// Save 创建或者更新某个角色 +func (h *ChatRoleHandler) Save(c *gin.Context) { var data vo.ChatRole if err := c.ShouldBindJSON(&data); err != nil { resp.ERROR(c, types.InvalidArgs) diff --git a/api/go/main.go b/api/go/main.go index 918fcc03..5ff130ae 100644 --- a/api/go/main.go +++ b/api/go/main.go @@ -128,8 +128,9 @@ func main() { }), fx.Invoke(func(s *core.AppServer, h *admin.ApiKeyHandler) { group := s.Engine.Group("/api/admin/apikey/") - group.POST("add", h.Add) + group.POST("save", h.Save) group.GET("list", h.List) + group.GET("remove", h.Remove) }), fx.Invoke(func(s *core.AppServer, h *admin.UserHandler) { group := s.Engine.Group("/api/admin/user/") @@ -141,7 +142,7 @@ func main() { fx.Invoke(func(s *core.AppServer, h *admin.ChatRoleHandler) { group := s.Engine.Group("/api/admin/role/") group.GET("list", h.List) - group.POST("update", h.Update) + group.POST("save", h.Save) group.POST("sort", h.SetSort) group.GET("remove", h.Remove) }), diff --git a/web/src/utils/libs.js b/web/src/utils/libs.js index abb30af5..80ee9012 100644 --- a/web/src/utils/libs.js +++ b/web/src/utils/libs.js @@ -123,4 +123,8 @@ export function renderInputText(text) { // 拷贝对象 export function copyObj(origin) { return JSON.parse(JSON.stringify(origin)); +} + +export function disabledDate(time) { + return time.getTime() < Date.now() } \ No newline at end of file diff --git a/web/src/views/admin/Admin.vue b/web/src/views/admin/Admin.vue index b61b95c9..2213f8f1 100644 --- a/web/src/views/admin/Admin.vue +++ b/web/src/views/admin/Admin.vue @@ -84,6 +84,9 @@ + + + @@ -104,6 +107,7 @@ import RoleList from "@/views/admin/RoleList.vue"; import {httpGet} from "@/utils/http"; import {ElMessage} from "element-plus"; import {useRouter} from "vue-router"; +import ApiKey from "@/views/admin/ApiKey.vue"; const title = ref('Chat-Plus 控制台') const logo = ref('images/logo.png') @@ -126,6 +130,12 @@ const navs = ref([ title: '角色管理', tab: 'role', active: false, + }, + { + id: 4, + title: 'API KEY', + tab: 'apikey', + active: false, } ]) const tabs = ref([]) diff --git a/web/src/views/admin/ApiKey.vue b/web/src/views/admin/ApiKey.vue new file mode 100644 index 00000000..d6e3bd3a --- /dev/null +++ b/web/src/views/admin/ApiKey.vue @@ -0,0 +1,171 @@ + + + + + \ No newline at end of file diff --git a/web/src/views/admin/RoleList.vue b/web/src/views/admin/RoleList.vue index 61611f0b..15f0969d 100644 --- a/web/src/views/admin/RoleList.vue +++ b/web/src/views/admin/RoleList.vue @@ -140,7 +140,7 @@ @@ -245,11 +245,11 @@ const addRole = function () { showDialog.value = true } -const doUpdate = function () { +const save = function () { formRef.value.validate((valid) => { if (valid) { showDialog.value = false - httpPost('/api/admin/role/update', role.value).then((res) => { + httpPost('/api/admin/role/save', role.value).then((res) => { ElMessage.success('操作成功') // 更新当前数据行 if (role.value.id) { diff --git a/web/src/views/admin/UserList.vue b/web/src/views/admin/UserList.vue index 27fd92fc..e0daf8f6 100644 --- a/web/src/views/admin/UserList.vue +++ b/web/src/views/admin/UserList.vue @@ -14,7 +14,7 @@ @@ -40,7 +40,7 @@ v-model:current-page="users.page" v-model:page-size="users.page_size" @update:current-change="fetchUserList(users.page, users.page_size)" - :page-count="users.total_page"/> + :total="users.total"/> @@ -105,7 +105,7 @@ import {nextTick, onMounted, reactive, ref} from "vue"; import {httpGet, httpPost} from "@/utils/http"; import {ElMessage, ElMessageBox} from "element-plus"; -import {dateFormat, removeArrayItem} from "@/utils/libs"; +import {dateFormat, disabledDate, removeArrayItem} from "@/utils/libs"; // 变量定义 const users = ref({}) @@ -141,16 +141,19 @@ onMounted(() => { const fetchUserList = function (page, pageSize) { httpGet('/api/admin/user/list', {page: page, page_size: pageSize}).then((res) => { - users.value = res.data; + if (res.data) { + // 初始化数据 + const arr = res.data.items; + for (let i = 0; i < arr.length; i++) { + arr[i].expired_time = dateFormat(arr[i].expired_time) + } + users.value.items = arr + } }).catch(() => { ElMessage.error('加载用户列表失败') }) } -const disabledDate = (time) => { - return time.getTime() < Date.now() -} - // 删除用户 const removeUser = function (user) { ElMessageBox.confirm( @@ -179,7 +182,6 @@ const removeUser = function (user) { } const userEdit = function (_user) { - _user.expired_time = dateFormat(_user.expired_time) user.value = _user showUserEditDialog.value = true }