refactor: 用户列表页面优化
This commit is contained in:
@@ -42,11 +42,7 @@
|
||||
},
|
||||
{
|
||||
"path": "pages/mine/account/index",
|
||||
"type": "page",
|
||||
"style": {
|
||||
"navigationBarTitleText": "账号安全",
|
||||
"backgroundColor": "#f1f5f9"
|
||||
}
|
||||
"type": "page"
|
||||
},
|
||||
{
|
||||
"path": "pages/mine/feedback/index",
|
||||
@@ -167,6 +163,10 @@
|
||||
"style": {
|
||||
"navigationBarTitleText": "主题设置"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/work/user/detail/index",
|
||||
"type": "page"
|
||||
}
|
||||
],
|
||||
"globalStyle": {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<view class="home-page">
|
||||
<view class="page">
|
||||
<!-- 轮播图 -->
|
||||
<view class="hero">
|
||||
<wd-swiper
|
||||
@@ -19,7 +19,7 @@
|
||||
v-for="(item, index) in quickNavList"
|
||||
:key="index"
|
||||
use-slot
|
||||
@click="handleNavClick(item)"
|
||||
@itemclick="handleNavClick(item)"
|
||||
>
|
||||
<view class="nav-item">
|
||||
<image class="nav-item__icon" :src="item.icon" />
|
||||
@@ -371,14 +371,9 @@ onReady(() => {
|
||||
|
||||
<style lang="scss" scoped>
|
||||
// ============================================================================
|
||||
// 页面容器
|
||||
// 轮播图
|
||||
// ============================================================================
|
||||
|
||||
.home-page {
|
||||
min-height: 100%;
|
||||
background-color: var(--color-bg-secondary);
|
||||
}
|
||||
|
||||
.hero {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<view class="page page--full account-page dark:text-[var(--wot-color-text)] py-2">
|
||||
<view class="page account-page dark:text-[var(--wot-color-text)] py-2">
|
||||
<wd-card>
|
||||
<wd-cell-group border>
|
||||
<wd-cell
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<view class="page page--full dark:text-[var(--wot-color-text)]">
|
||||
<view class="page dark:text-[var(--wot-color-text)]">
|
||||
<view class="profile-content">
|
||||
<view class="pt-20rpx">
|
||||
<wd-card v-if="userProfile">
|
||||
|
||||
110
src/pages/work/user/detail/index.vue
Normal file
110
src/pages/work/user/detail/index.vue
Normal file
@@ -0,0 +1,110 @@
|
||||
<template>
|
||||
<view class="page page--padding">
|
||||
<wd-card v-if="userDetail">
|
||||
<template #title>
|
||||
<view class="w-full flex-between">
|
||||
<view class="flex-center">
|
||||
<wd-img :width="60" :height="60" round :src="userDetail.avatar" />
|
||||
<view class="ml-3">
|
||||
<view class="text-lg font-semibold text-slate-900">
|
||||
{{ userDetail.nickname }}
|
||||
<wd-icon v-if="userDetail.gender == 1" name="gender-male" class="color-#4D80F0" />
|
||||
<wd-icon
|
||||
v-else-if="userDetail.gender == 2"
|
||||
name="gender-female"
|
||||
class="color-#FA4350"
|
||||
/>
|
||||
</view>
|
||||
<view class="mt-1 text-sm text-slate-500">{{ userDetail.deptName }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<wd-tag v-if="userDetail.status === 1" type="success">正常</wd-tag>
|
||||
<wd-tag v-else-if="userDetail.status === 0" type="warning">禁用</wd-tag>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<wd-cell-group border>
|
||||
<wd-cell title="用户名" :value="userDetail.username" icon="user" />
|
||||
<wd-cell title="角色" :value="userDetail.roleNames" icon="usergroup" />
|
||||
<wd-cell title="手机号码" :value="userDetail.mobile" icon="mobile" />
|
||||
<wd-cell title="邮箱" :value="userDetail.email" icon="mail" />
|
||||
<wd-cell title="创建时间" :value="userDetail.createTime" icon="calendar" />
|
||||
</wd-cell-group>
|
||||
</wd-card>
|
||||
|
||||
<wd-loading v-else-if="loading" />
|
||||
<wd-status-tip v-else image="error" tip="加载失败" />
|
||||
|
||||
<view class="mt-8 px-6">
|
||||
<wd-button v-if="hasPermission('sys:user:update')" type="primary" block @click="handleEdit">
|
||||
编辑
|
||||
</wd-button>
|
||||
<wd-button
|
||||
v-if="hasPermission('sys:user:delete')"
|
||||
type="error"
|
||||
block
|
||||
class="mt-3"
|
||||
@click="handleDelete"
|
||||
>
|
||||
删除
|
||||
</wd-button>
|
||||
</view>
|
||||
|
||||
<wd-message-box />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { onLoad } from "@dcloudio/uni-app";
|
||||
import { useMessage } from "wot-design-uni";
|
||||
|
||||
import UserAPI, { UserPageVO } from "@/api/user";
|
||||
import { hasPermission } from "@/utils/permission";
|
||||
|
||||
const message = useMessage();
|
||||
|
||||
const userDetail = ref<UserPageVO>();
|
||||
const loading = ref(true);
|
||||
const userId = ref<number>(0);
|
||||
|
||||
onLoad((options) => {
|
||||
const id = Number(options?.id);
|
||||
if (id) {
|
||||
userId.value = id;
|
||||
loadDetail(id);
|
||||
}
|
||||
});
|
||||
|
||||
function loadDetail(id: number) {
|
||||
loading.value = true;
|
||||
UserAPI.getFormData(id)
|
||||
.then((data) => {
|
||||
userDetail.value = data as unknown as UserPageVO;
|
||||
})
|
||||
.finally(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
function handleEdit() {
|
||||
uni.navigateTo({
|
||||
url: `/pages/work/user/index?id=${userId.value}`,
|
||||
});
|
||||
}
|
||||
|
||||
function handleDelete() {
|
||||
message
|
||||
.confirm({
|
||||
msg: "确认删除该用户吗?",
|
||||
title: "提示",
|
||||
})
|
||||
.then(() => {
|
||||
UserAPI.deleteByIds(userId.value + "").then(() => {
|
||||
message.show("删除成功");
|
||||
setTimeout(() => {
|
||||
uni.navigateBack();
|
||||
}, 1500);
|
||||
});
|
||||
});
|
||||
}
|
||||
</script>
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<view class="page page--full page--padding">
|
||||
<view class="page page--padding">
|
||||
<!-- 搜索筛选 -->
|
||||
<view class="filter">
|
||||
<view class="filter__search">
|
||||
@@ -10,44 +10,44 @@
|
||||
@search="handleQuery"
|
||||
/>
|
||||
</view>
|
||||
<view class="filter__bar">
|
||||
<view class="filter__item" @click="sortSheetVisible = true">
|
||||
<text class="filter__text">排序</text>
|
||||
<wd-icon name="arrow-down" size="14" color="#64748b" />
|
||||
<view class="filter__bar" @click="closeOutside">
|
||||
<view class="filter__half">
|
||||
<wd-drop-menu>
|
||||
<wd-drop-menu-item
|
||||
v-model="sortValue"
|
||||
title="排序"
|
||||
:options="sortOptions"
|
||||
@change="handleSortChange"
|
||||
/>
|
||||
</wd-drop-menu>
|
||||
</view>
|
||||
|
||||
<view class="filter__divider" />
|
||||
<view class="filter__item" @click="filterVisible = true">
|
||||
<text class="filter__text">筛选</text>
|
||||
<wd-icon name="filter" size="14" color="#64748b" />
|
||||
|
||||
<view class="filter__half">
|
||||
<wd-drop-menu>
|
||||
<wd-drop-menu-item title="筛选" @open="handleFilterOpen">
|
||||
<view class="filter-panel">
|
||||
<wd-input
|
||||
v-model="queryParams.keywords"
|
||||
label="关键字"
|
||||
placeholder="用户名/昵称/手机号"
|
||||
/>
|
||||
<cu-date-query v-model="queryParams.createTime" label="创建时间" />
|
||||
<view class="filter-panel__footer">
|
||||
<wd-button type="info" @click="handleResetQuery">重置</wd-button>
|
||||
<wd-button type="primary" @click="handleFilterQuery">查询</wd-button>
|
||||
</view>
|
||||
</view>
|
||||
</wd-drop-menu-item>
|
||||
</wd-drop-menu>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<wd-action-sheet
|
||||
v-model="sortSheetVisible"
|
||||
:actions="sortActions"
|
||||
cancel-text="取消"
|
||||
@select="handleSortSelect"
|
||||
/>
|
||||
|
||||
<wd-popup
|
||||
v-model="filterVisible"
|
||||
position="bottom"
|
||||
custom-style="border-top-left-radius: 24rpx; border-top-right-radius: 24rpx;"
|
||||
>
|
||||
<view class="filter-panel">
|
||||
<wd-input v-model="queryParams.keywords" label="关键字" placeholder="用户名/昵称/手机号" />
|
||||
<cu-date-query v-model="queryParams.createTime" label="创建时间" />
|
||||
<view class="filter-panel__footer">
|
||||
<wd-button type="info" @click="handleResetQuery">重置</wd-button>
|
||||
<wd-button type="primary" @click="handleQuery">查询</wd-button>
|
||||
</view>
|
||||
</view>
|
||||
</wd-popup>
|
||||
|
||||
<!-- 数据列表 -->
|
||||
<view class="list">
|
||||
<view v-for="item in pageData" :key="item.id" class="list__card">
|
||||
<view v-for="item in pageData" :key="item.id" class="list__card" @click="goToDetail(item.id)">
|
||||
<wd-card>
|
||||
<template #title>
|
||||
<view class="flex-between">
|
||||
@@ -81,31 +81,9 @@
|
||||
</wd-cell-group>
|
||||
|
||||
<template #footer>
|
||||
<view class="flex-between">
|
||||
<view class="text-left">
|
||||
<wd-text text="创建时间:" size="small" class="font-bold" />
|
||||
<wd-text :text="item.createTime" size="small" />
|
||||
</view>
|
||||
<view class="text-right">
|
||||
<wd-button
|
||||
v-if="hasPermission('sys:user:update')"
|
||||
type="primary"
|
||||
size="small"
|
||||
plain
|
||||
@click="handleOpenDialog(item.id)"
|
||||
>
|
||||
编辑
|
||||
</wd-button>
|
||||
<wd-button
|
||||
v-if="hasPermission('sys:user:delete')"
|
||||
type="error"
|
||||
size="small"
|
||||
plain
|
||||
@click="handleDelete(item.id)"
|
||||
>
|
||||
删除
|
||||
</wd-button>
|
||||
</view>
|
||||
<view class="list__footer">
|
||||
<wd-text text="创建时间:" size="small" class="font-bold" />
|
||||
<wd-text :text="item.createTime" size="small" />
|
||||
</view>
|
||||
</template>
|
||||
</wd-card>
|
||||
@@ -163,7 +141,7 @@ import { onLoad, onReachBottom } from "@dcloudio/uni-app";
|
||||
|
||||
import { LoadMoreState } from "wot-design-uni/components/wd-loadmore/types";
|
||||
import { FormRules } from "wot-design-uni/components/wd-form/types";
|
||||
import { useMessage } from "wot-design-uni";
|
||||
import { useMessage, useQueue } from "wot-design-uni";
|
||||
|
||||
import UserAPI, { type UserPageQuery, UserPageVO, UserForm } from "@/api/user";
|
||||
import RoleAPI from "@/api/role";
|
||||
@@ -171,12 +149,10 @@ import DeptAPI from "@/api/dept";
|
||||
import { hasPermission } from "@/utils/permission";
|
||||
|
||||
const message = useMessage();
|
||||
const { closeOutside } = useQueue();
|
||||
const loadMoreState = ref<LoadMoreState>("loading");
|
||||
const userFormRef = ref();
|
||||
|
||||
const sortSheetVisible = ref(false);
|
||||
const filterVisible = ref(false);
|
||||
|
||||
const sortValue = ref(0);
|
||||
const sortOptions = ref<Record<string, any>[]>([
|
||||
{ label: "默认排序", value: 0 },
|
||||
@@ -184,15 +160,11 @@ const sortOptions = ref<Record<string, any>[]>([
|
||||
{ label: "最近更新", value: 2 },
|
||||
]);
|
||||
|
||||
const sortActions = computed(() =>
|
||||
sortOptions.value.map((item) => ({ name: item.label, value: item.value }))
|
||||
);
|
||||
|
||||
let queryParams: UserPageQuery = {
|
||||
const queryParams = reactive<UserPageQuery>({
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
keywords: "",
|
||||
};
|
||||
});
|
||||
|
||||
const total = ref(0);
|
||||
const pageData = ref<UserPageVO[]>([]);
|
||||
@@ -259,12 +231,12 @@ const rules: FormRules = {
|
||||
/**
|
||||
* 排序改变
|
||||
*/
|
||||
const handleSortChange = (event: { value: string | number }) => {
|
||||
const value = Number(event.value);
|
||||
if (value === 1) {
|
||||
const handleSortChange = ({ value }: { value: string | number }) => {
|
||||
const num = Number(value);
|
||||
if (num === 1) {
|
||||
queryParams.field = "create_time";
|
||||
queryParams.direction = "desc";
|
||||
} else if (value === 2) {
|
||||
} else if (num === 2) {
|
||||
queryParams.field = "update_time";
|
||||
queryParams.direction = "desc";
|
||||
} else {
|
||||
@@ -274,30 +246,39 @@ const handleSortChange = (event: { value: string | number }) => {
|
||||
handleQuery();
|
||||
};
|
||||
|
||||
const handleSortSelect = (action: { name: string; value: string | number }) => {
|
||||
sortValue.value = Number(action.value);
|
||||
handleSortChange({ value: action.value });
|
||||
/**
|
||||
* 筛选面板打开
|
||||
*/
|
||||
const handleFilterOpen = () => {
|
||||
// 筛选面板打开时的回调
|
||||
};
|
||||
|
||||
/**
|
||||
* 查询
|
||||
*/
|
||||
const handleQuery = () => {
|
||||
filterVisible.value = false;
|
||||
queryParams.pageNum = 1;
|
||||
loadmore();
|
||||
};
|
||||
|
||||
/**
|
||||
* 重置查询
|
||||
* 筛选查询
|
||||
*/
|
||||
const handleFilterQuery = () => {
|
||||
closeOutside();
|
||||
handleQuery();
|
||||
};
|
||||
|
||||
/**
|
||||
* 重置筛选
|
||||
*/
|
||||
const handleResetQuery = () => {
|
||||
queryParams = {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
keywords: "",
|
||||
};
|
||||
handleQuery();
|
||||
queryParams.keywords = "";
|
||||
queryParams.createTime = undefined;
|
||||
queryParams.field = "";
|
||||
queryParams.direction = "";
|
||||
sortValue.value = 0;
|
||||
handleFilterQuery();
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -371,22 +352,12 @@ function hancleCloseDialog() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除
|
||||
*
|
||||
* @param id 用户id
|
||||
* 跳转详情页
|
||||
*/
|
||||
function handleDelete(id: number) {
|
||||
message
|
||||
.confirm({
|
||||
msg: "确认删除用户吗?",
|
||||
title: "提示",
|
||||
})
|
||||
.then(() => {
|
||||
UserAPI.deleteByIds(id + "").then(() => {
|
||||
message.show("删除成功");
|
||||
handleQuery();
|
||||
});
|
||||
});
|
||||
function goToDetail(id: number) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/work/user/detail/index?id=${id}`,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -25,11 +25,8 @@ body,
|
||||
// ==========================================================================
|
||||
|
||||
.page {
|
||||
background-color: var(--color-bg-tertiary, #f1f5f9);
|
||||
}
|
||||
|
||||
.page--full {
|
||||
min-height: 100vh;
|
||||
background-color: var(--color-bg-tertiary, #f1f5f9);
|
||||
}
|
||||
|
||||
.page--auto {
|
||||
@@ -47,39 +44,76 @@ body,
|
||||
.filter {
|
||||
&__search {
|
||||
overflow: hidden;
|
||||
background: #fff;
|
||||
border-radius: 12rpx;
|
||||
|
||||
:deep(.wd-search) {
|
||||
background: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
&__bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 88rpx;
|
||||
margin-top: 12rpx;
|
||||
height: 72rpx;
|
||||
margin-top: 16rpx;
|
||||
overflow: hidden;
|
||||
background: #fff;
|
||||
border-radius: 12rpx;
|
||||
|
||||
:deep(.wd-drop-menu) {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
:deep(.wd-drop-menu-item) {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
&__item {
|
||||
&__half {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
|
||||
:deep(.wd-drop-menu) {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
:deep(.wd-drop-menu__menu) {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
:deep(.wd-drop-menu__item) {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
}
|
||||
|
||||
&__btn {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
height: 100%;
|
||||
font-size: 26rpx;
|
||||
color: #475569;
|
||||
cursor: pointer;
|
||||
transition: background 0.2s;
|
||||
|
||||
&__text {
|
||||
margin-right: 8rpx;
|
||||
font-size: 28rpx;
|
||||
color: #64748b;
|
||||
&:active {
|
||||
background: #f8fafc;
|
||||
}
|
||||
|
||||
.wd-icon {
|
||||
margin-left: 4rpx;
|
||||
}
|
||||
}
|
||||
|
||||
&__divider {
|
||||
width: 1px;
|
||||
height: 40rpx;
|
||||
height: 32rpx;
|
||||
background: #e2e8f0;
|
||||
}
|
||||
}
|
||||
@@ -152,6 +186,14 @@ body,
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
&__footer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 16rpx 24rpx;
|
||||
color: #64748b;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
}
|
||||
|
||||
// ==========================================================================
|
||||
|
||||
3
src/types/uni-pages.d.ts
vendored
3
src/types/uni-pages.d.ts
vendored
@@ -25,7 +25,8 @@ interface NavigateToOptions {
|
||||
"/pages/mine/settings/agreement/index" |
|
||||
"/pages/mine/settings/network/index" |
|
||||
"/pages/mine/settings/privacy/index" |
|
||||
"/pages/mine/settings/theme/index";
|
||||
"/pages/mine/settings/theme/index" |
|
||||
"/pages/work/user/detail/index";
|
||||
}
|
||||
interface RedirectToOptions extends NavigateToOptions {}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user