|
@@ -7,71 +7,67 @@
|
|
|
:title="form.MenuId?'编辑菜单':'添加菜单'"
|
|
|
@close="$emit('close')"
|
|
|
width="820px"
|
|
|
- v-dialogDrag
|
|
|
center
|
|
|
+ :footer="false"
|
|
|
>
|
|
|
- <div class="dialog-container-wrap">
|
|
|
- <el-form :model="form" :rules="rules" label-width="80px" :hide-required-asterisk="true" ref="menuForm">
|
|
|
- <el-form-item label="菜单类型" prop="MenuType">
|
|
|
- <el-radio-group v-model="form.MenuType" :disabled="form.MenuId">
|
|
|
- <el-radio :label="0" :disabled="isMenuDisabled">菜单</el-radio>
|
|
|
- <el-radio :label="1" :disabled="isbtnDisabled">按钮</el-radio>
|
|
|
- <el-radio :label="2" :disabled="isbtnDisabled">字段</el-radio>
|
|
|
- </el-radio-group>
|
|
|
- </el-form-item>
|
|
|
- <el-form-item label="上级菜单" prop="ParentId">
|
|
|
- <el-cascader v-model="form.ParentId"
|
|
|
- :options="menuList"
|
|
|
- :props="menuProps"
|
|
|
- :disabled="openType==='add'?false:!(openType!=='add'&&form.MenuType===0&&form.treeLevel===1)"
|
|
|
- >
|
|
|
- </el-cascader>
|
|
|
- </el-form-item>
|
|
|
- <el-form-item :label="nameLabel" prop="Name">
|
|
|
- <el-input v-model="form.Name"></el-input>
|
|
|
- </el-form-item>
|
|
|
- <template v-if="form.MenuType===0">
|
|
|
- <el-form-item label="菜单图标" prop="Name" v-if="form.treeLevel===0">
|
|
|
- <div class="icon-wrap">
|
|
|
- <img :src="form.IconPath" v-if="form.IconPath">
|
|
|
- <el-button @click="isShowIconDialog = true">选择图标</el-button>
|
|
|
- </div>
|
|
|
- </el-form-item>
|
|
|
- <el-form-item label="路由地址" prop="Path">
|
|
|
- <el-input v-model="form.Path"></el-input>
|
|
|
- <el-tooltip effect="dark" content="页面跳转路径" placement="right">
|
|
|
- <span class="hint-text">
|
|
|
- <i class="el-icon-warning-outline"></i>
|
|
|
- </span>
|
|
|
- </el-tooltip>
|
|
|
- </el-form-item>
|
|
|
- <el-form-item label="组件地址" prop="Component">
|
|
|
- <el-input v-model="form.Component"></el-input>
|
|
|
- <el-tooltip effect="dark" content="代码中页面地址" placement="right">
|
|
|
- <span class="hint-text">
|
|
|
- <i class="el-icon-warning-outline"></i>
|
|
|
- </span>
|
|
|
- </el-tooltip>
|
|
|
- </el-form-item>
|
|
|
- </template>
|
|
|
- <el-form-item label="按钮ID" prop="ButtonCode" v-if="form.MenuType!==0">
|
|
|
- <el-input v-model="form.ButtonCode"></el-input>
|
|
|
- </el-form-item>
|
|
|
- <el-form-item label="显示排序" prop="Sort">
|
|
|
- <el-input v-model="form.Sort" type="number" :min="0"></el-input>
|
|
|
- </el-form-item>
|
|
|
- <el-form-item label="是否隐藏" prop="Hidden">
|
|
|
- <el-radio-group v-model="form.Hidden">
|
|
|
- <el-radio :label="0">显示</el-radio>
|
|
|
- <el-radio :label="1">隐藏</el-radio>
|
|
|
- </el-radio-group>
|
|
|
- </el-form-item>
|
|
|
- </el-form>
|
|
|
- <div class="btn-wrap" style="text-align: center;margin-bottom: 25px;">
|
|
|
- <el-button type="primary" plain style="width:200px;" @click="$emit('close')">取消</el-button>
|
|
|
- <el-button type="primary" style="margin-left:50px;width:200px;" @click="saveMenu">保存</el-button>
|
|
|
- </div>
|
|
|
+ <div class="dialog-container-wrap">
|
|
|
+ <t-form :data="form" :rules="rules" label-width="80px" ref="menuFormRef">
|
|
|
+ <t-form-item label="菜单类型" name="MenuType">
|
|
|
+ <t-radio-group v-model="form.MenuType" :disabled="form.MenuId">
|
|
|
+ <t-radio :value="0" :disabled="isMenuDisabled">菜单</t-radio>
|
|
|
+ <t-radio :value="1" :disabled="isbtnDisabled">按钮</t-radio>
|
|
|
+ <t-radio :value="2" :disabled="isbtnDisabled">字段</t-radio>
|
|
|
+ </t-radio-group>
|
|
|
+ </t-form-item>
|
|
|
+ <t-form-item label="上级菜单" name="ParentId">
|
|
|
+ <t-cascader v-model="form.ParentId" :options="menuList" :keys="menuProps" :disabled="openType === 'add' ? false : !(openType !== 'add' && form.MenuType === 0 && form.treeLevel === 1)">
|
|
|
+ </t-cascader>
|
|
|
+ </t-form-item>
|
|
|
+ <t-form-item :label="nameLabel" name="Name">
|
|
|
+ <t-input v-model="form.Name"></t-input>
|
|
|
+ </t-form-item>
|
|
|
+ <template v-if="form.MenuType === 0">
|
|
|
+ <t-form-item label="菜单图标" name="Name" v-if="form.treeLevel === 0">
|
|
|
+ <div class="icon-wrap">
|
|
|
+ <img :src="form.IconPath" v-if="form.IconPath">
|
|
|
+ <t-button @click="isShowIconDialog = true">选择图标</t-button>
|
|
|
+ </div>
|
|
|
+ </t-form-item>
|
|
|
+ <t-form-item label="路由地址" name="Path">
|
|
|
+ <t-input v-model="form.Path"></t-input>
|
|
|
+ <t-tooltip effect="dark" content="页面跳转路径" placement="right">
|
|
|
+ <span class="hint-text">
|
|
|
+ <i class="t-icon t-icon-warning"></i>
|
|
|
+ </span>
|
|
|
+ </t-tooltip>
|
|
|
+ </t-form-item>
|
|
|
+ <t-form-item label="组件地址" name="Component">
|
|
|
+ <t-input v-model="form.Component"></t-input>
|
|
|
+ <t-tooltip effect="dark" content="代码中页面地址" placement="right">
|
|
|
+ <span class="hint-text">
|
|
|
+ <i class="t-icon t-icon-warning"></i>
|
|
|
+ </span>
|
|
|
+ </t-tooltip>
|
|
|
+ </t-form-item>
|
|
|
+ </template>
|
|
|
+ <t-form-item label="按钮ID" name="ButtonCode" v-if="form.MenuType !== 0">
|
|
|
+ <t-input v-model="form.ButtonCode"></t-input>
|
|
|
+ </t-form-item>
|
|
|
+ <t-form-item label="显示排序" name="Sort">
|
|
|
+ <t-input v-model="form.Sort" type="number" :min="0"></t-input>
|
|
|
+ </t-form-item>
|
|
|
+ <t-form-item label="是否隐藏" name="Hidden">
|
|
|
+ <t-radio-group v-model="form.Hidden">
|
|
|
+ <t-radio :value="0">显示</t-radio>
|
|
|
+ <t-radio :value="1">隐藏</t-radio>
|
|
|
+ </t-radio-group>
|
|
|
+ </t-form-item>
|
|
|
+ </t-form>
|
|
|
+ <div class="btn-wrap" style="text-align: center; margin-bottom: 25px;">
|
|
|
+ <t-button theme="default" variant="outline" plain style="width: 200px;" @click="$emit('close')">取消</t-button>
|
|
|
+ <t-button theme="primary" style="margin-left: 50px; width: 200px;" @click="saveMenu">保存</t-button>
|
|
|
</div>
|
|
|
+ </div>
|
|
|
</t-dialog>
|
|
|
<ChoosedIconDialog
|
|
|
:isShowIconDialog="isShowIconDialog"
|
|
@@ -81,143 +77,168 @@
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
-<script>
|
|
|
+<script setup>
|
|
|
+import { ref, watch, computed, onMounted } from 'vue';
|
|
|
+import _ from 'lodash'; // 确保项目中已安装lodash库
|
|
|
import ChoosedIconDialog from './ChoosedIconDialog.vue';
|
|
|
|
|
|
-export default {
|
|
|
- props: {
|
|
|
- formData: {
|
|
|
- type: Object,
|
|
|
- default: {}
|
|
|
- },
|
|
|
- isShowMenuDialog: {
|
|
|
- type: Boolean,
|
|
|
- default: false
|
|
|
- },
|
|
|
- etaMenu: {
|
|
|
- type: Array,
|
|
|
- default: []
|
|
|
- },
|
|
|
- openType: {
|
|
|
- type: String,
|
|
|
- default: 'add'
|
|
|
- }
|
|
|
- },
|
|
|
- data() {
|
|
|
- return {
|
|
|
- form: {
|
|
|
- MenuType: 0,
|
|
|
- ParentId: 0,
|
|
|
- Name: '',
|
|
|
- IconPath: '',
|
|
|
- Path: '',
|
|
|
- Component: '',
|
|
|
- Sort: 0,
|
|
|
- Hidden: 0,
|
|
|
- ButtonCode: '',
|
|
|
- treeLevel: 0
|
|
|
- },
|
|
|
- rules: {
|
|
|
- ParentId:[{required:true,message:'请选择上级菜单'}],
|
|
|
- Name:[{required:true,message:'请输入菜单标题'}],
|
|
|
- IconPath:[{required:true,message:'请选择菜单图标'}],
|
|
|
- Path:[{required:true,message:'请输入路由地址'}],
|
|
|
- Component:[{required:true,message:'请输入组件地址'}],
|
|
|
- Sort:[{required:true,message:'请输入显示排序'}],
|
|
|
- ButtonCode:[{required:true,message:'请输入按钮ID'}]
|
|
|
- },
|
|
|
- menuList: [{
|
|
|
- MenuId: -1,
|
|
|
- Name: '无'
|
|
|
- }],
|
|
|
- menuProps: {
|
|
|
- value: 'MenuId',
|
|
|
- label: 'Name',
|
|
|
- children: 'Children',
|
|
|
- checkStrictly: true,
|
|
|
- emitPath: false,
|
|
|
- },
|
|
|
- isShowIconDialog: false,
|
|
|
- };
|
|
|
- },
|
|
|
- watch: {
|
|
|
- isShowMenuDialog(newVal) {
|
|
|
- if (newVal) {
|
|
|
- this.form = this.$options.data().form;
|
|
|
- this.menuList = this.$options.data().menuList;
|
|
|
- this.initForm();
|
|
|
- this.$nextTick(()=>{
|
|
|
- this.$refs.menuForm&&this.$refs.menuForm.clearValidate();
|
|
|
- })
|
|
|
- }
|
|
|
- },
|
|
|
- 'form.MenuType': {
|
|
|
- handler(newVal) {
|
|
|
- this.changeListLevel(newVal);
|
|
|
- },
|
|
|
- deep: true
|
|
|
- }
|
|
|
- },
|
|
|
- computed: {
|
|
|
- //菜单类型-菜单 是否禁用
|
|
|
- isMenuDisabled() {
|
|
|
- return this.form.treeLevel > 1 && this.openType !== 'add';
|
|
|
- },
|
|
|
- //菜单类型-按钮、字段 是否禁用
|
|
|
- isbtnDisabled() {
|
|
|
- return this.form.treeLevel === 1 && this.openType !== 'add';
|
|
|
- },
|
|
|
- nameLabel(){
|
|
|
- const nameMap = {
|
|
|
- 0:'菜单标题',
|
|
|
- 1:'按钮名称',
|
|
|
- 2:'字段名称'
|
|
|
- }
|
|
|
- return nameMap[this.form.MenuType]||'菜单标题'
|
|
|
- },
|
|
|
- },
|
|
|
- methods: {
|
|
|
- initForm() {
|
|
|
- this.menuList = [...this.menuList, ..._.cloneDeep(this.etaMenu)];
|
|
|
- if (this.openType === 'addNext') {
|
|
|
- this.form.ParentId = this.formData.ParentId;
|
|
|
- this.form.treeLevel = this.formData.treeLevel;
|
|
|
- }
|
|
|
- if (this.openType === 'edit') {
|
|
|
- this.form = _.cloneDeep(this.formData);
|
|
|
- }
|
|
|
- if (this.form.treeLevel > 1 && this.openType !== 'edit') {
|
|
|
- this.form.MenuType = 1;
|
|
|
- }
|
|
|
- if(this.form.treeLevel===0 && this.openType !== 'add'){
|
|
|
- this.form.ParentId = -1
|
|
|
- }
|
|
|
- },
|
|
|
- saveMenu() {
|
|
|
- //检验表单
|
|
|
- this.$refs.menuForm.validate((valid)=>{
|
|
|
- if(valid){
|
|
|
- this.$emit(this.form.MenuId ? 'edit' : 'add', this.form);
|
|
|
- }
|
|
|
- })
|
|
|
-
|
|
|
- },
|
|
|
- changeListLevel(level) {
|
|
|
- if (level === 0) {
|
|
|
- this.menuList = this.menuList.map(m => {
|
|
|
- if (m.Children) {
|
|
|
- delete m.Children;
|
|
|
- }
|
|
|
- return m;
|
|
|
- });
|
|
|
- }
|
|
|
- else {
|
|
|
- this.menuList = [...this.$options.data().menuList, ..._.cloneDeep(this.etaMenu)];
|
|
|
- }
|
|
|
- }
|
|
|
- },
|
|
|
- components: { ChoosedIconDialog }
|
|
|
+// Props
|
|
|
+const props = defineProps({
|
|
|
+ formData: {
|
|
|
+ type: Object,
|
|
|
+ default: () => ({}),
|
|
|
+ },
|
|
|
+ isShowMenuDialog: {
|
|
|
+ type: Boolean,
|
|
|
+ default: false,
|
|
|
+ },
|
|
|
+ etaMenu: {
|
|
|
+ type: Array,
|
|
|
+ default: () => [],
|
|
|
+ },
|
|
|
+ openType: {
|
|
|
+ type: String,
|
|
|
+ default: 'add',
|
|
|
+ },
|
|
|
+});
|
|
|
+// Events
|
|
|
+const emit = defineEmits(['add', 'edit', 'close']);
|
|
|
+
|
|
|
+// 响应式数据
|
|
|
+const form = ref({
|
|
|
+ MenuType: 0,
|
|
|
+ ParentId: 0,
|
|
|
+ Name: '',
|
|
|
+ IconPath: '',
|
|
|
+ Path: '',
|
|
|
+ Component: '',
|
|
|
+ Sort: 0,
|
|
|
+ Hidden: 0,
|
|
|
+ ButtonCode: '',
|
|
|
+ treeLevel: 0,
|
|
|
+});
|
|
|
+
|
|
|
+const rules = {
|
|
|
+ ParentId: [{ required: true, message: '请选择上级菜单' }],
|
|
|
+ Name: [{ required: true, message: '请输入菜单标题' }],
|
|
|
+ IconPath: [{ required: true, message: '请选择菜单图标' }],
|
|
|
+ Path: [{ required: true, message: '请输入路由地址' }],
|
|
|
+ Component: [{ required: true, message: '请输入组件地址' }],
|
|
|
+ Sort: [{ required: true, message: '请输入显示排序' }],
|
|
|
+ ButtonCode: [{ required: true, message: '请输入按钮ID' }],
|
|
|
+}
|
|
|
+
|
|
|
+const menuList = ref([{ MenuId: -1, Name: '无' }]);
|
|
|
+const menuProps = ref({
|
|
|
+ value: 'MenuId',
|
|
|
+ label: 'Name',
|
|
|
+ children: 'Children',
|
|
|
+ checkStrictly: true,
|
|
|
+ emitPath: false,
|
|
|
+});
|
|
|
+
|
|
|
+const menuFormRef = ref(null);
|
|
|
+const isShowIconDialog = ref(false);
|
|
|
+
|
|
|
+// Watchers
|
|
|
+watch(
|
|
|
+ () => props.isShowMenuDialog,
|
|
|
+ (newVal) => {
|
|
|
+ if (newVal) {
|
|
|
+ resetForm();
|
|
|
+ initForm();
|
|
|
+ }
|
|
|
+ },
|
|
|
+ { immediate: true }
|
|
|
+);
|
|
|
+
|
|
|
+watch(
|
|
|
+ () => form.value.MenuType,
|
|
|
+ (newVal) => {
|
|
|
+ changeListLevel(newVal);
|
|
|
+ },
|
|
|
+ { deep: true }
|
|
|
+);
|
|
|
+
|
|
|
+// Computed Properties
|
|
|
+const isMenuDisabled = computed(() => {
|
|
|
+ return form.value.treeLevel > 1 && props.openType !== 'add';
|
|
|
+});
|
|
|
+
|
|
|
+const isbtnDisabled = computed(() => {
|
|
|
+ return form.value.treeLevel === 1 && props.openType !== 'add';
|
|
|
+});
|
|
|
+
|
|
|
+const nameLabel = computed(() => {
|
|
|
+ const nameMap = {
|
|
|
+ 0: '菜单标题',
|
|
|
+ 1: '按钮名称',
|
|
|
+ 2: '字段名称',
|
|
|
+ };
|
|
|
+ return nameMap[form.value.MenuType] || '菜单标题';
|
|
|
+});
|
|
|
+
|
|
|
+// Methods
|
|
|
+const initForm = () => {
|
|
|
+ menuList.value = [...menuList.value, ..._.cloneDeep(props.etaMenu)];
|
|
|
+ if (props.openType === 'addNext') {
|
|
|
+ form.value.ParentId = props.formData.ParentId;
|
|
|
+ form.value.treeLevel = props.formData.treeLevel;
|
|
|
+ }
|
|
|
+ if (props.openType === 'edit') {
|
|
|
+ form.value = _.cloneDeep(props.formData);
|
|
|
+ }
|
|
|
+ if (form.value.treeLevel > 1 && props.openType !== 'edit') {
|
|
|
+ form.value.MenuType = 1;
|
|
|
+ }
|
|
|
+ if (form.value.treeLevel === 0 && props.openType !== 'add') {
|
|
|
+ form.value.ParentId = -1;
|
|
|
+ }
|
|
|
};
|
|
|
+
|
|
|
+const saveMenu = async () => {
|
|
|
+ const validRes = await menuFormRef.value.validate();
|
|
|
+ if (validRes !== true) return;
|
|
|
+ const emitType = form.value.MenuId ? 'edit' : 'add';
|
|
|
+ emit(emitType, form.value);
|
|
|
+};
|
|
|
+
|
|
|
+const changeListLevel = (level) => {
|
|
|
+ if (level === 0) {
|
|
|
+ menuList.value = menuList.value.map((m) => {
|
|
|
+ if (m.Children) {
|
|
|
+ delete m.Children;
|
|
|
+ }
|
|
|
+ return m;
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ menuList.value = [...menuList.value, ..._.cloneDeep(props.etaMenu)];
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+const resetForm = () => {
|
|
|
+ form.value = {
|
|
|
+ MenuType: 0,
|
|
|
+ ParentId: 0,
|
|
|
+ Name: '',
|
|
|
+ IconPath: '',
|
|
|
+ Path: '',
|
|
|
+ Component: '',
|
|
|
+ Sort: 0,
|
|
|
+ Hidden: 0,
|
|
|
+ ButtonCode: '',
|
|
|
+ treeLevel: 0,
|
|
|
+ };
|
|
|
+ menuList.value = [{ MenuId: -1, Name: '无' }];
|
|
|
+};
|
|
|
+
|
|
|
+// 组件挂载时执行的操作
|
|
|
+onMounted(() => {
|
|
|
+ if (props.isShowMenuDialog) {
|
|
|
+ resetForm();
|
|
|
+ initForm();
|
|
|
+ }
|
|
|
+});
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss">
|
|
@@ -225,6 +246,8 @@ export default {
|
|
|
.dialog-container-wrap{
|
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
|
+ margin: 0 auto;
|
|
|
+ width: 400px;
|
|
|
.el-form{
|
|
|
align-self: center;
|
|
|
.el-form-item{
|
|
@@ -242,6 +265,11 @@ export default {
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+ .btn-wrap {
|
|
|
+ margin-top: 20px;
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
</style>
|