<template>
|
<div class="app-container">
|
<el-form :model="queryParams" ref="queryRef" v-show="showSearch" :inline="true" label-width="100px">
|
<el-form-item label="分类名称" prop="className">
|
<el-input v-model="queryParams.className" placeholder="请输入分类名称" style="width: 200px" />
|
</el-form-item>
|
<el-form-item>
|
<el-button type="primary" icon="Search" @click="getDataList">搜索</el-button>
|
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
</el-form-item>
|
</el-form>
|
<el-row :gutter="10" class="mb8">
|
<el-col :span="1.5">
|
<el-button type="primary" plain icon="Plus" :disabled="power.add" @click="handleAdd" v-hasPermi="['system:role:add']">新增</el-button>
|
</el-col>
|
<el-col :span="1.5">
|
<el-button type="danger" plain icon="Delete" :disabled="power.multiple" @click="handleDelete()" v-hasPermi="['system:role:remove']">删除</el-button>
|
</el-col>
|
<right-toolbar v-model:showSearch="showSearch" @queryTable="getDataList"></right-toolbar>
|
</el-row>
|
<el-table
|
v-loading="tableOption.loading"
|
:data="dataTable"
|
ref="tableRef"
|
@expand-change="expandChange"
|
@selection-change="handleSelectionChange"
|
@cell-dblclick="handleInfo"
|
lazy
|
row-key="classCode"
|
:load="tableLoad"
|
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
|
>
|
<el-table-column type="selection" width="50" align="center" />
|
<el-table-column label="名称" align="center" key="className" prop="className" />
|
<el-table-column label="缩略图" align="center">
|
<template #default="scope">
|
<div class="custom-img">
|
<el-image :src="baseUrl + scope.row.classImg" fit="contain"> </el-image>
|
</div>
|
</template>
|
</el-table-column>
|
<el-table-column label="分类编码" align="center" key="classCode" prop="classCode" />
|
<el-table-column label="排序" align="center" key="sortNum" prop="sortNum" />
|
<el-table-column label="创建人" align="center" key="createName" prop="createName" width="120" />
|
<el-table-column label="创建时间" align="center" key="createTime" prop="createTime" width="170" />
|
<el-table-column label="操作" align="center" width="120">
|
<template #default="scope">
|
<el-tooltip content="新增子分类" placement="top" v-if="scope.row.hasChildren">
|
<el-button link type="primary" icon="Plus" @click="handleAddSub(scope.row)" v-hasPermi="['system:role:edit']"></el-button>
|
</el-tooltip>
|
<el-tooltip content="修改" placement="top">
|
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:role:edit']"></el-button>
|
</el-tooltip>
|
<el-tooltip content="删除" placement="top">
|
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:role:remove']"></el-button>
|
</el-tooltip>
|
</template>
|
</el-table-column>
|
</el-table>
|
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getDataList" />
|
|
<el-dialog :title="dialogTitle" v-model="isOpenFormData" width="500px" draggable :close-on-click-modal="false">
|
<el-form ref="formRef" :model="data" :rules="formData.rules" label-width="100px">
|
<el-form-item label="分类编码" prop="className" v-if="formData.handleStatus == 2">
|
<el-input v-model="data.classCode" placeholder="请输入分类编码" style="width: 200px" disabled />
|
</el-form-item>
|
<el-form-item label="分类名称" prop="className">
|
<el-input v-model="data.className" placeholder="请输入分类名称" style="width: 200px" />
|
</el-form-item>
|
<el-form-item label="分类图标" prop="classImg">
|
<ImageUpload :limit="1" v-model="data.classImg"></ImageUpload>
|
</el-form-item>
|
<el-form-item label="排序" prop="sortNum">
|
<el-input-number v-model="data.sortNum" :min="0" :max="100" :step="1"></el-input-number>
|
</el-form-item>
|
<el-form-item label="备注" prop="remark">
|
<el-input v-model="data.remark" placeholder="备注" style="width: 200px" />
|
</el-form-item>
|
</el-form>
|
<template #footer>
|
<el-button @click="formData.isOpenFormData = false">取消</el-button>
|
<el-button type="primary" @click="submitDataScope"> 提交 </el-button>
|
</template>
|
</el-dialog>
|
</div>
|
</template>
|
<script setup lang="ts">
|
import { reactive, onMounted, toRefs, getCurrentInstance, ref } from "vue";
|
import { saveClass, getClassInfo, getClassList, getClassThreeList, updateClass, deleteClass } from "@/api/goods/classify";
|
import { classifyDTO, TypeClassifyDTO, TypeClassifyThreeDTO } from "@/types/DTO/classifyDTO";
|
const baseUrl = import.meta.env.VITE_APP_BASE_API;
|
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
const ids = ref<number[]>([]);
|
const row_keys = ref<string[]>([]);
|
const state = reactive({
|
dataTable: [] as TypeClassifyDTO[], //数据列表
|
total: 0, //总条数
|
tableOption: {
|
//表格配置
|
loading: false,
|
},
|
power: {
|
//操作权限
|
add: false,
|
single: false, //
|
multiple: true, //
|
},
|
showSearch: true, //是否显示搜索
|
showAddGoods: false, //是否显示新增
|
isOpenSeletGoods: false, //是否显示选择商品
|
isOpenInfo: false, //是否显示优惠券详情
|
});
|
const { dataTable, total, tableOption, power, showSearch } = toRefs(state);
|
|
const tableRef = ref(); //表格实例
|
|
onMounted(() => {
|
getDataList();
|
});
|
|
//#region commonDisp
|
|
//#endregion
|
|
//#region 查询
|
const queryRef = ref<Omit<Common.formDataType, "formRef">>();
|
const queryParams = reactive({
|
//查询配置参数
|
pageNum: 1,
|
pageSize: 10,
|
className: "",
|
});
|
|
/**
|
* 获取数据列表
|
*/
|
const getDataList = async () => {
|
await getClassList(queryParams).then((res) => {
|
if (res.code == 200) {
|
state.dataTable = res.rows;
|
state.total = res.total;
|
state.tableOption.loading = false;
|
}
|
});
|
};
|
|
let loadMap = new Map();
|
/**
|
* 懒加载方法
|
*/
|
const tableLoad = async (row: TypeClassifyDTO, treeNode: unknown, resolve: (date: TypeClassifyDTO[]) => void) => {
|
// await getClassThreeList(queryParams)
|
loadMap.set(row.classCode, { row, treeNode, resolve });
|
await getClassList({ parentCode: row.classCode, pageNum: 1, pageSize: 1000 }).then((res) => {
|
if (res.code == 200) {
|
// state.dataTable = res.rows;
|
// state.total = res.total;
|
// state.tableOption.loading = false;
|
resolve(res.rows);
|
}
|
});
|
};
|
|
//#region table刷新/局部刷新
|
const tableRefresh = (data: TypeClassifyDTO) => {
|
if (data.parentCode == "0") {
|
//一级分类 直接加载列表
|
getDataList();
|
} else {
|
// let val = state.dataTable.find((f) => f.classCode == data.parentCode);
|
// // console.log("log=====>", val);
|
// if (val) {
|
// // const node = tableRef.value.getNode(val.classCode);
|
// // // 更改属性
|
// // node.loaded = false;
|
// // // 手动调用数据加载方法
|
// // node.loadData();
|
// tableRef.value.store.states.treeData.value[val.classCode].loaded = false;
|
// tableRef.value.store.loadOrToggle(val);
|
// }
|
let { row, node, resolve } = loadMap.get(data.parentCode);
|
tableLoad(row, node, resolve);
|
}
|
};
|
//#endregion
|
|
/**
|
* 展开的行
|
* @param row
|
* @param expanded
|
*/
|
const expandChange = (row: TypeClassifyDTO, expanded: any) => {
|
if (expanded) {
|
row_keys.value.push(row.classCode);
|
} else {
|
row_keys.value.splice(row_keys.value.indexOf(row.classCode), 1);
|
}
|
};
|
|
/**
|
* 重置
|
*/
|
const resetQuery = () => {
|
queryRef.value!.resetFields();
|
};
|
//#endregion
|
|
//#region 新增
|
|
/**
|
* 新增
|
*/
|
const handleAdd = () => {
|
formData.dialogTitle = "新增一级分类";
|
formData.handleStatus = 1;
|
formData.data = { ...classifyDTO };
|
formData.isOpenFormData = true;
|
};
|
|
/**
|
* 新增分类子集
|
*/
|
const handleAddSub = (e: TypeClassifyDTO) => {
|
formData.dialogTitle = "新增二级分类";
|
formData.handleStatus = 1;
|
formData.data = { ...classifyDTO };
|
formData.data.parentCode = e.classCode;
|
formData.isOpenFormData = true;
|
};
|
|
interface formA extends Common.formDataType<TypeClassifyDTO> {}
|
|
const formData = reactive<formA>({
|
data: {} as TypeClassifyDTO,
|
isOpenFormData: false, //是否展开新增对话框
|
dialogTitle: "", //弹窗标题
|
handleStatus: 0,
|
formRef: null,
|
rules: {
|
className: [{ required: true, message: "请输入分类名称", trigger: "change" }],
|
},
|
});
|
|
const { data, isOpenFormData, dialogTitle, formRef } = toRefs(formData);
|
|
/**
|
* 提交表单检验
|
*/
|
const submitDataScope = () => {
|
formData.formRef!.validate((valid) => {
|
if (valid) {
|
if (formData.data.classId) {
|
editData();
|
} else {
|
SaveData();
|
}
|
}
|
});
|
};
|
|
/**
|
* 保存
|
*/
|
const SaveData = async () => {
|
await saveClass(formData.data).then((res) => {
|
if (res.code == 200) {
|
proxy.$modal.msgSuccess("新增成功");
|
state.isOpenSeletGoods = false;
|
tableRefresh(formData.data);
|
formData.isOpenFormData = false;
|
} else {
|
proxy.$modal.msgError(res.msg);
|
}
|
});
|
};
|
|
//#endregion
|
|
//#region 删除
|
/**
|
* 选择时
|
* @param {} row
|
*/
|
const handleSelectionChange = (row: TypeClassifyDTO[]) => {
|
ids.value = row.map((item: TypeClassifyDTO) => item.classId);
|
state.power.multiple = !ids.value.length;
|
};
|
|
/**
|
* 删除
|
*/
|
const handleDelete = (row?: TypeClassifyDTO) => {
|
const roleIds = (row && row.classId) || ids.value;
|
proxy.$modal
|
.confirm("是否确认删除选中的分类?")
|
.then(function () {
|
return deleteClass(roleIds);
|
})
|
.then(() => {
|
getDataList();
|
// let ss = new Set(row_keys.value);
|
row_keys.value.forEach((f) => {
|
let { row, node, resolve } = loadMap.get(f);
|
tableLoad(row, node, resolve);
|
});
|
proxy.$modal.msgSuccess("删除成功");
|
})
|
.catch(() => {});
|
};
|
|
//#endregion
|
|
//#region 修改
|
|
/**
|
* 修改
|
*/
|
const handleUpdate = (e: TypeClassifyDTO) => {
|
getDataInfo(e.classId, () => {
|
formData.dialogTitle = "修改分类";
|
formData.handleStatus = 2;
|
formData.isOpenFormData = true;
|
});
|
};
|
|
/**
|
* 修改
|
*/
|
const editData = async () => {
|
await updateClass(formData.data).then((res) => {
|
if (res.code == 200) {
|
proxy.$modal.msgSuccess("操作成功");
|
state.isOpenSeletGoods = false;
|
// getDataList();
|
tableRefresh(formData.data);
|
formData.isOpenFormData = false;
|
} else {
|
proxy.$modal.msgError(res.msg);
|
}
|
});
|
};
|
|
//#endregion
|
|
//#region 详情
|
|
/**
|
* 展开详情
|
*/
|
const handleInfo = (e: TypeClassifyDTO) => {
|
getDataInfo(e.classId, () => {
|
state.isOpenInfo = true;
|
});
|
};
|
|
/**
|
* 获取详情
|
* @param {} e
|
*/
|
const getDataInfo = async (e: number, fnc: () => void) => {
|
await getClassInfo(e).then((res) => {
|
if (res.code == 200) {
|
let data = res.data;
|
formData.data = { ...data };
|
if (fnc != null) {
|
fnc();
|
}
|
}
|
});
|
};
|
|
//#endregion
|
|
/**
|
* 导出
|
*/
|
const handleExport = () => {};
|
</script>
|
|
<style scoped lang="scss">
|
.custom-img {
|
width: 50px;
|
height: 50px;
|
}
|
._el-row {
|
padding: 5px 0px;
|
border-bottom: 1px solid var(--el-border-color);
|
margin-left: 20px;
|
align-items: center;
|
}
|
.actImage {
|
max-width: 250px;
|
}
|
</style>
|