feat: add reset password function to user list page

This commit is contained in:
RockYang 2023-07-26 15:22:11 +08:00
parent a0df84e4f2
commit 4b77280c65
6 changed files with 124 additions and 15 deletions

View File

@ -28,12 +28,24 @@ func NewUserHandler(app *core.AppServer, db *gorm.DB) *UserHandler {
func (h *UserHandler) List(c *gin.Context) { func (h *UserHandler) List(c *gin.Context) {
page := h.GetInt(c, "page", 1) page := h.GetInt(c, "page", 1)
pageSize := h.GetInt(c, "page_size", 20) pageSize := h.GetInt(c, "page_size", 20)
mobile := h.GetTrim(c, "mobile")
username := h.GetTrim(c, "username")
offset := (page - 1) * pageSize offset := (page - 1) * pageSize
var items []model.User var items []model.User
var users = make([]vo.User, 0) var users = make([]vo.User, 0)
var total int64 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 { if res.Error == nil {
for _, item := range items { for _, item := range items {
var user vo.User var user vo.User
@ -83,6 +95,34 @@ func (h *UserHandler) Update(c *gin.Context) {
resp.SUCCESS(c) 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) { func (h *UserHandler) Remove(c *gin.Context) {
id := h.GetInt(c, "id", 0) id := h.GetInt(c, "id", 0)
if id > 0 { if id > 0 {

View File

@ -218,6 +218,7 @@ func main() {
group.POST("update", h.Update) group.POST("update", h.Update)
group.GET("remove", h.Remove) group.GET("remove", h.Remove)
group.GET("loginLog", h.LoginLog) group.GET("loginLog", h.LoginLog)
group.POST("resetPass", h.ResetPass)
}), }),
fx.Invoke(func(s *core.AppServer, h *admin.ChatRoleHandler) { fx.Invoke(func(s *core.AppServer, h *admin.ChatRoleHandler) {
group := s.Engine.Group("/api/admin/role/") group := s.Engine.Group("/api/admin/role/")

View File

@ -2,8 +2,7 @@ version: '3'
services: services:
# 后端 API 程序 # 后端 API 程序
chatgpt-plus-go: chatgpt-plus-go:
image: registry.cn-hangzhou.aliyuncs.com/geekmaster/chatgpt-plus-go:v3.0.4 image: chatgpt-plus-go:v3.0.5
# image: chatgpt-plus-go:v3.0.2
container_name: chatgpt-plus-go container_name: chatgpt-plus-go
restart: always restart: always
environment: environment:
@ -17,13 +16,13 @@ services:
# 前端应用 # 前端应用
chatgpt-vue: chatgpt-vue:
image: registry.cn-hangzhou.aliyuncs.com/geekmaster/chatgpt-plus-vue:v3.0.4 image: chatgpt-plus-vue:v3.0.5
# image: chatgpt-plus-vue:v3.0.2
container_name: chatgpt-plus-vue container_name: chatgpt-plus-vue
restart: always restart: always
ports: ports:
- "8080:8080" - "8080:8080"
volumes: volumes:
- /usr/share/zoneinfo/Asia/Shanghai:/etc/localtime
- ./logs/nginx:/var/log/nginx - ./logs/nginx:/var/log/nginx
- ./conf/nginx/conf.d:/etc/nginx/conf.d - ./conf/nginx/conf.d:/etc/nginx/conf.d
- ./conf/nginx/nginx.conf:/etc/nginx/nginx.conf - ./conf/nginx/nginx.conf:/etc/nginx/nginx.conf

View File

@ -36,7 +36,7 @@
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="打招呼信息" prop="hello_msg"/> <el-table-column label="打招呼信息" prop="hello_msg"/>
<el-table-column label="操作" width="180" align="right"> <el-table-column label="操作" width="150" align="right">
<template #default="scope"> <template #default="scope">
<el-button size="small" type="primary" @click="rowEdit(scope.$index, scope.row)">编辑</el-button> <el-button size="small" type="primary" @click="rowEdit(scope.$index, scope.row)">编辑</el-button>
<el-popconfirm title="确定要删除当前角色吗?" @confirm="removeRole(scope.row)"> <el-popconfirm title="确定要删除当前角色吗?" @confirm="removeRole(scope.row)">

View File

@ -1,5 +1,11 @@
<template> <template>
<div class="container user-list" v-loading="loading"> <div class="container user-list" v-loading="loading">
<div class="handle-box">
<el-input v-model="query.username" placeholder="用户名" class="handle-input mr10"></el-input>
<el-input v-model="query.mobile" placeholder="手机号码" class="handle-input mr10"></el-input>
<el-button type="primary" :icon="Search" @click="handleSearch">搜索</el-button>
</div>
<el-row> <el-row>
<el-table :data="users.items" border class="table" :row-key="row => row.id" <el-table :data="users.items" border class="table" :row-key="row => row.id"
@selection-change="handleSelectionChange"> @selection-change="handleSelectionChange">
@ -27,10 +33,13 @@
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" width="180"> <el-table-column fixed="right" label="操作" width="200">
<template #default="scope"> <template #default="scope">
<el-button size="small" type="primary" @click="userEdit(scope.row)">编辑</el-button> <el-button-group class="ml-4">
<el-button size="small" type="danger" @click="removeUser(scope.row)">删除</el-button> <el-button size="small" type="primary" @click="userEdit(scope.row)">编辑</el-button>
<el-button size="small" type="danger" @click="removeUser(scope.row)">删除</el-button>
<el-button size="small" type="success" @click="resetPass(scope.row)">重置密码</el-button>
</el-button-group>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@ -101,6 +110,29 @@
</span> </span>
</template> </template>
</el-dialog> </el-dialog>
<el-dialog
v-model="showResetPassDialog"
title="重置密码"
width="50%"
>
<el-form label-width="100px" ref="userEditFormRef">
<el-form-item label="用户名:">
<el-input v-model="pass.username" autocomplete="off" readonly disabled/>
</el-form-item>
<el-form-item label="新密码:">
<el-input v-model="pass.password" autocomplete="off"/>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button type="primary" @click="doResetPass">提交</el-button>
</span>
</template>
</el-dialog>
</div> </div>
</template> </template>
@ -109,13 +141,17 @@ import {nextTick, onMounted, reactive, ref} from "vue";
import {httpGet, httpPost} from "@/utils/http"; import {httpGet, httpPost} from "@/utils/http";
import {ElMessage, ElMessageBox} from "element-plus"; import {ElMessage, ElMessageBox} from "element-plus";
import {dateFormat, disabledDate, removeArrayItem} from "@/utils/libs"; 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 user = ref({chat_roles: []})
const pass = ref({username: '', password: '', id: 0})
const roles = ref([]) const roles = ref([])
const showUserEditDialog = ref(false) const showUserEditDialog = ref(false)
const showResetPassDialog = ref(false)
const rules = reactive({ const rules = reactive({
nickname: [{required: true, message: '请输入昵称', trigger: 'change',}], nickname: [{required: true, message: '请输入昵称', trigger: 'change',}],
calls: [ calls: [
@ -143,7 +179,9 @@ onMounted(() => {
}) })
const fetchUserList = function (page, pageSize) { 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) { if (res.data) {
// //
const arr = res.data.items; 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) { const removeUser = function (user) {
ElMessageBox.confirm( ElMessageBox.confirm(
@ -212,11 +254,38 @@ const handleSelectionChange = function (rows) {
// TODO: // TODO:
console.log(rows) 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)
})
}
</script> </script>
<style lang="stylus" scoped> <style lang="stylus" scoped>
.user-list { .user-list {
.handle-box {
.handle-input {
max-width 150px;
margin-right 10px;
}
}
.table {
width 100%
}
.opt-box { .opt-box {
padding-bottom: 10px; padding-bottom: 10px;

View File

@ -11,8 +11,8 @@
<el-button type="primary" :icon="Search" @click="handleSearch">搜索</el-button> <el-button type="primary" :icon="Search" @click="handleSearch">搜索</el-button>
<el-button type="primary" :icon="Plus">新增</el-button> <el-button type="primary" :icon="Plus">新增</el-button>
</div> </div>
<el-table :data="tableData" border class="table" ref="multipleTable" header-cell-class-name="table-header"> <el-table :data="tableData" border class="table" style="width: 100%" header-cell-class-name="table-header">
<el-table-column prop="id" label="ID" width="55" align="center"></el-table-column> <el-table-column prop="id" fixed label="ID" width="55" align="center"></el-table-column>
<el-table-column prop="name" label="姓名"></el-table-column> <el-table-column prop="name" label="姓名"></el-table-column>
<el-table-column label="头像(查看大图)" align="center"> <el-table-column label="头像(查看大图)" align="center">
<template #default="scope"> <template #default="scope">
@ -38,7 +38,7 @@
</el-table-column> </el-table-column>
<el-table-column prop="date" label="注册时间"></el-table-column> <el-table-column prop="date" label="注册时间"></el-table-column>
<el-table-column label="操作" width="220" align="center"> <el-table-column label="操作" fixed="right" align="center">
<template #default="scope"> <template #default="scope">
<el-button text :icon="Edit" @click="handleEdit(scope.$index, scope.row)"> <el-button text :icon="Edit" @click="handleEdit(scope.$index, scope.row)">
编辑 编辑