A8000
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

499 lines
12 KiB

<template>
<div class="user-management">
<div class="user-table" :key="refreshKey">
<el-table
:data="tableData"
header-cell-class-name="table-header"
row-class-name="table-row"
>
<el-table-column type="selection" width="80" />
<el-table-column label="用户" property="account" min-width="200" />
<el-table-column label="权限" property="usrRole" min-width="200" />
</el-table>
<div class="table-footer">
<el-button type="primary" @click="addUser">新增</el-button>
<el-button type="primary" @click="modifyPin">PIN</el-button>
<el-button type="danger" @click="deleteSelectedUsers">删除</el-button>
</div>
</div>
<!-- 弹窗组件 -->
<DelWarn
v-if="delShowModal"
:visible="delShowModal"
icon="/src/assets/Warn.svg"
title="删除用户"
:message="deleteUserMessage"
description="您正在删除用户,请谨慎操作"
confirm-text="确认删除"
cancel-text="取消删除"
@confirm="handleConfirmDelete"
@cancel="handleCancelDelete"
/>
<DelMessage
v-if="delMessageShowModal"
v-model:visible="delMessageShowModal"
icon="/src/assets/OK.svg"
message="已成功删除用户"
:username="selectedUsers[0]?.account"
@confirm="handleConfirmMsgDelete"
/>
<DelWarn
v-if="updatePinModal"
:visible="updatePinModal"
icon="/src/assets/update-pin-icon.svg"
title="PIN码更新"
:message="updatePinMessage"
description="您正在更改PIN码,请谨慎操作"
confirm-text="确认更新"
cancel-text="取消更新"
@confirm="handleConfirmUpdatePin"
@cancel="handleCancelUpdatePin"
/>
<EnterPinModal
v-if="enterPinModal"
:visible="enterPinModal"
:loading="updatePinLoading"
@confirm="updatePinConfirm"
@cancel="closeEnterPinModal"
/>
<DelMessage
v-if="updatePinMsgModal"
:visible="updatePinMsgModal"
icon="/src/assets/OK.svg"
message="PIN码更新成功"
:username="selectedUsers[0].account"
@confirm="handleConfirmMsg"
/>
<!-- 添加用户相关弹窗 -->
<template v-if="currentStep === 'username'">
<AddUserModal
:visible="insertUserShowModal"
:already-exist="isExist"
placeholder="请输入用户名"
:tips="tips"
@confirm="handleConfirmInsert"
@cancel="handleCancelInsert"
@resetAlreadyExist="resetAlreadyExist"
/>
</template>
<template v-else-if="currentStep === 'pin'">
<EnterPinModal
:visible="isPinModalVisible"
:loading="registerLoading"
@confirm="handlePinConfirm"
@cancel="closeModal"
/>
</template>
<DelMessage
v-if="confirmInsert"
:visible="confirmInsert"
icon="/src/assets/OK.svg"
message="已成功添加新用户"
:username="newUser.account"
@confirm="handleConfirmMsg"
/>
</div>
</template>
<script setup lang="ts">
import type { User } from '../../../types/Index'
import { DelWarn, DelMessage, AddUserModal, EnterPinModal } from '../components'
import { ref, onMounted, computed } from 'vue'
import {
getUserList,
deleteUser,
userRegister,
changeUserPassword,
} from '../../../services/Index/index'
const tableData = ref<User[]>([
{
id: 1,
account: '管理员',
password: '0000',
usrRole: 'Admin',
isBuiltInUser: true,
},
{
id: 2,
account: '操作员01',
password: '0000',
usrRole: 'Usr',
isBuiltInUser: false,
},
])
// 创建 `newUser` 对象存储用户名和 PIN 码
const newUser = ref({
account: '',
password: '',
usrRole: 'Usr',
})
//创建临时用户对象,用于存储用户名和PIN码
const tempUser = ref({
id: 0,
password: '',
})
const registerLoading = ref(false)
const updatePinLoading = ref(false)
const placeholder = ref('请输入用户名')
const currentStep = ref('username') // 当前步骤,初始为用户名输入页面
//控制删除提醒teleport
const delShowModal = ref(false)
const delMessageShowModal = ref(false)
const updatePinModal = ref(false)
const updatePinMsgModal = ref(false)
const insertUserShowModal = ref(false)
const isPinModalVisible = ref(true)
const confirmInsert = ref(false)
const isChecked = ref(false)
const enterPinModal = ref(false)
//用户是否存在
const isExist = ref(false)
//提醒
const tips = ref('')
// 模拟用户数据
const selectedUsers = ref<User[]>([])
const refreshKey = ref(0)
// 获取用户列表
const fetchUserList = async () => {
const response = await getUserList()
console.log('获取用户列表', response)
if (response && response.success) {
tableData.value = response.data
} else {
console.log('获取用户列表失败')
}
}
// 处理选择变化
const handleSelectionChange = (val: User[]) => {
selectedUsers.value = val
console.log('选中的用户', val)
// 只有当有选中用户时才更新 tempUser
if (val && val.length > 0) {
tempUser.value.id = val[0].id
tempUser.value.password = val[0].password
} else {
// 当没有选中用户时,重置 tempUser
tempUser.value.id = 0
tempUser.value.password = ''
}
}
// 新增用户
const addUser = async () => {
insertUserShowModal.value = true
}
// 修改用户权限 (模拟 PIN 码修改功能)
const modifyPin = async () => {
if (selectedUsers.value.length === 0) {
//通知用户没有选择用户,不使用控制台打印
isChecked.value = true
return
}
updatePinModal.value = true
}
// 删除用户
const deleteSelectedUsers = () => {
if (selectedUsers.value.length === 0) {
//通知用户没有选择用户,不使用控制台打印
isChecked.value = true
return
}
delShowModal.value = true
}
// 在组件挂载时调用获取用户列表
onMounted(() => {
fetchUserList()
})
const handleConfirmDelete = async () => {
try {
const ids = selectedUsers.value.map((user) => user.id)
for (const id of ids) {
const response = await deleteUser({ id })
if (!response || !response.success) {
console.log('删除用户失败')
return
}
}
delShowModal.value = false
// 在显示成功消息之前先保存要显示的用户名
// const deletedUsername = selectedUsers.value[0]?.account
// 清空选中的用户
selectedUsers.value = []
delMessageShowModal.value = true
} catch (error) {
console.error('删除用户时发生错误:', error)
}
}
const handleCancelDelete = () => {
delShowModal.value = false
}
const handleConfirmMsg = () => {
confirmInsert.value = false
isChecked.value = false
updatePinMsgModal.value = false
fetchUserList()
}
const handleConfirmMsgDelete = () => {
delMessageShowModal.value = false
fetchUserList()
}
//更新PIN
//定义请求
const handleUpdatePin = async () => {
if (selectedUsers.value.length !== 1) {
console.log('请选择一个用户来修改PIN码')
return
}
const user = tempUser.value
const response = await changeUserPassword({
id: user.id,
password: user.password,
})
if (response && response.success) {
} else {
console.log('修改用户权限失败')
}
}
//确认更新pin,打开输入框
const handleConfirmUpdatePin = () => {
updatePinModal.value = false
enterPinModal.value = true
}
//输入pin,确认,发送请求
const updatePinConfirm = (val: string) => {
enterPinModal.value = false
updatePinLoading.value = true
tempUser.value.password = val
handleUpdatePin().then(() => {
updatePinLoading.value = false
updatePinMsgModal.value = true
})
}
//取消
const closeEnterPinModal = () => {
enterPinModal.value = false
}
//取消
const handleCancelUpdatePin = () => {
updatePinModal.value = false
}
//添加用户
const handleConfirmInsert = (val: string) => {
const user = tableData.value.find((item) => item.account == val)
if (val == '') {
isExist.value = true
tips.value = '用户名不能为空'
placeholder.value = '请输入用户名'
} else if (user) {
isExist.value = true
tips.value = '用户已存在,请重新输入'
placeholder.value = val
} else {
newUser.value.account = val // 存储用户名
currentStep.value = 'pin'
}
}
const handleCancelInsert = () => {
insertUserShowModal.value = false
}
// 重置 `alreadyExist` 状态
const resetAlreadyExist = () => {
isExist.value = false
placeholder.value = '请输入用户名'
}
const handlePinConfirm = (pin: string) => {
// 处理 PIN 码确认逻辑
registerLoading.value = true
newUser.value.password = pin
handleAddUser().then(() => {
confirmInsert.value = true
registerLoading.value = false
isPinModalVisible.value = false
})
}
const closeModal = () => {
isPinModalVisible.value = false
}
//添加用户的api
const handleAddUser = async () => {
const res = await userRegister(newUser.value)
if (res && res.success) {
fetchUserList()
}
}
// 选中用户的 `account` 信息,用于显示在 `Warning` 组件中
const selectedUserAccount = computed(() => {
return selectedUsers.value.length > 0 ? selectedUsers.value[0].account : ''
})
// 动态生成的 message 内容
const updatePinMessage = computed(
() => `是否更新PIN码 <strong>${selectedUserAccount.value}</strong> 用户`,
)
const deleteUserMessage = computed(
() => `是否删除 <strong>${selectedUserAccount.value}</strong> 用户`,
)
</script>
<style scoped lang="less">
.user-management {
width: 100%;
height: 90vh;
padding: 20px;
box-sizing: border-box;
background-color: #f5f7fa;
display: flex;
flex-direction: column;
.user-table {
flex: 1;
background-color: #fff;
border-radius: 12px;
padding: 24px;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
display: flex;
flex-direction: column;
transition: all 0.3s ease;
&:hover {
box-shadow: 0 4px 16px 0 rgba(0, 0, 0, 0.08);
}
:deep(.el-table) {
flex: 1;
border: none;
border-radius: 8px;
overflow: hidden;
&::before {
display: none;
}
.el-table__header {
th {
background-color: #f5f7fa;
border: none;
height: 60px;
font-size: 24px;
font-weight: 500;
color: #303133;
&.is-leaf {
border: none;
}
}
}
.el-table__body {
td {
border: none;
height: 60px;
font-size: 24px;
color: #606266;
transition: background-color 0.3s;
}
tr {
border: none;
transition: all 0.3s;
&:hover > td {
background-color: #f5f7fa;
}
&.selected-row > td {
background-color: #ecf5ff;
}
}
}
// 放大多选框
.el-checkbox {
transform: scale(1.5);
.el-checkbox__inner {
border-color: #dcdfe6;
transition: all 0.3s;
&:hover {
border-color: #409eff;
}
}
}
}
.table-footer {
margin-top: 24px;
display: flex;
justify-content: center;
gap: 20px;
.el-button {
min-width: 160px;
height: 56px;
border-radius: 8px;
font-size: 24px;
font-weight: 500;
transition: all 0.3s;
display: flex;
align-items: center;
justify-content: center;
&:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(64, 158, 255, 0.2);
}
&.el-button--primary {
background-color: #409eff;
border-color: #409eff;
&:hover {
background-color: #66b1ff;
border-color: #66b1ff;
}
}
&.el-button--danger {
&:hover {
box-shadow: 0 4px 12px rgba(245, 108, 108, 0.2);
}
}
}
}
}
}
// 添加响应式设计
@media screen and (max-width: 768px) {
.user-management {
padding: 10px;
.user-table {
padding: 16px;
.table-footer {
flex-direction: column;
align-items: stretch;
gap: 12px;
.el-button {
width: 100%;
}
}
}
}
}
</style>