refactor: ♻️ 用户管理页面优化

This commit is contained in:
ray
2024-11-25 00:52:42 +08:00
parent d02c29f18b
commit 4b757bcfc7
3 changed files with 85 additions and 66 deletions

View File

@@ -1,6 +1,6 @@
<template>
<view class="home">
<view style=" width: 100%;height: var(--status-bar-height)" />
<view style="width: 100%; height: var(--status-bar-height)" />
<wd-swiper
v-model:current="current"
:list="swiperList"
@@ -36,18 +36,6 @@
<!-- 数据统计 -->
<wd-grid :column="2" class="mt-2" :gutter="2">
<wd-grid-item use-slot custom-class="custom-item">
<view class="flex justify-start pl-5">
<view class="flex-center">
<image class="w-80rpx h-80rpx rounded-8rpx" src="/static/icons/online.png" />
<view class="ml-5 text-left">
<view class="font-bold">在线用户</view>
<view class="mt-1">1</view>
</view>
</view>
</view>
</wd-grid-item>
<wd-grid-item
v-for="(item, index) in visitStatsData"
:key="index"
@@ -94,9 +82,10 @@
<script setup lang="ts">
import { dayjs } from "wot-design-uni";
import LogAPI, { VisitTrendVO, VisitTrendQuery, VisitStatsVO } from "@/api/system/log";
import LogAPI, { VisitStatsVO } from "@/api/system/log";
interface VisitStats {
type: string;
title: string;
icon: string;
growthRate: number;
@@ -106,7 +95,40 @@ interface VisitStats {
const current = ref<number>(0);
const visitStatsData = ref<VisitStats[] | null>(Array(3).fill({}));
const visitStatsData = ref<VisitStats[] | null>([
{
type: "online",
title: "在线用户数",
icon: "/static/icons/online.png",
growthRate: 0,
granularity: "-",
todayCount: 1,
},
{
type: "pv",
title: "浏览量(PV)",
icon: "/static/icons/pv.png",
growthRate: 0,
granularity: "日",
todayCount: 0,
},
{
type: "uv",
title: "(UV)",
icon: "/static/icons/visit.png",
growthRate: 0,
granularity: "日",
todayCount: 0,
},
{
type: "ip",
title: "访问客户端",
icon: "/static/icons/client.png",
growthRate: 0,
granularity: "日",
todayCount: 0,
},
]);
// 图表数据
const chartData = ref({});
@@ -160,23 +182,14 @@ function onChange(e: any) {
// 加载访问统计数据
const loadVisitStatsData = async () => {
const list: VisitStatsVO[] = await LogAPI.getVisitStats();
if (list) {
const iconList = [
"/static/icons/pv.png",
"/static/icons/visit.png",
"/static/icons/client.png",
];
const transformedList: VisitStats[] = list.map((item, index) => ({
title: item.title,
icon: iconList[index],
growthRate: item.growthRate,
granularity: "日",
todayCount: item.todayCount,
totalCount: item.totalCount,
}));
visitStatsData.value = transformedList;
}
visitStatsData.value?.forEach((item) => {
const data = list.find((v) => v.type === item.type);
if (data) {
item.todayCount = data.todayCount;
item.growthRate = data.growthRate;
}
});
};
// 加载访问趋势数据

View File

@@ -1,26 +1,30 @@
<template>
<view class="user">
<view style=" width: 100%;height: var(--status-bar-height)" />
<view style="width: 100%; height: var(--status-bar-height)" />
<wd-navbar title="用户管理">
<template #left>
<wd-icon name="thin-arrow-left" @click="handleNavigateback()" />
</template>
<template #right>
<wd-icon name="add-circle" @click="handleOpenDialog()" />
</template>
</wd-navbar>
<!-- 排序筛选 -->
<view class="mb-24rpx">
<wd-drop-menu>
<wd-drop-menu-item v-model="sortValue" :options="sortOptions" @change="handleSortChange" />
<wd-drop-menu-item ref="dropMenuRef" title="筛选">
<wd-drop-menu-item
v-model="sortValue"
:options="sortOptions"
title="排序"
@change="handleSortChange"
/>
<wd-drop-menu-item ref="filterDropMenu" title="筛选">
<view>
<wd-input
v-model="queryParams.keywords"
label="关键字"
placeholder="用户名/昵称/手机号"
/>
<wd-datetime-picker v-model="createTimeRange" type="date" label="创建时间" />
<wd-calendar v-model="createTimeRange" label="创建时间" type="daterange" />
<view class="flex-between py-2">
<wd-button class="w-20%" type="info" @click="hendleResetQuery">重置</wd-button>
<wd-button class="w-70%" @click="handleQuery">确定</wd-button>
@@ -28,12 +32,6 @@
</view>
</wd-drop-menu-item>
</wd-drop-menu>
<view>
<wd-text text="共" size="12px" />
<wd-text :text="total" size="12px" />
<wd-text text="条数据" size="12px" />
</view>
</view>
<!-- 用户卡片 -->
@@ -67,31 +65,25 @@
<template #footer>
<view class="flex-between">
<view>
<wd-text text="创建时间:" size="12px" />
<wd-text :text="item.createTime" size="12px" />
<view class="text-left">
<wd-text text="创建时间:" size="small" class="font-bold" />
<wd-text :text="item.createTime" size="small" />
</view>
<view class="flex-end">
<view class="text-right">
<wd-button type="primary" size="small" plain @click="handleOpenDialog(item.id)">
编辑
</wd-button>
<view class="ml-2">
<wd-drop-menu>
<wd-drop-menu-item ref="dropMenu" title="更多" icon="more">
<view class="text-right m-5">
<wd-button type="error" size="small" plain @click="handleDelete(item.id)">
删除
</wd-button>
</view>
</wd-drop-menu-item>
</wd-drop-menu>
</view>
&nbsp;
<wd-button type="error" size="small" plain @click="handleDelete(item.id)">
删除
</wd-button>
</view>
</view>
</template>
</wd-card>
<wd-loadmore v-if="total > 0" :state="state" @reload="loadmore" />
<wd-status-tip v-else-if="total == 0" image="search" tip="当前搜索无结果" />
<wd-message-box />
<!-- 编辑弹窗 -->
@@ -106,7 +98,7 @@
:columns="roleOptions"
required
/>
<vut-picker
<CuPicker
v-model="formData.deptId"
v-model:data="deptOptions"
label="部门"
@@ -124,7 +116,12 @@
</view>
</wd-popup>
<!-- <wd-fab position="left-bottom" :expandable="false" @click="handleOpenDialog" /> -->
<wd-fab
position="left-bottom"
:expandable="false"
customStyle="width: 1rem; height: 1rem; line-height: 1rem;z-index:9"
@click="handleOpenDialog"
/>
</view>
</template>
@@ -137,7 +134,7 @@ import UserAPI, { type UserPageQuery, UserPageVO, UserForm } from "@/api/system/
import RoleAPI from "@/api/system/role";
import DeptAPI from "@/api/system/dept";
import VutPicker from "@/components/VutPicker.vue";
import CuPicker from "@/components/CuPicker.vue";
const message = useMessage();
@@ -145,8 +142,9 @@ const loading = ref(false);
const state = ref<LoadMoreState>("loading");
const dataList = ref<UserPageVO[]>([]);
const sortValue = ref(1);
const sortValue = ref(0);
const sortOptions = ref<Record<string, any>[]>([
{ label: "默认排序", value: 0 },
{ label: "最近创建", value: 1 },
{ label: "最近更新", value: 2 },
]);
@@ -158,7 +156,7 @@ const queryParams: UserPageQuery = {
const createTimeRange = ref<any[]>([null, null]);
const dropMenuRef = ref();
const filterDropMenu = ref();
const total = ref(0);
const dialog = reactive({
@@ -232,6 +230,9 @@ const handleSortChange = ({ value }: { value: number }) => {
} else if (value === 2) {
queryParams.field = "update_time";
queryParams.direction = "DESC";
} else {
queryParams.field = "";
queryParams.direction = "";
}
handleQuery();
};
@@ -240,7 +241,7 @@ const handleSortChange = ({ value }: { value: number }) => {
* 查询
*/
const handleQuery = () => {
dropMenuRef.value?.close();
filterDropMenu.value?.close();
queryParams.pageNum = 1;
// 格式化时间范围
@@ -264,9 +265,10 @@ const handleQuery = () => {
* 重置查询
*/
const hendleResetQuery = () => {
dropMenuRef.value?.close();
filterDropMenu.value?.close();
queryParams.pageNum = 1;
queryParams.keywords = "";
queryParams.createTime = "";
createTimeRange.value = ["", ""];
loadmore();
};
@@ -394,5 +396,9 @@ onLoad(() => {
padding-right: 10rpx;
background: #f8f8f8;
}
:deep(.wd-fab__trigger) {
width: 80rpx !important;
height: 80rpx !important;
}
}
</style>