diff --git a/api/handler/admin/user_handler.go b/api/handler/admin/user_handler.go
index a2b9fe4c..d491d83a 100644
--- a/api/handler/admin/user_handler.go
+++ b/api/handler/admin/user_handler.go
@@ -8,6 +8,7 @@ import (
"chatplus/store/vo"
"chatplus/utils"
"chatplus/utils/resp"
+ "fmt"
"github.com/gin-gonic/gin"
"gorm.io/gorm"
@@ -64,9 +65,12 @@ func (h *UserHandler) List(c *gin.Context) {
resp.SUCCESS(c, pageVo)
}
-func (h *UserHandler) Update(c *gin.Context) {
+func (h *UserHandler) Save(c *gin.Context) {
var data struct {
Id uint `json:"id"`
+ Username string `json:"username"`
+ Password string `json:"password"`
+ Mobile string `json:"mobile"`
Nickname string `json:"nickname"`
Calls int `json:"calls"`
ChatRoles []string `json:"chat_roles"`
@@ -78,21 +82,54 @@ func (h *UserHandler) Update(c *gin.Context) {
return
}
var user = model.User{}
- user.Id = data.Id
- // 此处需要用 map 更新,用结构体无法更新 0 值
- res := h.db.Model(&user).Updates(map[string]interface{}{
- "nickname": data.Nickname,
- "calls": data.Calls,
- "status": data.Status,
- "chat_roles_json": utils.JsonEncode(data.ChatRoles),
- "expired_time": utils.Str2stamp(data.ExpiredTime),
- })
+ var res *gorm.DB
+ var userVo vo.User
+ if data.Id > 0 { // 更新
+ user.Id = data.Id
+ // 此处需要用 map 更新,用结构体无法更新 0 值
+ res = h.db.Model(&user).Updates(map[string]interface{}{
+ "nickname": data.Nickname,
+ "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 {
resp.ERROR(c, "更新数据库失败")
return
}
- resp.SUCCESS(c)
+ resp.SUCCESS(c, userVo)
}
// ResetPass 重置密码
diff --git a/api/handler/user_handler.go b/api/handler/user_handler.go
index 215431cb..e9169feb 100644
--- a/api/handler/user_handler.go
+++ b/api/handler/user_handler.go
@@ -146,6 +146,11 @@ func (h *UserHandler) Login(c *gin.Context) {
return
}
+ if user.Status == false {
+ resp.ERROR(c, "该用户已被禁止登录,请联系管理员")
+ return
+ }
+
// 更新最后登录时间和IP
user.LastLoginIp = c.ClientIP()
user.LastLoginAt = time.Now().Unix()
diff --git a/api/main.go b/api/main.go
index 0d8b13e2..77f26705 100644
--- a/api/main.go
+++ b/api/main.go
@@ -215,7 +215,7 @@ func main() {
fx.Invoke(func(s *core.AppServer, h *admin.UserHandler) {
group := s.Engine.Group("/api/admin/user/")
group.GET("list", h.List)
- group.POST("update", h.Update)
+ group.POST("save", h.Save)
group.GET("remove", h.Remove)
group.GET("loginLog", h.LoginLog)
group.POST("resetPass", h.ResetPass)
diff --git a/api/utils/strings.go b/api/utils/strings.go
index a8fa3be6..ac8d24ae 100644
--- a/api/utils/strings.go
+++ b/api/utils/strings.go
@@ -56,6 +56,10 @@ func Stamp2str(timestamp int64) string {
// Str2stamp 字符串转时间戳
func Str2stamp(str string) int64 {
+ if len(str) == 0 {
+ return 0
+ }
+
layout := "2006-01-02 15:04:05"
t, err := time.Parse(layout, str)
if err != nil {
diff --git a/web/src/views/admin/UserList.vue b/web/src/views/admin/UserList.vue
index 45676927..457cc6de 100644
--- a/web/src/views/admin/UserList.vue
+++ b/web/src/views/admin/UserList.vue
@@ -4,6 +4,8 @@
搜索
+
+ 新增用户
@@ -59,14 +61,24 @@
-
+
+
+
+
+
+
+
+
+
+
+
@@ -106,7 +118,7 @@
@@ -147,13 +159,18 @@ import {Plus, Search} from "@element-plus/icons-vue";
const users = ref({page: 1, page_size: 15, items: []})
const query = ref({username: '', mobile: '', page: 1, page_size: 15})
+const title = ref('添加用户')
+const add = ref(true)
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({
+ username: [{required: true, message: '请输入用户名', trigger: 'change',}],
nickname: [{required: true, message: '请输入昵称', trigger: 'change',}],
+ password: [{required: true, message: '请输入密码', trigger: 'change',}],
+ mobile: [{required: true, message: '请输入手机号码', trigger: 'change',}],
calls: [
{required: true, message: '请输入提问次数'},
{type: 'number', message: '请输入有效数字'},
@@ -212,35 +229,44 @@ const removeUser = function (user) {
cancelButtonText: '取消',
type: 'warning',
}
- )
- .then(() => {
- httpGet('/api/admin/user/remove', {id: user.id}).then(() => {
- ElMessage.success('操作成功!')
- users.value.items = removeArrayItem(users.value.items, user, function (v1, v2) {
- return v1.id === v2.id
- })
- }).catch((e) => {
- ElMessage.error('操作失败,' + e.message)
- })
- })
- .catch(() => {
- ElMessage.info('操作被取消')
+ ).then(() => {
+ httpGet('/api/admin/user/remove', {id: user.id}).then(() => {
+ ElMessage.success('操作成功!')
+ users.value.items = removeArrayItem(users.value.items, user, function (v1, v2) {
+ return v1.id === v2.id
})
+ }).catch((e) => {
+ ElMessage.error('操作失败,' + e.message)
+ })
+ }).catch(() => {
+ ElMessage.info('操作被取消')
+ })
}
-const userEdit = function (_user) {
- user.value = _user
+const userEdit = function (row) {
+ user.value = row
+ title.value = '编辑用户'
showUserEditDialog.value = true
+ add.value = false
}
-// 更新口令
-const updateUser = function () {
+const addUser = () => {
+ user.value = {}
+ title.value = '添加用户'
+ showUserEditDialog.value = true
+ add.value = true
+}
+
+const saveUser = function () {
userEditFormRef.value.validate((valid) => {
if (valid) {
showUserEditDialog.value = false
- httpPost('/api/admin/user/update', user.value).then(() => {
+ httpPost('/api/admin/user/save', user.value).then((res) => {
ElMessage.success('操作成功!')
+ if (add.value) {
+ users.value.items.push(res.data)
+ }
}).catch((e) => {
ElMessage.error('操作失败,' + e.message)
})