封装qms三级物料多选组件

qms项目中的物料数据有很多,若是直接通过select下拉展示,首先是数据太多,会卡住,然后展示的内容也不全,目前物料有三个层级,分别一级物料、二级物料、三级物料,若是多加几个筛选条件,那最后获取到的数据就不是很多,然后就想到重新写个组件展示,
实现效果:
目前有两个框,一个展示选中的物料类别,一个是选中的物料名称,希望通过,点击一级物料列表项,获取到二级物料列表,点击二级物料列表项,获取三级物料列表,点击三级物料列表项,获取到物料清单,点击待选择物料列表项,选中物料列表新增一个物料,可以多选,点击选中的物料列表项,物料列表删除该物料,同时取消该物料的选中状态;若是点击一级物料列表项,则重新获取二级物料列表,同时把三级物料列表、待选择物料列表、已选择物料列表清空;点击二级物料列表时,则重新获取三级物料列表,同时把待选择物料列表、已选择物料列表清空;点击三级物料列表时,则重新获取待选择物料列表,同时把已选择物料列表清空;
在这里插入图片描述
在这里插入图片描述

20240126_190247

代码如下

materialType.vue

<template>
  <div>
    <div @click="inputClick()" style="cursor: pointer;">
      <!--通过css样式 pointer-events:none; 控制设为disabled的input可以点击 -->
      <a-input v-model:value="selectName"  disabled style="pointer-events:none;width:100%;" placeholder="请选择" ref="searchInput" autocomplete="off">%
      </a-input>
    </div>
    <a-modal v-model:visible="visible" @ok="handleOk" @cancel="handleCancel" width="850px" height="400px">
      <template #title>
        <div style="font-weight: 600; font-size: 16px">物料</div>
      </template>
      <div class="warp flex_between">
        <div class="flex_7">
          <div class="line30">未选择</div>
          <div class="flex_between">
            <div class="borderRight borderBottom table_title table_width150">一级物料</div>
            <div class="borderRight borderBottom table_title table_width150">二级物料</div>
            <div class="borderRight borderBottom table_title table_width150">三级物料</div>
            <div class="borderBottom table_title table_width200">物料名称</div>
          </div>
          <div class="flex_between">
            <div class="borderRight max_height table_width150">
              <div v-for="(item,index) in firstData" :key="index" :title="item.label" @click="firstClick(item)" :class="{'list_style':item.value!=firstTier,'list_active':item.value==firstTier}">{{item.label}}</div>
            </div>
            <div class="borderRight max_height table_width150">
              <div v-for="(item,index) in secondData" :key="index" :title="item.label" @click="secondClick(item)" :class="{'list_style':item.value!=secondTier,'list_active':item.value==secondTier}">{{item.label}}</div>
            </div>
            <div class="borderRight max_height table_width150">
              <div v-for="(item,index) in thirdData" :key="index" :title="item.label" @click="thirdClick(item)" :class="{'list_style':item.value!=thirdTier,'list_active':item.value==thirdTier}">{{item.label}}</div>
            </div>
            <div class="max_height table_width200">
              <div v-for="(item,index) in waitData" :key="index" :title="item.label" @click="waitClick(item)" :class="{'list_style':selectedMaterialName.includes(item.value),'list_active':selectedMaterialName.includes(item.value)}">{{item.label}}</div>
            </div>
          </div>
        </div>
        <div class="flex_3" >
          <div class="line30">选中</div>
          <div class="borderBottom table_title">物料名称</div>
          <div style="height:calc(100% - 30px);">
            <div style="width:100%;height:100%;" class="max_height">
              <div v-for="(item,index) in selectedData" :title="item.label" :key="index" @click="selectedClick(item)" class="list_style">{{item.label}}</div>
            </div>
          </div>
        </div>
      </div>
    </a-modal>
  </div>
</template>
<script setup>
import {onMounted, ref,defineEmits,defineProps, onBeforeUnmount, watch, nextTick} from 'vue';
import {defHttp } from '/@/utils/http/axios';
import { useMessage } from '/@/hooks/web/useMessage';
import qs from 'qs'
const { createMessage } = useMessage();
const visible = ref(false);
const emits = defineEmits(['check']);
const props = defineProps({
  //选中的物料级别
  checkLevel: {
    type: Object,
    default:{},
  }, //字段
  //选中的物料
  checkedMaterial: {
    type: Array,
    default:[],
  }, //字段
});

const selectedMaterialName=ref([]);//选中的物料名称数组,进行选中状态判断

const selectName=ref('');//选中返回值
const levels=[];//接收传过来的物料级别
levels.value=props.checkLevel;

const materials=[];//接收传过来的物料编号
materials.value=props.checkedMaterial;

const firstTier=ref('');//选中的第一列物料code
const firstTierName=ref('');//选中的第一列物料名称
const secondTier=ref('');//选中的第二列物料code
const secondTierName=ref('');//选中的第二列物料名称
const thirdTier=ref('');//选中的第三列物料code
const thirdTierName=ref('');//选中的第三列物料名称

//第一级物料列表
const firstData=ref([]);
//第二级物料列表
const secondData=ref([]);
//第三级物料列表
const thirdData=ref([]);

//待选择物料清单列表
const waitData=ref([]);

//选中的物料清单列表
const selectedData=ref([]);

onMounted(() => {
  // console.log(levels.value,'物料级别回显值');
  // console.log(materials.value,'选中物料回显值');

  //一级物料级别、二级物料级别、三级物料级别同时存在才会回显数据
  if(levels.value.firstTier&&levels.value.secondTier&&levels.value.thirdTier){
    firstTier.value=levels.value.firstTier;
    secondTier.value=levels.value.secondTier;
    thirdTier.value=levels.value.thirdTier;
    getFirstList();
    getOtherList(2,levels.value.firstTier);
    getOtherList(3,levels.value.secondTier);
    getMaterialList();
  }else{
    //传过来的数据为空时,则只显示一级物料
    getFirstList();
  }
});
//获取一级物料列表
async function getFirstList(){
  let url = '/materiel/tierLlist/'+1;
  await defHttp.get({ url}, { isTransformResponse: false }).then((res) => {
    if (res.success) {
      firstData.value=res.result;
      //对一级物料列表进行遍历,根据传过来的物料编号,查找对应的物料名称
      for(let i=0;i<firstData.value.length;i++){
        if(firstTier.value==firstData.value[i].value){
          firstTierName.value=firstData.value[i].label
        }
      }

    } else {
      createMessage.error(res.message);
    }
  });
}
//获取其他级别的物料列表
async function getOtherList(level,code){
  let url = '/materiel/tierLlist/'+level;
  let params={
    code:code,
  }
  await defHttp.get({ url,params}, { isTransformResponse: false }).then((res) => {
    if (res.success) {
      if(level==2){
        secondData.value=res.result;
        //对二级物料列表进行遍历,根据传过来的物料编号,查找对应的物料名称
        for(let i=0;i<secondData.value.length;i++){
          if(secondTier.value==secondData.value[i].value){
            secondTierName.value=secondData.value[i].label
          }
        }
      }else if(level==3){
        thirdData.value=res.result;
        //对三级物料列表进行遍历,根据传过来的物料编号,查找对应的物料名称
        for(let i=0;i<thirdData.value.length;i++){
          if(thirdTier.value==thirdData.value[i].value){
            thirdTierName.value=thirdData.value[i].label
          }
        }
      }
      //将一级物料名称、二级物料名称、三级物料名称进行组合,如 一级物料名称/二级物料名称/三级物料名称
      selectName.value=firstTierName.value+'/'+secondTierName.value+'/'+thirdTierName.value;
    } else {
      createMessage.error(res.message);
    }
  });
}

//获取待选中物料
async function getMaterialList(){
  let url = '/materiel/tierLlist/';
  let params={
    firstTier:firstTier.value,
    secondTier:secondTier.value,
    thirdTier:thirdTier.value,
  }
  await defHttp.get({ url,params}, { isTransformResponse: false }).then((res) => {
    if (res.success) {
      waitData.value=res.result;
      //若是传过来的物料编号数组存在,与查到的待选择物料列表进行遍历,获取选中的物料列表,
      if(materials.value){
        for(let i=0;i<waitData.value.length;i++){
          for(let j=0;j<materials.value.length;j++){
            if(materials.value[j]==waitData.value[i].value){
              selectedData.value.push(waitData.value[i])
            }
          }
        }
        // 对获取到的选中物料列表进行遍历,获取选中物料编号列表,用于待选则物料的选中状态判断
        selectedMaterialName.value=selectedData.value.map(item=>{
          return item.value
        })
        let levels={
          firstTier:{value:firstTier.value,label:firstTierName.value},
          secondTier:{value:secondTier.value,label:secondTierName.value},
          thirdTier:{value:thirdTier.value,label:thirdTierName.value},
        }
        console.log(selectedData.value,'selectedData')
        emits('check', selectedData.value,levels); //把选中的物料列表、选中的物料级别传过去
      }
    } else {
      createMessage.error(res.message);
    }
  });
}

//一级物料点击事件
function firstClick(val){
  //一级物料级别存在时,点击一级物料列表项,把二级物料列表、三级物料列表、待选择物料列表、已选择物料列表清空
  if(firstTier.value!=val.value){
    secondData.value=[];
    thirdData.value=[];
    waitData.value=[];
    selectedData.value=[];
    firstTier.value=val.value;//获取此时点击的一级物料名称、一级物料编号
    firstTierName.value=val.label;
    getOtherList(2,val.value);//重新获取此时点击的一级物料编号对应的二级物料列表
  }
}
//二级物料点击事件
function secondClick(val){
  //二级物料级别存在时,点击二级物料列表项,把三级物料列表、待选择物料列表、已选择物料列表清空
  if(secondTier.value!=val.value){
    thirdData.value=[];
    waitData.value=[];
    selectedData.value=[];
    secondTier.value=val.value;//获取此时点击的二级物料名称、二级物料编号
    secondTierName.value=val.label;
    getOtherList(3,val.value)//重新获取此时点击的二级物料编号对应的三级物料列表
  }
}
//三级物料点击事件
function thirdClick(val){
  //三级物料级别存在时,点击三级物料列表项,把待选择物料列表、已选择物料列表清空
  if(thirdTier.value!=val.value){
    selectedData.value=[];
    thirdTier.value=val.value;//获取此时点击的三级物料名称、三级物料编号
    thirdTierName.value=val.label;
    getMaterialList();//重新获取此时点击的一级二级三级物料编号对应的物料清单列表
  }
}

//物料点击
function waitClick(val){
  //对此时点击的待选择物料列表项进行判断,若是不存在已选中物料列表里面,则添加到已选中物料列表中,同时更新已选中物料编号数组
  if(selectedMaterialName.value.includes(val.value)==false){
    waitData.value.map(item=>{
      if(item.value==val.value){
        selectedData.value.push(item);
      }
    })
    selectedMaterialName.value=selectedData.value.map(item=>{
      return item.value
    })
  }else{
  //对此时点击的待选择物料列表项进行判断,若是存在已选中物料列表里面,则遍历查到点击的物料编号在已选中物料列表中的索引,进行删除,同时更新已选中物料编号数组
    selectedData.value.map((item,index)=>{
      if(item.value==val.value){
        selectedData.value.splice(index,1);
      }
    })
    selectedMaterialName.value=selectedData.value.map(item=>{
      return item.value
    })
  }
}
//已选中物料点击
function selectedClick(val){
  //点击已选中物料列表项,遍历查到点击的物料编号在已选中物料列表中的索引,进行删除,同时更新已选中物料编号数组
  selectedData.value.map((item,i)=>{
    if(item.value==val.value){
      selectedData.value.splice(i,1)
    }
  })
  selectedMaterialName.value=selectedData.value.map(item=>{
    return item.value
  })
}
//点击显示弹窗
function inputClick(){
  visible.value=true;
}

const handleCancel = (e) => {
  visible.value = false;
}

const handleOk = (e) => {
  // 点击确定时,把此时选中的物料列表、一级、二级、三级物料传过去
  if(selectedData.value.length>0){
    visible.value = false;
    selectName.value=firstTierName.value+'/'+secondTierName.value+'/'+thirdTierName.value;//返回物料类别
    let levels={
      firstTier:{value:firstTier.value,label:firstTierName.value},
      secondTier:{value:secondTier.value,label:secondTierName.value},
      thirdTier:{value:thirdTier.value,label:thirdTierName.value},
    }
    emits('check', selectedData.value,levels); //把列表选中的值传过去
  }else{
    createMessage.warning('至少选中一个物料~');
  }
};


</script>
<style lang="less" scoped>
.flex_between{
  display:flex;
  justify-content:center;
  text-align: center;
}
.warp{
  margin:10px;
  border:1px solid #ddd;
  height:auto;
  border-top:none;
  border-left:none;
  box-sizing: border-box;
  .flex_7{
    // flex:7;
    width:650px;
    border:1px solid #ddd;
    height:100%;
    border-bottom:none;
  }
  .line30{
    border-bottom:1px solid #ddd;
    height:30px;
    line-height:30px;
  }
  .borderRight{
    border-right:1px solid #ddd;
    width:100%;
  }
  .table_title{
    font-size: 16px;
    color: #333;
  }
  .borderBottom{
    width:100%;
    border-bottom:1px solid #ddd;
  }
  .max_height{
    max-height: 500px;
    overflow-y: scroll;
  }
  .table_width200{
    width:200px;
  }
  .table_width150{
    width:150px;
  }
  .flex_3{
    // flex:3;
    width:200px;
    border-top:1px solid #ddd;
    height:100%;
  }
}
.list_style{
  cursor: pointer;
}
.list_active{
  color: rgb(24, 144, 255);
}
.list_style:hover{
  color: #409eff;
}
</style>

引用组件

<template>
 
    <a-card :bordered="false">
      <a-tabs defaultActiveKey="4">
        <a-tab-pane tab="物料名称组件" key="4">
          <a-form :label-col="{style:{width:'150px'} }">
            <a-row :gutter="24">
              <a-col :span="8">
                <a-form-item label="供货工艺类别:">
                  <material-type :checkedMaterial='selectedMaterial' :checkLevel='levels' @check='getMaterialLevel'></material-type>
                </a-form-item>
              </a-col>
              <a-col :span="24">
                <a-form-item label="供货产品名称:">
                  <a-input v-model:value="selectedMaterialNames" disabled></a-input>
                </a-form-item>
              </a-col>
            </a-row>
          </a-form>
        </a-tab-pane>
      </a-tabs>
    </a-card>
</template>

<script setup>
import {onMounted, ref,defineEmits,defineProps, onBeforeUnmount, watch, nextTick} from 'vue';
import materialType from '/@/components/materialType.vue';

onMounted(()=>{
  getMaterialLevel();
})

//物料选择调用
const levels=ref(
  {
    firstTier:'A',
    secondTier:'A.2',
    thirdTier:'A.2.1',
  }
)

const selectedMaterial=ref(
  [
    '02.10.MSP120H-11-01',
    '02.10.MSP120H-30-01',
  ]
)

const selectedMaterialNames=ref('');//选中的产品名称
const checkedMaterial=ref([]);//回显的数据
let materielData=[];
function getMaterialLevel(materials,levels){
  if(materials){
    materielData=materials.map(item=>{
      return item.label
    });
    selectedMaterialNames.value=materielData.toString();
  }
  // console.log(selectedMaterialNames.value,'选中物料名称')
}
//物料选择调用
</script>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/350263.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Mysql 学习(十 四)事务简介

为什么要有事务&#xff1f; 数据库的出现其实是有应用场景的&#xff0c;最好的例子就是交易&#xff0c;以前的交易是通过账本记录的&#xff0c;也就是通过纸和笔来记录&#xff0c;而数据库的出现大大提升了效率&#xff0c;但是现实中的有些问题&#xff0c;数据库也需要…

基于Grafana+Prometheus搭建可视化监控系统实践

基本介绍 Grafana&#xff1a;一个监控仪表系统&#xff0c;可以根据提供的监控数据&#xff0c;生产可视化仪表盘&#xff0c;同时也具有告警通知功能。这里的监控数据来源&#xff0c;目前主要以Prometheus为主&#xff08;也支持其它数据源&#xff09;&#xff0c;每次展现…

1.26 day3 C++

设计一个Per类&#xff0c;类中包含私有成员:姓名、年龄、指针成员身高、体重&#xff0c;再设计一个Stu类&#xff0c;类中包含私有成员:成绩、Per类对象p1&#xff0c;设计这两个类的构造函数、析构函数和拷贝构造函数。 #include <iostream>using namespace std; cla…

CS奇技淫巧之1.1.1.1上线

编者注&#xff1a;本文仅供学习研究&#xff0c;严禁从事非法活动。 前期准备 一个干净的域名 一台VPS 一个CloudFlare账号 CloudFlare配置 Cloudflare 是一家国外的 CDN 加速服务商&#xff0c;提供免费和付费的加速和网站保护服务&#xff0c;百度云加速的国外节点就是和 …

力扣面试题 16.06. 最小差

Problem: 面试题 16.06. 最小差 文章目录 题目描述思路即解法复杂度Code 题目描述 思路即解法 注意本题目的数据范围!!! 1.对数组a与数组b进行排序;获取a与b的数组长度aLen,bLen&#xff0c;定义一个long类型的变量min&#xff1b; 2.分别让两个指针i&#xff0c;j指向数组的开…

ROS 计算图级 小结

ROS 会创建一个连接到所有进程的网络。在系统中的任何节点都可以访问此网络&#xff0c;并通过该网络与其他节点交互&#xff0c;获取其他节点发布的信息&#xff0c;并将自身数据发布到网络上。 在这一层级中最基本的概念包括节点、节点管理器、参数服务器、消息、服务、主题和…

鸿蒙开发会是前端程序员的下一个春天吗?

前言 最近前端的大环境不太行&#xff0c;之前身处在前端的自己薪资也越来越无望了&#xff0c;隐隐约约感觉前端做不下去了&#xff0c;2024前端找不到工作要转行吗&#xff1f; 看新闻的过程中&#xff0c;**发现越来越多的巨头公司融入鸿蒙生态建设&#xff0c;鸿蒙“朋友…

Flink Checkpoint 超时问题和解决办法

第一种、计算量大&#xff0c;CPU密集性&#xff0c;导致TM内线程一直在processElement&#xff0c;而没有时间做CP【过滤掉部分数据&#xff1b;增大并行度】 代表性作业为算法指标-用户偏好的计算&#xff0c;需要对用户在商城的曝光、点击、订单、出价、上下滑等所有事件进…

Soul App深化社交元宇宙生态治理,与用户共建清朗网络家园

近日,新型开放式社交平台Soul App发布了《2023年第二季度Soul生态安全报告》,展现了其在深化社交元宇宙生态治理方面的创新成果。报告显示,第二季度,Soul围绕反诈、引导社交礼仪规范、未成年保护、用户共治众裁、防治网暴骚扰等方面开展用户安全生态专项治理,通过一系列创新举措…

MATLAB字符串编辑常用代码

1.字符串赋值 % 字符串赋值 sabcdefg 2.字符串属性和操作 (1)获取字符串长度 sabcdefg;% 字符串赋值 length(a) % 获取字符串长度 (2)连接字符串 % 连接两个字符串,每个字符串最右边的空格被裁切 s1a s2b s3strcat(s1,s2) 3.字符串比较 % strcmp 比较两个字符串是…

Linux--基础开发工具篇(1)(yum)

1.Linux 软件包管理器 yum 1.1yum是什么&#xff1f;什么是软件包&#xff1f; yum是什么&#xff1f; yum是一个软件下载安装管理的一个客户端&#xff0c;就如小米应用商店&#xff0c;华为应用商城。 Linux中软件包可能有依赖关系--yum会帮助我们解决依赖关系的问题。 什么是…

acrobat调整pdf的页码和实际页码保持一致

Acrobat版本 具体操作 现在拿到pdf的结构如下&#xff1a; pdf页码实际页码1-10页无页码数11页第1页 操作&#xff0c;选择pdf第10页&#xff0c;右键点击 具体设置 最终效果

MySQL 多表查询

文章目录 多表关系一对多多对多一对一 查询合并查询&#xff08;笛卡尔积&#xff0c;会展示所有组合结果&#xff09;&#xff1a;内连接查询外连接查询自连接查询联合查询 union, union all子查询单行子查询列子查询行子查询表子查询 :::success 多表查询&#xff0c;也称为…

Linux/Academy

Enumeration nmap 首先扫描目标端口对外开放情况 nmap -p- 10.10.10.215 -T4 发现对外开放了22,80,33060三个端口&#xff0c;端口详细信息如下 结果显示80端口运行着http&#xff0c;且给出了域名academy.htb&#xff0c;现将ip与域名写到/et/hosts中&#xff0c;然后从ht…

负载均衡-Ribbon-自定义负载均衡算法

1.Ribbon 是什么 SpringCloud Ribbon 是基于 Netflix Ribbon 实现的一套客户端负载均衡的工具主要功能是提供客户端的软件负载均衡算法&#xff0c;将 Netflix 的中间服务处连接在一起Ribbon的客户端组件提供一系列完整的配置项&#xff0c;如&#xff1a;连接超时、重试等。简…

TCP通信流程以及套接字函数

TCP和UDP的特点&#xff1a; 对于单播&#xff0c;多播&#xff0c;广播的解释&#xff1a; 单播&#xff1a; 一对一通信&#xff0c;目标地址唯一。多播&#xff1a; 一对多通信&#xff0c;目标地址是一个特定的组。广播&#xff1a; 一对全部通信&#xff0c;目标地址是整…

vue3之 websoket发送消息

1.封装websoket var ws null; //建立的连接 var lockReconnect false;//是否真正建立连接 var timeout 6 * 1000 * 5;//30秒一次心跳 var timeoutObj null;//心跳心跳倒计时 var serverTimeoutObj null;//心跳倒计时 var timeoutnum null;//断开 重连倒计时 var global_…

win10安装redis并配置加自启动(采用官方推荐unix子系统)

记录&#xff0c;为啥有msi安装包&#xff0c;还这么麻烦的用linux版本redis的安装方式&#xff0c;是因为从github上下载别人制作的msi报毒&#xff0c;还不止一处&#xff0c;这种链接数据库的东西&#xff0c;用别人加工过的&#xff0c;都报毒了还用就是傻逼了。 所以采用…

Linux---文件系统

在基础IO中&#xff0c;我们所讲的都是对被打开文件的管理&#xff0c;但是不是所有的文件都是被打开的&#xff0c;对那些在磁盘中保存的没有被打开的文件&#xff0c;我们同样也需要管理&#xff0c;这个就像是快递站中等待被人取走的快递&#xff0c;我们需要将它们分门别类…

赋值运算符

注意点&#xff1a;复合赋值运算符&#xff0c;会进行强制类型转换&#xff0c;不会报错 byte b 2; b 3; b; b 2; b为byte类型 b 3; 等价于b b 3;而b3的结果为int类型&#xff1b; 但在此过程中存在强制类型转换&#xff0c;b(byte)(b3);因而不会报错