wangting
2024-12-20 c47e02ce2df67fe5426bf186add45d141ddfbc00
Source/plt-web/plt-web-ui/src/views/modelingMenu/ui/Icons/index.vue
@@ -2,39 +2,382 @@
  <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">分类</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 }}
            </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 icon="el-icon-plus" type="primary" size="mini" @click="uploadHandler">添加</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 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="500px"
          @close="visibleCloseHandler"
        >
          <avue-form ref="form" :option="option" v-model="form" :upload-after="uploadAfter"> </avue-form>
        </el-dialog>
        <!-- 修改 -->
        <el-dialog
          v-dialogDrag
          title="修改图标"
          :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 {validatenull} from "@/util/validate";
import {getStore} from "@/util/store";
import store from "@/store";
import {getToken} from "@/util/auth";
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: [{
        label:'按钮',
        value:0
      },{
        label:'标签二',
        value:1
      },{
        label:'标签三',
        value:2
      }],
      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:this.types
        }, {
            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
      },
      editVisible:false,
      editOption:{
        labelWidth: 80,
        submitBtn:false,
        emptyBtn:false,
        column: [{
          label: 'name',
          prop: 'name',
          type: 'input',
          disabled:true,
          span: 24,
          rules: [{
            required: true,
            message: "请输入图标name",
            trigger: "blur"
          }]
        }, {
          label: "svg",
          prop: "content",
          type: "textarea",
          span: 24,
          rules: [{
            required: true,
            message: "请输入图标svg代码",
            trigger: "blur"
          }]
        }]
      },
      editForm:{
        oid:'',
        name:'',
        content:''
      },
      menuVisible:false,
      menuPosition: {
        top: 0,
        left: 0
      }
    }
  },
  computed: {
    uploadHeaders() {
      return {
        "Authorizationtoken":getToken(),
      };
    },
  },
  watch:{
    'form.groups'(val){
      this.option.column[1].data={
        type:'svg',
        groups:val
      }
    }
  },
  created() {
    this.initList();
    this.option.column[0].dicData=this.types;
  },
  methods:{
    changeType(type){
    initList(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;
          }
        })
        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 => {
          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>"
            }]
          }]
          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;
          }
        })
      }
    },
    changeType(type){debugger;
      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);
        this.iconList=this.allIconList.filter(item=> {
          return checkedTypes.indexOf(JSON.stringify(item.groups))!=-1;
        })
      }
      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;
        }
      });
    },
    editHandler(){
      this.editForm=this.checkItem;
      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);
            }
          })
        } else {
          return false;
        }
      });
    },
    closeHandler(){
      this.editForm={
        oid:'',
        name:'',
        content:''
      }
      this.editVisible=false;
    },
    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: '已取消删除'
        });
      });
    }
  }
}
@@ -46,4 +389,41 @@
  margin: 0 0 10px 10px;
  cursor: pointer;
}
.iconList{
  display: flex;
  justify-content: flex-start;
  flex-wrap: wrap;
}
.iconList .iconItem{
  width: 35px;
  margin: 6px 12px;
  text-align: center;
}
.iconList .iconItem div: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>