feat: new function for add user in manger console user list page

This commit is contained in:
RockYang 2023-08-01 16:02:49 +08:00
parent ffb1ef0470
commit 9eb8da2789
5 changed files with 105 additions and 33 deletions

View File

@ -8,6 +8,7 @@ import (
"chatplus/store/vo" "chatplus/store/vo"
"chatplus/utils" "chatplus/utils"
"chatplus/utils/resp" "chatplus/utils/resp"
"fmt"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"gorm.io/gorm" "gorm.io/gorm"
@ -64,9 +65,12 @@ func (h *UserHandler) List(c *gin.Context) {
resp.SUCCESS(c, pageVo) resp.SUCCESS(c, pageVo)
} }
func (h *UserHandler) Update(c *gin.Context) { func (h *UserHandler) Save(c *gin.Context) {
var data struct { var data struct {
Id uint `json:"id"` Id uint `json:"id"`
Username string `json:"username"`
Password string `json:"password"`
Mobile string `json:"mobile"`
Nickname string `json:"nickname"` Nickname string `json:"nickname"`
Calls int `json:"calls"` Calls int `json:"calls"`
ChatRoles []string `json:"chat_roles"` ChatRoles []string `json:"chat_roles"`
@ -78,21 +82,54 @@ func (h *UserHandler) Update(c *gin.Context) {
return return
} }
var user = model.User{} var user = model.User{}
user.Id = data.Id var res *gorm.DB
// 此处需要用 map 更新,用结构体无法更新 0 值 var userVo vo.User
res := h.db.Model(&user).Updates(map[string]interface{}{ if data.Id > 0 { // 更新
"nickname": data.Nickname, user.Id = data.Id
"calls": data.Calls, // 此处需要用 map 更新,用结构体无法更新 0 值
"status": data.Status, res = h.db.Model(&user).Updates(map[string]interface{}{
"chat_roles_json": utils.JsonEncode(data.ChatRoles), "nickname": data.Nickname,
"expired_time": utils.Str2stamp(data.ExpiredTime), "mobile": data.Mobile,
}) "calls": data.Calls,
"status": data.Status,
"chat_roles_json": utils.JsonEncode(data.ChatRoles),
"expired_time": utils.Str2stamp(data.ExpiredTime),
})
} else {
salt := utils.RandString(8)
u := model.User{
Username: data.Username,
Password: utils.GenPassword(data.Password, salt),
Nickname: fmt.Sprintf("极客学长@%d", utils.RandomNumber(5)),
Avatar: "/images/avatar/user.png",
Salt: salt,
Status: true,
Mobile: data.Mobile,
ChatRoles: utils.JsonEncode(data.ChatRoles),
ExpiredTime: utils.Str2stamp(data.ExpiredTime),
ChatConfig: utils.JsonEncode(types.ChatConfig{
Temperature: h.App.ChatConfig.Temperature,
MaxTokens: h.App.ChatConfig.MaxTokens,
EnableContext: h.App.ChatConfig.EnableContext,
EnableHistory: true,
Model: h.App.ChatConfig.Model,
ApiKey: "",
}),
Calls: h.App.SysConfig.UserInitCalls,
}
res = h.db.Create(&u)
_ = utils.CopyObject(u, &userVo)
userVo.Id = u.Id
userVo.CreatedAt = u.CreatedAt.Unix()
userVo.UpdatedAt = u.UpdatedAt.Unix()
}
if res.Error != nil { if res.Error != nil {
resp.ERROR(c, "更新数据库失败") resp.ERROR(c, "更新数据库失败")
return return
} }
resp.SUCCESS(c) resp.SUCCESS(c, userVo)
} }
// ResetPass 重置密码 // ResetPass 重置密码

View File

@ -146,6 +146,11 @@ func (h *UserHandler) Login(c *gin.Context) {
return return
} }
if user.Status == false {
resp.ERROR(c, "该用户已被禁止登录,请联系管理员")
return
}
// 更新最后登录时间和IP // 更新最后登录时间和IP
user.LastLoginIp = c.ClientIP() user.LastLoginIp = c.ClientIP()
user.LastLoginAt = time.Now().Unix() user.LastLoginAt = time.Now().Unix()

View File

@ -215,7 +215,7 @@ func main() {
fx.Invoke(func(s *core.AppServer, h *admin.UserHandler) { fx.Invoke(func(s *core.AppServer, h *admin.UserHandler) {
group := s.Engine.Group("/api/admin/user/") group := s.Engine.Group("/api/admin/user/")
group.GET("list", h.List) group.GET("list", h.List)
group.POST("update", h.Update) group.POST("save", h.Save)
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) group.POST("resetPass", h.ResetPass)

View File

@ -56,6 +56,10 @@ func Stamp2str(timestamp int64) string {
// Str2stamp 字符串转时间戳 // Str2stamp 字符串转时间戳
func Str2stamp(str string) int64 { func Str2stamp(str string) int64 {
if len(str) == 0 {
return 0
}
layout := "2006-01-02 15:04:05" layout := "2006-01-02 15:04:05"
t, err := time.Parse(layout, str) t, err := time.Parse(layout, str)
if err != nil { if err != nil {

View File

@ -4,6 +4,8 @@
<el-input v-model="query.username" placeholder="用户名" class="handle-input mr10"></el-input> <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-input v-model="query.mobile" placeholder="手机号码" class="handle-input mr10"></el-input>
<el-button type="primary" :icon="Search" @click="handleSearch">搜索</el-button> <el-button type="primary" :icon="Search" @click="handleSearch">搜索</el-button>
<el-button type="success" :icon="Plus" @click="addUser">新增用户</el-button>
</div> </div>
<el-row> <el-row>
@ -59,14 +61,24 @@
<el-dialog <el-dialog
v-model="showUserEditDialog" v-model="showUserEditDialog"
title="编辑用户" :title="title"
width="50%" width="50%"
> >
<el-form :model="user" label-width="100px" ref="userEditFormRef" :rules="rules"> <el-form :model="user" label-width="100px" ref="userEditFormRef" :rules="rules">
<el-form-item label="昵称:" prop="nickname"> <el-form-item v-if="add" label="用户名:" prop="username">
<el-input v-model="user.username" autocomplete="off"/>
</el-form-item>
<el-form-item v-else label="昵称:" prop="nickname">
<el-input v-model="user.nickname" autocomplete="off"/> <el-input v-model="user.nickname" autocomplete="off"/>
</el-form-item> </el-form-item>
<el-form-item v-if="add" label="密码:" prop="password">
<el-input v-model="user.password" autocomplete="off"/>
</el-form-item>
<el-form-item label="手机号:" prop="mobile">
<el-input v-model="user.mobile" autocomplete="off"/>
</el-form-item>
<el-form-item label="提问次数:" prop="calls"> <el-form-item label="提问次数:" prop="calls">
<el-input v-model.number="user.calls" autocomplete="off" placeholder="0"/> <el-input v-model.number="user.calls" autocomplete="off" placeholder="0"/>
</el-form-item> </el-form-item>
@ -106,7 +118,7 @@
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
<el-button @click="showUserEditDialog = false">取消</el-button> <el-button @click="showUserEditDialog = false">取消</el-button>
<el-button type="primary" @click="updateUser">提交</el-button> <el-button type="primary" @click="saveUser">提交</el-button>
</span> </span>
</template> </template>
</el-dialog> </el-dialog>
@ -147,13 +159,18 @@ import {Plus, Search} from "@element-plus/icons-vue";
const users = ref({page: 1, page_size: 15, items: []}) const users = ref({page: 1, page_size: 15, items: []})
const query = ref({username: '', mobile: '', page: 1, page_size: 15}) const query = ref({username: '', mobile: '', page: 1, page_size: 15})
const title = ref('添加用户')
const add = ref(true)
const user = ref({chat_roles: []}) const user = ref({chat_roles: []})
const pass = ref({username: '', password: '', id: 0}) 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 showResetPassDialog = ref(false)
const rules = reactive({ const rules = reactive({
username: [{required: true, message: '请输入用户名', trigger: 'change',}],
nickname: [{required: true, message: '请输入昵称', trigger: 'change',}], nickname: [{required: true, message: '请输入昵称', trigger: 'change',}],
password: [{required: true, message: '请输入密码', trigger: 'change',}],
mobile: [{required: true, message: '请输入手机号码', trigger: 'change',}],
calls: [ calls: [
{required: true, message: '请输入提问次数'}, {required: true, message: '请输入提问次数'},
{type: 'number', message: '请输入有效数字'}, {type: 'number', message: '请输入有效数字'},
@ -212,35 +229,44 @@ const removeUser = function (user) {
cancelButtonText: '取消', cancelButtonText: '取消',
type: 'warning', type: 'warning',
} }
) ).then(() => {
.then(() => { httpGet('/api/admin/user/remove', {id: user.id}).then(() => {
httpGet('/api/admin/user/remove', {id: user.id}).then(() => { ElMessage.success('操作成功!')
ElMessage.success('操作成功!') users.value.items = removeArrayItem(users.value.items, user, function (v1, v2) {
users.value.items = removeArrayItem(users.value.items, user, function (v1, v2) { return v1.id === v2.id
return v1.id === v2.id
})
}).catch((e) => {
ElMessage.error('操作失败,' + e.message)
})
})
.catch(() => {
ElMessage.info('操作被取消')
}) })
}).catch((e) => {
ElMessage.error('操作失败,' + e.message)
})
}).catch(() => {
ElMessage.info('操作被取消')
})
} }
const userEdit = function (_user) { const userEdit = function (row) {
user.value = _user user.value = row
title.value = '编辑用户'
showUserEditDialog.value = true showUserEditDialog.value = true
add.value = false
} }
// const addUser = () => {
const updateUser = function () { user.value = {}
title.value = '添加用户'
showUserEditDialog.value = true
add.value = true
}
const saveUser = function () {
userEditFormRef.value.validate((valid) => { userEditFormRef.value.validate((valid) => {
if (valid) { if (valid) {
showUserEditDialog.value = false showUserEditDialog.value = false
httpPost('/api/admin/user/update', user.value).then(() => { httpPost('/api/admin/user/save', user.value).then((res) => {
ElMessage.success('操作成功!') ElMessage.success('操作成功!')
if (add.value) {
users.value.items.push(res.data)
}
}).catch((e) => { }).catch((e) => {
ElMessage.error('操作失败,' + e.message) ElMessage.error('操作失败,' + e.message)
}) })