Compare commits
6 Commits
d2390361b1
...
210386a036
Author | SHA1 | Date |
---|---|---|
|
210386a036 | |
|
9d7b502698 | |
|
e1f18cfc48 | |
|
b4451bd2ea | |
|
c01a01519a | |
|
b1f4216df6 |
|
@ -0,0 +1,59 @@
|
|||
import { http } from "@/utils/http";
|
||||
|
||||
export interface Ab98UserTagDTO {
|
||||
/** 标签ID */
|
||||
tagId?: number;
|
||||
/** 关联用户ID */
|
||||
ab98UserId?: number;
|
||||
/** 标签名称 */
|
||||
tagName?: string;
|
||||
/** 创建时间 */
|
||||
createTime?: string;
|
||||
}
|
||||
|
||||
export interface Ab98UserTagQuery extends BasePageQuery {
|
||||
/** 关联用户ID */
|
||||
ab98UserId?: number;
|
||||
/** 标签名称 */
|
||||
tagName?: string;
|
||||
/** 开始时间 */
|
||||
startTime?: string;
|
||||
/** 结束时间 */
|
||||
endTime?: string;
|
||||
}
|
||||
|
||||
export interface AddAb98UserTagCommand {
|
||||
/** 关联用户ID */
|
||||
ab98UserId: number;
|
||||
/** 标签名称 */
|
||||
tagName: string;
|
||||
}
|
||||
|
||||
export interface UpdateAb98UserTagCommand extends AddAb98UserTagCommand {
|
||||
/** 标签ID */
|
||||
tagId: number;
|
||||
}
|
||||
|
||||
export const getAb98UserTagListApi = (params: Ab98UserTagQuery) => {
|
||||
return http.request<ResponseData<PageDTO<Ab98UserTagDTO>>>("get", "/ab98/userTags", { params });
|
||||
};
|
||||
|
||||
export const addAb98UserTagApi = (data: AddAb98UserTagCommand) => {
|
||||
return http.request<ResponseData<void>>("post", "/ab98/userTags", { data });
|
||||
};
|
||||
|
||||
export const updateAb98UserTagApi = (id: number, data: UpdateAb98UserTagCommand) => {
|
||||
return http.request<ResponseData<void>>("put", `/ab98/userTags/${id}`, { data });
|
||||
};
|
||||
|
||||
export const deleteAb98UserTagApi = (ids: number[]) => {
|
||||
return http.request<ResponseData<void>>("delete", `/ab98/userTags/${ids.join(',')}`);
|
||||
};
|
||||
|
||||
export const deleteAb98UserTagConfirmApi = (tagId: number) => {
|
||||
return http.request<ResponseData<void>>("delete", `/ab98/userTags/${tagId}`);
|
||||
};
|
||||
|
||||
export const getAb98UserTagNamesApi = () => {
|
||||
return http.request<ResponseData<string[]>>("get", "/ab98/userTags/names");
|
||||
};
|
|
@ -61,6 +61,7 @@ export interface Ab98UserQuery extends BasePageQuery {
|
|||
tel?: string;
|
||||
/** 身份证号码 */
|
||||
idnum?: string;
|
||||
tagName?: string;
|
||||
}
|
||||
|
||||
export interface AddAb98UserCommand {
|
||||
|
|
|
@ -4,6 +4,7 @@ export interface CabinetCellQuery extends BasePageQuery {
|
|||
cabinetId?: number;
|
||||
cellNo?: number;
|
||||
cellType?: number;
|
||||
goodsName?: string;
|
||||
}
|
||||
|
||||
export interface CabinetCellDTO {
|
||||
|
|
|
@ -2,47 +2,97 @@ import { http } from '@/utils/http';
|
|||
import { CabinetCellDTO } from './cabinet-cell';
|
||||
|
||||
export interface SmartCabinetQuery extends BasePageQuery {
|
||||
/** 柜机名称 */
|
||||
cabinetName?: string;
|
||||
/** 柜机类型(0主柜 1副柜) */
|
||||
cabinetType?: number;
|
||||
/** 柜机模版编号 */
|
||||
templateNo?: string;
|
||||
/** 归属类型(0-借还柜 1-固资通) */
|
||||
belongType?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* 智能柜信息
|
||||
* @description 智能柜信息表
|
||||
*/
|
||||
export interface SmartCabinetDTO {
|
||||
/** 柜机唯一ID */
|
||||
cabinetId?: number;
|
||||
/** 柜机名称 */
|
||||
cabinetName: string;
|
||||
/** 柜机类型(0主柜 1副柜) */
|
||||
cabinetType: number;
|
||||
/** 归属主柜ID */
|
||||
mainCabinet?: number;
|
||||
/** 归属主柜名称 */
|
||||
mainCabinetName?: string;
|
||||
/** MQTT服务ID */
|
||||
mqttServerId?: number;
|
||||
/** 商店ID */
|
||||
shopId?: number;
|
||||
/** 商店名称 */
|
||||
shopName?: string;
|
||||
/** 柜机模版编号 */
|
||||
templateNo: string;
|
||||
/** 锁控板序号 */
|
||||
lockControlNo: number;
|
||||
/** 柜机位置 */
|
||||
location: number;
|
||||
/** 操作人 */
|
||||
operator?: string;
|
||||
/** 归属类型(0-借还柜 1-固资通) */
|
||||
belongType?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加智能柜命令
|
||||
*/
|
||||
export interface AddSmartCabinetCommand {
|
||||
/** 柜机名称 */
|
||||
cabinetName: string;
|
||||
/** 柜机类型(0主柜 1副柜) */
|
||||
cabinetType: number;
|
||||
/** 归属主柜ID */
|
||||
mainCabinet?: number;
|
||||
/** MQTT服务ID */
|
||||
mqttServerId?: number;
|
||||
/** 商店ID */
|
||||
shopId?: number;
|
||||
/** 柜机模版编号 */
|
||||
templateNo: string;
|
||||
/** 锁控板序号 */
|
||||
lockControlNo: number;
|
||||
/** 柜机位置 */
|
||||
location: number;
|
||||
/** 归属类型(0-借还柜 1-固资通) */
|
||||
belongType: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新智能柜命令
|
||||
*/
|
||||
export interface UpdateSmartCabinetCommand {
|
||||
/** 柜机唯一ID */
|
||||
cabinetId: number;
|
||||
/** 柜机名称 */
|
||||
cabinetName?: string;
|
||||
/** 柜机类型(0主柜 1副柜) */
|
||||
cabinetType?: number;
|
||||
/** 归属主柜ID */
|
||||
mainCabinet?: number;
|
||||
/** MQTT服务ID */
|
||||
mqttServerId?: number;
|
||||
/** 商店ID */
|
||||
shopId?: number;
|
||||
/** 柜机模版编号 */
|
||||
templateNo?: string;
|
||||
/** 锁控板序号 */
|
||||
lockControlNo?: number;
|
||||
/** 柜机位置 */
|
||||
location?: number;
|
||||
/** 归属类型(0-借还柜 1-固资通) */
|
||||
belongType?: number;
|
||||
}
|
||||
|
||||
export interface AllCabinetDataDTO {
|
||||
|
|
|
@ -69,6 +69,7 @@ export interface QyUserQuery extends BasePageQuery {
|
|||
mainDepartment?: number;
|
||||
roleId?: number;
|
||||
sysRoleId?: number;
|
||||
balancePage?: number;
|
||||
}
|
||||
|
||||
export interface AddQyUserCommand {
|
||||
|
@ -128,3 +129,9 @@ export const exportQyUserExcelApi = (params: QyUserQuery, fileName: string) => {
|
|||
export const getQyUserDetailApi = (id: number) => {
|
||||
return http.request<ResponseData<QyUserDTO>>("get", `/qywx/users/detail/${id}`);
|
||||
};
|
||||
|
||||
export const getTotalBalanceApi = (corpid: string) => {
|
||||
return http.request<ResponseData<number>>("get", `/qywx/users/getTotalBalance`, {
|
||||
params: { corpid }
|
||||
});
|
||||
};
|
|
@ -1,6 +1,4 @@
|
|||
<script setup lang="ts">
|
||||
import Search from "./search/index.vue";
|
||||
import Notice from "./notice/index.vue";
|
||||
import QrCodeHover from "@/components/QrCodeHover/index.vue";
|
||||
import mixNav from "./sidebar/mixNav.vue";
|
||||
import { useNav } from "@/layout/hooks/useNav";
|
||||
|
|
|
@ -129,15 +129,15 @@ function handleDown() {
|
|||
|
||||
/** key enter */
|
||||
function handleEnter() {
|
||||
const { length } = resultOptions.value;
|
||||
/* const { length } = resultOptions.value;
|
||||
if (length === 0 || activePath.value === "") return;
|
||||
router.push(activePath.value);
|
||||
handleClose();
|
||||
handleClose(); */
|
||||
}
|
||||
|
||||
onKeyStroke("Enter", handleEnter);
|
||||
/* onKeyStroke("Enter", handleEnter);
|
||||
onKeyStroke("ArrowUp", handleUp);
|
||||
onKeyStroke("ArrowDown", handleDown);
|
||||
onKeyStroke("ArrowDown", handleDown); */
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
<script setup lang="ts">
|
||||
import Search from "../search/index.vue";
|
||||
import Notice from "../notice/index.vue";
|
||||
import SidebarItem from "./sidebarItem.vue";
|
||||
import { isAllEmpty } from "@pureadmin/utils";
|
||||
import { ref, nextTick, computed } from "vue";
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
<script setup lang="ts">
|
||||
import extraIcon from "./extraIcon.vue";
|
||||
import Search from "../search/index.vue";
|
||||
import Notice from "../notice/index.vue";
|
||||
import { isAllEmpty } from "@pureadmin/utils";
|
||||
import { useNav } from "@/layout/hooks/useNav";
|
||||
import { ref, toRaw, watch, onMounted, nextTick } from "vue";
|
||||
|
|
|
@ -204,10 +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 v-model.number="searchFormParams.cabinetId" placeholder="请输入柜体ID" clearable class="!w-[200px]" />
|
||||
<el-input @keyup.enter.native.prevent="onSearch" 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-input @keyup.enter.native.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]">
|
||||
|
|
|
@ -122,10 +122,12 @@ 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="serverUrl">
|
||||
<el-input v-model="searchFormParams.serverUrl" placeholder="请输入服务地址" clearable class="!w-[200px]" />
|
||||
<el-input @keyup.enter.native.prevent="onSearch" v-model="searchFormParams.serverUrl" placeholder="请输入服务地址"
|
||||
clearable class="!w-[200px]" />
|
||||
</el-form-item>
|
||||
<el-form-item label="用户名:" prop="username">
|
||||
<el-input v-model="searchFormParams.username" placeholder="请输入用户名" clearable class="!w-[200px]" />
|
||||
<el-input @keyup.enter.native.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">
|
||||
|
|
|
@ -84,7 +84,8 @@ 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="格口ID:" prop="cellId">
|
||||
<el-input v-model="searchFormParams.cellId" placeholder="请输入格口ID" clearable class="!w-[200px]" />
|
||||
<el-input @keyup.enter.native.prevent="onSearch" v-model="searchFormParams.cellId" placeholder="请输入格口ID"
|
||||
clearable class="!w-[200px]" />
|
||||
</el-form-item>
|
||||
<el-form-item label="操作类型:" prop="operationType">
|
||||
<el-select v-model="searchFormParams.operationType" placeholder="请选择类型" clearable class="!w-[180px]">
|
||||
|
|
|
@ -138,7 +138,8 @@ 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="shopName">
|
||||
<el-input v-model="searchFormParams.shopName" placeholder="请输入商店名称" clearable class="!w-[200px]" />
|
||||
<el-input @keyup.enter.native.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">
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
import { ref, onMounted } from "vue";
|
||||
import { useRoute, useRouter } from "vue-router";
|
||||
import { getSmartCabinetDetailApi, type SmartCabinetDTO } from "@/api/cabinet/smart-cabinet";
|
||||
import { changeGoodsCellsStock, clearGoodsCells, getCabinetCellList, type CabinetCellDTO } from "@/api/cabinet/cabinet-cell";
|
||||
import { CabinetCellQuery, changeGoodsCellsStock, clearGoodsCells, getCabinetCellList, type CabinetCellDTO } from "@/api/cabinet/cabinet-cell";
|
||||
import { useRenderIcon } from "@/components/ReIcon/src/hooks";
|
||||
import { CabinetImgMap } from "@/utils/cabinetImgMap";
|
||||
import GatewayConfigModal from "@/views/cabinet/smart-cabinet/GatewayConfigModal.vue";
|
||||
|
@ -50,6 +50,9 @@ const shopConfigVisible = ref(false);
|
|||
const mainCabinetConfigVisible = ref(false);
|
||||
const editCabinetDrawerVisible = ref(false);
|
||||
const cellList = ref<CabinetCellDTO[]>([]);
|
||||
const searchCellParams = ref<CabinetCellQuery>({
|
||||
goodsName: null
|
||||
});
|
||||
const cellPagination = ref({
|
||||
pageSize: 5,
|
||||
currentPage: 1,
|
||||
|
@ -140,11 +143,17 @@ function switchCellType(cellType: number) {
|
|||
}
|
||||
}
|
||||
|
||||
function resetCellSearch() {
|
||||
searchCellParams.value.cellNo = null;
|
||||
fetchCellList();
|
||||
}
|
||||
|
||||
async function fetchCellList() {
|
||||
try {
|
||||
loading.value = true;
|
||||
const { data } = await getCabinetCellList({
|
||||
cabinetId: cabinetId.value,
|
||||
goodsName: searchCellParams.value.goodsName,
|
||||
pageSize: cellPagination.value.pageSize,
|
||||
pageNum: cellPagination.value.currentPage
|
||||
});
|
||||
|
@ -295,16 +304,35 @@ 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="归属类型">
|
||||
{{ cabinetInfo.belongType === 0 ? '借还柜' : '固资通' }}
|
||||
</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: flex-end; margin-bottom: 16px;">
|
||||
<el-button type="primary" :size="'small'" :icon="useRenderIcon(AddFill)" @click="cellFormVisible = true">
|
||||
新增格口
|
||||
<div style="display: flex; justify-content: space-between; margin-bottom: 16px;">
|
||||
<el-form :inline="true" :model="searchCellParams" class="search-form">
|
||||
<el-form-item>
|
||||
<el-input @keyup.enter.native.prevent="fetchCellList" v-model="searchCellParams.goodsName"
|
||||
placeholder="请输入商品名称" clearable class="!w-[180px]" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" :icon="useRenderIcon(Search)" :loading="loading" @click="fetchCellList">
|
||||
搜索
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button :icon="useRenderIcon(Refresh)" @click="resetCellSearch">
|
||||
重置
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<!-- <el-button type="primary" :size="'small'" :icon="useRenderIcon(AddFill)" @click="cellFormVisible = true">
|
||||
新增格口
|
||||
</el-button> -->
|
||||
</div>
|
||||
<el-table v-loading="loading" :data="cellList" border>
|
||||
<el-table-column label="格口ID" prop="cellId" width="80" />
|
||||
|
@ -343,7 +371,8 @@ onMounted(() => {
|
|||
</el-table-column>
|
||||
<el-table-column label="操作" width="150" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button type="success" link :icon="useRenderIcon(AddFill)" @click="handleConfigure(row)">
|
||||
<el-button v-if="cabinetInfo.belongType === 0" type="success" link :icon="useRenderIcon(AddFill)"
|
||||
@click="handleConfigure(row)">
|
||||
配置商品
|
||||
</el-button>
|
||||
|
||||
|
|
|
@ -26,7 +26,8 @@ const formData = reactive({
|
|||
cabinetType: 1,
|
||||
templateNo: "",
|
||||
lockControlNo: 0,
|
||||
location: 0
|
||||
location: 0,
|
||||
belongType: 0
|
||||
});
|
||||
|
||||
const rules = reactive<FormRules>({
|
||||
|
@ -39,6 +40,9 @@ const rules = reactive<FormRules>({
|
|||
location: [
|
||||
{ required: true, message: "位置信息必填", trigger: "blur" },
|
||||
{ type: 'number', min: 0, message: '位置编号不能为负数', trigger: 'blur' }
|
||||
],
|
||||
belongType: [
|
||||
{ required: true, message: "请选择归属类型", trigger: "change" }
|
||||
]
|
||||
});
|
||||
|
||||
|
@ -91,6 +95,14 @@ watch(() => props.cabinetInfo, (newVal) => {
|
|||
<el-option v-for="option in templateOptions" :key="option.value" :label="option.label" :value="option.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<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-button type="primary" :icon="useRenderIcon(Confirm)" @click="handleConfirm">
|
||||
确认
|
||||
|
|
|
@ -92,7 +92,8 @@ 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 v-model="searchFormParams.cabinetName" placeholder="请输入柜体名称" clearable class="!w-[200px]" />
|
||||
<el-input @keyup.enter.native.prevent="onSearch" v-model="searchFormParams.cabinetName" placeholder="请输入柜体名称"
|
||||
clearable class="!w-[200px]" />
|
||||
</el-form-item>
|
||||
<el-form-item label="" prop="cabinetType">
|
||||
<el-select v-model="searchFormParams.cabinetType" placeholder="请选择柜体类型" clearable class="!w-[180px]">
|
||||
|
|
|
@ -13,6 +13,7 @@ export interface FormDTO {
|
|||
templateNo: string;
|
||||
lockControlNo: number;
|
||||
location: number;
|
||||
belongType: number;
|
||||
}
|
||||
|
||||
const props = defineProps({
|
||||
|
@ -30,7 +31,8 @@ const formData = reactive<FormDTO>({
|
|||
cabinetType: 1,
|
||||
templateNo: "",
|
||||
lockControlNo: 0,
|
||||
location: 0
|
||||
location: 0,
|
||||
belongType: 0
|
||||
});
|
||||
|
||||
const rules = reactive<FormRules>({
|
||||
|
@ -43,6 +45,9 @@ const rules = reactive<FormRules>({
|
|||
location: [
|
||||
{ required: true, message: "位置信息必填", trigger: "blur" },
|
||||
{ type: 'number', min: 0, message: '位置编号不能为负数', trigger: 'blur' }
|
||||
],
|
||||
belongType: [
|
||||
{ required: true, message: "请选择归属类型", trigger: "change" }
|
||||
]
|
||||
});
|
||||
|
||||
|
@ -87,6 +92,14 @@ const templateOptions = Object.entries(CabinetImgMap).map(([value, item]) => ({
|
|||
<el-option v-for="option in templateOptions" :key="option.value" :label="option.label" :value="option.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<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-button type="primary" :icon="useRenderIcon(Confirm)" @click="handleConfirm">
|
||||
确认
|
||||
|
|
|
@ -160,7 +160,8 @@ 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 v-model="searchFormParams.cabinetName" placeholder="请输入柜体名称" clearable class="!w-[200px]" />
|
||||
<el-input @keyup.enter.native.prevent="onSearch" v-model="searchFormParams.cabinetName" placeholder="请输入柜体名称"
|
||||
clearable class="!w-[200px]" />
|
||||
</el-form-item>
|
||||
<el-form-item label="柜体类型:" prop="cabinetType">
|
||||
<el-select v-model="searchFormParams.cabinetType" placeholder="请选择类型" clearable class="!w-[180px]">
|
||||
|
|
|
@ -0,0 +1,127 @@
|
|||
<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";
|
||||
import Refresh from "@iconify-icons/ep/refresh";
|
||||
import { ElMessage } from "element-plus";
|
||||
import { useWxStore } from "@/store/modules/wx";
|
||||
|
||||
defineOptions({
|
||||
name: "UserBalance"
|
||||
});
|
||||
|
||||
const wxStore = useWxStore(); // 微信相关状态管理
|
||||
const formRef = ref();
|
||||
const tableRef = ref();
|
||||
|
||||
// 搜索表单
|
||||
const searchFormParams = ref<QyUserQuery>({
|
||||
name: null,
|
||||
mobile: null,
|
||||
corpid: wxStore.corpid, // 企业ID
|
||||
balancePage: 1
|
||||
});
|
||||
|
||||
// 分页参数
|
||||
const pagination = ref({
|
||||
pageSize: 10,
|
||||
currentPage: 1,
|
||||
total: 0
|
||||
});
|
||||
|
||||
const loading = ref(false);
|
||||
const dataList = ref<QyUserDTO[]>([]);
|
||||
const totalBalance = ref(0);
|
||||
|
||||
// 获取用户余额列表
|
||||
const getList = async () => {
|
||||
try {
|
||||
loading.value = true;
|
||||
const { data } = await getQyUserListApi({
|
||||
...searchFormParams.value,
|
||||
pageSize: pagination.value.pageSize,
|
||||
pageNum: pagination.value.currentPage
|
||||
});
|
||||
dataList.value = data.rows;
|
||||
pagination.value.total = data.total;
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 搜索
|
||||
const onSearch = () => {
|
||||
pagination.value.currentPage = 1;
|
||||
getList();
|
||||
};
|
||||
|
||||
// 重置
|
||||
const resetForm = () => {
|
||||
formRef.value.resetFields();
|
||||
onSearch();
|
||||
};
|
||||
|
||||
// 分页变化
|
||||
const handlePaginationChange = () => getList();
|
||||
|
||||
// 获取总余额
|
||||
const getTotalBalance = async () => {
|
||||
try {
|
||||
const { data } = await getTotalBalanceApi(wxStore.corpid);
|
||||
totalBalance.value = data;
|
||||
} catch (error) {
|
||||
console.error('获取总余额失败:', error);
|
||||
}
|
||||
};
|
||||
|
||||
// 在getList中调用获取总余额
|
||||
getList().then(() => getTotalBalance());
|
||||
|
||||
</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="姓名:" prop="name">
|
||||
<el-input @keyup.enter.native.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-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="`用户总余额: ${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>
|
||||
<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>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.main {
|
||||
padding: 16px;
|
||||
}
|
||||
</style>
|
|
@ -133,13 +133,16 @@ getList();
|
|||
value-format="YYYY-MM-DD HH:mm:ss" class="!w-[200px]" />
|
||||
</el-form-item>
|
||||
<el-form-item label="审批ID:" prop="approvalId">
|
||||
<el-input v-model.number="searchFormParams.approvalId" placeholder="请输入审批ID" clearable class="!w-[180px]" />
|
||||
<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 v-model.number="searchFormParams.orderId" placeholder="请输入订单ID" clearable class="!w-[180px]" />
|
||||
<el-input @keyup.enter.native.prevent="onSearch" v-model.number="searchFormParams.orderId" placeholder="请输入订单ID"
|
||||
clearable class="!w-[180px]" />
|
||||
</el-form-item>
|
||||
<el-form-item label="商品ID:" prop="goodsId">
|
||||
<el-input v-model.number="searchFormParams.goodsId" placeholder="请输入商品ID" clearable class="!w-[180px]" />
|
||||
<el-input @keyup.enter.native.prevent="onSearch" v-model.number="searchFormParams.goodsId" 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]">
|
||||
|
|
|
@ -231,7 +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 v-model.number="searchFormParams.cellNo" placeholder="请输入单元格号" clearable class="!w-[180px]" />
|
||||
<el-input @keyup.enter.native.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]">
|
||||
|
@ -311,8 +312,8 @@ const handleClearGoods = async (row: CabinetCellDTO) => {
|
|||
</el-table-column>
|
||||
</el-table>
|
||||
<el-pagination v-model:current-page="pagination.currentPage" v-model:page-size="pagination.pageSize"
|
||||
:page-sizes="[5,8,10,11,12,13,14,15,16,18,20]" layout="total, sizes, prev, pager, next, jumper" :total="pagination.total"
|
||||
@size-change="onSizeChange" @current-change="onCurrentChange" class="pagination" />
|
||||
:page-sizes="[5, 8, 10, 11, 12, 13, 14, 15, 16, 18, 20]" layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="pagination.total" @size-change="onSizeChange" @current-change="onCurrentChange" class="pagination" />
|
||||
</div>
|
||||
<el-dialog v-model="configVisible" title="配置商品" width="80%">
|
||||
<CabinetGoodsConfigModal v-model="configVisible" :cell-id="currentCellId" @refresh="getList" />
|
||||
|
|
|
@ -158,10 +158,12 @@ 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 v-model="searchFormParams.categoryName" placeholder="请输入分类名称" clearable class="!w-[200px]" />
|
||||
<el-input @keyup.enter.native.prevent="onSearch" v-model="searchFormParams.categoryName" placeholder="请输入分类名称"
|
||||
clearable class="!w-[200px]" />
|
||||
</el-form-item>
|
||||
<el-form-item label="排序:" prop="sort">
|
||||
<el-input-number v-model="searchFormParams.sort" :min="0" class="!w-[120px]" />
|
||||
<el-input-number @keyup.enter.native.prevent="onSearch" v-model="searchFormParams.sort" :min="0"
|
||||
class="!w-[120px]" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" :icon="useRenderIcon(Search)" @click="onSearch">
|
||||
|
|
|
@ -134,7 +134,8 @@ const handleEdit = (row: GoodsDTO) => {
|
|||
<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 v-model="searchFormParams.goodsName" placeholder="请输入商品名称" clearable class="!w-[200px]" />
|
||||
<el-input @keyup.enter.native.prevent="onSearch" v-model="searchFormParams.goodsName" 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]">
|
||||
|
|
|
@ -142,10 +142,12 @@ getList();
|
|||
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-input @keyup.enter.native.prevent="onSearch" 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-input @keyup.enter.native.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]">
|
||||
|
|
|
@ -103,7 +103,7 @@ async function openDialog(type: "add" | "update", row?: RoleDTO) {
|
|||
</el-form>
|
||||
|
||||
<PureTableBar
|
||||
title="角色列表(仅演示,操作后不生效)"
|
||||
title="角色列表"
|
||||
:columns="columns"
|
||||
@refresh="onSearch"
|
||||
>
|
||||
|
@ -133,9 +133,6 @@ async function openDialog(type: "add" | "update", row?: RoleDTO) {
|
|||
background: 'var(--el-table-row-hover-bg-color)',
|
||||
color: 'var(--el-text-color-primary)'
|
||||
}"
|
||||
@selection-change="handleSelectionChange"
|
||||
@page-size-change="handleSizeChange"
|
||||
@page-current-change="handleCurrentChange"
|
||||
>
|
||||
<template #operation="{ row }">
|
||||
<el-button
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
import VDialog from "@/components/VDialog/VDialog.vue";
|
||||
import { computed, reactive, ref } from "vue";
|
||||
import { useUserStoreHook } from "@/store/modules/user";
|
||||
import { ElMessage, FormInstance, FormRules } from "element-plus";
|
||||
import { ElMessage, ElTree, FormInstance, FormRules } from "element-plus";
|
||||
import {
|
||||
AddRoleCommand,
|
||||
RoleDTO,
|
||||
|
@ -71,6 +71,7 @@ function handleOpened() {
|
|||
if (props.row) {
|
||||
Object.assign(formData, props.row);
|
||||
formData.menuIds = props.row.selectedMenuList;
|
||||
treeRef.value!.setCheckedKeys(props.row.selectedMenuList);
|
||||
} else {
|
||||
formRef.value?.resetFields();
|
||||
}
|
||||
|
@ -100,20 +101,42 @@ async function handleConfirm() {
|
|||
loading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
const processedMenuOptions = computed(() => {
|
||||
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.forEach(child => {
|
||||
collectMenus(child);
|
||||
});
|
||||
}
|
||||
};
|
||||
props.menuOptions.forEach(menuOption => {
|
||||
collectMenus(menuOption);
|
||||
})
|
||||
|
||||
return categories;
|
||||
});
|
||||
</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 show-full-screen fixed-body-height use-body-scrolling :title="type === 'add' ? '新增角色' : '更新角色'"
|
||||
v-model="visible" :loading="loading" @confirm="handleConfirm" @cancel="visible = false" @opened="handleOpened">
|
||||
<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" />
|
||||
|
@ -126,29 +149,20 @@ async function handleConfirm() {
|
|||
</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 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">
|
||||
<el-tree
|
||||
ref="treeRef"
|
||||
:props="{ label: 'menuName', children: 'children' }"
|
||||
:data="props.menuOptions"
|
||||
node-key="id"
|
||||
check-strictly
|
||||
show-checkbox
|
||||
default-expand-all
|
||||
check-on-click-node
|
||||
:expand-on-click-node="false"
|
||||
:default-checked-keys="formData.menuIds"
|
||||
@check-change="handleCheckChange"
|
||||
style="width: 100%"
|
||||
/>
|
||||
<el-checkbox-group v-model="formData.menuIds" class="checkbox-group">
|
||||
<template v-for="menu in processedMenuOptions" :key="menu.id">
|
||||
<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 prop="remark" label="备注" style="margin-bottom: 0">
|
||||
<el-input type="textarea" v-model="formData.remark" />
|
||||
|
@ -156,3 +170,9 @@ async function handleConfirm() {
|
|||
</el-form>
|
||||
</v-dialog>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.divider {
|
||||
margin: 4px 0;
|
||||
}
|
||||
</style>
|
|
@ -53,7 +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 v-model="searchFormParams.nickname" placeholder="请输入" clearable class="!w-[160px]" />
|
||||
<el-input @keyup.enter.native.prevent="onSearch" v-model="searchFormParams.nickname" placeholder="请输入"
|
||||
clearable class="!w-[160px]" />
|
||||
</el-form-item>
|
||||
<!-- <el-form-item label="用户编号:" prop="userId">
|
||||
<el-input
|
||||
|
|
|
@ -3,6 +3,9 @@ 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";
|
||||
import { Ab98UserTagDTO, addAb98UserTagApi, deleteAb98UserTagConfirmApi, getAb98UserTagListApi } from "@/api/ab98/tag";
|
||||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
import { PureTableBar } from "@/components/RePureTableBar";
|
||||
|
||||
defineOptions({
|
||||
name: "Ab98UserDetail"
|
||||
|
@ -11,6 +14,12 @@ defineOptions({
|
|||
const route = useRoute();
|
||||
const userInfo = ref<Ab98UserDetailDTO>({});
|
||||
const loading = ref(false);
|
||||
const tags = ref<Ab98UserTagDTO[]>([]);
|
||||
const tagsLoading = ref(false);
|
||||
const showAddTagDialog = ref(false);
|
||||
const addTagForm = ref({
|
||||
tagName: ''
|
||||
});
|
||||
|
||||
// 基础信息
|
||||
const basicInfo = ref({
|
||||
|
@ -57,11 +66,64 @@ async function fetchUserDetail() {
|
|||
const userId = route.query.id;
|
||||
const { data } = await getAb98UserDetailApi(Number(userId));
|
||||
userInfo.value = data;
|
||||
await fetchUserTags();
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function fetchUserTags() {
|
||||
try {
|
||||
tagsLoading.value = true;
|
||||
const { data } = await getAb98UserTagListApi({
|
||||
ab98UserId: userInfo.value.ab98UserId,
|
||||
pageSize: 6,
|
||||
pageNum: 1
|
||||
});
|
||||
tags.value = data.rows;
|
||||
} finally {
|
||||
tagsLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function handleAddTag() {
|
||||
try {
|
||||
tagsLoading.value = true;
|
||||
await addAb98UserTagApi({
|
||||
ab98UserId: userInfo.value.ab98UserId,
|
||||
tagName: addTagForm.value.tagName
|
||||
});
|
||||
showAddTagDialog.value = false;
|
||||
addTagForm.value.tagName = '';
|
||||
await fetchUserTags();
|
||||
ElMessage.success('标签添加成功');
|
||||
} catch (error) {
|
||||
ElMessage.error('标签添加失败');
|
||||
} finally {
|
||||
tagsLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function handleDeleteTag(tagId: number) {
|
||||
try {
|
||||
await ElMessageBox.confirm('确定要删除这个标签吗?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
});
|
||||
tagsLoading.value = true;
|
||||
await deleteAb98UserTagConfirmApi(tagId);
|
||||
await fetchUserTags();
|
||||
ElMessage.success('标签删除成功');
|
||||
} catch (error) {
|
||||
if (error !== 'cancel') {
|
||||
ElMessage.error('标签删除失败');
|
||||
}
|
||||
} finally {
|
||||
tagsLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
fetchUserDetail();
|
||||
});
|
||||
|
@ -107,6 +169,17 @@ onMounted(() => {
|
|||
<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">
|
||||
<div class="tag-container">
|
||||
<div class="user-tags" v-if="tags.length > 0">
|
||||
<el-tag v-for="tag in tags" :key="tag.tagId" class="tag-item" closable
|
||||
@close="handleDeleteTag(tag.tagId)">
|
||||
{{ tag.tagName }}
|
||||
</el-tag>
|
||||
</div>
|
||||
<el-button type="primary" size="small" @click="showAddTagDialog = true">添加标签</el-button>
|
||||
</div>
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
|
||||
|
||||
|
@ -170,6 +243,16 @@ onMounted(() => {
|
|||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
<el-dialog v-model="showAddTagDialog" title="添加标签" width="30%">
|
||||
<el-form :model="addTagForm" label-width="80px">
|
||||
<el-form-item label="标签名称">
|
||||
<el-input v-model="addTagForm.tagName" placeholder="请输入标签名称" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button type="primary" @click="handleAddTag">确定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -217,6 +300,45 @@ onMounted(() => {
|
|||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
.tag-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
width: 100%;
|
||||
|
||||
.user-tags {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.el-button {
|
||||
width: 80px;
|
||||
margin-left: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.el-button {
|
||||
margin-top: 5px;
|
||||
background-color: #409eff;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
padding: 8px 16px;
|
||||
font-size: 14px;
|
||||
transition: all 0.3s;
|
||||
|
||||
&:hover {
|
||||
background-color: #66b1ff;
|
||||
box-shadow: 0 2px 8px rgba(64, 158, 255, 0.3);
|
||||
}
|
||||
|
||||
&:active {
|
||||
background-color: #3a8ee6;
|
||||
}
|
||||
}
|
||||
|
||||
.order-item {
|
||||
margin-bottom: 20px;
|
||||
padding: 10px;
|
||||
|
|
|
@ -10,6 +10,7 @@ import Refresh from "@iconify-icons/ep/refresh";
|
|||
import View from "@iconify-icons/ep/view";
|
||||
import { useRouter } from "vue-router";
|
||||
import { useMultiTagsStoreHook } from "@/store/modules/multiTags";
|
||||
import { getAb98UserTagNamesApi } from "@/api/ab98/tag";
|
||||
|
||||
defineOptions({
|
||||
name: "Ab98User"
|
||||
|
@ -17,10 +18,13 @@ defineOptions({
|
|||
|
||||
const router = useRouter();
|
||||
const formRef = ref();
|
||||
const searchFormParams = reactive<Ab98UserQuery>({
|
||||
const tagOptions = ref<string[]>([]);
|
||||
const searchFormParams = reactive<Ab98UserQuery & { search?: string }>({
|
||||
name: undefined,
|
||||
tel: undefined,
|
||||
idnum: undefined
|
||||
idnum: undefined,
|
||||
tagName: undefined,
|
||||
search: undefined
|
||||
});
|
||||
|
||||
const pageLoading = ref(false);
|
||||
|
@ -51,6 +55,27 @@ async function getList() {
|
|||
pagination.total = data.total;
|
||||
}
|
||||
|
||||
const handleSearchInput = (value) => {
|
||||
// 身份证号正则(18位)
|
||||
const idCardRegex = /^[1-9]\d{5}(18|19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[\dXx]$/;
|
||||
// 手机号正则
|
||||
const phoneRegex = /^1[3-9]\d{9}$/;
|
||||
|
||||
if (idCardRegex.test(value)) {
|
||||
searchFormParams.idnum = value;
|
||||
searchFormParams.name = '';
|
||||
searchFormParams.tel = '';
|
||||
} else if (phoneRegex.test(value)) {
|
||||
searchFormParams.tel = value;
|
||||
searchFormParams.name = '';
|
||||
searchFormParams.idnum = '';
|
||||
} else {
|
||||
searchFormParams.name = value;
|
||||
searchFormParams.tel = '';
|
||||
searchFormParams.idnum = '';
|
||||
}
|
||||
};
|
||||
|
||||
const resetForm = formEl => {
|
||||
if (!formEl) return;
|
||||
formEl.resetFields();
|
||||
|
@ -78,6 +103,9 @@ const handleViewDetail = (row: Ab98UserDTO) => {
|
|||
|
||||
onMounted(() => {
|
||||
getList();
|
||||
getAb98UserTagNamesApi().then(res => {
|
||||
tagOptions.value = res.data;
|
||||
});
|
||||
})
|
||||
</script>
|
||||
|
||||
|
@ -86,14 +114,14 @@ onMounted(() => {
|
|||
<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 label="搜索:" prop="search">
|
||||
<el-input v-model="searchFormParams.search" placeholder="请输入姓名/手机号/身份证" clearable class="!w-[300px]"
|
||||
@keyup.enter.native.prevent="onSearch" @change="handleSearchInput" />
|
||||
</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 label="标签:" prop="tagName">
|
||||
<el-select v-model="searchFormParams.tagName" placeholder="请选择" clearable class="!w-[160px]">
|
||||
<el-option v-for="item in tagOptions" :key="item" :label="item" :value="item" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" :icon="useRenderIcon(Search)" :loading="pageLoading" @click="onSearch">
|
||||
|
|
|
@ -55,7 +55,6 @@ export function useHook() {
|
|||
|
||||
// 下拉选项数据
|
||||
const deptTreeList = ref([]); // 部门树形数据
|
||||
const postOptions = ref([]); // 岗位选项
|
||||
const roleOptions = ref([]); // 角色选项
|
||||
|
||||
/**
|
||||
|
@ -107,10 +106,6 @@ export function useHook() {
|
|||
"status"
|
||||
);
|
||||
|
||||
// 获取岗位选项
|
||||
const postResponse = await getPostListApi({});
|
||||
postOptions.value = postResponse.data.rows;
|
||||
|
||||
// 获取角色选项
|
||||
const roleResponse = await getRoleListApi({});
|
||||
roleOptions.value = roleResponse.data.rows;
|
||||
|
|
|
@ -51,7 +51,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="name">
|
||||
<el-input v-model="searchFormParams.name" placeholder="请输入" clearable class="!w-[160px]" />
|
||||
<el-input @keyup.enter.native.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">
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<script setup lang="ts">
|
||||
import { Goods, Shop, Document, Money } from '@element-plus/icons-vue';
|
||||
import { getStats, TodayLatestOrderGoodsDTO, TopGoodsDTO } from '@/api/shop/stats';
|
||||
import { onMounted, ref } from 'vue';
|
||||
import { markRaw, onMounted, ref } from 'vue';
|
||||
|
||||
defineOptions({
|
||||
name: "Welcome"
|
||||
|
@ -36,10 +36,10 @@ onMounted(async () => {
|
|||
try {
|
||||
const { data } = await getStats();
|
||||
shopData.value = [
|
||||
{ name: '商店', icon: Shop, value: data.shopCount },
|
||||
{ name: '商品总数量', icon: Goods, value: data.goodsCount },
|
||||
{ name: '商品总订单', icon: Document, value: data.orderCount },
|
||||
{ name: '商品总金额', icon: Money, value: data.goodsTotalAmount }
|
||||
{ name: '商店', icon: markRaw(Shop), value: data.shopCount },
|
||||
{ name: '商品总数量', icon: markRaw(Goods), value: data.goodsCount },
|
||||
{ name: '商品总订单', icon: markRaw(Document), value: data.orderCount },
|
||||
{ name: '商品总金额', icon: markRaw(Money), value: data.goodsTotalAmount }
|
||||
];
|
||||
unReturnedData.value = [
|
||||
{ name: '未还商品', value: data.unReturnedGoodsCount },
|
||||
|
@ -353,6 +353,8 @@ onMounted(async () => {
|
|||
}
|
||||
|
||||
.goods-container {
|
||||
margin-bottom: 0;
|
||||
|
||||
.goods-right {
|
||||
width: 150px;
|
||||
}
|
||||
|
@ -363,6 +365,8 @@ onMounted(async () => {
|
|||
}
|
||||
|
||||
.order-container {
|
||||
margin-bottom: 0;
|
||||
|
||||
.goods-right {
|
||||
width: 250px;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue