diff --git a/api/handler/admin/user_handler.go b/api/handler/admin/user_handler.go index 96a4b4ed..a2b9fe4c 100644 --- a/api/handler/admin/user_handler.go +++ b/api/handler/admin/user_handler.go @@ -28,12 +28,24 @@ func NewUserHandler(app *core.AppServer, db *gorm.DB) *UserHandler { func (h *UserHandler) List(c *gin.Context) { page := h.GetInt(c, "page", 1) pageSize := h.GetInt(c, "page_size", 20) + mobile := h.GetTrim(c, "mobile") + username := h.GetTrim(c, "username") + offset := (page - 1) * pageSize var items []model.User var users = make([]vo.User, 0) var total int64 - h.db.Model(&model.User{}).Count(&total) - res := h.db.Offset(offset).Limit(pageSize).Find(&items) + + session := h.db.Session(&gorm.Session{}) + if mobile != "" { + session = session.Where("mobile LIKE ?", "%"+mobile+"%") + } + if username != "" { + session = session.Where("username LIKE ?", "%"+username+"%") + } + + session.Model(&model.User{}).Count(&total) + res := session.Offset(offset).Limit(pageSize).Find(&items) if res.Error == nil { for _, item := range items { var user vo.User @@ -83,6 +95,34 @@ func (h *UserHandler) Update(c *gin.Context) { resp.SUCCESS(c) } +// ResetPass 重置密码 +func (h *UserHandler) ResetPass(c *gin.Context) { + var data struct { + Id uint + Password string + } + if err := c.ShouldBindJSON(&data); err != nil { + resp.ERROR(c, types.InvalidArgs) + return + } + + var user model.User + res := h.db.First(&user, data.Id) + if res.Error != nil { + resp.ERROR(c, "No user found") + return + } + + password := utils.GenPassword(data.Password, user.Salt) + user.Password = password + res = h.db.Updates(&user) + if res.Error != nil { + resp.ERROR(c) + } else { + resp.SUCCESS(c) + } +} + func (h *UserHandler) Remove(c *gin.Context) { id := h.GetInt(c, "id", 0) if id > 0 { diff --git a/api/main.go b/api/main.go index 595f8532..1a64934a 100644 --- a/api/main.go +++ b/api/main.go @@ -218,6 +218,7 @@ func main() { group.POST("update", h.Update) group.GET("remove", h.Remove) group.GET("loginLog", h.LoginLog) + group.POST("resetPass", h.ResetPass) }), fx.Invoke(func(s *core.AppServer, h *admin.ChatRoleHandler) { group := s.Engine.Group("/api/admin/role/") diff --git a/docker/docker-compose.yaml b/docker/docker-compose.yaml index 0f545f47..b73bf577 100644 --- a/docker/docker-compose.yaml +++ b/docker/docker-compose.yaml @@ -2,8 +2,7 @@ version: '3' services: # 后端 API 程序 chatgpt-plus-go: - image: registry.cn-hangzhou.aliyuncs.com/geekmaster/chatgpt-plus-go:v3.0.4 - # image: chatgpt-plus-go:v3.0.2 + image: chatgpt-plus-go:v3.0.5 container_name: chatgpt-plus-go restart: always environment: @@ -17,13 +16,13 @@ services: # 前端应用 chatgpt-vue: - image: registry.cn-hangzhou.aliyuncs.com/geekmaster/chatgpt-plus-vue:v3.0.4 - # image: chatgpt-plus-vue:v3.0.2 + image: chatgpt-plus-vue:v3.0.5 container_name: chatgpt-plus-vue restart: always ports: - "8080:8080" volumes: + - /usr/share/zoneinfo/Asia/Shanghai:/etc/localtime - ./logs/nginx:/var/log/nginx - ./conf/nginx/conf.d:/etc/nginx/conf.d - ./conf/nginx/nginx.conf:/etc/nginx/nginx.conf diff --git a/web/src/views/admin/RoleList.vue b/web/src/views/admin/RoleList.vue index 5760dcb4..0e189256 100644 --- a/web/src/views/admin/RoleList.vue +++ b/web/src/views/admin/RoleList.vue @@ -36,7 +36,7 @@ - + + + + + + + + + + + + + + + + @@ -109,13 +141,17 @@ import {nextTick, onMounted, reactive, ref} from "vue"; import {httpGet, httpPost} from "@/utils/http"; import {ElMessage, ElMessageBox} from "element-plus"; import {dateFormat, disabledDate, removeArrayItem} from "@/utils/libs"; +import {Plus, Search} from "@element-plus/icons-vue"; // 变量定义 -const users = ref({page: 1, page_size: 15}) +const users = ref({page: 1, page_size: 15, items: []}) +const query = ref({username: '', mobile: '', page: 1, page_size: 15}) const user = ref({chat_roles: []}) +const pass = ref({username: '', password: '', id: 0}) const roles = ref([]) const showUserEditDialog = ref(false) +const showResetPassDialog = ref(false) const rules = reactive({ nickname: [{required: true, message: '请输入昵称', trigger: 'change',}], calls: [ @@ -143,7 +179,9 @@ onMounted(() => { }) const fetchUserList = function (page, pageSize) { - httpGet('/api/admin/user/list', {page: page, page_size: pageSize}).then((res) => { + query.value.page = page + query.value.page_size = pageSize + httpGet('/api/admin/user/list', query.value).then((res) => { if (res.data) { // 初始化数据 const arr = res.data.items; @@ -160,6 +198,10 @@ const fetchUserList = function (page, pageSize) { }) } +const handleSearch = () => { + fetchUserList(users.value.page, users.value.page_size) +} + // 删除用户 const removeUser = function (user) { ElMessageBox.confirm( @@ -212,11 +254,38 @@ const handleSelectionChange = function (rows) { // TODO: 批量删除操作 console.log(rows) } + +const resetPass = (row) => { + showResetPassDialog.value = true + pass.value.id = row.id + pass.value.username = row.username +} + +const doResetPass = () => { + httpPost('/api/admin/user/resetPass', pass.value).then(() => { + ElMessage.success('操作成功!') + showResetPassDialog.value = false + }).catch((e) => { + ElMessage.error('操作失败,' + e.message) + }) +} +