mirror of
				https://github.com/YunaiV/ruoyi-vue-pro.git
				synced 2025-10-31 10:37:41 +08:00 
			
		
		
		
	feat: add modal component
This commit is contained in:
		
							
								
								
									
										3
									
								
								yudao-ui-admin-vue3/src/components/XModal/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								yudao-ui-admin-vue3/src/components/XModal/index.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | ||||
| import XModal from './src/XModal.vue' | ||||
|  | ||||
| export { XModal } | ||||
							
								
								
									
										62
									
								
								yudao-ui-admin-vue3/src/components/XModal/src/XModal.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								yudao-ui-admin-vue3/src/components/XModal/src/XModal.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,62 @@ | ||||
| <script setup lang="ts"> | ||||
| import { propTypes } from '@/utils/propTypes' | ||||
| import { computed, useAttrs, useSlots } from 'vue' | ||||
|  | ||||
| const slots = useSlots() | ||||
|  | ||||
| const props = defineProps({ | ||||
|   id: propTypes.string.def('model_1'), | ||||
|   modelValue: propTypes.bool.def(false), | ||||
|   fullscreen: propTypes.bool.def(false), | ||||
|   loading: propTypes.bool.def(false), | ||||
|   title: propTypes.string.def('弹窗'), | ||||
|   width: propTypes.string.def('800'), | ||||
|   height: propTypes.string.def('480'), | ||||
|   minWidth: propTypes.string.def('460'), | ||||
|   minHeight: propTypes.string.def('320'), | ||||
|   showFooter: propTypes.bool.def(true) | ||||
| }) | ||||
|  | ||||
| const getBindValue = computed(() => { | ||||
|   const delArr: string[] = ['title'] | ||||
|   const attrs = useAttrs() | ||||
|   const obj = { ...attrs, ...props } | ||||
|   for (const key in obj) { | ||||
|     if (delArr.indexOf(key) !== -1) { | ||||
|       delete obj[key] | ||||
|     } | ||||
|   } | ||||
|   return obj | ||||
| }) | ||||
| </script> | ||||
|  | ||||
| <template> | ||||
|   <vxe-modal | ||||
|     v-bind="getBindValue" | ||||
|     :width="width" | ||||
|     :height="height" | ||||
|     :title="title" | ||||
|     min-width="460" | ||||
|     min-height="320" | ||||
|     :loading="loading" | ||||
|     :fullscreen="fullscreen" | ||||
|     destroy-on-close | ||||
|     show-zoom | ||||
|     resize | ||||
|     transfer | ||||
|     :show-footer="showFooter" | ||||
|   > | ||||
|     <template v-if="slots.header" #header> | ||||
|       <slot name="header"></slot> | ||||
|     </template> | ||||
|     <template v-if="slots.default" #default> | ||||
|       <slot name="default"></slot> | ||||
|     </template> | ||||
|     <template v-if="slots.corner" #corner> | ||||
|       <slot name="corner"></slot> | ||||
|     </template> | ||||
|     <template v-if="slots.footer" #footer> | ||||
|       <slot name="footer"></slot> | ||||
|     </template> | ||||
|   </vxe-modal> | ||||
| </template> | ||||
| @ -4,6 +4,7 @@ import { Form } from '@/components/Form' | ||||
| import { Table } from '@/components/Table' | ||||
| import { Search } from '@/components/Search' | ||||
| import { Dialog } from '@/components/Dialog' | ||||
| import { XModal } from '@/components/XModal' | ||||
| import { DictTag } from '@/components/DictTag' | ||||
| import { ContentWrap } from '@/components/ContentWrap' | ||||
| import { Descriptions } from '@/components/Descriptions' | ||||
| @ -14,6 +15,7 @@ export const setupGlobCom = (app: App<Element>): void => { | ||||
|   app.component('Table', Table) | ||||
|   app.component('Search', Search) | ||||
|   app.component('Dialog', Dialog) | ||||
|   app.component('XModal', XModal) | ||||
|   app.component('DictTag', DictTag) | ||||
|   app.component('ContentWrap', ContentWrap) | ||||
|   app.component('Descriptions', Descriptions) | ||||
|  | ||||
| @ -4,6 +4,7 @@ import { VxeGridProps } from 'vxe-table' | ||||
| export const useVxeGrid = (allSchemas, getPageApi) => { | ||||
|   const gridOptions = reactive<VxeGridProps>({ | ||||
|     loading: false, | ||||
|     height: 800, | ||||
|     rowConfig: { | ||||
|       keyField: 'id', | ||||
|       isHover: true | ||||
|  | ||||
| @ -114,8 +114,10 @@ VXETable.setup({ | ||||
|     titleColon: true // 是否显示标题冒号 | ||||
|   }, | ||||
|   modal: { | ||||
|     width: 600, // 窗口的宽度 | ||||
|     height: 400, // 窗口的高度 | ||||
|     width: 800, // 窗口的宽度 | ||||
|     height: 600, // 窗口的高度 | ||||
|     minWidth: 460, | ||||
|     minHeight: 320, | ||||
|     showZoom: true, // 标题是否标显示最大化与还原按钮 | ||||
|     resize: true, // 是否允许窗口边缘拖动调整窗口大小 | ||||
|     marginSize: 0, // 只对 resize 启用后有效,用于设置可拖动界限范围,如果为负数则允许拖动超出屏幕边界 | ||||
|  | ||||
| @ -1,3 +1,244 @@ | ||||
| <template> | ||||
|   <ContentWrap> | ||||
|     <el-form :model="queryParams" ref="queryForm" :inline="true"> | ||||
|       <el-form-item label="菜单名称" prop="name"> | ||||
|         <el-input v-model="queryParams.name" placeholder="请输入菜单名称" /> | ||||
|       </el-form-item> | ||||
|       <el-form-item label="状态" prop="status"> | ||||
|         <el-select v-model="queryParams.status" placeholder="请选择菜单状态"> | ||||
|           <el-option | ||||
|             v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)" | ||||
|             :key="dict.value" | ||||
|             :label="dict.label" | ||||
|             :value="dict.value" | ||||
|           /> | ||||
|         </el-select> | ||||
|       </el-form-item> | ||||
|       <el-form-item> | ||||
|         <el-button type="primary" @click="handleQuery"> | ||||
|           <Icon icon="ep:search" class="mr-5px" /> | ||||
|           {{ t('common.query') }} | ||||
|         </el-button> | ||||
|         <el-button @click="resetQuery"> | ||||
|           <Icon icon="ep:refresh-right" class="mr-5px" /> | ||||
|           {{ t('common.reset') }} | ||||
|         </el-button> | ||||
|       </el-form-item> | ||||
|     </el-form> | ||||
|     <vxe-toolbar> | ||||
|       <template #buttons> | ||||
|         <vxe-button status="primary" v-hasPermi="['system:post:create']" @click="handleCreate"> | ||||
|           <Icon icon="ep:zoom-in" class="mr-5px" /> {{ t('action.add') }} | ||||
|         </vxe-button> | ||||
|         <vxe-button @click="xTable?.setAllTreeExpand(true)">展开所有</vxe-button> | ||||
|         <vxe-button @click="xTable?.clearTreeExpand()">关闭所有</vxe-button> | ||||
|       </template> | ||||
|     </vxe-toolbar> | ||||
|     <vxe-table | ||||
|       show-overflow | ||||
|       keep-source | ||||
|       ref="xTable" | ||||
|       :loading="tableLoading" | ||||
|       :row-config="{ keyField: 'id' }" | ||||
|       :column-config="{ resizable: true }" | ||||
|       :tree-config="{ transform: true, rowField: 'id', parentField: 'parentId' }" | ||||
|       :print-config="{}" | ||||
|       :export-config="{}" | ||||
|       :data="tableData" | ||||
|       class="xtable" | ||||
|     > | ||||
|       <vxe-column title="菜单名称" field="name" width="200" tree-node> | ||||
|         <template #default="{ row }"> | ||||
|           <Icon :icon="row.icon" /> | ||||
|           <span class="ml-3">{{ row.name }}</span> | ||||
|         </template> | ||||
|       </vxe-column> | ||||
|       <vxe-column title="菜单类型" field="type"> | ||||
|         <template #default="{ row }"> | ||||
|           <DictTag :type="DICT_TYPE.SYSTEM_MENU_TYPE" :value="row.type" /> | ||||
|         </template> | ||||
|       </vxe-column> | ||||
|       <vxe-column title="路由地址" field="path" /> | ||||
|       <vxe-column title="组件路径" field="component" /> | ||||
|       <vxe-column title="权限标识" field="permission" /> | ||||
|       <vxe-column title="排序" field="sort" /> | ||||
|       <vxe-column title="状态" field="status"> | ||||
|         <template #default="{ row }"> | ||||
|           <DictTag :type="DICT_TYPE.COMMON_STATUS" :value="row.status" /> | ||||
|         </template> | ||||
|       </vxe-column> | ||||
|       <vxe-column title="创建时间" field="createTime" formatter="formatDate" /> | ||||
|       <vxe-column title="操作" width="200"> | ||||
|         <template #default="{ row }"> | ||||
|           <vxe-button | ||||
|             type="text" | ||||
|             status="primary" | ||||
|             v-hasPermi="['system:menu:update']" | ||||
|             @click="handleUpdate(row)" | ||||
|           > | ||||
|             <Icon icon="ep:edit" class="mr-1px" /> {{ t('action.edit') }} | ||||
|           </vxe-button> | ||||
|           <vxe-button | ||||
|             type="text" | ||||
|             status="primary" | ||||
|             v-hasPermi="['system:menu:delete']" | ||||
|             @click="handleDelete(row)" | ||||
|           > | ||||
|             <Icon icon="ep:delete" class="mr-1px" /> {{ t('action.del') }} | ||||
|           </vxe-button> | ||||
|         </template> | ||||
|       </vxe-column> | ||||
|     </vxe-table> | ||||
|   </ContentWrap> | ||||
|   <XModal v-model="dialogVisible" id="menuModel" :title="dialogTitle"> | ||||
|     <template #default> | ||||
|       <!-- 对话框(添加 / 修改) --> | ||||
|       <el-form | ||||
|         :model="menuForm" | ||||
|         :rules="rules" | ||||
|         :inline="true" | ||||
|         label-width="120px" | ||||
|         label-position="right" | ||||
|       > | ||||
|         <el-row :gutter="24"> | ||||
|           <el-col :span="24"> | ||||
|             <el-form-item label="上级菜单"> | ||||
|               <el-tree-select | ||||
|                 node-key="id" | ||||
|                 v-model="menuForm.parentId" | ||||
|                 :props="menuProps" | ||||
|                 :data="menuOptions" | ||||
|                 check-strictly | ||||
|               /> | ||||
|             </el-form-item> | ||||
|           </el-col> | ||||
|           <el-col :span="12"> | ||||
|             <el-form-item label="菜单类型" prop="type"> | ||||
|               <el-radio-group v-model="menuForm.type"> | ||||
|                 <el-radio-button | ||||
|                   v-for="dict in getIntDictOptions(DICT_TYPE.SYSTEM_MENU_TYPE)" | ||||
|                   :key="dict.value" | ||||
|                   :label="dict.value" | ||||
|                 > | ||||
|                   {{ dict.label }} | ||||
|                 </el-radio-button> | ||||
|               </el-radio-group> | ||||
|             </el-form-item> | ||||
|           </el-col> | ||||
|           <el-col :span="12"> | ||||
|             <el-form-item label="菜单名称" prop="name"> | ||||
|               <el-input v-model="menuForm.name" placeholder="请输入菜单名称" clearable /> | ||||
|             </el-form-item> | ||||
|           </el-col> | ||||
|           <template v-if="menuForm.type !== 3"> | ||||
|             <el-col :span="12"> | ||||
|               <el-form-item label="菜单图标"> | ||||
|                 <IconSelect v-model="menuForm.icon" clearable /> | ||||
|               </el-form-item> | ||||
|             </el-col> | ||||
|             <el-col :span="12"> | ||||
|               <el-form-item label="路由地址" prop="path"> | ||||
|                 <template #label> | ||||
|                   <Tooltip | ||||
|                     titel="路由地址" | ||||
|                     message="访问的路由地址,如:`user`。如需外网地址时,则以 `http(s)://` 开头" | ||||
|                   /> | ||||
|                 </template> | ||||
|                 <el-input v-model="menuForm.path" placeholder="请输入路由地址" clearable /> | ||||
|               </el-form-item> | ||||
|             </el-col> | ||||
|           </template> | ||||
|           <template v-if="menuForm.type === 2"> | ||||
|             <el-col :span="12"> | ||||
|               <el-form-item label="路由地址" prop="component"> | ||||
|                 <el-input v-model="menuForm.component" placeholder="请输入组件地址" clearable /> | ||||
|               </el-form-item> | ||||
|             </el-col> | ||||
|           </template> | ||||
|           <template v-if="menuForm.type !== 1"> | ||||
|             <el-col :span="12"> | ||||
|               <el-form-item label="权限标识" prop="permission"> | ||||
|                 <template #label> | ||||
|                   <Tooltip | ||||
|                     titel="权限标识" | ||||
|                     message="Controller 方法上的权限字符,如:@PreAuthorize(`@ss.hasPermission('system:user:list')`)" | ||||
|                   /> | ||||
|                 </template> | ||||
|                 <el-input v-model="menuForm.permission" placeholder="请输入权限标识" clearable /> | ||||
|               </el-form-item> | ||||
|             </el-col> | ||||
|           </template> | ||||
|           <el-col :span="12"> | ||||
|             <el-form-item label="显示排序" prop="sort"> | ||||
|               <el-input-number | ||||
|                 v-model="menuForm.sort" | ||||
|                 controls-position="right" | ||||
|                 :min="0" | ||||
|                 clearable | ||||
|               /> | ||||
|             </el-form-item> | ||||
|           </el-col> | ||||
|           <el-col :span="12"> | ||||
|             <el-form-item label="菜单状态" prop="status"> | ||||
|               <el-radio-group v-model="menuForm.status"> | ||||
|                 <el-radio-button | ||||
|                   v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)" | ||||
|                   :key="dict.value" | ||||
|                   :label="dict.value" | ||||
|                 > | ||||
|                   {{ dict.label }} | ||||
|                 </el-radio-button> | ||||
|               </el-radio-group> | ||||
|             </el-form-item> | ||||
|           </el-col> | ||||
|           <template v-if="menuForm.type !== 3"> | ||||
|             <el-col :span="12"> | ||||
|               <el-form-item label="显示状态" prop="status"> | ||||
|                 <template #label> | ||||
|                   <Tooltip | ||||
|                     titel="显示状态" | ||||
|                     message="选择隐藏时,路由将不会出现在侧边栏,但仍然可以访问" | ||||
|                   /> | ||||
|                 </template> | ||||
|                 <el-radio-group v-model="menuForm.visible"> | ||||
|                   <el-radio-button key="true" :label="true">显示</el-radio-button> | ||||
|                   <el-radio-button key="false" :label="false">隐藏</el-radio-button> | ||||
|                 </el-radio-group> | ||||
|               </el-form-item> | ||||
|             </el-col> | ||||
|           </template> | ||||
|           <template v-if="menuForm.type === 2"> | ||||
|             <el-col :span="12"> | ||||
|               <el-form-item label="缓存状态" prop="keepAlive"> | ||||
|                 <template #label> | ||||
|                   <Tooltip | ||||
|                     titel="缓存状态" | ||||
|                     message="选择缓存时,则会被 `keep-alive` 缓存,需要匹配组件的 `name` 和路由地址保持一致" | ||||
|                   /> | ||||
|                 </template> | ||||
|                 <el-radio-group v-model="menuForm.keepAlive"> | ||||
|                   <el-radio-button key="true" :label="true">缓存</el-radio-button> | ||||
|                   <el-radio-button key="false" :label="false">不缓存</el-radio-button> | ||||
|                 </el-radio-group> | ||||
|               </el-form-item> | ||||
|             </el-col> | ||||
|           </template> | ||||
|         </el-row> | ||||
|       </el-form> | ||||
|     </template> | ||||
|     <template #footer> | ||||
|       <!-- 操作按钮 --> | ||||
|       <el-button | ||||
|         v-if="['create', 'update'].includes(actionType)" | ||||
|         type="primary" | ||||
|         :loading="actionLoading" | ||||
|         @click="submitForm" | ||||
|         :content="t('action.save')" | ||||
|       /> | ||||
|       <el-button @click="dialogVisible = false" :content="t('dialog.close')" /> | ||||
|     </template> | ||||
|   </XModal> | ||||
| </template> | ||||
| <script setup lang="ts"> | ||||
| import * as MenuApi from '@/api/system/menu' | ||||
| import { MenuVO } from '@/api/system/menu/types' | ||||
| @ -164,256 +405,3 @@ onMounted(async () => { | ||||
|   getTree() | ||||
| }) | ||||
| </script> | ||||
| <template> | ||||
|   <ContentWrap> | ||||
|     <el-form :model="queryParams" ref="queryForm" :inline="true"> | ||||
|       <el-form-item label="菜单名称" prop="name"> | ||||
|         <el-input v-model="queryParams.name" placeholder="请输入菜单名称" /> | ||||
|       </el-form-item> | ||||
|       <el-form-item label="状态" prop="status"> | ||||
|         <el-select v-model="queryParams.status" placeholder="请选择菜单状态"> | ||||
|           <el-option | ||||
|             v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)" | ||||
|             :key="dict.value" | ||||
|             :label="dict.label" | ||||
|             :value="dict.value" | ||||
|           /> | ||||
|         </el-select> | ||||
|       </el-form-item> | ||||
|       <el-form-item> | ||||
|         <el-button type="primary" @click="handleQuery"> | ||||
|           <Icon icon="ep:search" class="mr-5px" /> | ||||
|           {{ t('common.query') }} | ||||
|         </el-button> | ||||
|         <el-button @click="resetQuery"> | ||||
|           <Icon icon="ep:refresh-right" class="mr-5px" /> | ||||
|           {{ t('common.reset') }} | ||||
|         </el-button> | ||||
|       </el-form-item> | ||||
|     </el-form> | ||||
|     <vxe-toolbar> | ||||
|       <template #buttons> | ||||
|         <vxe-button status="primary" v-hasPermi="['system:post:create']" @click="handleCreate"> | ||||
|           <Icon icon="ep:zoom-in" class="mr-5px" /> {{ t('action.add') }} | ||||
|         </vxe-button> | ||||
|         <vxe-button @click="xTable?.setAllTreeExpand(true)">展开所有</vxe-button> | ||||
|         <vxe-button @click="xTable?.clearTreeExpand()">关闭所有</vxe-button> | ||||
|       </template> | ||||
|     </vxe-toolbar> | ||||
|     <vxe-table | ||||
|       show-overflow | ||||
|       keep-source | ||||
|       ref="xTable" | ||||
|       :loading="tableLoading" | ||||
|       :row-config="{ keyField: 'id' }" | ||||
|       :column-config="{ resizable: true }" | ||||
|       :tree-config="{ transform: true, rowField: 'id', parentField: 'parentId' }" | ||||
|       :print-config="{}" | ||||
|       :export-config="{}" | ||||
|       :data="tableData" | ||||
|     > | ||||
|       <vxe-column title="菜单名称" field="name" width="200" tree-node> | ||||
|         <template #default="{ row }"> | ||||
|           <Icon :icon="row.icon" /> | ||||
|           <span class="ml-3">{{ row.name }}</span> | ||||
|         </template> | ||||
|       </vxe-column> | ||||
|       <vxe-column title="菜单类型" field="type"> | ||||
|         <template #default="{ row }"> | ||||
|           <DictTag :type="DICT_TYPE.SYSTEM_MENU_TYPE" :value="row.type" /> | ||||
|         </template> | ||||
|       </vxe-column> | ||||
|       <vxe-column title="路由地址" field="path" /> | ||||
|       <vxe-column title="组件路径" field="component" /> | ||||
|       <vxe-column title="权限标识" field="permission" /> | ||||
|       <vxe-column title="排序" field="sort" /> | ||||
|       <vxe-column title="状态" field="status"> | ||||
|         <template #default="{ row }"> | ||||
|           <DictTag :type="DICT_TYPE.COMMON_STATUS" :value="row.status" /> | ||||
|         </template> | ||||
|       </vxe-column> | ||||
|       <vxe-column title="创建时间" field="createTime" formatter="formatDate" /> | ||||
|       <vxe-column title="操作" width="200"> | ||||
|         <template #default="{ row }"> | ||||
|           <vxe-button | ||||
|             type="text" | ||||
|             status="primary" | ||||
|             v-hasPermi="['system:menu:update']" | ||||
|             @click="handleUpdate(row)" | ||||
|           > | ||||
|             <Icon icon="ep:edit" class="mr-1px" /> {{ t('action.edit') }} | ||||
|           </vxe-button> | ||||
|           <vxe-button | ||||
|             type="text" | ||||
|             status="primary" | ||||
|             v-hasPermi="['system:menu:delete']" | ||||
|             @click="handleDelete(row)" | ||||
|           > | ||||
|             <Icon icon="ep:delete" class="mr-1px" /> {{ t('action.del') }} | ||||
|           </vxe-button> | ||||
|         </template> | ||||
|       </vxe-column> | ||||
|     </vxe-table> | ||||
|   </ContentWrap> | ||||
|   <vxe-modal | ||||
|     v-model="dialogVisible" | ||||
|     id="menuModel" | ||||
|     :title="dialogTitle" | ||||
|     width="800" | ||||
|     height="6f00" | ||||
|     min-width="460" | ||||
|     min-height="320" | ||||
|     show-zoom | ||||
|     resize | ||||
|     transfer | ||||
|     show-footer | ||||
|   > | ||||
|     <template #default> | ||||
|       <!-- 对话框(添加 / 修改) --> | ||||
|       <el-form | ||||
|         :model="menuForm" | ||||
|         :rules="rules" | ||||
|         :inline="true" | ||||
|         label-width="120px" | ||||
|         label-position="right" | ||||
|       > | ||||
|         <el-row :gutter="24"> | ||||
|           <el-col :span="24"> | ||||
|             <el-form-item label="上级菜单"> | ||||
|               <el-tree-select | ||||
|                 node-key="id" | ||||
|                 v-model="menuForm.parentId" | ||||
|                 :props="menuProps" | ||||
|                 :data="menuOptions" | ||||
|                 check-strictly | ||||
|               /> | ||||
|             </el-form-item> | ||||
|           </el-col> | ||||
|           <el-col :span="12"> | ||||
|             <el-form-item label="菜单类型" prop="type"> | ||||
|               <el-radio-group v-model="menuForm.type"> | ||||
|                 <el-radio-button | ||||
|                   v-for="dict in getIntDictOptions(DICT_TYPE.SYSTEM_MENU_TYPE)" | ||||
|                   :key="dict.value" | ||||
|                   :label="dict.value" | ||||
|                 > | ||||
|                   {{ dict.label }} | ||||
|                 </el-radio-button> | ||||
|               </el-radio-group> | ||||
|             </el-form-item> | ||||
|           </el-col> | ||||
|           <el-col :span="12"> | ||||
|             <el-form-item label="菜单名称" prop="name"> | ||||
|               <el-input v-model="menuForm.name" placeholder="请输入菜单名称" clearable /> | ||||
|             </el-form-item> | ||||
|           </el-col> | ||||
|           <template v-if="menuForm.type !== 3"> | ||||
|             <el-col :span="12"> | ||||
|               <el-form-item label="菜单图标"> | ||||
|                 <IconSelect v-model="menuForm.icon" clearable /> | ||||
|               </el-form-item> | ||||
|             </el-col> | ||||
|             <el-col :span="12"> | ||||
|               <el-form-item label="路由地址" prop="path"> | ||||
|                 <template #label> | ||||
|                   <Tooltip | ||||
|                     titel="路由地址" | ||||
|                     message="访问的路由地址,如:`user`。如需外网地址时,则以 `http(s)://` 开头" | ||||
|                   /> | ||||
|                 </template> | ||||
|                 <el-input v-model="menuForm.path" placeholder="请输入路由地址" clearable /> | ||||
|               </el-form-item> | ||||
|             </el-col> | ||||
|           </template> | ||||
|           <template v-if="menuForm.type === 2"> | ||||
|             <el-col :span="12"> | ||||
|               <el-form-item label="路由地址" prop="component"> | ||||
|                 <el-input v-model="menuForm.component" placeholder="请输入组件地址" clearable /> | ||||
|               </el-form-item> | ||||
|             </el-col> | ||||
|           </template> | ||||
|           <template v-if="menuForm.type !== 1"> | ||||
|             <el-col :span="12"> | ||||
|               <el-form-item label="权限标识" prop="permission"> | ||||
|                 <template #label> | ||||
|                   <Tooltip | ||||
|                     titel="权限标识" | ||||
|                     message="Controller 方法上的权限字符,如:@PreAuthorize(`@ss.hasPermission('system:user:list')`)" | ||||
|                   /> | ||||
|                 </template> | ||||
|                 <el-input v-model="menuForm.permission" placeholder="请输入权限标识" clearable /> | ||||
|               </el-form-item> | ||||
|             </el-col> | ||||
|           </template> | ||||
|           <el-col :span="12"> | ||||
|             <el-form-item label="显示排序" prop="sort"> | ||||
|               <el-input-number | ||||
|                 v-model="menuForm.sort" | ||||
|                 controls-position="right" | ||||
|                 :min="0" | ||||
|                 clearable | ||||
|               /> | ||||
|             </el-form-item> | ||||
|           </el-col> | ||||
|           <el-col :span="12"> | ||||
|             <el-form-item label="菜单状态" prop="status"> | ||||
|               <el-radio-group v-model="menuForm.status"> | ||||
|                 <el-radio-button | ||||
|                   v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)" | ||||
|                   :key="dict.value" | ||||
|                   :label="dict.value" | ||||
|                 > | ||||
|                   {{ dict.label }} | ||||
|                 </el-radio-button> | ||||
|               </el-radio-group> | ||||
|             </el-form-item> | ||||
|           </el-col> | ||||
|           <template v-if="menuForm.type !== 3"> | ||||
|             <el-col :span="12"> | ||||
|               <el-form-item label="显示状态" prop="status"> | ||||
|                 <template #label> | ||||
|                   <Tooltip | ||||
|                     titel="显示状态" | ||||
|                     message="选择隐藏时,路由将不会出现在侧边栏,但仍然可以访问" | ||||
|                   /> | ||||
|                 </template> | ||||
|                 <el-radio-group v-model="menuForm.visible"> | ||||
|                   <el-radio-button key="true" :label="true">显示</el-radio-button> | ||||
|                   <el-radio-button key="false" :label="false">隐藏</el-radio-button> | ||||
|                 </el-radio-group> | ||||
|               </el-form-item> | ||||
|             </el-col> | ||||
|           </template> | ||||
|           <template v-if="menuForm.type === 2"> | ||||
|             <el-col :span="12"> | ||||
|               <el-form-item label="缓存状态" prop="keepAlive"> | ||||
|                 <template #label> | ||||
|                   <Tooltip | ||||
|                     titel="缓存状态" | ||||
|                     message="选择缓存时,则会被 `keep-alive` 缓存,需要匹配组件的 `name` 和路由地址保持一致" | ||||
|                   /> | ||||
|                 </template> | ||||
|                 <el-radio-group v-model="menuForm.keepAlive"> | ||||
|                   <el-radio-button key="true" :label="true">缓存</el-radio-button> | ||||
|                   <el-radio-button key="false" :label="false">不缓存</el-radio-button> | ||||
|                 </el-radio-group> | ||||
|               </el-form-item> | ||||
|             </el-col> | ||||
|           </template> | ||||
|         </el-row> | ||||
|       </el-form> | ||||
|     </template> | ||||
|     <template #footer> | ||||
|       <!-- 操作按钮 --> | ||||
|       <el-button | ||||
|         v-if="['create', 'update'].includes(actionType)" | ||||
|         type="primary" | ||||
|         :loading="actionLoading" | ||||
|         @click="submitForm" | ||||
|       > | ||||
|         {{ t('action.save') }} | ||||
|       </el-button> | ||||
|       <el-button @click="dialogVisible = false">{{ t('dialog.close') }}</el-button> | ||||
|     </template> | ||||
|   </vxe-modal> | ||||
| </template> | ||||
|  | ||||
| @ -1,3 +1,76 @@ | ||||
| <template> | ||||
|   <ContentWrap> | ||||
|     <vxe-grid ref="xGrid" v-bind="gridOptions" class="xtable-scrollbar"> | ||||
|       <template #toolbar_buttons> | ||||
|         <el-button type="primary" v-hasPermi="['system:post:create']" @click="handleCreate"> | ||||
|           <Icon icon="ep:zoom-in" class="mr-5px" /> {{ t('action.add') }} | ||||
|         </el-button> | ||||
|       </template> | ||||
|       <template #status_default="{ row }"> | ||||
|         <DictTag :type="DICT_TYPE.COMMON_STATUS" :value="row.status" /> | ||||
|       </template> | ||||
|       <template #action_default="{ row }"> | ||||
|         <el-button | ||||
|           link | ||||
|           type="primary" | ||||
|           v-hasPermi="['system:post:update']" | ||||
|           @click="handleUpdate(row.id)" | ||||
|         > | ||||
|           <Icon icon="ep:edit" class="mr-1px" /> {{ t('action.edit') }} | ||||
|         </el-button> | ||||
|         <el-button | ||||
|           link | ||||
|           type="primary" | ||||
|           v-hasPermi="['system:post:update']" | ||||
|           @click="handleDetail(row)" | ||||
|         > | ||||
|           <Icon icon="ep:view" class="mr-1px" /> {{ t('action.detail') }} | ||||
|         </el-button> | ||||
|         <el-button | ||||
|           link | ||||
|           type="primary" | ||||
|           v-hasPermi="['system:post:delete']" | ||||
|           @click="handleDelete(row.id)" | ||||
|         > | ||||
|           <Icon icon="ep:delete" class="mr-1px" /> {{ t('action.del') }} | ||||
|         </el-button> | ||||
|       </template> | ||||
|     </vxe-grid> | ||||
|   </ContentWrap> | ||||
|   <XModal id="postModel" v-model="dialogVisible" :title="dialogTitle"> | ||||
|     <template #default> | ||||
|       <!-- 对话框(添加 / 修改) --> | ||||
|       <vxe-form | ||||
|         ref="xForm" | ||||
|         v-if="['create', 'update'].includes(actionType)" | ||||
|         :data="formData" | ||||
|         :items="formItems" | ||||
|         :rules="rules" | ||||
|       /> | ||||
|       <Descriptions | ||||
|         v-if="actionType === 'detail'" | ||||
|         :schema="allSchemas.detailSchema" | ||||
|         :data="detailRef" | ||||
|       > | ||||
|         <template #status="{ row }"> | ||||
|           <DictTag :type="DICT_TYPE.COMMON_STATUS" :value="row.status" /> | ||||
|         </template> | ||||
|         <template #createTime="{ row }"> | ||||
|           <span>{{ dayjs(row.createTime).format('YYYY-MM-DD HH:mm:ss') }}</span> | ||||
|         </template> | ||||
|       </Descriptions> | ||||
|     </template> | ||||
|     <template #footer> | ||||
|       <vxe-button | ||||
|         v-if="['create', 'update'].includes(actionType)" | ||||
|         status="primary" | ||||
|         @click="submitForm" | ||||
|         :content="t('action.save')" | ||||
|       /> | ||||
|       <vxe-button @click="dialogVisible = false" :content="t('dialog.close')" /> | ||||
|     </template> | ||||
|   </XModal> | ||||
| </template> | ||||
| <script setup lang="ts"> | ||||
| import { ref } from 'vue' | ||||
| import dayjs from 'dayjs' | ||||
| @ -82,89 +155,3 @@ const submitForm: VxeFormEvents.Submit = async () => { | ||||
|   } | ||||
| } | ||||
| </script> | ||||
| <template> | ||||
|   <ContentWrap> | ||||
|     <vxe-grid ref="xGrid" v-bind="gridOptions"> | ||||
|       <template #toolbar_buttons> | ||||
|         <el-button type="primary" v-hasPermi="['system:post:create']" @click="handleCreate"> | ||||
|           <Icon icon="ep:zoom-in" class="mr-5px" /> {{ t('action.add') }} | ||||
|         </el-button> | ||||
|       </template> | ||||
|       <template #status_default="{ row }"> | ||||
|         <DictTag :type="DICT_TYPE.COMMON_STATUS" :value="row.status" /> | ||||
|       </template> | ||||
|       <template #action_default="{ row }"> | ||||
|         <el-button | ||||
|           link | ||||
|           type="primary" | ||||
|           v-hasPermi="['system:post:update']" | ||||
|           @click="handleUpdate(row.id)" | ||||
|         > | ||||
|           <Icon icon="ep:edit" class="mr-1px" /> {{ t('action.edit') }} | ||||
|         </el-button> | ||||
|         <el-button | ||||
|           link | ||||
|           type="primary" | ||||
|           v-hasPermi="['system:post:update']" | ||||
|           @click="handleDetail(row)" | ||||
|         > | ||||
|           <Icon icon="ep:view" class="mr-1px" /> {{ t('action.detail') }} | ||||
|         </el-button> | ||||
|         <el-button | ||||
|           link | ||||
|           type="primary" | ||||
|           v-hasPermi="['system:post:delete']" | ||||
|           @click="handleDelete(row.id)" | ||||
|         > | ||||
|           <Icon icon="ep:delete" class="mr-1px" /> {{ t('action.del') }} | ||||
|         </el-button> | ||||
|       </template> | ||||
|     </vxe-grid> | ||||
|   </ContentWrap> | ||||
|   <vxe-modal | ||||
|     v-model="dialogVisible" | ||||
|     id="postModel" | ||||
|     :title="dialogTitle" | ||||
|     width="800" | ||||
|     height="400" | ||||
|     min-width="460" | ||||
|     min-height="320" | ||||
|     show-zoom | ||||
|     resize | ||||
|     transfer | ||||
|     show-footer | ||||
|   > | ||||
|     <template #default> | ||||
|       <!-- 对话框(添加 / 修改) --> | ||||
|       <vxe-form | ||||
|         ref="xForm" | ||||
|         v-if="['create', 'update'].includes(actionType)" | ||||
|         :data="formData" | ||||
|         :items="formItems" | ||||
|         :rules="rules" | ||||
|       /> | ||||
|       <Descriptions | ||||
|         v-if="actionType === 'detail'" | ||||
|         :schema="allSchemas.detailSchema" | ||||
|         :data="detailRef" | ||||
|       > | ||||
|         <template #status="{ row }"> | ||||
|           <DictTag :type="DICT_TYPE.COMMON_STATUS" :value="row.status" /> | ||||
|         </template> | ||||
|         <template #createTime="{ row }"> | ||||
|           <span>{{ dayjs(row.createTime).format('YYYY-MM-DD HH:mm:ss') }}</span> | ||||
|         </template> | ||||
|       </Descriptions> | ||||
|     </template> | ||||
|     <template #footer> | ||||
|       <vxe-button | ||||
|         v-if="['create', 'update'].includes(actionType)" | ||||
|         status="primary" | ||||
|         @click="submitForm" | ||||
|       > | ||||
|         {{ t('action.save') }} | ||||
|       </vxe-button> | ||||
|       <vxe-button @click="dialogVisible = false">{{ t('dialog.close') }}</vxe-button> | ||||
|     </template> | ||||
|   </vxe-modal> | ||||
| </template> | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 xingyu4j
					xingyu4j