123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415 |
- <template>
- <!-- `branch-wrap--${nodeConfig.local_status}`-->
- <div class="branch-wrap" :class="[disabled ? 'branch-wrap--disabled' : '']">
- <div class="branch-box-wrap">
- <div class="branch-box">
- <el-button class="add-branch" type="success" plain round @click="addTerm"> 添加条件 </el-button>
- <div v-for="(item, index) in nodeConfig.conditionNodes" :key="index" class="col-box">
- <div class="condition-node">
- <div class="condition-node-box">
- <div :class="['auto-judge', `auto-judge--${item.local_status}`]" @click="show(index)">
- <!-- 不是第一个 也不是 最后一个-->
- <div v-if="index != 0 && index != nodeConfig.conditionNodes.length - 1" class="sort-left" @click.stop="arrTransfer(index, -1)">
- <el-icon><ArrowLeft /></el-icon>
- </div>
- <div class="title">
- <span class="node-title" :class="[index === nodeConfig.conditionNodes.length - 1 ? 'last-child-title' : '']">{{
- index === nodeConfig.conditionNodes.length - 1 ? '默认条件' : item.nodeName
- }}</span>
- <span class="priority-title">优先级{{ item.priorityLevel }}</span>
- <el-icon v-if="index != nodeConfig.conditionNodes.length - 1" class="close" @click.stop="delTerm(index)">
- <Close />
- </el-icon>
- </div>
- <div class="content" :class="[index === nodeConfig.conditionNodes.length - 1 ? 'last-child-title' : '']">
- <span v-if="toText(nodeConfig, index)">{{ toText(nodeConfig, index) }}</span>
- <span v-else class="placeholder"> 请设置条件 </span>
- </div>
- <!-- 最后一个没有,长度大于2倒数第二个没有 -->
- <div
- v-if="
- !(nodeConfig.conditionNodes.length == 2 && (index === nodeConfig.conditionNodes.length - 1 || index === 0)) &&
- !(
- (nodeConfig.conditionNodes.length > 2 && index === nodeConfig.conditionNodes.length - 1) ||
- index === nodeConfig.conditionNodes.length - 2
- )
- "
- class="sort-right"
- @click.stop="arrTransfer(index)"
- >
- <el-icon><ArrowRight /></el-icon>
- </div>
- </div>
- <add-node v-model="item.childNode" :disabled="disabled"></add-node>
- </div>
- </div>
- <slot v-if="item.childNode" :node="item"></slot>
- <div v-if="index == 0" class="top-left-cover-line"></div>
- <div v-if="index == 0" class="bottom-left-cover-line"></div>
- <div v-if="index == nodeConfig.conditionNodes.length - 1" class="top-right-cover-line"></div>
- <div v-if="index == nodeConfig.conditionNodes.length - 1" class="bottom-right-cover-line"></div>
- </div>
- </div>
- <add-node v-model="nodeConfig.childNode" :disabled="disabled"></add-node>
- </div>
- <el-drawer v-model="drawer" title="条件设置" destroy-on-close append-to-body :size="600">
- <template #header>
- <div class="node-wrap-drawer__title">
- <label v-if="!isEditTitle" @click="editTitle">
- {{ form.nodeName }}<el-icon class="node-wrap-drawer__title-edit"><Edit /></el-icon>
- <!-- <div @click="rmConditionGroup(conditionGroup)">-->
- <!-- -->
- <!-- </div>-->
- </label>
- <el-input v-if="isEditTitle" ref="nodeTitle" v-model="form.nodeName" clearable @blur="saveTitle" @keyup.enter="saveTitle"></el-input>
- </div>
- </template>
- <el-container>
- <el-main style="padding: 0 0 20px 0">
- <div class="top-tips">满足以下条件时进入当前分支</div>
- <template v-for="(conditionGroup, conditionGroupIdx) in form.conditionList" :key="conditionGroupIdx">
- <div v-if="conditionGroupIdx != 0" class="or-branch-link-tip">或满足</div>
- <div class="condition-group-editor">
- <div class="header">
- <span>条件组 {{ conditionGroupIdx + 1 }}</span>
- <div @click="deleteConditionGroup(conditionGroupIdx)">
- <el-icon class="branch-delete-icon"><Delete /></el-icon>
- </div>
- </div>
- <div class="main-content">
- <!-- 单个条件 -->
- <div class="condition-content-box cell-box">
- <div v-if="false">描述</div>
- <div>条件字段</div>
- <div>运算符</div>
- <div>值</div>
- </div>
- <div v-for="(condition, idx) in conditionGroup" :key="idx" class="condition-content">
- <div class="condition-relation">
- <span>{{ idx == 0 ? '当' : '且' }}</span>
- <div v-if="conditionGroup.length > 1" @click="deleteConditionList(conditionGroup, idx)">
- <el-icon class="branch-delete-icon"><Delete /></el-icon>
- </div>
- </div>
- <div class="condition-content">
- <div class="condition-content-box">
- <el-input
- v-if="condition.type === 'custom'"
- v-model="condition.label"
- placeholder="自定义条件字段"
- @input="getCurrentItemField(conditionGroupIdx, idx)"
- />
- <el-select
- v-if="condition.type === 'form'"
- v-model="condition.field"
- filterable
- placeholder="表单条件字段"
- @change="getCurrentItemLabel(conditionGroupIdx, idx)"
- >
- <el-option v-for="{ id, label, key } in expressionFormList" :key="id" :label="label" :value="key" />
- </el-select>
- <el-select v-model="condition.operator" placeholder="请选择表达式">
- <el-option label="等于" value="=="></el-option>
- <el-option label="不等于" value="!="></el-option>
- <el-option label="大于" value=">"></el-option>
- <el-option label="大于等于" value=">="></el-option>
- <el-option label="小于" value="<"></el-option>
- <el-option label="小于等于" value="<="></el-option>
- <el-option label="包含" value="include"></el-option>
- <el-option label="不包含" value="notinclude"></el-option>
- </el-select>
- <el-input v-model="condition.value" placeholder="值" />
- </div>
- </div>
- </div>
- </div>
- <div class="sub-content">
- <el-button link type="primary" :icon="Plus" @click="addConditionList(conditionGroup, 'custom')"> 添加自定义条件 </el-button>
- <el-button
- v-if="expressionFormList.length"
- link
- type="primary"
- :icon="Plus"
- style="margin-left: 8px"
- @click="addConditionList(conditionGroup, 'form')"
- >
- 添加表单条件
- </el-button>
- </div>
- </div>
- </template>
- <el-button style="width: 100%" type="info" :icon="Plus" text bg @click="addConditionGroup"> 添加条件组 </el-button>
- </el-main>
- <el-footer>
- <el-button type="primary" @click="save"> 保存 </el-button>
- <el-button @click="drawer = false">取消</el-button>
- </el-footer>
- </el-container>
- </el-drawer>
- </div>
- </template>
- <script>
- import addNode from './addNode.vue'
- import useFlowStore from '@/store/modules/flow'
- import { Delete, Plus, ArrowLeft, Close, ArrowRight, Edit } from '@element-plus/icons-vue'
- import { mapState } from 'pinia'
- import { getNodeKey } from '@/utils/workflow'
- export default {
- components: {
- addNode
- },
- props: {
- modelValue: { type: Object, default: () => {} },
- disabled: {
- type: Boolean,
- default: false
- }
- },
- data() {
- return {
- nodeConfig: {},
- drawer: false,
- isEditTitle: false,
- index: 0,
- form: {},
- expressionFormList: []
- }
- },
- computed: {
- Plus() {
- return Plus
- },
- ...mapState(useFlowStore, ['processForm']) //映射函数,取出processForm
- },
- watch: {
- modelValue() {
- this.nodeConfig = this.modelValue
- }
- },
- mounted() {
- this.nodeConfig = this.modelValue
- },
- methods: {
- show(index) {
- if (this.disabled) return
- if (index === this.nodeConfig.conditionNodes.length - 1) {
- // 最后一个节点不能编辑
- return
- }
- this.index = index
- this.form = {}
- this.form = JSON.parse(JSON.stringify(this.nodeConfig.conditionNodes[index]))
- const { formStructure } = JSON.parse(this.processForm) // 表单设计字段
- // 使用 filter 方法找到 required 属性为 true 的对象
- const requiredList = (formStructure?.fields || []).filter(item => item.options && item.options.required === true)
- console.log(`%c 这里打印出符合条件的表单对象-=== ${JSON.stringify(requiredList)}`, 'background: orange; color: #fff')
- this.expressionFormList = requiredList || []
- this.drawer = true
- },
- editTitle() {
- this.isEditTitle = true
- this.$nextTick(() => {
- this.$refs.nodeTitle.focus()
- })
- },
- saveTitle() {
- this.isEditTitle = false
- },
- save() {
- this.nodeConfig.conditionNodes[this.index] = this.form
- this.$emit('update:modelValue', this.nodeConfig)
- this.drawer = false
- },
- addTerm() {
- let len = this.nodeConfig.conditionNodes.length + 1
- this.nodeConfig.conditionNodes.push({
- nodeName: '条件' + len,
- nodeKey: getNodeKey(),
- type: 3,
- priorityLevel: len,
- conditionMode: 1,
- conditionList: []
- })
- },
- delTerm(index) {
- this.nodeConfig.conditionNodes.splice(index, 1)
- if (this.nodeConfig.conditionNodes.length == 1) {
- if (this.nodeConfig.childNode) {
- if (this.nodeConfig.conditionNodes[0].childNode) {
- this.reData(this.nodeConfig.conditionNodes[0].childNode, this.nodeConfig.childNode)
- } else {
- this.nodeConfig.conditionNodes[0].childNode = this.nodeConfig.childNode
- }
- }
- this.$emit('update:modelValue', this.nodeConfig.conditionNodes[0].childNode)
- }
- },
- reData(data, addData) {
- if (!data.childNode) {
- data.childNode = addData
- } else {
- this.reData(data.childNode, addData)
- }
- },
- arrTransfer(index, type = 1) {
- this.nodeConfig.conditionNodes[index] = this.nodeConfig.conditionNodes.splice(index + type, 1, this.nodeConfig.conditionNodes[index])[0]
- this.nodeConfig.conditionNodes.map((item, index) => {
- item.priorityLevel = index + 1
- })
- this.$emit('update:modelValue', this.nodeConfig)
- },
- addConditionList(conditionList, type) {
- conditionList.push({
- label: '',
- field: '',
- operator: '==',
- value: '',
- type
- })
- },
- deleteConditionList(conditionList, index) {
- conditionList.splice(index, 1)
- },
- addConditionGroup() {
- this.addConditionList(this.form.conditionList[this.form.conditionList.push([]) - 1], 'custom')
- },
- deleteConditionGroup(index) {
- this.form.conditionList.splice(index, 1)
- },
- toText(nodeConfig, index) {
- var { conditionList } = nodeConfig.conditionNodes[index]
- if (conditionList && conditionList.length == 1) {
- const text = conditionList.map(conditionGroup => conditionGroup.map(item => `${item.label}${item.operator}${item.value}`)).join(' 和 ')
- return text
- } else if (conditionList && conditionList.length > 1) {
- return conditionList.length + '个条件,或满足'
- } else {
- if (index == nodeConfig.conditionNodes.length - 1) {
- return '未满足时其他条件时,将进入默认流程'
- } else {
- return false
- }
- }
- },
- getCurrentItemLabel(conditionIdx, idx) {
- const currentCondition = this.form.conditionList[conditionIdx]
- const field = currentCondition[idx].field
- // const labelObj = this.expressionFormList.find(i => i.key === field)
- // currentCondition[idx].label = labelObj.label
- currentCondition[idx].label = field
- },
- getCurrentItemField(conditionIdx, idx) {
- const currentCondition = this.form.conditionList[conditionIdx]
- currentCondition[idx].field = currentCondition[idx].label
- }
- }
- }
- </script>
- <style scoped lang="scss">
- .top-tips {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 12px;
- color: #646a73;
- }
- .or-branch-link-tip {
- margin: 10px 0;
- color: #646a73;
- }
- .condition-group-editor {
- user-select: none;
- border-radius: 4px;
- border: 1px solid #e4e5e7;
- position: relative;
- margin-bottom: 16px;
- .branch-delete-icon {
- font-size: 18px;
- }
- .header {
- background-color: #f4f6f8;
- padding: 0 12px;
- font-size: 14px;
- color: #171e31;
- height: 36px;
- display: flex;
- align-items: center;
- span {
- flex: 1;
- }
- }
- .main-content {
- padding: 0 12px;
- .condition-relation {
- color: #9ca2a9;
- display: flex;
- align-items: center;
- height: 36px;
- display: flex;
- justify-content: space-between;
- padding: 0 2px;
- }
- .condition-content-box {
- display: flex;
- justify-content: space-between;
- align-items: center;
- div {
- width: 100%;
- min-width: 120px;
- }
- div:not(:first-child) {
- margin-left: 16px;
- }
- }
- .cell-box {
- div {
- padding: 16px 0;
- width: 100%;
- min-width: 120px;
- color: #909399;
- font-size: 14px;
- font-weight: 600;
- text-align: center;
- }
- }
- .condition-content {
- display: flex;
- flex-direction: column;
- :deep(.el-input__wrapper) {
- border-top-left-radius: 0;
- border-bottom-left-radius: 0;
- }
- .content {
- flex: 1;
- padding: 0 0 4px 0;
- display: flex;
- align-items: center;
- min-height: 31.6px;
- flex-wrap: wrap;
- }
- }
- }
- .sub-content {
- padding: 12px;
- }
- }
- </style>
|