Compare commits
6 Commits
f3451a3357
...
5eb7ae6f00
Author | SHA1 | Date |
---|---|---|
|
5eb7ae6f00 | |
|
4146851ac2 | |
|
312fb7ae81 | |
|
43cfec18ab | |
|
bdb5a1128c | |
|
42fee5ed40 |
|
@ -0,0 +1,104 @@
|
|||
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}`);
|
||||
};
|
|
@ -3,6 +3,12 @@ import { http } from "@/utils/http";
|
|||
export interface OrderQuery extends BasePageQuery {
|
||||
/** 订单编号 */
|
||||
orderId?: number;
|
||||
/**
|
||||
* 微信openid
|
||||
*/
|
||||
openid?: string;
|
||||
/** 柜机id */
|
||||
cabinetId?: number;
|
||||
/** 格口id */
|
||||
cellId?: number;
|
||||
/**
|
||||
|
|
|
@ -15,6 +15,14 @@ export default {
|
|||
meta: {
|
||||
title: "个人中心"
|
||||
}
|
||||
},
|
||||
{
|
||||
path: "/user/ab98/detail",
|
||||
name: "ab98Detail",
|
||||
component: () => import("@/views/user/ab98/detail.vue"),
|
||||
meta: {
|
||||
title: "会员详情"
|
||||
}
|
||||
}
|
||||
]
|
||||
} as RouteConfigsTable;
|
||||
|
|
|
@ -175,3 +175,7 @@
|
|||
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;
|
||||
}
|
|
@ -4,6 +4,7 @@ import { PureTableBar } from "@/components/RePureTableBar";
|
|||
import { onBeforeRouteUpdate, useRoute } from "vue-router";
|
||||
import { useRenderIcon } from "@/components/ReIcon/src/hooks";
|
||||
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 Delete from "@iconify-icons/ep/delete";
|
||||
import AddFill from "@iconify-icons/ri/add-circle-line";
|
||||
|
@ -14,39 +15,56 @@ import CellEditModal from "./cell-edit-modal.vue";
|
|||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
import { on } from "events";
|
||||
|
||||
// 定义组件选项
|
||||
defineOptions({
|
||||
name: "CabinetCell"
|
||||
name: "CabinetCell" // 组件名称
|
||||
});
|
||||
|
||||
// 表单引用
|
||||
const formRef = ref();
|
||||
// 表格引用
|
||||
const tableRef = ref();
|
||||
// 新增单元格模态框显示状态
|
||||
const modalVisible = ref(false);
|
||||
|
||||
// 搜索表单参数
|
||||
const searchFormParams = ref({
|
||||
cabinetId: null,
|
||||
cellNo: null,
|
||||
cellType: null
|
||||
cabinetId: null, // 柜体ID
|
||||
cellNo: null, // 单元格号
|
||||
cellType: null // 单元格类型
|
||||
});
|
||||
|
||||
// 分页参数
|
||||
const pagination = ref({
|
||||
pageSize: 10,
|
||||
currentPage: 1,
|
||||
total: 0
|
||||
pageSize: 10, // 每页显示数量
|
||||
currentPage: 1, // 当前页码
|
||||
total: 0 // 总条数
|
||||
});
|
||||
|
||||
// 加载状态
|
||||
const loading = ref(false);
|
||||
// 表格数据列表
|
||||
const dataList = ref([]);
|
||||
// 多选选中项
|
||||
const multipleSelection = ref<number[]>([]);
|
||||
// 编辑单元格模态框显示状态
|
||||
const editVisible = ref(false);
|
||||
// 当前编辑行数据
|
||||
const currentRow = ref<CabinetCellDTO>();
|
||||
|
||||
// 路由实例
|
||||
const route = useRoute();
|
||||
|
||||
onMounted(() => {
|
||||
// 柜机列表数据
|
||||
const cabinets = ref<SmartCabinetDTO[]>([]);
|
||||
|
||||
onMounted(async () => {
|
||||
const { data } = await allCabinets();
|
||||
cabinets.value = data;
|
||||
if (route.query.cabinetId) {
|
||||
searchFormParams.value.cabinetId = Number(route.query.cabinetId);
|
||||
getList();
|
||||
}
|
||||
getList();
|
||||
});
|
||||
onBeforeRouteUpdate(() => {
|
||||
if (route.query.cabinetId) {
|
||||
|
@ -55,24 +73,33 @@ onBeforeRouteUpdate(() => {
|
|||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 获取单元格列表数据
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
const getList = async () => {
|
||||
try {
|
||||
loading.value = true;
|
||||
loading.value = true; // 显示加载状态
|
||||
// 调用API获取单元格列表
|
||||
const { data } = await getCabinetCellList({
|
||||
...searchFormParams.value,
|
||||
pageSize: pagination.value.pageSize,
|
||||
pageNum: pagination.value.currentPage
|
||||
...searchFormParams.value, // 搜索参数
|
||||
pageSize: pagination.value.pageSize, // 每页数量
|
||||
pageNum: pagination.value.currentPage // 当前页码
|
||||
});
|
||||
dataList.value = data.rows;
|
||||
pagination.value.total = data.total;
|
||||
dataList.value = data.rows; // 更新表格数据
|
||||
pagination.value.total = data.total; // 更新总条数
|
||||
} finally {
|
||||
loading.value = false;
|
||||
loading.value = false; // 隐藏加载状态
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 搜索按钮点击事件
|
||||
* 重置页码为第一页并重新获取数据
|
||||
*/
|
||||
const onSearch = () => {
|
||||
pagination.value.currentPage = 1;
|
||||
getList();
|
||||
pagination.value.currentPage = 1; // 重置页码
|
||||
getList(); // 重新获取数据
|
||||
};
|
||||
|
||||
const resetForm = () => {
|
||||
|
@ -90,13 +117,18 @@ const onCurrentChange = (val: number) => {
|
|||
getList();
|
||||
};
|
||||
|
||||
/**
|
||||
* 删除单元格
|
||||
* @param {CabinetCellDTO} row - 要删除的单元格数据
|
||||
*/
|
||||
const handleDelete = async (row: CabinetCellDTO) => {
|
||||
try {
|
||||
// 调用API删除单元格
|
||||
await deleteCabinetCell(row.cellId!.toString());
|
||||
ElMessage.success("删除成功");
|
||||
getList();
|
||||
ElMessage.success("删除成功"); // 显示成功消息
|
||||
getList(); // 刷新列表
|
||||
} catch (error) {
|
||||
console.error("删除失败", error);
|
||||
console.error("删除失败", error); // 打印错误信息
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -128,6 +160,11 @@ const handleEdit = (row: CabinetCellDTO) => {
|
|||
editVisible.value = true;
|
||||
};
|
||||
|
||||
/**
|
||||
* 转换单元格类型为中文描述
|
||||
* @param {number} cellType - 单元格类型编号
|
||||
* @returns {string} 单元格类型中文描述
|
||||
*/
|
||||
const switchCellType = (cellType: number) => {
|
||||
switch (cellType) {
|
||||
case 1:
|
||||
|
@ -146,89 +183,120 @@ const switchCellType = (cellType: number) => {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<div class="main">
|
||||
<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="柜体ID:" prop="cabinetId">
|
||||
<el-input v-model.number="searchFormParams.cabinetId" placeholder="请输入柜体ID" clearable class="!w-[200px]" />
|
||||
</el-form-item>
|
||||
<el-form-item label="单元格号:" prop="cellNo">
|
||||
<el-input v-model.number="searchFormParams.cellNo" placeholder="请输入单元格号" clearable class="!w-[180px]" />
|
||||
</el-form-item>
|
||||
<el-form-item label="单元格类型:" prop="cellType">
|
||||
<el-select v-model="searchFormParams.cellType" placeholder="请选择类型" clearable class="!w-[180px]">
|
||||
<el-option label="小格" :value="1" />
|
||||
<el-option label="中格" :value="2" />
|
||||
<el-option label="大格" :value="3" />
|
||||
<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>
|
||||
<div class="main flex">
|
||||
<!-- 左侧柜机列表 -->
|
||||
<div class="w-[200px] pr-4 border-r h-full left-list">
|
||||
<div class="text-lg font-bold mb-4 px-2">柜机列表</div>
|
||||
<div class="h-[calc(100vh-180px)] overflow-y-auto">
|
||||
<div class="cabinet-list">
|
||||
<div v-for="cabinet in cabinets" :key="cabinet.cabinetId"
|
||||
class="cabinet-item p-3 mb-2 cursor-pointer rounded hover:bg-gray-100 transition-colors"
|
||||
:class="{ 'bg-blue-50': searchFormParams.cabinetId === cabinet.cabinetId }"
|
||||
@click="searchFormParams.cabinetId = cabinet.cabinetId; onSearch()">
|
||||
{{ cabinet.cabinetName }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<PureTableBar title="柜体单元格管理" @refresh="getList">
|
||||
<template #buttons>
|
||||
<el-button type="primary" :icon="useRenderIcon(AddFill)" @click="modalVisible = true">
|
||||
新增单元格
|
||||
</el-button>
|
||||
<el-button type="danger" :icon="useRenderIcon(Delete)" :disabled="multipleSelection.length === 0"
|
||||
@click="handleBulkDelete">
|
||||
批量删除
|
||||
</el-button>
|
||||
</template>
|
||||
<el-table ref="tableRef" v-loading="loading" :data="dataList" row-key="cellId"
|
||||
@selection-change="handleSelectionChange" border>
|
||||
<el-table-column type="selection" width="55" />
|
||||
<el-table-column label="柜体ID" prop="cabinetId" width="100" />
|
||||
<el-table-column label="单元格号" prop="cellNo" width="120" />
|
||||
<el-table-column label="针脚号" prop="pinNo" width="120" />
|
||||
<el-table-column label="单元格类型" prop="cellType">
|
||||
<template #default="{ row }">
|
||||
{{ switchCellType(row.cellType) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="使用状态" prop="usageStatus" width="120">
|
||||
<template #default="{ row }">
|
||||
{{ { 1: '空闲', 2: '已占用' }[row.usageStatus] || '未知' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="可用状态" prop="availableStatus" width="120">
|
||||
<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 class="flex-1 pl-4">
|
||||
<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="柜体ID:" prop="cabinetId">
|
||||
<el-input v-model.number="searchFormParams.cabinetId" placeholder="请输入柜体ID" clearable class="!w-[200px]" />
|
||||
</el-form-item>
|
||||
<el-form-item label="单元格号:" prop="cellNo">
|
||||
<el-input v-model.number="searchFormParams.cellNo" placeholder="请输入单元格号" clearable class="!w-[180px]" />
|
||||
</el-form-item>
|
||||
<el-form-item label="单元格类型:" prop="cellType">
|
||||
<el-select v-model="searchFormParams.cellType" placeholder="请选择类型" clearable class="!w-[180px]">
|
||||
<el-option label="小格" :value="1" />
|
||||
<el-option label="中格" :value="2" />
|
||||
<el-option label="大格" :value="3" />
|
||||
<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">
|
||||
<template #buttons>
|
||||
<el-button type="primary" :icon="useRenderIcon(AddFill)" @click="modalVisible = true">
|
||||
新增单元格
|
||||
</el-button>
|
||||
<el-button type="danger" :icon="useRenderIcon(Delete)" :disabled="multipleSelection.length === 0"
|
||||
@click="handleBulkDelete">
|
||||
批量删除
|
||||
</el-button>
|
||||
</template>
|
||||
<el-table ref="tableRef" v-loading="loading" :data="dataList" row-key="cellId"
|
||||
@selection-change="handleSelectionChange" border>
|
||||
<el-table-column type="selection" width="55" />
|
||||
<el-table-column label="柜体ID" prop="cabinetId" width="100" />
|
||||
<el-table-column label="单元格号" prop="cellNo" width="120" />
|
||||
<el-table-column label="针脚号" prop="pinNo" width="120" />
|
||||
<el-table-column label="单元格类型" prop="cellType">
|
||||
<template #default="{ row }">
|
||||
{{ switchCellType(row.cellType) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="使用状态" prop="usageStatus" width="120">
|
||||
<template #default="{ row }">
|
||||
{{ { 1: '空闲', 2: '已占用' }[row.usageStatus] || '未知' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="可用状态" prop="availableStatus" width="120">
|
||||
<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>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
<style lang="scss" scoped>
|
||||
.flex {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.border-r {
|
||||
border-right: 1px solid #ebeef5;
|
||||
}
|
||||
|
||||
.left-list {
|
||||
background: #FFFFFF;
|
||||
padding: 15px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -111,6 +111,7 @@ getList();
|
|||
<PureTableBar title="格口开启记录" @refresh="getList">
|
||||
<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="cellId" width="120" />
|
||||
<el-table-column label="操作人" prop="name" width="120" />
|
||||
<el-table-column label="手机号" prop="mobile" width="120" />
|
||||
<el-table-column label="商品名称" prop="goodsName" width="180" />
|
||||
|
|
|
@ -12,6 +12,7 @@ import Qrcode from "@iconify-icons/ep/iphone";
|
|||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
import ShopFormModal from "./shop-form-modal.vue";
|
||||
import ReQrcode from "@/components/ReQrcode";
|
||||
import { copyTextToClipboard } from "@pureadmin/utils";
|
||||
|
||||
defineOptions({
|
||||
name: "Shop"
|
||||
|
@ -123,6 +124,12 @@ const showQrCode = (shopId: number) => {
|
|||
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();
|
||||
</script>
|
||||
|
||||
|
@ -188,6 +195,9 @@ getList();
|
|||
<ReQrcode :text="`http://wxshop.ab98.cn/shop-api/api/shop/wechatAuth?shopId=${currentShopId}`"
|
||||
:options="{ width: 200 }" />
|
||||
<div class="mt-2 text-sm text-gray-500">微信扫码访问</div>
|
||||
<el-button class="mt-2" type="primary" size="small" @click="copyLink">
|
||||
复制链接
|
||||
</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
|
|
|
@ -199,8 +199,7 @@ getList();
|
|||
<el-button type="primary" link :icon="useRenderIcon(EditPen)" @click="handleEdit(row)">
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button type="warning" link :icon="useRenderIcon('fluent:cell-phone-arrow-right-20-regular')"
|
||||
@click="goCellManagement(row)">
|
||||
<el-button type="warning" link :icon="useRenderIcon(EditPen)" @click="goCellManagement(row)">
|
||||
格口
|
||||
</el-button>
|
||||
<el-button type="warning" link :icon="useRenderIcon('ant-design:gateway-outlined')"
|
||||
|
|
|
@ -261,6 +261,7 @@ const handleClearGoods = async (row: CabinetCellDTO) => {
|
|||
<el-table ref="tableRef" v-loading="loading" :data="dataList" row-key="cellId"
|
||||
@selection-change="handleSelectionChange" border>
|
||||
<el-table-column label="格口ID" prop="cellId" width="80" />
|
||||
<el-table-column label="格口号" prop="cellNo" width="80" />
|
||||
<el-table-column label="商品图片" width="120">
|
||||
<template #default="{ row }">
|
||||
<el-image :src="row.coverImg" :preview-src-list="[row.coverImg]" :z-index="9999"
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
<script setup lang="ts">
|
||||
import { ref, watch } from "vue";
|
||||
import { ref, watch, onMounted } from "vue";
|
||||
import { PureTableBar } from "@/components/RePureTableBar";
|
||||
import { useRenderIcon } from "@/components/ReIcon/src/hooks";
|
||||
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 Refresh from "@iconify-icons/ep/refresh";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
@ -15,8 +16,10 @@ const route = useRoute();
|
|||
|
||||
const formRef = ref();
|
||||
const tableRef = ref();
|
||||
const cabinets = ref<SmartCabinetDTO[]>([]);
|
||||
|
||||
const searchFormParams = ref<OrderQuery>({
|
||||
cabinetId: null,
|
||||
orderId: null,
|
||||
cellId: null,
|
||||
status: null,
|
||||
|
@ -36,6 +39,11 @@ const pagination = ref({
|
|||
const loading = ref(false);
|
||||
const dataList = ref<OrderDTO[]>([]);
|
||||
|
||||
onMounted(async () => {
|
||||
const { data } = await allCabinets();
|
||||
cabinets.value = data;
|
||||
});
|
||||
|
||||
const getList = async () => {
|
||||
try {
|
||||
loading.value = true;
|
||||
|
@ -107,125 +115,138 @@ getList();
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<div class="main">
|
||||
<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="时间范围:">
|
||||
<div class="main flex">
|
||||
<!-- 左侧柜机列表 -->
|
||||
<div class="w-[200px] mr-4 bg-white rounded shadow p-4">
|
||||
<div class="text-lg font-bold mb-4">柜机列表</div>
|
||||
<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="开始时间"
|
||||
value-format="YYYY-MM-DD HH:mm:ss" class="!w-[200px]" />
|
||||
<span class="mx-2">至</span>
|
||||
<el-date-picker v-model="searchFormParams.endTime" type="date" placeholder="结束时间"
|
||||
value-format="YYYY-MM-DD HH:mm:ss" class="!w-[200px]" />
|
||||
</el-form-item> -->
|
||||
<el-form-item label="支付日期:">
|
||||
<el-date-picker v-model="searchFormParams.payTime" type="date" placeholder="支付时间"
|
||||
value-format="YYYY-MM-DD HH:mm:ss" class="!w-[200px]" />
|
||||
</el-form-item>
|
||||
<el-form-item label="订单编号:" prop="orderId">
|
||||
<el-input v-model="searchFormParams.orderId" placeholder="请输入订单编号" clearable class="!w-[200px]" />
|
||||
</el-form-item>
|
||||
<el-form-item label="格口ID:" prop="cellId">
|
||||
<el-input v-model="searchFormParams.cellId" placeholder="请输入格口ID" clearable class="!w-[200px]" />
|
||||
</el-form-item>
|
||||
<el-form-item label="订单状态:" prop="status">
|
||||
<el-select v-model="searchFormParams.status" placeholder="请选择状态" clearable class="!w-[180px]">
|
||||
<el-option label="待付款" :value="1" />
|
||||
<el-option label="已付款" :value="2" />
|
||||
<el-option label="已发货" :value="3" />
|
||||
<el-option label="已完成" :value="4" />
|
||||
<el-option label="已取消" :value="5" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="支付状态:" prop="payStatus">
|
||||
<el-select v-model="searchFormParams.payStatus" placeholder="请选择支付状态" clearable class="!w-[180px]">
|
||||
<el-option label="未支付" :value="1" />
|
||||
<el-option label="已支付" :value="2" />
|
||||
<el-option label="退款中" :value="3" />
|
||||
<el-option label="已退款" :value="4" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="支付方式:" prop="paymentMethod">
|
||||
<el-select v-model="searchFormParams.paymentMethod" placeholder="请选择支付方式" clearable class="!w-[180px]">
|
||||
<el-option label="微信支付" value="wechat" />
|
||||
<el-option label="余额支付" value="balance" />
|
||||
</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-button type="success" :loading="exportLoading" :icon="useRenderIcon('vscode-icons:file-type-excel2')"
|
||||
@click="handleExport">
|
||||
导出Excel
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-form-item label="支付日期:">
|
||||
<el-date-picker v-model="searchFormParams.payTime" type="date" placeholder="支付时间"
|
||||
value-format="YYYY-MM-DD HH:mm:ss" class="!w-[200px]" />
|
||||
</el-form-item>
|
||||
<el-form-item label="订单编号:" prop="orderId">
|
||||
<el-input v-model="searchFormParams.orderId" placeholder="请输入订单编号" clearable class="!w-[200px]" />
|
||||
</el-form-item>
|
||||
<el-form-item label="格口ID:" prop="cellId">
|
||||
<el-input v-model="searchFormParams.cellId" placeholder="请输入格口ID" clearable class="!w-[200px]" />
|
||||
</el-form-item>
|
||||
<el-form-item label="订单状态:" prop="status">
|
||||
<el-select v-model="searchFormParams.status" placeholder="请选择状态" clearable class="!w-[180px]">
|
||||
<el-option label="待付款" :value="1" />
|
||||
<el-option label="已付款" :value="2" />
|
||||
<el-option label="已发货" :value="3" />
|
||||
<el-option label="已完成" :value="4" />
|
||||
<el-option label="已取消" :value="5" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="支付状态:" prop="payStatus">
|
||||
<el-select v-model="searchFormParams.payStatus" placeholder="请选择支付状态" clearable class="!w-[180px]">
|
||||
<el-option label="未支付" :value="1" />
|
||||
<el-option label="已支付" :value="2" />
|
||||
<el-option label="退款中" :value="3" />
|
||||
<el-option label="已退款" :value="4" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="支付方式:" prop="paymentMethod">
|
||||
<el-select v-model="searchFormParams.paymentMethod" placeholder="请选择支付方式" clearable class="!w-[180px]">
|
||||
<el-option label="微信支付" value="wechat" />
|
||||
<el-option label="余额支付" value="balance" />
|
||||
</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-button type="success" :loading="exportLoading" :icon="useRenderIcon('vscode-icons:file-type-excel2')"
|
||||
@click="handleExport">
|
||||
导出Excel
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<PureTableBar title="订单列表" @refresh="getList">
|
||||
<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="商品名称" 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-column label="操作" width="100" fixed="right">
|
||||
<PureTableBar title="订单列表" @refresh="getList">
|
||||
<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="商品名称" 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-column label="操作" width="100" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button type="primary" link @click="handleDetail(row)">
|
||||
详情
|
||||
</el-button>
|
||||
</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="onSizeChange" @current-change="onCurrentChange" />
|
||||
</PureTableBar>
|
||||
</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="onSizeChange" @current-change="onCurrentChange" />
|
||||
</PureTableBar>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -0,0 +1,253 @@
|
|||
<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>
|
|
@ -0,0 +1,226 @@
|
|||
<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>
|
|
@ -60,10 +60,21 @@ watch(
|
|||
<el-col v-for="(item, index) in dataList" :key="item.id" :xs="24" :sm="12" :md="8" :lg="6">
|
||||
<el-card class="user-card">
|
||||
<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="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="balance">余额:¥{{ item.balance?.toFixed(2) }}</div>
|
||||
</div>
|
||||
|
|
Loading…
Reference in New Issue