Merge branch 'main' of github.com:zstar1003/ragflow-plus
This commit is contained in:
commit
41d575221f
|
@ -81,6 +81,9 @@ RAGFLOWPLUS_MANAGEMENT_SERVER_IMAGE=zstar1003/ragflowplus-management-server:v0.2
|
|||
# The local time zone.
|
||||
TIMEZONE='Asia/Shanghai'
|
||||
|
||||
# 后端允许上传的最大文件大小
|
||||
MAX_CONTENT_LENGTH=10737418240 # 10GB
|
||||
|
||||
# 管理系统用户名和密码
|
||||
MANAGEMENT_ADMIN_USERNAME=admin
|
||||
MANAGEMENT_ADMIN_PASSWORD=12345678
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
from flask import jsonify, request
|
||||
from services.users.service import get_users_with_pagination, delete_user, create_user, update_user
|
||||
from services.users.service import get_users_with_pagination, delete_user, create_user, update_user, reset_user_password
|
||||
from .. import users_bp
|
||||
|
||||
@users_bp.route('', methods=['GET'])
|
||||
|
@ -71,4 +71,39 @@ def get_current_user():
|
|||
"roles": ["admin"]
|
||||
},
|
||||
"message": "获取用户信息成功"
|
||||
})
|
||||
})
|
||||
|
||||
@users_bp.route('/<string:user_id>/reset-password', methods=['PUT'])
|
||||
def reset_password_route(user_id):
|
||||
"""
|
||||
重置用户密码的API端点
|
||||
Args:
|
||||
user_id (str): 需要重置密码的用户ID
|
||||
Returns:
|
||||
Response: JSON响应
|
||||
"""
|
||||
try:
|
||||
data = request.json
|
||||
new_password = data.get('password')
|
||||
|
||||
# 校验密码是否存在
|
||||
if not new_password:
|
||||
return jsonify({"code": 400, "message": "缺少新密码参数 'password'"}), 400
|
||||
|
||||
# 调用 service 函数重置密码
|
||||
success = reset_user_password(user_id=user_id, new_password=new_password)
|
||||
|
||||
if success:
|
||||
return jsonify({
|
||||
"code": 0,
|
||||
"message": f"用户密码重置成功"
|
||||
})
|
||||
else:
|
||||
# service 层可能因为用户不存在或其他原因返回 False
|
||||
return jsonify({"code": 404, "message": f"用户未找到或密码重置失败"}), 404
|
||||
except Exception as e:
|
||||
# 统一处理异常
|
||||
return jsonify({
|
||||
"code": 500,
|
||||
"message": f"重置密码失败: {str(e)}"
|
||||
}), 500
|
|
@ -229,7 +229,7 @@ class KnowledgebaseService:
|
|||
|
||||
# 设置默认值
|
||||
default_parser_config = json.dumps({
|
||||
"layout_recognize": "DeepDOC",
|
||||
"layout_recognize": "MinerU",
|
||||
"chunk_token_num": 512,
|
||||
"delimiter": "\n!?;。;!?",
|
||||
"auto_keywords": 0,
|
||||
|
@ -557,7 +557,7 @@ class KnowledgebaseService:
|
|||
# 设置默认值
|
||||
default_parser_id = "naive"
|
||||
default_parser_config = json.dumps({
|
||||
"layout_recognize": "DeepDOC",
|
||||
"layout_recognize": "MinerU",
|
||||
"chunk_token_num": 512,
|
||||
"delimiter": "\n!?;。;!?",
|
||||
"auto_keywords": 0,
|
||||
|
|
|
@ -287,4 +287,61 @@ def update_user(user_id, user_data):
|
|||
return True
|
||||
except mysql.connector.Error as err:
|
||||
print(f"更新用户错误: {err}")
|
||||
return False
|
||||
|
||||
def reset_user_password(user_id, new_password):
|
||||
"""
|
||||
重置指定用户的密码
|
||||
Args:
|
||||
user_id (str): 用户ID
|
||||
new_password (str): 新的明文密码
|
||||
Returns:
|
||||
bool: 操作是否成功
|
||||
"""
|
||||
try:
|
||||
conn = mysql.connector.connect(**DB_CONFIG)
|
||||
cursor = conn.cursor()
|
||||
|
||||
# 加密新密码
|
||||
encrypted_password = encrypt_password(new_password) # 使用与创建用户时相同的加密方法
|
||||
update_time = int(datetime.now().timestamp() * 1000)
|
||||
update_date = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||
|
||||
# 更新用户密码
|
||||
update_query = """
|
||||
UPDATE user
|
||||
SET password = %s, update_time = %s, update_date = %s
|
||||
WHERE id = %s
|
||||
"""
|
||||
cursor.execute(update_query, (encrypted_password, update_time, update_date, user_id))
|
||||
|
||||
# 检查是否有行被更新
|
||||
if cursor.rowcount == 0:
|
||||
conn.rollback() # 如果没有更新,回滚
|
||||
cursor.close()
|
||||
conn.close()
|
||||
print(f"用户 {user_id} 未找到,密码未更新。")
|
||||
return False # 用户不存在
|
||||
|
||||
conn.commit() # 提交事务
|
||||
cursor.close()
|
||||
conn.close()
|
||||
print(f"用户 {user_id} 密码已成功重置。")
|
||||
return True
|
||||
|
||||
except mysql.connector.Error as err:
|
||||
print(f"重置密码时数据库错误: {err}")
|
||||
# 可以在这里添加更详细的日志记录
|
||||
# 如果 conn 存在且打开,尝试回滚
|
||||
if 'conn' in locals() and conn.is_connected():
|
||||
conn.rollback()
|
||||
cursor.close()
|
||||
conn.close()
|
||||
return False
|
||||
except Exception as e:
|
||||
print(f"重置密码时发生未知错误: {e}")
|
||||
if 'conn' in locals() and conn.is_connected():
|
||||
conn.rollback()
|
||||
cursor.close()
|
||||
conn.close()
|
||||
return False
|
|
@ -35,3 +35,17 @@ export function getTableDataApi(params: Tables.TableRequestData) {
|
|||
params
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置用户密码
|
||||
* @param userId 用户ID
|
||||
* @param password 新密码
|
||||
* @returns BaseResponse
|
||||
*/
|
||||
export function resetPasswordApi(userId: number, password: string) {
|
||||
return request({
|
||||
url: `api/v1/users/${userId}/reset-password`,
|
||||
method: "put",
|
||||
data: { password } // 发送新密码
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<script lang="ts" setup>
|
||||
import type { CreateOrUpdateTableRequestData, TableData } from "@@/apis/tables/type"
|
||||
import type { FormInstance, FormRules } from "element-plus"
|
||||
import { createTableDataApi, deleteTableDataApi, getTableDataApi, updateTableDataApi } from "@@/apis/tables"
|
||||
import { createTableDataApi, deleteTableDataApi, getTableDataApi, resetPasswordApi, updateTableDataApi } from "@@/apis/tables"
|
||||
import { usePagination } from "@@/composables/usePagination"
|
||||
import { CirclePlus, Delete, Refresh, RefreshRight, Search } from "@element-plus/icons-vue"
|
||||
import { CirclePlus, Delete, Edit, Key, Refresh, RefreshRight, Search } from "@element-plus/icons-vue"
|
||||
import { cloneDeep } from "lodash-es"
|
||||
|
||||
defineOptions({
|
||||
|
@ -36,10 +36,23 @@ const formRules: FormRules<CreateOrUpdateTableRequestData> = {
|
|||
],
|
||||
password: [{ required: true, trigger: "blur", message: "请输入密码" }]
|
||||
}
|
||||
// #region 重置密码
|
||||
const resetPasswordDialogVisible = ref<boolean>(false)
|
||||
const resetPasswordFormRef = ref<FormInstance | null>(null)
|
||||
const currentUserId = ref<number | undefined>(undefined) // 用于存储当前要重置密码的用户ID
|
||||
const resetPasswordFormData = reactive({
|
||||
password: ""
|
||||
})
|
||||
const resetPasswordFormRules: FormRules = {
|
||||
password: [
|
||||
{ required: true, message: "请输入新密码", trigger: "blur" }
|
||||
]
|
||||
}
|
||||
// #endregion
|
||||
function handleCreateOrUpdate() {
|
||||
formRef.value?.validate((valid) => {
|
||||
if (!valid) {
|
||||
ElMessage.error("表单校验不通过")
|
||||
ElMessage.error("登录校验不通过")
|
||||
return
|
||||
}
|
||||
loading.value = true
|
||||
|
@ -59,6 +72,60 @@ function resetForm() {
|
|||
}
|
||||
// #endregion
|
||||
|
||||
// #region 重置密码处理
|
||||
/**
|
||||
* 打开重置密码对话框
|
||||
* @param {TableData} row - 当前行用户数据
|
||||
*/
|
||||
function handleResetPassword(row: TableData) {
|
||||
currentUserId.value = row.id
|
||||
resetPasswordFormData.password = "" // 清空上次输入
|
||||
resetPasswordDialogVisible.value = true
|
||||
// 清除之前的校验状态
|
||||
nextTick(() => {
|
||||
resetPasswordFormRef.value?.clearValidate()
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 提交重置密码表单
|
||||
*/
|
||||
function submitResetPassword() {
|
||||
resetPasswordFormRef.value?.validate((valid) => {
|
||||
if (!valid) {
|
||||
ElMessage.error("表单校验不通过")
|
||||
return
|
||||
}
|
||||
if (currentUserId.value === undefined) {
|
||||
ElMessage.error("用户ID丢失,无法重置密码")
|
||||
return
|
||||
}
|
||||
loading.value = true
|
||||
// 调用后端API重置密码
|
||||
resetPasswordApi(currentUserId.value, resetPasswordFormData.password)
|
||||
.then(() => {
|
||||
ElMessage.success("密码重置成功")
|
||||
resetPasswordDialogVisible.value = false
|
||||
})
|
||||
.catch((error: any) => {
|
||||
console.error("重置密码失败:", error)
|
||||
ElMessage.error("密码重置失败")
|
||||
})
|
||||
.finally(() => {
|
||||
loading.value = false
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭重置密码对话框时重置状态
|
||||
*/
|
||||
function resetPasswordDialogClosed() {
|
||||
currentUserId.value = undefined
|
||||
resetPasswordFormRef.value?.resetFields() // 重置表单字段
|
||||
}
|
||||
// #endregion
|
||||
|
||||
// #region 删
|
||||
function handleDelete(row: TableData) {
|
||||
ElMessageBox.confirm(`正在删除用户:${row.username},确认删除?`, "提示", {
|
||||
|
@ -198,12 +265,15 @@ watch([() => paginationData.currentPage, () => paginationData.pageSize], getTabl
|
|||
<el-table-column prop="email" label="邮箱" align="center" />
|
||||
<el-table-column prop="createTime" label="创建时间" align="center" />
|
||||
<el-table-column prop="updateTime" label="更新时间" align="center" />
|
||||
<el-table-column fixed="right" label="操作" width="150" align="center">
|
||||
<el-table-column fixed="right" label="操作" width="300" align="center">
|
||||
<template #default="scope">
|
||||
<el-button type="primary" text bg size="small" @click="handleUpdate(scope.row)">
|
||||
修改
|
||||
<el-button type="primary" text bg size="small" :icon="Edit" @click="handleUpdate(scope.row)">
|
||||
修改用户名
|
||||
</el-button>
|
||||
<el-button type="danger" text bg size="small" @click="handleDelete(scope.row)">
|
||||
<el-button type="warning" text bg size="small" :icon="Key" @click="handleResetPassword(scope.row)">
|
||||
重置密码
|
||||
</el-button>
|
||||
<el-button type="danger" text bg size="small" :icon="Delete" @click="handleDelete(scope.row)">
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
|
@ -250,6 +320,28 @@ watch([() => paginationData.currentPage, () => paginationData.pageSize], getTabl
|
|||
</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 重置密码对话框 -->
|
||||
<el-dialog
|
||||
v-model="resetPasswordDialogVisible"
|
||||
title="重置密码"
|
||||
width="30%"
|
||||
@closed="resetPasswordDialogClosed"
|
||||
>
|
||||
<el-form ref="resetPasswordFormRef" :model="resetPasswordFormData" :rules="resetPasswordFormRules" label-width="100px" label-position="left">
|
||||
<el-form-item prop="password" label="新密码">
|
||||
<el-input v-model="resetPasswordFormData.password" type="password" show-password placeholder="请输入新密码" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="resetPasswordDialogVisible = false">
|
||||
取消
|
||||
</el-button>
|
||||
<el-button type="primary" :loading="loading" @click="submitResetPassword">
|
||||
确认重置
|
||||
</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -38,6 +38,8 @@ declare module 'vue' {
|
|||
ElPagination: typeof import('element-plus/es')['ElPagination']
|
||||
ElPopover: typeof import('element-plus/es')['ElPopover']
|
||||
ElProgress: typeof import('element-plus/es')['ElProgress']
|
||||
ElRadio: typeof import('element-plus/es')['ElRadio']
|
||||
ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup']
|
||||
ElScrollbar: typeof import('element-plus/es')['ElScrollbar']
|
||||
ElSelect: typeof import('element-plus/es')['ElSelect']
|
||||
ElSubMenu: typeof import('element-plus/es')['ElSubMenu']
|
||||
|
|
Loading…
Reference in New Issue