Compare commits

..

No commits in common. "5eb7ae6f0000e996b26ef51a58636acf6fc689c1" and "f3451a3357c3461be4edde2744f402bdbbe764f6" have entirely different histories.

13 changed files with 214 additions and 926 deletions

View File

@ -1,104 +0,0 @@
import { http } from "@/utils/http";
export interface Ab98UserDTO {
/** 主键ID */
ab98UserId?: number;
/** openid */
openid?: string;
/** 汇邦云用户唯一ID */
userid?: string;
/** 真实姓名 */
name?: string;
/** 手机号码 */
tel?: string;
/** 身份证号码 */
idnum?: string;
/** 性别(男 女) */
sex?: string;
/** 人脸照片地址 */
faceImg?: string;
/** 身份证正面地址 */
idcardFront?: string;
/** 身份证背面地址 */
idcardBack?: string;
/** 身份证登记地址 */
address?: string;
/** 是否已注册0未注册 1已注册 */
registered?: boolean;
}
export interface Ab98UserDetailDTO {
/** 主键ID */
ab98UserId?: number;
/** openid */
openid?: string;
/** 汇邦云用户唯一ID */
userid?: string;
/** 真实姓名 */
name?: string;
/** 手机号码 */
tel?: string;
/** 身份证号码 */
idnum?: string;
/** 性别(男 女) */
sex?: string;
/** 人脸照片地址 */
faceImg?: string;
/** 身份证正面地址 */
idcardFront?: string;
/** 身份证背面地址 */
idcardBack?: string;
/** 身份证登记地址 */
address?: string;
/** 是否已注册0未注册 1已注册 */
registered?: boolean;
createTime?: string;
}
export interface Ab98UserQuery extends BasePageQuery {
/** 真实姓名 */
name?: string;
/** 手机号码 */
tel?: string;
/** 身份证号码 */
idnum?: string;
}
export interface AddAb98UserCommand {
/** openid */
openid?: string;
/** 汇邦云用户唯一ID */
userid?: string;
/** 真实姓名 */
name?: string;
/** 手机号码 */
tel?: string;
/** 身份证号码 */
idnum?: string;
/** 性别(男 女) */
sex?: string;
}
export interface UpdateAb98UserCommand extends AddAb98UserCommand {
/** 主键ID */
ab98UserId: number;
}
export const getAb98UserListApi = (params: Ab98UserQuery) => {
return http.request<ResponseData<PageDTO<Ab98UserDTO>>>("get", "/ab98/users", { params });
};
export const addAb98UserApi = (data: AddAb98UserCommand) => {
return http.request<ResponseData<void>>("post", "/ab98/users", { data });
};
export const updateAb98UserApi = (id: number, data: UpdateAb98UserCommand) => {
return http.request<ResponseData<void>>("put", `/ab98/users/${id}`, { data });
};
export const deleteAb98UserApi = (ids: number[]) => {
return http.request<ResponseData<void>>("delete", `/ab98/users/${ids.join(',')}`);
};
export const getAb98UserDetailApi = (id: number) => {
return http.request<ResponseData<Ab98UserDetailDTO>>("get", `/ab98/users/detail/${id}`);
};

View File

@ -3,12 +3,6 @@ import { http } from "@/utils/http";
export interface OrderQuery extends BasePageQuery { export interface OrderQuery extends BasePageQuery {
/** 订单编号 */ /** 订单编号 */
orderId?: number; orderId?: number;
/**
* openid
*/
openid?: string;
/** 柜机id */
cabinetId?: number;
/** 格口id */ /** 格口id */
cellId?: number; cellId?: number;
/** /**

View File

@ -15,14 +15,6 @@ export default {
meta: { meta: {
title: "个人中心" title: "个人中心"
} }
},
{
path: "/user/ab98/detail",
name: "ab98Detail",
component: () => import("@/views/user/ab98/detail.vue"),
meta: {
title: "会员详情"
}
} }
] ]
} as RouteConfigsTable; } as RouteConfigsTable;

View File

@ -175,7 +175,3 @@
box-shadow: 0 -1px 0 0 #e0e3e8, 0 -3px 6px 0 rgb(69 98 155 / 12%); box-shadow: 0 -1px 0 0 #e0e3e8, 0 -3px 6px 0 rgb(69 98 155 / 12%);
} }
} }
.el-card.is-always-shadow {
box-shadow: 0px 0px 12px rgba(0, 0, 0, 0.04)!important;
}

View File

@ -4,7 +4,6 @@ import { PureTableBar } from "@/components/RePureTableBar";
import { onBeforeRouteUpdate, useRoute } from "vue-router"; import { onBeforeRouteUpdate, useRoute } from "vue-router";
import { useRenderIcon } from "@/components/ReIcon/src/hooks"; import { useRenderIcon } from "@/components/ReIcon/src/hooks";
import { getCabinetCellList, deleteCabinetCell, CabinetCellDTO } from "@/api/cabinet/cabinet-cell"; import { getCabinetCellList, deleteCabinetCell, CabinetCellDTO } from "@/api/cabinet/cabinet-cell";
import { allCabinets, SmartCabinetDTO } from "@/api/cabinet/smart-cabinet";
import EditPen from "@iconify-icons/ep/edit-pen"; import EditPen from "@iconify-icons/ep/edit-pen";
import Delete from "@iconify-icons/ep/delete"; import Delete from "@iconify-icons/ep/delete";
import AddFill from "@iconify-icons/ri/add-circle-line"; import AddFill from "@iconify-icons/ri/add-circle-line";
@ -15,56 +14,39 @@ import CellEditModal from "./cell-edit-modal.vue";
import { ElMessage, ElMessageBox } from "element-plus"; import { ElMessage, ElMessageBox } from "element-plus";
import { on } from "events"; import { on } from "events";
//
defineOptions({ defineOptions({
name: "CabinetCell" // name: "CabinetCell"
}); });
//
const formRef = ref(); const formRef = ref();
//
const tableRef = ref(); const tableRef = ref();
//
const modalVisible = ref(false); const modalVisible = ref(false);
//
const searchFormParams = ref({ const searchFormParams = ref({
cabinetId: null, // ID cabinetId: null,
cellNo: null, // cellNo: null,
cellType: null // cellType: null
}); });
//
const pagination = ref({ const pagination = ref({
pageSize: 10, // pageSize: 10,
currentPage: 1, // currentPage: 1,
total: 0 // total: 0
}); });
//
const loading = ref(false); const loading = ref(false);
//
const dataList = ref([]); const dataList = ref([]);
//
const multipleSelection = ref<number[]>([]); const multipleSelection = ref<number[]>([]);
//
const editVisible = ref(false); const editVisible = ref(false);
//
const currentRow = ref<CabinetCellDTO>(); const currentRow = ref<CabinetCellDTO>();
//
const route = useRoute(); const route = useRoute();
// onMounted(() => {
const cabinets = ref<SmartCabinetDTO[]>([]);
onMounted(async () => {
const { data } = await allCabinets();
cabinets.value = data;
if (route.query.cabinetId) { if (route.query.cabinetId) {
searchFormParams.value.cabinetId = Number(route.query.cabinetId); searchFormParams.value.cabinetId = Number(route.query.cabinetId);
getList();
} }
getList();
}); });
onBeforeRouteUpdate(() => { onBeforeRouteUpdate(() => {
if (route.query.cabinetId) { if (route.query.cabinetId) {
@ -73,33 +55,24 @@ onBeforeRouteUpdate(() => {
} }
}); });
/**
* 获取单元格列表数据
* @returns {Promise<void>}
*/
const getList = async () => { const getList = async () => {
try { try {
loading.value = true; // loading.value = true;
// API
const { data } = await getCabinetCellList({ const { data } = await getCabinetCellList({
...searchFormParams.value, // ...searchFormParams.value,
pageSize: pagination.value.pageSize, // pageSize: pagination.value.pageSize,
pageNum: pagination.value.currentPage // pageNum: pagination.value.currentPage
}); });
dataList.value = data.rows; // dataList.value = data.rows;
pagination.value.total = data.total; // pagination.value.total = data.total;
} finally { } finally {
loading.value = false; // loading.value = false;
} }
}; };
/**
* 搜索按钮点击事件
* 重置页码为第一页并重新获取数据
*/
const onSearch = () => { const onSearch = () => {
pagination.value.currentPage = 1; // pagination.value.currentPage = 1;
getList(); // getList();
}; };
const resetForm = () => { const resetForm = () => {
@ -117,18 +90,13 @@ const onCurrentChange = (val: number) => {
getList(); getList();
}; };
/**
* 删除单元格
* @param {CabinetCellDTO} row - 要删除的单元格数据
*/
const handleDelete = async (row: CabinetCellDTO) => { const handleDelete = async (row: CabinetCellDTO) => {
try { try {
// API
await deleteCabinetCell(row.cellId!.toString()); await deleteCabinetCell(row.cellId!.toString());
ElMessage.success("删除成功"); // ElMessage.success("删除成功");
getList(); // getList();
} catch (error) { } catch (error) {
console.error("删除失败", error); // console.error("删除失败", error);
} }
}; };
@ -160,11 +128,6 @@ const handleEdit = (row: CabinetCellDTO) => {
editVisible.value = true; editVisible.value = true;
}; };
/**
* 转换单元格类型为中文描述
* @param {number} cellType - 单元格类型编号
* @returns {string} 单元格类型中文描述
*/
const switchCellType = (cellType: number) => { const switchCellType = (cellType: number) => {
switch (cellType) { switch (cellType) {
case 1: case 1:
@ -183,120 +146,89 @@ const switchCellType = (cellType: number) => {
</script> </script>
<template> <template>
<div class="main flex"> <div class="main">
<!-- 左侧柜机列表 --> <el-form ref="formRef" :inline="true" :model="searchFormParams"
<div class="w-[200px] pr-4 border-r h-full left-list"> class="search-form bg-bg_color w-[99/100] pl-8 pt-[12px]">
<div class="text-lg font-bold mb-4 px-2">柜机列表</div> <el-form-item label="柜体ID" prop="cabinetId">
<div class="h-[calc(100vh-180px)] overflow-y-auto"> <el-input v-model.number="searchFormParams.cabinetId" placeholder="请输入柜体ID" clearable class="!w-[200px]" />
<div class="cabinet-list"> </el-form-item>
<div v-for="cabinet in cabinets" :key="cabinet.cabinetId" <el-form-item label="单元格号:" prop="cellNo">
class="cabinet-item p-3 mb-2 cursor-pointer rounded hover:bg-gray-100 transition-colors" <el-input v-model.number="searchFormParams.cellNo" placeholder="请输入单元格号" clearable class="!w-[180px]" />
:class="{ 'bg-blue-50': searchFormParams.cabinetId === cabinet.cabinetId }" </el-form-item>
@click="searchFormParams.cabinetId = cabinet.cabinetId; onSearch()"> <el-form-item label="单元格类型:" prop="cellType">
{{ cabinet.cabinetName }} <el-select v-model="searchFormParams.cellType" placeholder="请选择类型" clearable class="!w-[180px]">
</div> <el-option label="小格" :value="1" />
</div> <el-option label="中格" :value="2" />
</div> <el-option label="大格" :value="3" />
</div> <el-option label="超大格" :value="4" />
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" :icon="useRenderIcon(Search)" @click="onSearch">
搜索
</el-button>
<el-button :icon="useRenderIcon(Refresh)" @click="resetForm">
重置
</el-button>
</el-form-item>
</el-form>
<!-- 右侧内容 --> <PureTableBar title="柜体单元格管理" @refresh="getList">
<div class="flex-1 pl-4"> <template #buttons>
<el-form ref="formRef" :inline="true" :model="searchFormParams" <el-button type="primary" :icon="useRenderIcon(AddFill)" @click="modalVisible = true">
class="search-form bg-bg_color w-[99/100] pl-8 pt-[12px]"> 新增单元格
<el-form-item label="柜体ID" prop="cabinetId"> </el-button>
<el-input v-model.number="searchFormParams.cabinetId" placeholder="请输入柜体ID" clearable class="!w-[200px]" /> <el-button type="danger" :icon="useRenderIcon(Delete)" :disabled="multipleSelection.length === 0"
</el-form-item> @click="handleBulkDelete">
<el-form-item label="单元格号:" prop="cellNo"> 批量删除
<el-input v-model.number="searchFormParams.cellNo" placeholder="请输入单元格号" clearable class="!w-[180px]" /> </el-button>
</el-form-item> </template>
<el-form-item label="单元格类型:" prop="cellType"> <el-table ref="tableRef" v-loading="loading" :data="dataList" row-key="cellId"
<el-select v-model="searchFormParams.cellType" placeholder="请选择类型" clearable class="!w-[180px]"> @selection-change="handleSelectionChange" border>
<el-option label="小格" :value="1" /> <el-table-column type="selection" width="55" />
<el-option label="中格" :value="2" /> <el-table-column label="柜体ID" prop="cabinetId" width="100" />
<el-option label="大格" :value="3" /> <el-table-column label="单元格号" prop="cellNo" width="120" />
<el-option label="超大格" :value="4" /> <el-table-column label="针脚号" prop="pinNo" width="120" />
</el-select> <el-table-column label="单元格类型" prop="cellType">
</el-form-item> <template #default="{ row }">
<el-form-item> {{ switchCellType(row.cellType) }}
<el-button type="primary" :icon="useRenderIcon(Search)" @click="onSearch"> </template>
搜索 </el-table-column>
</el-button> <el-table-column label="使用状态" prop="usageStatus" width="120">
<el-button :icon="useRenderIcon(Refresh)" @click="resetForm"> <template #default="{ row }">
重置 {{ { 1: '空闲', 2: '已占用' }[row.usageStatus] || '未知' }}
</el-button> </template>
</el-form-item> </el-table-column>
</el-form> <el-table-column label="可用状态" prop="availableStatus" width="120">
<template #default="{ row }">
<PureTableBar title="柜体单元格管理" @refresh="getList"> <el-tag :type="row.availableStatus === 1 ? 'success' : 'danger'">
<template #buttons> {{ { 1: '正常', 2: '故障' }[row.availableStatus] || '未知' }}
<el-button type="primary" :icon="useRenderIcon(AddFill)" @click="modalVisible = true"> </el-tag>
新增单元格 </template>
</el-button> </el-table-column>
<el-button type="danger" :icon="useRenderIcon(Delete)" :disabled="multipleSelection.length === 0" <el-table-column label="操作" width="150" fixed="right">
@click="handleBulkDelete"> <template #default="{ row }">
批量删除 <el-button type="primary" link :icon="useRenderIcon(EditPen)" @click="handleEdit(row)">
</el-button> 编辑
</template> </el-button>
<el-table ref="tableRef" v-loading="loading" :data="dataList" row-key="cellId" <el-popconfirm :title="`确认删除【${row.cellNo}】号单元格?`" @confirm="handleDelete(row)">
@selection-change="handleSelectionChange" border> <template #reference>
<el-table-column type="selection" width="55" /> <el-button type="danger" link :icon="useRenderIcon(Delete)">
<el-table-column label="柜体ID" prop="cabinetId" width="100" /> 删除
<el-table-column label="单元格号" prop="cellNo" width="120" /> </el-button>
<el-table-column label="针脚号" prop="pinNo" width="120" /> </template>
<el-table-column label="单元格类型" prop="cellType"> </el-popconfirm>
<template #default="{ row }"> </template>
{{ switchCellType(row.cellType) }} </el-table-column>
</template> </el-table>
</el-table-column> <el-pagination v-model:current-page="pagination.currentPage" v-model:page-size="pagination.pageSize"
<el-table-column label="使用状态" prop="usageStatus" width="120"> :page-sizes="[10, 20, 50]" layout="total, sizes, prev, pager, next, jumper" :total="pagination.total"
<template #default="{ row }"> @size-change="onSizeChange" @current-change="onCurrentChange" />
{{ { 1: '空闲', 2: '已占用' }[row.usageStatus] || '未知' }} </PureTableBar>
</template> <cell-form-modal v-model:visible="modalVisible" :initial-cabinet-id="searchFormParams.cabinetId"
</el-table-column> @refresh="getList" />
<el-table-column label="可用状态" prop="availableStatus" width="120"> <cell-edit-modal v-model:visible="editVisible" :row="currentRow" @refresh="getList" />
<template #default="{ row }">
<el-tag :type="row.availableStatus === 1 ? 'success' : 'danger'">
{{ { 1: '正常', 2: '故障' }[row.availableStatus] || '未知' }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" width="150" fixed="right">
<template #default="{ row }">
<el-button type="primary" link :icon="useRenderIcon(EditPen)" @click="handleEdit(row)">
编辑
</el-button>
<el-popconfirm :title="`确认删除【${row.cellNo}】号单元格?`" @confirm="handleDelete(row)">
<template #reference>
<el-button type="danger" link :icon="useRenderIcon(Delete)">
删除
</el-button>
</template>
</el-popconfirm>
</template>
</el-table-column>
</el-table>
<el-pagination v-model:current-page="pagination.currentPage" v-model:page-size="pagination.pageSize"
:page-sizes="[10, 20, 50]" layout="total, sizes, prev, pager, next, jumper" :total="pagination.total"
@size-change="onSizeChange" @current-change="onCurrentChange" />
</PureTableBar>
<cell-form-modal v-model:visible="modalVisible" :initial-cabinet-id="searchFormParams.cabinetId"
@refresh="getList" />
<cell-edit-modal v-model:visible="editVisible" :row="currentRow" @refresh="getList" />
</div>
</div> </div>
</template> </template>
<style lang="scss" scoped> <style scoped></style>
.flex {
display: flex;
}
.border-r {
border-right: 1px solid #ebeef5;
}
.left-list {
background: #FFFFFF;
padding: 15px;
}
</style>

View File

@ -111,7 +111,6 @@ getList();
<PureTableBar title="格口开启记录" @refresh="getList"> <PureTableBar title="格口开启记录" @refresh="getList">
<el-table ref="tableRef" v-loading="loading" :data="dataList" row-key="operationId" border> <el-table ref="tableRef" v-loading="loading" :data="dataList" row-key="operationId" border>
<el-table-column label="操作ID" prop="operationId" width="120" /> <el-table-column label="操作ID" prop="operationId" width="120" />
<el-table-column label="格口ID" prop="cellId" width="120" />
<el-table-column label="操作人" prop="name" width="120" /> <el-table-column label="操作人" prop="name" width="120" />
<el-table-column label="手机号" prop="mobile" width="120" /> <el-table-column label="手机号" prop="mobile" width="120" />
<el-table-column label="商品名称" prop="goodsName" width="180" /> <el-table-column label="商品名称" prop="goodsName" width="180" />

View File

@ -12,7 +12,6 @@ import Qrcode from "@iconify-icons/ep/iphone";
import { ElMessage, ElMessageBox } from "element-plus"; import { ElMessage, ElMessageBox } from "element-plus";
import ShopFormModal from "./shop-form-modal.vue"; import ShopFormModal from "./shop-form-modal.vue";
import ReQrcode from "@/components/ReQrcode"; import ReQrcode from "@/components/ReQrcode";
import { copyTextToClipboard } from "@pureadmin/utils";
defineOptions({ defineOptions({
name: "Shop" name: "Shop"
@ -124,12 +123,6 @@ const showQrCode = (shopId: number) => {
qrVisible.value = true; qrVisible.value = true;
}; };
const copyLink = () => {
const url = `http://wxshop.ab98.cn/shop-api/api/shop/wechatAuth?shopId=${currentShopId.value}`;
const success = copyTextToClipboard(url);
success ? ElMessage.success('链接复制成功') : ElMessage.error('复制失败,请手动复制');
};
getList(); getList();
</script> </script>
@ -195,9 +188,6 @@ getList();
<ReQrcode :text="`http://wxshop.ab98.cn/shop-api/api/shop/wechatAuth?shopId=${currentShopId}`" <ReQrcode :text="`http://wxshop.ab98.cn/shop-api/api/shop/wechatAuth?shopId=${currentShopId}`"
:options="{ width: 200 }" /> :options="{ width: 200 }" />
<div class="mt-2 text-sm text-gray-500">微信扫码访问</div> <div class="mt-2 text-sm text-gray-500">微信扫码访问</div>
<el-button class="mt-2" type="primary" size="small" @click="copyLink">
复制链接
</el-button>
</div> </div>
</el-dialog> </el-dialog>
</div> </div>

View File

@ -199,7 +199,8 @@ getList();
<el-button type="primary" link :icon="useRenderIcon(EditPen)" @click="handleEdit(row)"> <el-button type="primary" link :icon="useRenderIcon(EditPen)" @click="handleEdit(row)">
编辑 编辑
</el-button> </el-button>
<el-button type="warning" link :icon="useRenderIcon(EditPen)" @click="goCellManagement(row)"> <el-button type="warning" link :icon="useRenderIcon('fluent:cell-phone-arrow-right-20-regular')"
@click="goCellManagement(row)">
格口 格口
</el-button> </el-button>
<el-button type="warning" link :icon="useRenderIcon('ant-design:gateway-outlined')" <el-button type="warning" link :icon="useRenderIcon('ant-design:gateway-outlined')"

View File

@ -261,7 +261,6 @@ const handleClearGoods = async (row: CabinetCellDTO) => {
<el-table ref="tableRef" v-loading="loading" :data="dataList" row-key="cellId" <el-table ref="tableRef" v-loading="loading" :data="dataList" row-key="cellId"
@selection-change="handleSelectionChange" border> @selection-change="handleSelectionChange" border>
<el-table-column label="格口ID" prop="cellId" width="80" /> <el-table-column label="格口ID" prop="cellId" width="80" />
<el-table-column label="格口号" prop="cellNo" width="80" />
<el-table-column label="商品图片" width="120"> <el-table-column label="商品图片" width="120">
<template #default="{ row }"> <template #default="{ row }">
<el-image :src="row.coverImg" :preview-src-list="[row.coverImg]" :z-index="9999" <el-image :src="row.coverImg" :preview-src-list="[row.coverImg]" :z-index="9999"

View File

@ -1,9 +1,8 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, watch, onMounted } from "vue"; import { ref, watch } from "vue";
import { PureTableBar } from "@/components/RePureTableBar"; import { PureTableBar } from "@/components/RePureTableBar";
import { useRenderIcon } from "@/components/ReIcon/src/hooks"; import { useRenderIcon } from "@/components/ReIcon/src/hooks";
import { getOrderListApi, exportOrderExcelApi, type OrderDTO, OrderQuery } from "@/api/shop/order"; import { getOrderListApi, exportOrderExcelApi, type OrderDTO, OrderQuery } from "@/api/shop/order";
import { allCabinets, SmartCabinetDTO } from "@/api/cabinet/smart-cabinet";
import Search from "@iconify-icons/ep/search"; import Search from "@iconify-icons/ep/search";
import Refresh from "@iconify-icons/ep/refresh"; import Refresh from "@iconify-icons/ep/refresh";
import { ElMessage } from "element-plus"; import { ElMessage } from "element-plus";
@ -16,10 +15,8 @@ const route = useRoute();
const formRef = ref(); const formRef = ref();
const tableRef = ref(); const tableRef = ref();
const cabinets = ref<SmartCabinetDTO[]>([]);
const searchFormParams = ref<OrderQuery>({ const searchFormParams = ref<OrderQuery>({
cabinetId: null,
orderId: null, orderId: null,
cellId: null, cellId: null,
status: null, status: null,
@ -39,11 +36,6 @@ const pagination = ref({
const loading = ref(false); const loading = ref(false);
const dataList = ref<OrderDTO[]>([]); const dataList = ref<OrderDTO[]>([]);
onMounted(async () => {
const { data } = await allCabinets();
cabinets.value = data;
});
const getList = async () => { const getList = async () => {
try { try {
loading.value = true; loading.value = true;
@ -115,138 +107,125 @@ getList();
</script> </script>
<template> <template>
<div class="main flex"> <div class="main">
<!-- 左侧柜机列表 --> <el-form ref="formRef" :inline="true" :model="searchFormParams"
<div class="w-[200px] mr-4 bg-white rounded shadow p-4"> class="search-form bg-bg_color w-[99/100] pl-8 pt-[12px]">
<div class="text-lg font-bold mb-4">柜机列表</div> <!-- <el-form-item label="时间范围:">
<div class="space-y-2">
<div v-for="cabinet in cabinets" :key="cabinet.cabinetId" class="p-2 rounded cursor-pointer hover:bg-gray-100"
:class="{ 'bg-blue-50': searchFormParams.cabinetId === cabinet.cabinetId }"
@click="searchFormParams.cabinetId = cabinet.cabinetId; onSearch()">
{{ cabinet.cabinetName }}
</div>
</div>
</div>
<div class="flex-1">
<el-form ref="formRef" :inline="true" :model="searchFormParams"
class="search-form bg-bg_color w-[99/100] pl-8 pt-[12px]">
<!-- <el-form-item label="时间范围:">
<el-date-picker v-model="searchFormParams.startTime" type="date" placeholder="开始时间" <el-date-picker v-model="searchFormParams.startTime" type="date" placeholder="开始时间"
value-format="YYYY-MM-DD HH:mm:ss" class="!w-[200px]" /> value-format="YYYY-MM-DD HH:mm:ss" class="!w-[200px]" />
<span class="mx-2"></span> <span class="mx-2"></span>
<el-date-picker v-model="searchFormParams.endTime" type="date" placeholder="结束时间" <el-date-picker v-model="searchFormParams.endTime" type="date" placeholder="结束时间"
value-format="YYYY-MM-DD HH:mm:ss" class="!w-[200px]" /> value-format="YYYY-MM-DD HH:mm:ss" class="!w-[200px]" />
</el-form-item> --> </el-form-item> -->
<el-form-item label="支付日期:"> <el-form-item label="支付日期:">
<el-date-picker v-model="searchFormParams.payTime" type="date" placeholder="支付时间" <el-date-picker v-model="searchFormParams.payTime" type="date" placeholder="支付时间"
value-format="YYYY-MM-DD HH:mm:ss" class="!w-[200px]" /> value-format="YYYY-MM-DD HH:mm:ss" class="!w-[200px]" />
</el-form-item> </el-form-item>
<el-form-item label="订单编号:" prop="orderId"> <el-form-item label="订单编号:" prop="orderId">
<el-input v-model="searchFormParams.orderId" placeholder="请输入订单编号" clearable class="!w-[200px]" /> <el-input v-model="searchFormParams.orderId" placeholder="请输入订单编号" clearable class="!w-[200px]" />
</el-form-item> </el-form-item>
<el-form-item label="格口ID" prop="cellId"> <el-form-item label="格口ID" prop="cellId">
<el-input v-model="searchFormParams.cellId" placeholder="请输入格口ID" clearable class="!w-[200px]" /> <el-input v-model="searchFormParams.cellId" placeholder="请输入格口ID" clearable class="!w-[200px]" />
</el-form-item> </el-form-item>
<el-form-item label="订单状态:" prop="status"> <el-form-item label="订单状态:" prop="status">
<el-select v-model="searchFormParams.status" placeholder="请选择状态" clearable class="!w-[180px]"> <el-select v-model="searchFormParams.status" placeholder="请选择状态" clearable class="!w-[180px]">
<el-option label="待付款" :value="1" /> <el-option label="待付款" :value="1" />
<el-option label="已付款" :value="2" /> <el-option label="已付款" :value="2" />
<el-option label="已发货" :value="3" /> <el-option label="已发货" :value="3" />
<el-option label="已完成" :value="4" /> <el-option label="已完成" :value="4" />
<el-option label="已取消" :value="5" /> <el-option label="已取消" :value="5" />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="支付状态:" prop="payStatus"> <el-form-item label="支付状态:" prop="payStatus">
<el-select v-model="searchFormParams.payStatus" placeholder="请选择支付状态" clearable class="!w-[180px]"> <el-select v-model="searchFormParams.payStatus" placeholder="请选择支付状态" clearable class="!w-[180px]">
<el-option label="未支付" :value="1" /> <el-option label="未支付" :value="1" />
<el-option label="已支付" :value="2" /> <el-option label="已支付" :value="2" />
<el-option label="退款中" :value="3" /> <el-option label="退款中" :value="3" />
<el-option label="已退款" :value="4" /> <el-option label="已退款" :value="4" />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="支付方式:" prop="paymentMethod"> <el-form-item label="支付方式:" prop="paymentMethod">
<el-select v-model="searchFormParams.paymentMethod" placeholder="请选择支付方式" clearable class="!w-[180px]"> <el-select v-model="searchFormParams.paymentMethod" placeholder="请选择支付方式" clearable class="!w-[180px]">
<el-option label="微信支付" value="wechat" /> <el-option label="微信支付" value="wechat" />
<el-option label="余额支付" value="balance" /> <el-option label="余额支付" value="balance" />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button type="primary" :icon="useRenderIcon(Search)" @click="onSearch"> <el-button type="primary" :icon="useRenderIcon(Search)" @click="onSearch">
搜索 搜索
</el-button> </el-button>
<el-button :icon="useRenderIcon(Refresh)" @click="resetForm"> <el-button :icon="useRenderIcon(Refresh)" @click="resetForm">
重置 重置
</el-button> </el-button>
<el-button type="success" :loading="exportLoading" :icon="useRenderIcon('vscode-icons:file-type-excel2')" <el-button type="success" :loading="exportLoading" :icon="useRenderIcon('vscode-icons:file-type-excel2')"
@click="handleExport"> @click="handleExport">
导出Excel 导出Excel
</el-button> </el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
<PureTableBar title="订单列表" @refresh="getList"> <PureTableBar title="订单列表" @refresh="getList">
<el-table ref="tableRef" v-loading="loading" :data="dataList" row-key="orderId" border> <el-table ref="tableRef" v-loading="loading" :data="dataList" row-key="orderId" border>
<el-table-column label="订单ID" prop="orderId" width="120" /> <el-table-column label="订单ID" prop="orderId" width="120" />
<el-table-column label="商品名称" prop="goodsNames" width="180"> <el-table-column label="商品名称" prop="goodsNames" width="180">
<template #default="{ row }"> <template #default="{ row }">
<span v-if="row.goodsNames"> <span v-if="row.goodsNames">
{{ row.goodsNames.split(',').join(', ') }} {{ row.goodsNames.split(',').join(', ') }}
</span> </span>
<span v-else>-</span> <span v-else>-</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="商品封面" prop="coverImgs" width="100"> <el-table-column label="商品封面" prop="coverImgs" width="100">
<template #default="{ row }"> <template #default="{ row }">
<div v-if="row.coverImgs" class="flex gap-2"> <div v-if="row.coverImgs" class="flex gap-2">
<el-image v-for="(img, index) in row.coverImgs.split(',')" :key="index" :src="img" <el-image v-for="(img, index) in row.coverImgs.split(',')" :key="index" :src="img"
:preview-src-list="row.coverImgs.split(',')" :z-index="9999" :preview-teleported="true" :preview-src-list="row.coverImgs.split(',')" :z-index="9999" :preview-teleported="true"
:hide-on-click-modal="true" fit="cover" class="rounded" width="60" height="60" /> :hide-on-click-modal="true" fit="cover" class="rounded" width="60" height="60" />
</div> </div>
<span v-else>-</span> <span v-else>-</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="姓名" prop="name" width="120" /> <el-table-column label="姓名" prop="name" width="120" />
<el-table-column label="手机号" prop="mobile" width="120" /> <el-table-column label="手机号" prop="mobile" width="120" />
<el-table-column label="订单金额" prop="totalAmount" width="120"> <el-table-column label="订单金额" prop="totalAmount" width="120">
<template #default="{ row }">{{ row.totalAmount }}</template> <template #default="{ row }">{{ row.totalAmount }}</template>
</el-table-column> </el-table-column>
<el-table-column label="订单状态" prop="status" width="120"> <el-table-column label="订单状态" prop="status" width="120">
<template #default="{ row }"> <template #default="{ row }">
<el-tag :type="row.status === 2 ? 'success' : row.status === 5 ? 'danger' : 'info'"> <el-tag :type="row.status === 2 ? 'success' : row.status === 5 ? 'danger' : 'info'">
{{ { 1: '待付款', 2: '已付款', 3: '已发货', 4: '已完成', 5: '已取消' }[row.status] }} {{ { 1: '待付款', 2: '已付款', 3: '已发货', 4: '已完成', 5: '已取消' }[row.status] }}
</el-tag> </el-tag>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="支付状态" prop="payStatus" width="120"> <el-table-column label="支付状态" prop="payStatus" width="120">
<template #default="{ row }"> <template #default="{ row }">
<el-tag :type="row.payStatus === 2 ? 'success' : 'info'"> <el-tag :type="row.payStatus === 2 ? 'success' : 'info'">
{{ { 1: '未支付', 2: '已支付', 3: '退款中', 4: '已退款' }[row.payStatus] }} {{ { 1: '未支付', 2: '已支付', 3: '退款中', 4: '已退款' }[row.payStatus] }}
</el-tag> </el-tag>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="支付方式" prop="paymentMethod" width="120"> <el-table-column label="支付方式" prop="paymentMethod" width="120">
<template #default="{ row }"> <template #default="{ row }">
{{ { wechat: '微信支付', balance: '余额支付' }[row.paymentMethod] || row.paymentMethod }} {{ { wechat: '微信支付', balance: '余额支付' }[row.paymentMethod] || row.paymentMethod }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="支付时间" prop="payTime" width="180"> <el-table-column label="支付时间" prop="payTime" width="180">
<template #default="{ row }"> <template #default="{ row }">
{{ row.payTime ? new Date(row.payTime).toLocaleString() : '-' }} {{ row.payTime ? new Date(row.payTime).toLocaleString() : '-' }}
</template> </template>
</el-table-column> </el-table-column>
<!-- <el-table-column label="操作" width="100" fixed="right"> <!-- <el-table-column label="操作" width="100" fixed="right">
<template #default="{ row }"> <template #default="{ row }">
<el-button type="primary" link @click="handleDetail(row)"> <el-button type="primary" link @click="handleDetail(row)">
详情 详情
</el-button> </el-button>
</template> </template>
</el-table-column> --> </el-table-column> -->
</el-table> </el-table>
<el-pagination v-model:current-page="pagination.currentPage" v-model:page-size="pagination.pageSize" <el-pagination v-model:current-page="pagination.currentPage" v-model:page-size="pagination.pageSize"
:page-sizes="[5, 10, 20, 50]" layout="total, sizes, prev, pager, next, jumper" :total="pagination.total" :page-sizes="[5, 10, 20, 50]" layout="total, sizes, prev, pager, next, jumper" :total="pagination.total"
@size-change="onSizeChange" @current-change="onCurrentChange" /> @size-change="onSizeChange" @current-change="onCurrentChange" />
</PureTableBar> </PureTableBar>
</div>
</div> </div>
</template> </template>

View File

@ -1,253 +0,0 @@
<script setup lang="ts">
import { ref, onMounted, watch } from "vue";
import { useRoute } from "vue-router";
import { type Ab98UserDetailDTO, getAb98UserDetailApi } from "@/api/ab98/user";
import { getOrderListApi, type OrderDTO } from "@/api/shop/order";
defineOptions({
name: "Ab98UserDetail"
});
const route = useRoute();
const userInfo = ref<Ab98UserDetailDTO>({});
const loading = ref(false);
//
const basicInfo = ref({
registerTime: "2023-01-15",
lastLogin: "2023-06-20",
loginCount: 42,
device: "iPhone 13"
});
//
const orderRecords = ref<OrderDTO[]>([]);
const pagination = ref({
pageSize: 5,
currentPage: 1,
total: 0
});
const orderLoading = ref(false);
const activeTab = ref('basic');
async function fetchOrders() {
try {
orderLoading.value = true;
const { data } = await getOrderListApi({
openid: userInfo.value.openid,
pageSize: pagination.value.pageSize,
pageNum: pagination.value.currentPage
});
orderRecords.value = data.rows;
pagination.value.total = data.total;
} finally {
orderLoading.value = false;
}
}
watch(activeTab, (newVal) => {
if (newVal === 'orders') {
fetchOrders();
}
});
async function fetchUserDetail() {
try {
loading.value = true;
const userId = route.query.id;
const { data } = await getAb98UserDetailApi(Number(userId));
userInfo.value = data;
} finally {
loading.value = false;
}
}
onMounted(() => {
fetchUserDetail();
});
</script>
<template>
<div class="detail-container">
<div class="flex-container">
<el-card class="user-info-card">
<div class="user-header">
<el-avatar :size="100" :src="userInfo.faceImg" fit="cover" shape="square">
<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>
</el-avatar>
<div class="user-name">{{ userInfo.name }}</div>
</div>
<el-divider />
<el-descriptions class="user-details" :column="1" border>
<el-descriptions-item label="性别">{{ userInfo.sex }}</el-descriptions-item>
<el-descriptions-item label="手机号">{{ userInfo.tel }}</el-descriptions-item>
<el-descriptions-item label="身份证号">{{ userInfo.idnum }}</el-descriptions-item>
<el-descriptions-item label="住址">{{ userInfo.address }}</el-descriptions-item>
</el-descriptions>
</el-card>
<el-card class="info-card">
<div class="tab-header">
<el-tabs type="card" v-model="activeTab">
<el-tab-pane label="基础信息" name="basic"></el-tab-pane>
<el-tab-pane label="订单记录" name="orders"></el-tab-pane>
</el-tabs>
</div>
<el-descriptions class="info-details" v-if="activeTab === 'basic'" :column="2" border>
<el-descriptions-item label="会员ID">{{ userInfo.ab98UserId }}</el-descriptions-item>
<el-descriptions-item label="微信openid">{{ userInfo.openid }}</el-descriptions-item>
<el-descriptions-item label="注册时间">{{ userInfo.createTime }}</el-descriptions-item>
<el-descriptions-item label="最后登录">{{ basicInfo.lastLogin }}</el-descriptions-item>
<el-descriptions-item label="登录次数">{{ basicInfo.loginCount }}</el-descriptions-item>
<el-descriptions-item label="常用设备">{{ basicInfo.device }}</el-descriptions-item>
</el-descriptions>
<div class="info-details" v-if="activeTab === 'orders'">
<PureTableBar title="订单列表" @refresh="fetchOrders">
<el-table ref="tableRef" v-loading="orderLoading" :data="orderRecords" row-key="orderId" border>
<el-table-column label="订单ID" prop="orderId" width="120" />
<el-table-column label="商品名称" prop="goodsNames" width="180">
<template #default="{ row }">
<span v-if="row.goodsNames">
{{ row.goodsNames.split(',').join(', ') }}
</span>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column label="商品封面" prop="coverImgs" width="100">
<template #default="{ row }">
<div v-if="row.coverImgs" class="flex gap-2">
<el-image v-for="(img, index) in row.coverImgs.split(',')" :key="index" :src="img"
:preview-src-list="row.coverImgs.split(',')" :z-index="9999" :preview-teleported="true"
:hide-on-click-modal="true" fit="cover" class="rounded" width="60" height="60" />
</div>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column label="姓名" prop="name" width="120" />
<el-table-column label="手机号" prop="mobile" width="120" />
<el-table-column label="订单金额" prop="totalAmount" width="120">
<template #default="{ row }">{{ row.totalAmount }}</template>
</el-table-column>
<el-table-column label="订单状态" prop="status" width="120">
<template #default="{ row }">
<el-tag :type="row.status === 2 ? 'success' : row.status === 5 ? 'danger' : 'info'">
{{ { 1: '待付款', 2: '已付款', 3: '已发货', 4: '已完成', 5: '已取消' }[row.status] }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="支付状态" prop="payStatus" width="120">
<template #default="{ row }">
<el-tag :type="row.payStatus === 2 ? 'success' : 'info'">
{{ { 1: '未支付', 2: '已支付', 3: '退款中', 4: '已退款' }[row.payStatus] }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="支付方式" prop="paymentMethod" width="120">
<template #default="{ row }">
{{ { wechat: '微信支付', balance: '余额支付' }[row.paymentMethod] || row.paymentMethod }}
</template>
</el-table-column>
<el-table-column label="支付时间" prop="payTime" width="180">
<template #default="{ row }">
{{ row.payTime ? new Date(row.payTime).toLocaleString() : '-' }}
</template>
</el-table-column>
</el-table>
<el-pagination v-model:current-page="pagination.currentPage" v-model:page-size="pagination.pageSize"
:page-sizes="[5, 10, 20, 50]" layout="total, sizes, prev, pager, next, jumper" :total="pagination.total"
@size-change="fetchOrders" @current-change="fetchOrders" />
</PureTableBar>
</div>
</el-card>
</div>
</div>
</template>
<style scoped lang="scss">
.detail-container {
display: flex;
flex-direction: column;
height: 100%;
.flex-container {
display: flex;
flex: 1;
gap: 20px;
min-height: 0;
.user-info-card {
width: 20%;
}
.info-card {
width: 80%;
}
}
.user-info-card,
.shop-info-card {
height: 100%;
min-height: 85vh;
}
.user-header {
display: flex;
flex-direction: column;
align-items: center;
margin-bottom: 20px;
.user-name {
margin-top: 15px;
font-size: 20px;
font-weight: bold;
}
}
.tab-header {
margin-bottom: 20px;
}
.order-item {
margin-bottom: 20px;
padding: 10px;
background-color: #f9f9f9;
border-radius: 4px;
.order-id {
font-weight: bold;
margin-bottom: 8px;
}
.order-detail {
display: flex;
justify-content: space-between;
font-size: 13px;
color: #666;
}
}
.detail-item {
margin: 15px 0;
font-size: 14px;
.label {
color: #606266;
margin-right: 10px;
}
.value {
color: #303133;
}
}
}
</style>

View File

@ -1,226 +0,0 @@
<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";
defineOptions({
name: "Ab98User"
});
const router = useRouter();
const formRef = ref();
const searchFormParams = reactive<Ab98UserQuery>({
name: undefined,
tel: undefined,
idnum: undefined
});
const pageLoading = ref(false);
const dataList = ref<Ab98UserDTO[]>([]);
const pagination = reactive<PaginationProps>({
total: 0,
pageSize: 12,
currentPage: 1,
background: true
});
async function onSearch() {
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 resetForm = formEl => {
if (!formEl) return;
formEl.resetFields();
onSearch();
};
const handleViewDetail = (row: any) => {
router.push({
path: '/user/ab98/detail',
query: {
id: row.ab98UserId
}
});
};
onMounted(() => {
getList();
})
</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 w-[99/100] pl-8 pt-[12px]">
<el-form-item label="姓名:" prop="name">
<el-input v-model="searchFormParams.name" placeholder="请输入" clearable class="!w-[160px]" />
</el-form-item>
<el-form-item label="手机号:" prop="tel">
<el-input v-model="searchFormParams.tel" placeholder="请输入" clearable class="!w-[160px]" />
</el-form-item>
<el-form-item label="身份证:" prop="idnum">
<el-input v-model="searchFormParams.idnum" placeholder="请输入" clearable class="!w-[160px]" />
</el-form-item>
<el-form-item>
<el-button type="primary" :icon="useRenderIcon(Search)" :loading="pageLoading" @click="onSearch">
搜索
</el-button>
<el-button :icon="useRenderIcon(Refresh)" @click="resetForm(formRef)">
重置
</el-button>
</el-form-item>
</el-form>
<div class="grid-container">
<el-row :gutter="20">
<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;
}
}
.user-card {
margin-bottom: 20px;
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: 20px 0;
padding-bottom: 60px;
position: relative;
.el-row {
margin-bottom: -20px;
}
}
.pagination-wrapper {
position: relative;
background: var(--el-bg-color);
padding: 12px 12px;
margin-top: 20px;
text-align: center;
:deep(.el-pagination) {
margin: 0;
padding: 8px 0;
}
}
</style>

View File

@ -60,21 +60,10 @@ watch(
<el-col v-for="(item, index) in dataList" :key="item.id" :xs="24" :sm="12" :md="8" :lg="6"> <el-col v-for="(item, index) in dataList" :key="item.id" :xs="24" :sm="12" :md="8" :lg="6">
<el-card class="user-card"> <el-card class="user-card">
<div class="card-content"> <div class="card-content">
<el-avatar :size="60" :src="item.avatar" fit="cover" shape="square" class="avatar"> <el-avatar :size="60" :src="item.avatar" fit="cover" shape="square" class="avatar" />
<template v-if="!item.avatar">
<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="user-info">
<div class="name">{{ item.name }}</div> <div class="name">{{ item.name }}</div>
<!-- <div class="gender">性别{{ item.gender === '1' ? '男' : item.gender === '2' ? '女' : '' }}</div> --> <div class="gender">性别{{ item.gender === '1' ? '男' : item.gender === '2' ? '女' : '' }}</div>
<div class="create-time">创建时间{{ item.createTimeStr }}</div> <div class="create-time">创建时间{{ item.createTimeStr }}</div>
<div class="balance">余额¥{{ item.balance?.toFixed(2) }}</div> <div class="balance">余额¥{{ item.balance?.toFixed(2) }}</div>
</div> </div>