src/api/data/ind/category/index.ts | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/views/data/ind/category/CategoryForm.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/views/data/ind/category/index.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
src/api/data/ind/category/index.ts
对比新文件 @@ -0,0 +1,42 @@ import request from '@/config/axios' export interface IndItemCategoryVO { id: string label: string pid: string sort: number } export interface IndItemCategoryReqVO { label?: string } // 查询列表 export const getCategoryList = (params) => { return request.get({ url: '/data/ind/category/list', params}) } // 查询列表 export const getCategoryListAllSimple = () => { return request.get({ url: '/data/ind/category/list-all-simple'}) } // 查询详情 export const getCategory = (id: number) => { return request.get({ url: '/data/ind/category/get?id=' + id}) } // 新增 export const createCategory = (data: ScheduleModelVO) => { return request.post({ url: '/data/ind/category/create', data }) } // 修改 export const updateCategory = (data: ScheduleModelVO) => { return request.put({ url: '/data/ind/category/update', data }) } // 删除 export const deleteCategory = (id: number) => { return request.delete({ url: '/data/ind/category/delete?id=' + id }) } src/views/data/ind/category/CategoryForm.vue
对比新文件 @@ -0,0 +1,141 @@ <template> <Dialog v-model="dialogVisible" :title="dialogTitle"> <el-form ref="formRef" v-loading="formLoading" :model="formData" :rules="formRules" label-width="100px" > <el-form-item label="上级菜单"> <el-tree-select v-model="formData.pid" :data="categoryTree" :default-expanded-keys="[0]" :props="categoryTreeProps" check-strictly node-key="id" /> </el-form-item> <el-form-item label="分类名称" prop="label"> <el-input v-model="formData.label" clearable placeholder="请输入分类名称" /> </el-form-item> <el-form-item label="显示排序" prop="sort"> <el-input-number v-model="formData.sort" :min="0" clearable controls-position="right" /> </el-form-item> </el-form> <template #footer> <el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button> <el-button @click="dialogVisible = false">取 消</el-button> </template> </Dialog> </template> <script lang="ts" setup> import { DICT_TYPE, getIntDictOptions } from '@/utils/dict' import * as CategoryApi from '@/api/data/ind/category' import { CACHE_KEY, useCache } from '@/hooks/web/useCache' import { CommonStatusEnum, SystemMenuTypeEnum } from '@/utils/constants' import { defaultProps, handleTree } from '@/utils/tree' defineOptions({ name: 'IndItemCategoryForm' }) const { wsCache } = useCache() const { t } = useI18n() // 国际化 const message = useMessage() // 消息弹窗 const categoryTreeProps = ref({ children: 'children', label: 'label', value: 'id', isLeaf: 'leaf', emitPath: false }) const dialogVisible = ref(false) // 弹窗的是否展示 const dialogTitle = ref('') // 弹窗的标题 const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用 const formType = ref('') // 表单的类型:create - 新增;update - 修改 const formData = ref({ id: undefined, label: '', pid: '0', sort: Number(undefined) }) const formRules = reactive({ label: [{ required: true, message: '分类名称不能为空', trigger: 'blur' }], sort: [{ required: true, message: '分类顺序不能为空', trigger: 'blur' }] }) const formRef = ref() // 表单 Ref /** 打开弹窗 */ const open = async (type: string, id?: number, parentId?: number) => { dialogVisible.value = true dialogTitle.value = t('action.' + type) formType.value = type resetForm() if (parentId) { formData.value.parentId = parentId } // 修改时,设置数据 if (id) { formLoading.value = true try { formData.value = await CategoryApi.getCategory(id) } finally { formLoading.value = false } } // 获得菜单列表 await getTree() } defineExpose({ open }) // 提供 open 方法,用于打开弹窗 /** 提交表单 */ const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调 const submitForm = async () => { // 校验表单 if (!formRef) return const valid = await formRef.value.validate() if (!valid) return // 提交请求 formLoading.value = true try { const data = formData.value as unknown as CategoryApi.IndItemCategoryVO if (formType.value === 'create') { await CategoryApi.createCategory(data) message.success(t('common.createSuccess')) } else { await CategoryApi.updateCategory(data) message.success(t('common.updateSuccess')) } dialogVisible.value = false // 发送操作成功的事件 emit('success') } finally { formLoading.value = false // 清空,从而触发刷新 wsCache.delete(CACHE_KEY.ROLE_ROUTERS) } } /** 获取下拉框[上级菜单]的数据 */ const categoryTree = ref<Tree[]>([]) // 树形结构 const getTree = async () => { categoryTree.value = [] const res = await CategoryApi.getCategoryListAllSimple() let menu: Tree = { id: '0', label: '主类目', children: [] } menu.children = handleTree(res, 'id', 'pid') categoryTree.value.push(menu) } /** 重置表单 */ const resetForm = () => { formData.value = { id: undefined, label: '', pid: '0', sort: Number(undefined) } formRef.value?.resetFields() } </script> src/views/data/ind/category/index.vue
对比新文件 @@ -0,0 +1,159 @@ <template> <!-- 搜索工作栏 --> <ContentWrap> <el-form ref="queryFormRef" :inline="true" :model="queryParams" class="-mb-15px" label-width="68px" > <el-form-item label="分类名称" prop="name"> <el-input v-model="queryParams.label" class="!w-240px" clearable placeholder="请输入分类名称" @keyup.enter="handleQuery" /> </el-form-item> <el-form-item> <el-button @click="handleQuery"> <Icon class="mr-5px" icon="ep:search" /> 搜索 </el-button> <el-button @click="resetQuery"> <Icon class="mr-5px" icon="ep:refresh" /> 重置 </el-button> <el-button v-hasPermi="['data:ind-item-category:create']" plain type="primary" @click="openForm('create')" > <Icon class="mr-5px" icon="ep:plus" /> 新增 </el-button> <el-button plain type="danger" @click="toggleExpandAll"> <Icon class="mr-5px" icon="ep:sort" /> 展开/折叠 </el-button> </el-form-item> </el-form> </ContentWrap> <!-- 列表 --> <ContentWrap> <el-table v-if="refreshTable" v-loading="loading" :data="list" :default-expand-all="isExpandAll" row-key="id" > <el-table-column :show-overflow-tooltip="true" label="分类名称" prop="label" width="300" /> <el-table-column label="排序" prop="sort" width="60" /> <el-table-column align="center" label="操作"> <template #default="scope"> <el-button v-hasPermi="['data:ind-item-category:update']" link type="primary" @click="openForm('update', scope.row.id)" > 修改 </el-button> <el-button v-hasPermi="['data:ind-item-category:delete']" link type="danger" @click="handleDelete(scope.row.id)" > 删除 </el-button> </template> </el-table-column> </el-table> </ContentWrap> <!-- 表单弹窗:添加/修改 --> <CategoryForm ref="formRef" @success="getList" /> </template> <script lang="ts" setup> import { DICT_TYPE, getIntDictOptions } from '@/utils/dict' import { handleTree } from '@/utils/tree' import * as CategoryApi from '@/api/data/ind/category' import CategoryForm from './CategoryForm.vue' import { CACHE_KEY, useCache } from '@/hooks/web/useCache' defineOptions({ name: 'IndItemCategory' }) const { wsCache } = useCache() const { t } = useI18n() // 国际化 const message = useMessage() // 消息弹窗 const loading = ref(true) // 列表的加载中 const list = ref<any>([]) // 列表的数据 const queryParams = reactive({ label: undefined }) const queryFormRef = ref() // 搜索的表单 const isExpandAll = ref(false) // 是否展开,默认全部折叠 const refreshTable = ref(true) // 重新渲染表格状态 /** 查询列表 */ const getList = async () => { loading.value = true try { const data = await CategoryApi.getCategoryList(queryParams) list.value = handleTree(data, 'id', 'pid') } finally { loading.value = false } } /** 搜索按钮操作 */ const handleQuery = () => { getList() } /** 重置按钮操作 */ const resetQuery = () => { queryFormRef.value.resetFields() handleQuery() } /** 添加/修改操作 */ const formRef = ref() const openForm = (type: string, id?: number, parentId?: number) => { formRef.value.open(type, id, parentId) } /** 展开/折叠操作 */ const toggleExpandAll = () => { refreshTable.value = false isExpandAll.value = !isExpandAll.value nextTick(() => { refreshTable.value = true }) } /** 删除按钮操作 */ const handleDelete = async (id: number) => { try { // 删除的二次确认 await message.delConfirm() // 发起删除 await CategoryApi.deleteCategory(id) message.success(t('common.delSuccess')) // 刷新列表 await getList() } catch {} } /** 初始化 **/ onMounted(() => { getList() }) </script>