feat: 查询用户信息.
This commit is contained in:
@@ -1,7 +1,15 @@
|
||||
<template>
|
||||
<a-spin :loading="loading" class="main-container">
|
||||
<span class="extra-message">只展示最近登录的 30 条历史记录</span>
|
||||
<a-timeline>
|
||||
<span class="extra-message">
|
||||
<template v-if="user">
|
||||
只展示用户 <span class="user-info">{{ user.nickname }}({{ user.username }})</span> 最近登录的 30 条历史记录
|
||||
</template>
|
||||
<template v-else>
|
||||
只展示最近登录的 30 条历史记录
|
||||
</template>
|
||||
</span>
|
||||
<!-- 登录历史时间线 -->
|
||||
<a-timeline v-if="list.length">
|
||||
<a-timeline-item v-for="item in list"
|
||||
:key="item.id">
|
||||
<!-- 图标 -->
|
||||
@@ -33,6 +41,15 @@
|
||||
</div>
|
||||
</a-timeline-item>
|
||||
</a-timeline>
|
||||
<!-- 加载中 -->
|
||||
<a-space direction="vertical"
|
||||
v-else-if="loading"
|
||||
:style="{width: '70%'}"
|
||||
size="large">
|
||||
<a-skeleton-line :rows="4" />
|
||||
</a-space>
|
||||
<!-- 空 -->
|
||||
<a-empty v-else />
|
||||
</a-spin>
|
||||
</template>
|
||||
|
||||
@@ -43,14 +60,21 @@
|
||||
</script>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { UserQueryResponse } from '@/api/user/user';
|
||||
import type { LoginHistoryQueryResponse } from '@/api/user/operator-log';
|
||||
import type { PropType } from 'vue';
|
||||
import useLoading from '@/hooks/loading';
|
||||
import { ref, onMounted } from 'vue';
|
||||
import { ResultStatus } from '../types/const';
|
||||
import { getCurrentLoginHistory } from '@/api/user/mine';
|
||||
import { getLoginHistory } from '@/api/user/operator-log';
|
||||
import { dateFormat } from '@/utils';
|
||||
import { isMobile } from '@/utils/is';
|
||||
|
||||
const props = defineProps({
|
||||
user: Object as PropType<UserQueryResponse>,
|
||||
});
|
||||
|
||||
const list = ref<LoginHistoryQueryResponse[]>([]);
|
||||
|
||||
const { loading, setLoading } = useLoading();
|
||||
@@ -59,8 +83,15 @@
|
||||
onMounted(async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
const { data } = await getCurrentLoginHistory();
|
||||
list.value = data;
|
||||
if (props.user) {
|
||||
// 查询其他用户
|
||||
const { data } = await getLoginHistory(props.user.username);
|
||||
list.value = data;
|
||||
} else {
|
||||
// 查询当前用户
|
||||
const { data } = await getCurrentLoginHistory();
|
||||
list.value = data;
|
||||
}
|
||||
} catch (e) {
|
||||
} finally {
|
||||
setLoading(false);
|
||||
@@ -77,11 +108,16 @@
|
||||
}
|
||||
|
||||
.extra-message {
|
||||
margin-bottom: 38px;
|
||||
margin-bottom: 42px;
|
||||
margin-left: -24px;
|
||||
display: block;
|
||||
color: var(--color-text-3);
|
||||
user-select: none;
|
||||
|
||||
.user-info {
|
||||
color: rgb(var(--primary-6));
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
.icon-container {
|
||||
|
||||
@@ -1,124 +1,32 @@
|
||||
<template>
|
||||
<!-- 搜索 -->
|
||||
<a-card class="general-card table-search-card">
|
||||
<a-query-header :model="formModel"
|
||||
label-align="left"
|
||||
@submit="fetchTableData"
|
||||
@reset="fetchTableData"
|
||||
@keyup.enter="() => fetchTableData()">
|
||||
<!-- 角色名称 -->
|
||||
<a-form-item field="name" label="角色名称" label-col-flex="50px">
|
||||
<a-input v-model="formModel.name" placeholder="请输入角色名称" allow-clear />
|
||||
</a-form-item>
|
||||
<!-- 角色编码 -->
|
||||
<a-form-item field="code" label="角色编码" label-col-flex="50px">
|
||||
<a-input v-model="formModel.code" placeholder="请输入角色编码" allow-clear />
|
||||
</a-form-item>
|
||||
<!-- 角色状态 -->
|
||||
<a-form-item field="status" label="角色状态" label-col-flex="50px">
|
||||
<a-select v-model="formModel.status"
|
||||
placeholder="请选择角色状态"
|
||||
:options="toOptions(roleStatusKey)"
|
||||
allow-clear />
|
||||
</a-form-item>
|
||||
</a-query-header>
|
||||
</a-card>
|
||||
<!-- 表格 -->
|
||||
<a-card class="general-card table-card">
|
||||
<template #title>
|
||||
<!-- 左侧操作 -->
|
||||
<div class="table-left-bar-handle">
|
||||
<!-- 标题 -->
|
||||
<div class="table-title">
|
||||
角色列表
|
||||
</div>
|
||||
</div>
|
||||
<!-- 右侧操作 -->
|
||||
<div class="table-right-bar-handle">
|
||||
<a-space>
|
||||
<!-- 新增 -->
|
||||
<a-button type="primary"
|
||||
v-permission="['infra:system-role:create']"
|
||||
@click="emits('openAdd')">
|
||||
新增
|
||||
<template #icon>
|
||||
<icon-plus />
|
||||
</template>
|
||||
</a-button>
|
||||
</a-space>
|
||||
</div>
|
||||
</template>
|
||||
<!-- table -->
|
||||
<a-table row-key="id"
|
||||
class="table-wrapper-8"
|
||||
ref="tableRef"
|
||||
label-align="left"
|
||||
:loading="loading"
|
||||
:columns="columns"
|
||||
:data="tableRenderData"
|
||||
:pagination="pagination"
|
||||
@page-change="(page) => fetchTableData(page, pagination.pageSize)"
|
||||
@page-size-change="(size) => fetchTableData(1, size)"
|
||||
:bordered="false">
|
||||
<!-- 编码 -->
|
||||
<template #code="{ record }">
|
||||
<a-tag>{{ record.code }}</a-tag>
|
||||
</template>
|
||||
<!-- 状态 -->
|
||||
<template #status="{ record }">
|
||||
<span class="circle" :style="{
|
||||
background: getDictValue(roleStatusKey, record.status, 'color')
|
||||
}" />
|
||||
{{ getDictValue(roleStatusKey, record.status) }}
|
||||
</template>
|
||||
<!-- 操作 -->
|
||||
<template #handle="{ record }">
|
||||
<div class="table-handle-wrapper">
|
||||
<!-- 修改状态 -->
|
||||
<a-popconfirm :content="`确定要${toggleDictValue(roleStatusKey, record.status, 'label')}当前角色吗?`"
|
||||
position="left"
|
||||
type="warning"
|
||||
@ok="toggleRoleStatus(record)">
|
||||
<a-button v-permission="['infra:system-role:delete']"
|
||||
:disabled="record.code === 'admin'"
|
||||
:status="toggleDictValue(roleStatusKey, record.status, 'status')"
|
||||
type="text"
|
||||
size="mini">
|
||||
{{ toggleDictValue(roleStatusKey, record.status, 'label') }}
|
||||
</a-button>
|
||||
</a-popconfirm>
|
||||
<!-- 分配菜单 -->
|
||||
<a-button v-permission="['infra:system-role:grant-menu']"
|
||||
:disabled="record.code === 'admin'"
|
||||
type="text"
|
||||
size="mini"
|
||||
@click="emits('openGrant', record)">
|
||||
分配菜单
|
||||
</a-button>
|
||||
<!-- 修改 -->
|
||||
<a-button v-permission="['infra:system-role:update']"
|
||||
type="text"
|
||||
size="mini"
|
||||
@click="emits('openUpdate', record)">
|
||||
修改
|
||||
</a-button>
|
||||
<!-- 删除 -->
|
||||
<a-popconfirm content="确认删除这条记录吗?"
|
||||
position="left"
|
||||
type="warning"
|
||||
@ok="deleteRow(record)">
|
||||
<a-button v-permission="['infra:system-role:delete']"
|
||||
:disabled="record.code === 'admin'"
|
||||
type="text"
|
||||
size="mini"
|
||||
status="danger">
|
||||
删除
|
||||
</a-button>
|
||||
</a-popconfirm>
|
||||
<div class="main-container" v-if="render">
|
||||
<!-- 查询头 -->
|
||||
<a-card class="general-card table-search-card">
|
||||
<!-- 查询头组件 -->
|
||||
<operator-log-query-header :visible-user="false"
|
||||
@submit="(e) => table.fetchTableData(undefined, undefined, e)" />
|
||||
</a-card>
|
||||
<!-- 表格 -->
|
||||
<a-card class="general-card table-card">
|
||||
<template #title>
|
||||
<!-- 左侧操作 -->
|
||||
<div class="table-left-bar-handle">
|
||||
<!-- 标题 -->
|
||||
<div class="table-title">
|
||||
操作日志 <span class="user-info" v-if="user">{{ user.nickname }}({{ user.username }})</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</a-table>
|
||||
</a-card>
|
||||
<!-- 表格组件 -->
|
||||
<operator-log-table ref="table"
|
||||
:visible-user="false"
|
||||
:current="!user"
|
||||
:base-params="{userId: user?.id}"
|
||||
@viewDetail="(e) => view.open(e)" />
|
||||
</a-card>
|
||||
<!-- json 查看器模态框 -->
|
||||
<json-view-modal ref="view" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
@@ -128,107 +36,53 @@
|
||||
</script>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { RoleQueryRequest, RoleQueryResponse } from '@/api/user/role';
|
||||
import { reactive, ref, onMounted } from 'vue';
|
||||
import { deleteRole, getRolePage, updateRoleStatus } from '@/api/user/role';
|
||||
import { Message } from '@arco-design/web-vue';
|
||||
import useLoading from '@/hooks/loading';
|
||||
import columns from '../../role/types/table.columns';
|
||||
import { roleStatusKey } from '../../role/types/const';
|
||||
import { usePagination } from '@/types/table';
|
||||
import { useDictStore } from '@/store';
|
||||
import type { UserQueryResponse } from '@/api/user/user';
|
||||
import type { PropType } from 'vue';
|
||||
import { ref, onBeforeMount } from 'vue';
|
||||
import { useCacheStore, useDictStore } from '@/store';
|
||||
import { dictKeys } from '../../operator-log/types/const';
|
||||
import OperatorLogQueryHeader from '../../operator-log/components/operator-log-query-header.vue';
|
||||
import OperatorLogTable from '../../operator-log/components/operator-log-table.vue';
|
||||
import JsonViewModal from '@/components/view/json/json-view-modal.vue';
|
||||
|
||||
const emits = defineEmits(['openAdd', 'openUpdate', 'openGrant']);
|
||||
|
||||
const tableRenderData = ref<RoleQueryResponse[]>([]);
|
||||
|
||||
const pagination = usePagination();
|
||||
const { loading, setLoading } = useLoading();
|
||||
const { toOptions, getDictValue, toggleDictValue, toggleDict } = useDictStore();
|
||||
|
||||
const formModel = reactive<RoleQueryRequest>({
|
||||
id: undefined,
|
||||
name: undefined,
|
||||
code: undefined,
|
||||
status: undefined,
|
||||
const props = defineProps({
|
||||
user: Object as PropType<UserQueryResponse>,
|
||||
});
|
||||
|
||||
// 修改状态
|
||||
const toggleRoleStatus = async (record: any) => {
|
||||
try {
|
||||
setLoading(true);
|
||||
const toggleStatus = toggleDict(roleStatusKey, record.status);
|
||||
// 调用修改接口
|
||||
await updateRoleStatus({
|
||||
id: record.id,
|
||||
status: toggleStatus.value as number
|
||||
});
|
||||
Message.success(`${toggleStatus.label}成功`);
|
||||
// 修改行状态
|
||||
record.status = toggleStatus.value;
|
||||
} catch (e) {
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
const cacheStore = useCacheStore();
|
||||
|
||||
// 删除当前行
|
||||
const deleteRow = async ({ id }: {
|
||||
id: number
|
||||
}) => {
|
||||
try {
|
||||
setLoading(true);
|
||||
// 调用删除接口
|
||||
await deleteRole(id);
|
||||
Message.success('删除成功');
|
||||
// 重新加载数据
|
||||
fetchTableData();
|
||||
} catch (e) {
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
const render = ref();
|
||||
const table = ref();
|
||||
const view = ref();
|
||||
|
||||
// 添加后回调
|
||||
const addedCallback = () => {
|
||||
fetchTableData();
|
||||
};
|
||||
|
||||
// 更新后回调
|
||||
const updatedCallback = () => {
|
||||
fetchTableData();
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
addedCallback, updatedCallback
|
||||
});
|
||||
|
||||
// 加载数据
|
||||
const doFetchTableData = async (request: RoleQueryRequest) => {
|
||||
try {
|
||||
setLoading(true);
|
||||
const { data } = await getRolePage(request);
|
||||
tableRenderData.value = data.rows;
|
||||
pagination.total = data.total;
|
||||
pagination.current = request.page;
|
||||
pagination.pageSize = request.limit;
|
||||
} catch (e) {
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
// 切换页码
|
||||
const fetchTableData = (page = 1, limit = pagination.pageSize, form = formModel) => {
|
||||
doFetchTableData({ page, limit, ...form });
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
fetchTableData();
|
||||
onBeforeMount(async () => {
|
||||
// 加载字典值
|
||||
const dictStore = useDictStore();
|
||||
await dictStore.loadKeys(dictKeys);
|
||||
render.value = true;
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.main-container {
|
||||
padding-left: 16px;
|
||||
|
||||
.table-search-card {
|
||||
padding-top: 8px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.table-card {
|
||||
:deep(.arco-card-body) {
|
||||
padding-bottom: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.user-info {
|
||||
display: inline-block;
|
||||
margin-left: 6px;
|
||||
color: rgb(var(--primary-6));
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -43,35 +43,46 @@
|
||||
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: 'user-info'
|
||||
name: 'user-base-info'
|
||||
};
|
||||
</script>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { UserUpdateRequest } from '@/api/user/user';
|
||||
import type { UserUpdateRequest, UserQueryResponse } from '@/api/user/user';
|
||||
import type { PropType } from 'vue';
|
||||
import useLoading from '@/hooks/loading';
|
||||
import { computed, ref, onMounted } from 'vue';
|
||||
import { ref, onMounted } from 'vue';
|
||||
import formRules from '../../user/types/form.rules';
|
||||
import { useUserStore } from '@/store';
|
||||
import { getCurrentUser, updateCurrentUser } from '@/api/user/mine';
|
||||
import { pick } from 'lodash';
|
||||
import { Message } from '@arco-design/web-vue';
|
||||
import { updateUser } from '@/api/user/user';
|
||||
|
||||
const props = defineProps({
|
||||
user: Object as PropType<UserQueryResponse>,
|
||||
});
|
||||
|
||||
const userStore = useUserStore();
|
||||
const { loading, setLoading } = useLoading();
|
||||
|
||||
const nickname = ref('');
|
||||
const formRef = ref();
|
||||
const formModel = ref<UserUpdateRequest>({});
|
||||
|
||||
// 用户名
|
||||
const nickname = computed(() => userStore.nickname?.substring(0, 1));
|
||||
|
||||
// 保存
|
||||
// 修改用户信息
|
||||
const save = async () => {
|
||||
setLoading(true);
|
||||
try {
|
||||
await updateCurrentUser(formModel.value);
|
||||
userStore.nickname = formModel.value.nickname;
|
||||
if (props.user) {
|
||||
// 更新用户
|
||||
await updateUser(formModel.value);
|
||||
} else {
|
||||
// 更新自己
|
||||
await updateCurrentUser(formModel.value);
|
||||
userStore.nickname = formModel.value.nickname;
|
||||
nickname.value = formModel.value.nickname?.substring(0, 1) as string;
|
||||
}
|
||||
Message.success('保存成功');
|
||||
} catch (e) {
|
||||
} finally {
|
||||
@@ -83,8 +94,17 @@
|
||||
onMounted(async () => {
|
||||
setLoading(true);
|
||||
try {
|
||||
const { data } = await getCurrentUser();
|
||||
formModel.value = pick(data, 'username', 'nickname', 'mobile', 'email');
|
||||
let u: UserQueryResponse;
|
||||
if (props.user) {
|
||||
// 从参数中获取
|
||||
u = props.user;
|
||||
} else {
|
||||
// 查询个人信息
|
||||
const { data } = await getCurrentUser();
|
||||
u = data;
|
||||
}
|
||||
formModel.value = pick(u, 'id', 'username', 'nickname', 'mobile', 'email');
|
||||
nickname.value = u.nickname?.substring(0, 1);
|
||||
} catch (e) {
|
||||
} finally {
|
||||
setLoading(false);
|
||||
@@ -1,7 +1,15 @@
|
||||
<template>
|
||||
<a-spin :loading="loading" class="main-container">
|
||||
<span class="extra-message">所有登录设备的会话列表</span>
|
||||
<a-timeline>
|
||||
<span class="extra-message">
|
||||
<template v-if="user">
|
||||
用户 <span class="user-info">{{ user.nickname }}({{ user.username }})</span> 所有登录设备的会话列表
|
||||
</template>
|
||||
<template v-else>
|
||||
所有登录设备的会话列表
|
||||
</template>
|
||||
</span>
|
||||
<!-- 登录会话时间线 -->
|
||||
<a-timeline v-if="list.length">
|
||||
<template v-for="item in list"
|
||||
:key="item.loginTime">
|
||||
<a-timeline-item v-if="item.visible">
|
||||
@@ -19,7 +27,7 @@
|
||||
<span>{{ item.address }}</span>
|
||||
<span>{{ item.location }}</span>
|
||||
<a-tag v-if="item.current" color="arcoblue">当前会话</a-tag>
|
||||
<a-button v-else
|
||||
<a-button v-else-if="hasPermission('infra:system-user:offline-session')"
|
||||
style="font-weight: 600;"
|
||||
type="text"
|
||||
size="mini"
|
||||
@@ -40,6 +48,15 @@
|
||||
</a-timeline-item>
|
||||
</template>
|
||||
</a-timeline>
|
||||
<!-- 加载中 -->
|
||||
<a-space direction="vertical"
|
||||
v-else-if="loading"
|
||||
:style="{width: '70%'}"
|
||||
size="large">
|
||||
<a-skeleton-line :rows="4" />
|
||||
</a-space>
|
||||
<!-- 空 -->
|
||||
<a-empty v-else />
|
||||
</a-spin>
|
||||
</template>
|
||||
|
||||
@@ -50,17 +67,26 @@
|
||||
</script>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { UserQueryResponse } from '@/api/user/user';
|
||||
import type { UserSessionQueryResponse } from '@/api/user/user';
|
||||
import type { PropType } from 'vue';
|
||||
import useLoading from '@/hooks/loading';
|
||||
import { ref, onMounted } from 'vue';
|
||||
import { getCurrentUserSessionList, offlineCurrentUserSession } from '@/api/user/mine';
|
||||
import { dateFormat } from '@/utils';
|
||||
import { isMobile } from '@/utils/is';
|
||||
import { Message } from '@arco-design/web-vue';
|
||||
import usePermission from '@/hooks/permission';
|
||||
import { getUserSessionList } from '@/api/user/user';
|
||||
|
||||
const props = defineProps({
|
||||
user: Object as PropType<UserQueryResponse>,
|
||||
});
|
||||
|
||||
const list = ref<UserSessionQueryResponse[]>([]);
|
||||
|
||||
const { loading, setLoading } = useLoading();
|
||||
const { hasPermission } = usePermission();
|
||||
|
||||
// 下线
|
||||
const offline = async (item: UserSessionQueryResponse) => {
|
||||
@@ -81,9 +107,18 @@
|
||||
onMounted(async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
const { data } = await getCurrentUserSessionList();
|
||||
data.forEach(s => s.visible = true);
|
||||
list.value = data;
|
||||
let sessions: UserSessionQueryResponse[];
|
||||
if (props.user) {
|
||||
// 查询其他用户
|
||||
const { data } = await getUserSessionList(props.user.id);
|
||||
sessions = data;
|
||||
} else {
|
||||
// 查询当前用户
|
||||
const { data } = await getCurrentUserSessionList();
|
||||
sessions = data;
|
||||
}
|
||||
sessions.forEach(s => s.visible = true);
|
||||
list.value = sessions;
|
||||
} catch (e) {
|
||||
} finally {
|
||||
setLoading(false);
|
||||
@@ -100,11 +135,16 @@
|
||||
}
|
||||
|
||||
.extra-message {
|
||||
margin-bottom: 38px;
|
||||
margin-bottom: 42px;
|
||||
margin-left: -24px;
|
||||
display: block;
|
||||
color: var(--color-text-3);
|
||||
user-select: none;
|
||||
|
||||
.user-info {
|
||||
color: rgb(var(--primary-6));
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
.icon-container {
|
||||
|
||||
@@ -1,25 +1,41 @@
|
||||
<template>
|
||||
<div class="tabs-container">
|
||||
<div class="tabs-container" v-if="render">
|
||||
<a-tabs type="rounded"
|
||||
size="medium"
|
||||
position="left"
|
||||
:lazy-load="true"
|
||||
:destroy-on-hide="true">
|
||||
:destroy-on-hide="true"
|
||||
@tab-click="clickTab">
|
||||
<!-- 个人信息 -->
|
||||
<a-tab-pane key="1" title="个人信息">
|
||||
<user-info />
|
||||
<a-tab-pane key="mineInfo"
|
||||
v-if="!user || hasPermission('infra:system-user:update')"
|
||||
:title="user ? '用户信息' : '个人信息'">
|
||||
<user-base-info :user="user" />
|
||||
</a-tab-pane>
|
||||
<!-- 登录日志 -->
|
||||
<a-tab-pane key="2" title="登录日志">
|
||||
<login-history />
|
||||
<a-tab-pane key="loginHistory"
|
||||
v-if="!user || hasPermission('infra:operator-log:query')"
|
||||
title="登录日志">
|
||||
<login-history :user="user" />
|
||||
</a-tab-pane>
|
||||
<!-- 登录设备 -->
|
||||
<a-tab-pane key="3" title="登录设备">
|
||||
<user-session />
|
||||
<a-tab-pane key="userSession"
|
||||
v-if="!user || hasPermission('infra:system-user:query-session')"
|
||||
title="登录设备">
|
||||
<user-session :user="user" />
|
||||
</a-tab-pane>
|
||||
<!-- 操作日志 -->
|
||||
<a-tab-pane key="4" title="操作日志">
|
||||
<operator-log-list />
|
||||
<a-tab-pane key="operatorLog"
|
||||
v-if="!user || hasPermission('infra:operator-log:query')"
|
||||
title="操作日志">
|
||||
<operator-log-list :user="user" />
|
||||
</a-tab-pane>
|
||||
<!-- 返回 -->
|
||||
<a-tab-pane key="back" v-if="userId">
|
||||
<template #title>
|
||||
<icon-arrow-left style="font-size: 16px" />
|
||||
返回
|
||||
</template>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</div>
|
||||
@@ -32,10 +48,56 @@
|
||||
</script>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import UserInfo from './components/user-info.vue';
|
||||
import UserBaseInfo from './components/user-base-info.vue';
|
||||
import LoginHistory from './components/login-history.vue';
|
||||
import UserSession from './components/user-session.vue';
|
||||
import OperatorLogList from './components/operator-log-list.vue';
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
import { onBeforeMount, ref } from 'vue';
|
||||
import usePermission from '@/hooks/permission';
|
||||
import { useUserStore } from '@/store';
|
||||
import { getUser, UserQueryResponse } from '@/api/user/user';
|
||||
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
const userStore = useUserStore();
|
||||
const { hasPermission } = usePermission();
|
||||
|
||||
const render = ref<boolean>(false);
|
||||
const userId = ref<number>();
|
||||
const user = ref<UserQueryResponse>();
|
||||
|
||||
// 点击 tab
|
||||
const clickTab = (key: string) => {
|
||||
if (key === 'back') {
|
||||
router.back();
|
||||
}
|
||||
};
|
||||
|
||||
// 初始化
|
||||
const init = async () => {
|
||||
// 获取 userId
|
||||
const queryUserId = route.query.id as string;
|
||||
if (!queryUserId) {
|
||||
return;
|
||||
}
|
||||
const id = parseInt(queryUserId);
|
||||
userId.value = id;
|
||||
// 当前用户 直接返回
|
||||
if (userStore.id === id) {
|
||||
return;
|
||||
}
|
||||
// 查询用户信息
|
||||
const { data } = await getUser(id);
|
||||
user.value = data;
|
||||
};
|
||||
|
||||
onBeforeMount(async () => {
|
||||
// 初始化
|
||||
await init();
|
||||
render.value = true;
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
@@ -48,11 +110,19 @@
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
:deep(.arco-tabs-nav-tab-list) {
|
||||
width: 88px;
|
||||
}
|
||||
|
||||
:deep(.arco-tabs-pane) {
|
||||
border-left: 1px var(--color-neutral-3) solid;
|
||||
}
|
||||
|
||||
:deep(.arco-tabs-tab-title) {
|
||||
:deep(.arco-tabs-tab) {
|
||||
user-select: none;
|
||||
white-space: nowrap;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user