From daa3d9edea915514e28c568b7288e6415f02fef4 Mon Sep 17 00:00:00 2001
From: 田源 <tianyuan@vci-tech.com>
Date: 星期二, 07 一月 2025 17:24:20 +0800
Subject: [PATCH] 页面按钮权限以及图标和样式

---
 Source/plt-web/plt-web-ui/src/views/modelingMenu/ui/Icons/index.vue |  527 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 512 insertions(+), 15 deletions(-)

diff --git a/Source/plt-web/plt-web-ui/src/views/modelingMenu/ui/Icons/index.vue b/Source/plt-web/plt-web-ui/src/views/modelingMenu/ui/Icons/index.vue
index 8029910..4bdb4a0 100644
--- a/Source/plt-web/plt-web-ui/src/views/modelingMenu/ui/Icons/index.vue
+++ b/Source/plt-web/plt-web-ui/src/views/modelingMenu/ui/Icons/index.vue
@@ -2,48 +2,545 @@
   <el-container>
     <el-main>
       <basic-container>
-        <div class="tag-group">
-          <span class="tag-group__title">鍒嗙被</span>
-          <el-tag
-            v-for="item in types"
-            :key="item"
-            :type="checkedTypes.includes(item)?'success':'info'" size="small"
-            effect="plain" @click="changeType(item)">
-            {{ item }}
-          </el-tag>
+        <div style="display: flex;justify-content: space-between;flex-wrap: wrap">
+          <div class="tag-group">
+            <span class="tag-group__title" v-if="types.length>0">鍒嗙粍</span>
+            <el-tag
+              v-for="item in types"
+              :key="item.key"
+              :type="checkedTypes.includes(item.key)?'success':'info'" size="small"
+              effect="plain" @click="changeType(item.key)">
+              {{ item.value }}
+            </el-tag>
+          </div>
+          <avue-input v-model="searchText" @change="handleSearch" placeholder="鏌ヨ" size="mini" prefixIcon="el-icon-search" style="width: 300px;max-width: 30%"></avue-input>
         </div>
-        <div>
+        <div style="height: calc(100vh - 190px)">
+          <div>
+            <el-button v-if="permissionList.addBtn" class="button-custom-icon" type="primary" size="small" @click="addHandler">
+              <icon-show :name="permissionList.addBtn.source"></icon-show>
+              娣诲姞
+            </el-button>
+            <el-button v-if="permissionList.uploadBtn" class="button-custom-icon" type="primary" size="small" @click="uploadHandler">
+              <icon-show :name="permissionList.uploadBtn.source"></icon-show>
+              涓婁紶
+            </el-button>
+          </div>
+
+          <el-tabs v-model="activeName" @tab-click="handleClick">
+            <el-tab-pane v-for="item in iconList" :label="item.lable" :name="item.lable" style="height: calc(100vh - 270px);overflow: auto ">
+              <div class="iconList">
+                <div class="iconItem" v-for="svg in item.list"
+                     :data-value="svg.name" v-right-click="{action:checkSvg,data:svg}">
+                  <div class="svgContent" v-html="svg.content"></div>
+                  <span>{{svg.name.split(':')[1]}}</span>
+                </div>
+              </div>
+              <div v-if="menuVisible" class="el-cascader-panel is-bordered iconList__menu"  :style="menuPosition">
+                <div class="iconList__item" @click="editHandler">缂� 杈�</div>
+                <div class="iconList__item" @click="delHandler">鍒� 闄�</div>
+              </div>
+            </el-tab-pane>
+          </el-tabs>
         </div>
+        <!-- 涓婁紶 -->
+        <el-dialog
+          v-dialogDrag
+          title="涓婁紶鍥炬爣"
+          :visible.sync="visible"
+          append-to-body="true"
+          class="avue-dialog"
+          width="600px"
+          @close="visibleCloseHandler"
+        >
+          <avue-form ref="form" :option="option" v-model="form" :upload-after="uploadAfter" style="margin-bottom: 0;height:90px;overflow: hidden"> </avue-form>
+          <pre style="font-size: 12px;color: #909399;margin-top: 0;padding:5px;background-color: #F5F7FA">涓婁紶鏂囦欢涓簀son鏂囦欢锛岀ず渚嬪涓�
+[{
+    "name": "鍥炬爣搴撳悕:鍥炬爣鍚嶇О",
+    "svg": "svg鐨刪tml浠g爜"
+  },
+  {
+    "name": "鍥炬爣搴撳悕:鍥炬爣鍚嶇О",
+    "svg": "svg鐨刪tml浠g爜"
+ }]
+ 鏂囦欢鍐呭椤讳弗鏍兼寜鐓хず渚嬫牸寮忥紝name涓哄浘鏍囧簱鍚�+鍥炬爣鍚嶇О锛屼互鈥�:鈥濆垎闅旓紝svg涓哄浘鏍噃tml浠g爜</pre>
+        </el-dialog>
+        <!-- 娣诲姞銆佷慨鏀� -->
+        <el-dialog
+          v-dialogDrag
+          :title="editType=='add'?'娣诲姞鍥炬爣':'淇敼鍥炬爣'"
+          :visible.sync="editVisible"
+          append-to-body="true"
+          class="avue-dialog"
+          width="500px"
+          @close="closeHandler"
+        >
+          <avue-form ref="editForm" :option="editOption" v-model="editForm"> </avue-form>
+          <span slot="footer" class="dialog-footer">
+           <el-button size="small" type="primary" @click="editSaveHandler">纭� 瀹�</el-button>
+           <el-button size="small" @click="closeHandler">鍙� 娑�</el-button>
+          </span>
+        </el-dialog>
       </basic-container>
     </el-main>
   </el-container>
 </template>
 
 <script>
+import {getIcons,addIcon,updateIcon,deleteIcon} from "@/api/UI/Icons";
+import {getDicts} from "@/api/system/dict";
+import {validatenull} from "@/util/validate";
+import {getStore} from "@/util/store";
+import store from "@/store";
+import {getToken} from "@/util/auth";
+import {mapGetters} from "vuex";
+
 export default {
 name: "index",
-  data() {
-    return {
-      types: ['鏍囩涓�' , '鏍囩浜�' ,  '鏍囩涓�' , '鏍囩鍥�','鏍囩浜�'  ],
-      checkedTypes:[]
+  directives: {
+    rightClick: {
+      bind(el, binding) {
+        el.oncontextmenu = (e) => {
+          e.preventDefault();
+          const menu = binding.value;
+          menu.action(e,menu.data);
+        };
+      }
     }
   },
+  data() {
+    return {
+      types: [],
+      checkedTypes:[],
+      searchText:'',
+      activeName:'',
+      allIconList:[],
+      iconList:[],
+      visible: false,
+      checkItem:null,
+      option: {
+        labelWidth: 80,
+        submitBtn:false,
+        emptyBtn:false,
+        column: [{
+          label: '鍒嗙粍',
+          prop: 'groups',
+          type: 'select',
+          span: 24,
+          multiple:true,
+          dicData:[],
+          props:{
+            label:'value',
+            value:'key'
+          }
+        }, {
+            label: "闄勪欢涓婁紶",
+            prop: "file",
+            type: "upload",
+            dataType: "object",
+            accept:'.json',
+            action:"api/webIconController/importIcon",
+            data:{},
+            headers:this.uploadHeaders,
+            span: 24,
+          }
+        ]
+      },
+      form:{
+        type:'svg',
+        groups:[],
+        file:null
+      },
+      editType:'edit',
+      editVisible:false,
+      editOption:{
+        labelWidth: 90,
+        submitBtn:false,
+        emptyBtn:false,
+        column: [{
+          label: '鍥炬爣搴撳悕',
+          prop: 'libname',
+          type: 'input',
+          disabled:true,
+          span: 24,
+          rules: [{
+            required: true,
+            message: "璇疯緭鍏ュ浘鏍囧簱鍚�",
+            trigger: "blur"
+          }]
+        },{
+          label: '鍚嶇О',
+          prop: 'iconname',
+          type: 'input',
+          disabled:true,
+          span: 24,
+          rules: [{
+            required: true,
+            message: "璇疯緭鍏ュ浘鏍囧悕绉�",
+            trigger: "blur"
+          }]
+        },{
+          label: '鍒嗙粍',
+          prop: 'groups',
+          type: 'select',
+          span: 24,
+          multiple:true,
+          dicData:[],
+          props:{
+            label:'value',
+            value:'key'
+          }
+        }, {
+          label: "鍥炬爣浠g爜",
+          prop: "content",
+          type: "textarea",
+          span: 24,
+          placeholder:'璇疯緭鍏ュ浘鏍噃tml浠g爜锛屾牸寮忕ず渚�<svg xmlns=\"http://www.w3.org/2000/svg\" ></svg>',
+          rules: [{
+            required: true,
+            message: "璇疯緭鍏ュ浘鏍噑vg浠g爜",
+            trigger: "blur"
+          }]
+        }]
+      },
+      editForm:{
+        oid:'',
+        libname:'',
+        iconname:'',
+        content:''
+      },
+      menuVisible:false,
+      menuPosition: {
+        top: 0,
+        left: 0
+      }
+    }
+  },
+  computed: {
+    uploadHeaders() {
+      return {
+        "Authorizationtoken":getToken(),
+      };
+    },
+    ...mapGetters(["permission"]),
+    permissionList() {
+      return {
+        addBtn: this.vaildData(this.permission[this.$route.query.id].ADD, false),
+        uploadBtn: this.vaildData(this.permission[this.$route.query.id].UPLOAD, false),
+      };
+    },
+  },
+  watch:{
+    'form.groups'(val){
+      this.option.column[1].data={
+        type:'svg',
+        groups:val
+      }
+    }
+  },
+  created() {
+    this.getGroups();
+    this.initList();
+  },
   methods:{
+    getGroups() {
+      getDicts('EnumIconGroups').then(res => {
+        if (res.data.success) {
+          this.types = res.data.obj;
+          this.option.column[0].dicData = res.data.obj;
+          this.editOption.column[2].dicData =res.data.obj;
+        } else {
+          this.$message.error(res.data.msg);
+        }
+      })
+    },
+    initList(reload){
+      if(reload) {
+        getIcons().then(res => {
+          if (res.data.success) {
+            this.iconList = res.data.data;
+            this.allIconList = this.iconList;
+            store.dispatch("setIcons", this.iconList);
+            if (this.iconList.length > 0) {
+              this.activeName = this.iconList[0].lable;
+            }
+          } else {
+            this.$message.error(res.data.msg);
+          }
+        })
+
+        return;
+      }
+      if (!validatenull(this.$store.state.icons)) {
+        this.iconList = this.$store.state.icons;
+      } else {
+        this.iconList = getStore({ name:'icons'});
+      }
+      this.allIconList=this.iconList;
+      if(this.iconList && this.iconList.length>0){
+        this.activeName=this.iconList[0].lable;
+      }else {
+        getIcons().then(res => {
+          if (res.data.success) {
+            this.iconList = [{
+              lable: 'iconoir',
+              list: [{
+                oid: '',
+                groups: '1',
+                "name": "iconoir:accessibility",
+                "content": "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"1em\" height=\"1em\" viewBox=\"0 0 24 24\"><g fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.5\"><path d=\"M12 22c5.523 0 10-4.477 10-10S17.523 2 12 2S2 6.477 2 12s4.477 10 10 10M7 9l5 1m5-1l-5 1m0 0v3m0 0l-2 5m2-5l2 5\"/><path fill=\"currentColor\" d=\"M12 7a.5.5 0 1 1 0-1a.5.5 0 0 1 0 1\"/></g></svg>"
+              }]
+            }]
+            this.iconList = res.data.data;
+            this.allIconList = this.iconList;
+            store.dispatch("setIcons", this.iconList);
+            if (this.iconList.length > 0) {
+              this.activeName = this.iconList[0].lable;
+            }
+          } else {
+            this.$message.error(res.data.msg);
+          }
+        })
+      }
+    },
     changeType(type){
       if(this.checkedTypes.includes(type)){
         this.checkedTypes=this.checkedTypes.filter(item=> item!=type)
       }else {
         this.checkedTypes.push(type)
       }
+      //鎸夌収鍒嗙被杩囨护鍥炬爣
+      if(this.checkedTypes.length==0){
+        this.iconList=this.allIconList
+      }else{
+        const checkedTypes=JSON.stringify(this.checkedTypes);
+        const iconList=[];
+        this.allIconList.forEach(item=>{
+          iconList.push({
+            lable:item.lable,
+            list:item.list.filter(iconitem=> {
+              return checkedTypes.indexOf(iconitem.groups)!=-1;
+            })
+          })
+        })
+        this.iconList=iconList;
+      }
+      this.activeName=this.iconList[0].lable;
+    },
+    handleSearch(data){
+      if(data.value==''){
+        this.iconList=this.allIconList;
+      }
+      let iconList=[]
+      this.allIconList.forEach(item=> {
+        iconList.push({
+          lable:item.lable,
+          list: item.list.filter(iconItem=>{
+            return iconItem.name.replace(item.lable,'').indexOf(data.value)!=-1;
+          })
+        })
+      })
+      this.iconList=iconList;
+    },
+    handleClick(tab, event){
+
+    },
+    uploadHandler(){
+      this.visible = true;
+    },
+    //涓婁紶鍚�
+    uploadAfter(res,done){
+      if (res.success) {
+        this.$message.success(res.msg);
+        this.initList(true);
+        this.visibleCloseHandler();
+      }else {
+        this.$message.error(res.msg);
+      }
+      done();
+    },
+    // 鍏抽棴瀵硅瘽妗�
+    visibleCloseHandler() {
+      const form = {
+        type:'svg',
+        groups:[],
+        file:null
+      }
+      this.form = form;
+      this.visible = false;
+      this.$refs.form.clearValidate();
+    },
+    checkSvg(event,svgObj){
+      this.checkItem=svgObj;
+      // 璁剧疆鑿滃崟鍙
+      this.menuVisible = true;
+      this.menuPosition.top = `${event.clientY}px`;
+      this.menuPosition.left = `${event.clientX}px`;
+      document.addEventListener('click',()=>{
+        this.menuVisible=false;
+      })
+    },
+    // 涓婁紶淇濆瓨
+    uploadSaveHandler() {
+      this.$refs.form.validate((valid,done) => {
+        if (valid) {
+          done()
+          addIcon(this.form).then(res => {
+            if (res.data.code === 200) {
+              this.$message.success(res.data.msg);
+              this.initList(true);
+              done();
+              this.visibleCloseHandler();
+            } else {
+              this.$message.error(res.data.msg);
+            }
+          })
+        } else {
+          return false;
+        }
+      });
+    },
+    addHandler(){
+      this.editOption.column[0].disabled=false;
+      this.editOption.column[1].disabled=false;
+      this.editType='add';
+      this.editVisible=true;
+    },
+    editHandler(){
+      this.editType='edit';
+      this.editOption.column[0].disabled=true;
+      this.editOption.column[1].disabled=true;
+      this.editForm=this.checkItem;
+      this.editForm.libname=this.checkItem.name.split(':')[0]
+      this.editForm.iconname=this.checkItem.name.split(':')[1]
+      this.editVisible=true;
+    },
+    editSaveHandler(){
+      this.$refs.editForm.validate((valid,done) => {
+        if (valid) {
+          done()
+          this.editForm.name= this.editForm.libname+':'+ this.editForm.iconname;
+          if(this.editType=='edit'){
+            updateIcon(this.editForm).then(res => {
+              if (res.data.code === 200) {
+                this.$message.success(res.data.msg);
+                this.initList(true);
+                done();
+                this.closeHandler();
+              } else {
+                this.$message.error(res.data.msg);
+              }
+            })
+          }else {
+            addIcon(this.editForm).then(res => {
+              if (res.data.code === 200) {
+                this.$message.success(res.data.msg);
+                this.initList(true);
+                done();
+                this.closeHandler();
+              } else {
+                this.$message.error(res.data.msg);
+              }
+            })
+          }
+        } else {
+          return false;
+        }
+      });
+    },
+    closeHandler(){
+      this.editForm={
+        type:'svg',
+        oid:'',
+        libname:'',
+        iconname:'',
+        groups:[],
+        content:''
+      };
+      this.editOption.column[0].disabled=false;
+      this.editOption.column[1].disabled=false;
+      this.editVisible=false;
+      this.$refs.editForm.clearValidate();
+    },
+    delHandler(){
+      this.$confirm('鎮ㄧ‘瀹氳鍒犻櫎璇ュ浘鏍囧悧锛�', '鎻愮ず', {
+        confirmButtonText: '纭畾',
+        cancelButtonText: '鍙栨秷',
+        type: 'warning'
+      }).then(() => {
+        const {name,oid} = this.checkItem;
+        const obj = {name,oid};
+        deleteIcon(obj).then(res => {
+          if (res.data.code === 200) {
+            this.$message.success(res.data.msg);
+            this.initList(true);
+          }
+        })
+      }).catch(() => {
+        this.$message({
+          type: 'info',
+          message: '宸插彇娑堝垹闄�'
+        });
+      });
     }
   }
 }
 </script>
 
-<style scoped>
+<style scoped lang="scss">
+::v-deep{
+  svg{
+    font-size: inherit;
+    height: 100%;
+    width:100%;
+  }
+}
 .tag-group{font-size: 14px;}
 .el-tag{
   margin: 0 0 10px 10px;
   cursor: pointer;
 }
+.iconList{
+  display: flex;
+  justify-content: flex-start;
+  flex-wrap: wrap;
+}
+.iconList .iconItem{
+  width: 85px;
+  margin: 6px 5px 10px 5px;
+  text-align: center;
+}
+.iconList .iconItem .svgContent{
+  font-size: 24px;
+  width: 24px;
+  height: 24px;
+  margin: 0 auto;
+}
+.iconList .iconItem .svgContent:hover{
+  transform: scale(1.5);
+}
+.iconList .iconItem span{
+  font-size: 12px;
+}
+.iconList__menu{
+  width: 150px;
+  position: fixed;
+  z-index: 1024;
+  flex-wrap: wrap;
+  background-color: #fff;
+}
+.iconList__item {
+  height: 34px;
+  line-height: 34px;
+  outline: 0;
+  padding: 0 10px;
+  white-space: nowrap;
+  text-overflow: ellipsis;
+  width: 100%;
+  color: #666;
+}
+.iconList__item:hover {
+  cursor: pointer;
+  color: #409eff
+}
 </style>

--
Gitblit v1.9.3