Pārlūkot izejas kodu

feat: 1将设计器中的 id 明文改为 code
2. 增加菜单绑定,菜单编辑,发布,取消发布,限制菜单管理中不能编辑删除设计器添加的菜单操作
3. 优化添加页面的显示等

yanglzh 6 mēneši atpakaļ
vecāks
revīzija
458880efb6

+ 3 - 2
package.json

@@ -8,8 +8,9 @@
     "dev": "npm run plugin:check && npm run writeEnv:dev && vite --force",
     "plugin:check": "ls ./public/plugin/topo && npm run plugin:has || npm run plugin:not",
     "plugin:has": "echo '\\033[31m 插件存在,无需拉取 \\033[0m'",
-    "plugin:not": "echo '\\033[31m 插件不存在,需要拉取 拉取后会自动运行 \\033[0m' && npm run plugin:pull",
-    "plugin:pull": "git clone --depth 1 http://git.mydig.net/Sagoo-Cloud/sagoo-admin-ui-plugin.git ./public/plugin/",
+    "plugin:not": "echo '\\033[31m 插件不存在,需要拉取 拉取后会自动运行 \\033[0m' && npm run plugin:clone",
+    "plugin:clone": "git clone --depth 1 http://git.mydig.net/Sagoo-Cloud/sagoo-admin-ui-plugin.git ./public/plugin/",
+    "plugin:pull": "cd ./public/plugin/ && git pull || npm run plugin:clone",
     "plugin:update": "rm -rf ./public/plugin/ && npm run plugin:pull",
     "build": "npm run plugin:check && cross-env NODE_ENV=production node ./writeEnv.mjs && vite build && npm run getVersion",
     "build:dev": "npm run plugin:check && npm run writeEnv:dev && vite build --mode development && npm run getVersion",

+ 1 - 1
src/api/modules/designer.ts

@@ -7,5 +7,5 @@ export default {
   getList: (data: object) => get("/designer/list", data),
   publish: (data: object) => put("/designer/publish", data),
   getAll: (data: object) => get("/designer/getAll", data),
-  get: (id: number) => get("/designer/getInfoById", { id }),
+  get: (code: string) => get("/designer/getInfoByCode", { code }),
 }

+ 62 - 74
src/views/designer/edit.vue

@@ -1,100 +1,88 @@
 <template>
-  <el-dialog class="api-edit" v-model="showDialog" :title="`${formData.id ? '编辑组态图' : '新增组态图'}`" width="600px" :close-on-click-modal="false" :close-on-press-escape="false">
-    <el-form ref="formRef" :model="formData" :rules="ruleForm" label-width="100px">
-      <el-form-item label="组态图名称" prop="name">
-        <el-input v-model.trim="formData.name" placeholder="输入组态图名称" />
-      </el-form-item>
-      <!-- <el-form-item label="说明" prop="remarks">
-        <el-input v-model="formData.remarks" type="textarea" :rows="3" />
-      </el-form-item> -->
-    </el-form>
-    <template #footer>
-      <div class="dialog-footer">
-        <el-button @click="showDialog = false">取消</el-button>
-        <el-button type="primary" @click="onSubmit">确定</el-button>
-      </div>
-    </template>
-  </el-dialog>
+	<el-dialog
+		class="api-edit"
+		v-model="showDialog"
+		:title="`${formData.id ? '编辑' : '新增'}`"
+		width="600px"
+		:close-on-click-modal="false"
+		:close-on-press-escape="false"
+	>
+		<el-form ref="formRef" :model="formData" :rules="ruleForm" label-width="100px">
+			<el-form-item label="名称" prop="name">
+				<el-input v-model.trim="formData.name" placeholder="输入名称" />
+			</el-form-item>
+			<el-form-item label="说明" prop="ext01">
+				<el-input v-model="formData.ext01" type="textarea" :rows="3" />
+			</el-form-item>
+		</el-form>
+		<template #footer>
+			<div class="dialog-footer">
+				<el-button @click="showDialog = false">取消</el-button>
+				<el-button type="primary" @click="onSubmit">确定</el-button>
+			</div>
+		</template>
+	</el-dialog>
 </template>
 
 <script lang="ts" setup>
-import { ref, reactive, nextTick } from 'vue';
-import api from '/@/api/configuration';
-import { ruleRequired } from '/@/utils/validator';
-import { ElMessage } from 'element-plus';
-import pako from 'pako'
-import { Session } from '/@/utils/storage';
+import { ref, reactive, nextTick } from 'vue'
+import { ruleRequired } from '/@/utils/validator'
+import { ElMessage } from 'element-plus'
+import api from '/@/api/modules/designer'
 
-const emit = defineEmits(['getList']);
+const emit = defineEmits(['getList'])
 
-const showDialog = ref(false);
-const formRef = ref();
+const showDialog = ref(false)
+const formRef = ref()
 
-const jsonData = pako.deflate('{"x":0,"y":0,"scale":1,"pens":[],"origin":{"x":0,"y":0},"center":{"x":0,"y":0},"paths":{},"version":"1.2.13"}', { to: 'string' })
+const jsonData = `{"0":{"rule":"[]","options":"{\"form\":{\"inline\":false,\"hideRequiredAsterisk\":false,\"labelPosition\":\"right\",\"size\":\"default\",\"labelWidth\":\"125px\"},\"resetBtn\":{\"show\":false,\"innerText\":\"重置\"},\"submitBtn\":{\"show\":true,\"innerText\":\"提交\"}}"}}`
 
 const baseForm = {
-  "id": undefined,
-  "folderId": 1,
-  "types": "topology",
-  "jsonData": jsonData,
-  "name": "",
-  "pointIds": "",
-  "images": "https://dummyimage.com/100x100?text=no%20data",
-  "status": 1
+	id: undefined,
+	name: null,
+	content: jsonData,
+	ext01: null,
 }
 
 const formData = reactive({
-  ...baseForm,
-});
+	...baseForm,
+})
 
 const ruleForm = {
-  name: [ruleRequired('图纸名称不能为空')],
-};
+	name: [ruleRequired('名称不能为空')],
+	ext01: [ruleRequired('说明不能为空')],
+}
 
 const onSubmit = async () => {
-  await formRef.value.validate();
-
-  const theApi = formData.id ? api.edit : api.add;
+	await formRef.value.validate()
 
-  if (!formData.id) {
-    formData.folderId = 1;
-    api.getFolder().then((res: any) => {
-      if (res.topology && res.topology.length > 0) {
-        formData.folderId = res.topology[0].id;
-        toSend(theApi, formData)
-      } else {
-        api.addFolder({ types: 'topology', name: '默认分类-' + Session.get('userInfo')?.dept?.deptName }).then(({ folderId }: any) => {
-          formData.folderId = folderId
-          toSend(theApi, formData)
-        })
-      }
-    })
-  } else {
-    toSend(theApi, formData)
-  }
-};
+  const theApi = formData.id ? api.edit : api.add
 
-const toSend = async (theApi: any, formData: any) => {
-  await theApi(formData);
+  await theApi(formData)
 
-  ElMessage.success('操作成功');
-  resetForm();
-  showDialog.value = false;
-  emit('getList');
-};
+  ElMessage.success('操作成功')
+  resetForm()
+  showDialog.value = false
+  emit('getList')
+}
 
 const resetForm = async () => {
-  Object.assign(formData, { ...baseForm });
-  formRef.value && formRef.value.resetFields();
-};
+	Object.assign(formData, { ...baseForm })
+	formRef.value && formRef.value.resetFields()
+}
 
 const open = async (row: any) => {
-  resetForm();
-  showDialog.value = true;
+	resetForm()
+	showDialog.value = true
   nextTick(() => {
-    Object.assign(formData, { ...row });
-  });
-};
+    if (row) {
+      formData.id = row.id
+      formData.name = row.name
+      formData.content = row.content
+      formData.ext01 = row.ext01
+    }
+	})
+}
 
-defineExpose({ open });
+defineExpose({ open })
 </script>

+ 51 - 17
src/views/designer/index.vue

@@ -30,23 +30,36 @@
 					</el-form-item>
 				</el-form>
 			</div>
-			<el-table :data="tableData" style="width: 100%" row-key="id" v-loading="loading">
-				<el-table-column prop="id" label="ID" width="100" show-overflow-tooltip></el-table-column>
+			<el-table :data="tableData" style="width: 100%" v-loading="loading">
 				<el-table-column prop="name" label="名称" show-overflow-tooltip></el-table-column>
-				<el-table-column prop="createdAt" label="创建时间" min-width="100" align="center"></el-table-column>
-				<el-table-column prop="updatedAt" label="更新时间" min-width="100" align="center"></el-table-column>
-				<el-table-column prop="status" label="状态" min-width="100" align="center"></el-table-column>
-				<el-table-column label="操作" width="200" align="center">
+				<el-table-column prop="ext01" label="说明" show-overflow-tooltip></el-table-column>
+				<el-table-column prop="menuId" label="绑定菜单" width="100" align="center">
+					<template #default="{ row }">
+						<el-tag :type="row.menuId ? 'success' : 'info'" size="small">{{ row.menuId ? '已绑定' : '未绑定' }}</el-tag>
+					</template>
+				</el-table-column>
+				<el-table-column prop="status" label="发布状态" width="100" align="center">
+					<template #default="{ row }">
+						<el-tag :type="row.status ? 'success' : 'info'" size="small">{{ row.status ? '已发布' : '未发布' }}</el-tag>
+					</template>
+				</el-table-column>
+				<el-table-column prop="createdAt" label="创建时间" width="170" align="center"></el-table-column>
+				<el-table-column prop="updatedAt" label="更新时间" width="170" align="center"></el-table-column>
+				<el-table-column label="操作" width="280" align="center">
 					<template #default="scope">
 						<el-button size="small" text type="primary" v-if="!scope.row.folderName" @click="view(scope.row)">预览</el-button>
-						<!-- <el-button size="small" text type="warning" v-auth="'edit'" @click="addOrEdit(scope.row)">编辑</el-button> -->
+						<el-button size="small" text type="warning" v-auth="'edit'" @click="addOrEdit(scope.row)">编辑</el-button>
 						<el-button size="small" text type="warning" @click="edit(scope.row)">设计</el-button>
+						<el-button size="small" text type="success" v-if="scope.row.menuId" @click="bindMenu(scope.row)">编辑菜单</el-button>
+						<el-button size="small" text type="success" v-if="scope.row.status === 0" @click="publish(scope.row, 1)">发布</el-button>
+						<el-button size="small" text type="info" v-if="scope.row.status === 1" @click="publish(scope.row, 0)">取消发布</el-button>
 						<el-button size="small" text type="info" v-auth="'del'" @click="del(scope.row)">删除</el-button>
 					</template>
 				</el-table-column>
 			</el-table>
 			<pagination v-if="params.total" :total="params.total" v-model:page="params.pageNum" v-model:limit="params.pageSize" @pagination="getList()" />
 			<EditForm ref="editFormRef" @getList="getList(1)"></EditForm>
+			<MenuForm ref="menuFormRef" @getList="getList(1)"></MenuForm>
 		</el-card>
 	</div>
 </template>
@@ -56,9 +69,11 @@ import api from '/@/api/modules/designer'
 import { useSearch } from '/@/hooks/useCommon'
 import { ElMessageBox, ElMessage } from 'element-plus'
 import EditForm from './edit.vue'
+import MenuForm from './menu.vue'
 import { ref } from 'vue'
 
 const editFormRef = ref()
+const menuFormRef = ref()
 
 const { params, tableData, getList, loading } = useSearch<any[]>(api.getList, 'Data', { keyWord: '' })
 
@@ -70,25 +85,44 @@ function getTokenUrl(url: string) {
 }
 
 const view = (row: any) => {
-	window.open('/designer/' + row.id)
+	window.open('/designer/' + row.code)
 }
 
 const addOrEdit = async (row?: any) => {
-	// const url = getTokenUrl('#/editor/new');
-	// window.open(url);
-	// if (row) {
-	// 	editFormRef.value.open(row)
-	// 	return
-	// } else {
-	// 	editFormRef.value.open()
-	// }
+	editFormRef.value.open(row)
 }
 
 const edit = (row: any) => {
-	const url = getTokenUrl('#' + row.id)
+	const url = getTokenUrl('#' + row.code)
 	window.open(url)
 }
 
+const bindMenu = (row: any) => {
+	menuFormRef.value.open(row)
+}
+
+const publish = (row: any, status: number) => {
+	if (!row.menuId) {
+		ElMessageBox.confirm('第一次发布需要绑定菜单,绑定之后自动发布成功', '提示', {
+			confirmButtonText: '确认',
+			cancelButtonText: '取消',
+			type: 'warning',
+		}).then(() => {
+			bindMenu(row)
+		})
+		return
+	}
+	ElMessageBox.confirm(`此操作将${status === 1 ? '发布' : '取消发布'}:“${row.name}”,是否继续?`, '提示', {
+		confirmButtonText: '确认',
+		cancelButtonText: '取消',
+		type: 'warning',
+	}).then(async () => {
+		await api.publish({ id: row.id, status, menuId: row.menuId || undefined })
+		ElMessage.success(`${status === 1 ? '发布' : '取消发布'}成功`)
+		getList(1)
+	})
+}
+
 const del = (row: any) => {
 	ElMessageBox.confirm(`此操作将删除:“${row.name}”,是否继续?`, '提示', {
 		confirmButtonText: '确认',

+ 144 - 0
src/views/designer/menu.vue

@@ -0,0 +1,144 @@
+<template>
+	<el-dialog class="api-edit" v-model="showDialog" title="绑定菜单" width="500px" :close-on-click-modal="false" :close-on-press-escape="false">
+		<el-form ref="formRef" :model="formData" :rules="ruleForm" label-width="100px">
+			<el-form-item label="上级菜单" prop="parentId">
+				<el-cascader
+					:options="[
+						{
+							id: -1,
+							title: '主类目',
+							children: menu,
+						},
+					]"
+					:props="{ label: 'title', value: 'id', checkStrictly: true, emitPath: false }"
+					placeholder="请选择上级菜单"
+					:clearable="false"
+					class="w100"
+					v-model="formData.parentId"
+				>
+					<template #default="{ node, data }">
+						<span>{{ data.title }}</span>
+						<span v-if="!node.isLeaf"> ({{ data.children.length }}) </span>
+					</template>
+				</el-cascader>
+			</el-form-item>
+			<el-form-item label="菜单名称" prop="title">
+				<el-input v-model="formData.title" placeholder="请输入菜单名称" clearable @input="formData.name = $event"></el-input>
+			</el-form-item>
+			<el-form-item label="菜单图标" prop="icon">
+				<IconSelector placeholder="请输入菜单图标" v-model="formData.icon" type="all" />
+			</el-form-item>
+			<el-form-item label="菜单排序">
+				<el-input-number v-model="formData.weigh" controls-position="right" placeholder="请输入排序" class="w100" />
+			</el-form-item>
+		</el-form>
+		<template #footer>
+			<div class="dialog-footer">
+				<el-button @click="showDialog = false">取消</el-button>
+				<el-button type="primary" @click="onSubmit">确定</el-button>
+			</div>
+		</template>
+	</el-dialog>
+</template>
+
+<script lang="ts" setup>
+import { ref, reactive, nextTick } from 'vue'
+import { ruleRequired } from '/@/utils/validator'
+import { ElMessage } from 'element-plus'
+import api from '/@/api/system'
+import designerApi from '/@/api/modules/designer'
+import IconSelector from '/@/components/iconSelector/index.vue'
+
+const emit = defineEmits(['getList'])
+const menu = ref([])
+
+api.menu.getList({}).then((res: any) => {
+	menu.value = res || []
+})
+
+const showDialog = ref(false)
+const isEdit = ref(false)
+const formRef = ref()
+
+const baseForm = {
+	designerId: undefined,
+	id: undefined,
+	parentId: null,
+	menuType: 1,
+	title: '',
+	name: '',
+	path: '',
+	component: '',
+	icon: undefined,
+	weigh: null,
+	isHide: 0,
+	isLink: 0,
+	linkUrl: null,
+	isIframe: 0,
+	isAffix: 0,
+	status: 1,
+}
+
+const formData = reactive({
+	...baseForm,
+})
+
+const ruleForm = {
+	title: [ruleRequired('菜单名称不能为空')],
+	parentId: [ruleRequired('上级菜单不能为空')],
+}
+
+const onSubmit = async () => {
+	await formRef.value.validate()
+
+	const theApi = formData.id ? api.menu.edit : api.menu.add
+
+	const res = await theApi(formData)
+
+	if (isEdit.value) {
+		ElMessage.success('编辑成功')
+		resetForm()
+		showDialog.value = false
+		return
+	}
+
+	await designerApi.publish({ id: formData.designerId, menuId: res.id, status: 1 })
+
+	ElMessage.success('发布成功')
+	resetForm()
+	showDialog.value = false
+	emit('getList')
+}
+
+const resetForm = async () => {
+	Object.assign(formData, { ...baseForm })
+	formRef.value && formRef.value.resetFields()
+}
+
+const open = async (row: any) => {
+	resetForm()
+	nextTick(() => {
+		formData.designerId = row.id
+		formData.id = row.menuId || undefined
+		formData.component = '/designer/view'
+		formData.path = '/designerPage/' + row.code
+		if (!row.menuId) {
+			formData.name = row.name
+			formData.title = row.name
+		} else {
+			isEdit.value = true
+			api.menu.detail(row.menuId).then((res: any) => {
+				formData.parentId = res.parentId
+				formData.name = res.name
+				formData.title = res.title
+				formData.isHide = res.isHide
+				formData.icon = res.icon
+				formData.weigh = res.weigh
+			})
+		}
+		showDialog.value = true
+	})
+}
+
+defineExpose({ open })
+</script>

+ 7 - 7
src/views/designer/view.vue

@@ -12,19 +12,19 @@ import { useRoute } from 'vue-router'
 
 const route = useRoute()
 
-const id = route.params?.id
+const code = route.path.replace('/designerPage/', '')
 
 const option = ref({})
 const rule = ref([])
 const fapi = ref(null)
 const formData = ref({})
 
-api.get(id).then((res) => {
-  if (res.content) {
-    const data = JSON.parse(res.content)?.[0]
-    option.value = formCreate.parseJson(data?.options)
-    rule.value = formCreate.parseJson(data?.rule)
-  }
+api.get(code).then((res) => {
+	if (res.content) {
+		const data = JSON.parse(res.content)?.[0]
+		option.value = formCreate.parseJson(data?.options)
+		rule.value = formCreate.parseJson(data?.rule)
+	}
 })
 
 const onSubmit = (formData) => {

+ 159 - 145
src/views/system/menu/index.vue

@@ -1,168 +1,182 @@
 <template>
-  <el-card shadow="nover" class="page">
-    <el-form :model="state.queryParams" inline ref="queryRef" @keyup.enter="handleQuery()">
-      <el-form-item label="菜单名称" prop="title">
-        <el-input v-model="state.queryParams.title" placeholder="请输入菜单名称" clearable class="w-50" />
-      </el-form-item>
-      <!-- <el-form-item label="组件路径">
+	<el-card shadow="nover" class="page">
+		<el-form :model="state.queryParams" inline ref="queryRef" @keyup.enter="handleQuery()">
+			<el-form-item label="菜单名称" prop="title">
+				<el-input v-model="state.queryParams.title" placeholder="请输入菜单名称" clearable class="w-50" />
+			</el-form-item>
+			<!-- <el-form-item label="组件路径">
             <el-input v-model="queryParams.component" placeholder="请输入组件路径" clearable  class="w-50" />
           </el-form-item> -->
-      <el-form-item>
-        <el-button type="primary" class="ml10" @click="handleQuery">
-          <el-icon>
-            <ele-Search />
-          </el-icon>
-          查询
-        </el-button>
-        <el-button @click="resetQuery()">
-          <el-icon>
-            <ele-Refresh />
-          </el-icon>
-          重置
-        </el-button>
-        <el-button type="primary" class="ml10" @click="onOpenAddMenu(null)" v-auth="'add'">
-          <el-icon>
-            <ele-FolderAdd />
-          </el-icon>
-          新增菜单
-        </el-button>
-      </el-form-item>
-    </el-form>
-    <el-table :data="state.menuTableData" :default-expand-all="false" style="width: 100%" row-key="path" :tree-props="{ children: 'children', hasChildren: 'hasChildren' }" v-loading="state.loading">
-      <el-table-column label="菜单名称" show-overflow-tooltip v-col="'title'">
-        <template #default="scope">
-          <SvgIcon :name="scope.row.icon" />
-          <span class="ml10">{{ scope.row.title }}</span>
-        </template>
-      </el-table-column>
-      <el-table-column prop="path" v-col="'path'" label="路由路径" show-overflow-tooltip></el-table-column>
-      <el-table-column label="组件路径" v-col="'component'" prop="component" show-overflow-tooltip></el-table-column>
-      <el-table-column label="排序" v-col="'weigh'" prop="weigh" width="80" align="center"></el-table-column>
-      <el-table-column label="类型" v-col="'menuType'" width="80" align="center">
-        <template #default="scope">
-          <el-tag :type="scope.row.menuType === 0 ? 'info' : scope.row.menuType === 1 ? 'success' : 'warning'" size="small">{{
-            scope.row.menuType === 0 ? '目录' : scope.row.menuType === 1 ? '菜单' : '按钮'
-          }}</el-tag>
-        </template>
-      </el-table-column>
-      <el-table-column prop="isHide" v-col="'isHide'" label="显示状态" align="center" width="120">
-        <template #default="{ row }">
-          {{ row.isHide ? '隐藏' : '显示' }}
-        </template>
-      </el-table-column>
-      <el-table-column label="操作" v-col="'handle'" width="200" align="center" fixed="right">
-        <template #default="scope">
-          <el-button v-if="!scope.row.menuType" size="small" type="text" @click="onOpenAddMenu(scope.row)" v-auth="'add'">新增</el-button>
-          <el-button size="small" text type="warning" @click="onOpenEditMenu(scope.row)" v-auth="'edit'">修改</el-button>
-          <el-button size="small" text type="info" @click="onTabelRowDel(scope.row)" v-auth="'del'">删除</el-button>
-          <el-dropdown v-if="scope.row.menuType">
-            <el-button type="text" size="small" style="margin-top: 1px; margin-left: 10px" v-auth="'more'">更多
-              <el-icon>
-                <ele-ArrowDown />
-              </el-icon>
-            </el-button>
-            <template #dropdown>
-              <el-dropdown-menu>
-                <el-dropdown-item @click.native="authOpen(scope.row, 'buttonAuthorizeList')" v-auth="'btn'">按钮权限</el-dropdown-item>
-                <el-dropdown-item @click.native="authOpen(scope.row, 'listAuthorizeList')" v-auth="'list'">列表权限</el-dropdown-item>
-                <el-dropdown-item @click.native="authOpen(scope.row, 'apiAuthorizeList')" v-auth="'list'">接口权限</el-dropdown-item>
-              </el-dropdown-menu>
-            </template>
-          </el-dropdown>
-        </template>
-      </el-table-column>
-    </el-table>
-    <EditMenu ref="editMenuRef" @menuList="menuList" :menu="state.menuTableData" :visibleOptions="sys_show_hide" :acType="acType" />
-    <ButtonAuthorizeListDrawer ref="buttonAuthorizeList" />
-    <ListAuthorizeListDrawer ref="listAuthorizeList" />
-    <ApiAuthorizeListDrawer ref="apiAuthorizeList" />
-  </el-card>
+			<el-form-item>
+				<el-button type="primary" class="ml10" @click="handleQuery">
+					<el-icon>
+						<ele-Search />
+					</el-icon>
+					查询
+				</el-button>
+				<el-button @click="resetQuery()">
+					<el-icon>
+						<ele-Refresh />
+					</el-icon>
+					重置
+				</el-button>
+				<el-button type="primary" class="ml10" @click="onOpenAddMenu(null)" v-auth="'add'">
+					<el-icon>
+						<ele-FolderAdd />
+					</el-icon>
+					新增菜单
+				</el-button>
+			</el-form-item>
+		</el-form>
+		<el-table
+			:data="state.menuTableData"
+			:default-expand-all="false"
+			style="width: 100%"
+			row-key="path"
+			:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
+			v-loading="state.loading"
+		>
+			<el-table-column label="菜单名称" show-overflow-tooltip v-col="'title'">
+				<template #default="scope">
+					<SvgIcon :name="scope.row.icon" />
+					<span class="ml10">{{ scope.row.title }}</span>
+				</template>
+			</el-table-column>
+			<el-table-column prop="path" v-col="'path'" label="路由路径" show-overflow-tooltip></el-table-column>
+			<el-table-column label="组件路径" v-col="'component'" prop="component" show-overflow-tooltip></el-table-column>
+			<el-table-column label="排序" v-col="'weigh'" prop="weigh" width="80" align="center"></el-table-column>
+			<el-table-column label="类型" v-col="'menuType'" width="80" align="center">
+				<template #default="scope">
+					<el-tag :type="scope.row.menuType === 0 ? 'info' : scope.row.menuType === 1 ? 'success' : 'warning'" size="small">{{
+						scope.row.menuType === 0 ? '目录' : scope.row.menuType === 1 ? '菜单' : '按钮'
+					}}</el-tag>
+				</template>
+			</el-table-column>
+			<el-table-column prop="isHide" v-col="'isHide'" label="显示状态" align="center" width="120">
+				<template #default="{ row }">
+					{{ row.isHide ? '隐藏' : '显示' }}
+				</template>
+			</el-table-column>
+			<el-table-column label="操作" v-col="'handle'" width="200" align="center" fixed="right">
+				<template #default="scope">
+					<el-button v-if="!scope.row.menuType" size="small" type="text" @click="onOpenAddMenu(scope.row)" v-auth="'add'">新增</el-button>
+					<el-button size="small" text type="warning" @click="onOpenEditMenu(scope.row)" v-auth="'edit'">修改</el-button>
+					<el-button size="small" text type="info" @click="onTabelRowDel(scope.row)" v-auth="'del'">删除</el-button>
+					<el-dropdown v-if="scope.row.menuType">
+						<el-button type="text" size="small" style="margin-top: 1px; margin-left: 10px" v-auth="'more'"
+							>更多
+							<el-icon>
+								<ele-ArrowDown />
+							</el-icon>
+						</el-button>
+						<template #dropdown>
+							<el-dropdown-menu>
+								<el-dropdown-item @click.native="authOpen(scope.row, 'buttonAuthorizeList')" v-auth="'btn'">按钮权限</el-dropdown-item>
+								<el-dropdown-item @click.native="authOpen(scope.row, 'listAuthorizeList')" v-auth="'list'">列表权限</el-dropdown-item>
+								<el-dropdown-item @click.native="authOpen(scope.row, 'apiAuthorizeList')" v-auth="'list'">接口权限</el-dropdown-item>
+							</el-dropdown-menu>
+						</template>
+					</el-dropdown>
+				</template>
+			</el-table-column>
+		</el-table>
+		<EditMenu ref="editMenuRef" @menuList="menuList" :menu="state.menuTableData" :visibleOptions="sys_show_hide" :acType="acType" />
+		<ButtonAuthorizeListDrawer ref="buttonAuthorizeList" />
+		<ListAuthorizeListDrawer ref="listAuthorizeList" />
+		<ApiAuthorizeListDrawer ref="apiAuthorizeList" />
+	</el-card>
 </template>
 
 <script lang="ts" setup>
-import { ref, reactive, onBeforeMount, getCurrentInstance } from 'vue';
-import { ElMessageBox, ElMessage } from 'element-plus';
-import EditMenu from '/@/views/system/menu/component/editMenu.vue';
-import api from '/@/api/system';
-import ButtonAuthorizeListDrawer from './component/btn.vue';
-import ListAuthorizeListDrawer from './component/list.vue';
-import ApiAuthorizeListDrawer from './component/api.vue';
-const editMenuRef = ref();
-const queryRef = ref();
-const buttonAuthorizeList = ref();
-const listAuthorizeList = ref();
-const apiAuthorizeList = ref();
+import { ref, reactive, onBeforeMount, getCurrentInstance } from 'vue'
+import { ElMessageBox, ElMessage } from 'element-plus'
+import EditMenu from '/@/views/system/menu/component/editMenu.vue'
+import api from '/@/api/system'
+import ButtonAuthorizeListDrawer from './component/btn.vue'
+import ListAuthorizeListDrawer from './component/list.vue'
+import ApiAuthorizeListDrawer from './component/api.vue'
+const editMenuRef = ref()
+const queryRef = ref()
+const buttonAuthorizeList = ref()
+const listAuthorizeList = ref()
+const apiAuthorizeList = ref()
 const state = reactive({
-  loading: false,
-  queryParams: {
-    title: '',
-    component: '',
-    status: -1,
-  },
-  menuTableData: [],
-});
-const { proxy } = getCurrentInstance() as any;
-const { sys_show_hide } = proxy.useDict('sys_show_hide');
-const acType = ref('add');
+	loading: false,
+	queryParams: {
+		title: '',
+		component: '',
+		status: -1,
+	},
+	menuTableData: [],
+})
+const { proxy } = getCurrentInstance() as any
+const { sys_show_hide } = proxy.useDict('sys_show_hide')
+const acType = ref('add')
 // 打开新增菜单弹窗
 const onOpenAddMenu = (row: any) => {
-  acType.value = 'add';
-  editMenuRef.value.openDialog(row);
-};
+	acType.value = 'add'
+	editMenuRef.value.openDialog(row)
+}
 // 打开编辑菜单弹窗
 const onOpenEditMenu = (row: any) => {
-  acType.value = 'edit';
-  editMenuRef.value.openDialog(row);
-};
+	if (row.path.includes('designerPage')) {
+		return ElMessage.error('设计器菜单无法编辑,请在设计器中编辑')
+	}
+	acType.value = 'edit'
+	editMenuRef.value.openDialog(row)
+}
 
 // 打开按钮权限抽下
 const authOpen = (row: any, key: string) => {
-  if (key === 'buttonAuthorizeList') {
-    return buttonAuthorizeList.value.open(row);
-  }
-  if (key === 'listAuthorizeList') {
-    return listAuthorizeList.value.open(row);
-  }
-  if (key === 'apiAuthorizeList') {
-    return apiAuthorizeList.value.open(row);
-  }
-};
+	if (key === 'buttonAuthorizeList') {
+		return buttonAuthorizeList.value.open(row)
+	}
+	if (key === 'listAuthorizeList') {
+		return listAuthorizeList.value.open(row)
+	}
+	if (key === 'apiAuthorizeList') {
+		return apiAuthorizeList.value.open(row)
+	}
+}
 
 // 删除当前行
 const onTabelRowDel = (row: any) => {
-  ElMessageBox.confirm(`此操作将永久删除菜单:“${row.title}”, 是否继续?`, '提示', {
-    confirmButtonText: '删除',
-    cancelButtonText: '取消',
-    type: 'warning',
-  })
-    .then(() => {
-      api.menu.del(row.id).then(() => {
-        ElMessage.success('删除成功');
-        proxy.$refs['editMenuRef'].resetMenuSession();
-        menuList();
-      });
-    })
-    .catch(() => { });
-};
+	if (row.path.includes('designerPage')) {
+		return ElMessage.error('设计器菜单无法编辑,请在设计器中编辑')
+	}
+	ElMessageBox.confirm(`此操作将永久删除菜单:“${row.title}”, 是否继续?`, '提示', {
+		confirmButtonText: '删除',
+		cancelButtonText: '取消',
+		type: 'warning',
+	})
+		.then(() => {
+			api.menu.del(row.id).then(() => {
+				ElMessage.success('删除成功')
+				proxy.$refs['editMenuRef'].resetMenuSession()
+				menuList()
+			})
+		})
+		.catch(() => {})
+}
 onBeforeMount(() => {
-  menuList();
-});
+	menuList()
+})
 const handleQuery = () => {
-  menuList();
-};
+	menuList()
+}
 // 重置表单
 const resetQuery = () => {
-  queryRef.value.resetFields();
-  handleQuery();
-};
+	queryRef.value.resetFields()
+	handleQuery()
+}
 const menuList = () => {
-  state.loading = true;
-  api.menu
-    .getList(state.queryParams)
-    .then((res: any) => {
-      // console.log({...res[0]})
-      state.menuTableData = res || [];
-    })
-    .finally(() => (state.loading = false));
-};
+	state.loading = true
+	api.menu
+		.getList(state.queryParams)
+		.then((res: any) => {
+			// console.log({...res[0]})
+			state.menuTableData = res || []
+		})
+		.finally(() => (state.loading = false))
+}
 </script>