operation-system/src/views/customer/customerManage.vue

313 lines
11 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

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

<template>
<div class="app-container customer-control">
<div class="container-custom">
<!-- 搜索栏 -->
<div ref="searchBarRef" class="search-box">
<div class="search-bar">
<div class="search-bar-left">
<el-form ref="searchForm" :inline="true" :model="formInline" class="demo-form-inline" :label-width="'auto'">
<el-form-item label="昵称" prop="nickname">
<el-input v-model="formInline.nickname" placeholder="用户昵称" clearable />
</el-form-item>
<el-form-item label="ID" prop="id">
<el-input v-model="formInline.id" placeholder="用户ID" clearable />
</el-form-item>
<el-form-item label="姓名" prop="userName">
<el-input v-model="formInline.userName" placeholder="用户姓名" clearable />
</el-form-item>
<el-form-item label="账号" prop="accountNumber">
<el-input v-model="formInline.accountNumber" placeholder="用户账号" clearable />
</el-form-item>
<el-form-item label="手机号" prop="phoneNumber">
<el-input v-model="formInline.phoneNumber" placeholder="用户手机号" clearable />
</el-form-item>
<el-form-item label="性别" prop="sex">
<el-select v-model="formInline.sex" placeholder="请选择" clearable>
<el-option label="男" value="1" />
<el-option label="女" value="2" />
</el-select>
</el-form-item>
<el-form-item label="用户状态" prop="userStatus">
<el-select v-model="formInline.userStatus" placeholder="请选择" clearable>
<el-option label="异常" value="0" />
<el-option label="正常" value="1" />
</el-select>
</el-form-item>
<el-form-item label="用户分类" prop="userCategory">
<el-select v-model="formInline.userCategory" placeholder="请选择" clearable>
<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="unitPrice">
<el-select v-model="formInline.unitPrice" placeholder="请选择" clearable>
<el-option label="≤500" value="1" />
<el-option label="≤1000" value="2" />
<el-option label="≤1500" value="3" />
</el-select>
</el-form-item>
<el-form-item label="订单数目" prop="ordersNums">
<el-select v-model="formInline.ordersNums" placeholder="请选择" clearable>
<el-option label="≤500" value="1" />
<el-option label="≤1000" value="2" />
<el-option label="≤1500" value="3" />
</el-select>
</el-form-item>
<el-form-item label="申请日期" prop="startDate" style="margin-right: 0">
<el-date-picker v-model="formInline.startDate" type="date" value-format="YYYY-MM-DD"
placeholder="请选择起始日期" clearable :disabled-date="disableStartDate" style="width: 160px" />
<span style="width: 30px; text-align: center; display: inline-block">
-
</span>
<el-date-picker v-model="formInline.endDate" type="date" value-format="YYYY-MM-DD" placeholder="请选择截止日期"
clearable :disabled-date="disableEndDate" style="width: 160px" />
</el-form-item>
</el-form>
</div>
<div class="search-bar-right">
<el-button type="primary" class="el-button-gry" icon="Search" @click="onSubmit">查询</el-button>
<el-button icon="Refresh" style="margin: 16px 0 0 0" @click="resetForm">重置</el-button>
</div>
</div>
</div>
<!-- 表格 -->
<div class="table-cont" :style="{ height: tableViewportHeight + 'px' }">
<tableComponent :table-data="tableData" :columns="columns" :show-border="false" :show-selection="false"
:header-cell-class-name="getHeaderClass" @page-change="handlePaginationChange"
@selection-change="handleSelectionChange" :total="tableTotal" :current-page="formInline.current"
:page-size="formInline.size">
<!-- 自定义-状态 -->
<template #userStatus="slotProps">
<span v-if="slotProps.row.userStatus == 1" class="color-green">正常</span>
<span v-else-if="slotProps.row.userStatus == 0" class="color-red">异常</span>
</template>
<!-- 自定义-操作 -->
<template #action="slotProps">
<el-button text class="el-button-custom" @click="seeDetails(slotProps.row)">查看</el-button>
<el-button text class="el-button-custom" @click="handleEdit(slotProps.row)">编辑</el-button>
<el-button text class="el-button-delete" @click="handleDelete(slotProps.row)">删除</el-button>
</template>
</tableComponent>
</div>
</div>
</div>
</template>
<script setup>
import { ref, reactive, computed, onMounted, onBeforeUnmount } from "vue";
import tableComponent from "@/components/tableComponent.vue";
import Mock from "mockjs";
const iconSize = "16px";
const formInline = reactive({
id: "",
nickname: "",
userName: "",
accountNumber: "",
phoneNumber: "",
sex: "",
userStatus: "",
userCategory: "",
unitPrice: "",
ordersNums: "",
startDate: "",
endDate: "",
current: 1,
size: 10,
});
// 禁用开始日期的逻辑(不能晚于已选的结束日期)
const disableStartDate = (time) => {
if (!formInline.endDate) return false;
const endDate = new Date(formInline.endDate);
return time.getTime() > endDate.getTime();
};
// 禁用结束日期的逻辑(不能早于已选的开始日期)
const disableEndDate = (time) => {
if (!formInline.startDate) return false;
const startDate = new Date(formInline.startDate).setHours(0, 0, 0, 0);
const currentDate = new Date(time).setHours(0, 0, 0, 0);
return currentDate < startDate;
};
const searchForm = ref(null);
const onSubmit = () => {
console.log("submit!");
console.log(formInline);
loadData();
};
const resetForm = () => {
searchForm.value.resetFields();
formInline.endDate = "";
};
// 表格数据
const tableData = ref([]);
const tableLoading = ref(false);
const tableTotal = ref(0);
let nowClickRow = ref({});
// 列配置
const columns = ref([
{ prop: "id", label: "ID" },
{ prop: "nickname", label: "昵称", width: "120" },
{ prop: "userName", label: "姓名" },
{ prop: "accountNumber", label: "账号" },
{ prop: "phoneNumber", label: "手机号", width: "120" },
{ prop: "sex", label: "性别" },
{ prop: "userStatus", label: "用户状态", slotName: "userStatus" },
{ prop: "userCategory", label: "用户分类" },
{ prop: "unitPrice", label: "客单价" },
{ prop: "ordersNums", label: "订单数目" },
{ prop: "action", label: "操作", slotName: "action",width: "140",align: "center" },
]);
// 生成食物主题昵称
const generateFoodNickname = () => {
// 形容词(情绪/风格)
const adjectives = [
"暴躁的",
"快乐的",
"忧郁的",
"疯狂的",
"安静的",
"慵懒的",
"甜甜的",
"咸咸的",
"酸酸的",
"辣辣的",
];
// 食物名词(仅限食物)
const foods = [
"辣椒",
"西瓜",
"土豆",
"番茄",
"黄瓜",
"苹果",
"蛋糕",
"面包",
"披萨",
"冰淇淋",
"奶茶",
"咖啡",
"啤酒",
"炸鸡",
];
// 随机组合:形容词 + 食物
return Mock.mock(`@pick(${adjectives})`) + Mock.mock(`@pick(${foods})`);
};
// 生成模拟数据
const generateMockData = () => {
return Mock.mock({
"list|10": [
{
"id|+1": 10000,
nickname: () => generateFoodNickname(), //昵称
userName: "@cname", //姓名
accountNumber: Mock.mock("@id").toString().slice(0, 10), //账号
phoneNumber: "@integer(13000000000, 18999999999)", //手机号
sex: '@pick(["男", "女"])', //性别
"userStatus|1": [0, 1], //0异常 1正常
"userCategory|1":
'@pick(["活跃/低消费", "活跃/中消费", "活跃/高消费"])', //用户分类
unitPrice: "@float(10, 200, 2, 2)", //客单价
ordersNums: "@integer(10, 200)",
},
],
}).list;
};
// 加载数据
const loadData = async () => {
// 模拟API请求延迟
setTimeout(() => {
tableData.value = generateMockData();
tableTotal.value = tableData.value.length;
}, 500);
// try {
// let response = await getGoodManageInfo(formInline);
// console.log(response);
// if (response.code == 200) {
// tableData.value = response.data.records;
// tableTotal.value = response.data.total;
// }
// } catch (error) {
// console.log(error);
// }
};
// 自定义表头类名,也可以在columns指定列中添加headerClassName: 'custom-header'
const getHeaderClass = ({ column }) => {
return "custom-header";
};
// 分页变化
const handlePaginationChange = ({ page, pageSize }) => {
console.log("分页变化:", page, pageSize);
// 这里可以调用API获取新数据
loadData();
};
// 多选框变化
const handleSelectionChange = (selection) => {
console.log("选中项:", selection);
};
// 查看详情
const seeDetails = (row) => {
nowClickRow.value = row;
console.log("要查看详情的行:", row);
};
// 编辑操作
const handleEdit = (row) => {
nowClickRow.value = row;
console.log("要编辑的行:", row);
};
// 删除操作
const handleDelete = (row) => {
nowClickRow.value = row;
console.log("要编辑的行:", row);
};
const titleRef = ref(null);
const searchBarRef = ref(null);
const tableViewportHeight = ref(0);
// 精确计算可用高度
const calculateTableHeight = () => {
// 获取窗口总高度
const windowHeight = window.innerHeight;
// 获取各组件高度
const headerHeight = titleRef.value?.$el?.offsetHeight || 0;
const searchBarHeight = searchBarRef.value?.offsetHeight || 0;
// 计算容器内边距补偿(根据实际样式调整)
const paddingCompensation = 130;
// 最终计算
tableViewportHeight.value =
windowHeight - headerHeight - searchBarHeight - paddingCompensation;
// console.log(tableViewportHeight.value);
};
// 组件挂载时加载数据
onMounted(() => {
loadData();
calculateTableHeight();
// 添加响应式监听
window.addEventListener("resize", calculateTableHeight);
// 监听DOM变化适用于动态变化的header/searchbar
const observer = new ResizeObserver(calculateTableHeight);
if (titleRef.value?.$el) observer.observe(titleRef.value.$el);
if (searchBarRef.value) observer.observe(searchBarRef.value);
});
onBeforeUnmount(() => {
window.removeEventListener("resize", calculateTableHeight);
});
</script>
<style lang="scss" scoped></style>