<template> 
 | 
  <div class="menu-container"> 
 | 
    <!-- <el-input/> --> 
 | 
    <vol-box :width="940" :mask="true" :height="500" title="图标列表" v-model="model"> 
 | 
      <Icons :onSelect="onSelect"></Icons> 
 | 
      <template #footer> 
 | 
        <el-button type="primary" size="mini" @click="model = false">确 认</el-button> 
 | 
      </template> 
 | 
    </vol-box> 
 | 
    <vol-box :width="600" :mask="true" :height="270" title="其他权限" v-model="actionModel"> 
 | 
      <vol-form ref="actionForm" :formRules="actionOptions" :formFields="actionFields"> 
 | 
        <template #header> 
 | 
          <div> 
 | 
            <el-alert show-icon type="success"> 
 | 
              配置的其他权限 
 | 
              <br />1、添加新的权限后请在vue项目中config文件夹下buttns.js添加此权限的按钮。 
 | 
              <br />2、如果权限只在某少数几个功能中使用,在vue的对应页面扩展extension文件找到对应js,添加到el-buttons对象中,格式同config文件夹下buttns.js一样。 
 | 
            </el-alert> 
 | 
          </div> 
 | 
        </template> 
 | 
      </vol-form> 
 | 
      <template #footer> 
 | 
        <el-button type="primary" size="mini" @click="otherAction">确 认</el-button> 
 | 
      </template> 
 | 
    </vol-box> 
 | 
  
 | 
    <!-- v-if="tree.length" --> 
 | 
    <div class="menu-left"> 
 | 
      <div class="m-title"><i class="el-icon-warning-outline"></i>菜单列表</div> 
 | 
      <el-scrollbar style="height: 100%; width: 200px"> 
 | 
        <VolMenu :onSelect="getTreeItem" :list="tree" :isCollapse="false"></VolMenu> 
 | 
      </el-scrollbar> 
 | 
    </div> 
 | 
    <div class="menu-right"> 
 | 
      <el-scrollbar style="height: 100%"> 
 | 
        <el-alert title="菜单配置说明" type="warning" :closable="false" show-icon> 
 | 
          <div> 
 | 
            1、如果是用代码生器生成的Vue页面,Url为Vue项目中src->router->viewGrid.js对应表名的path属性 
 | 
          </div> 
 | 
          <div style="padding-top: 5px"> 
 | 
            2、 如果只是建一级菜单或空菜单url不用填写,【视图/表名】填写.或者/ 
 | 
          </div> 
 | 
        </el-alert> 
 | 
        <div style="padding: 0px 30px 0 20px"> 
 | 
          <vol-form class="form-content" ref="form" :formRules="options" :formFields="fields"> 
 | 
          </vol-form> 
 | 
          <div> 
 | 
            <div class="auth-group"> 
 | 
              <label style="width: 100px">权限按钮:</label> 
 | 
              <div class="ck"> 
 | 
                <el-checkbox-group v-model="actions"> 
 | 
                  <el-checkbox v-for="(item, index) in action" :key="index" :label="item.value">{{ item.text + "(" + 
 | 
                    item.value + ")" }}</el-checkbox> 
 | 
                </el-checkbox-group> 
 | 
              </div> 
 | 
            </div> 
 | 
          </div> 
 | 
          <div style="padding-left: 100px"> 
 | 
            <el-button @click="handleCheckAll" size="mini" type="success" plain><i class="el-icon-check"></i>全 
 | 
              选</el-button> 
 | 
            <el-button @click="actionModel = true" size="mini" type="primary" plain><i 
 | 
                class="el-icon-plus"></i>其他权限</el-button> 
 | 
          </div> 
 | 
          <div class="m-btn"> 
 | 
            <el-button type="primary" @click="save"><i class="el-icon-check"></i>保存</el-button> 
 | 
            <el-button type="success" @click="add"><i class="el-icon-plus"></i>新建</el-button> 
 | 
            <el-button type="warning" @click="addChild"><i class="el-icon-plus"></i>添加子级</el-button> 
 | 
            <el-button type="primary" plain @click="addBrother"><i class="el-icon-circle-plus"></i> 添加同级</el-button> 
 | 
            <el-button type="warning" plain @click="delMenu"><i class="el-icon-delete"></i> 删除菜单</el-button> 
 | 
          </div> 
 | 
        </div> 
 | 
      </el-scrollbar> 
 | 
    </div> 
 | 
  </div> 
 | 
</template> 
 | 
<script> 
 | 
import VolForm from "@/components/basic/VolForm.vue"; 
 | 
import VolBox from "@/components/basic/VolBox.vue"; 
 | 
import Icons from "@/components/basic/Icons.vue"; 
 | 
import VolMenu from "@/components/basic/VolElementMenu.vue"; 
 | 
import { 
 | 
  defineComponent, 
 | 
  reactive, 
 | 
  ref, 
 | 
  toRefs, 
 | 
  onMounted, 
 | 
  h, 
 | 
  resolveComponent, 
 | 
} from "vue"; 
 | 
  
 | 
import http from "@/api/http"; 
 | 
export default defineComponent({ 
 | 
  components: { 
 | 
    VolForm: VolForm, 
 | 
    VolBox: VolBox, 
 | 
    Icons: Icons, 
 | 
    VolMenu, 
 | 
  }, 
 | 
  methods: { 
 | 
    otherAction() { 
 | 
      this.$refs.actionForm.validate(() => { 
 | 
        let exist = this.action.some((x) => { 
 | 
          return ( 
 | 
            x.text == this.actionFields.name || 
 | 
            x.value == this.actionFields.value 
 | 
          ); 
 | 
        }); 
 | 
        if (exist) { 
 | 
          return this.$message.error("权限名称或权限值已存在"); 
 | 
        } 
 | 
        this.actionModel = false; 
 | 
        this.action.push({ 
 | 
          text: this.actionFields.name, 
 | 
          value: this.actionFields.value, 
 | 
        }); 
 | 
      }); 
 | 
    }, 
 | 
    handleCheckAll() { 
 | 
      if (this.actions == this.action.length) { 
 | 
        this.checkAll = false; 
 | 
      } else { 
 | 
        this.checkAll = !this.checkAll; 
 | 
      } 
 | 
      if (this.checkAll) { 
 | 
        this.actions = this.action.map((x) => { 
 | 
          return x.value; 
 | 
        }); 
 | 
      } else { 
 | 
        this.actions = []; 
 | 
      } 
 | 
    }, 
 | 
    checkAllGroupChange(data) { 
 | 
      if (data.length === this.action.length) { 
 | 
        this.checkAll = true; 
 | 
      } else if (data.length > 0) { 
 | 
        this.checkAll = false; 
 | 
      } else { 
 | 
        this.checkAll = false; 
 | 
      } 
 | 
    }, 
 | 
    add(obj) { 
 | 
      this.$refs.form.reset( 
 | 
        Object.assign({ enable: 1 }, obj || { parentId: 0 }) 
 | 
      ); 
 | 
      this.icon = ""; 
 | 
      // this.actions = []; 
 | 
      //2020.08.07新建菜单时,默认选中查询按钮权限 
 | 
      this.actions = ["Search"]; 
 | 
    }, 
 | 
    addChild() { 
 | 
      if (!this.isSelect()) return; 
 | 
      this.add({ parentId: this.fields.menuId }); 
 | 
    }, 
 | 
    addBrother() { 
 | 
      if (!this.isSelect()) return; 
 | 
      this.add({ parentId: this.fields.parentId }); 
 | 
    }, 
 | 
    delMenu() { 
 | 
      //2020.08.07增加菜单删除功能 
 | 
      if (this.fields.menuId == 0) { 
 | 
        return this.$Message.error("请选择菜单"); 
 | 
      } 
 | 
  
 | 
      let tigger = false; 
 | 
      this.$confirm( 
 | 
        "确认要删除【" + this.fields.menuName + "】菜单吗?", 
 | 
        "警告", 
 | 
        { 
 | 
          confirmButtonText: "确定", 
 | 
          cancelButtonText: "取消", 
 | 
          type: "warning", 
 | 
          center: true, 
 | 
        } 
 | 
      ).then(() => { 
 | 
        if (tigger) return; 
 | 
        tigger = true; 
 | 
        let menuId = this.fields.menuId; 
 | 
        this.http 
 | 
          .post("/api/Sys_Menu/delMenu?menuId=" + menuId, {}, "正在删除数据....") 
 | 
          .then((x) => { 
 | 
            if (!x.status) return this.$Message.error(x.message); 
 | 
            this.$refs.form.reset(); 
 | 
            this.$Message.info(x.message); 
 | 
            this.initTree(); 
 | 
          }); 
 | 
      }); 
 | 
    }, 
 | 
    save() { 
 | 
      this.$refs.form.validate(() => { 
 | 
        this.fields.auth = ""; 
 | 
        if (this.actions) { 
 | 
          this.fields.auth = this.action.filter((x) => { 
 | 
            return this.actions.indexOf(x.value) != -1; 
 | 
          }); 
 | 
        } 
 | 
        if ( 
 | 
          this.fields.auth && 
 | 
          this.fields.auth instanceof Array && 
 | 
          this.fields.auth.length > 0 
 | 
        ) { 
 | 
          this.fields.auth = JSON.stringify(this.fields.auth); 
 | 
        } else { 
 | 
          this.fields.auth = ""; 
 | 
        } 
 | 
        this.http.post("/api/Sys_Menu/save", this.fields, true).then((x) => { 
 | 
          if (!x.status) { 
 | 
            this.$Message.error(x.message); 
 | 
            return; 
 | 
          } 
 | 
  
 | 
          this.$Message.info(x.message); 
 | 
          if (this.fields.menuId) { 
 | 
            this.tree.forEach((t) => { 
 | 
              if (t.id == this.fields.menuId) { 
 | 
                t.name = this.fields.menuName; 
 | 
                t.orderNo = this.fields.orderNo; 
 | 
                t.parentId = this.fields.parentId; 
 | 
              } 
 | 
            }); 
 | 
            return; 
 | 
          } 
 | 
          this.fields.menuId = x.data.menuId; 
 | 
          this.fields.createDate = x.data.createDate; 
 | 
          this.tree.push({ 
 | 
            id: x.data.menuId, 
 | 
            name: this.fields.menuName, 
 | 
            orderNo: this.fields.orderNo, 
 | 
            parentId: this.fields.parentId, 
 | 
          }); 
 | 
          console.log(this.tree) 
 | 
        }); 
 | 
      }); 
 | 
    }, 
 | 
    isSelect() { 
 | 
      let id = this.fields.menuId; 
 | 
      if (!id) { 
 | 
        this.$message.error("请选择节点"); 
 | 
        return false; 
 | 
      } 
 | 
      return true; 
 | 
    }, 
 | 
    onSelect(icon) { 
 | 
      this.fields.icon = icon; 
 | 
      this.$message.info(icon); 
 | 
    }, 
 | 
    onOpenChange(node) { 
 | 
      if (node.length == 0) return; 
 | 
      this.getTreeItem(node[node.length > 1 ? node.length - 1 : 0]); 
 | 
    } 
 | 
  }, 
 | 
  created(){ 
 | 
  
 | 
  }, 
 | 
  setup() { 
 | 
    const tree = ref([]); 
 | 
    const actionValues = ref([]); 
 | 
    const action = ref([ 
 | 
      { text: "查询", value: "Search" }, 
 | 
      { text: "新建", value: "Add" }, 
 | 
      { text: "删除", value: "Delete" }, 
 | 
      { text: "编辑", value: "Update" }, 
 | 
      { text: "导入", value: "Import" }, 
 | 
      { text: "导出", value: "Export" }, 
 | 
      // { text: "上传", value: "Upload" }, 
 | 
      // { text: "审核", value: "Audit" }, 
 | 
    ]); 
 | 
    const actions = ref([]); 
 | 
    actionValues.value = action.value.map((x) => { 
 | 
      return x.value; 
 | 
    }); 
 | 
    const initTree = () => { 
 | 
      http.post("/api/Sys_Menu/getMenu", {}, true).then((x) => { 
 | 
        x.forEach(item => { 
 | 
          item.icon = 'el-icon-menu'; 
 | 
        }) 
 | 
         
 | 
        tree.value = x; 
 | 
      }); 
 | 
    }; 
 | 
    onMounted(() => { 
 | 
      initTree(); 
 | 
    }); 
 | 
    const actionModel = ref(false); 
 | 
    const checkAll = ref(false); 
 | 
    const model = ref(false); 
 | 
  
 | 
    const fields = ref({ 
 | 
      menuId: 0, 
 | 
      parentId: 0, 
 | 
      menuName: "", 
 | 
      tableName: "", 
 | 
      url: "", 
 | 
      auth: "", 
 | 
      icon: "", 
 | 
      orderNo: "", 
 | 
      enable: 1, 
 | 
      createDate: "", 
 | 
      creator: "", 
 | 
      modifyDate: "", 
 | 
    }); 
 | 
  
 | 
    const actionFields = ref({ 
 | 
      name: "", 
 | 
      value: "", 
 | 
    }); 
 | 
    const actionOptions = ref([ 
 | 
      [ 
 | 
        { 
 | 
          title: "权限名称", 
 | 
          field: "name", 
 | 
          placeholder: "权限名称,如:新增", 
 | 
          required: true, 
 | 
        }, 
 | 
      ], 
 | 
      [ 
 | 
        { 
 | 
          title: "权 限 值", 
 | 
          field: "value", 
 | 
          placeholder: "权限值,如:Add", 
 | 
          required: true, 
 | 
        }, 
 | 
      ], 
 | 
    ]); 
 | 
  
 | 
    const options = ref([ 
 | 
      [ 
 | 
        { 
 | 
          title: "菜 单 ID", 
 | 
          field: "menuId", 
 | 
          placeholder: "菜单ID", 
 | 
          min: 0, 
 | 
          disabled: true, 
 | 
        }, 
 | 
        { 
 | 
          title: "父 级 ID", 
 | 
          required: true, 
 | 
          type: "number", 
 | 
          min: 0, 
 | 
          field: "parentId", 
 | 
          // min: 0, max: 50 
 | 
        }, 
 | 
        { 
 | 
          title: "菜单名称", 
 | 
          field: "menuName", 
 | 
          required: true, 
 | 
        }, 
 | 
      ], 
 | 
      [ 
 | 
        { 
 | 
          title: "视图/表名", 
 | 
          field: "tableName", 
 | 
          placeholder: "与代码生成器使用的名称相同", 
 | 
          required: true, 
 | 
        }, 
 | 
        { 
 | 
          title: "(路由)Url", 
 | 
          field: "url", 
 | 
          placeholder: "见:上面菜单配置说明", 
 | 
        }, 
 | 
        { 
 | 
          title: "排序号", 
 | 
          field: "orderNo", 
 | 
          type: "number", 
 | 
          min: 0, 
 | 
          placeholder: "值越大显示越靠前", 
 | 
          required: true, 
 | 
        }, 
 | 
      ], 
 | 
      [ 
 | 
        { 
 | 
          title: "是否启用", 
 | 
          field: "enable", 
 | 
          required: true, 
 | 
          type: "select", 
 | 
          colSize: 4, 
 | 
          data: [ 
 | 
            { key: 1, value: "启用" }, 
 | 
            { key: 2, value: "启用不显示" }, 
 | 
            { key: 0, value: "禁用" }, 
 | 
          ], 
 | 
        }, 
 | 
        // { 
 | 
        //   // 2022.03.26增移动端加菜单类型 
 | 
        //   title: "菜单类型", 
 | 
        //   field: "menuType", 
 | 
        //   required: true, 
 | 
        //   type: "select", 
 | 
        //   colSize: 4, 
 | 
        //   data: [ 
 | 
        //     { key: 1, value: "WCS菜单" }, 
 | 
        //     { key: 0, value: "WMS菜单" }, 
 | 
        //     { key: 99, value: "共用" } 
 | 
        //   ], 
 | 
        // }, 
 | 
        { 
 | 
          title: "图标Icon", 
 | 
          field: "icon", 
 | 
          render: (h) => { 
 | 
            return h("div", {}, [ 
 | 
              h("i", { 
 | 
                style: { 
 | 
                  "font-size": "25px", 
 | 
                  margin: "0px 9px", 
 | 
                  position: "relative", 
 | 
                  top: "4px", 
 | 
                }, 
 | 
                class: [fields.value.icon], 
 | 
              }), 
 | 
              h( 
 | 
                resolveComponent("el-button"), 
 | 
                { 
 | 
                  size: "small", 
 | 
                  style: { padding: "0px 9px" }, 
 | 
                  type: "primary", 
 | 
                  plain: true, 
 | 
                  onClick: () => { 
 | 
                    model.value = true; 
 | 
                  }, 
 | 
                }, 
 | 
                "选择图标" 
 | 
              ), 
 | 
            ]); 
 | 
          }, 
 | 
        }, 
 | 
      ], 
 | 
    ]); 
 | 
    const refForm = ref(); 
 | 
    const getTreeItem = (node) => { 
 | 
      http.post("api/Sys_Menu/getTreeItem?menuId=" + node, {}, true).then((x) => { 
 | 
        try { 
 | 
          fields.value.icon = x.icon; 
 | 
          if (x.auth) { 
 | 
            x.auth = JSON.parse(x.auth); 
 | 
            action.value.splice(8, action.value.length); 
 | 
  
 | 
            actions.value = x.auth.map((element) => { 
 | 
              if (actionValues.value.indexOf(element.value) == -1) { 
 | 
                action.value.push(element); 
 | 
              } 
 | 
              return element.value; 
 | 
            }); 
 | 
          } else { 
 | 
            action.value.splice(8, action.value.length); 
 | 
            x.auth = []; 
 | 
            fields.value.icon = ""; 
 | 
            actions.value = []; 
 | 
          } 
 | 
        } catch (error) { 
 | 
          console.log("菜单功能权限转换成JSON失败:" + x.auth); 
 | 
          x.auth = []; 
 | 
          //   this.icon = ""; 
 | 
          actions.value = []; 
 | 
        } 
 | 
        refForm.value.reset(x); 
 | 
      }); 
 | 
    }; 
 | 
    return { 
 | 
      tree, 
 | 
      initTree, 
 | 
      action, 
 | 
      actions, 
 | 
      actionValues, 
 | 
      actionModel, 
 | 
      checkAll, 
 | 
      model, 
 | 
      fields, 
 | 
      actionFields, 
 | 
      actionOptions, 
 | 
      options, 
 | 
      form: refForm, 
 | 
      getTreeItem 
 | 
    }; 
 | 
  }, 
 | 
  data() { 
 | 
    return {}; 
 | 
  }, 
 | 
}); 
 | 
</script> 
 | 
  
 | 
<style lang="less" scoped> 
 | 
.on-icon { 
 | 
  line-height: 20px; 
 | 
  position: relative; 
 | 
  
 | 
  .remove { 
 | 
    display: none; 
 | 
    color: red; 
 | 
    right: 7px; 
 | 
    position: absolute; 
 | 
    top: -14px; 
 | 
    font-size: 13px; 
 | 
  } 
 | 
} 
 | 
  
 | 
.on-icon:hover { 
 | 
  cursor: pointer; 
 | 
  
 | 
  .remove { 
 | 
    display: block; 
 | 
  } 
 | 
} 
 | 
  
 | 
.action { 
 | 
  width: 100%; 
 | 
  display: flex; 
 | 
  
 | 
  margin-bottom: 15px; 
 | 
  
 | 
  .ivu-checkbox-wrapper { 
 | 
    margin-right: 20px; 
 | 
  } 
 | 
  
 | 
  .ck { 
 | 
    line-height: 33px; 
 | 
    display: inline-block; 
 | 
    display: flex; 
 | 
  
 | 
    label:first-child { 
 | 
      min-width: 58px; 
 | 
      float: left; 
 | 
      margin-top: 1px; 
 | 
    } 
 | 
  
 | 
    >div { 
 | 
      float: left; 
 | 
    } 
 | 
  } 
 | 
} 
 | 
  
 | 
.menu-container { 
 | 
  display: flex; 
 | 
  position: absolute; 
 | 
  width: 100%; 
 | 
  height: 100%; 
 | 
  padding: 8px; 
 | 
  background: #f7f7f7; 
 | 
  
 | 
  .menu-left { 
 | 
    height: 100%; 
 | 
    width: 201px; 
 | 
    border: 1px solid #eee; 
 | 
    display: flex; 
 | 
    background: white; 
 | 
    flex-direction: column; 
 | 
  
 | 
    .module-name { 
 | 
      border-radius: 0px; 
 | 
      /* height: 5%; */ 
 | 
      line-height: 21px; 
 | 
      margin-bottom: 0; 
 | 
    } 
 | 
  } 
 | 
  
 | 
  .menu-right { 
 | 
    flex: 1; 
 | 
    border-radius: 3px; 
 | 
    border: 1px solid #eee; 
 | 
    background: white; 
 | 
    margin-left: 9px; 
 | 
    margin-right: 3px; 
 | 
  } 
 | 
} 
 | 
  
 | 
.m-btn { 
 | 
  margin-top: 20px; 
 | 
  text-align: center; 
 | 
} 
 | 
  
 | 
.m-title { 
 | 
  line-height: 40px; 
 | 
  font-size: 15px; 
 | 
  background: #66b1ff0f; 
 | 
  font-weight: bold; 
 | 
  padding: 6px 16px; 
 | 
  border-bottom: 1px solid #eee; 
 | 
  
 | 
  i { 
 | 
    padding-right: 5px; 
 | 
  } 
 | 
} 
 | 
  
 | 
.form-content { 
 | 
  margin-top: 30px; 
 | 
} 
 | 
  
 | 
.menu-left ::v-deep(.el-scrollbar__bar.is-vertical) { 
 | 
  width: 2px; 
 | 
} 
 | 
  
 | 
.auth-group { 
 | 
  display: flex; 
 | 
  
 | 
  label { 
 | 
    display: inline-block; 
 | 
    width: 100px; 
 | 
    text-align: right; 
 | 
    color: #797979; 
 | 
    font-size: 14px; 
 | 
  } 
 | 
  
 | 
  .ck { 
 | 
    flex: 1; 
 | 
  } 
 | 
  
 | 
  .el-checkbox { 
 | 
    min-width: 105px; 
 | 
    width: auto !important; 
 | 
    margin-right: 5px; 
 | 
    display: inline-block; 
 | 
    padding-bottom: 10px; 
 | 
  } 
 | 
} 
 | 
  
 | 
.auth-group ::v-deep(.el-checkbox__label) { 
 | 
  padding-left: 4px; 
 | 
} 
 | 
</style> 
 |