update:完成用户启用/禁用功能 (#694)

* update:优化文档

* update:完成用户启用/禁用功能
This commit is contained in:
hrz
2025-04-07 15:14:20 +08:00
committed by GitHub
parent 6862735aa0
commit 07d8f783e0
7 changed files with 166 additions and 74 deletions
+17
View File
@@ -104,4 +104,21 @@ export default {
}) })
.send(); .send();
}, },
// 修改用户状态
changeUserStatus(status, userIds, successCallback) {
return RequestService.sendRequest()
.url(`${getServiceUrl()}/admin/users/changeStatus/${status}`)
.method('put')
.data(userIds)
.success((res) => {
RequestService.clearRequestTime()
successCallback(res);
})
.fail((err) => {
console.error('修改用户状态失败:', err)
RequestService.reAjaxFun(() => {
this.changeUserStatus(status, userIds)
})
}).send()
},
} }
@@ -1,43 +1,44 @@
<template> <template>
<form> <form>
<el-dialog :visible.sync="value" width="400px" center> <el-dialog :visible.sync="value" width="400px" center>
<div style="margin: 0 10px 10px;display: flex;align-items: center;gap: 10px;font-weight: 700;font-size: 20px;text-align: left;color: #3d4566;"> <div
<div style="width: 40px;height: 40px;border-radius: 50%;background: #5778ff;display: flex;align-items: center;justify-content: center;"> style="margin: 0 10px 10px;display: flex;align-items: center;gap: 10px;font-weight: 700;font-size: 20px;text-align: left;color: #3d4566;">
<img loading="lazy" src="@/assets/login/shield.png" alt="" style="width: 19px;height: 23px; filter: brightness(0) invert(1);" /> <div
style="width: 40px;height: 40px;border-radius: 50%;background: #5778ff;display: flex;align-items: center;justify-content: center;">
<img loading="lazy" src="@/assets/login/shield.png" alt=""
style="width: 19px;height: 23px; filter: brightness(0) invert(1);" />
</div> </div>
修改密码 修改密码
</div> </div>
<div style="height: 1px;background: #e8f0ff;"/> <div style="height: 1px;background: #e8f0ff;" />
<div style="margin: 22px 15px;"> <div style="margin: 22px 15px;">
<div style="font-weight: 400;font-size: 14px;text-align: left;color: #3d4566;"> <div style="font-weight: 400;font-size: 14px;text-align: left;color: #3d4566;">
<div style="color: red;display: inline-block;">*</div> <div style="color: red;display: inline-block;">*</div>
旧密码 旧密码
</div> </div>
<div class="input-46" style="margin-top: 12px;"> <div class="input-46" style="margin-top: 12px;">
<el-input placeholder="请输入旧密码" v-model="oldPassword" type="password" show-password/> <el-input placeholder="请输入旧密码" v-model="oldPassword" type="password" show-password />
</div> </div>
<div style="font-weight: 400;font-size: 14px;text-align: left;color: #3d4566;margin-top: 12px;"> <div style="font-weight: 400;font-size: 14px;text-align: left;color: #3d4566;margin-top: 12px;">
<div style="color: red;display: inline-block;">*</div> <div style="color: red;display: inline-block;">*</div>
新密码 新密码
</div> </div>
<div class="input-46" style="margin-top: 12px;"> <div class="input-46" style="margin-top: 12px;">
<el-input placeholder="请输入新密码" v-model="newPassword" type="password" show-password/> <el-input placeholder="请输入新密码" v-model="newPassword" type="password" show-password />
</div> </div>
<div style="font-weight: 400;font-size: 14px;text-align: left;color: #3d4566;margin-top: 12px;"> <div style="font-weight: 400;font-size: 14px;text-align: left;color: #3d4566;margin-top: 12px;">
<div style="color: red;display: inline-block;">*</div> <div style="color: red;display: inline-block;">*</div>
确认新密码 确认新密码
</div> </div>
<div class="input-46" style="margin-top: 12px;"> <div class="input-46" style="margin-top: 12px;">
<el-input placeholder="请再次输入新密码" v-model="confirmNewPassword" type="password" show-password/> <el-input placeholder="请再次输入新密码" v-model="confirmNewPassword" type="password" show-password />
</div> </div>
</div> </div>
<div style="display: flex;margin: 15px 15px;gap: 7px;"> <div style="display: flex;margin: 15px 15px;gap: 7px;">
<div class="dialog-btn" @click="confirm"> <div class="dialog-btn" @click="confirm">
确定 确定
</div> </div>
<div class="dialog-btn" <div class="dialog-btn" style="background: #e6ebff;border: 1px solid #adbdff;color: #5778ff;" @click="cancel">
style="background: #e6ebff;border: 1px solid #adbdff;color: #5778ff;"
@click="cancel">
取消 取消
</div> </div>
</div> </div>
@@ -83,12 +84,15 @@ export default {
// 修改后的接口调用 // 修改后的接口调用
userApi.changePassword(this.oldPassword, this.newPassword, (res) => { userApi.changePassword(this.oldPassword, this.newPassword, (res) => {
if (res.data.code === 0) { if (res.data.code === 0) {
this.$message.success('密码修改成功,请重新登录'); this.$message.success({
message: '密码修改成功,请重新登录',
showClose: true
});
this.logout().then(() => { this.logout().then(() => {
this.$router.push('/login'); this.$router.push('/login');
this.$emit('update:visible', false); this.$emit('update:visible', false);
}); });
}else{ } else {
this.$message.error(res.data.msg || '密码修改失败'); this.$message.error(res.data.msg || '密码修改失败');
} }
}, (err) => { }, (err) => {
@@ -30,7 +30,7 @@
<!-- 右侧元素 --> <!-- 右侧元素 -->
<div class="header-right"> <div class="header-right">
<div class="search-container"> <div class="search-container" v-if="$route.path === '/home'">
<el-input v-model="search" placeholder="输入名称搜索.." class="custom-search-input" <el-input v-model="search" placeholder="输入名称搜索.." class="custom-search-input"
@keyup.enter.native="handleSearch"> @keyup.enter.native="handleSearch">
<i slot="suffix" class="el-icon-search search-icon" @click="handleSearch"></i> <i slot="suffix" class="el-icon-search search-icon" @click="handleSearch"></i>
@@ -1,8 +1,11 @@
<template> <template>
<el-dialog :visible.sync="visible" width="400px" center> <el-dialog :visible.sync="visible" width="400px" center>
<div style="margin: 0 10px 10px;display: flex;align-items: center;gap: 10px;font-weight: 700;font-size: 20px;text-align: left;color: #3d4566;"> <div
<div style="width: 40px;height: 40px;border-radius: 50%;background: #5778ff;display: flex;align-items: center;justify-content: center;"> style="margin: 0 10px 10px;display: flex;align-items: center;gap: 10px;font-weight: 700;font-size: 20px;text-align: left;color: #3d4566;">
<img src="@/assets/login/shield.png" alt="" style="width: 19px;height: 23px; filter: brightness(0) invert(1);" /> <div
style="width: 40px;height: 40px;border-radius: 50%;background: #5778ff;display: flex;align-items: center;justify-content: center;">
<img src="@/assets/login/shield.png" alt=""
style="width: 19px;height: 23px; filter: brightness(0) invert(1);" />
</div> </div>
用户新密码 用户新密码
</div> </div>
@@ -13,27 +16,15 @@
用户新密码 用户新密码
</div> </div>
<div class="input-46" style="margin-top: 12px;"> <div class="input-46" style="margin-top: 12px;">
<el-input <el-input v-model="password" type="text" :readonly="true" style="font-weight: bold; color: #333;" />
v-model="password"
type="text"
:readonly="true"
style="font-weight: bold; color: #333;"
/>
</div> </div>
</div> </div>
<div style="display: flex;margin: 15px 15px;gap: 7px;"> <div style="display: flex;margin: 15px 15px;gap: 7px;">
<div <div class="dialog-btn" style="background: #e6ebff;border: 1px solid #adbdff;color: #5778ff;"
class="dialog-btn" @click="closeDialog">
style="background: #e6ebff;border: 1px solid #adbdff;color: #5778ff;"
@click="closeDialog"
>
关闭 关闭
</div> </div>
<div <div class="dialog-btn" style="background: #5778ff;color: white;" @click="copyPassword">
class="dialog-btn"
style="background: #5778ff;color: white;"
@click="copyPassword"
>
复制密码 复制密码
</div> </div>
</div> </div>
@@ -53,7 +44,10 @@ export default {
}, },
copyPassword() { copyPassword() {
navigator.clipboard.writeText(this.password) navigator.clipboard.writeText(this.password)
this.$message.success('密码已复制') this.$message.success({
message: '密码已复制',
showClose: true
})
} }
} }
} }
+25 -7
View File
@@ -101,7 +101,7 @@
<div class="batch-actions"> <div class="batch-actions">
<el-button size="mini" @click="selectAll" style="width: 75px; background: #606ff3">{{ isAllSelected ? <el-button size="mini" @click="selectAll" style="width: 75px; background: #606ff3">{{ isAllSelected ?
'取消全选' : '全选' '取消全选' : '全选'
}}</el-button> }}</el-button>
<el-button size="mini" type="danger" icon="el-icon-delete" @click="batchDelete"> <el-button size="mini" type="danger" icon="el-icon-delete" @click="batchDelete">
删除 删除
</el-button> </el-button>
@@ -239,10 +239,16 @@ export default {
Promise.all(deletePromises).then(results => { Promise.all(deletePromises).then(results => {
if (results.every(Boolean)) { if (results.every(Boolean)) {
this.$message.success('批量删除成功') this.$message.success({
message: '批量删除成功',
showClose: true
})
this.loadData() this.loadData()
} else { } else {
this.$message.error('部分删除失败') this.$message.error({
message: '部分删除失败',
showClose: true
})
} }
}) })
}).catch(() => { }).catch(() => {
@@ -269,10 +275,16 @@ export default {
model.id, model.id,
({ data }) => { ({ data }) => {
if (data.code === 0) { if (data.code === 0) {
this.$message.success('删除成功') this.$message.success({
message: '删除成功',
showClose: true
})
this.loadData() this.loadData()
} else { } else {
this.$message.error(data.msg || '删除失败') this.$message.error({
message: data.msg || '删除失败',
showClose: true
})
} }
} }
) )
@@ -325,10 +337,16 @@ export default {
Api.model.addModel(params, ({ data }) => { Api.model.addModel(params, ({ data }) => {
if (data.code === 0) { if (data.code === 0) {
this.$message.success('新增成功'); this.$message.success({
message: '新增成功',
showClose: true
});
this.loadData(); this.loadData();
} else { } else {
this.$message.error(data.msg || '新增失败'); this.$message.error({
message: data.msg || '新增失败',
showClose: true
});
} }
}); });
}, },
+73 -29
View File
@@ -21,14 +21,19 @@
<el-table-column label="用户Id" prop="userid" align="center"></el-table-column> <el-table-column label="用户Id" prop="userid" align="center"></el-table-column>
<el-table-column label="手机号码" prop="mobile" align="center"></el-table-column> <el-table-column label="手机号码" prop="mobile" align="center"></el-table-column>
<el-table-column label="设备数量" prop="deviceCount" align="center"></el-table-column> <el-table-column label="设备数量" prop="deviceCount" align="center"></el-table-column>
<el-table-column label="状态" prop="status" align="center"></el-table-column> <el-table-column label="状态" prop="status" align="center">
<template slot-scope="scope">
<el-tag v-if="scope.row.status === 1" type="success">正常</el-tag>
<el-tag v-else type="danger">禁用</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" align="center"> <el-table-column label="操作" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button size="mini" type="text" @click="resetPassword(scope.row)">重置密码</el-button> <el-button size="mini" type="text" @click="resetPassword(scope.row)">重置密码</el-button>
<el-button size="mini" type="text" v-if="scope.row.status === '正常'" <el-button size="mini" type="text" v-if="scope.row.status === 1"
@click="disableUser(scope.row)">禁用账户</el-button> @click="handleChangeStatus(scope.row, 0)">禁用账户</el-button>
<el-button size="mini" type="text" v-if="scope.row.status === '禁用'" <el-button size="mini" type="text" v-if="scope.row.status === 0"
@click="restoreUser(scope.row)">恢复账号</el-button> @click="handleChangeStatus(scope.row, 1)">恢复账号</el-button>
<el-button size="mini" type="text" @click="deleteUser(scope.row)">删除用户</el-button> <el-button size="mini" type="text" @click="deleteUser(scope.row)">删除用户</el-button>
</template> </template>
</el-table-column> </el-table-column>
@@ -49,7 +54,6 @@
<button class="pagination-btn" :disabled="currentPage === 1" @click="goPrev"> <button class="pagination-btn" :disabled="currentPage === 1" @click="goPrev">
上一页 上一页
</button> </button>
<button v-for="page in visiblePages" :key="page" class="pagination-btn" <button v-for="page in visiblePages" :key="page" class="pagination-btn"
:class="{ active: page === currentPage }" @click="goToPage(page)"> :class="{ active: page === currentPage }" @click="goToPage(page)">
{{ page }} {{ page }}
@@ -120,10 +124,7 @@ export default {
}, },
({ data }) => { ({ data }) => {
if (data.code === 0) { if (data.code === 0) {
this.userList = data.data.list.map((user) => ({ this.userList = data.data.list
...user,
status: user.status === "1" ? "正常" : "禁用",
}));
this.total = data.data.total; this.total = data.data.total;
} }
} }
@@ -175,9 +176,15 @@ export default {
const failCount = results.length - successCount; const failCount = results.length - successCount;
if (failCount === 0) { if (failCount === 0) {
this.$message.success(`成功删除${successCount}个用户`); this.$message.success({
message: `成功删除${successCount}个用户`,
showClose: true
});
} else if (successCount === 0) { } else if (successCount === 0) {
this.$message.error(`删除失败,请重试`); this.$message.error({
message: '删除失败,请重试',
showClose: true
});
} else { } else {
this.$message.warning( this.$message.warning(
`成功删除${successCount}个用户,${failCount}个删除失败` `成功删除${successCount}个用户,${failCount}个删除失败`
@@ -201,16 +208,15 @@ export default {
this.$message.warning("请先选择需要启用的用户"); this.$message.warning("请先选择需要启用的用户");
return; return;
} }
selectedUsers.forEach((user) => { this.handleChangeStatus(selectedUsers, 1);
user.status = "正常";
});
this.$message.success("启用操作成功");
}, },
batchDisable() { batchDisable() {
this.userList.forEach((user) => { const selectedUsers = this.$refs.userTable.selection;
user.status = "禁用"; if (selectedUsers.length === 0) {
}); this.$message.warning("请先选择需要禁用的用户");
this.$message.success("状态已更新为禁用"); return;
}
this.handleChangeStatus(selectedUsers, 0);
}, },
resetPassword(row) { resetPassword(row) {
this.$confirm("重置后将会生成新密码,是否继续?", "提示", { this.$confirm("重置后将会生成新密码,是否继续?", "提示", {
@@ -221,17 +227,14 @@ export default {
if (data.code === 0) { if (data.code === 0) {
this.currentPassword = data.data; this.currentPassword = data.data;
this.showViewPassword = true; this.showViewPassword = true;
this.$message.success("密码已重置,请通知用户使用新密码登录"); this.$message.success({
message: "密码已重置,请通知用户使用新密码登录",
showClose: true
});
} }
}); });
}); });
}, },
disableUser(row) {
row.status = "禁用";
},
restoreUser(row) {
row.status = "正常";
},
deleteUser(row) { deleteUser(row) {
this.$confirm("确定要删除该用户吗?", "警告", { this.$confirm("确定要删除该用户吗?", "警告", {
confirmButtonText: "确定", confirmButtonText: "确定",
@@ -241,10 +244,16 @@ export default {
.then(() => { .then(() => {
Api.admin.deleteUser(row.userid, ({ data }) => { Api.admin.deleteUser(row.userid, ({ data }) => {
if (data.code === 0) { if (data.code === 0) {
this.$message.success("删除成功"); this.$message.success({
message: "删除成功",
showClose: true
});
this.fetchUsers(); this.fetchUsers();
} else { } else {
this.$message.error(data.msg || "删除失败"); this.$message.error({
message: data.msg || "删除失败",
showClose: true
});
} }
}); });
}) })
@@ -276,6 +285,41 @@ export default {
this.currentPage = page; this.currentPage = page;
this.fetchUsers(); this.fetchUsers();
}, },
handleChangeStatus(row, status) {
// 处理单个用户或用户数组
const users = Array.isArray(row) ? row : [row];
const confirmText = status === 0 ? '禁用' : '启用';
const userCount = users.length;
this.$confirm(`确定要${confirmText}选中的${userCount}个用户吗?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
const userIds = users.map(user => Number(user.userid));
if (userIds.some(id => isNaN(id))) {
this.$message.error('存在无效的用户ID');
return;
}
Api.user.changeUserStatus(status, userIds, ({ data }) => {
if (data.code === 0) {
this.$message.success({
message: `成功${confirmText}${userCount}个用户`,
showClose: true
});
this.fetchUsers(); // 刷新用户列表
} else {
this.$message.error({
message: '操作失败,请重试',
showClose: true
});
}
});
}).catch(() => {
// 用户取消操作
});
}
}, },
}; };
</script> </script>
+20 -5
View File
@@ -148,9 +148,15 @@ export default {
}; };
Api.agent.updateAgentConfig(this.$route.query.agentId, configData, ({ data }) => { Api.agent.updateAgentConfig(this.$route.query.agentId, configData, ({ data }) => {
if (data.code === 0) { if (data.code === 0) {
this.$message.success('配置保存成功'); this.$message.success({
message: '配置保存成功',
showClose: true
});
} else { } else {
this.$message.error(data.msg || '配置保存失败'); this.$message.error({
message: data.msg || '配置保存失败',
showClose: true
});
} }
}); });
}, },
@@ -178,7 +184,10 @@ export default {
intentModelId: "", intentModelId: "",
} }
} }
this.$message.success('配置已重置') this.$message.success({
message: '配置已重置',
showClose: true
})
}).catch(() => { }).catch(() => {
}) })
}, },
@@ -196,9 +205,15 @@ export default {
this.loadingTemplate = true; this.loadingTemplate = true;
try { try {
this.applyTemplateData(template); this.applyTemplateData(template);
this.$message.success(`${template.agentName}」模板已应用`); this.$message.success({
message: `${template.agentName}」模板已应用`,
showClose: true
});
} catch (error) { } catch (error) {
this.$message.error('应用模板失败'); this.$message.error({
message: '应用模板失败',
showClose: true
});
console.error('应用模板失败:', error); console.error('应用模板失败:', error);
} finally { } finally {
this.loadingTemplate = false; this.loadingTemplate = false;