vue:使用【3.0】:条件模块

一、条件层级效果图

二、代码

<template>
  <ContentWrap>
    <!-- 添加条件分支:level1 -->
    <div class="btnBox" v-if="isEdit">
      <el-button type="primary" @click="add">添加条件分支</el-button>
    </div>

    <div v-if="tableList.length > 0" class="boxOne">
      <div class="title" v-for="(level1, index) in tableList" :key="level1.accountName">
        <!-- 返回科目:level2 -->
        <el-form-item :label="`${level1.accountName}`" label-width="80px">
          <el-select
            v-model="level1.conditionName"
            placeholder="请选择数据"
            :disabled="!isEdit"
            filterable
          >
            <el-option
              v-for="(item, index1) in titleList"
              :key="index1"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
          <el-button
            link
            :icon="Delete"
            @click="handleDelete(index)"
            type="danger"
            class="ml-10px"
            v-if="isEdit"
          />
          <el-button link :icon="Plus" @click="handleAdd(level1)" v-if="isEdit" />
        </el-form-item>

        <!-- 条件设置:level3 -->
        <div class="boxTwo" v-if="level1.children?.length > 0">
          <!-- 此处可不展示 style="display: none" -->
          <div class="left">
            <div class="round" @click="handleRelation(level1)">
              {{ level1.relation }}
            </div>
            <div class="border"></div>
          </div>
          <div class="right">
            <div
              class="level1Right"
              v-for="(level2, level2Index) in level1.children"
              :key="level2Index"
            >
              <!-- 符号:or/AND -->
              <div class="left" v-if="level2.children?.length > 0">
                <div class="round" @click="handleLevelRelation(level2)">
                  {{ level2.relation }}
                </div>
                <div class="border"></div>
              </div>
              <div class="levelRight" v-if="level2.children?.length > 0">
                <div
                  class="mb-20px"
                  v-for="(level3, level3Index) in level2.children"
                  :key="level3Index"
                >
                  <el-row :gutter="20">
                    <!-- 字典表 -->
                    <el-col :span="5">
                      <el-form-item>
                        <el-select
                          v-model="level3.pName"
                          placeholder="请选择数据"
                          :disabled="!isEdit"
                        >
                          <el-option
                            v-for="(operator, index1) in operatorList"
                            :key="index1"
                            :label="operator.label"
                            :value="operator.value"
                          />
                        </el-select>
                      </el-form-item>
                    </el-col>
                    <!-- 数值类型 -->
                    <el-col :span="5">
                      <el-form-item>
                        <el-select
                          v-model="level3.pType"
                          :placeholder="t('common.inputText')"
                          :disabled="!isEdit"
                        >
                          <el-option
                            v-for="(accountType, index1) in accountTypeList"
                            :key="index1"
                            :label="accountType.label"
                            :value="accountType.value"
                          />
                        </el-select>
                      </el-form-item>
                    </el-col>
                    <!-- 运算符,根据数值类型显示 -->
                    <el-col :span="5">
                      <el-form-item>
                        <el-select
                          v-model="level3.pOption"
                          placeholder="请选择数据"
                          :disabled="level3.pType === '' || !isEdit"
                        >
                          <el-option
                            v-for="(kind, index1) in typeMap[level3.pType]"
                            :key="index1"
                            :label="kind.label"
                            :value="kind.value"
                          />
                        </el-select>
                      </el-form-item>
                    </el-col>
                    <!-- 值 -->
                    <el-col :span="6">
                      <el-form-item>
                        <el-input
                          placeholder="请输入"
                          v-model="level3.pValue"
                          :disabled="!isEdit"
                        />
                        <!-- <el-date-picker
                          v-if="level3.pType === '3'"
                          v-model="level3.pValue"
                          clearable
                          :placeholder="t('common.selectText')"
                          type="date"
                          value-format="YYYY-MM-DD"
                          :disabled="!isEdit"
                        />
                        <el-input
                          v-else
                          placeholder="请输入"
                          v-model="level3.pValue"
                          :disabled="!isEdit"
                        /> -->
                      </el-form-item>
                    </el-col>
                    <!-- 操作 -->
                    <el-col :span="3">
                      <el-form-item>
                        <el-button
                          link
                          :icon="Delete"
                          @click="handleRowDelete(level2, level3Index)"
                          type="danger"
                          class="ml-10px"
                          v-if="isEdit"
                        />
                        <el-button
                          link
                          :icon="Plus"
                          @click="handleRowAdd(level2, index)"
                          v-if="isEdit"
                        />
                      </el-form-item>
                    </el-col>
                  </el-row>
                </div>
                <div>
                  <el-button
                    link
                    :icon="Delete"
                    @click="handleNodeDelete(level1, level2Index)"
                    type="danger"
                    class="ml-10px"
                    v-if="isEdit"
                  />
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </ContentWrap>
</template>
<script lang="ts" setup>
import { Delete, Plus } from '@element-plus/icons-vue'
import * as apiType from '@/api/system/dict/dict.data.ts'

defineOptions({ name: 'SettingTable' })
const { t } = useI18n() // 国际化
const message = useMessage() // 消息弹窗
const emits = defineEmits(['success'])
const titleList = [
  { label: 'lemon', value: 1 },
  { label: 'orange', value: 2 },
  { label: 'apple', value: 3 },
  { label: 'banana', value: 4 },
  { label: 'mango', value: 5 },
  { label: 'cherry', value: 6 }
]
const operatorList = [
  { label: 'doudou1', value: 1 },
  { label: 'doudou2', value: 2 },
  { label: 'doudou3', value: 3 },
  { label: 'doudou4', value: 4 },
  { label: 'doudou5', value: 5 },
  { label: 'doudou6', value: 6 }
]
const accountTypeList = [
  {
    value: 1,
    label: '数值'
  },
  {
    value: 2,
    label: '字符串'
  },
  {
    value: 3,
    label: '日期'
  }
]
// 条件配置(数据类型:数值)
const numberConfig = [
  {
    value: 1,
    label: '>'
  },
  {
    value: 2,
    label: '>='
  },
  {
    value: 3,
    label: '<= '
  },
  {
    value: 4,
    label: '<'
  },
  {
    value: 5,
    label: '='
  },
  {
    value: 6,
    label: '!='
  }
]

// 条件配置(数据类型:字符串)
const stringConfig = [
  {
    value: 7,
    label: 'equals'
  },
  {
    value: 8,
    label: 'contains'
  },
  {
    value: 9,
    label: 'startsWith'
  },
  {
    value: 10,
    label: 'endsWith'
  },
  {
    value: 11,
    label: 'equals'
  },
  {
    value: 12,
    label: 'before'
  },
  {
    value: 13,
    label: 'after'
  }
]

// 条件配置(数据类型:日期)
const dateConfig = [
  {
    value: 11,
    label: 'YYYY-MM-DD'
  },
  {
    value: 12,
    label: ' YYYY-MM-DD HH:mm:ss'
  },
  {
    value: 13,
    label: 'YYYY-MM'
  }
]

interface AccountItem {
  accountCode?: string
  accountName?: string
  label?: string
  value?: string
}

interface ConditionItem {
  conditionName?: string
  children?: childrenItems[]
  accountName?: string
  relation?: string
}

interface itemProps {
  pName: string
  pType: string
  pOption: string
  pValue: string
}

interface childrenItems {
  relation?: string
  children?: itemProps[]
}

const props = defineProps({
  accountList: {
    type: Array as () => AccountItem[],
    required: true
  },
  chooseList: {
    type: Array as () => ConditionItem[],
    default: () => []
  },
  isEdit: {
    type: Boolean,
    default: false
  }
})
const chooseList = computed(() => {
  return props.chooseList
})

const tableList = ref<ConditionItem[]>([])
// 运算符
const typeMap = {
  '1': numberConfig,
  '2': stringConfig,
  '3': dateConfig
}

/** 第一步:【level1】添加条件分支:新增 */
const add = () => {
  console.log('第一步:')
  // 1、判断上面一条数据是否填写
  const lastItem = tableList.value[tableList.value.length - 1]
  if (lastItem !== undefined) {
    if (lastItem?.conditionName === '') {
      message.error(`返回科目规则需配置完整`)
      return
    }
    const hasAllValues = checkValues(lastItem.children)
    if (!hasAllValues) {
      message.error('请填写完整条件')
      return
    }
  }

  // 2、添加数据
  const result: ConditionItem = {
    accountName: '返回科目',
    conditionName: '',
    relation: 'AND',
    children: []
  }
  tableList.value.push(result)
  console.log('添加条件分支', tableList.value)
  emits('success', tableList.value)
}
// 外层:条件
const handleRelation = (item) => {
  console.log('外层', item)
  if (!props.isEdit) return
  item.relation = item.relation === 'AND' ? 'OR' : 'AND'
  console.log('????', tableList.value)
  emits('success', tableList.value)
}

function checkValues(data) {
  for (const item of data) {
    if (item.pName === '' || item.pType === '' || item.pOption === '' || item.pValue === '') {
      return false
    }
    if (item.children && item.children.length > 0) {
      const hasAllFields = checkValues(item.children)
      if (!hasAllFields) {
        return false
      }
    }
  }
  return true
}

/** 第二步:【level2】返回科目:新增、删除、条件关系 */
// 新增
const handleAdd = (item) => {
  console.log('第二步:', item)
  // 1、判断上面一条数据是否填写
  if (item?.conditionName === '') {
    message.error('请选择提成科目!')
    return
  }
  // 2、判断上条数据是否填写完整
  const lastItem = item.children[item.children.length - 1]
  if (lastItem !== undefined) {
    if (lastItem.children?.length > 0) {
      const hasAllValues = checkFields(lastItem)
      if (!hasAllValues) {
        message.error('请填写完整条件')
        return
      }
    }
  } else {
    if (lastItem?.children?.length == 0) {
      message.error('请填写完整条件')
      return
    }
  }

  // 3、添加数据
  const result: itemProps = {
    pName: '',
    pType: '',
    pOption: '',
    pValue: ''
  }
  item.children.push({
    relation: 'AND',
    children: [result]
  })
  console.log('科目添加条件:新增', tableList.value)
  emits('success', tableList.value)
}
// 删除
const handleDelete = (index) => {
  console.log('第一步:科目添加条件:删除', tableList.value)
  tableList.value.splice(index, 1)
  emits('success', tableList.value)
}
// 条件关系
const handleLevelRelation = (item) => {
  console.log('里层')
  if (!props.isEdit) return
  item.relation = item.relation === 'AND' ? 'OR' : 'AND'
  emits('success', tableList.value)
}

// 判断数组中的每个对象的 pName、pType、pOption、pValue 字段是否都有值
function checkFields(data) {
  for (const item of data.children) {
    if (item.pName === '' || item.pType === '' || item.pOption === '' || item.pValue === '') {
      return false
    }
  }
  return true
}

/** 第三步:行内添加 */
const handleRowAdd = (item, index: number) => {
  console.log('第三步:新增行', item, index)
  // 1、判断上面一条数据是否填写
  const arr = item.children
  const lastItem = arr.length > 0 ? arr[arr.length - 1] : null
  console.log('lastItem', lastItem)
  if (
    lastItem.pName === '' ||
    lastItem.pType === '' ||
    lastItem.pOption === '' ||
    lastItem.pValue === ''
  ) {
    message.error(`返回科目规则需配置完整!`)
    return
  }
  // 2、添加数据
  const result: itemProps = {
    pName: '',
    pType: '',
    pOption: '',
    pValue: ''
  }
  item.children.push(result)
  console.log('tableList', tableList.value)
  emits('success', tableList.value)
}
const handleRowDelete = (item, index?: number) => {
  item.children.splice(index, 1)
  console.log('????', tableList.value)
  emits('success', tableList.value)
}

/** 第四步:删除节点 */
const handleNodeDelete = (item, index) => {
  item.children.splice(index, 1)
  emits('success', tableList.value)
}

onMounted(() => {
  tableList.value = chooseList.value // 初始化赋值
})

watch(
  () => props.chooseList,
  (val) => {
    tableList.value = val
  }
)
</script>

<style lang="scss" scoped>
.title {
  padding: 10px 0;
}
.btnBox {
  display: flex;
  justify-content: flex-end;
}
.boxTwo {
  display: flex;
  justify-content: space-between;
  margin-top: 10px;
  .left {
    display: flex;
    align-items: center;
    position: relative;
    .round {
      width: 30px;
      height: 30px;
      border-radius: 50%;
      background-color: white;
      border: 1px solid black;
      font-size: 14px;
      color: black;
      margin: auto;
      position: relative;
      z-index: 3;
      text-align: center;
    }
    .border {
      position: absolute;
      left: 50%;
      top: 0;
      bottom: 0;
      border-left: 1px solid black;
    }
  }
  .right {
    flex: 1;
    padding: 10px;
  }
  .level1Right {
    display: flex;
    margin-bottom: 10px;
  }
  .levelRight {
    flex: 1;
    padding: 10px 10px 0 10px;
    display: block;
  }
}
</style>

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

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

相关文章

YOLOv8改进 | 细节涨点篇 | UNetv2提出的一种SDI多层次特征融合模块(分割高效涨点)

一、本文介绍 本问给大家带来的改进机制是UNetv2提出的一种多层次特征融合模块(SDI)其是一种用于替换Concat操作的模块,SDI模块的主要思想是通过整合编码器生成的层级特征图来增强图像中的语义信息和细节信息。该方法已在多个公开的医学图像分割数据集上进行了验证,包括皮…

HANA:传参,游标(Cursor)应用,FOR循环,解决存储表内存溢出的问题

作者 idan lian 如需转载备注出处 1.应用场景 最近项目上用HANA开发的比较多&#xff0c;之前我是bw用的比较多&#xff0c;就不会有这种问题。我们这个项目很多都是开发的计算视图&#xff0c;但最近做acdoca的逻辑时&#xff0c;计算视图在生产环境执行的时候报错&#xf…

阿里巴巴分拆业务板块,中台架构已经死了吗?

阿里巴巴集团董事会主席兼首席执行官张勇发布全员信&#xff0c;宣布启动“16N”组织变革。在阿里巴巴集团之下&#xff0c;将设立阿里云智能、淘宝天猫商业、本地生活、菜鸟、国际数字商业、大文娱等六大业务集团和多家业务公司。 业务集团和业务公司分别成立董事会&#xff…

基于电源完整性的一些PCB设计建议

基于电源完整性的一些PCB设计建议 1. 尽量减少电源和地通路之间的环路电感&#xff0c;在相邻的层上分配电源和接地面时&#xff0c;使用尽可能薄的电介质&#xff1b; 2. 通过在平面之间使用尽可能高的介电常数来获得平面之间的最低阻抗&#xff0c;与尽可能薄的介电常数设计…

深入理解 Flink(七)Flink Slot 管理详解

1.JobMaster 注册成功之后开始调度 JobMaster 中封装了一个 DefaultScheduler&#xff0c;在 DefaultScheduler.startSchedulingInternal() 方法中生成 ExecutionGraph 以执行调度。 2.Flink 的资源管理机制 资源调度的大体流程如下&#xff1a; a.TaskExecutor 注册 Reg…

从CISC到RISC-V:揭开指令集的面纱

对于大多数同学来说&#xff0c;计算机或智能手机的运行似乎就像魔法一样神奇。你可能知道它们内部都是一些复杂的电子组件&#xff0c;比如CPU、内存等等&#xff0c;但这些组件是如何协同工作&#xff0c;让我们可以在电脑上打字&#xff0c;或者在手机上看视频呢&#xff1f…

matplotlib绘制动态瀑布图

绘制瀑布图思路&#xff1a;遍历指定文件目录下所有的csv文件&#xff0c;每读一个文件&#xff0c;取文件前20行数据进行保存&#xff0c;如果超过规定的行数300行&#xff0c;将最旧的数据删除&#xff0c;仅保留300行数据进行展示。 网上找的大部分绘制瀑布图的代码&#x…

ssh远程登录协议 搞定远程访问控制

远程管理linux系统基本上都要使用到ssh&#xff0c;原因很简单&#xff1a;telnet、FTP等传输方式是以明文传送用户认证信息&#xff0c;本质上是不安全的&#xff0c;存在被网络窃听的危险。SSH&#xff08;Secure Shell&#xff09;目前较可靠&#xff0c;是专为远程登录会话…

走迷宫(c语言)

前言&#xff1a; 制作一个迷宫游戏是一个有趣的编程挑战。首先&#xff0c;我们需要设计一个二维数组来表示迷宫的布局&#xff0c;其中每个元素代表迷宫中的一个格子。我们可以使用不同的值来表示空格、墙壁和起点/终点。接下来&#xff0c;我们需生成迷宫。在生成迷宫的过程…

智能手表喇叭无气孔导致老化播放后没声音

智能音箱喇叭老化播放后没声音 智能手表要做防水&#xff0c;在外壳上打了防水胶&#xff0c;结果出现播放突然没声音的现象&#xff0e; 原因 一直播放&#xff0c;设备温度升高&#xff0c;因为做了防水密闭导致喇叭腔体气压异常&#xff0c;导致播放没声音&#xff0e; …

nginx入门学习

nginx简介 nginx 是什么?用来干嘛的 通俗解释&#xff1a;客户端向服务器请求时&#xff0c;提供让多个服务器一起处理请求的东西 是一个反向代理服务器&#xff0c;能够提供负载均衡&#xff0c;和进行反向代理的功能 正向代理&反向代理 客户端向代理服务器请求&#…

短剧分销系统,助力短剧市场发展,实现短剧收益

近几年来&#xff0c;我国短剧兴起&#xff0c;在经过几年的蓄力后迎来了爆发期&#xff0c;短剧市场规模一路狂飙&#xff01;短剧拥有节奏快、剧情“爽”的优势&#xff0c;成功占领了各大观众的碎片化时间&#xff0c;短剧已经成为了影视行业的新力量&#xff0c;也成为了当…

微服务概述之微服务特性

前言 既然系统采用了微服务架构&#xff0c;就需要了解一些微服务的特性&#xff0c;这样在进行微服务开发时&#xff0c;脑海中才会有一些指导方向。微服务具有以下特性。 1. 服务组件化 组件是独立、可替换、可升级的软件的单元。将整体应用拆分成独立的服务组件后&#xff…

嵌入式软件开发对硬件知识的掌握要求要多高?

嵌入式软件开发对硬件知识的掌握要求要多高&#xff1f; 在开始前我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「嵌入式的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共享给大家&#xff0…

并发编程(一)线程基础知识与线程控制

进程与线程 进程&#xff1a;如任务管理器中各种程序叫做正在运行的进程。对于操作系统来说&#xff0c;仅仅是一个数据结构&#xff0c;并不真实的执行代码 线程&#xff1a;真实执行代码的 每个进程启动的是时候会同步启动一个主线程即main函数&#xff0c;当main函数结束…

倒F天线设计经验分享

一、IFA天线理论分析 为了改善&#xff29;&#xff2c;&#xff21;天线难以使用的缺点&#xff0c;在&#xff29;&#xff2c;&#xff21;天线的基础上再增加一个倒L结构&#xff0c;形成IFA天线&#xff0c;此种天线体积小、易于匹配并具有双极化的特点&#xff0c;而在蓝…

帆软报表11.0.19增加postgres数据源方案

项目使用postgres数据库&#xff0c;帆软报表集成开发时需要手工增加该数据源。 https://help.fanruan.com/finereport/doc-view-2563.html 但增加数据源后测试报告无此驱动&#xff0c;经查看文档&#xff0c;现在是通过驱动管理来上传&#xff0c; 但新版又不允许上传驱动JAR…

外贸群发邮件最好的软件?群发软件哪个好?

外贸开发信群发软件推荐&#xff1f;做外贸用什么邮件群发软件&#xff1f; 在外贸业务中&#xff0c;与潜在客户建立联系并保持沟通是至关重要的。那么&#xff0c;如何快速有效地发送邮件给大量的潜在客户呢&#xff1f;这就涉及到了外贸群发邮件。蜂邮EDM来探讨一下&#x…

presto/trino 入门介绍实战

引言 Presto是一款分布式SQL查询引擎&#xff0c;它能够在大规模数据集上实现快速、交互式的查询。本文将介绍Presto的基本概念并结合一些实际的代码示例&#xff0c;能够让的大家快速入门并在实际项目中应用。 官网&#xff1a;Launch Presto: Local download, JDBC, Docker…

11.云原生分布式数据库之TIDB

云原生专栏大纲 文章目录 为什么使用TIDB后端视角运维视角基础架构视角 TiDB Operator 简介软件版本要求部署tidbTIDB工具helm常用命令TIDB学习推荐资料 为什么使用TIDB 从后端视角、运维视角和基础架构视角来看&#xff0c;使用 TiDB 作为数据库系统可以获得分布式架构、高可…