wangting
2024-12-24 8e93a889280064483b901959e3b42f966d0ad371
图标管理,图标选择组件,图标显示组件
已修改5个文件
已添加1个文件
368 ■■■■ 文件已修改
Source/plt-web/plt-web-ui/src/components/PLT-basic-component/iconShow.vue 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/plt-web/plt-web-ui/src/components/PLT-basic-component/input-icon.vue 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/plt-web/plt-web-ui/src/main.js 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/plt-web/plt-web-ui/src/views/modelingMenu/modeling/businessType/index.vue 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/plt-web/plt-web-ui/src/views/modelingMenu/modeling/statusPool/index.vue 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/plt-web/plt-web-ui/src/views/modelingMenu/ui/Icons/index.vue 236 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/plt-web/plt-web-ui/src/components/PLT-basic-component/iconShow.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,41 @@
<template>
   <div :style="'width:'+fontSize+';height:'+fontSize+';font-size: '+fontSize+';'+style" v-html="svgHtml"></div>
</template>
<script>
import func from "@/util/func";
export default {
name: "iconShow",
  props: {
    name: {
      type: String,
      default: ''
    },
    fontSize: {
      type: String,
      default:'20px'
    },
    style:{
      type: String,
      default:''
    }
  },
  computed:{
    svgHtml() {
      return func.getSVGByName(this.name);
    },
  },
  methods:{
  }
}
</script>
<style lang="scss" scoped>
::v-deep {
  svg{
    font-size: inherit;
    height: 100%;
    width:auto;
  }
}
</style>
Source/plt-web/plt-web-ui/src/components/PLT-basic-component/input-icon.vue
@@ -2,7 +2,7 @@
  <div>
    <el-input :width="width" :class="inputClass" :style="inputStyle" :clearable="true" :value="value"
              :disabled="disabled" :placeholder="placeholder" type="text" :size="size" @clear="clearValue" @focus="handleFocus">
      <span slot="append" v-html="svgHtml"></span>
      <span slot="append" v-html="svgHtml" style="font-size: 18px;height:18px;display: block"></span>
    </el-input>
    <el-dialog v-dialogDrag
               v-dialog-resize
@@ -17,10 +17,10 @@
          <span class="tag-group__title">分类</span>
          <el-tag
            v-for="item in types"
            :key="item.value"
            :type="checkedTypes.includes(item.value)?'success':'info'" size="small"
            effect="plain" @click="changeType(item.value)">
            {{ item.label }}
            :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>
@@ -30,8 +30,8 @@
          <el-tab-pane v-for="item in iconList" :label="item.lable" :name="item.lable" style="height: calc(60vh - 80px);;overflow: auto ">
            <div class="iconList">
              <div class="iconItem" v-for="svg in item.list" :data-value="svg.name" @click="checkSvg(svg,item.lable)">
                <div v-html="svg.content"></div>
                <!--<span>{{svg.name.split(':')[1]}}</span>-->
                <div class="svgContent" v-html="svg.content"></div>
                <span>{{svg.name.split(':')[1]}}</span>
              </div>
            </div>
          </el-tab-pane>
@@ -47,6 +47,7 @@
import func from "@/util/func";
import store from "@/store";
import {getIcons} from "@/api/UI/Icons";
import {getDicts} from "@/api/system/dict";
export default {
  name: "input-icon",
@@ -79,16 +80,7 @@
  data(){
    return {
      visible: false,
      types: [{
        label:'按钮',
        value:0
      },{
        label:'标签二',
        value:1
      },{
        label:'标签三',
        value:2
      }],
      types: [],
      checkedTypes:[],
      searchText:'',
      activeName:'',
@@ -105,6 +97,7 @@
    }
  },
  created(){
    this.getGroups();
    if (!validatenull(this.$store.state.icons)) {
      this.iconList = this.$store.state.icons;
    } else {
@@ -115,16 +108,31 @@
      this.activeName=this.iconList[0].lable;
    }else {
      getIcons().then(res => {
        this.iconList=res.data.data;
        this.allIconList=this.iconList;
        store.dispatch("setIcons", this.iconList);
        if(this.iconList&&this.iconList.length>0) {
          this.activeName=this.iconList[0].lable;
        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);
        }
      })
    }
    this.svgHtml=func.getSVGByName(this.value);
  },
  methods:{
    getGroups() {
      getDicts('EnumIconGroups').then(res => {
        if (res.data.success) {
          this.types = res.data.obj;
        } else {
          this.$message.error(res.data.msg);
        }
      })
    },
    dialogClose() {
      this.visible = false;
    },
@@ -148,9 +156,16 @@
        this.iconList=this.allIconList
      }else{
        const checkedTypes=JSON.stringify(this.checkedTypes);
        this.iconList=this.allIconList.filter(item=> {
          return checkedTypes.indexOf(JSON.stringify(item.groups))!=-1;
        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;
    },
@@ -197,11 +212,14 @@
  flex-wrap: wrap;
}
.iconList .iconItem{
  width: 65px;
  margin: 6px;
  width: 85px;
  margin: 6px 5px 10px 5px;
  text-align: center;
}
.iconList .iconItem div:hover{
.iconList .iconItem .svgContent{
  font-size: 24px;
}
.iconList .iconItem .svgContent:hover{
  transform: scale(1.5);
}
.iconList .iconItem span{
Source/plt-web/plt-web-ui/src/main.js
@@ -46,6 +46,8 @@
import transfer from "@/components/PLT-basic-component/transfer";
//图标选择器组件
import inputIcon from "@/components/PLT-basic-component/input-icon";
//图标显示组件
import iconShow from "@/components/PLT-basic-component/iconShow";
// æ³¨å†Œå…¨å±€å®¹å™¨
Vue.component('basicContainer', basicContainer);
Vue.component('basicBlock', basicBlock);
@@ -63,6 +65,7 @@
Vue.component('Divider', Divider);
Vue.component('transfer', transfer);
Vue.component('inputIcon', inputIcon);
Vue.component('iconShow', iconShow);
import ECharts from 'vue-echarts'
Vue.component('v-chart', ECharts)
Source/plt-web/plt-web-ui/src/views/modelingMenu/modeling/businessType/index.vue
@@ -55,8 +55,8 @@
                <template slot="label">
                  å›¾æ ‡
                </template>
                <span class="avue-icon avue-icon--small" style="display: block">
                  <span v-html="svgHtml(nodeRow.imageName )"></span>
                <span class="avue-icon">
                  <icon-show :name="nodeRow.imageName"></icon-show>
                </span>
              </el-descriptions-item>
              <el-descriptions-item :span="12" :contentStyle="descriptionOption.contentStyle"
@@ -829,9 +829,6 @@
    }
  },
  methods: {
    svgHtml(svgName){
      return func.getSVGByName(svgName);
    },
    //树表查询
    getTreeList() {
      this.treeLoading = true;
Source/plt-web/plt-web-ui/src/views/modelingMenu/modeling/statusPool/index.vue
@@ -33,7 +33,9 @@
      </template>
      <template #icon="{ row }">
        <span v-html="svgHtml(row.imagePath )"></span>
        <span class="avue-icon">
          <icon-show :name="row.imagePath"></icon-show>
        </span>
      </template>
    </avue-crud>
@@ -108,14 +110,12 @@
import {gridStatus, addSave, editSave, deleteStatus, exportStatus, listUsed} from "@/api/modeling/statusPool/api";
import func from "@/util/func";
import basicOption from "@/util/basic-option";
import iconList from "@/config/iconList";
import {mapGetters} from "vuex";
export default {
  name: "index",
  data() {
    return {
      iconList: iconList,
      loading: false,
      data: [],
      option: {
@@ -219,9 +219,6 @@
    this.getList();
  },
  methods: {
    svgHtml(svgName){
      return func.getSVGByName(svgName);
    },
    getList() {
      gridStatus(this.page.currentPage, this.page.pageSize).then(res => {
        const data = res.data.data;
Source/plt-web/plt-web-ui/src/views/modelingMenu/ui/Icons/index.vue
@@ -4,20 +4,21 @@
      <basic-container>
        <div style="display: flex;justify-content: space-between;flex-wrap: wrap">
          <div class="tag-group">
            <span class="tag-group__title">分类</span>
            <span class="tag-group__title">分组</span>
            <el-tag
              v-for="item in types"
              :key="item.value"
              :type="checkedTypes.includes(item.value)?'success':'info'" size="small"
              effect="plain" @click="changeType(item.value)">
              {{ item.label }}
              :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 style="height: calc(100vh - 190px)">
          <div>
            <el-button icon="el-icon-plus" type="primary" size="mini" @click="uploadHandler">添加</el-button>
            <el-button icon="el-icon-plus" type="primary" size="mini" @click="addHandler">添加</el-button>
            <el-button icon="el-icon-upload" type="primary" size="mini" @click="uploadHandler">上传</el-button>
          </div>
          <el-tabs v-model="activeName" @tab-click="handleClick">
@@ -25,8 +26,8 @@
              <div class="iconList">
                <div class="iconItem" v-for="svg in item.list"
                     :data-value="svg.name" v-right-click="{action:checkSvg,data:svg}">
                  <div v-html="svg.content"></div>
                  <!--<span>{{svg.name.split(':')[1]}}</span>-->
                  <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">
@@ -39,19 +40,31 @@
        <!-- ä¸Šä¼  -->
        <el-dialog
          v-dialogDrag
          title="添加图标"
          title="上传图标"
          :visible.sync="visible"
          append-to-body="true"
          class="avue-dialog"
          width="500px"
          width="600px"
          @close="visibleCloseHandler"
        >
          <avue-form ref="form" :option="option" v-model="form" :upload-after="uploadAfter"> </avue-form>
          <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: #b3b3b3;margin-top: 0;padding:5px;background-color: #f5f5f5">上传文件为json文件,示例如下
[
  {
    "name": "iconoir:accessibility",
    "svg": "<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>"
  },
  {
    "name": "iconoir:accessibility-sign",
    "svg": "<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=\"m11.5 12.5l7-.5l-1.5 6.5m-5.5-6l4.5-5L12.5 5L10 7.5m8.5-1a2 2 0 1 1 0-4a2 2 0 0 1 0 4\"/><path d=\"M5.5 12.5a5 5 0 0 1 7.584 6M3.729 15A5 5 0 0 0 11 20.831\"/></g></svg>"
  }
 ]
 æ–‡ä»¶å†…容须严格按照示例格式,name为图标库名+图标名称,以“:”分隔,svg为图标html代码</pre>
        </el-dialog>
        <!-- ä¿®æ”¹ -->
        <!-- æ·»åŠ ã€ä¿®æ”¹ -->
        <el-dialog
          v-dialogDrag
          title="修改图标"
          :title="editType=='add'?'添加图标':'修改图标'"
          :visible.sync="editVisible"
          append-to-body="true"
          class="avue-dialog"
@@ -71,6 +84,7 @@
<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";
@@ -91,16 +105,7 @@
  },
  data() {
    return {
      types: [{
        label:'按钮',
        value:0
      },{
        label:'标签二',
        value:1
      },{
        label:'标签三',
        value:2
      }],
      types: [],
      checkedTypes:[],
      searchText:'',
      activeName:'',
@@ -113,12 +118,16 @@
        submitBtn:false,
        emptyBtn:false,
        column: [{
          label: '分类',
          label: '分组',
          prop: 'groups',
          type: 'select',
          span: 24,
          multiple:true,
          dicData:this.types
          dicData:[],
          props:{
            label:'value',
            value:'key'
          }
        }, {
            label: "附件上传",
            prop: "file",
@@ -137,27 +146,51 @@
        groups:[],
        file:null
      },
      editType:'edit',
      editVisible:false,
      editOption:{
        labelWidth: 80,
        labelWidth: 90,
        submitBtn:false,
        emptyBtn:false,
        column: [{
          label: 'name',
          prop: 'name',
          label: '图标库名',
          prop: 'libname',
          type: 'input',
          disabled:true,
          span: 24,
          rules: [{
            required: true,
            message: "请输入图标name",
            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: "svg",
          label: "svg代码",
          prop: "content",
          type: "textarea",
          span: 24,
          placeholder:'请输入图标svg代码,格式示例<svg xmlns=\"http://www.w3.org/2000/svg\" ></svg>',
          rules: [{
            required: true,
            message: "请输入图标svg代码",
@@ -167,7 +200,8 @@
      },
      editForm:{
        oid:'',
        name:'',
        libname:'',
        iconname:'',
        content:''
      },
      menuVisible:false,
@@ -193,20 +227,35 @@
    }
  },
  created() {
    this.initList();
    this.option.column[0].dicData=this.types;
  },
    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){
      if(reload) {
        getIcons().then(res => {
          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;
          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)) {
@@ -219,25 +268,29 @@
        this.activeName=this.iconList[0].lable;
      }else {
        getIcons().then(res => {
          this.iconList = [{
            lable: 'iconoir',
            list: [{
              oid: '',
              groups: '0',
              "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>"
          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;
            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){debugger;
    changeType(type){
      if(this.checkedTypes.includes(type)){
        this.checkedTypes=this.checkedTypes.filter(item=> item!=type)
      }else {
@@ -248,9 +301,16 @@
        this.iconList=this.allIconList
      }else{
        const checkedTypes=JSON.stringify(this.checkedTypes);
        this.iconList=this.allIconList.filter(item=> {
          return checkedTypes.indexOf(JSON.stringify(item.groups))!=-1;
        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;
    },
@@ -327,24 +387,49 @@
        }
      });
    },
    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()
          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);
            }
          })
          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;
        }
@@ -352,11 +437,17 @@
    },
    closeHandler(){
      this.editForm={
        type:'svg',
        oid:'',
        name:'',
        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('您确定要删除该图标吗?', '提示', {
@@ -395,11 +486,14 @@
  flex-wrap: wrap;
}
.iconList .iconItem{
  width: 35px;
  margin: 6px 12px;
  width: 85px;
  margin: 6px 5px 10px 5px;
  text-align: center;
}
.iconList .iconItem div:hover{
.iconList .iconItem .svgContent{
  font-size: 26px;
}
.iconList .iconItem .svgContent:hover{
  transform: scale(1.5);
}
.iconList .iconItem span{