339 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="violateGoodName">
<el-input v-model="formInline.violateGoodName" placeholder="请输入物品名称" clearable />
</el-form-item>
<br>
<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" 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' }">
<div class="table-toolbar">
<el-button icon="delete" @click="batchDelete" :disabled="btnStatus" style="margin-right: 0px">批量删除</el-button>
<el-button type="primary" icon="plus" @click="addItem">添加物品</el-button>
</div>
<tableComponent :table-data="tableData" :columns="columns" :show-border="false" :show-selection="true"
:header-cell-class-name="getHeaderClass" @page-change="handlePaginationChange" :loading="tableLoading"
@selection-change="handleSelectionChange" :total="tableTotal" :current-page="formInline.current"
:page-size="formInline.size" :showSort="true">
<!-- 自定义-状态 -->
<template #goodsUrl="slotProps">
<div class="table-cell-img-box">
<img :src="slotProps.row.goodsUrl" class="table-cell-img" alt="" />
</div>
</template>
<!-- 自定义-操作 -->
<template #action="slotProps">
<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>
<!-- 添加物品 -->
<el-dialog v-model="dialogFormVisible" :title="dialogTitle" width="500">
<el-form :model="dialogForm" :label-width="'110'" :rules="dialogFormRules" ref="dialogRef">
<el-form-item label="违禁物品名称" prop="violateGoodName">
<el-input v-model="dialogForm.violateGoodName" autocomplete="off" placeholder="请输入违禁物品名称" />
</el-form-item>
<el-form-item label="违禁物品参数" prop="goodParameter">
<el-input v-model="dialogForm.goodParameter" autocomplete="off" placeholder="请输入违禁物品参数" />
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="onSaveCategory">
保存
</el-button>
<el-button @click="cancelDialog">取消</el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script setup>
import { ref, reactive, computed, onMounted, onBeforeUnmount } from "vue";
import tableComponent from "@/components/tableComponent.vue";
import Mock from "mockjs";
import { getViolateGoodPage, violateGoodSave, violateGoodEdit, deleteContraband } from "@/api/goods/info";
import { ca } from "element-plus/es/locales.mjs";
const { proxy } = getCurrentInstance()
import { ElMessage } from 'element-plus'
const formInline = reactive({
violateGoodName: "",
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 = () => {
formInline.current = 1;
if (formInline.startDate && !formInline.endDate) {
ElMessage.warning("请选择结束日期!");
return;
}
if (formInline.endDate && !formInline.startDate) {
ElMessage.warning("请选择开始日期!");
return;
}
loadData();
};
const resetForm = () => {
searchForm.value.resetFields();
};
// 表格数据
const tableData = ref([]);
const selectedIds = ref([]);
const btnStatus = computed(() => {
return selectedIds.value.length <= 0;
});
const tableLoading = ref(false);
const tableTotal = ref(0);
let nowClickRow = ref({});
// 列配置
const columns = ref([]);
const columns1 = ref([
{ prop: "id", label: "ID" },
{ prop: "violateGoodName", label: "违禁物品名称" },
{ prop: "goodParameter", label: "违禁物品参数" },
{ prop: "createTime", label: "创建时间" },
{ prop: "action", label: "操作", slotName: "action" },
]);
// 生成模拟数据
const generateMockData = () => {
return Mock.mock({
"list|10": [
{
"id|+1": 10000,
violateGoodName: '@pick(["毒品", "炸药", "血腥"])', //分类名称
goodParameter: '@pick(["手动编辑", "图片上传"])', //状态
createTime: "@datetime", //添加时间
},
],
}).list;
};
// 加载数据
const loadData = async () => {
tableLoading.value = true;
// tableData.value = generateMockData();
// tableTotal.value = tableData.value.length;
try {
let response = await getViolateGoodPage(formInline);
if (response.code == 200) {
tableData.value = response.data.records;
tableTotal.value = response.data.total;
}
} catch (error) {
}
tableLoading.value = false;
};
// 自定义表头类名,也可以在columns指定列中添加headerClassName: 'custom-header'
const getHeaderClass = ({ column }) => {
return "custom-header";
};
// 分页变化
const handlePaginationChange = ({ page, pageSize }) => {
formInline.current = page;
formInline.size = pageSize;
// 这里可以调用API获取新数据
loadData();
};
// 多选框变化
const handleSelectionChange = (selection, ids) => {
console.log("选中项:", selection, ids);
selectedIds.value = ids;
};
// 编辑操作
const handleEdit = (row) => {
nowClickRow.value = row;
dialogTitle.value = "编辑违禁物品";
dialogFormVisible.value = true;
dialogForm.id = row.id;
dialogForm.violateGoodName = row.violateGoodName;
dialogForm.goodParameter = row.goodParameter;
};
// 删除操作
const handleDelete = (row) => {
onDelete(row.id)
};
// 批量删除
const batchDelete = () => {
onDelete(selectedIds.value.join(","))
};
const onDelete = async (ids) => {
try {
tableLoading.value = true;
let res = await deleteContraband( ids );
tableLoading.value = false;
if (res.code == 200) {
onSubmit();
ElMessage.success("删除成功");
} else {
ElMessage.error(res.msg);
}
} catch (error) {
tableLoading.value = false;
}
};
const dialogFormVisible = ref(false);
const dialogRef = ref(null);
const dialogTitle = ref("添加违禁物品");
const dialogForm = reactive({
violateGoodName: "",
goodParameter: "",
});
const dialogFormRules = ref({
violateGoodName: [
{ required: true, message: "请输入违禁物品名称", trigger: "blur" },
{ min: 2, max: 10, message: "长度在 2 到 10 个字符", trigger: "blur" },
],
goodParameter: [
{ required: true, message: "请输入违禁物品参数", trigger: "blur" },
{ min: 2, max: 10, message: "长度在 2 到 10 个字符", trigger: "blur" },
],
});
// 级联选择器配置
const cascaderProps = ref({
label: "name", // 选项标签字段名
value: "id", // 选项值字段名
children: "children", // 子选项字段名
emitPath: true,
expandTrigger: "hover",
});
const onSaveCategory = () => {
dialogRef.value.validate(async (valid, fields) => {
if (valid) {
try {
proxy.$modal.loading("正在保存...")
let response;
if (dialogTitle.value == "添加违禁物品") {
response = await violateGoodSave(dialogForm);
} else {
response = await violateGoodEdit(dialogForm);
}
proxy.$modal.closeLoading()
if (response.code == 200) {
cancelDialog();
onSubmit();
if (dialogTitle.value == "添加违禁物品") {
ElMessage.success("添加成功!");
} else {
ElMessage.success("编辑成功!");
}
} else {
ElMessage.error(response.msg);
}
} catch (error) {
proxy.$modal.closeLoading()
}
}
});
};
const addItem = () => {
dialogTitle.value = "添加违禁物品";
dialogFormVisible.value = true;
};
const cancelDialog = () => {
dialogRef.value.resetFields();
dialogFormVisible.value = false;
};
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;
};
// 组件挂载时加载数据
onMounted(() => {
columns.value = columns1.value;
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>
.table-toolbar {
width: 300px;
height: 50px;
position: absolute;
right: 0;
top: 0;
display: flex;
justify-content: end;
padding: 14px 16px 0 0;
}
</style>