From d528cfd6bd630988368340989e4431c5db110aeb Mon Sep 17 00:00:00 2001 From: aaron <> Date: Thu, 16 Jan 2025 15:54:09 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=20=E9=87=8D=E7=BD=AE?= =?UTF-8?q?=E5=AF=86=E7=A0=81=E7=9A=84=E5=8A=9F=E8=83=BD=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/user/UserList.vue | 122 ++++++++++++++++++++++++++++++++++-- 1 file changed, 118 insertions(+), 4 deletions(-) diff --git a/src/views/user/UserList.vue b/src/views/user/UserList.vue index bd3eff6..29cefe5 100644 --- a/src/views/user/UserList.vue +++ b/src/views/user/UserList.vue @@ -66,9 +66,14 @@ {{ record.points || 0 }} @@ -97,6 +102,29 @@ + + + +

密码重置成功!新密码为:

+
+ +
+

请及时保存并告知用户

+ + +
@@ -323,6 +351,64 @@ export default defineComponent({ fetchData() } + // 密码重置相关状态 + const passwordModalVisible = ref(false) + const newPassword = ref('') + const passwordInput = ref(null) + + // 生成随机密码 + const generatePassword = () => { + const chars = '0123456789abcdefghijklmnopqrstuvwxyz' + let password = '' + for (let i = 0; i < 8; i++) { + password += chars.charAt(Math.floor(Math.random() * chars.length)) + } + return password + } + + // 处理重置密码 + const handleResetPassword = (record) => { + Modal.confirm({ + title: '重置密码', + content: `确定要重置用户 ${record.username || record.phone} 的密码吗?`, + async onOk() { + try { + const password = generatePassword() + await request.post('/api/user/reset-password', { + user_id: record.userid, + new_password: password + }) + + newPassword.value = password + passwordModalVisible.value = true + message.success('密码重置成功') + } catch (error) { + console.error('重置密码失败:', error) + message.error('重置密码失败') + } + } + }) + } + + // 复制密码 + const handleCopyPassword = async () => { + try { + await navigator.clipboard.writeText(newPassword.value) + message.success('密码已复制到剪贴板') + } catch (err) { + // 降级处理:如果剪贴板API不可用,使用输入框选择 + passwordInput.value.select() + document.execCommand('copy') + message.success('密码已复制到剪贴板') + } + } + + // 关闭密码模态框 + const handleClosePasswordModal = () => { + passwordModalVisible.value = false + newPassword.value = '' + } + onMounted(() => { fetchData() }) @@ -346,7 +432,13 @@ export default defineComponent({ filterForm, handleFilterChange, handleSearch, - handleReset + handleReset, + passwordModalVisible, + newPassword, + passwordInput, + handleResetPassword, + handleCopyPassword, + handleClosePasswordModal } } }) @@ -405,4 +497,26 @@ export default defineComponent({ :deep(.ant-form-item:last-child) { margin-right: 0; } + +.password-display { + margin: 16px 0; + background: #f5f5f5; + padding: 12px; + border-radius: 4px; +} + +.password-tip { + color: #ff4d4f; + margin-top: 8px; + margin-bottom: 0; +} + +:deep(.ant-input[readonly]) { + background-color: #fff; + cursor: text; + color: rgba(0, 0, 0, 0.85); + font-family: monospace; + font-size: 16px; + text-align: center; +} \ No newline at end of file