474 lines
14 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="code">
<el-input
v-model="formInline.code"
placeholder="请输入品牌编码"
clearable
/>
</el-form-item>
<el-form-item label="品牌名称" prop="title">
<el-input
v-model="formInline.title"
placeholder="请输入品牌名称"
clearable
/>
</el-form-item>
<el-form-item label="使用状态" prop="status">
<el-select v-model="formInline.status" placeholder="请选择" clearable>
<el-option v-for="item in statusList" :key="item.id" :value="item.id" :label="item.name" />
</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 class="el-button-gry" 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: 10px"
>批量删除</el-button
>
<el-button type="primary" class="el-button-gry" icon="plus" @click="handleAdd"
>添加品牌</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"
:rowkey="'id'"
>
<!-- 自定义-图片 -->
<template #imgPath="slotProps">
<div class="table-cell-img-box">
<img :src="slotProps.row.imgPath" class="table-cell-img" alt="" />
</div>
</template>
<!-- 自定义-状态 -->
<template #status="slotProps">
<span v-if="slotProps.row.status == 1" class="color-green"
>使用中</span
>
<span v-else-if="slotProps.row.status == 0" class="color-red"
>已停用</span
>
</template>
<!-- 自定义-操作 -->
<template #action="slotProps">
<el-button v-if="slotProps.row.status == 0" text class="el-button-custom" @click="startStop(slotProps.row)">启用</el-button>
<el-button v-if="slotProps.row.status == 1" text class="el-button-custom" @click="startStop(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>
<!-- 添加/编辑商品 -->
<el-dialog v-model="dialogFormVisible" :title="dialogTitle" width="500" :close-on-click-modal="false">
<el-form :model="dialogForm" :label-width="'80'" :rules="dialogFormRules" ref="dialogRef">
<el-form-item label="品牌名称" prop="title">
<el-input v-model="dialogForm.title" autocomplete="off" placeholder="请输入品牌名称" />
</el-form-item>
<el-form-item label="品牌图片" prop="imgPath">
<myUploadImage v-model="dialogForm.imgPath" :limit="1" ></myUploadImage>
</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 myUploadImage from "@/components/myUploadImage.vue";
import Mock from "mockjs";
import {getBrandbaseList,addBrand,updateBrand,deleteBrand,getBrandInfo,updateStatusBrand} from "@/api/brand/index";
import { id } from "element-plus/es/locales.mjs";
import { ElMessage,ElMessageBox } from "element-plus";
const formInline = reactive({
id: "",
imgPath:'',//商品图片
title: "",//商品名称
code:'',//商品编码
phoneNumber: "",//时间
applicationNum:'',//申请数量
useNum:'',//使用数量
status: "",//状态
startDate: "",//开始时间
endDate: "",//结束时间
current: 1,
size: 10,
});
let isADD = ref(true);
const dialogFormVisible = ref(false);
const dialogRef = ref(null);
const dialogTitle = ref("添加品牌");
let dialogForm = reactive({
id: "",
title: "",
imgPath:"",
});
const dialogFormRules = ref({
title: [
{ required: true, message: "请输入品牌名称", trigger: "blur" },
]
});
const statusList = ref([
{ name: "使用中", id: "1" },
{ name: "已停用", id: "0" },
]);
// 禁用开始日期的逻辑(不能晚于已选的结束日期)
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 loadData = async () => {
tableLoading.value = true;
let prams = { ...formInline };
try {
prams.startDate = formInline.startDate ? formInline.startDate + " 00:00:00" : "";
prams.endDate = formInline.endDate ? formInline.endDate + " 23:59:59" : "";
let response = await getBrandbaseList(prams);
if (response.code == 200) {
tableData.value = response.data.records;
tableTotal.value = response.data.total;
}
} catch (error) {
}
tableLoading.value = false;
};
const onSubmit = () => {
formInline.current = 1;
loadData();
};
const resetForm = () => {
searchForm.value.resetFields();
formInline.endDate = "";
loadData();
};
// 表格数据
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([
{ prop: "id", label: "ID" },
{ prop: "imgPath", label: "品牌LOGO", slotName:'imgPath', width: "120", align: "left" },
{ prop: "title", label: "品牌名称" },
{ prop: "code", label: "品牌编码", width: "120" },
{ prop: "createTime", label: "时间", width: "120" },
{ prop: "applicationNum", label: "申请数量" },
{ prop: "useNum", label: "使用数量" },
{ prop: "status", label: "状态", slotName: "status", width: "140"},
{ prop: "action", label: "操作", slotName: "action",width: "140",align: "center" },
]);
// 自定义表头类名,也可以在columns指定列中添加headerClassName: 'custom-header'
const getHeaderClass = ({ column }) => {
return "custom-header";
};
// 分页变化
const handlePaginationChange = ({ page, pageSize }) => {
console.log("分页变化:", page, pageSize);
formInline.current = page;
formInline.size = pageSize;
// 这里可以调用API获取新数据
loadData();
};
// 多选框变化
const handleSelectionChange = (selection) => {
console.log("选中项:", selection);
selectedIds.value = [];
selection.forEach(element => {
selectedIds.value.push(element.id);
});
};
// 批量删除
const batchDelete = async () => {
// deleteGoods(selectedIds.value.join(","));
ElMessageBox.confirm("确定要删除选中的数据吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(async () => {
deleteGoods(selectedIds.value);
})
.catch(() => {
ElMessage.info("已取消删除");
})
};
const deleteGoods = async (param) => {
console.log("批量删除参数:", param);
try {
tableLoading.value = true;
let res = await deleteBrand(param);
tableLoading.value = false;
if (res.code == 200) {
ElMessage.success("删除成功");
loadData();
} else {
ElMessage.error(res.msg);
}
} catch (error) {
tableLoading.value = false;
}
};
// 添加商品
const handleAdd = () => {
resetDlg();
dialogTitle.value = "添加品牌";
isADD.value = true;
dialogFormVisible.value = true;
// console.log(formInline);
};
//提交保存
const onSaveCategory = async () => {
dialogRef.value.validate(async (valid) => {
if (valid) {
if(isADD.value){
let response = await addBrand(dialogForm);
if (response.code === 200) {
dialogFormVisible.value = false;
ElMessage.success("新增成功!");
dialogRef.value.resetFields();
loadData();
} else {
ElMessage.error(response.message);
}
}else{
let response = await updateBrand(dialogForm);
if (response.code === 200) {
dialogFormVisible.value = false;
ElMessage.success("编辑成功!");
dialogRef.value.resetFields();
loadData();
} else {
ElMessage.error(response.message);
}
}
}
});
};
//启用停用
const startStop = async (row) => {
let status = row.status == 1 ? 0 : 1;
let params = { id: row.id, status: status };
let response = await updateStatusBrand(params);
if (response.code === 200) {
ElMessage.success("操作成功!");
loadData();
} else {
ElMessage.error(response.message);
}
};
// 编辑操作
const handleEdit = async(row) => {
resetDlg();
isADD.value = false;
dialogFormVisible.value = true;
let response = await getBrandInfo(row.id);
if (response.code === 200) {
Object.assign(dialogForm, response.data); // 保持响应性
dialogTitle.value = "编辑品牌";
} else {
ElMessage.error(response.message);
}
};
// 删除操作
const handleDelete = async(row) => {
//提示一下是否确定删除
ElMessageBox.confirm("确定要删除吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(async () => {
let response = await deleteBrand(row.id);
if (response.code === 200) {
ElMessage.success("品牌删除成功!");
loadData();
} else {
ElMessage.error(response.message);
}
})
.catch(() => {
ElMessage.info("已取消删除");
})
};
//取消弹框
const cancelDialog = () => {
resetDlg();
};
const resetDlg= () => {
dialogRef.value?.resetFields(); // 重置表单验证状态
Object.assign(dialogForm, { // 保持响应性,手动清空字段
id: "",
title: "",
imgPath: "",
code: ""
});
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;
// 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>
.table-toolbar {
width: 300px;
height: 50px;
position: absolute;
right: 0;
top: 0;
display: flex;
justify-content: end;
padding: 14px 16px 0 0;
}
</style>