Compare commits
13 Commits
210386a036
...
7319fae447
Author | SHA1 | Date |
---|---|---|
|
7319fae447 | |
|
33408d023d | |
|
908ff3e191 | |
|
dd957140e4 | |
|
9862f8bff8 | |
|
8a3cd9fec9 | |
|
adddd98d7d | |
|
fc6889cd10 | |
|
cab3eeaecc | |
|
0bb25784f0 | |
|
28789ce95d | |
|
c73260a207 | |
|
2ca1a758a4 |
|
@ -43,6 +43,8 @@ export interface SmartCabinetDTO {
|
|||
operator?: string;
|
||||
/** 归属类型(0-借还柜 1-固资通) */
|
||||
belongType?: number;
|
||||
usedCells?: number;
|
||||
availableCells?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -4,6 +4,15 @@ import { UserDTO } from "../system/user";
|
|||
/**
|
||||
* 企业微信用户信息
|
||||
*/
|
||||
export interface QyUserStatsDTO {
|
||||
/** 剩余借呗 */
|
||||
balance?: number;
|
||||
/** 已使用借呗 */
|
||||
useBalance?: number;
|
||||
/** 借呗额度 */
|
||||
balanceLimit?: number;
|
||||
}
|
||||
|
||||
export interface QyUserDTO {
|
||||
/** 用户ID(导出列:用户ID) */
|
||||
id?: number;
|
||||
|
@ -52,8 +61,12 @@ export interface QyUserDTO {
|
|||
corpid?: string;
|
||||
/** 应用ID(导出列:应用ID) */
|
||||
appid?: string;
|
||||
/** 用户余额 */
|
||||
/** 剩余借呗 */
|
||||
balance?: number;
|
||||
/** 已使用借呗 */
|
||||
useBalance?: number;
|
||||
/** 借呗额度 */
|
||||
balanceLimit?: number;
|
||||
/** 角色id */
|
||||
roleId?: number;
|
||||
/** 角色 */
|
||||
|
@ -77,8 +90,12 @@ export interface AddQyUserCommand {
|
|||
mobile?: string;
|
||||
department?: string;
|
||||
corpid?: string;
|
||||
/** 用户余额 */
|
||||
/** 剩余借呗 */
|
||||
balance?: number;
|
||||
/** 已使用借呗 */
|
||||
useBalance?: number;
|
||||
/** 借呗额度 */
|
||||
balanceLimit?: number;
|
||||
roleId?: number;
|
||||
sysRoleId?: number;
|
||||
}
|
||||
|
@ -131,7 +148,7 @@ export const getQyUserDetailApi = (id: number) => {
|
|||
};
|
||||
|
||||
export const getTotalBalanceApi = (corpid: string) => {
|
||||
return http.request<ResponseData<number>>("get", `/qywx/users/getTotalBalance`, {
|
||||
return http.request<ResponseData<QyUserStatsDTO>>("get", `/qywx/users/getTotalBalance`, {
|
||||
params: { corpid }
|
||||
});
|
||||
};
|
|
@ -30,6 +30,16 @@ export function getRoleListApi(params: RoleQuery) {
|
|||
);
|
||||
}
|
||||
|
||||
export function getRoleAllApi(params: RoleQuery) {
|
||||
return http.request<ResponseData<RoleDTO[]>>(
|
||||
"get",
|
||||
"/system/role/all",
|
||||
{
|
||||
params
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export function getRoleInfoApi(roleId: number) {
|
||||
return http.request<ResponseData<RoleDTO>>("get", "/system/role/" + roleId);
|
||||
}
|
||||
|
|
|
@ -1,38 +1,38 @@
|
|||
export const CabinetImgMap = {
|
||||
1: {
|
||||
img: "cabinet_16.jpg",
|
||||
name: "16口机柜",
|
||||
name: "16格柜",
|
||||
},
|
||||
2: {
|
||||
img: "cabinet_20.jpg",
|
||||
name: "20口机柜",
|
||||
name: "20格柜",
|
||||
},
|
||||
3: {
|
||||
img: "cabinet_22.jpg",
|
||||
name: "22口机柜",
|
||||
name: "22格柜",
|
||||
},
|
||||
4: {
|
||||
img: "cabinet_24.jpg",
|
||||
name: "24口机柜",
|
||||
name: "24格柜",
|
||||
},
|
||||
5: {
|
||||
img: "cabinet_40.jpg",
|
||||
name: "40口机柜",
|
||||
name: "40格柜",
|
||||
},
|
||||
6: {
|
||||
img: "cabinet_48.jpg",
|
||||
name: "48口机柜",
|
||||
name: "48格柜",
|
||||
},
|
||||
7: {
|
||||
img: "cabinet_60.jpg",
|
||||
name: "60口机柜",
|
||||
name: "60格柜",
|
||||
},
|
||||
8: {
|
||||
img: "cabinet_120.jpg",
|
||||
name: "120口机柜",
|
||||
name: "120格柜",
|
||||
},
|
||||
9: {
|
||||
img: "cabinet_4.jpg",
|
||||
name: "4口机柜",
|
||||
name: "4格柜",
|
||||
},
|
||||
}
|
|
@ -204,12 +204,12 @@ const switchCellType = (cellType: number) => {
|
|||
<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 @keyup.enter.native.prevent="onSearch" v-model.number="searchFormParams.cabinetId"
|
||||
placeholder="请输入柜体ID" clearable class="!w-[200px]" />
|
||||
<el-input @keydown.enter.prevent="onSearch" v-model.number="searchFormParams.cabinetId" placeholder="请输入柜体ID"
|
||||
clearable class="!w-[200px]" />
|
||||
</el-form-item>
|
||||
<el-form-item label="单元格号:" prop="cellNo">
|
||||
<el-input @keyup.enter.native.prevent="onSearch" v-model.number="searchFormParams.cellNo"
|
||||
placeholder="请输入单元格号" clearable class="!w-[180px]" />
|
||||
<el-input @keydown.enter.prevent="onSearch" 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]">
|
||||
|
|
|
@ -120,35 +120,30 @@ getList();
|
|||
<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="服务地址:" prop="serverUrl">
|
||||
<el-input @keyup.enter.native.prevent="onSearch" v-model="searchFormParams.serverUrl" placeholder="请输入服务地址"
|
||||
clearable class="!w-[200px]" />
|
||||
class="search-form bg-bg_color flex w-[99/100] pl-[22px] pt-[12px]">
|
||||
<el-form-item prop="serverUrl">
|
||||
<el-input @keydown.enter.prevent="onSearch" v-model="searchFormParams.serverUrl" placeholder="请输入服务地址" clearable
|
||||
class="!w-[200px]" />
|
||||
</el-form-item>
|
||||
<el-form-item label="用户名:" prop="username">
|
||||
<el-input @keyup.enter.native.prevent="onSearch" v-model="searchFormParams.username" placeholder="请输入用户名"
|
||||
clearable class="!w-[200px]" />
|
||||
<el-form-item prop="username">
|
||||
<el-input @keydown.enter.prevent="onSearch" v-model="searchFormParams.username" placeholder="请输入用户名" clearable
|
||||
class="!w-[200px]" />
|
||||
</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-form-item>
|
||||
<el-form-item class="space-item">
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" :icon="useRenderIcon(AddFill)" @click="modalVisible = true">
|
||||
新增服务
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<PureTableBar title="MQTT服务管理" @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>
|
||||
<div class="table-container">
|
||||
<el-table ref="tableRef" v-loading="loading" :data="dataList" row-key="id"
|
||||
@selection-change="handleSelectionChange" border>
|
||||
<el-table-column type="selection" width="55" />
|
||||
|
@ -174,10 +169,41 @@ getList();
|
|||
</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>
|
||||
@size-change="onSizeChange" @current-change="onCurrentChange" class="pagination" />
|
||||
</div>
|
||||
<MqttServerFormModal :visible="modalVisible" @update:visible="val => modalVisible = val" @refresh="handleRefresh" />
|
||||
<MqttServerFormModal :visible="editVisible" :row="currentRow" @update:visible="val => editVisible = val"
|
||||
@refresh="handleRefresh" />
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.search-form {
|
||||
:deep(.el-form-item) {
|
||||
margin-bottom: 12px;
|
||||
margin-right: 12px;
|
||||
}
|
||||
}
|
||||
.space-item {
|
||||
flex: 1;
|
||||
width: 100%;
|
||||
}
|
||||
.table-container {
|
||||
margin-top: 8px;
|
||||
background-color: var(--el-bg-color);
|
||||
border-radius: 4px;
|
||||
padding: 16px;
|
||||
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.el-table {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.pagination {
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -82,40 +82,40 @@ getList();
|
|||
<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="cellId">
|
||||
<el-input @keyup.enter.native.prevent="onSearch" v-model="searchFormParams.cellId" placeholder="请输入格口ID"
|
||||
clearable class="!w-[200px]" />
|
||||
class="search-form bg-bg_color flex w-[99/100] pl-[22px] pt-[12px]">
|
||||
<el-form-item prop="cellId">
|
||||
<el-input @keydown.enter.prevent="onSearch" v-model="searchFormParams.cellId" placeholder="请输入格口ID" clearable
|
||||
class="!w-[200px]" />
|
||||
</el-form-item>
|
||||
<el-form-item label="操作类型:" prop="operationType">
|
||||
<el-form-item prop="operationType">
|
||||
<el-select v-model="searchFormParams.operationType" placeholder="请选择类型" clearable class="!w-[180px]">
|
||||
<el-option label="用户操作" :value="1" />
|
||||
<el-option label="管理员操作" :value="2" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="操作状态:" prop="status">
|
||||
<el-form-item prop="status">
|
||||
<el-select v-model="searchFormParams.status" placeholder="请选择状态" clearable class="!w-[180px]">
|
||||
<el-option label="正常" :value="1" />
|
||||
<el-option label="操作失败" :value="2" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" :icon="useRenderIcon(Search)" @click="onSearch">
|
||||
<el-button type="primary" :icon="useRenderIcon(Search)" @click="onSearch" class="mr-2">
|
||||
搜索
|
||||
</el-button>
|
||||
<el-button :icon="useRenderIcon(Refresh)" @click="resetForm">
|
||||
<el-button :icon="useRenderIcon(Refresh)" @click="resetForm" class="mr-2">
|
||||
重置
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<PureTableBar title="格口开启记录" @refresh="getList">
|
||||
<div class="table-container">
|
||||
<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" />
|
||||
<el-table-column label="商品名称" prop="goodsName" />
|
||||
<el-table-column label="操作类型" prop="operationType" width="120">
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="row.operationType === 1 ? 'success' : 'warning'">
|
||||
|
@ -134,13 +134,34 @@ getList();
|
|||
</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>
|
||||
@size-change="onSizeChange" @current-change="onCurrentChange" class="pagination" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.right-btn {
|
||||
margin: 0;
|
||||
<style scoped lang="scss">
|
||||
.search-form {
|
||||
:deep(.el-form-item) {
|
||||
margin-bottom: 12px;
|
||||
margin-right: 12px;
|
||||
}
|
||||
}
|
||||
.table-container {
|
||||
margin-top: 8px;
|
||||
background-color: var(--el-bg-color);
|
||||
border-radius: 4px;
|
||||
padding: 16px;
|
||||
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.el-table {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.pagination {
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -93,7 +93,7 @@ const handleBulkDelete = async () => {
|
|||
|
||||
try {
|
||||
await ElMessageBox.confirm(
|
||||
`确认删除选中的${multipleSelection.value.length}家商店吗?`,
|
||||
`确认删除选中的${multipleSelection.value.length}家地址吗?`,
|
||||
"警告",
|
||||
{ confirmButtonText: "确定", cancelButtonText: "取消", type: "warning" }
|
||||
);
|
||||
|
@ -136,36 +136,32 @@ getList();
|
|||
<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="商店名称:" prop="shopName">
|
||||
<el-input @keyup.enter.native.prevent="onSearch" v-model="searchFormParams.shopName" placeholder="请输入商店名称"
|
||||
clearable class="!w-[200px]" />
|
||||
class="search-form bg-bg_color flex w-[99/100] pl-[22px] pt-[12px]">
|
||||
<el-form-item prop="shopName">
|
||||
<el-input @keydown.enter.prevent="onSearch" v-model="searchFormParams.shopName" placeholder="请输入地址名称" clearable
|
||||
class="!w-[200px]" />
|
||||
</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-form-item>
|
||||
<el-form-item class="space-item">
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" :icon="useRenderIcon(AddFill)" @click="modalVisible = true"
|
||||
style="margin-right: 10px;">
|
||||
新增地址
|
||||
</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>
|
||||
<div class="table-container">
|
||||
<el-table ref="tableRef" v-loading="loading" :data="dataList" row-key="id"
|
||||
@selection-change="handleSelectionChange" border>
|
||||
<el-table-column type="selection" width="55" />
|
||||
<el-table-column label="商店ID" prop="shopId" width="100" />
|
||||
<el-table-column label="商店名称" prop="shopName" />
|
||||
<el-table-column label="地址ID" prop="shopId" width="100" />
|
||||
<el-table-column label="地址名称" prop="shopName" />
|
||||
<el-table-column label="操作" width="150" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button type="primary" link :icon="useRenderIcon(EditPen)" @click="handleEdit(row)">
|
||||
|
@ -186,8 +182,8 @@ getList();
|
|||
</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>
|
||||
@size-change="onSizeChange" @current-change="onCurrentChange" class="pagination" />
|
||||
</div>
|
||||
<ShopFormModal :visible="modalVisible" @update:visible="val => modalVisible = val" @refresh="handleRefresh" />
|
||||
<ShopFormModal :visible="editVisible" :row="currentRow" @update:visible="val => editVisible = val"
|
||||
@refresh="handleRefresh" />
|
||||
|
@ -202,4 +198,35 @@ getList();
|
|||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.search-form {
|
||||
:deep(.el-form-item) {
|
||||
margin-bottom: 12px;
|
||||
margin-right: 12px;
|
||||
}
|
||||
}
|
||||
.space-item {
|
||||
flex: 1;
|
||||
width: 100%;
|
||||
}
|
||||
.table-container {
|
||||
margin-top: 8px;
|
||||
background-color: var(--el-bg-color);
|
||||
border-radius: 4px;
|
||||
padding: 16px;
|
||||
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.el-table {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.pagination {
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -23,7 +23,7 @@ const formData = ref<UpdateShopCommand>({
|
|||
});
|
||||
|
||||
const rules = {
|
||||
shopName: [{ required: true, message: "请输入商店名称", trigger: "blur" }]
|
||||
shopName: [{ required: true, message: "请输入地址名称", trigger: "blur" }]
|
||||
};
|
||||
|
||||
watch(
|
||||
|
@ -70,14 +70,14 @@ const handleClose = () => {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<el-dialog :title="formData.shopId ? '编辑商店' : '新增商店'" :model-value="visible" @update:model-value="handleClose"
|
||||
<el-dialog :title="formData.shopId ? '编辑地址' : '新增地址'" :model-value="visible" @update:model-value="handleClose"
|
||||
width="600px">
|
||||
<el-form ref="formRef" :model="formData" :rules="rules" label-width="100px">
|
||||
<el-form-item label="商店ID" prop="shopId" v-if="formData.shopId">
|
||||
<el-form-item label="地址ID" prop="shopId" v-if="formData.shopId">
|
||||
<el-input v-model="formData.shopId" :disabled="true" />
|
||||
</el-form-item>
|
||||
<el-form-item label="商店名称" prop="shopName">
|
||||
<el-input v-model="formData.shopName" placeholder="请输入商店名称" />
|
||||
<el-form-item label="地址名称" prop="shopName">
|
||||
<el-input v-model="formData.shopName" placeholder="请输入地址名称" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
|
|
|
@ -304,19 +304,19 @@ onMounted(() => {
|
|||
<el-descriptions :column="2" border>
|
||||
<el-descriptions-item label="主柜ID">{{ cabinetInfo.mainCabinet || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="主柜名称">{{ cabinetInfo.mainCabinetName || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="归属类型">
|
||||
<!-- <el-descriptions-item label="归属类型">
|
||||
{{ cabinetInfo.belongType === 0 ? '借还柜' : '固资通' }}
|
||||
</el-descriptions-item>
|
||||
</el-descriptions-item> -->
|
||||
<el-descriptions-item label="MQTT服务器ID">{{ cabinetInfo.mqttServerId || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="操作员">{{ cabinetInfo.operator || '-' }}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</div>
|
||||
|
||||
<div class="cell-details" v-if="activeTab === 'cells'">
|
||||
<div style="display: flex; justify-content: space-between; margin-bottom: 16px;">
|
||||
<div style="display: flex; justify-content: space-between; margin-bottom: 0px;">
|
||||
<el-form :inline="true" :model="searchCellParams" class="search-form">
|
||||
<el-form-item>
|
||||
<el-input @keyup.enter.native.prevent="fetchCellList" v-model="searchCellParams.goodsName"
|
||||
<el-input @keydown.enter.prevent="fetchCellList" v-model="searchCellParams.goodsName"
|
||||
placeholder="请输入商品名称" clearable class="!w-[180px]" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
|
@ -421,17 +421,21 @@ onMounted(() => {
|
|||
<ShopConfigModal v-model="shopConfigVisible" :cabinet-id="cabinetId" @refresh="fetchCabinetDetail" />
|
||||
<MainCabinetConfigModal v-model="mainCabinetConfigVisible" :cabinet-id="cabinetId"
|
||||
@refresh="fetchCabinetDetail" />
|
||||
<el-drawer v-model="editCabinetDrawerVisible" title="编辑柜体" size="30%" direction="rtl">
|
||||
<el-drawer v-model="editCabinetDrawerVisible"
|
||||
title="编辑柜体" size="30%" direction="rtl">
|
||||
<EditCabinetDrawer v-model="editCabinetDrawerVisible" :cabinet-info="cabinetInfo"
|
||||
@refresh="fetchCabinetDetail" />
|
||||
</el-drawer>
|
||||
<el-drawer v-model="goodsConfigVisible" title="配置商品" size="50%" direction="rtl">
|
||||
<el-drawer v-model="goodsConfigVisible" title="配置商品"
|
||||
size="50%" direction="rtl">
|
||||
<CabinetGoodsConfigModal v-model="goodsConfigVisible" :cell-id="currentCellId" @refresh="fetchCellList" />
|
||||
</el-drawer>
|
||||
<el-drawer v-model="cellFormVisible" title="新增格口" size="30%" direction="rtl">
|
||||
<el-drawer v-model="cellFormVisible" title="新增格口"
|
||||
size="30%" direction="rtl">
|
||||
<CellFormModal v-model="cellFormVisible" :initial-cabinet-id="cabinetId" @refresh="fetchCellList" />
|
||||
</el-drawer>
|
||||
<el-drawer v-model="cellEditVisible" title="编辑格口" size="30%" direction="rtl">
|
||||
<el-drawer v-model="cellEditVisible" title="编辑格口"
|
||||
size="30%" direction="rtl">
|
||||
<CellEditModal v-model="cellEditVisible" :row="currentCell" @refresh="fetchCellList" />
|
||||
</el-drawer>
|
||||
</div>
|
||||
|
@ -439,6 +443,21 @@ onMounted(() => {
|
|||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
:deep(.el-tabs__header) {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
:deep(.el-drawer__header) {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
:deep(.el-drawer__body) {
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.el-form-item {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.detail-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
@ -485,4 +504,7 @@ onMounted(() => {
|
|||
margin-bottom: 0px;
|
||||
}
|
||||
}
|
||||
.pagination {
|
||||
margin-top: 10px;
|
||||
}
|
||||
</style>
|
|
@ -96,12 +96,12 @@ watch(() => props.cabinetInfo, (newVal) => {
|
|||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="归属类型" prop="belongType">
|
||||
<!-- <el-form-item label="归属类型" prop="belongType">
|
||||
<el-select v-model="formData.belongType" placeholder="请选择归属类型">
|
||||
<el-option label="借还柜" :value="0" />
|
||||
<el-option label="固资通" :value="1" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form-item> -->
|
||||
|
||||
<el-form-item>
|
||||
<el-button type="primary" :icon="useRenderIcon(Confirm)" @click="handleConfirm">
|
||||
|
|
|
@ -92,7 +92,7 @@ onMounted(() => {
|
|||
<el-form ref="formRef" :inline="true" :model="searchFormParams"
|
||||
class="search-form bg-bg_color flex w-[99/100] pl-[22px] pt-[12px]">
|
||||
<el-form-item label="" prop="cabinetName">
|
||||
<el-input @keyup.enter.native.prevent="onSearch" v-model="searchFormParams.cabinetName" placeholder="请输入柜体名称"
|
||||
<el-input @keydown.enter.prevent="onSearch" v-model="searchFormParams.cabinetName" placeholder="请输入柜体名称"
|
||||
clearable class="!w-[200px]" />
|
||||
</el-form-item>
|
||||
<el-form-item label="" prop="cabinetType">
|
||||
|
@ -124,17 +124,23 @@ onMounted(() => {
|
|||
<div class="grid-container">
|
||||
<el-row :gutter="12">
|
||||
<el-col v-for="(item, index) in dataList" :key="item.cabinetId" :xs="24" :sm="12" :md="8" :lg="4" :xl="4">
|
||||
<el-card class="cabinet-card" :body-style="{ padding: '8px 20px' }">
|
||||
<el-card class="cabinet-card" :body-style="{ padding: '8px 10px' }">
|
||||
<div class="card-content">
|
||||
<img :src="`${IMG_PATH}img/cabinet/${CabinetImgMap[item.templateNo]?.img || 'default.jpg'}`"
|
||||
class="cabinet-image" />
|
||||
<el-descriptions class="cabinet-info" :column="2">
|
||||
<el-descriptions-item class="name" :span="2">柜体名称:{{ item.cabinetName }}
|
||||
<el-descriptions class="cabinet-info" :column="1">
|
||||
<el-descriptions-item class="name">名称:{{ item.cabinetName }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item class="name">模式:{{ '支付模式' }}
|
||||
</el-descriptions-item>
|
||||
<!-- <div class="type">柜体类型:{{ item.cabinetType === 0 ? '主柜' : '副柜' }}</div> -->
|
||||
<el-descriptions-item class="template">模板:{{ CabinetImgMap[item.templateNo]?.name || '-' }}
|
||||
<el-descriptions-item class="template">格式:{{ CabinetImgMap[item.templateNo]?.name || '-' }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item class="shop">商店:{{ item.shopName || '-' }}
|
||||
<el-descriptions-item class="shop">已用:{{ item.usedCells }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item class="shop">未用:{{ item.availableCells }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item class="shop">柜址:{{ item.shopName || '-' }}
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</div>
|
||||
|
@ -176,7 +182,7 @@ onMounted(() => {
|
|||
justify-content: space-between;
|
||||
|
||||
.cabinet-image {
|
||||
width: 100%;
|
||||
width: 55%;
|
||||
height: 200px;
|
||||
object-fit: contain;
|
||||
border-radius: 4px;
|
||||
|
@ -185,10 +191,13 @@ onMounted(() => {
|
|||
|
||||
.card-content {
|
||||
flex: 1;
|
||||
margin: 15px 0px;
|
||||
margin: 0px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
||||
.cabinet-info {
|
||||
text-align: left;
|
||||
padding: 16px 0px;
|
||||
|
||||
.name,
|
||||
.type,
|
||||
|
@ -198,7 +207,7 @@ onMounted(() => {
|
|||
width: 100%;
|
||||
font-size: 14px;
|
||||
color: #606266;
|
||||
margin-bottom: 6px;
|
||||
margin-bottom: 12px;
|
||||
line-height: 1;
|
||||
text-align: left;
|
||||
}
|
||||
|
|
|
@ -93,12 +93,12 @@ const templateOptions = Object.entries(CabinetImgMap).map(([value, item]) => ({
|
|||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="归属类型" prop="belongType">
|
||||
<!-- <el-form-item label="归属类型" prop="belongType">
|
||||
<el-select v-model="formData.belongType" placeholder="请选择归属类型">
|
||||
<el-option label="借还柜" :value="0" />
|
||||
<el-option label="固资通" :value="1" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form-item> -->
|
||||
|
||||
<el-form-item>
|
||||
<el-button type="primary" :icon="useRenderIcon(Confirm)" @click="handleConfirm">
|
||||
|
|
|
@ -160,7 +160,7 @@ getList();
|
|||
<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="cabinetName">
|
||||
<el-input @keyup.enter.native.prevent="onSearch" v-model="searchFormParams.cabinetName" placeholder="请输入柜体名称"
|
||||
<el-input @keydown.enter.prevent="onSearch" v-model="searchFormParams.cabinetName" placeholder="请输入柜体名称"
|
||||
clearable class="!w-[200px]" />
|
||||
</el-form-item>
|
||||
<el-form-item label="柜体类型:" prop="cabinetType">
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<script setup lang="ts">
|
||||
import { ref } from "vue";
|
||||
import { PureTableBar } from "@/components/RePureTableBar";
|
||||
|
||||
import { useRenderIcon } from "@/components/ReIcon/src/hooks";
|
||||
import { getQyUserListApi, getTotalBalanceApi, QyUserDTO, QyUserQuery } from "@/api/qy/qyUser";
|
||||
import Search from "@iconify-icons/ep/search";
|
||||
|
@ -17,9 +17,10 @@ const formRef = ref();
|
|||
const tableRef = ref();
|
||||
|
||||
// 搜索表单
|
||||
const searchFormParams = ref<QyUserQuery>({
|
||||
const searchFormParams = ref<QyUserQuery & { search?: string }>({
|
||||
name: null,
|
||||
mobile: null,
|
||||
search: null,
|
||||
corpid: wxStore.corpid, // 企业ID
|
||||
balancePage: 1
|
||||
});
|
||||
|
@ -33,12 +34,31 @@ const pagination = ref({
|
|||
|
||||
const loading = ref(false);
|
||||
const dataList = ref<QyUserDTO[]>([]);
|
||||
const totalBalance = ref(0);
|
||||
|
||||
const formatCurrency = (value) => {
|
||||
return value.toLocaleString('en-US', {
|
||||
minimumFractionDigits: 0,
|
||||
maximumFractionDigits: 2
|
||||
}) || 0 + '元';
|
||||
};
|
||||
|
||||
const balanceData = ref([
|
||||
{
|
||||
name: '用户总借呗', value: '0元',
|
||||
},
|
||||
{
|
||||
name: '已用总借呗', value: '0元',
|
||||
},
|
||||
{
|
||||
name: '剩余总借呗', value: '0元',
|
||||
},
|
||||
]);
|
||||
|
||||
// 获取用户余额列表
|
||||
const getList = async () => {
|
||||
try {
|
||||
loading.value = true;
|
||||
handleSearchInput(searchFormParams.value.search);
|
||||
const { data } = await getQyUserListApi({
|
||||
...searchFormParams.value,
|
||||
pageSize: pagination.value.pageSize,
|
||||
|
@ -51,6 +71,19 @@ const getList = async () => {
|
|||
}
|
||||
};
|
||||
|
||||
const handleSearchInput = (value) => {
|
||||
// 手机号正则
|
||||
const phoneRegex = /^1[3-9]\d{9}$/;
|
||||
|
||||
if (phoneRegex.test(value)) {
|
||||
searchFormParams.value.mobile = value;
|
||||
searchFormParams.value.name = '';
|
||||
} else {
|
||||
searchFormParams.value.name = value;
|
||||
searchFormParams.value.mobile = '';
|
||||
}
|
||||
};
|
||||
|
||||
// 搜索
|
||||
const onSearch = () => {
|
||||
pagination.value.currentPage = 1;
|
||||
|
@ -70,7 +103,9 @@ const handlePaginationChange = () => getList();
|
|||
const getTotalBalance = async () => {
|
||||
try {
|
||||
const { data } = await getTotalBalanceApi(wxStore.corpid);
|
||||
totalBalance.value = data;
|
||||
balanceData.value[0].value = formatCurrency(data.balanceLimit);
|
||||
balanceData.value[1].value = formatCurrency(data.useBalance);
|
||||
balanceData.value[2].value = formatCurrency(data.balance);
|
||||
} catch (error) {
|
||||
console.error('获取总余额失败:', error);
|
||||
}
|
||||
|
@ -83,15 +118,26 @@ getList().then(() => getTotalBalance());
|
|||
|
||||
<template>
|
||||
<div class="main">
|
||||
<el-form ref="formRef" :inline="true" :model="searchFormParams"
|
||||
<el-row :gutter="12" class="data-section">
|
||||
<!-- 商店数据 -->
|
||||
<el-col :span="4" v-for="item in balanceData" :key="item.name">
|
||||
<el-card shadow="never" :body-style="{ padding: ' 20px 0' }" class="todo-card">
|
||||
<div class="todo-content">
|
||||
<div class="todo-name">{{ item.name }}</div>
|
||||
<div class="todo-count">{{ item.value }}</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<!-- <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 @keyup.enter.native.prevent="onSearch" v-model="searchFormParams.name" placeholder="请输入姓名" clearable
|
||||
<el-input @keydown.enter.prevent="onSearch" v-model="searchFormParams.name" placeholder="请输入姓名" clearable
|
||||
class="!w-[180px]" />
|
||||
</el-form-item>
|
||||
<el-form-item label="手机号:" prop="mobile">
|
||||
<el-input @keyup.enter.native.prevent="onSearch" v-model="searchFormParams.mobile" placeholder="请输入手机号"
|
||||
clearable class="!w-[180px]" />
|
||||
<el-input @keydown.enter.prevent="onSearch" v-model="searchFormParams.mobile" placeholder="请输入手机号" clearable
|
||||
class="!w-[180px]" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" :icon="useRenderIcon(Search)" @click="onSearch">
|
||||
|
@ -101,27 +147,95 @@ getList().then(() => getTotalBalance());
|
|||
重置
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-form> -->
|
||||
|
||||
<div class="table-container">
|
||||
<el-form ref="formRef" :inline="true" :model="searchFormParams" class="search-form bg-bg_color w-[99/100]">
|
||||
<el-form-item prop="search">
|
||||
<el-input v-model="searchFormParams.search" placeholder="请输入姓名/手机号" clearable class="!w-[300px]"
|
||||
@keydown.enter.prevent="onSearch" @change="handleSearchInput" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" :icon="useRenderIcon(Search)" @click="onSearch">
|
||||
搜索
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<PureTableBar :title="`用户总余额: ${totalBalance}元`" @refresh="getList">
|
||||
<el-table ref="tableRef" v-loading="loading" :data="dataList" border>
|
||||
<el-table-column label="用户ID" prop="id" width="80" />
|
||||
<el-table-column label="姓名" prop="name" width="100" />
|
||||
<el-table-column label="余额" prop="balance" width="130">
|
||||
<template #default="{ row }">{{ row.balance || 0 }}元</template>
|
||||
<el-table-column label="姓名" prop="name" width="200" />
|
||||
<el-table-column label="借呗" prop="balanceLimit" width="230">
|
||||
<template #default="{ row }">{{ formatCurrency(row.balanceLimit) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="已用借呗" prop="useBalance" width="230">
|
||||
<template #default="{ row }">{{ formatCurrency(row.useBalance) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="剩余借呗" prop="balance" width="230">
|
||||
<template #default="{ row }">{{ formatCurrency(row.balance) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="手机号" prop="mobile" />
|
||||
<!-- <el-table-column label="所属部门" prop="department" /> -->
|
||||
</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="handlePaginationChange" @current-change="handlePaginationChange" />
|
||||
</PureTableBar>
|
||||
<el-pagination class="table-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="handlePaginationChange"
|
||||
@current-change="handlePaginationChange" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.main {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.data-section {
|
||||
margin-bottom: 0;
|
||||
|
||||
.todo-card {
|
||||
height: 100%;
|
||||
border: none;
|
||||
|
||||
.todo-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: start;
|
||||
justify-content: center;
|
||||
padding: 10px 0 10px 26px;
|
||||
|
||||
.todo-name {
|
||||
font-size: 14px;
|
||||
color: var(--el-text-color-regular);
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.todo-icon {
|
||||
margin-bottom: 10px;
|
||||
color: var(--el-color-primary);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.table-container {
|
||||
margin-top: 8px;
|
||||
background-color: var(--el-bg-color);
|
||||
border-radius: 4px;
|
||||
padding: 16px;
|
||||
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.el-table {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.table-pagination {
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -127,41 +127,41 @@ getList();
|
|||
<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="审批时间:">
|
||||
class="search-form bg-bg_color flex w-[99/100] pl-[22px] pt-[12px]">
|
||||
<el-form-item>
|
||||
<el-date-picker v-model="searchFormParams.approvalTime" type="date" placeholder="选择审批时间"
|
||||
value-format="YYYY-MM-DD HH:mm:ss" class="!w-[200px]" />
|
||||
</el-form-item>
|
||||
<el-form-item label="审批ID:" prop="approvalId">
|
||||
<el-input @keyup.enter.native.prevent="onSearch" v-model.number="searchFormParams.approvalId"
|
||||
placeholder="请输入审批ID" clearable class="!w-[180px]" />
|
||||
</el-form-item>
|
||||
<el-form-item label="订单ID:" prop="orderId">
|
||||
<el-input @keyup.enter.native.prevent="onSearch" v-model.number="searchFormParams.orderId" placeholder="请输入订单ID"
|
||||
<el-form-item prop="approvalId">
|
||||
<el-input @keydown.enter.prevent="onSearch" v-model.number="searchFormParams.approvalId" placeholder="请输入审批ID"
|
||||
clearable class="!w-[180px]" />
|
||||
</el-form-item>
|
||||
<el-form-item label="商品ID:" prop="goodsId">
|
||||
<el-input @keyup.enter.native.prevent="onSearch" v-model.number="searchFormParams.goodsId" placeholder="请输入商品ID"
|
||||
<el-form-item prop="orderId">
|
||||
<el-input @keydown.enter.prevent="onSearch" v-model.number="searchFormParams.orderId" placeholder="请输入订单ID"
|
||||
clearable class="!w-[180px]" />
|
||||
</el-form-item>
|
||||
<el-form-item label="状态:" prop="status">
|
||||
<el-select v-model="searchFormParams.status" placeholder="请选择状态" clearable class="!w-[180px]">
|
||||
<el-form-item prop="goodsId">
|
||||
<el-input @keydown.enter.prevent="onSearch" v-model.number="searchFormParams.goodsId" placeholder="请输入商品ID"
|
||||
clearable class="!w-[180px]" />
|
||||
</el-form-item>
|
||||
<el-form-item 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-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="支付方式:" prop="paymentMethod">
|
||||
<el-form-item 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 type="primary" :icon="useRenderIcon(Search)" @click="onSearch" class="mr-2">
|
||||
搜索
|
||||
</el-button>
|
||||
<el-button :icon="useRenderIcon(Refresh)" @click="resetForm">
|
||||
<el-button :icon="useRenderIcon(Refresh)" @click="resetForm" class="mr-2">
|
||||
重置
|
||||
</el-button>
|
||||
<el-button type="success" :loading="exportLoading" :icon="useRenderIcon('vscode-icons:file-type-excel2')"
|
||||
|
@ -171,13 +171,7 @@ getList();
|
|||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<PureTableBar title="退货审批列表" @refresh="getList">
|
||||
<template #buttons>
|
||||
<el-button type="danger" :icon="useRenderIcon(Delete)" :disabled="multipleSelection.length === 0"
|
||||
@click="handleBulkDelete">
|
||||
批量删除
|
||||
</el-button>
|
||||
</template>
|
||||
<div class="table-container">
|
||||
<el-table ref="tableRef" v-loading="loading" :data="dataList" row-key="approvalId"
|
||||
@selection-change="rows => multipleSelection = rows.map(r => r.approvalId)" border>
|
||||
<el-table-column label="审批ID" prop="approvalId" width="80" />
|
||||
|
@ -185,7 +179,7 @@ getList();
|
|||
<el-table-column label="商品ID" prop="goodsId" width="80" />
|
||||
<el-table-column label="用户姓名" prop="name" width="100" />
|
||||
<el-table-column label="手机号" prop="mobile" width="120" />
|
||||
<el-table-column label="商品名称" prop="goodsName" width="120" />
|
||||
<el-table-column label="商品名称" prop="goodsName" />
|
||||
<el-table-column label="商品封面" width="120">
|
||||
<template #default="{ row }">
|
||||
<div v-if="row.coverImg" class="flex gap-2">
|
||||
|
@ -193,7 +187,7 @@ getList();
|
|||
:preview-src-list="row.coverImg.split(',')" :z-index="9999" :preview-teleported="true"
|
||||
:hide-on-click-modal="true" fit="cover" class="rounded" width="40" height="40" />
|
||||
</div>
|
||||
<span v-else>-</span>
|
||||
<span v-else>-\</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="商品价格" prop="goodsPrice" width="90">
|
||||
|
@ -232,7 +226,7 @@ getList();
|
|||
:preview-src-list="row.returnImages.split(',')" :z-index="9999" :preview-teleported="true"
|
||||
:hide-on-click-modal="true" fit="cover" class="rounded" width="40" height="40" />
|
||||
</div>
|
||||
<span v-else>-</span>
|
||||
<span v-else>-\</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="120" fixed="right">
|
||||
|
@ -253,8 +247,8 @@ getList();
|
|||
</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="handlePaginationChange" @current-change="handlePaginationChange" />
|
||||
</PureTableBar>
|
||||
@size-change="handlePaginationChange" @current-change="handlePaginationChange" class="pagination" />
|
||||
</div>
|
||||
|
||||
<!-- 详情弹窗 -->
|
||||
<el-dialog v-model="detailVisible" title="审批详情" width="50%">
|
||||
|
@ -279,8 +273,33 @@ getList();
|
|||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
<style scoped lang="scss">
|
||||
.search-form {
|
||||
:deep(.el-form-item) {
|
||||
margin-bottom: 12px;
|
||||
margin-right: 12px;
|
||||
}
|
||||
}
|
||||
:deep(.el-image-viewer__wrapper) {
|
||||
z-index: 9999 !important;
|
||||
}
|
||||
|
||||
.table-container {
|
||||
margin-top: 8px;
|
||||
background-color: var(--el-bg-color);
|
||||
border-radius: 4px;
|
||||
padding: 16px;
|
||||
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.el-table {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.pagination {
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -106,10 +106,6 @@ defineExpose({ getList });
|
|||
<el-button type="primary" :icon="useRenderIcon(Search)" @click="getList">
|
||||
搜索
|
||||
</el-button>
|
||||
<el-button :icon="useRenderIcon(Refresh)"
|
||||
@click="searchFormParams = { goodsName: '', status: null }; getList()">
|
||||
重置
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
|
@ -141,16 +137,24 @@ defineExpose({ getList });
|
|||
|
||||
<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" :total="pagination.total"
|
||||
@size-change="getList" @current-change="getList" />
|
||||
@size-change="getList" @current-change="getList" class="pagination" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
<style scoped lang="scss">
|
||||
.config-modal {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.search-form {
|
||||
margin-bottom: 20px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.el-form-item {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.pagination {
|
||||
margin-top: 10px;
|
||||
}
|
||||
</style>
|
|
@ -231,8 +231,8 @@ const handleClearGoods = async (row: CabinetCellDTO) => {
|
|||
<div class="flex-1 pl-4">
|
||||
<el-form ref="formRef" :inline="true" :model="searchFormParams" class="search-form bg-bg_color w-full pt-[12px]">
|
||||
<el-form-item label="单元格号:" prop="cellNo">
|
||||
<el-input @keyup.enter.native.prevent="onSearch" v-model.number="searchFormParams.cellNo"
|
||||
placeholder="请输入单元格号" clearable class="!w-[180px]" />
|
||||
<el-input @keydown.enter.prevent="onSearch" 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]">
|
||||
|
|
|
@ -158,11 +158,11 @@ getList();
|
|||
<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="categoryName">
|
||||
<el-input @keyup.enter.native.prevent="onSearch" v-model="searchFormParams.categoryName" placeholder="请输入分类名称"
|
||||
<el-input @keydown.enter.prevent="onSearch" v-model="searchFormParams.categoryName" placeholder="请输入分类名称"
|
||||
clearable class="!w-[200px]" />
|
||||
</el-form-item>
|
||||
<el-form-item label="排序:" prop="sort">
|
||||
<el-input-number @keyup.enter.native.prevent="onSearch" v-model="searchFormParams.sort" :min="0"
|
||||
<el-input-number @keydown.enter.prevent="onSearch" v-model="searchFormParams.sort" :min="0"
|
||||
class="!w-[120px]" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
|
|
|
@ -147,7 +147,7 @@ const handleDelete = async () => {
|
|||
:on-success="handleAvatarSuccess" :before-upload="beforeAvatarUpload">
|
||||
<img v-if="formData.coverImg" :src="formData.coverImg" class="avatar" />
|
||||
<el-icon v-else class="avatar-uploader-icon">
|
||||
<Icon :icon="Upload" />
|
||||
<IconifyIconOffline :icon="Upload" />
|
||||
</el-icon>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
|
|
|
@ -106,7 +106,7 @@ const beforeAvatarUpload = (rawFile) => {
|
|||
:on-success="handleAvatarSuccess" :before-upload="beforeAvatarUpload">
|
||||
<img v-if="formData.coverImg" :src="formData.coverImg" class="avatar" />
|
||||
<el-icon v-else class="avatar-uploader-icon">
|
||||
<Icon :icon="Upload" />
|
||||
<IconifyIconOffline :icon="Upload" />
|
||||
</el-icon>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
|
|
|
@ -11,7 +11,6 @@ import Refresh from "@iconify-icons/ep/refresh";
|
|||
import Setting from "@iconify-icons/ep/setting";
|
||||
import GoodsFormModal from "./goods-form-modal.vue";
|
||||
import GoodsEditModal from "./goods-edit-modal.vue";
|
||||
import GoodsCabinetConfigModal from "./goods-cabinet-config-modal.vue";
|
||||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
import { deleteGoodsApi } from "@/api/shop/goods";
|
||||
|
||||
|
@ -31,7 +30,7 @@ const searchFormParams = ref({
|
|||
|
||||
// 分页参数
|
||||
const pagination = ref({
|
||||
pageSize: 10,
|
||||
pageSize: 6,
|
||||
currentPage: 1,
|
||||
total: 0
|
||||
});
|
||||
|
@ -41,7 +40,6 @@ const loading = ref(false);
|
|||
const dataList = ref<GoodsDTO[]>([]);
|
||||
const multipleSelection = ref<number[]>([]);
|
||||
const editVisible = ref(false);
|
||||
const configVisible = ref(false);
|
||||
const currentRow = ref<GoodsDTO>();
|
||||
|
||||
const getList = async () => {
|
||||
|
@ -132,37 +130,33 @@ const handleEdit = (row: GoodsDTO) => {
|
|||
<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="商品名称:" prop="goodsName">
|
||||
<el-input @keyup.enter.native.prevent="onSearch" v-model="searchFormParams.goodsName" placeholder="请输入商品名称"
|
||||
clearable class="!w-[200px]" />
|
||||
class="search-form bg-bg_color flex w-[99/100] pl-[22px] pt-[12px]">
|
||||
<el-form-item prop="goodsName">
|
||||
<el-input @keydown.enter.prevent="onSearch" v-model="searchFormParams.goodsName" placeholder="请输入商品名称" clearable
|
||||
class="!w-[200px]" />
|
||||
</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-option label="已上架" :value="1" />
|
||||
<el-option label="已下架" :value="2" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</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-form-item>
|
||||
<el-form-item class="space-item">
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" :icon="useRenderIcon(AddFill)" @click="modalVisible = true"
|
||||
style="margin-right: 10px;">
|
||||
新增商品
|
||||
</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>
|
||||
<div class="table-container">
|
||||
<el-table ref="tableRef" v-loading="loading" :data="dataList" row-key="id"
|
||||
@selection-change="handleSelectionChange" border>
|
||||
<el-table-column type="selection" width="55" />
|
||||
|
@ -209,21 +203,20 @@ const handleEdit = (row: GoodsDTO) => {
|
|||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-popconfirm> -->
|
||||
</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>
|
||||
:page-sizes="[6, 10, 20, 50]" layout="total, sizes, prev, pager, next, jumper" :total="pagination.total"
|
||||
@size-change="onSizeChange" @current-change="onCurrentChange" class="pagination" />
|
||||
</div>
|
||||
<!-- 新增商品弹窗 -->
|
||||
<goods-form-modal v-model:visible="modalVisible" @refresh="getList" />
|
||||
<goods-edit-modal v-model:visible="editVisible" :row="currentRow" @refresh="getList" />
|
||||
<goods-cabinet-config-modal v-model:visible="configVisible" :row-data="currentRow" @refresh="getList" />
|
||||
</div>
|
||||
</template>
|
||||
<style scoped>
|
||||
<style scoped lang="scss">
|
||||
/* 覆盖预览层样式 */
|
||||
:deep(.el-image-viewer__wrapper) {
|
||||
z-index: 9999 !important;
|
||||
|
@ -233,8 +226,37 @@ const handleEdit = (row: GoodsDTO) => {
|
|||
opacity: 1;
|
||||
background-color: rgba(0, 0, 0, 0.8);
|
||||
}
|
||||
.search-form {
|
||||
:deep(.el-form-item) {
|
||||
margin-bottom: 12px;
|
||||
margin-right: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.space-item {
|
||||
flex: 1;
|
||||
width: 100%;
|
||||
}
|
||||
.right-btn {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.table-container {
|
||||
margin-top: 8px;
|
||||
background-color: var(--el-bg-color);
|
||||
border-radius: 4px;
|
||||
padding: 16px;
|
||||
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.el-table {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.pagination {
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -31,7 +31,7 @@ const searchFormParams = ref<OrderQuery>({
|
|||
});
|
||||
|
||||
const pagination = ref({
|
||||
pageSize: 5,
|
||||
pageSize: 8,
|
||||
currentPage: 1,
|
||||
total: 0
|
||||
});
|
||||
|
@ -129,7 +129,7 @@ getList();
|
|||
</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]">
|
||||
class="search-form bg-bg_color flex w-[99/100] pl-[22px] 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]" />
|
||||
|
@ -137,20 +137,20 @@ getList();
|
|||
<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-form-item>
|
||||
<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 @keyup.enter.native.prevent="onSearch" v-model="searchFormParams.orderId" placeholder="请输入订单编号"
|
||||
clearable class="!w-[200px]" />
|
||||
<el-form-item prop="orderId">
|
||||
<el-input @keydown.enter.prevent="onSearch" v-model="searchFormParams.orderId" placeholder="请输入订单编号" clearable
|
||||
class="!w-[200px]" />
|
||||
</el-form-item>
|
||||
<el-form-item label="格口ID:" prop="cellId">
|
||||
<el-input @keyup.enter.native.prevent="onSearch" v-model="searchFormParams.cellId" placeholder="请输入格口ID"
|
||||
clearable class="!w-[200px]" />
|
||||
<el-form-item prop="cellId">
|
||||
<el-input @keydown.enter.prevent="onSearch" 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-form-item 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" />
|
||||
|
@ -158,7 +158,7 @@ getList();
|
|||
<el-option label="已取消" :value="5" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="支付状态:" prop="payStatus">
|
||||
<el-form-item prop="payStatus">
|
||||
<el-select v-model="searchFormParams.payStatus" placeholder="请选择支付状态" clearable class="!w-[180px]">
|
||||
<el-option label="未支付" :value="1" />
|
||||
<el-option label="已支付" :value="2" />
|
||||
|
@ -166,17 +166,19 @@ getList();
|
|||
<el-option label="已退款" :value="4" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="支付方式:" prop="paymentMethod">
|
||||
<el-form-item 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>
|
||||
<el-form :inline="true" class="search-form bg-bg_color flex w-[99/100] pl-[22px] pt-0">
|
||||
<el-form-item>
|
||||
<el-button type="primary" :icon="useRenderIcon(Search)" @click="onSearch">
|
||||
<el-button type="primary" :icon="useRenderIcon(Search)" @click="onSearch" style="margin-right: 10px;">
|
||||
搜索
|
||||
</el-button>
|
||||
<el-button :icon="useRenderIcon(Refresh)" @click="resetForm">
|
||||
<el-button :icon="useRenderIcon(Refresh)" @click="resetForm" style="margin-right: 10px;">
|
||||
重置
|
||||
</el-button>
|
||||
<el-button type="success" :loading="exportLoading" :icon="useRenderIcon('vscode-icons:file-type-excel2')"
|
||||
|
@ -186,10 +188,10 @@ getList();
|
|||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<PureTableBar title="订单列表" @refresh="getList">
|
||||
<div class="table-container">
|
||||
<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">
|
||||
<el-table-column label="商品名称" prop="goodsNames">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row.goodsNames">
|
||||
{{ row.goodsNames.split(',').join(', ') }}
|
||||
|
@ -245,15 +247,41 @@ getList();
|
|||
</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>
|
||||
:page-sizes="[8, 10, 20, 50]" layout="total, sizes, prev, pager, next, jumper" :total="pagination.total"
|
||||
@size-change="onSizeChange" @current-change="onCurrentChange" class="pagination" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
<style scoped lang="scss">
|
||||
.search-form {
|
||||
:deep(.el-form-item) {
|
||||
margin-bottom: 12px;
|
||||
margin-right: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.right-btn {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.table-container {
|
||||
margin-top: 8px;
|
||||
background-color: var(--el-bg-color);
|
||||
border-radius: 4px;
|
||||
padding: 16px;
|
||||
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.el-table {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.pagination {
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -30,103 +30,46 @@ const {
|
|||
|
||||
<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="菜单名称:" prop="menuName">
|
||||
<el-input
|
||||
v-model="searchFormParams.menuName"
|
||||
placeholder="请输入菜单名称"
|
||||
clearable
|
||||
class="!w-[200px]"
|
||||
/>
|
||||
<el-form ref="formRef" :inline="true" :model="searchFormParams"
|
||||
class="search-form bg-bg_color flex w-[99/100] pl-[22px] pt-[12px]">
|
||||
<el-form-item prop="menuName">
|
||||
<el-input v-model="searchFormParams.menuName" placeholder="请输入菜单名称" 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-form-item prop="status">
|
||||
<el-select v-model="searchFormParams.status" placeholder="请选择状态" clearable class="!w-[180px]">
|
||||
<el-option label="启用" :value="1" />
|
||||
<el-option label="停用" :value="0" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button
|
||||
type="primary"
|
||||
:icon="useRenderIcon(Search)"
|
||||
:loading="loading"
|
||||
@click="onSearch"
|
||||
>
|
||||
<el-button type="primary" :icon="useRenderIcon(Search)" :loading="loading" @click="onSearch">
|
||||
搜索
|
||||
</el-button>
|
||||
<el-button :icon="useRenderIcon(Refresh)" @click="resetForm(formRef)">
|
||||
重置
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<PureTableBar
|
||||
title="菜单列表"
|
||||
:columns="columns"
|
||||
:tableRef="tableRef?.getTableRef()"
|
||||
@refresh="onSearch"
|
||||
>
|
||||
<PureTableBar title="菜单列表" :columns="columns" :tableRef="tableRef?.getTableRef()" @refresh="onSearch">
|
||||
<template #buttons>
|
||||
<el-button
|
||||
type="primary"
|
||||
:icon="useRenderIcon(AddFill)"
|
||||
@click="openDialog()"
|
||||
>
|
||||
<el-button type="primary" :icon="useRenderIcon(AddFill)" @click="openDialog()">
|
||||
新增菜单
|
||||
</el-button>
|
||||
</template>
|
||||
<template v-slot="{ size, dynamicColumns }">
|
||||
<pure-table
|
||||
ref="tableRef"
|
||||
adaptive
|
||||
:adaptiveConfig="{ offsetBottom: 32 }"
|
||||
align-whole="center"
|
||||
row-key="id"
|
||||
showOverflowTooltip
|
||||
table-layout="auto"
|
||||
:loading="loading"
|
||||
:size="size"
|
||||
:data="dataList"
|
||||
:columns="dynamicColumns"
|
||||
:header-cell-style="{
|
||||
<pure-table ref="tableRef" adaptive :adaptiveConfig="{ offsetBottom: 32 }" align-whole="center" row-key="id"
|
||||
showOverflowTooltip table-layout="auto" :loading="loading" :size="size" :data="dataList"
|
||||
:columns="dynamicColumns" :header-cell-style="{
|
||||
background: 'var(--el-table-row-hover-bg-color)',
|
||||
color: 'var(--el-text-color-primary)'
|
||||
}"
|
||||
>
|
||||
}">
|
||||
<template #operation="{ row }">
|
||||
<el-button
|
||||
class="reset-margin"
|
||||
link
|
||||
type="primary"
|
||||
:size="size"
|
||||
:icon="useRenderIcon(EditPen)"
|
||||
@click="openDialog('编辑', row)"
|
||||
>
|
||||
<el-button class="reset-margin" link type="primary" :size="size" :icon="useRenderIcon(EditPen)"
|
||||
@click="openDialog('编辑', row)">
|
||||
编辑
|
||||
</el-button>
|
||||
|
||||
<el-popconfirm
|
||||
:title="`是否确认删除菜单名称为${row.menuName}的这条数据`"
|
||||
@confirm="handleDelete(row)"
|
||||
>
|
||||
<el-popconfirm :title="`是否确认删除菜单名称为${row.menuName}的这条数据`" @confirm="handleDelete(row)">
|
||||
<template #reference>
|
||||
<el-button
|
||||
class="reset-margin"
|
||||
link
|
||||
type="danger"
|
||||
:size="size"
|
||||
:icon="useRenderIcon(Delete)"
|
||||
>
|
||||
<el-button class="reset-margin" link type="danger" :size="size" :icon="useRenderIcon(Delete)">
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
|
@ -142,6 +85,7 @@ const {
|
|||
.search-form {
|
||||
:deep(.el-form-item) {
|
||||
margin-bottom: 12px;
|
||||
margin-right: 12px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<script setup lang="ts">
|
||||
import { ref } from "vue";
|
||||
import { computed, ComputedRef, reactive, ref, watch } from "vue";
|
||||
import { useRole } from "./utils/hook";
|
||||
import { PureTableBar } from "@/components/RePureTableBar";
|
||||
import { useRenderIcon } from "@/components/ReIcon/src/hooks";
|
||||
|
@ -9,9 +9,9 @@ import EditPen from "@iconify-icons/ep/edit-pen";
|
|||
import Search from "@iconify-icons/ep/search";
|
||||
import Refresh from "@iconify-icons/ep/refresh";
|
||||
import AddFill from "@iconify-icons/ri/add-circle-line";
|
||||
import { getRoleInfoApi, RoleDTO } from "@/api/system/role";
|
||||
import RoleFormModal from "@/views/system/role/role-form-modal.vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
import { addRoleApi, AddRoleCommand, getRoleInfoApi, RoleDTO, updateRoleApi, UpdateRoleCommand } from "@/api/system/role";
|
||||
import { ElMessage, FormRules } from "element-plus";
|
||||
import { MenuDTO } from "@/api/system/menu";
|
||||
|
||||
defineOptions({
|
||||
name: "SystemRole"
|
||||
|
@ -23,6 +23,7 @@ const {
|
|||
loading,
|
||||
columns,
|
||||
dataList,
|
||||
activeTab,
|
||||
pagination,
|
||||
onSearch,
|
||||
resetForm,
|
||||
|
@ -32,10 +33,62 @@ const {
|
|||
} = useRole();
|
||||
|
||||
const opType = ref<"add" | "update">("add");
|
||||
const modalVisible = ref(false);
|
||||
const opRow = ref<RoleDTO>();
|
||||
async function openDialog(type: "add" | "update", row?: RoleDTO) {
|
||||
debugger;
|
||||
|
||||
const formData = reactive<AddRoleCommand | UpdateRoleCommand>({
|
||||
roleId: 0,
|
||||
dataScope: "",
|
||||
menuIds: [],
|
||||
remark: "",
|
||||
roleKey: "",
|
||||
roleName: "",
|
||||
roleSort: 1,
|
||||
status: "1"
|
||||
});
|
||||
const resetFromData = () => {
|
||||
Object.assign(formData, {
|
||||
roleId: 0,
|
||||
dataScope: "",
|
||||
menuIds: [],
|
||||
remark: "",
|
||||
roleKey: "",
|
||||
roleName: "",
|
||||
roleSort: 1,
|
||||
status: "1"
|
||||
});
|
||||
}
|
||||
const rules: FormRules = {
|
||||
roleName: [
|
||||
{
|
||||
required: true,
|
||||
message: "角色名称不能为空"
|
||||
}
|
||||
],
|
||||
roleKey: [
|
||||
{
|
||||
required: true,
|
||||
message: "权限标识不能为空"
|
||||
}
|
||||
],
|
||||
roleSort: [
|
||||
{
|
||||
required: true,
|
||||
message: "角色序号不能为空"
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
watch(activeTab, async (val) => {
|
||||
console.log("activeTab", val); // 输出当前选中的标签的 key 或其他标识符
|
||||
opRow.value = dataList.value.find(item => item.roleKey == val);
|
||||
if (!opRow.value) {
|
||||
return;
|
||||
}
|
||||
await getRoleInfo("update", opRow.value);
|
||||
Object.assign(formData, opRow.value);
|
||||
formData.menuIds = opRow.value.selectedMenuList;
|
||||
});
|
||||
async function getRoleInfo(type: "add" | "update", row?: RoleDTO) {
|
||||
try {
|
||||
await getMenuTree();
|
||||
if (row) {
|
||||
|
@ -49,170 +102,168 @@ async function openDialog(type: "add" | "update", row?: RoleDTO) {
|
|||
}
|
||||
opType.value = type;
|
||||
opRow.value = row;
|
||||
modalVisible.value = true;
|
||||
}
|
||||
const processedMenuOptions = ref<{ categoryName: string; items: MenuDTO[] }[]>([]);
|
||||
|
||||
// 监听菜单树变化,处理菜单选项结构
|
||||
watch(menuTree, (val) => {
|
||||
// 初始化分类数组
|
||||
const categories = [];
|
||||
|
||||
// 收集叶子节点(没有子菜单的节点)
|
||||
const collectLeaves = (menu: MenuDTO) => {
|
||||
if (!menu.children) return [];
|
||||
// 过滤出没有子菜单的子节点
|
||||
return menu.children.filter(child => child.children?.length ? false : true);
|
||||
};
|
||||
|
||||
// 递归收集菜单项
|
||||
const collectMenus = (menuOption: MenuDTO) => {
|
||||
// 获取当前菜单的叶子节点
|
||||
const leaves = collectLeaves(menuOption);
|
||||
// 将当前菜单项添加到叶子节点数组开头
|
||||
leaves.unshift(menuOption);
|
||||
|
||||
// 如果有叶子节点,则创建分类
|
||||
if (leaves.length) {
|
||||
categories.push({
|
||||
categoryName: menuOption.menuName, // 使用菜单名作为分类名
|
||||
items: leaves // 包含当前菜单及其叶子节点
|
||||
});
|
||||
}
|
||||
|
||||
// 处理有子菜单的节点
|
||||
if (menuOption.children?.length) {
|
||||
// 筛选出还有子菜单的子节点
|
||||
const lastMenu = menuOption.children.filter(child => child.children?.length);
|
||||
// 递归处理这些子节点
|
||||
lastMenu.filter(lastMenuOption => lastMenuOption.routerName != 'MenuManagement').forEach(child => {
|
||||
collectMenus(child);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// 遍历菜单树,开始收集菜单项
|
||||
console.log("遍历菜单树 val", val);
|
||||
val.forEach(menuOption => {
|
||||
collectMenus(menuOption);
|
||||
})
|
||||
|
||||
console.log("categories", categories); // 输出处理后的菜单选项结构,方便调试和查看结构
|
||||
// 更新处理后的菜单选项
|
||||
processedMenuOptions.value = categories;
|
||||
});
|
||||
|
||||
async function handleConfirm() {
|
||||
try {
|
||||
await formRef.value?.validate();
|
||||
loading.value = true;
|
||||
console.log("opType", opType.value);
|
||||
if (opType.value === 'add') {
|
||||
await addRoleApi(formData as AddRoleCommand);
|
||||
} else {
|
||||
await updateRoleApi(formData as UpdateRoleCommand);
|
||||
}
|
||||
ElMessage.info("提交成功");
|
||||
onSearch().then(() => {
|
||||
activeTab.value = dataList.value[0].roleKey;
|
||||
});
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
ElMessage.error((e as Error)?.message || "提交失败");
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
const addRole = async () => {
|
||||
await getRoleInfo("add");
|
||||
activeTab.value = '';
|
||||
resetFromData();
|
||||
}
|
||||
|
||||
getMenuTree();
|
||||
onSearch().then(() => {
|
||||
activeTab.value = dataList.value[0].roleKey;
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<div class="main">
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:inline="true"
|
||||
:model="form"
|
||||
class="search-form bg-bg_color w-[99/100] pl-8 pt-[12px]"
|
||||
>
|
||||
<el-form-item label="角色名称:" prop="name">
|
||||
<el-input
|
||||
v-model="form.roleName"
|
||||
placeholder="请输入角色名称"
|
||||
clearable
|
||||
class="!w-[200px]"
|
||||
/>
|
||||
|
||||
<div class="tab-header">
|
||||
<el-button :icon="useRenderIcon(AddFill)" @click="addRole" style="margin-bottom: 16px">
|
||||
新建角色
|
||||
</el-button>
|
||||
<ul class="role-list">
|
||||
<li v-for="role in dataList" :key="role.roleKey" :class="{ 'active': activeTab === role.roleKey }"
|
||||
@click="activeTab = role.roleKey">
|
||||
{{ role.roleName }}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<el-form :model="formData" label-width="120px" :rules="rules" ref="formRef">
|
||||
<el-form-item prop="roleName" label="角色名称" required inline-message>
|
||||
<el-input v-model="formData.roleName" class="form-input" />
|
||||
</el-form-item>
|
||||
<el-form-item label="角色标识:" prop="code">
|
||||
<el-input
|
||||
v-model="form.roleKey"
|
||||
placeholder="请输入角色标识"
|
||||
clearable
|
||||
class="!w-[180px]"
|
||||
/>
|
||||
<el-form-item prop="roleKey" label="权限字符" required>
|
||||
<el-input v-model="formData.roleKey" class="form-input" />
|
||||
</el-form-item>
|
||||
<el-form-item label="状态:" prop="status">
|
||||
<el-select
|
||||
v-model="form.status"
|
||||
placeholder="请选择状态"
|
||||
clearable
|
||||
class="!w-[180px]"
|
||||
>
|
||||
<el-option label="已启用" value="1" />
|
||||
<el-option label="已停用" value="0" />
|
||||
</el-select>
|
||||
<!-- <el-form-item prop="roleSort" label="角色顺序" required>
|
||||
<el-input-number :min="1" v-model="formData.roleSort" />
|
||||
</el-form-item> -->
|
||||
<!-- <el-form-item prop="status" label="角色状态">
|
||||
<el-radio-group v-model="formData.status">
|
||||
<el-radio v-for="item in Object.keys(statusList)" :key="item" :label="statusList[item].value">{{
|
||||
statusList[item].label }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item> -->
|
||||
<el-form-item label="菜单权限" prop="menuIds" class="form-input">
|
||||
<el-checkbox-group v-model="formData.menuIds" class="checkbox-group">
|
||||
<template v-for="menu in processedMenuOptions" :key="menu.categoryName">
|
||||
<span class="menu-category">{{ menu.categoryName }}:</span>
|
||||
<el-checkbox v-for="item in menu.items" :key="item.id" :label="item.id" class="menu-checkbox">
|
||||
{{ item.menuName }}
|
||||
</el-checkbox>
|
||||
<el-divider class="divider" />
|
||||
</template>
|
||||
</el-checkbox-group>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button
|
||||
type="primary"
|
||||
:icon="useRenderIcon(Search)"
|
||||
:loading="loading"
|
||||
@click="onSearch"
|
||||
>
|
||||
搜索
|
||||
</el-button>
|
||||
<el-button :icon="useRenderIcon(Refresh)" @click="resetForm(formRef)">
|
||||
重置
|
||||
</el-button>
|
||||
<!-- <el-form-item prop="remark" label="备注" style="margin-bottom: 0">
|
||||
<el-input type="textarea" class="form-input" v-model="formData.remark" />
|
||||
</el-form-item> -->
|
||||
<el-form-item class="form-actions">
|
||||
<el-button type="primary" @click="handleConfirm">确认</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<PureTableBar
|
||||
title="角色列表"
|
||||
:columns="columns"
|
||||
@refresh="onSearch"
|
||||
>
|
||||
<template #buttons>
|
||||
<el-button
|
||||
type="primary"
|
||||
:icon="useRenderIcon(AddFill)"
|
||||
@click="openDialog('add')"
|
||||
>
|
||||
新增角色
|
||||
</el-button>
|
||||
</template>
|
||||
<template v-slot="{ size, dynamicColumns }">
|
||||
<pure-table
|
||||
border
|
||||
align-whole="center"
|
||||
showOverflowTooltip
|
||||
table-layout="auto"
|
||||
:loading="loading"
|
||||
:size="size"
|
||||
adaptive
|
||||
:data="dataList"
|
||||
:columns="dynamicColumns"
|
||||
:pagination="pagination"
|
||||
:paginationSmall="size === 'small' ? true : false"
|
||||
:header-cell-style="{
|
||||
background: 'var(--el-table-row-hover-bg-color)',
|
||||
color: 'var(--el-text-color-primary)'
|
||||
}"
|
||||
>
|
||||
<template #operation="{ row }">
|
||||
<el-button
|
||||
class="reset-margin"
|
||||
link
|
||||
type="primary"
|
||||
:size="size"
|
||||
:icon="useRenderIcon(EditPen)"
|
||||
@click="openDialog('update', row)"
|
||||
>
|
||||
修改
|
||||
</el-button>
|
||||
<el-popconfirm
|
||||
:title="`是否确认删除角色名称为${row.roleName}的这条数据`"
|
||||
@confirm="handleDelete(row)"
|
||||
>
|
||||
<template #reference>
|
||||
<el-button
|
||||
class="reset-margin"
|
||||
link
|
||||
type="primary"
|
||||
:size="size"
|
||||
:icon="useRenderIcon(Delete)"
|
||||
>
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-popconfirm>
|
||||
<!-- <el-dropdown>
|
||||
<el-button
|
||||
class="ml-3 mt-[2px]"
|
||||
link
|
||||
type="primary"
|
||||
:size="size"
|
||||
:icon="useRenderIcon(More)"
|
||||
/>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item>
|
||||
<el-button
|
||||
:class="buttonClass"
|
||||
link
|
||||
type="primary"
|
||||
:size="size"
|
||||
:icon="useRenderIcon(Menu)"
|
||||
@click="handleMenu"
|
||||
>
|
||||
菜单权限
|
||||
</el-button>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item>
|
||||
<el-button
|
||||
:class="buttonClass"
|
||||
link
|
||||
type="primary"
|
||||
:size="size"
|
||||
:icon="useRenderIcon(Database)"
|
||||
@click="handleDatabase"
|
||||
>
|
||||
数据权限
|
||||
</el-button>
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown> -->
|
||||
</template>
|
||||
</pure-table>
|
||||
</template>
|
||||
</PureTableBar>
|
||||
|
||||
<role-form-modal
|
||||
v-model="modalVisible"
|
||||
:type="opType"
|
||||
:row="opRow"
|
||||
:menu-options="menuTree"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.role-list {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
|
||||
li {
|
||||
width: 200px;
|
||||
padding: 6px 12px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
border-left: 3px solid transparent;
|
||||
font-weight: 700;
|
||||
font-size: 16px;
|
||||
|
||||
&:hover {
|
||||
background-color: var(--el-color-primary-light-9);
|
||||
}
|
||||
|
||||
&.active {
|
||||
background-color: var(--el-color-primary-light-8);
|
||||
/* border-left-color: var(--el-color-primary); */
|
||||
color: var(--el-color-primary);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.el-dropdown-menu__item i) {
|
||||
margin: 0;
|
||||
}
|
||||
|
@ -222,4 +273,37 @@ async function openDialog(type: "add" | "update", row?: RoleDTO) {
|
|||
margin-bottom: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.main {
|
||||
display: flex;
|
||||
gap: 5px;
|
||||
}
|
||||
|
||||
.tab-header {
|
||||
height: 86vh;
|
||||
padding: 20px 12px 12px 12px;
|
||||
background-color: #FFFFFF;
|
||||
flex: 0 0 0px;
|
||||
}
|
||||
|
||||
.el-form {
|
||||
height: 86vh;
|
||||
padding-top: 20px;
|
||||
background-color: #FFFFFF;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.form-input {
|
||||
width: 40%;
|
||||
}
|
||||
|
||||
.divider {
|
||||
margin: 6px 0;
|
||||
|
||||
}
|
||||
|
||||
.form-actions {
|
||||
margin-top: 20px;
|
||||
text-align: right;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -135,8 +135,8 @@ const processedMenuOptions = computed(() => {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<v-dialog show-full-screen fixed-body-height use-body-scrolling :title="type === 'add' ? '新增角色' : '更新角色'"
|
||||
v-model="visible" :loading="loading" @confirm="handleConfirm" @cancel="visible = false" @opened="handleOpened">
|
||||
<v-dialog fullScreen show-full-screen use-body-scrolling :title="type === 'add' ? '新增角色' : '更新角色'" v-model="visible"
|
||||
@cancel="visible = false" @opened="handleOpened" class="">
|
||||
<el-form :model="formData" label-width="120px" :rules="rules" ref="formRef">
|
||||
<el-form-item prop="roleName" label="角色名称" required inline-message>
|
||||
<el-input v-model="formData.roleName" />
|
||||
|
@ -144,9 +144,9 @@ const processedMenuOptions = computed(() => {
|
|||
<el-form-item prop="roleKey" label="权限字符" required>
|
||||
<el-input v-model="formData.roleKey" />
|
||||
</el-form-item>
|
||||
<el-form-item prop="roleSort" label="角色顺序" required>
|
||||
<!-- <el-form-item prop="roleSort" label="角色顺序" required>
|
||||
<el-input-number :min="1" v-model="formData.roleSort" />
|
||||
</el-form-item>
|
||||
</el-form-item> -->
|
||||
<el-form-item prop="status" label="角色状态">
|
||||
<el-radio-group v-model="formData.status">
|
||||
<el-radio v-for="item in Object.keys(statusList)" :key="item" :label="statusList[item].value">{{
|
||||
|
|
|
@ -2,6 +2,7 @@ import dayjs from "dayjs";
|
|||
import { message } from "@/utils/message";
|
||||
import {
|
||||
deleteRoleApi,
|
||||
getRoleAllApi,
|
||||
getRoleListApi,
|
||||
RoleDTO,
|
||||
RoleQuery
|
||||
|
@ -10,7 +11,7 @@ import { getMenuListApi, MenuDTO } from "@/api/system/menu";
|
|||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
import { usePublicHooks } from "../../hooks";
|
||||
import { type PaginationProps } from "@pureadmin/table";
|
||||
import { onMounted, reactive, ref, toRaw } from "vue";
|
||||
import { onMounted, reactive, ref, toRaw, watch } from "vue";
|
||||
import { toTree } from "@/utils/tree";
|
||||
|
||||
export function useRole() {
|
||||
|
@ -19,13 +20,14 @@ export function useRole() {
|
|||
roleName: "",
|
||||
status: undefined
|
||||
});
|
||||
const dataList = ref([]);
|
||||
const dataList = ref<RoleDTO[]>([]);
|
||||
const loading = ref(true);
|
||||
const switchLoadMap = ref({});
|
||||
const { switchStyle } = usePublicHooks();
|
||||
const activeTab = ref('');
|
||||
const pagination = reactive<PaginationProps>({
|
||||
total: 0,
|
||||
pageSize: 10,
|
||||
pageSize: 100,
|
||||
currentPage: 1,
|
||||
background: true
|
||||
});
|
||||
|
@ -149,10 +151,16 @@ export function useRole() {
|
|||
async function onSearch() {
|
||||
try {
|
||||
loading.value = true;
|
||||
const { data } = await getRoleListApi(toRaw(form));
|
||||
const { data } = await getRoleAllApi(toRaw(form));
|
||||
console.log("role list", data);
|
||||
dataList.value = data.rows;
|
||||
pagination.total = data.total;
|
||||
// 重新排序:base排第一,admin排最后
|
||||
dataList.value = data.sort((a, b) => {
|
||||
if (a.roleKey === 'base') return -1;
|
||||
if (b.roleKey === 'base') return 1;
|
||||
if (a.roleKey === 'admin') return 1;
|
||||
if (b.roleKey === 'admin') return -1;
|
||||
return 0;
|
||||
});
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
ElMessage.error((e as Error)?.message || "加载失败");
|
||||
|
@ -190,6 +198,7 @@ export function useRole() {
|
|||
loading,
|
||||
columns,
|
||||
dataList,
|
||||
activeTab,
|
||||
pagination,
|
||||
onSearch,
|
||||
resetForm,
|
||||
|
|
|
@ -53,8 +53,8 @@ watch(
|
|||
<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="nickname">
|
||||
<el-input @keyup.enter.native.prevent="onSearch" v-model="searchFormParams.nickname" placeholder="请输入"
|
||||
clearable class="!w-[160px]" />
|
||||
<el-input @keydown.enter.prevent="onSearch" v-model="searchFormParams.nickname" placeholder="请输入" clearable
|
||||
class="!w-[160px]" />
|
||||
</el-form-item>
|
||||
<!-- <el-form-item label="用户编号:" prop="userId">
|
||||
<el-input
|
||||
|
|
|
@ -165,10 +165,7 @@ onMounted(() => {
|
|||
<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-item label="注册时间" :span="2">{{ userInfo.createTime }}</el-descriptions-item>
|
||||
<el-descriptions-item label="标签" :span="2">
|
||||
<div class="tag-container">
|
||||
<div class="user-tags" v-if="tags.length > 0">
|
||||
|
|
|
@ -37,6 +37,7 @@ const pagination = reactive<PaginationProps>({
|
|||
});
|
||||
|
||||
async function onSearch() {
|
||||
handleSearchInput(searchFormParams.search);
|
||||
pagination.currentPage = 1;
|
||||
getList();
|
||||
}
|
||||
|
@ -113,13 +114,13 @@ onMounted(() => {
|
|||
<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="search">
|
||||
class="search-form bg-bg_color flex w-[99/100] pl-[22px] pt-[12px]">
|
||||
<el-form-item prop="search">
|
||||
<el-input v-model="searchFormParams.search" placeholder="请输入姓名/手机号/身份证" clearable class="!w-[300px]"
|
||||
@keyup.enter.native.prevent="onSearch" @change="handleSearchInput" />
|
||||
@keydown.enter.prevent="onSearch" @change="handleSearchInput" />
|
||||
</el-form-item>
|
||||
<el-form-item label="标签:" prop="tagName">
|
||||
<el-select v-model="searchFormParams.tagName" placeholder="请选择" clearable class="!w-[160px]">
|
||||
<el-form-item prop="tagName">
|
||||
<el-select v-model="searchFormParams.tagName" placeholder="请选择用户标签" clearable class="!w-[160px]">
|
||||
<el-option v-for="item in tagOptions" :key="item" :label="item" :value="item" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
@ -180,6 +181,7 @@ onMounted(() => {
|
|||
.search-form {
|
||||
:deep(.el-form-item) {
|
||||
margin-bottom: 12px;
|
||||
margin-right: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -21,11 +21,11 @@ const emit = defineEmits(["update:visible", "refresh"]);
|
|||
|
||||
const formRef = ref();
|
||||
const formData = reactive({
|
||||
balance: 0
|
||||
balanceLimit: 0
|
||||
});
|
||||
|
||||
const rules = reactive<FormRules>({
|
||||
balance: [
|
||||
balanceLimit: [
|
||||
{ required: true, message: "请输入金额", trigger: "blur" },
|
||||
{ type: 'number', message: '必须为数字类型' },
|
||||
{ validator: (_, v, cb) => v >= 0 ? cb() : cb(new Error('金额不能小于0')), trigger: 'blur' }
|
||||
|
@ -37,7 +37,7 @@ const handleConfirm = async () => {
|
|||
await formRef.value.validate();
|
||||
await updateQyUserApi(props.row.id, {
|
||||
id: props.row.id,
|
||||
balance: formData.balance
|
||||
balanceLimit: formData.balanceLimit
|
||||
});
|
||||
ElMessage.success("余额修改成功");
|
||||
emit("refresh");
|
||||
|
@ -54,16 +54,16 @@ const closeDialog = () => {
|
|||
|
||||
watch(() => props.row, (val) => {
|
||||
if (val) {
|
||||
formData.balance = val.balance || 0;
|
||||
formData.balanceLimit = val.balanceLimit || 0;
|
||||
}
|
||||
}, { immediate: true });
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-dialog title="修改余额" :model-value="visible" width="500px" @close="closeDialog">
|
||||
<el-dialog title="修改借呗额度" :model-value="visible" width="500px" @close="closeDialog">
|
||||
<el-form ref="formRef" :model="formData" :rules="rules" label-width="80px">
|
||||
<el-form-item label="金额" prop="balance">
|
||||
<el-input-number v-model="formData.balance" :precision="2" :step="0.1" :min="0" controls-position="right"
|
||||
<el-form-item label="金额" prop="balanceLimit">
|
||||
<el-input-number v-model="formData.balanceLimit" :precision="2" :step="0.1" :min="0" controls-position="right"
|
||||
class="!w-[200px]" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
|
|
@ -15,7 +15,6 @@ const router = useRouter();
|
|||
const userInfo = ref<QyUserDTO>({});
|
||||
const loading = ref(false);
|
||||
const balanceVisible = ref(false);
|
||||
const currentBalance = ref(0);
|
||||
const roleVisible = ref(false);
|
||||
const roleList = ref<RoleDTO[]>([]);
|
||||
const selectedRoleId = ref<number>();
|
||||
|
@ -102,7 +101,6 @@ onMounted(() => {
|
|||
fetchUserDetail();
|
||||
});
|
||||
async function handleModifyBalance(row: QyUserDTO) {
|
||||
currentBalance.value = row.balance || 0;
|
||||
balanceVisible.value = true;
|
||||
}
|
||||
|
||||
|
@ -128,8 +126,13 @@ async function handleModifyBalance(row: QyUserDTO) {
|
|||
<el-descriptions class="user-details" :column="1" border>
|
||||
<el-descriptions-item label="姓名">{{ userInfo.name }}</el-descriptions-item>
|
||||
<el-descriptions-item label="手机号">{{ userInfo.mobile }}</el-descriptions-item>
|
||||
<el-descriptions-item label="余额">¥{{ userInfo.balance?.toFixed(2) }} <el-button type="primary" size="small"
|
||||
@click="handleModifyBalance(userInfo)">修改</el-button></el-descriptions-item>
|
||||
<el-descriptions-item label="借呗">¥{{ userInfo.balanceLimit?.toFixed(2) }}
|
||||
<el-button type="primary" size="small" @click="handleModifyBalance(userInfo)">
|
||||
修改
|
||||
</el-button>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="已用借呗">{{ userInfo.useBalance?.toFixed(2) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="剩余借呗">¥{{ userInfo.balance?.toFixed(2) }}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</el-card>
|
||||
<el-card class="info-card">
|
||||
|
|
|
@ -50,17 +50,14 @@ watch(
|
|||
<div class="search-form-container">
|
||||
<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 @keyup.enter.native.prevent="onSearch" v-model="searchFormParams.name" placeholder="请输入" clearable
|
||||
<el-form-item prop="name">
|
||||
<el-input @keydown.enter.prevent="onSearch" v-model="searchFormParams.name" 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>
|
||||
|
||||
|
@ -94,7 +91,7 @@ watch(
|
|||
<div class="user-info">
|
||||
<div class="name">姓名:{{ item.name }}</div>
|
||||
<div class="tel">电话:{{ item.mobile }}</div>
|
||||
<div class="balance">余额:{{ item.balance }}</div>
|
||||
<div class="balance">剩余借呗:{{ item.balance }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-gap"></div>
|
||||
|
|
Loading…
Reference in New Issue