shop-front-end/src/views/user/ab98/index.vue

269 lines
7.1 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<script setup lang="ts">
import { onMounted, reactive, ref, watch } from "vue";
import { useRenderIcon } from "@/components/ReIcon/src/hooks";
import { getAb98UserListApi, type Ab98UserDTO, Ab98UserQuery } from "@/api/ab98/user";
import { type PaginationProps } from "@pureadmin/table";
import { CommonUtils } from "@/utils/common";
import Search from "@iconify-icons/ep/search";
import Refresh from "@iconify-icons/ep/refresh";
import View from "@iconify-icons/ep/view";
import { useRouter } from "vue-router";
import { useMultiTagsStoreHook } from "@/store/modules/multiTags";
import { getAb98UserTagNamesApi } from "@/api/ab98/tag";
defineOptions({
name: "Ab98User"
});
const router = useRouter();
const formRef = ref();
const tagOptions = ref<string[]>([]);
const searchFormParams = reactive<Ab98UserQuery & { search?: string }>({
name: undefined,
tel: undefined,
idnum: undefined,
tagName: undefined,
search: undefined
});
const pageLoading = ref(false);
const dataList = ref<Ab98UserDTO[]>([]);
const pagination = reactive<PaginationProps>({
total: 0,
pageSize: 12,
currentPage: 1,
background: true
});
async function onSearch() {
handleSearchInput(searchFormParams.search);
pagination.currentPage = 1;
getList();
}
async function getList() {
CommonUtils.fillPaginationParams(searchFormParams, pagination);
pageLoading.value = true;
const { data } = await getAb98UserListApi(searchFormParams).finally(
() => {
pageLoading.value = false;
}
);
dataList.value = data.rows;
pagination.total = data.total;
}
const handleSearchInput = (value) => {
// 身份证号正则(18位)
const idCardRegex = /^[1-9]\d{5}(18|19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[\dXx]$/;
// 手机号正则
const phoneRegex = /^1[3-9]\d{9}$/;
if (idCardRegex.test(value)) {
searchFormParams.idnum = value;
searchFormParams.name = '';
searchFormParams.tel = '';
} else if (phoneRegex.test(value)) {
searchFormParams.tel = value;
searchFormParams.name = '';
searchFormParams.idnum = '';
} else {
searchFormParams.name = value;
searchFormParams.tel = '';
searchFormParams.idnum = '';
}
};
const resetForm = formEl => {
if (!formEl) return;
formEl.resetFields();
onSearch();
};
const handleViewDetail = (row: Ab98UserDTO) => {
// 保存信息到标签页
useMultiTagsStoreHook().handleTags("push", {
path: `/user/ab98/detail`,
name: "ab98Detail",
query: { id: row.ab98UserId },
meta: {
title: `${row.name}`,
dynamicLevel: 3
}
});
router.push({
path: '/user/ab98/detail',
query: {
id: row.ab98UserId
}
});
};
onMounted(() => {
getList();
getAb98UserTagNamesApi().then(res => {
tagOptions.value = res.data;
});
})
</script>
<template>
<div class="main">
<div class="float-right w-full">
<el-form ref="formRef" :inline="true" :model="searchFormParams"
class="search-form bg-bg_color flex w-[99/100] pl-[22px] pt-[12px]">
<el-form-item prop="search">
<el-input v-model="searchFormParams.search" placeholder="请输入姓名/手机号/身份证" clearable class="!w-[300px]"
@keydown.enter.prevent="onSearch" @change="handleSearchInput" />
</el-form-item>
<el-form-item prop="tagName">
<el-select v-model="searchFormParams.tagName" placeholder="请选择用户标签" clearable class="!w-[160px]">
<el-option v-for="item in tagOptions" :key="item" :label="item" :value="item" />
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" :icon="useRenderIcon(Search)" :loading="pageLoading" @click="onSearch">
搜索
</el-button>
</el-form-item>
<el-form-item>
<el-button :icon="useRenderIcon(Refresh)" @click="resetForm(formRef)">
重置
</el-button>
</el-form-item>
</el-form>
<div class="grid-container">
<el-row :gutter="12">
<el-col v-for="(item, index) in dataList" :key="item.ab98UserId" :xs="24" :sm="12" :md="8" :lg="6">
<el-card class="user-card" :body-style="{ padding: '8px 20px' }">
<div class="card-content">
<el-avatar :size="80" :src="item.faceImg" fit="cover" shape="square" class="avatar">
<template v-if="!item.faceImg">
<svg width="100" height="100" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<circle cx="50" cy="50" r="48" fill="#f5f5f5" stroke="#e0e0e0" stroke-width="1" />
<circle cx="50" cy="40" r="12" fill="#9e9e9e" />
<rect x="40" y="52" width="20" height="30" rx="2" fill="#9e9e9e" />
</svg>
</template>
</el-avatar>
<div class="user-info">
<div class="name">姓名{{ item.name }}</div>
<div class="gender">性别{{ item.sex === '男' ? '男' : item.sex === '女' ? '女' : '' }}</div>
<div class="tel">电话{{ item.tel }}</div>
</div>
</div>
<div class="idnum">身份证号{{ item.idnum }}</div>
<div class="address"> {{ item.address }}</div>
<el-divider class="divider" />
<el-button class="detail-btn" :icon="useRenderIcon(View)" @click="handleViewDetail(item)" />
</el-card>
</el-col>
</el-row>
<div class="pagination-wrapper">
<el-pagination background layout="prev, pager, next" :page-size="pagination.pageSize"
:total="pagination.total" v-model:current-page="pagination.currentPage" @current-change="getList"
@size-change="getList" />
</div>
</div>
</div>
</div>
</template>
<style scoped lang="scss">
:deep(.el-dropdown-menu__item i) {
margin: 0;
}
.search-form {
:deep(.el-form-item) {
margin-bottom: 12px;
margin-right: 12px;
}
}
.user-card {
margin-bottom: 12px;
min-height: 210px;
display: flex;
flex-direction: column;
justify-content: space-between;
.card-content {
flex: 1;
display: flex;
flex-direction: row;
margin: 15px 0px;
gap: 15px;
.avatar {
align-self: flex-start;
}
.user-info {
text-align: left;
flex: 1;
.name,
.gender,
.tel {
font-size: 14px;
color: #606266;
margin-bottom: 6px;
line-height: 1.5;
}
.name {
font-weight: 500;
color: #303133;
}
}
.idnum,
.address {
font-size: 13px;
color: #606266;
margin: 4px 0;
line-height: 1.5;
word-break: break-all;
}
}
.divider {
margin: 10px 0px;
}
.detail-btn {
width: 100%;
border: 0;
margin-top: auto;
padding: 12px 0;
}
}
.grid-container {
margin: 12px 0;
padding-bottom: 0px;
position: relative;
.el-row {
margin-bottom: -20px;
}
}
.pagination-wrapper {
position: relative;
background: var(--el-bg-color);
padding: 9px 12px;
margin-top: 20px;
text-align: center;
:deep(.el-pagination) {
margin: 0;
padding: 0;
}
}
</style>