Commit 8564e2f5 by 周海峰

用户管理

parent 45e60497
......@@ -63,7 +63,11 @@ export function saveKeyParams(data) {
})
}
/**
* 上传HSM配置
* @param {*} formData
* @returns
*/
export function uploadHsmConfig(formData) {
return request({
url: '/key/manager/uploadHsmConfig',
......@@ -73,4 +77,86 @@ export function uploadHsmConfig(formData) {
'Content-Type': 'multipart/form-data'
}
})
}
\ No newline at end of file
}
/**
* 下载HSM配置
* @description 该方法用于下载HSM配置文件,通常用于测试或配置验证
* @param {Object} query - 查询参数,通常包含必要的配置或标识
* @returns {Promise} - 返回一个Promise对象,表示下载操作的结果
* @param {*} query
* @returns
*/
export function downloadHsmConfig(query) {
return request({
url: 'key/manager/downloadHsmConfig',
method: 'get',
params: query
})
}
/**
* 下载CloudHsm配置
* @description 该方法用于下载CloudHsm配置文件,通常用于测试或配置验证
* @param {Object} query - 查询参数,通常包含必要的配置或标识
* @returns {Promise} - 返回一个Promise对象,表示下载操作的结果
* @param {*} query
* @returns
*/
export function downloadCloudHsmConfig(query) {
return request({
url: 'key/manager/downloadCloudHsmConfig',
method: 'get',
params: query
})
}
/**
* 下载三维密管配置
* @description 该方法用于下载三维密管配置文件,通常用于测试或配置验证
* @param {Object} query - 查询参数,通常包含必要的配置或标识
* @returns {Promise} - 返回一个Promise对象,表示下载操作的结果
* @param {*} query
* @returns
*/
export function downloadSanWeiConfig(query) {
return request({
url: 'key/manager/downloadSanWeiConfig',
method: 'get',
params: query
})
}
/** * 上传三维密管配置
* @description 该方法用于上传三维密管配置文件,通常用于测试或配置验证
* @param {Object} formData - 包含文件数据的FormData对象
* @returns {Promise} - 返回一个Promise对象, 表示上传操作的结果
* @param {*} formData
* @returns
*/
export function uploadSanWeiConfig(formData) {
return request({
url: '/key/manager/uploadSanWeiConfig',
method: 'post',
data: formData,
headers: {
'Content-Type': 'multipart/form-data'
}
})
}
/** * 下载中电信密管配置
* @description 该方法用于下载中电信密管配置文件,通常用于测试或配置验证
* @param {Object} query - 查询参数,通常包含必要的配置或标识
* @returns {Promise} - 返回一个Promise对象,表示下载操作的结果
* @param {*} query
* @returns
*/
export function downloadZdxlzjceConfig(query) {
return request({
url: 'key/manager/downloadZdxlzjceConfig',
method: 'get',
params: query
})
}
import request from '@/utils/request'
import { parseStrEmpty } from "@/utils/ruoyi"
/**
* 组列表查询
* @param {} query
* @returns
*/
export function queryAll(query) {
return request({
url: '/console/usergroup/queryAll',
method: 'get',
params: query
})
}
\ No newline at end of file
import request from '@/utils/request'
import { parseStrEmpty } from "@/utils/ruoyi"
/**
* 菜单列表查询
* @param {*} query
* @returns
*/
export function queryAll(query) {
return request({
url: '/console/menu/queryAll',
method: 'get',
params: query
})
}
\ No newline at end of file
import request from '@/utils/request'
import { parseStrEmpty } from "@/utils/ruoyi"
/**
* 角色列表查询
* @param {*} query
* @returns
*/
export function queryAll(query) {
return request({
url: '/console/role/queryAll',
method: 'get',
params: query
})
}
\ No newline at end of file
import request from '@/utils/request'
import { parseStrEmpty } from "@/utils/ruoyi"
/**
* 用户列表查询
* @param {*} query
* @returns
*/
export function query(query) {
return request({
url: '/console/user/query',
method: 'get',
params: query
})
}
/**
* 用户编辑初始化
* @param {*} query
* @returns
*/
export function initEdit(query) {
return request({
url: '/console/user/initEdit',
method: 'get',
params: query
})
}
/**
* 添加用户
* @param {*} data
* @returns
*/
export function add(data) {
return request({
url: '/console/user/add',
method: 'post',
data: data
})
}
\ No newline at end of file
<template>
<div style="font-weight: bold; font-size: 16px; margin-top: 12px;margin-bottom: 12px;">权限设置</div>
<div>
<div class="permission-area">
<div class="all-select">
<el-checkbox :model-value="allSelected" @change="onAllChange">全选</el-checkbox>
</div>
<div class="permission-list">
<div v-for="(item, index) in permissionList" :key="index" class="permission-item">
<div class="permission-header" @click="item.children && item.children.length > 0 && toggleExpand(item)">
<div class="left">
<span class="expand-icon-placeholder">
<el-icon v-if="item.children && item.children.length > 0" class="expand-icon" :class="{ expanded: item.expanded }">
<component :is="item.expanded ? 'ArrowDown' : 'ArrowRight'" />
</el-icon>
</span>
<el-checkbox
v-model="item.selected"
:indeterminate="item.indeterminate"
@change="val => emit('permission-change', item, val)"
>
{{ item.name }}
</el-checkbox>
</div>
<div class="right">
<el-tag size="small" v-if="item.children && item.children.length > 0">{{ item.children.length }}</el-tag>
</div>
</div>
<div v-if="item.children" class="sub-permissions" v-show="item.expanded">
<el-checkbox
v-for="child in item.children"
:key="child.id"
v-model="child.selected"
@change="val => emit('sub-permission-change', item, child, val)"
>
{{ child.name }}
</el-checkbox>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref, watch } from 'vue'
import { ArrowRight, ArrowDown } from '@element-plus/icons-vue'
// 定义组件名称
defineOptions({
name: 'PermissionArea'
})
// 定义props
const props = defineProps({
permissionList: {
type: Array,
required: true
},
allPermissionsSelected: {
type: Boolean,
required: true
}
})
// 定义emit
const emit = defineEmits(['update:allPermissionsSelected', 'permission-change', 'sub-permission-change'])
// 定义响应式数据
const allSelected = ref(props.allPermissionsSelected)
// 监听props变化
watch(() => props.allPermissionsSelected, (newVal) => {
allSelected.value = newVal
})
// 方法
const toggleExpand = (item) => {
item.expanded = !item.expanded
}
const onAllChange = (val) => {
allSelected.value = val
emit('update:allPermissionsSelected', val)
}
</script>
<style scoped>
.permission-area {
border: 1px solid #dcdfe6;
border-radius: 4px;
width: 100%;
display: flex;
flex-direction: column;
height: 350px;
overflow-y: auto;
}
.all-select {
padding: 2px 12px;
background-color: #f5f7fa;
border-bottom: 1px solid #dcdfe6;
}
.permission-list {
padding: 12px;
}
.permission-item {
border-bottom: 1px solid #ebeef5;
}
.permission-item:last-child {
border-bottom: none;
}
.permission-header {
display: flex;
align-items: center;
justify-content: flex-start;
padding: 5px 0;
cursor: pointer;
gap: 12px;
}
.permission-header .left {
display: flex;
align-items: center;
gap: 8px;
}
.sub-permissions {
padding: 5px 0 5px 32px;
display: flex;
flex-direction: column;
gap: 12px;
background-color: #f8f9fb;
border-top: 1px solid #ebeef5;
}
.sub-permissions .el-checkbox {
margin-left: 0 !important;
}
.expand-icon-placeholder {
display: inline-block;
min-width: 22px;
height: 22px;
vertical-align: middle;
}
.expand-icon {
min-width: 22px;
text-align: center;
display: inline-flex;
}
</style>
<template>
<div style="font-weight: bold; font-size: 16px; margin-bottom: 12px;">角色选择</div>
<div class="role-transfer">
<div class="transfer-list">
<div class="transfer-header">
<span>角色列表</span>
<span class="select-all-action" @click="handleSelectAllAction">全选</span>
</div>
<div class="role-list">
<div v-for="role in filteredRoles" :key="role.id" class="role-item" @click="handleRoleDirectSelect(role)">
{{ role.name }}
</div>
</div>
</div>
<div class="transfer-list">
<div class="transfer-header">
<span>已选择角色列表</span>
<el-button link type="primary" @click="clearSelected">清空</el-button>
</div>
<div class="selected-list">
<div v-for="role in selectedRoles" :key="role.id" class="role-item" @click="handleRoleRemove(role)">
{{ role.name }}
</div>
</div>
</div>
</div>
</template>
<script setup>
import { computed } from 'vue'
// 定义组件名称
defineOptions({
name: 'RoleTransfer'
})
// 定义props
const props = defineProps({
roles: {
type: Array,
required: true
},
selectedRoles: {
type: Array,
required: true
},
searchRole: {
type: String,
default: ''
}
})
// 定义emit
const emit = defineEmits(['update:roles', 'update:selectedRoles', 'update:searchRole'])
// 计算属性
const filteredRoles = computed(() => {
return props.roles.filter(role =>
role.name.toLowerCase().includes(props.searchRole.toLowerCase())
)
})
// 方法
const handleSelectAllAction = () => {
emit('update:selectedRoles', [...props.selectedRoles, ...props.roles])
emit('update:roles', [])
}
const handleRoleDirectSelect = (role) => {
emit('update:selectedRoles', [...props.selectedRoles, role])
emit('update:roles', props.roles.filter(r => r.id !== role.id))
}
const handleRoleRemove = (role) => {
emit('update:roles', [...props.roles, { ...role, selected: false }])
emit('update:selectedRoles', props.selectedRoles.filter(r => r.id !== role.id))
}
const clearSelected = () => {
emit('update:roles', [...props.roles, ...props.selectedRoles])
emit('update:selectedRoles', [])
}
</script>
<style scoped>
.role-transfer {
display: flex;
align-items: flex-start;
gap: 10px;
}
.transfer-list {
flex: 1;
border: 1px solid #dcdfe6;
border-radius: 4px;
height: 300px;
display: flex;
flex-direction: column;
width: 310px;
}
.transfer-header {
padding: 8px 12px;
border-bottom: 1px solid #dcdfe6;
display: flex;
justify-content: space-between;
align-items: center;
background-color: #f5f7fa;
}
.select-all-action {
color: #409EFF;
cursor: pointer;
font-size: 14px;
margin-left: 10px;
user-select: none;
transition: color 0.2s;
}
.select-all-action:hover {
color: #66b1ff;
}
.role-list, .selected-list {
flex: 1;
overflow-y: auto;
padding: 6px 0;
}
.role-item {
padding: 6px 12px;
cursor: pointer;
}
.role-item:hover {
background-color: #f5f7fa;
}
</style>
......@@ -16,14 +16,14 @@
<el-form-item label="私钥授权码" required>
<div class="input-group">
<el-input v-model="params.sdkpassword" type="password" placeholder="****" show-password style="width: 500px" :disabled="!editable" />
<el-input v-model="params.sdkpassword" type="password" placeholder="pass" show-password style="width: 500px" :disabled="!editable" />
<div class="tip-text">* SDKPassword: SM2加密私钥授权码</div>
</div>
</el-form-item>
<el-form-item label="配置文件" required>
<div class="input-group">
<el-input v-model="params.sdkPath" placeholder="/home/ghca/data/" style="width: 500px" :disabled="!editable" />
<el-input v-model="params.hsmfiledir" placeholder="/home/ghca/data/" style="width: 500px" :disabled="!editable" />
<div class="button-group">
<el-button type="primary" @click="downloadTemplate">下载配置模板</el-button>
<el-button type="primary" @click="uploadConfig">上传配置文件</el-button>
......
......@@ -62,7 +62,9 @@
<!-- 分页 -->
<div class="pagination">
<div class="pagination-info">共有记录 1条,每页显示 8条,共 1页</div>
<div class="pagination-info">
共有记录 {{ total }} 条,每页显示 {{ pageSize }} 条,共 {{ Math.max(1, Math.ceil(total / pageSize)) }}
</div>
<el-pagination
background
layout="prev, pager, next, jumper"
......@@ -82,72 +84,98 @@
</div>
</template>
<script>
<script setup>
import { ref, reactive, onMounted, getCurrentInstance } from 'vue'
import { ElMessageBox } from 'element-plus'
import { User } from '@element-plus/icons-vue'
import UserEdit from './edit.vue'
import { query } from '@/api/safetyManagement/userConfig.js'
export default {
name: 'UserConfig',
components: {
UserEdit
},
data() {
return {
searchForm: {
name: '',
username: '',
remark: ''
},
userList: [
{
realname: 'admin',
username: 'admin',
remark: ''
}
],
total: 1,
currentPage: 1,
pageSize: 8,
editVisible: false,
editData: null
}
},
methods: {
handleSearch() {
// 实现搜索逻辑
},
handleAdd() {
// 打开新增用户弹窗
this.editData = null
this.editVisible = true
},
handlePageChange(page) {
// 实现分页逻辑
},
handleDelete(row) {
// 实现删除用户逻辑
this.$confirm('确认删除该用户吗?', '提示', {
type: 'warning'
}).then(() => {
// 调用删除接口
console.log('删除用户', row)
}).catch(() => {})
},
handleEdit(row) {
// 打开编辑用户弹窗
this.editData = { ...row }
this.editVisible = true
},
handleEditSuccess() {
// 编辑成功后的回调
this.editVisible = false
// 刷新列表数据
this.getList()
},
getList() {
// 获取用户列表数据
// 定义组件名称
defineOptions({
name: 'UserConfig'
})
// 响应式数据
const searchForm = reactive({
name: '',
username: '',
remark: ''
})
const userList = ref([])
const total = ref(1)
const currentPage = ref(1)
const pageSize = ref(8)
const editVisible = ref(false)
const editData = ref(null)
const instance = getCurrentInstance()
// 获取用户列表
const getList = async () => {
const params = {
...searchForm,
pageno: currentPage.value,
pagesize: pageSize.value
}
try {
const res = await query(params)
if (res.code === 'POP_00014') {
userList.value = res.data.list || []
total.value = res.data.total || 0
} else {
const modal = instance?.appContext.config.globalProperties.$modal
modal && modal.msgError ? modal.msgError(res.msg || '查询失败') : alert(res.msg || '查询失败')
}
} catch (e) {
const modal = instance?.appContext.config.globalProperties.$modal
modal && modal.msgError ? modal.msgError('查询异常') : alert('查询异常')
}
}
// 处理搜索
const handleSearch = () => {
currentPage.value = 1
getList()
}
// 添加用户
const handleAdd = () => {
editData.value = null
editVisible.value = true
}
// 分页变化
const handlePageChange = (page) => {
currentPage.value = page
getList()
}
// 删除用户
const handleDelete = (row) => {
ElMessageBox.confirm('确认删除该用户吗?', '提示', {
type: 'warning'
}).then(() => {
// 调用删除接口
console.log('删除用户', row)
}).catch(() => {})
}
// 编辑用户
const handleEdit = async (row) => {
editData.value = { id: row.id }
editVisible.value = true
}
// 编辑成功回调
const handleEditSuccess = () => {
editVisible.value = false
getList()
}
// 页面挂载时获取数据
onMounted(() => {
getList()
})
</script>
<style lang="scss" scoped>
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论