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

news2024/11/15 9:22:45

一、条件层级效果图

二、代码

<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>

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何优化大型语言模型,让AI回应更智能、更准确?

什么是检索增强生成&#xff08;RAG)&#xff1f; 检索增强生成&#xff08;RAG&#xff09;是一种优化大型语言模型输出的过程&#xff0c;它在生成回应之前会参考其训练数据源之外的权威知识库。大型语言模型&#xff08;LLM&#xff09;在大量数据上进行训练&#xff0c;使…

Windows10解决大小核调度问题

文章目录 1.开启高性能模式2.下载安装PowerSettingsExplorer3.修改配置生效的异类策略异类线程调度策略异类短时间线程调度策略 4.你的电源策略5.CPU展示 该教程是给笔记本电脑用的&#xff0c;经过我实践是成功的。 1.开启高性能模式 使用管理员模式的PowerShell输入下列指令 …

微信小程序上传并显示图片

实现效果&#xff1a; 上传前显示&#xff1a; 点击后可上传&#xff0c;上传后显示&#xff1a; 源代码&#xff1a; .wxml <view class"{{company_logo_src?blank-area:}}" style"position:absolute;top:30rpx;right:30rpx;height:100rpx;width:100rp…

C++ 设计模式之享元模式

【声明】本题目来源于卡码网&#xff08;题目页面 (kamacoder.com)&#xff09; 【提示&#xff1a;如果不想看文字介绍&#xff0c;可以直接跳转到C编码部分】 【简介】什么是享元模式 -- 可重复使用 享元模式是⼀种结构型设计模式&#xff0c;在享元模式中&#xff0c;对象被…

基于深度学习的桃子熟度与大小智能检测

基于深度学习的桃子熟度与大小智能检测 基于深度学习的桃子熟度与大小智能检测引言1. 环境搭建与准备2. 数据准备3. 模型准备4. 训练准备5. 服务器端部署结语 基于深度学习的桃子熟度与大小智能检测 引言 随着时代的快速发展&#xff0c;人工智能时代为中国农业带来了新的机遇…

Leetcode刷题【每日n题】(1)

目录 1.题目一 2.思路分析 3.代码实现 4.题目二 5.思路分析 6.代码实现 1.题目一 11. 盛最多水的容器 给定一个长度为 n 的整数数组 height 。有 n 条垂线&#xff0c;第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。 找出其中的两条线&#xff0c;使得它们与 x 轴…

Vue-20、Vue.set()的使用

1、添加对象某个属性 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Vue.set()的使用</title><script type"text/javascript" src"https://cdn.jsdelivr.net/npm/vue2/dist…

2023.12.30性质

若连通图上各边的权值均不相同&#xff0c;则该图的最小生成树是唯一的。 由k算法&#xff0c;即由边从小到大的顺序构造&#xff0c;如果边权值各不相同&#xff0c;那么构造出来的最小生成树唯一&#xff0c;就是唯一的顺序&#xff0c;从小到大 关于带权无向图的最小生成…

动态pv(nfs方式挂载)

1、定义 发布pvc之后可以生成pv&#xff0c;还可以在共享服务器上直接生成挂载目录 pvc直接绑定和使用pv 2、动态pv依赖两个组件 &#xff08;1&#xff09;provisioner卷插件&#xff1a;k8s本身支持的动态pv创建不包括nfs&#xff0c;需要声明和安装一个外部插件provisio…

HDFS和MapReduce综合实训

文章目录 第1关&#xff1a;WordCount词频统计第2关&#xff1a;HDFS文件读写第3关&#xff1a;倒排索引第4关&#xff1a; 网页排序——PageRank算法 第1关&#xff1a;WordCount词频统计 测试说明 以下是测试样例&#xff1a; 测试输入样例数据集&#xff1a;文本文档test1…

canvas截取视频图像(图文示例)

查看专栏目录 canvas示例教程100专栏&#xff0c;提供canvas的基础知识&#xff0c;高级动画&#xff0c;相关应用扩展等信息。canvas作为html的一部分&#xff0c;是图像图标地图可视化的一个重要的基础&#xff0c;学好了canvas&#xff0c;在其他的一些应用上将会起到非常重…

[VGG团队论文阅读]Free3D: Consistent Novel View Synthesis without 3D Representation

Vedaldi, C. Z. A. (n.d.). Free3D: Consistent Novel View Synthesis without 3D Representation. Chuanxiaz.com. https://chuanxiaz.com/free3d/static/videos/Free3D.pdf Free3D: 无需3D表示的一致新视角合成 Visual Geometry Group, University of Oxford 摘要 我们介绍…

C# 面向切面编程之AspectCore初探

写在前面 AspectCore 是Lemon名下的一个国产Aop框架&#xff0c;提供了一个全新的轻量级和模块化的Aop解决方案。面向切面也可以叫做代码拦截&#xff0c;分为静态和动态两种模式&#xff0c;AspectCore 可以实现动态代理&#xff0c;支持程序运行时在内存中“临时”生成 AOP 动…

Mindspore 公开课 - prompt

prompt 介绍 Fine-Tuning to Prompt Learning Pre-train, Fine-tune BERT bidirectional transformer&#xff0c;词语和句子级别的特征抽取&#xff0c;注重文本理解Pre-train: Maked Language Model Next Sentence PredictionFine-tune: 根据任务选取对应的representatio…

Android 仿快手视频列表,RecyclerView与Banner联动效果

这是看到群里讨论过快手APP的一个观看他人视频列表的一个联动效果&#xff0c;但是并不是完全按照这个软件的效果来做的&#xff0c;只是参考&#xff0c;并不是完全仿照这个软件来做的&#xff0c;没时间去优化排版问题了&#xff0c;请见谅&#xff0c;如图&#xff1a; 实现…

pycharm管理仓库(Manager Repository)不见了

经常使用pycharm的大佬们都知道&#xff0c;pycharm中内置了很多库和包&#xff0c;很好用 但是下载来用自带的源很麻烦&#xff0c;于是就用国内的源 可以当我们添加管理仓库的时候&#xff0c;却没有了按钮&#xff0c;如何解决呢&#xff1f; 回到pycharm的主界面&#xf…

C语言:自定义类型——结构体

一、什么叫做结构体 C语⾔已经提供了内置类型&#xff0c;如&#xff1a;char、short、int、long、float、double等&#xff0c;但是只有这些内置类型还是不够的&#xff0c;假设我想描述学⽣&#xff0c;描述⼀本书&#xff0c;这时单⼀的内置类型是不⾏的。描述⼀个学⽣需要 …

Leetcode2707. 字符串中的额外字符

Every day a Leetcode 题目来源&#xff1a;2707. 字符串中的额外字符 解法1&#xff1a;动态规划 题目要求将字符串 s 分割成若干个互不重叠的子字符串&#xff08;以下简称为子串&#xff09;&#xff0c;同时要求每个子串都必须在 dictionary 中出现。一些额外的字符可能…

【EI会议征稿通知】第五届计算机通信与网络安全国际学术会议 (CCNS 2024)

第五届计算机通信与网络安全国际学术会议 (CCNS 2024) 2024 5th International Conference on Computer Communication and Network Securit IEEE Fellow、海内外高层次专家云集&#xff0c;EI、Scopus稳定检索 第五届计算机通信与网络安全国际学术会议 (CCNS 2024) 将于202…

立白科技集团:研发安全推动数字化蜕变,日化业务再上新高度

立白科技集团成立于1994年&#xff0c;是我国日化行业的领军企业&#xff0c;致力于成为一家“品牌引领、数字经营、富有创新、富有活力”的智慧服务型企业。从2018年开始&#xff0c;立白科技集团加速数字化转型&#xff0c;打造数据和业务中台&#xff0c;并建立toB和toC平台…