瀏覽代碼

feat: 流程设计 - 替换条件流程 100%

luoyali 1 年之前
父節點
當前提交
576ef061b0
共有 1 個文件被更改,包括 190 次插入73 次删除
  1. 190 73
      src/components/scWorkflow/nodes/branch.vue

+ 190 - 73
src/components/scWorkflow/nodes/branch.vue

@@ -2,25 +2,27 @@
 	<div class="branch-wrap">
 		<div class="branch-box-wrap">
 			<div class="branch-box">
-				<el-button class="add-branch" type="success" plain round @click="addTerm">添加条件</el-button>
+				<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" @click="show(index)">
 								<div v-if="index != 0" class="sort-left" @click.stop="arrTransfer(index, -1)">
-									<el-icon><arrow-left /></el-icon>
+									<el-icon><el-icon-arrow-left /></el-icon>
 								</div>
 								<div class="title">
 									<span class="node-title">{{ item.nodeName }}</span>
 									<span class="priority-title">优先级{{ item.priorityLevel }}</span>
-									<el-icon class="close" @click.stop="delTerm(index)"><close /></el-icon>
+									<el-icon class="close" @click.stop="delTerm(index)">
+										<el-icon-close />
+									</el-icon>
 								</div>
 								<div class="content">
 									<span v-if="toText(nodeConfig, index)">{{ toText(nodeConfig, index) }}</span>
-									<span v-else class="placeholder">请设置条件</span>
+									<span v-else class="placeholder"> 请设置条件 </span>
 								</div>
 								<div v-if="index != nodeConfig.conditionNodes.length - 1" class="sort-right" @click.stop="arrTransfer(index)">
-									<el-icon><arrow-right /></el-icon>
+									<el-icon><el-icon-arrow-right /></el-icon>
 								</div>
 							</div>
 							<add-node v-model="item.childNode"></add-node>
@@ -35,68 +37,74 @@
 			</div>
 			<add-node v-model="nodeConfig.childNode"></add-node>
 		</div>
-		<el-drawer v-model="drawer" title="条件设置" destroy-on-close append-to-body :size="600" class="aDrawer">
+		<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
-					></label>
+					<label v-if="!isEditTitle" @click="editTitle">
+						{{ form.nodeName }}
+						<div @click="rmConditionGroup(conditionGroup)">
+							<el-icon class="node-wrap-drawer__title-edit"><el-icon-edit /></el-icon>
+						</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>
-					<el-form label-position="top">
-						<el-form-item label="条件关系">
-							<el-radio-group v-model="form.conditionMode">
-								<el-radio :label="1">且</el-radio>
-								<el-radio :label="2">或</el-radio>
-							</el-radio-group>
-						</el-form-item>
-						<el-divider></el-divider>
-						<el-form-item>
-							<el-table :data="form.conditionList">
-								<el-table-column prop="label" label="描述">
-									<template #default="scope">
-										<el-input v-model="scope.row.label" placeholder="描述"></el-input>
-									</template>
-								</el-table-column>
-								<el-table-column prop="field" label="条件字段" width="130">
-									<template #default="scope">
-										<el-input v-model="scope.row.field" placeholder="条件字段"></el-input>
-									</template>
-								</el-table-column>
-								<el-table-column prop="operator" label="运算符" width="130">
-									<template #default="scope">
-										<el-select v-model="scope.row.operator" placeholder="Select">
-											<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>
-									</template>
-								</el-table-column>
-								<el-table-column prop="value" label="值" width="100">
-									<template #default="scope">
-										<el-input v-model="scope.row.value" placeholder="值"></el-input>
-									</template>
-								</el-table-column>
-								<el-table-column prop="value" label="移除" width="55">
-									<template #default="scope">
-										<el-link type="danger" :underline="false" @click="deleteConditionList(scope.$index)">移除</el-link>
-									</template>
-								</el-table-column>
-							</el-table>
-						</el-form-item>
-						<p><el-button type="primary" :icon="Plus" round @click="addConditionList">增加条件</el-button></p>
-					</el-form>
+				<el-main style="padding: 0 0 20px 0">
+					<div class="top-tips">满足以下条件时进入当前分支</div>
+					<template v-for="(conditionGroup, conditionGroupIdx) in form.conditionList">
+						<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>描述</div>
+									<div>条件字段</div>
+									<div>运算符</div>
+									<div>值</div>
+								</div>
+								<div v-for="(condition, idx) in conditionGroup" class="condition-content">
+									<div class="condition-relation">
+										<span>{{ idx == 0 ? '当' : '且' }}</span>
+										<div @click="deleteConditionList(conditionGroup, idx)" v-if="conditionGroup.length > 1">
+											<el-icon class="branch-delete-icon"><Delete /></el-icon>
+										</div>
+									</div>
+									<div class="condition-content">
+										<div class="condition-content-box">
+											<el-input v-model="condition.label" placeholder="描述" />
+											<el-input v-model="condition.field" placeholder="条件字段" />
+											<el-select v-model="condition.operator" placeholder="Select">
+												<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)"> 添加条件 </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 type="primary" @click="save"> 保存 </el-button>
 					<el-button @click="drawer = false">取消</el-button>
 				</el-footer>
 			</el-container>
@@ -105,14 +113,10 @@
 </template>
 
 <script>
-import addNode from './addNode'
-import { Plus } from '@element-plus/icons-vue'
+import addNode from './addNode.vue'
+import { Delete, Plus } from '@element-plus/icons-vue'
+
 export default {
-	computed: {
-		Plus() {
-			return Plus
-		}
-	},
 	components: {
 		addNode
 	},
@@ -128,6 +132,11 @@ export default {
 			form: {}
 		}
 	},
+	computed: {
+		Plus() {
+			return Plus
+		}
+	},
 	watch: {
 		modelValue() {
 			this.nodeConfig = this.modelValue
@@ -194,25 +203,30 @@ export default {
 			})
 			this.$emit('update:modelValue', this.nodeConfig)
 		},
-		addConditionList() {
-			this.form.conditionList.push({
+		addConditionList(conditionList) {
+			conditionList.push({
 				label: '',
 				field: '',
 				operator: '=',
 				value: ''
 			})
 		},
-		deleteConditionList(index) {
+		deleteConditionList(conditionList, index) {
+			conditionList.splice(index, 1)
+		},
+		addConditionGroup() {
+			this.addConditionList(this.form.conditionList[this.form.conditionList.push([]) - 1])
+		},
+		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(item => `${item.label}${item.operator}${item.value}`).join(' 和 ')
+				const text = conditionList.map(conditionGroup => conditionGroup.map(item => `${item.label}${item.operator}${item.value}`)).join(' 和 ')
 				return text
 			} else if (conditionList && conditionList.length > 1) {
-				const conditionModeText = nodeConfig.conditionNodes[index].conditionMode == 1 ? '且行' : '或行'
-				return conditionList.length + '个条件,' + conditionModeText
+				return conditionList.length + '个条件,或满足'
 			} else {
 				if (index == nodeConfig.conditionNodes.length - 1) {
 					return '其他条件进入此流程'
@@ -225,4 +239,107 @@ export default {
 }
 </script>
 
-<style></style>
+<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>