mirror of
https://github.com/xhongc/music-tag-web.git
synced 2026-02-02 17:59:07 +08:00
feature:80%
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -12,3 +12,27 @@ node_type = (
|
||||
(4, "条件分支"),
|
||||
(5, "汇聚网关"),
|
||||
)
|
||||
|
||||
|
||||
class StateType(object):
|
||||
CREATED = "CREATED"
|
||||
READY = "READY"
|
||||
RUNNING = "RUNNING"
|
||||
SUSPENDED = "SUSPENDED"
|
||||
BLOCKED = "BLOCKED"
|
||||
FINISHED = "FINISHED"
|
||||
FAILED = "FAILED"
|
||||
REVOKED = "REVOKED"
|
||||
|
||||
|
||||
PIPELINE_STATE_TO_FLOW_STATE = {
|
||||
StateType.READY: "wait",
|
||||
StateType.RUNNING: "run",
|
||||
StateType.FAILED: "fail",
|
||||
StateType.FINISHED: "success",
|
||||
StateType.SUSPENDED: "pause",
|
||||
StateType.REVOKED: "cancel",
|
||||
StateType.BLOCKED: "stop",
|
||||
StateType.CREATED: "positive",
|
||||
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Generated by Django 2.2.6 on 2022-01-28 09:40
|
||||
# Generated by Django 2.2.6 on 2022-02-09 03:29
|
||||
|
||||
import datetime
|
||||
from django.db import migrations, models
|
||||
@@ -39,41 +39,23 @@ class Migration(migrations.Migration):
|
||||
('category', models.ManyToManyField(to='flow.Category')),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Node',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(max_length=255, verbose_name='节点名称')),
|
||||
('uuid', models.CharField(max_length=255, unique=True, verbose_name='UUID')),
|
||||
('description', models.CharField(blank=True, max_length=255, null=True, verbose_name='节点描述')),
|
||||
('show', models.BooleanField(default=True, verbose_name='是否显示')),
|
||||
('top', models.IntegerField(default=300)),
|
||||
('left', models.IntegerField(default=300)),
|
||||
('ico', models.CharField(blank=True, max_length=64, null=True, verbose_name='icon')),
|
||||
('fail_retry_count', models.IntegerField(default=0, verbose_name='失败重试次数')),
|
||||
('fail_offset', models.IntegerField(default=0, verbose_name='失败重试间隔')),
|
||||
('fail_offset_unit', models.CharField(choices=[('seconds', '秒'), ('hours', '时'), ('minutes', '分')], max_length=32, verbose_name='重试间隔单位')),
|
||||
('node_type', models.IntegerField(default=2)),
|
||||
('component_code', models.CharField(max_length=255, verbose_name='插件名称')),
|
||||
('is_skip_fail', models.BooleanField(default=False, verbose_name='忽略失败')),
|
||||
('is_timeout_alarm', models.BooleanField(default=False, verbose_name='超时告警')),
|
||||
('inputs', django_mysql.models.JSONField(default=dict, verbose_name='输入参数')),
|
||||
('outputs', django_mysql.models.JSONField(default=dict, verbose_name='输出参数')),
|
||||
('process', models.ForeignKey(db_constraint=False, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='nodes', to='flow.Process')),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='ProcessRun',
|
||||
fields=[
|
||||
('process_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='flow.Process')),
|
||||
('state', models.CharField(max_length=32, verbose_name='工作流状态')),
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(max_length=255, verbose_name='作业名称')),
|
||||
('description', models.CharField(blank=True, max_length=255, null=True, verbose_name='作业描述')),
|
||||
('run_type', models.CharField(max_length=32, verbose_name='调度类型')),
|
||||
('gateways', django_mysql.models.JSONField(default=dict, verbose_name='网关信息')),
|
||||
('constants', django_mysql.models.JSONField(default=dict, verbose_name='内部变量信息')),
|
||||
('dag', django_mysql.models.JSONField(default=dict, verbose_name='DAG')),
|
||||
('create_by', models.CharField(max_length=64, null=True, verbose_name='创建者')),
|
||||
('create_time', models.DateTimeField(default=datetime.datetime.now, verbose_name='创建时间')),
|
||||
('update_time', models.DateTimeField(auto_now=True, verbose_name='修改时间')),
|
||||
('update_by', models.CharField(max_length=64, null=True, verbose_name='修改人')),
|
||||
('root_id', models.CharField(max_length=255, verbose_name='根节点uuid')),
|
||||
('process', models.ForeignKey(db_constraint=False, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='run', to='flow.Process')),
|
||||
],
|
||||
bases=('flow.process',),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='NodeRun',
|
||||
@@ -101,4 +83,30 @@ class Migration(migrations.Migration):
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Node',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(max_length=255, verbose_name='节点名称')),
|
||||
('uuid', models.CharField(max_length=255, unique=True, verbose_name='UUID')),
|
||||
('description', models.CharField(blank=True, max_length=255, null=True, verbose_name='节点描述')),
|
||||
('show', models.BooleanField(default=True, verbose_name='是否显示')),
|
||||
('top', models.IntegerField(default=300)),
|
||||
('left', models.IntegerField(default=300)),
|
||||
('ico', models.CharField(blank=True, max_length=64, null=True, verbose_name='icon')),
|
||||
('fail_retry_count', models.IntegerField(default=0, verbose_name='失败重试次数')),
|
||||
('fail_offset', models.IntegerField(default=0, verbose_name='失败重试间隔')),
|
||||
('fail_offset_unit', models.CharField(choices=[('seconds', '秒'), ('hours', '时'), ('minutes', '分')], max_length=32, verbose_name='重试间隔单位')),
|
||||
('node_type', models.IntegerField(default=2)),
|
||||
('component_code', models.CharField(max_length=255, verbose_name='插件名称')),
|
||||
('is_skip_fail', models.BooleanField(default=False, verbose_name='忽略失败')),
|
||||
('is_timeout_alarm', models.BooleanField(default=False, verbose_name='超时告警')),
|
||||
('inputs', django_mysql.models.JSONField(default=dict, verbose_name='输入参数')),
|
||||
('outputs', django_mysql.models.JSONField(default=dict, verbose_name='输出参数')),
|
||||
('process', models.ForeignKey(db_constraint=False, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='nodes', to='flow.Process')),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
]
|
||||
|
||||
Binary file not shown.
@@ -26,6 +26,17 @@ class Process(models.Model):
|
||||
update_time = models.DateTimeField("修改时间", auto_now=True)
|
||||
update_by = models.CharField("修改人", max_length=64, null=True)
|
||||
|
||||
@property
|
||||
def clone_data(self):
|
||||
return {
|
||||
"name": self.name,
|
||||
"description": self.description,
|
||||
"run_type": self.run_type,
|
||||
"gateways": self.gateways,
|
||||
"constants": self.constants,
|
||||
"dag": self.dag,
|
||||
}
|
||||
|
||||
|
||||
class BaseNode(models.Model):
|
||||
name = models.CharField("节点名称", max_length=255, blank=False, null=False)
|
||||
@@ -58,14 +69,30 @@ class Node(BaseNode):
|
||||
related_name="nodes")
|
||||
|
||||
|
||||
class ProcessRun(Process):
|
||||
class ProcessRun(models.Model):
|
||||
# new
|
||||
process = models.ForeignKey(Process, on_delete=models.SET_NULL, null=True, db_constraint=False,
|
||||
related_name="run")
|
||||
state = models.CharField("工作流状态", max_length=32)
|
||||
|
||||
name = models.CharField("作业名称", max_length=255, blank=False, null=False)
|
||||
description = models.CharField("作业描述", max_length=255, blank=True, null=True)
|
||||
run_type = models.CharField("调度类型", max_length=32)
|
||||
gateways = JSONField("网关信息", default=dict)
|
||||
constants = JSONField("内部变量信息", default=dict)
|
||||
dag = JSONField("DAG", default=dict)
|
||||
|
||||
create_by = models.CharField("创建者", max_length=64, null=True)
|
||||
create_time = models.DateTimeField("创建时间", default=datetime.now)
|
||||
update_time = models.DateTimeField("修改时间", auto_now=True)
|
||||
update_by = models.CharField("修改人", max_length=64, null=True)
|
||||
|
||||
root_id = models.CharField("根节点uuid", max_length=255)
|
||||
|
||||
|
||||
class NodeRun(BaseNode):
|
||||
process_run = models.ForeignKey(ProcessRun, on_delete=models.SET_NULL, null=True, db_constraint=False,
|
||||
related_name="nodes_run")
|
||||
|
||||
@staticmethod
|
||||
def field_names():
|
||||
return [field.name for field in NodeRun._meta.get_fields() if field.name not in ["id"]]
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
import json
|
||||
|
||||
from django.db import transaction
|
||||
from rest_framework import serializers
|
||||
from bamboo_engine import api
|
||||
from pipeline.eri.runtime import BambooDjangoRuntime
|
||||
|
||||
from applications.flow.models import Process, Node, ProcessRun
|
||||
from applications.flow.constants import PIPELINE_STATE_TO_FLOW_STATE
|
||||
from applications.flow.models import Process, Node, ProcessRun, NodeRun
|
||||
|
||||
|
||||
class ProcessViewSetsSerializer(serializers.Serializer):
|
||||
@@ -105,11 +110,6 @@ class RetrieveProcessViewSetsSerializer(serializers.ModelSerializer):
|
||||
class RetrieveProcessRunViewSetsSerializer(serializers.ModelSerializer):
|
||||
pipeline_tree = serializers.SerializerMethodField()
|
||||
|
||||
# category = serializers.SerializerMethodField()
|
||||
#
|
||||
# def get_category(self, obj):
|
||||
# return obj.category.all()
|
||||
|
||||
def get_pipeline_tree(self, obj):
|
||||
lines = []
|
||||
nodes = []
|
||||
@@ -119,16 +119,28 @@ class RetrieveProcessRunViewSetsSerializer(serializers.ModelSerializer):
|
||||
"from": _from,
|
||||
"to": _to
|
||||
})
|
||||
node_list = Node.objects.filter(process_id=obj.id).values()
|
||||
runtime = BambooDjangoRuntime()
|
||||
process_info = api.get_pipeline_states(runtime, root_id=obj.root_id)
|
||||
process_state = PIPELINE_STATE_TO_FLOW_STATE.get(process_info.data[obj.root_id]["state"])
|
||||
state_map = process_info.data[obj.root_id]["children"]
|
||||
node_list = NodeRun.objects.filter(process_run_id=obj.id).values()
|
||||
for node in node_list:
|
||||
pipeline_state = state_map.get(node["uuid"], {}).get("state", "READY")
|
||||
flow_state = PIPELINE_STATE_TO_FLOW_STATE[pipeline_state]
|
||||
outputs = ""
|
||||
if node["node_type"] not in [0, 1] and flow_state == "success":
|
||||
output_data = api.get_execution_data_outputs(runtime, node_id=node["uuid"])
|
||||
outputs = json.dumps(output_data.data["outputs"])
|
||||
nodes.append({"show": node["show"],
|
||||
"top": node["top"],
|
||||
"left": node["left"],
|
||||
"ico": node["ico"],
|
||||
"type": node["node_type"],
|
||||
"name": node["name"],
|
||||
"state": flow_state,
|
||||
"node_data": {
|
||||
"inputs": node["inputs"],
|
||||
"outputs": outputs,
|
||||
"run_mark": 0,
|
||||
"node_name": node["name"],
|
||||
"description": node["description"],
|
||||
@@ -138,11 +150,11 @@ class RetrieveProcessRunViewSetsSerializer(serializers.ModelSerializer):
|
||||
"is_skip_fail": node["is_skip_fail"],
|
||||
"is_timeout_alarm": node["is_timeout_alarm"]},
|
||||
"uuid": node["uuid"]})
|
||||
return {"lines": lines, "nodes": nodes}
|
||||
return {"lines": lines, "nodes": nodes, "process_state": process_state}
|
||||
|
||||
class Meta:
|
||||
model = ProcessRun
|
||||
fields = ("id", "name", "description", "category", "run_type", "pipeline_tree")
|
||||
fields = ("id", "name", "description", "run_type", "pipeline_tree")
|
||||
|
||||
|
||||
class ExecuteProcessSerializer(serializers.Serializer):
|
||||
|
||||
@@ -3,5 +3,5 @@ from rest_framework.routers import DefaultRouter
|
||||
from . import views
|
||||
|
||||
flow_router = DefaultRouter()
|
||||
flow_router.register(r"", viewset=views.ProcessViewSets, base_name="flow")
|
||||
flow_router.register(r"flow", viewset=views.ProcessViewSets, base_name="flow")
|
||||
flow_router.register(r"run", viewset=views.ProcessRunViewSets, base_name="run")
|
||||
|
||||
@@ -6,17 +6,18 @@ from rest_framework import mixins
|
||||
from rest_framework.decorators import action
|
||||
from rest_framework.response import Response
|
||||
|
||||
from applications.flow.models import Process, Node, ProcessRun
|
||||
from applications.flow.models import Process, Node, ProcessRun, NodeRun
|
||||
from applications.flow.serializers import ProcessViewSetsSerializer, ListProcessViewSetsSerializer, \
|
||||
RetrieveProcessViewSetsSerializer, ExecuteProcessSerializer, ListProcessRunViewSetsSerializer, \
|
||||
RetrieveProcessRunViewSetsSerializer
|
||||
from applications.utils.dag_helper import DAG
|
||||
from applications.utils.dag_helper import DAG, instance_dag
|
||||
from component.drf.viewsets import GenericViewSet
|
||||
|
||||
|
||||
class ProcessViewSets(mixins.ListModelMixin,
|
||||
mixins.CreateModelMixin,
|
||||
mixins.RetrieveModelMixin,
|
||||
mixins.DestroyModelMixin,
|
||||
GenericViewSet):
|
||||
queryset = Process.objects.order_by("-update_time")
|
||||
|
||||
@@ -38,8 +39,10 @@ class ProcessViewSets(mixins.ListModelMixin,
|
||||
dag_obj = DAG()
|
||||
dag_obj.from_dict(process.dag)
|
||||
topological_sort = dag_obj.topological_sort()
|
||||
start = pipeline_tree = EmptyStartEvent()
|
||||
|
||||
start = pipeline_tree = EmptyStartEvent()
|
||||
# 运行实例的uuid
|
||||
process_run_uuid = {topological_sort[0]: start.id}
|
||||
for pipeline_id in topological_sort[1:]:
|
||||
if node_map[pipeline_id].node_type == 0:
|
||||
act = EmptyStartEvent()
|
||||
@@ -47,12 +50,24 @@ class ProcessViewSets(mixins.ListModelMixin,
|
||||
act = EmptyEndEvent()
|
||||
else:
|
||||
act = ServiceActivity(component_code="http_request")
|
||||
act.component.inputs.inputs = Var(type=Var.PLAIN, value=node_map[pipeline_id].inputs)
|
||||
process_run_uuid[pipeline_id] = act.id
|
||||
pipeline_tree = getattr(pipeline_tree, "extend")(act)
|
||||
|
||||
pipeline_data = Data()
|
||||
pipeline = builder.build_tree(start, data=pipeline_data)
|
||||
runtime = BambooDjangoRuntime()
|
||||
api.run_pipeline(runtime=runtime, pipeline=pipeline)
|
||||
|
||||
process_run_data = process.clone_data
|
||||
process_run_data["dag"] = instance_dag(process_run_data["dag"], process_run_uuid)
|
||||
process_run = ProcessRun.objects.create(process_id=process.id, root_id=pipeline["id"], **process_run_data)
|
||||
node_run_bulk = []
|
||||
for pipeline_id, node in node_map.items():
|
||||
_node = {k: v for k, v in node.__dict__.items() if k in NodeRun.field_names()}
|
||||
_node["uuid"] = process_run_uuid[pipeline_id]
|
||||
node_run_bulk.append(NodeRun(process_run=process_run, **_node))
|
||||
NodeRun.objects.bulk_create(node_run_bulk, batch_size=500)
|
||||
return Response({})
|
||||
|
||||
|
||||
|
||||
Binary file not shown.
@@ -191,6 +191,14 @@ class DAG(object):
|
||||
return len(self.graph)
|
||||
|
||||
|
||||
def instance_dag(dag_dict, process_run_uuid):
|
||||
new_dag_dict = defaultdict(list)
|
||||
for k, v_list in dag_dict.items():
|
||||
for v in v_list:
|
||||
new_dag_dict[process_run_uuid[k]].append(process_run_uuid[v])
|
||||
return dict(new_dag_dict)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
dag = DAG()
|
||||
dag.add_node("a")
|
||||
|
||||
Binary file not shown.
@@ -5,6 +5,7 @@ from pipeline.component_framework.component import Component
|
||||
import json
|
||||
import eventlet
|
||||
import time
|
||||
|
||||
requests = eventlet.import_patched('requests')
|
||||
|
||||
|
||||
@@ -12,9 +13,33 @@ class HttpRequestService(Service):
|
||||
__need_schedule__ = False
|
||||
|
||||
def execute(self, data, parent_data):
|
||||
print("执行了")
|
||||
time.sleep(5)
|
||||
return True
|
||||
try:
|
||||
inputs = data.get_one_of_inputs("inputs")
|
||||
headers = self.parse_headers(inputs["header"])
|
||||
inputs["body"] = json.loads(inputs["body"])
|
||||
req_data = [{"params": inputs["body"]}, {"json": inputs["body"]}][inputs["method"] != "get"]
|
||||
res = requests.request(inputs["method"], url=inputs["url"], headers=headers, timeout=inputs["timeout"],
|
||||
**req_data).content
|
||||
print("执行了", res)
|
||||
res = json.loads(res)
|
||||
data.outputs.outputs = res
|
||||
time.sleep(5)
|
||||
return True
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
def parse_headers(self, headers):
|
||||
return {header["key"]: header["value"] for header in headers if header["key"]}
|
||||
|
||||
def inputs_format(self):
|
||||
return [
|
||||
Service.InputItem(name="输入参数", key="inputs", type="dict", required=True)
|
||||
]
|
||||
|
||||
def outputs_format(self):
|
||||
return [
|
||||
Service.OutputItem(name="输出参数", key="outputs", type="dict", required=True)
|
||||
]
|
||||
|
||||
|
||||
class HttpRequestComponent(Component):
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -1,4 +1,3 @@
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
||||
@@ -108,15 +107,11 @@ AUTH_PASSWORD_VALIDATORS = [
|
||||
},
|
||||
]
|
||||
|
||||
LANGUAGE_CODE = 'en-us'
|
||||
|
||||
TIME_ZONE = 'UTC'
|
||||
|
||||
USE_I18N = True
|
||||
|
||||
USE_L10N = True
|
||||
|
||||
USE_TZ = True
|
||||
USE_TZ = False
|
||||
|
||||
STATIC_URL = '/static/'
|
||||
|
||||
@@ -144,3 +139,7 @@ REST_FRAMEWORK = {
|
||||
"DATETIME_FORMAT": "%Y-%m-%d %H:%M:%S",
|
||||
"NON_FIELD_ERRORS_KEY": "params_error",
|
||||
}
|
||||
|
||||
# 本地调试
|
||||
# CELERY_ALWAYS_EAGER = True
|
||||
# CELERY_TASK_ALWAYS_EAGER = True
|
||||
@@ -3,7 +3,7 @@
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<title>调度平台</title>
|
||||
<title>任务调度平台</title>
|
||||
<link href="{{ STATIC_URL }}dist/css/app.css" rel="stylesheet">
|
||||
<link href="{{ STATIC_URL }}img/{{ APP_CODE }}.png" rel="shortcut icon" type="image/x-icon">
|
||||
</head>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<head>
|
||||
<meta charset=utf-8>
|
||||
<meta name=viewport content="width=device-width,initial-scale=1">
|
||||
<title>调度平台</title>
|
||||
<title>任务调度平台</title>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
<!DOCTYPE html><html><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><title>调度平台</title><link href=./static/dist/css/app.css rel=stylesheet></head><body><script>window.siteUrl = "http://dev.cwbk.com:8000"
|
||||
<!DOCTYPE html><html><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><title>任务调度平台</title><link href=./static/dist/css/app.css rel=stylesheet></head><body><script>window.siteUrl = "http://dev.cwbk.com:8000"
|
||||
window.APP_CODE = 'run-batch';
|
||||
window.CSRF_COOKIE_NAME = 'run-batch_csrftoken'</script><div id=app></div><script type=text/javascript src=./static/dist/js/manifest.js></script><script type=text/javascript src=./static/dist/js/vendor.js></script><script type=text/javascript src=./static/dist/js/app.js></script></body></html>
|
||||
|
||||
@@ -3,25 +3,25 @@ import {GET, POST, PUT, DELETE, reUrl} from '../../axiosconfig/axiosconfig'
|
||||
export default {
|
||||
// 作业台
|
||||
list: function(params) {
|
||||
return GET(reUrl + '/process/', params)
|
||||
return GET(reUrl + '/process/flow/', params)
|
||||
},
|
||||
create: function(params) {
|
||||
return POST(reUrl + '/process/', params)
|
||||
return POST(reUrl + '/process/flow/', params)
|
||||
},
|
||||
retrieve: function(id) {
|
||||
return GET(reUrl + '/process/' + JSON.stringify(id) + '/')
|
||||
return GET(reUrl + '/process/flow/' + JSON.stringify(id) + '/')
|
||||
},
|
||||
update: function(id, params) {
|
||||
return PUT(reUrl + '/process/' + JSON.stringify(id) + '/', params)
|
||||
return PUT(reUrl + '/process/flow/' + JSON.stringify(id) + '/', params)
|
||||
},
|
||||
clone: function(params) {
|
||||
return POST(reUrl + '/process/clone/', params)
|
||||
},
|
||||
delete: function(id) {
|
||||
return DELETE(reUrl + '/process/' + JSON.stringify(id) + '/')
|
||||
return DELETE(reUrl + '/process/flow/' + JSON.stringify(id) + '/')
|
||||
},
|
||||
execute: function(params) {
|
||||
return POST(reUrl + '/process/execute/', params)
|
||||
return POST(reUrl + '/process/flow/execute/', params)
|
||||
},
|
||||
get_process_node: function(params) {
|
||||
return GET(reUrl + '/process/get_process_node/', params)
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
title: '调度平台',
|
||||
title: '任务调度平台',
|
||||
headerTitle: '',
|
||||
imgSrc: '',
|
||||
}
|
||||
|
||||
@@ -66,6 +66,7 @@
|
||||
},
|
||||
initEditor() {
|
||||
// 初始化编辑器,确保dom已经渲染
|
||||
console.log(this.codes)
|
||||
this.monacoEditor = monaco.editor.create(this.$refs.codeEditor, {
|
||||
value: this.codes, //编辑器初始显示文字
|
||||
language: this.language, //语言支持自行查阅demo
|
||||
|
||||
@@ -205,7 +205,7 @@
|
||||
setting: {
|
||||
size: 'small', // 表格大小
|
||||
fields: fields, // 表格所有列
|
||||
selectedFields: fields.slice(0, 8) // 表格当前显示列
|
||||
selectedFields: fields.slice(0, 1) // 表格当前显示列
|
||||
},
|
||||
opreateFlag: false,
|
||||
midSearchForm: {},
|
||||
|
||||
@@ -4,53 +4,76 @@
|
||||
<div class="box">
|
||||
<p class="title">基本信息</p>
|
||||
<div class="info">
|
||||
<bk-form ref="form" :label-width="144">
|
||||
<bk-form-item label="开始时间:">
|
||||
<span>{{form.nodeData.eta}}</span>
|
||||
<bk-form ref="form" :label-width="144" :model="form">
|
||||
<bk-form-item label="节点名称:" :required="true" :error-display-type="'normal'" :property="'node_name'">
|
||||
<bk-input v-model="form.node_name" type="text" style="width: 350px;margin-right: 9px;" :disabled="disabled"></bk-input>
|
||||
</bk-form-item>
|
||||
<bk-form-item label="执行前人工复核:">
|
||||
<span v-if="form.nodeData.need_confirm === 0">无</span>
|
||||
<span v-else-if="form.nodeData.need_confirm === 1">单人复核</span>
|
||||
<span v-else-if="form.nodeData.need_confirm === 2">双人复核</span>
|
||||
<bk-form-item label="运行标志:" :required="true" :error-display-type="'normal'" :property="'run_mark'">
|
||||
<bk-radio-group v-model="form.run_mark">
|
||||
<bk-radio :value="item.value" v-for="(item, index) in reviewList" :key="index" style="margin-right: 24px;"
|
||||
:disabled="disabled">
|
||||
{{item.label}}
|
||||
</bk-radio>
|
||||
</bk-radio-group>
|
||||
</bk-form-item>
|
||||
<bk-form-item label="执行后自动暂停:">
|
||||
<bk-switcher v-model="form.nodeData.is_book_pause" theme="primary" :disabled="disabled"></bk-switcher>
|
||||
<bk-form-item label="描述:">
|
||||
<bk-input v-model="form.description" type="textarea" style="width: 350px;margin-right: 9px;" :disabled="disabled" :min="0"></bk-input>
|
||||
</bk-form-item>
|
||||
<bk-form-item label="执行时长告警:">
|
||||
<bk-form-item label="失败重试次数:" :required="true" :error-display-type="'normal'" :property="'fail_retry_count'">
|
||||
<bk-input v-model="form.fail_retry_count" type="number" style="width: 350px;margin-right: 9px;" :disabled="disabled" :min="0"></bk-input>
|
||||
</bk-form-item>
|
||||
<bk-form-item label="失败重试间隔:">
|
||||
<bk-compose-form-item>
|
||||
<span>{{form.nodeData.alarm_policy.duration.period}}</span>
|
||||
<span>{{getUnit1}}</span>
|
||||
<span v-if="form.nodeData.alarm_policy.duration.period && getUnit1">产生告警</span>
|
||||
<bk-input v-model="form.fail_offset" type="number" style="width: 139px;margin-right: 9px;"
|
||||
:disabled="disabled" :min="0"></bk-input>
|
||||
<bk-select :clearable="true" style="background-color: #fff;width: 138px;margin-right: 14px;"
|
||||
v-model="form.fail_offset_unit" placeholder="请选择" :disabled="disabled">
|
||||
<bk-option v-for="(item, index) in timeTypeList" :key="index" :id="item.value"
|
||||
:name="item.label">
|
||||
</bk-option>
|
||||
</bk-select>
|
||||
<span>产生重试</span>
|
||||
</bk-compose-form-item>
|
||||
</bk-form-item>
|
||||
<bk-form-item label="执行时间点告警:">
|
||||
<span style="margin-right: 12px;" v-if="form.nodeData.alarm_policy.time_point">时间点超过</span>
|
||||
<span>{{form.nodeData.alarm_policy.time_point}}</span>
|
||||
<span v-if="form.nodeData.alarm_policy.time_point">产生告警</span>
|
||||
<bk-form-item label="忽略失败:">
|
||||
<bk-switcher v-model="form.is_skip_fail" :disabled="disabled"></bk-switcher>
|
||||
</bk-form-item>
|
||||
<bk-form-item label="前置文件路径:">
|
||||
<span>{{form.nodeData.file_dependence.file_path}}</span>
|
||||
<bk-form-item label="超时告警:">
|
||||
<bk-switcher v-model="form.is_timeout_alarm" :disabled="disabled"></bk-switcher>
|
||||
</bk-form-item>
|
||||
<bk-form-item label="巡检次数:">
|
||||
<span>{{form.nodeData.file_dependence.max_num}}</span>
|
||||
<bk-divider style="width: 540px;position: relative;right: 20px;border-color: #dcdee5;"></bk-divider>
|
||||
<p class="title">输入参数</p>
|
||||
<bk-form-item label="请求地址:">
|
||||
<bk-input v-model="form.inputs.url" type="textarea" style="width: 350px;margin-right: 9px;" :disabled="disabled" :min="0"></bk-input>
|
||||
</bk-form-item>
|
||||
<bk-form-item label="巡检周期:">
|
||||
<span>{{form.nodeData.file_dependence.cycle.value}}</span>
|
||||
<span>{{getUnit2}}</span>
|
||||
<bk-form-item label="请求类型:">
|
||||
<bk-select :clearable="true" style="background-color: #fff;width: 130px;margin-right: 14px;" v-model="form.inputs.method" placeholder="请选择" :disabled="disabled">
|
||||
<bk-option v-for="(item, index) in requestTypeList" :key="index" :id="item.value" :name="item.label">
|
||||
</bk-option>
|
||||
</bk-select>
|
||||
</bk-form-item>
|
||||
<bk-form-item label="前置条件检测命令:">
|
||||
<div v-for="(item, index) in form.nodeData.pre_commands" class="pre-commands" :key="index"
|
||||
style="margin-bottom: 12px;">
|
||||
<span>{{item.key}}</span>
|
||||
<bk-form-item label="Header:">
|
||||
<div v-for="(item, index) in form.inputs.header" class="pre-commands" :key="index" style="margin-bottom: 12px;">
|
||||
<bk-compose-form-item>
|
||||
<bk-input v-model="item.key" type="text" style="width: 130px;margin-right: 9px;" :disabled="disabled" :min="0"></bk-input>
|
||||
<bk-input v-model="item.value" type="text" style="width: 130px;margin-right: 9px;" :disabled="disabled" :min="0"></bk-input>
|
||||
</bk-compose-form-item>
|
||||
<i class="iconfont icon-changyongtubiao-chahao btn" style="margin-left: 8px;" @click="handleDeleteCommand(index)"
|
||||
v-if="!disabled && form.inputs.header.length > 1"></i>
|
||||
<i class="iconfont icon-changyongtubiao-jiahao btn" @click="handleAddCommand" v-if="!disabled"></i>
|
||||
</div>
|
||||
</bk-form-item>
|
||||
<bk-form-item label="状态:">{{statusList[statusList.findIndex(item => item.key === form.state)].label}}</bk-form-item>
|
||||
<bk-form-item label="执行时间:">{{form.start_time}}</bk-form-item>
|
||||
<bk-form-item label="结束时间:">{{form.end_time}}</bk-form-item>
|
||||
<bk-form-item label="执行脚本:">
|
||||
<editor :height="'200px'" ref="editor" :codes="form.script_content" :read-only="true" :language="'shell'"></editor>
|
||||
<bk-form-item label="Body:">
|
||||
<bk-input v-model="form.inputs.body" type="textarea" style="width: 350px;margin-right: 9px;" :disabled="disabled" :min="0"></bk-input>
|
||||
</bk-form-item>
|
||||
<bk-form-item label="超时时间:">
|
||||
<bk-input v-model="form.inputs.timeout" type="number" style="width: 350px;margin-right: 9px;" :disabled="disabled" :min="0"></bk-input>
|
||||
</bk-form-item>
|
||||
<bk-divider style="width: 540px;position: relative;right: 20px;border-color: #dcdee5;"></bk-divider>
|
||||
<p class="title">输出结果</p>
|
||||
<bk-form-item label="输出日志:">
|
||||
<editor :height="'200px'" ref="editor" :codes="form.outputs" :read-only="true" :language="'shell'"></editor>
|
||||
</bk-form-item>
|
||||
<bk-form-item label="执行日志:">{{form.log}}</bk-form-item>
|
||||
</bk-form>
|
||||
</div>
|
||||
</div>
|
||||
@@ -72,8 +95,9 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import editor from '@/components/monacoEditor'
|
||||
import statusList from './statusList.js'
|
||||
import editor from '@/components/monacoEditor'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
editor
|
||||
@@ -111,19 +135,43 @@
|
||||
label: '双人复核',
|
||||
value: 2
|
||||
}],
|
||||
timeTypeList1: [{ // 执行时长告警时间类型下拉列表
|
||||
value: 'hours',
|
||||
label: '时'
|
||||
},
|
||||
{
|
||||
value: 'minutes',
|
||||
label: '分'
|
||||
timeTypeList: [
|
||||
{ // 执行时长告警时间类型下拉列表
|
||||
value: 'hours',
|
||||
label: '时'
|
||||
},
|
||||
{
|
||||
value: 'minutes',
|
||||
label: '分'
|
||||
|
||||
},
|
||||
{
|
||||
value: 'seconds',
|
||||
label: '秒'
|
||||
}
|
||||
},
|
||||
{
|
||||
value: 'seconds',
|
||||
label: '秒'
|
||||
}
|
||||
],
|
||||
requestTypeList: [
|
||||
{
|
||||
value: 'get',
|
||||
label: 'GET'
|
||||
},
|
||||
{
|
||||
value: 'post',
|
||||
label: 'POST'
|
||||
|
||||
},
|
||||
{
|
||||
value: 'put',
|
||||
label: 'PUT'
|
||||
},
|
||||
{
|
||||
value: 'head',
|
||||
label: 'HEAD'
|
||||
},
|
||||
{
|
||||
value: 'delete',
|
||||
label: 'DELETE'
|
||||
}
|
||||
],
|
||||
form: {
|
||||
nodeData: {
|
||||
@@ -169,28 +217,11 @@
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.form.nodeData = this.nodeData.data
|
||||
if (!Object.keys(this.form.nodeData.file_dependence).length) {
|
||||
this.form.nodeData.file_dependence = {
|
||||
file_path: '', // 前置文件路径
|
||||
max_num: '', // 巡检次数
|
||||
cycle: { // 巡检周期
|
||||
type: '', // 时间类型
|
||||
value: '' // 时间值
|
||||
}
|
||||
}
|
||||
}
|
||||
this.form.log = this.nodeData.log
|
||||
this.form = this.nodeData.data
|
||||
this.form.state = this.nodeData.state
|
||||
this.form.start_time = this.nodeData.start_time
|
||||
this.form.end_time = this.nodeData.end_time
|
||||
this.form.script_content = this.nodeData.script_content
|
||||
if (this.form.nodeData.pre_commands.length === 0) {
|
||||
this.form.pre_commands = [{ // 命令前置依赖检测
|
||||
key: '',
|
||||
value: ''
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -87,7 +87,6 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import editor from '@/components/monacoEditor'
|
||||
import {
|
||||
deepClone, getUUID
|
||||
} from '../../../common/util.js'
|
||||
@@ -95,6 +94,7 @@
|
||||
import G6 from '@antv/g6'
|
||||
import statusList from './job_flow_view_detail/statusList.vue'
|
||||
import nodeInfo from './job_flow_view_detail/nodeInfo.vue'
|
||||
import editor from '@/components/monacoEditor'
|
||||
export default {
|
||||
components: {
|
||||
statusList,
|
||||
@@ -216,7 +216,7 @@
|
||||
this.timer = setInterval(() => {
|
||||
// 不需要清空画布,非首屏刷新
|
||||
this.handleLoad(false, false)
|
||||
}, 15000)
|
||||
}, 3000)
|
||||
window.addEventListener('resize', this.handleChangeCavasSize, false)
|
||||
},
|
||||
beforeDestroy() {
|
||||
@@ -595,6 +595,10 @@
|
||||
}
|
||||
// this.nodeDrawer.show = false
|
||||
this.renderCanvas(true, first)
|
||||
const processState = res.data.pipeline_tree.process_state
|
||||
if (processState === 'success') {
|
||||
clearInterval(this.timer)
|
||||
}
|
||||
} else {
|
||||
this.$cwMessage(res.message, 'error')
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user