Files
mosr-web/src/views/workflow/process/config/TriggerNodeConfig.vue
2024-06-21 13:02:55 +08:00

343 lines
12 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div>
<el-form label-position="top" label-width="90px">
<el-form-item label="选择触发的动作" prop="text" class="user-type">
<el-radio-group v-model="config.type">
<el-radio label="WEBHOOK">发送网络请求</el-radio>
<el-radio label="EMAIL">发送邮件</el-radio>
</el-radio-group>
</el-form-item>
<div v-if="config.type === 'WEBHOOK'">
<el-form-item label="请求地址" prop="text">
<el-input placeholder="请输入URL地址" v-model="config.http.url">
<el-select v-model="config.http.method" style="width: 85px;" slot="prepend" placeholder="URL" filterable>
<el-option label="GET" value="GET"></el-option>
<el-option label="POST" value="POST"></el-option>
<el-option label="PUT" value="PUT"></el-option>
<el-option label="DELETE" value="DELETE"></el-option>
</el-select>
</el-input>
</el-form-item>
<el-form-item label="Header请求头" prop="text">
<div slot="label">
<span style="margin-right: 10px">Header请求头</span>
<el-button type="primary" @click="addItem(config.http.headers)" link> + 添加</el-button>
</div>
<div v-for="(header, index) in config.http.headers" :key="index">
-
<el-input placeholder="参数名" style="width: 100px;" v-model="header.name"/>
<el-radio-group v-model="header.isField">
<el-radio-button :label="true">表单</el-radio-button>
<el-radio-button :label="false">固定</el-radio-button>
</el-radio-group>
<el-select v-if="header.isField" style="width: 180px;" v-model="header.value"
placeholder="请选择表单字段" filterable>
<el-option v-for="form in forms" :key="form.id" :label="form.title" :value="form.title"></el-option>
</el-select>
<el-input v-else placeholder="请设置字段值" v-model="header.value" style="width: 180px;"/>
<el-icon class="el-icon-delete" @click="delItem(config.http.headers, index)"
style="margin-left: 5px; color: #c75450; cursor: pointer"/>
</div>
</el-form-item>
<el-form-item label="Header请求参数" prop="text">
<div slot="label">
<span style="margin-right: 10px">请求参数 </span>
<el-button style="margin-right: 20px" type="primary" @click="addItem(config.http.params)" link> + 添加</el-button>
<span>参数类型 - </span>
<el-radio-group style="margin: 0 5px;" v-model="config.http.contentType">
<el-radio-button label="JSON">json</el-radio-button>
<el-radio-button label="FORM">form</el-radio-button>
</el-radio-group>
</div>
<div v-for="(param, index) in config.http.params" :key="index">
-
<el-input placeholder="参数名" style="width: 100px;" v-model="param.name"/>
<el-radio-group style="margin: 0 5px;" v-model="param.isField">
<el-radio-button :label="true">表单</el-radio-button>
<el-radio-button :label="false">固定</el-radio-button>
</el-radio-group>
<el-select v-if="param.isField" style="width: 180px;" v-model="param.value"
placeholder="请选择表单字段" filterable>
<el-option v-for="form in forms" :key="form.id" :label="form.title" :value="form.id"></el-option>
</el-select>
<el-input v-else placeholder="请设置字段值" v-model="param.value" style="width: 180px;"/>
<el-icon class="el-icon-delete" @click="delItem(config.http.params, index)"
style="margin-left: 5px; color: #c75450; cursor: pointer"/>
</div>
<div>
</div>
</el-form-item>
<!-- <el-form-item label="请求结果处理" prop="text">-->
<div slot="label">
<span>请求结果处理</span>
<span style="margin-left: 20px">自定义脚本: </span>
<el-switch v-model="config.http.handlerByScript"></el-switch>
</div>
<span class="item-desc" v-if="config.http.handlerByScript">
<p>👉 返回值为 ture 则流程通过 false 则流程将被驳回</p>
<p>👉 (上线注意)占不支持ES高级语法</p>
<p>👉 (上线注意)不支持浏览器的内置函数</p>
<!-- <div>支持函数-->
<!-- <span style="color: dodgerblue">setFormByName(-->
<!-- <span style="color: #939494">'表单字段名', '表单字段值'</span>-->
<!-- )</span>-->
<!-- 可改表单数据-->
<!-- </div>-->
</span>
<span class="item-desc" v-else>👉 无论请求结果如何均通过</span>
<div v-if="config.http.handlerByScript">
<div>
<el-button @click="requestTestHandler">测试</el-button>
</div>
<div>
<span>请求成功😀</span>
<js-code-edit v-model="config.http.success" :editor-placeholder="'请输入js代码'"
:editor-height="250" :tab-size="2"/>
</div>
<div>
<span>请求失败😥</span>
<js-code-edit v-model="config.http.fail" :editor-placeholder="'请输入js代码'"
:editor-height="250" :tab-size="2"/>
</div>
</div>
<!-- </el-form-item>-->
</div>
<div v-else-if="config.type === 'EMAIL'">
<el-form-item label="邮件主题" prop="text">
<el-input placeholder="请输入邮件主题" v-model="config.email.subject"/>
</el-form-item>
<el-form-item label="收件方" prop="text">
<el-select style="width: 100%;" v-model="config.email.to" filterable multiple allow-create
default-first-option placeholder="请输入收件人">
<el-option v-for="sender in config.email.to" :key="sender" :label="sender" :value="sender"></el-option>
</el-select>
</el-form-item>
<el-form-item label="抄送方" prop="text">
<el-select style="width: 100%;" v-model="config.email.cc" filterable multiple allow-create
default-first-option placeholder="请输入收件人">
<el-option v-for="item in config.email.cc" :key="item" :label="item" :value="item"></el-option>
</el-select>
</el-form-item>
<el-form-item label="邮件正文" prop="text">
<el-input type="textarea" v-model="config.email.content" :rows="4"
placeholder="邮件内容,支持变量提取表单数据 ${表单字段名} "></el-input>
</el-form-item>
</div>
</el-form>
</div>
</template>
<script setup>
import {computed, defineProps} from 'vue'
import {ElMessage, ElMessageBox} from 'element-plus'
import axios from "axios";
import {useProcessStore} from '@/stores/processStore.js'
import JsCodeEdit from "@/components/codeEdit/JsCodeEdit.vue";
const processStore = useProcessStore()
const props = defineProps({
config: {
type: Object,
default: () => {
return {}
}
}
})
const forms = computed(() => {
return processStore.getDesign().formItems || []
})
const addItem = (items) => {
if (items.length > 0 && (items[items.length - 1].name.trim() === ''
|| items[items.length - 1].value.trim() === '')) {
ElMessage.warning("请完善之前项后在添加")
return;
}
items.push({name: '', value: '', isField: true})
}
const delItem = (items, index) => {
items.splice(index, 1)
}
//url规范性检查
const restfulCheck = (url) => {
const httpProtocolPattern = /^http:/;
const httpsProtocolPattern = /^https:/;
const restfulUrlPattern = /\/\w+\/\w+(\/\{[^}]+\})*/;
if (httpProtocolPattern.test(url) || httpsProtocolPattern.test(url)) {
return restfulUrlPattern.test(url);
} else {
return false;
}
}
//是否含有动态参数
const hasUrlParams = (url) => {
const pattern = /{[^{}]+}/g;
let match;
while ((match = pattern.exec(url)) !== null) {
return true;
}
return false;
}
//获取到动态参数的名称
const getDynamicParamNames = (url) => {
const pattern = /{([^{}]+)}/g;
let match;
const paramNames = [];
while ((match = pattern.exec(url)) !== null) {
if (match[0].startsWith('{') && match[0].endsWith('}')) {
const paramName = match[1];
paramNames.push(paramName);
}
}
return paramNames;
}
//替换rul动态参数
const replaceDynamicParams = (url, params) => {
const dynamicParamPattern = /{\s*(\w+)\s*}/g;
return url.replace(dynamicParamPattern, (match, param) => {
return params[param] || '0';
});
}
//获取到参数值
const getParamsValue = (params, paramName) => {
for (let param of params) {
if (param.name === paramName) {
return param.value
}
}
return null;
}
//设置头部
const setHeaders = (http) => {
let headers = {}
for (let header of http.headers) {
if (header.isField) {
ElMessage.error("测试只支持固定参数")
return
}
if (header.name !== "" && header.value !== "") {
this.$set(headers, header.name, header.value);
}
}
if (http.contentType === "FORM") {
this.$set(headers, "Content-Type", "multipart/form-data")
} else {
this.$set(headers, "Content-Type", "application/json")
}
return headers;
}
//设置post和put参数
const setPostAndPutParams = (http) => {
let params = {}
for (let param of http.params) {
params[param.name] = param.value
}
return params;
}
//设置get和delete的参数
const setGetAndDeleteParams = (http) => {
let dynamicParams = []
let url = http.url
let hasParams = hasUrlParams(url)
if (hasParams) {
dynamicParams = getDynamicParamNames(url);
let replaceParams = {}
for (let paramsName of dynamicParams) {
let value = getParamsValue(http.params, paramsName)
if (null == value) {
ElMessage.error(paramsName + '参数未设置')
return;
}
replaceParams[paramsName] = value
}
url = replaceDynamicParams(url, replaceParams);
}
if (http.method === "DELETE") {
return url;
}
let getParams = []
for (let param of http.params) {
if (dynamicParams.indexOf(param.name) === -1 && param.name !== '' && param.value !== '') {
getParams.push(param.name + "=" + param.value)
}
}
if (getParams.length > 0) {
url += "?"
for (let i = 0; i < getParams.length; i++) {
if (i !== getParams.length - 1) {
url += getParams[i] + "&";
} else {
url += getParams[i];
}
}
}
return url;
}
//请求测试
const requestTestHandler = () => {
let http = props.config.http;
if (http.url == null || http.url === '') {
ElMessage.error("请填写请求路径!")
return
}
if (!restfulCheck(http.url)) {
ElMessage.error("当前只支持 RESTful URL!")
return
}
let headers = setHeaders(http)
let request
switch (http.method) {
case "GET":
case "DELETE":
let url = setGetAndDeleteParams(http)
if (null == url) {
return;
}
request = axios.request({
method: http.method,
url: url,
headers: headers,
});
break;
case "POST":
case "PUT":
request = axios.request({
method: http.method,
url: http.url,
headers: headers,
data: setPostAndPutParams(http)
});
break;
default:
break;
}
// console.log("==================[测试打印内容]==================")
request.then(res => {
console.log(res)
if (res.status === 200) {
let data = res.data
console.log(data)
let successFun = eval("(false ||" + http.success + ")");
let result = successFun(data);
console.log(result, "成功函数执行的返回结果")
} else {
let failFun = eval("(false ||" + http.fail + ")");
let result = failFun(res);
console.log(result, "失败函数执行的返回结果")
}
}).finally(() => {
console.log("==================[测试打印结束]==================")
})
}
</script>
<style lang="scss" scoped>
.item-desc {
color: #939494;
}
</style>