Commit 9747d75b authored by 刘殿昕's avatar 刘殿昕

四个缺省页,二级菜单,超管router,流程!流程!流程!

parent 7d09c890
......@@ -38,5 +38,8 @@ export const lang = {
online_component_tool: "在线组件中心",
process_design: "流程设计",
process_management: "流程管理",
new: "新建"
new: "新建",
// technical-support
technical_support: "技术支持"
}
\ No newline at end of file
<template>
<div class="side_nav_bar">
<h3 class="side_nav_bar_title" @click="titleAction">
<img :src="titleIcon" width="20" style="margin-right: 10px;" />
<span v-text="title"></span>
</h3>
<div v-for="(nav, index) in navList" :key="'nav' + index">
<div class="side_nav_bar_first_title">{{ nav.name }}</div>
<ul class="side_nav_bar_list">
<router-link
tag="li"
v-for="(item, indexs) in nav.child"
:class="{ current: $route.path.indexOf(item.path) > -1 }"
:key="index + 'a' + indexs"
:to="item.path"
>
<span v-text="item.name"></span>
</router-link>
</ul>
</div>
</div>
</template>
<script>
export default {
name: "sideNavBar",
props: {
title: {
type: String,
default: () => "我的服务",
},
titleIcon: {
type: String,
default: () => require("@/assets/imgs/tool_fuwu.png"),
},
titlePath: {
type: String,
default: () => "",
},
navList: {
type: Array,
default: () => [],
},
imgSrc: {
type: String,
default: "tool_fuwu",
},
},
methods: {
titleAction() {
if (this.titlePath) {
this.$router.push(this.titlePath);
}
},
},
};
</script>
<style scoped>
.side_nav_bar {
background-color: #0d1847;
}
.side_nav_bar_title {
height: 40px;
background-color: #182665;
border-radius: 10px;
overflow: hidden;
margin: 20px 15px 20px;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
}
.side_nav_bar_title > span {
font-size: 16px;
color: #c3caf8;
}
.side_nav_bar_first_title {
color: #c3caf8;
font-size: 14px;
padding: 10px 0 10px 34px;
position: relative;
}
.side_nav_bar_first_title::before {
content: "";
position: absolute;
left: 22px;
top: 12px;
width: 4px;
height: 16px;
background-color: #515fe7;
border-radius: 2px;
}
.side_nav_bar_list > li {
padding: 12px 10px 12px 42px;
border-left: 5px solid #0d1847;
font-size: 14px;
line-height: 24px;
color: #e6ebfe;
cursor: pointer;
}
.side_nav_bar_list > li:hover,
.side_nav_bar_list > li.current {
border-left: 5px solid #e56600;
background-color: #182665;
color: #e6ebfe;
}
</style>
......@@ -329,7 +329,6 @@ export default {
for (let i = 0; i < val.length; i++) {
this.filterLists[i + 1].name = val[i];
}
console.log(this.filterLists);
},
},
},
......
......@@ -14,16 +14,37 @@
<div class="node-container">
<p class="label_head">节点类型</p>
<p class="label_explanation">请拖拽添加到流程中</p>
<div class="node-item" :class="{'node-item-begin': item.value.meta.type == 1, 'node-item-end': item.value.meta.type == 2, 'node-item-default': item.value.meta.type == 3}" v-for="(item, index) in nodeItemList" :key="index" @mousedown="evt => nodeItemMouseDown(evt, item.value)">
<div
class="node-item"
:class="{'node-item-begin': item.value.meta.type == 1, 'node-item-end': item.value.meta.type == 2, 'node-item-default': item.value.meta.type == 3}"
v-for="(item, index) in nodeItemList"
:key="index"
@mousedown="evt => nodeItemMouseDown(evt, item.value)"
>
<span>{{item.label}}</span>
</div>
</div>
</div>
<div class="flow-container" ref="flowContainer">
<super-flow ref="superFlow" :node-list="nodeList" :link-list="linkList" :link-menu="linkMenu" line-color="#c4d8f8" onLineColor="#94a8c8" :origin="origin">
<super-flow
ref="superFlow"
:node-list="nodeList"
:link-list="linkList"
:link-menu="linkMenu"
line-color="#c4d8f8"
onLineColor="#94a8c8"
:origin="origin"
>
<template v-slot:node="{meta}">
<div :class="{'flow-node-begin': nodeParams(meta.id).type == 1, 'flow-node-end': nodeParams(meta.id).type == 2, 'flow-node-default': nodeParams(meta.id).type == 3 && meta.id != nodeItem.id, 'flow-node-default-active': nodeParams(meta.id).type == 3 && meta.id == nodeItem.id }" :id="meta.id">
<div class="node_span" @click="clickItem(meta.id)" @blur="blurItem">{{nodeParams(meta.id).name}}</div>
<div
:class="{'flow-node-begin': nodeParams(meta.id).type == 1, 'flow-node-end': nodeParams(meta.id).type == 2, 'flow-node-default': nodeParams(meta.id).type == 3 && meta.id != nodeItem.id, 'flow-node-default-active': nodeParams(meta.id).type == 3 && meta.id == nodeItem.id }"
:id="meta.id"
>
<div
class="node_span"
@click="clickItem(meta.id)"
@blur="blurItem"
>{{nodeParams(meta.id).name}}</div>
</div>
</template>
</super-flow>
......@@ -52,11 +73,23 @@
</div>
</div>
</div>
<div v-if="nodeParams(nodeItem.id).plugins && nodeParams(nodeItem.id).plugins.length > 0">
<div class="checked_line"></div>
</div>
<el-dialog :visible.sync="dialog_general" top="25vh" width="420px" :modal-append-to-body="false" title="常规设置" :close-on-click-modal="false">
</div>
<el-dialog
:visible.sync="dialog_general"
top="25vh"
width="420px"
:modal-append-to-body="false"
title="常规设置"
:close-on-click-modal="false"
>
<div class="general_settings">
<p class="general_title">节点编号:</p>
<p class="general_val">{{ nodeParams(nodeItem.id).node_code }}</p>
<p
class="general_val"
>{{ nodeParams(nodeItem.id).node_code == "暂无(保存后将自动生成节点编号)" ? "" : nodeParams(nodeItem.id).node_code }}</p>
<p class="general_title">节点名称:</p>
<p class="general_input">
<el-input v-model="node_name" placeholder="请输入节点名称"></el-input>
......@@ -67,7 +100,14 @@
</div>
</div>
</el-dialog>
<el-dialog :visible.sync="dialog_interface" top="25vh" width="80vw" :modal-append-to-body="false" title="接口插件" :close-on-click-modal="false">
<el-dialog
:visible.sync="dialog_interface"
top="25vh"
width="80vw"
:modal-append-to-body="false"
title="接口插件"
:close-on-click-modal="false"
>
<div class="interface_plugin">
<div class="interface_msg">
<i class="el-icon-warning-outline"></i>
......@@ -76,16 +116,46 @@
<div class="interface_plugin_item">
<div class="fwcs_fwdz">服务地址:</div>
<div class="fwcs_fwdz_inner">
<el-input placeholder="请输入内容" @input="getUrl" v-model="serviceUrl" class="input-with-select">
<el-input
placeholder="请输入内容"
@input="getUrl"
v-model="serviceUrl"
class="input-with-select"
>
<el-select v-model="select" slot="prepend" placeholder="请选择">
<el-option v-for="item in optionType" :key="item.value" :label="item.label" :value="item.value"></el-option>
<el-option
v-for="item in optionType"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
</el-input>
<el-button @click="clickFwcs()" class="fwcs_btn_fwcs">连接测试</el-button>
</div>
<el-tabs v-model="activeName" class="fwcs_tabs" @tab-click="clickTab">
<el-tab-pane label="请求参数" name="0">
<CesTable ref="fwcs_sjfw_qq" size="mini" :border="true" :headers="sjfwQqcs" url :datas="datasSj" :searchShow="false" :addRowBtn="false" :autoAdd="true" :isDialog="false" :isSelection="false" :isIndex="true" :radius="true" :emptyText="emptyText" :stripe="false" :paginationShow="false" :pageSizeShow="false" headerCellClassName="th_pink" @changeTable="changeTable"></CesTable>
<CesTable
ref="fwcs_sjfw_qq"
size="mini"
:border="true"
:headers="sjfwQqcs"
url
:datas="datasSj"
:searchShow="false"
:addRowBtn="false"
:autoAdd="true"
:isDialog="false"
:isSelection="false"
:isIndex="true"
:radius="true"
:emptyText="emptyText"
:stripe="false"
:paginationShow="false"
:pageSizeShow="false"
headerCellClassName="th_pink"
@changeTable="changeTable"
></CesTable>
</el-tab-pane>
<el-tab-pane label="请求体" name="1">
<div class="sjfw_qqt">
......@@ -100,7 +170,12 @@
<el-col :span="6">
<div class="sqxx_title">授权方式:</div>
<el-select v-model="sqfsVal" placeholder="请选择" class="sqxx_select">
<el-option v-for="item in optionsSq" :key="item.value" :label="item.label" :value="item.value"></el-option>
<el-option
v-for="item in optionsSq"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
</el-col>
<el-col :span="2" class="center_line_c">
......@@ -116,9 +191,47 @@
<div v-show="resultShow && resSuccess" class="add_params">
<div class="split_line"></div>
<div class="sjfw_qqcstx">请求参数信息填写:</div>
<CesTable ref="fwcs_sjfw_qqcs" size="mini" :border="true" :headers="sjfwQqcstx" url :datas="datasQqcs" :searchShow="false" :addRowBtn="false" :autoAdd="false" :isDialog="false" :isSelection="false" :isIndex="true" :radius="true" :emptyText="emptyText" :stripe="false" :paginationShow="false" :pageSizeShow="false" headerCellClassName="th_pink"></CesTable>
<CesTable
ref="fwcs_sjfw_qqcs"
size="mini"
:border="true"
:headers="sjfwQqcstx"
url
:datas="datasQqcs"
:searchShow="false"
:addRowBtn="false"
:autoAdd="false"
:isDialog="false"
:isSelection="false"
:isIndex="true"
:radius="true"
:emptyText="emptyText"
:stripe="false"
:paginationShow="false"
:pageSizeShow="false"
headerCellClassName="th_pink"
></CesTable>
<div class="sjfw_fhcstx">返回参数信息填写:</div>
<CesTable ref="fwcs_sjfw_fhcs" size="mini" :border="true" :headers="sjfwFhcstx" url :datas="datasFhcs" :searchShow="false" :addRowBtn="false" :autoAdd="false" :isDialog="false" :isSelection="false" :isIndex="true" :radius="true" :emptyText="emptyText" :stripe="false" :paginationShow="false" :pageSizeShow="false" headerCellClassName="th_pink"></CesTable>
<CesTable
ref="fwcs_sjfw_fhcs"
size="mini"
:border="true"
:headers="sjfwFhcstx"
url
:datas="datasFhcs"
:searchShow="false"
:addRowBtn="false"
:autoAdd="false"
:isDialog="false"
:isSelection="false"
:isIndex="true"
:radius="true"
:emptyText="emptyText"
:stripe="false"
:paginationShow="false"
:pageSizeShow="false"
headerCellClassName="th_pink"
></CesTable>
</div>
<div v-show="resultShow && !resSuccess">
<div class="skfw_csfwxx">测试服务信息:</div>
......@@ -135,7 +248,14 @@
</div>
</div>
</el-dialog>
<el-dialog :visible.sync="dialog_process" top="25vh" width="500px" :modal-append-to-body="false" title="流程服务" :close-on-click-modal="false">
<el-dialog
:visible.sync="dialog_process"
top="25vh"
width="600px"
:modal-append-to-body="false"
title="流程服务"
:close-on-click-modal="false"
>
<div class="process_service">
<div class="process_msg">
<i class="el-icon-warning-outline"></i>
......@@ -149,11 +269,18 @@
</p>
<div class="dia_footer">
<el-button class="cancel" @click="processCancel">取消</el-button>
<el-button class="submit" @click="processSubmit">确定</el-button>
<el-button class="submit" @click="processSubmit">添加</el-button>
</div>
</div>
</el-dialog>
<el-dialog :visible.sync="dialog_timeout" top="25vh" width="500px" :modal-append-to-body="false" title="超时管理" :close-on-click-modal="false">
<el-dialog
:visible.sync="dialog_timeout"
top="25vh"
width="600px"
:modal-append-to-body="false"
title="超时管理"
:close-on-click-modal="false"
>
<div class="timeout_service">
<div class="timeout_msg">
<i class="el-icon-warning-outline"></i>
......@@ -165,8 +292,13 @@
<div class="timeout_input_group">
<div class="input_left">最大时长</div>
<el-input-number v-model="max_time_0" controls-position="right" :min="0"></el-input-number>
<el-select v-model="max_time_type_0" class="input_right_select" placeholder="请选择申请时长">
<el-option v-for="item in durationOptions" :key="item.value" :label="item.label" :value="item.value"></el-option>
<el-select v-model="max_time_type_0" class="input_right_select" placeholder="请输入">
<el-option
v-for="item in durationOptions"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
</div>
<div class="timeout_check">
......@@ -179,12 +311,17 @@
<div class="timeout_input_group">
<div class="input_left">最大时长</div>
<el-input-number v-model="max_time_1" controls-position="right" :min="0"></el-input-number>
<el-select v-model="max_time_type_1" class="input_right_select" placeholder="请选择申请时长">
<el-option v-for="item in durationOptions" :key="item.value" :label="item.label" :value="item.value"></el-option>
<el-select v-model="max_time_type_1" class="input_right_select" placeholder="请输入">
<el-option
v-for="item in durationOptions"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
</div>
<div class="timeout_check">
<el-checkbox v-model="max_time_check_1">超时提醒</el-checkbox>
<el-checkbox v-model="max_time_check_1">超时终止流程</el-checkbox>
</div>
</div>
</div>
......@@ -202,12 +339,34 @@ import CesTable from "@/components/table/table-um";
import Codes from "@/components/general/codes";
const drawerType = {
node: 0,
link: 1
link: 1,
};
export default {
components: {
CesTable,
Codes
Codes,
},
props: {
node_list: {
type: Array,
default: () => [],
},
link_list: {
type: Array,
default: () => [],
},
node_params_list: {
type: Array,
default: () => [],
},
},
watch: {
node_list: {
handler(val) {
this.setVal();
},
deep: true,
},
},
data() {
return {
......@@ -248,14 +407,14 @@ export default {
} else {
this.$refs.linkSetting.clearValidate();
}
}
},
},
linkSetting: {
desc: ""
desc: "",
},
nodeSetting: {
name: "",
desc: ""
desc: "",
},
dragConf: {
isDown: false,
......@@ -265,7 +424,7 @@ export default {
clientX: 0,
clientY: 0,
ele: null,
info: null
info: null,
},
nodeItemList: [
{
......@@ -276,9 +435,9 @@ export default {
meta: {
label: "普通节点",
name: "普通节点",
type: 3
}
}
type: 3,
},
},
},
{
label: "开始",
......@@ -288,9 +447,9 @@ export default {
meta: {
label: "开始",
name: "开始",
type: 1
}
}
type: 1,
},
},
},
{
label: "结束",
......@@ -300,27 +459,27 @@ export default {
meta: {
label: "结束",
name: "结束",
type: 2
}
}
}
type: 2,
},
},
},
],
nodeParamsList: [],
linkMenu: [
[
{
label: "删除",
selected: link => {
selected: (link) => {
console.log(link);
link.remove();
}
}
]
},
},
],
],
dialog_general: false,
nodeItem: {
id: "",
name: ""
name: "",
},
node_name: "",
show_options_pop: false,
......@@ -329,7 +488,7 @@ export default {
{ label: "GET", value: 1 },
{ label: "POST", value: 2 },
{ label: "PUT", value: 3 },
{ label: "DELETE", value: 4 }
{ label: "DELETE", value: 4 },
],
select: 1,
serviceUrl: "",
......@@ -342,9 +501,9 @@ export default {
label: "请求字段编码",
prop: "requestEncoding",
type: "input",
align: "left"
align: "left",
},
{ label: "请求值", prop: "requestValue", type: "input", align: "left" }
{ label: "请求值", prop: "requestValue", type: "input", align: "left" },
],
datasSj: [],
optionsSq: [{ label: "Bearer Token", value: "Bearer" }],
......@@ -358,13 +517,13 @@ export default {
prop: "show_type",
type: "",
align: "left",
width: "140"
width: "140",
},
{
label: "字段名称*",
prop: "label",
type: "input",
align: "left"
align: "left",
},
{
label: "是否必须*",
......@@ -372,10 +531,13 @@ export default {
type: "select",
align: "left",
width: 100,
selectArr: [{ label: "", value: 1 }, { label: "", value: 0 }],
hasDefault: true
selectArr: [
{ label: "", value: 1 },
{ label: "", value: 0 },
],
hasDefault: true,
},
{ label: "字段说明", prop: "descript", type: "input", align: "left" }
{ label: "字段说明", prop: "descript", type: "input", align: "left" },
],
sjfwFhcstx: [
{ label: "字段编码", prop: "name", type: "", align: "left" },
......@@ -385,9 +547,9 @@ export default {
label: "字段名称*",
prop: "label",
type: "input",
align: "left"
align: "left",
},
{ label: "字段说明", prop: "descript", type: "input", align: "left" }
{ label: "字段说明", prop: "descript", type: "input", align: "left" },
],
datasQqcs: [],
datasFhcs: [],
......@@ -405,14 +567,14 @@ export default {
durationOptions: [
{ value: 1, label: "分钟" },
{ value: 2, label: "小时" },
{ value: 3, label: "" }
{ value: 3, label: "" },
],
max_time_0: undefined,
max_time_1: undefined,
max_time_type_0: 1,
max_time_type_1: 1,
max_time_check_0: false,
max_time_check_1: false
max_time_check_1: false,
};
},
mounted() {
......@@ -447,7 +609,7 @@ export default {
top,
right,
bottom,
left
left,
} = this.$refs.flowContainer.getBoundingClientRect();
// 判断鼠标是否进入 flow container
if (
......@@ -474,15 +636,18 @@ export default {
let query = { width: 120, height: 48, meta: {} };
query.meta.type = conf.info.meta.type;
if (!conf.info.meta.id) {
query.meta.id = parseInt(Math.random() * 1000 * 1000);
query.meta.id =
parseInt(Math.random() * 1000 * 1000) +
"a" +
parseInt(Math.random() * 1000 * 1000);
}
console.log(query);
this.$refs.superFlow.addNode({
coordinate,
...query
...query,
});
if (
this.nodeParamsList.findIndex(item => {
this.nodeParamsList.findIndex((item) => {
return item.id == query.meta.id;
}) == -1
) {
......@@ -492,21 +657,22 @@ export default {
label: "开始",
name: "开始",
type: 1,
id: query.meta.id
id: query.meta.id,
};
} else if (conf.info.meta.type == 2) {
obj = {
label: "结束",
name: "结束",
type: 2,
id: query.meta.id
id: query.meta.id,
};
} else if (conf.info.meta.type == 3) {
obj = {
label: "普通节点",
name: "普通节点",
type: 3,
id: query.meta.id
id: query.meta.id,
plugins: [],
};
}
this.nodeParamsList.push(obj);
......@@ -531,7 +697,7 @@ export default {
clientY: clientY,
info,
ele,
isDown: true
isDown: true,
});
ele.style.position = "fixed";
ele.style.margin = "0";
......@@ -546,14 +712,14 @@ export default {
},
blurItem() {
this.nodeItem = {
id: ""
id: "",
};
console.log(this.nodeItem);
},
getData() {
return {
obj: this.$refs.superFlow.toJSON(),
params: this.nodeParamsList
params: this.nodeParamsList,
};
},
handleChange() {},
......@@ -565,14 +731,14 @@ export default {
} else {
self.$message({
message: "开始和结束节点不可被编辑",
type: "warning"
type: "warning",
});
return false;
}
} else {
self.$message({
message: "请选择节点",
type: "warning"
type: "warning",
});
return false;
}
......@@ -580,17 +746,19 @@ export default {
showGeneralSettings() {
if (this.checkNodeCouldEdit()) {
let self = this;
self.node_name = self.nodeParamsList.find(item => {
self.node_name = self.nodeParamsList.find((item) => {
return item.id == self.nodeItem.id;
}).name;
self.dialog_general = true;
}
},
showInterfacePlugin() {
showInterfacePlugin(query) {
if (this.checkNodeCouldEdit()) {
this.dialog_interface = true;
}
},
nodeParams(id) {
let index = this.nodeParamsList.findIndex(item => {
let index = this.nodeParamsList.findIndex((item) => {
return item.id == id;
});
if (index != -1) {
......@@ -605,7 +773,7 @@ export default {
generalSubmit() {
let self = this;
if (self.nodeItem.type == 3) {
let index = self.nodeParamsList.findIndex(item => {
let index = self.nodeParamsList.findIndex((item) => {
return item.id == self.nodeItem.id;
});
if (index != -1) {
......@@ -613,7 +781,7 @@ export default {
} else {
self.$message({
message: "修改失败",
type: "error"
type: "error",
});
}
}
......@@ -676,17 +844,34 @@ export default {
? this.$refs.jsonCodes.getCodesVal()
: "";
let contentType = this.sjfwQqt;
let method = "";
switch (this.select) {
case 1:
method = "GET";
break;
case 2:
method = "POST";
break;
case 3:
method = "PUT";
break;
case 4:
method = "DELETE";
break;
default:
break;
}
let query = {
method: this.select,
method: method,
url: this.serviceUrl,
headers: headers,
params: requestData,
body: bodys,
content_type: contentType,
data_service_type1: 5,
data_service_type2: 12
data_service_type2: 12,
};
this.$api.workbench.fwzcFwcs(query).then(response => {
this.$api.workbench.fwzcFwcs(query).then((response) => {
if (response.data.success == 1) {
let data = response.data.data;
this.body_fields = data.body_fields;
......@@ -720,25 +905,26 @@ export default {
this.checkTable(requestData, 0);
this.checkTable(responseData, 1);
if (this.requestRules == 0 && this.responseRules == 0) {
this.request_fields = requestData;
this.response_fields = responseData;
let self = this;
let index = this.nodeParamsList.findIndex(item => {
return (item.id = self.nodeItem.id);
self.request_fields = requestData;
self.response_fields = responseData;
let index = self.nodeParamsList.findIndex((item) => {
return item.id == self.nodeItem.id;
});
console.log(self.nodeParamsList[index]);
self.nodeParamsList[index].plugins.push({
plugin_type: 1,
url: self.serviceUrl,
req_type: Number(self.select),
auth_method: self.sqfsVal,
auth_token: self.tokenVal,
query_fields:
self.dataType == "body" ? self.request_fields : self.body_fields,
body_fields:
self.dataType == "param"
? self.request_fields
: self.param_fields,
response_fields: self.response_fields
query_fields: JSON.stringify(
self.dataType == "body" ? self.request_fields : self.body_fields
),
body_fields: JSON.stringify(
self.dataType == "param" ? self.request_fields : self.param_fields
),
response_fields: JSON.stringify(self.response_fields),
});
console.log(self.nodeParamsList);
self.dialog_interface = false;
......@@ -770,20 +956,32 @@ export default {
}
},
showProcessService() {
if (this.checkNodeCouldEdit()) {
this.dialog_process = true;
}
},
processCancel() {
this.dialog_process = false;
},
processSubmit() {},
processSubmit() {
if (this.service != "") {
}
},
showTimeoutManagement() {
if (this.checkNodeCouldEdit()) {
this.dialog_timeout = true;
}
},
timeoutCancel() {
this.dialog_timeout = false;
},
timeoutSubmit() {}
}
timeoutSubmit() {},
setVal() {
this.nodeList = JSON.parse(JSON.stringify(this.node_list));
this.linkList = JSON.parse(JSON.stringify(this.link_list));
this.nodeParamsList = JSON.parse(JSON.stringify(this.node_params_list));
},
},
};
</script>
......@@ -882,6 +1080,11 @@ export default {
}
}
}
.checked_line {
width: 64px;
height: 1px;
background-color: #e5e8f5;
}
}
}
.node-item {
......@@ -1218,7 +1421,7 @@ export default {
.timeout_row {
display: flex;
.timeout_input_group {
width: 300px;
width: 400px;
display: flex;
.input_left {
display: inline-block;
......@@ -1238,6 +1441,19 @@ export default {
border-radius: 0;
color: #242c43;
}
.el-input-number__decrease {
display: none;
}
.el-input-number__increase {
display: none;
}
&.is-controls-right {
.el-input__inner {
padding-left: 15px;
padding-right: 15px;
text-align: left;
}
}
}
.input_right_select.el-select {
width: 80px;
......
<template>
<div class="fwgl_container">
<side-nav-bar
<sideNavBar
v-if="is_admin == 3 || is_admin == 4 || is_admin == 1"
title="运营管控中心"
imgSrc="tool_fuwu"
:nav-list="navList"
:title-path="navList[0] && navList[0].path"
></side-nav-bar>
></sideNavBar>
<sideNavBarClass
v-else-if="is_admin == 2"
title="运营管控中心"
imgSrc="tool_fuwu"
:nav-list="navList"
:title-path="navList[0] && navList[0].path"
></sideNavBarClass>
<div class="main_container">
<router-view :key="'type_' + $route.params.type"></router-view>
</div>
......@@ -14,10 +22,11 @@
<script>
import sideNavBar from "@/components/side-nav-bar";
import sideNavBarClass from "@/components/general/side-nav-bar-class";
export default {
components: {
sideNavBar,
sideNavBarClass,
},
data: () => ({
userNav: [
......@@ -32,24 +41,46 @@ export default {
],
userNav1: [
{
name: "组织服务数据分析",
name: "运营分析",
path: `/data_analysis/org_service`,
child: [
{
name: "服务分析",
path: `/data_analysis/org_service`,
},
{
name: "组织应用数据分析",
name: "应用分析",
path: `/data_analysis/org_application`,
},
],
},
{
name: "运行概况-组织",
name: "运行管控",
path: `/data_analysis/operation_overview`,
child: [
{
name: "运行概况",
path: `/data_analysis/operation_overview`,
},
{
name: "服务管控-组织",
name: "服务管控",
path: `/data_analysis/service_control`,
},
],
userNav2: [],
},
],
userNav2: [
{
name: "服务分析",
path: `/data_analysis/super_service`,
},
{
name: "应用分析",
path: `/data_analysis/super_application`,
},
],
navList: [],
is_admin: 0,
}),
watch: {
// "$route.fullPath"(path) {
......@@ -58,16 +89,15 @@ export default {
},
methods: {
initNavList() {
if (
this.$store.state.userInfo.is_admin == 3 ||
this.$store.state.userInfo.is_admin == 4
) {
this.is_admin = this.$store.state.userInfo.is_admin;
if (this.is_admin == 3 || this.is_admin == 4) {
this.navList = this.userNav;
} else if (this.$store.state.userInfo.is_admin == 2) {
} else if (this.is_admin == 2) {
this.navList = this.userNav1;
this.$router.push({ name: "orgServiceDataAnalysis" });
} else if (this.$store.state.userInfo.is_admin == 1) {
} else if (this.is_admin == 1) {
this.navList = this.userNav2;
this.$router.push({ name: "superServiceDataAnalysis" });
}
},
},
......
<template>
<div>
<el-breadcrumb separator="/" class="bread_crumb1">
<el-breadcrumb-item :to="{ path: '/data_analysis' }">{{ $t("lang.data_analysis") }}</el-breadcrumb-item>
<el-breadcrumb-item>{{ $t("lang.my_application_data_analysis") }}</el-breadcrumb-item>
</el-breadcrumb>
<BlockRadius class="default">
<div class="default_img">
<h1 class="default_title">开发中,敬请期待!</h1>
<h3 class="default_msg">
如需技术支持
<br />请联系管理员
</h3>
</div>
</BlockRadius>
</div>
</template>
<script>
import BlockRadius from "@/components/general/block-radius";
export default {
methods: {
getData() {},
},
components: {
BlockRadius,
},
};
</script>
<style lang="less" scoped>
.default {
height: calc(100vh - 160px);
display: flex;
align-items: center;
justify-content: center;
margin: 0 20px;
.default_img {
width: 1282px;
height: 629px;
background-image: url("~@/assets/imgs/img_default_jszc.png");
.default_title {
color: #264dd9;
font-size: 44px;
font-weight: bold;
margin-bottom: 40px;
}
.default_msg {
color: #58617a;
font-size: 24px;
line-height: 44px;
}
}
}
</style>
\ No newline at end of file
<template>
<div>
<el-breadcrumb separator="/" class="bread_crumb1">
<el-breadcrumb-item :to="{ path: '/data_analysis' }">
{{
$t("lang.data_analysis")
}}
</el-breadcrumb-item>
<el-breadcrumb-item>
{{
$t("lang.my_service_data_analysis")
}}
</el-breadcrumb-item>
</el-breadcrumb>
<BlockRadius class="default">
<div class="default_img">
<h1 class="default_title">开发中,敬请期待!</h1>
<h3 class="default_msg">
如需技术支持
<br />请联系管理员
</h3>
</div>
</BlockRadius>
</div>
</template>
<script>
import BlockRadius from "@/components/general/block-radius";
export default {
methods: {
getData() {},
},
components: {
BlockRadius,
},
};
</script>
<style lang="less" scoped>
.default {
height: calc(100vh - 160px);
display: flex;
align-items: center;
justify-content: center;
margin: 0 20px;
.default_img {
width: 1282px;
height: 629px;
background-image: url("~@/assets/imgs/img_default_jszc.png");
.default_title {
color: #264dd9;
font-size: 44px;
font-weight: bold;
margin-bottom: 40px;
}
.default_msg {
color: #58617a;
font-size: 24px;
line-height: 44px;
}
}
}
</style>
\ No newline at end of file
......@@ -5,7 +5,32 @@
<service-shop-menu></service-shop-menu>
</el-aside>
<el-main>
<service-list :filterNames="filterNames" :name="name" :url="url" :urlFilter="urlFilter"></service-list>
<service-list
v-show="urlFilter != '7' && urlFilter != '10'"
:filterNames="filterNames"
:name="name"
:url="url"
:urlFilter="urlFilter"
></service-list>
<div v-show="urlFilter == '7' || urlFilter == '10'">
<el-breadcrumb separator="/" class="bread_crumb1 bread_left">
<el-breadcrumb-item :to="{ path: '/shop' }">
{{
$t("lang.service_shop")
}}
</el-breadcrumb-item>
<el-breadcrumb-item>{{ name }}</el-breadcrumb-item>
</el-breadcrumb>
<BlockRadius class="default">
<div class="default_img">
<h1 class="default_title">开发中,敬请期待!</h1>
<h3 class="default_msg">
如需技术支持
<br />请联系管理员
</h3>
</div>
</BlockRadius>
</div>
</el-main>
</el-container>
</div>
......@@ -14,16 +39,18 @@
<script>
import ServiceShopMenu from "@/components/service-list/service_shop_menu";
import ServiceList from "@/components/service-list/service_list";
import BlockRadius from "@/components/general/block-radius";
export default {
components: {
ServiceShopMenu,
ServiceList
ServiceList,
BlockRadius,
},
data: () => ({
urlFilter: "",
url: "",
name: "",
filterNames: []
filterNames: [],
}),
mounted() {
this.getVal(this.$route.path);
......@@ -76,16 +103,39 @@ export default {
this.filterNames = [];
break;
}
}
},
},
watch: {
"$route.path": {
handler(val) {
this.getVal(val);
},
},
},
};
</script>
<style lang="less" scoped>
.default {
height: calc(100vh - 180px);
display: flex;
align-items: center;
justify-content: center;
margin: 0;
.default_img {
width: 1282px;
height: 629px;
background-image: url("~@/assets/imgs/img_default_jszc.png");
.default_title {
color: #264dd9;
font-size: 44px;
font-weight: bold;
margin-bottom: 40px;
}
.default_msg {
color: #58617a;
font-size: 24px;
line-height: 44px;
}
}
};
</script>
<style scoped>
}
</style>
\ No newline at end of file
<template>
<div class="contain"></div>
<div class="contain">
<div class="technical_head">{{ $t("lang.technical_support") }}</div>
<BlockRadius class="default">
<div class="default_img">
<h1 class="default_title">开发中,敬请期待!</h1>
<h3 class="default_msg">
如需技术支持
<br />请联系管理员
</h3>
</div>
</BlockRadius>
</div>
</template>
<script>
import BlockRadius from "@/components/general/block-radius";
export default {
data() {
return {};
},
components: {},
components: {
BlockRadius,
},
computed: {},
created() {},
mounted() {},
......@@ -15,6 +29,38 @@ export default {
};
</script>
<style>
<style lang="less" scoped>
.contain {
width: calc(100% - 80px);
margin: 0 auto;
margin-top: -157px;
margin-bottom: 20px;
.technical_head {
color: #626de9;
font-size: 14px;
padding: 20px;
}
.default {
height: calc(100vh - 180px);
display: flex;
align-items: center;
justify-content: center;
.default_img {
width: 1282px;
height: 629px;
background-image: url("~@/assets/imgs/img_default_jszc.png");
.default_title {
color: #264dd9;
font-size: 44px;
font-weight: bold;
margin-bottom: 40px;
}
.default_msg {
color: #58617a;
font-size: 24px;
line-height: 44px;
}
}
}
}
</style>
<template>
<div class="design_contain">
<el-breadcrumb separator="/" class="bread_crumb1">
<el-breadcrumb-item :to="{ path: '/workplace' }">{{ $t("lang.online_component_tool") }}</el-breadcrumb-item>
<el-breadcrumb-item :to="{ path: '/progress/designer' }">{{ $t("lang.process_design") }}</el-breadcrumb-item>
<el-breadcrumb-item :to="{ path: '/progress/designer' }">{{ $t("lang.process_management") }}</el-breadcrumb-item>
<el-breadcrumb-item>{{ $t("lang.new") }}</el-breadcrumb-item>
</el-breadcrumb>
<BlockRadius class="block_item">
<steps
:active-step="step"
:done="done"
:show-done="true"
done-title="保存成功"
done-sub-title="可返回流程管理列表查看该流程,并进行流程的部署和发布。"
class="apaas_steps"
>
<step
title="基本信息"
:step="0"
:active-icon="require('@/assets/imgs/progress_ic_xinxitx.png')"
class="apaas_step"
>
<div class="step_in">
<el-form :model="basic_form" :rules="rules" ref="basicInformation" class="form_left">
<el-form-item prop="name">
<p class="formname">流程名称:</p>
<el-input v-model="basic_form.name" placeholder="请输入流程名称"></el-input>
</el-form-item>
<el-form-item prop="workplace">
<p class="formname">工作区域:</p>
<el-select
v-model="basic_form.workplace"
@change="changeWorkPlace"
placeholder="请选择工作区域"
>
<el-option
v-for="(item, index) in workplace_list"
:label="item.name"
:value="item.id"
:key="index"
></el-option>
</el-select>
</el-form-item>
<el-form-item prop="desc">
<p class="formname">流程描述:</p>
<el-input
type="textarea"
:autosize="{ minRows: 6, maxRows: 10}"
v-model="basic_form.desc"
placeholder="请输入流程描述"
></el-input>
</el-form-item>
</el-form>
<div class="btn_footer">
<el-button class="cancel" @click="cancel">取消</el-button>
<el-button class="next" @click="next">下一步</el-button>
</div>
</div>
</step>
<step
title="流程设计"
:step="1"
:active-icon="require('@/assets/imgs/progress_ic_liucheng.png')"
class="apaas_step"
>
<div class="step_in">
<WorkFlow
ref="workFlow"
:node_list="node_list"
:link_list="link_list"
:node_params_list="node_params_list"
class="work_flow"
/>
<div class="btn_footer">
<el-button class="cancel" @click="cancel">取消</el-button>
<div>
<el-button class="cancel" @click="back">上一步</el-button>
<el-button class="next" @click="complete">完成</el-button>
</div>
</div>
</div>
</step>
<step
title
step-title="完成"
:step="2"
:active-icon="require('@/assets/imgs/progress_ic_wancheng.png')"
class="apaas_step"
></step>
<template slot="action">
<el-button type="primary" @click="backToList">返回列表</el-button>
</template>
</steps>
</BlockRadius>
</div>
</template>
<script>
import WorkFlow from "@/components/work-flow/super-flow";
import BlockRadius from "@/components/general/block-radius";
import Steps from "@/components/app-build-steps/app-build-steps";
import Step from "@/components/app-build-steps/app-build-step";
export default {
components: {
WorkFlow,
BlockRadius,
Steps,
Step,
},
data: () => {
return {
step: 0,
done: false,
basic_form: {
name: "",
workplace: "",
desc: "",
},
node_list: [],
link_list: [],
node_params_list: [],
rules: {
name: [
{ required: true, message: "请输入流程名称", trigger: "blur" },
{ max: 16, message: "不能超过16个字符", trigger: "blur" },
],
workplace: [
{ required: true, message: "请选择工作区域", trigger: "blur" },
],
desc: [
{ required: true, message: "请输入流程描述", trigger: "blur" },
{ max: 400, message: "不能超过400个字符", trigger: "blur" },
],
},
workplace_list: [],
};
},
methods: {
verification() {
let self = this;
let data = JSON.parse(JSON.stringify(self.$refs.workFlow.getData()));
console.log(JSON.stringify(data));
let start_num = 0;
let end_num = 0;
let start_id = "";
let end_id = "";
let start_before = 0;
let end_after = 0;
let in_edge = 0;
let out_edge = 0;
let datas = { ...data.obj };
console.log(data);
datas.nodeList.forEach((item) => {
let da = data.params.find((nodep) => {
return nodep.id == item.meta.id;
});
item.meta = da;
if (item.meta.type == 1) {
start_num++;
start_id = item.id;
}
if (item.meta.type == 2) {
end_num++;
end_id = item.id;
}
if (
datas.linkList.findIndex((el) => {
return el.startId == item.id;
}) == -1 &&
item.id != end_id
) {
in_edge++;
} else if (
datas.linkList.findIndex((el) => {
return el.endId == item.id;
}) == -1 &&
item.id != start_id
) {
out_edge++;
}
});
datas.linkList.forEach((item) => {
if (start_id == item.endId) {
start_before++;
}
if (end_id == item.startId) {
end_after++;
}
});
if (start_num != 1 || end_num != 1) {
this.$message({
message: "开始节点与结束节点均应有且只有一个",
type: "warning",
});
return false;
} else if (start_before != 0) {
this.$message({
message: "开始节点前面不应连接其它节点",
type: "warning",
});
return false;
} else if (end_after != 0) {
this.$message({
message: "结束节点后面不应连接其它节点",
type: "warning",
});
return false;
} else if (in_edge != 0 || out_edge != 0) {
this.$message({
message: "请保证每个节点都被连接",
type: "warning",
});
return false;
} else {
return datas;
}
},
backToList() {
this.$router.push("/message/directed_push");
},
changeWorkPlace() {},
cancel() {
this.$router.go(-1);
},
next() {
this.$refs["basicInformation"].validate((valid) => {
if (valid) {
this.step++;
} else {
}
});
},
back() {
this.step--;
},
complete() {
let self = this;
let res = self.verification();
if (res) {
let query = {
name: self.basic_form.name,
workarea: self.basic_form.workplace,
describe: self.basic_form.desc,
...res,
};
this.$api.workbench.addProcess(query).then((response) => {
if (response.data.success == 1) {
}
});
}
},
getNameSpaceList() {
this.$api.workbench.getProcessNamespaceList().then((response) => {
if (response.data.success == 1) {
this.workplace_list = response.data.data.workareas;
}
});
},
getProcessDetail() {
this.$api.workbench
.getProcessDetail({ id: this.$route.params.id })
.then((response) => {
if (response.data.success == 1) {
this.node_list = [];
this.link_list = [];
this.node_params_list = [];
this.node_list.forEach((item) => {
item.meta.id =
parseInt(Math.random() * 1000 * 1000) +
"a" +
parseInt(Math.random() * 1000 * 1000);
this.node_params_list.push(item.meta);
});
}
});
},
},
mounted() {
this.getNameSpaceList();
this.getProcessDetail();
},
};
</script>
<style scoped>
.design_contain {
width: 100%;
height: calc(100% - 20px);
padding: 0 20px;
}
.block_item {
height: calc(100% - 56px);
}
.step_in {
height: 100%;
}
.form_left {
width: 55%;
height: calc(100% - 70px);
}
.btn_footer {
width: calc(100% - 20px);
height: 40px;
padding: 0 10px;
display: flex;
justify-content: space-between;
}
.cancel {
background-color: #e3e5ef;
color: #0f2683;
}
.next {
background-color: #0f2683;
color: #f8f9fd;
}
.work_flow {
height: calc(100% - 70px);
}
</style>
<style>
.block_item .el-textarea__inner {
border-radius: 8px;
background-color: #f7f8f9;
border: solid 1px #e3e5ef;
}
.block_item .el-input__inner {
background-color: #f7f8f9;
border: solid 1px #e3e5ef;
}
.block_item .el-select {
width: 100%;
}
</style>
......@@ -7,8 +7,20 @@
<el-breadcrumb-item>{{ $t("lang.new") }}</el-breadcrumb-item>
</el-breadcrumb>
<BlockRadius class="block_item">
<steps :active-step="step" :done="done" :show-done="true" done-title="保存成功" done-sub-title="可返回流程管理列表查看该流程,并进行流程的部署和发布。" class="apaas_steps">
<step title="基本信息" :step="0" :active-icon="require('@/assets/imgs/progress_ic_xinxitx.png')" class="apaas_step">
<steps
:active-step="step"
:done="done"
:show-done="true"
done-title="保存成功"
done-sub-title="可返回流程管理列表查看该流程,并进行流程的部署和发布。"
class="apaas_steps"
>
<step
title="基本信息"
:step="0"
:active-icon="require('@/assets/imgs/progress_ic_xinxitx.png')"
class="apaas_step"
>
<div class="step_in">
<el-form :model="basic_form" :rules="rules" ref="basicInformation" class="form_left">
<el-form-item prop="name">
......@@ -17,13 +29,27 @@
</el-form-item>
<el-form-item prop="workplace">
<p class="formname">工作区域:</p>
<el-select v-model="basic_form.workplace" @change="changeWorkPlace" placeholder="请选择工作区域">
<el-option v-for="item in workplace_list" :label="item" :value="item" :key="item"></el-option>
<el-select
v-model="basic_form.workplace"
@change="changeWorkPlace"
placeholder="请选择工作区域"
>
<el-option
v-for="(item, index) in workplace_list"
:label="item.name"
:value="item.id"
:key="index"
></el-option>
</el-select>
</el-form-item>
<el-form-item prop="desc">
<p class="formname">流程描述:</p>
<el-input type="textarea" :autosize="{ minRows: 6, maxRows: 10}" v-model="basic_form.desc" placeholder="请输入流程描述"></el-input>
<el-input
type="textarea"
:autosize="{ minRows: 6, maxRows: 10}"
v-model="basic_form.desc"
placeholder="请输入流程描述"
></el-input>
</el-form-item>
</el-form>
<div class="btn_footer">
......@@ -32,7 +58,12 @@
</div>
</div>
</step>
<step title="流程设计" :step="1" :active-icon="require('@/assets/imgs/progress_ic_liucheng.png')" class="apaas_step">
<step
title="流程设计"
:step="1"
:active-icon="require('@/assets/imgs/progress_ic_liucheng.png')"
class="apaas_step"
>
<div class="step_in">
<WorkFlow ref="workFlow" class="work_flow" />
<div class="btn_footer">
......@@ -44,7 +75,13 @@
</div>
</div>
</step>
<step title step-title="完成" :step="2" :active-icon="require('@/assets/imgs/progress_ic_wancheng.png')" class="apaas_step"></step>
<step
title
step-title="完成"
:step="2"
:active-icon="require('@/assets/imgs/progress_ic_wancheng.png')"
class="apaas_step"
></step>
<template slot="action">
<el-button type="primary" @click="backToList">返回列表</el-button>
......@@ -65,7 +102,7 @@ export default {
WorkFlow,
BlockRadius,
Steps,
Step
Step,
},
data: () => {
return {
......@@ -74,22 +111,22 @@ export default {
basic_form: {
name: "",
workplace: "",
desc: ""
desc: "",
},
rules: {
name: [
{ required: true, message: "请输入流程名称", trigger: "blur" },
{ max: 16, message: "不能超过16个字符", trigger: "blur" }
{ max: 16, message: "不能超过16个字符", trigger: "blur" },
],
workplace: [
{ required: true, message: "请选择工作区域", trigger: "blur" }
{ required: true, message: "请选择工作区域", trigger: "blur" },
],
desc: [
{ required: true, message: "请输入流程描述", trigger: "blur" },
{ max: 400, message: "不能超过400个字符", trigger: "blur" }
]
{ max: 400, message: "不能超过400个字符", trigger: "blur" },
],
},
workplace_list: []
workplace_list: [],
};
},
methods: {
......@@ -107,8 +144,8 @@ export default {
let out_edge = 0;
let datas = { ...data.obj };
console.log(data);
datas.nodeList.forEach(item => {
let da = data.params.find(nodep => {
datas.nodeList.forEach((item) => {
let da = data.params.find((nodep) => {
return nodep.id == item.meta.id;
});
item.meta = da;
......@@ -121,14 +158,14 @@ export default {
end_id = item.id;
}
if (
datas.linkList.findIndex(el => {
datas.linkList.findIndex((el) => {
return el.startId == item.id;
}) == -1 &&
item.id != end_id
) {
in_edge++;
} else if (
datas.linkList.findIndex(el => {
datas.linkList.findIndex((el) => {
return el.endId == item.id;
}) == -1 &&
item.id != start_id
......@@ -136,7 +173,7 @@ export default {
out_edge++;
}
});
datas.linkList.forEach(item => {
datas.linkList.forEach((item) => {
if (start_id == item.endId) {
start_before++;
}
......@@ -147,25 +184,30 @@ export default {
if (start_num != 1 || end_num != 1) {
this.$message({
message: "开始节点与结束节点均应有且只有一个",
type: "warning"
type: "warning",
});
return false;
} else if (start_before != 0) {
this.$message({
message: "开始节点前面不应连接其它节点",
type: "warning"
type: "warning",
});
return false;
} else if (end_after != 0) {
this.$message({
message: "结束节点后面不应连接其它节点",
type: "warning"
type: "warning",
});
return false;
} else if (in_edge != 0 || out_edge != 0) {
this.$message({
message: "请保证每个节点都被连接",
type: "warning"
type: "warning",
});
return false;
} else {
return datas;
}
console.log(datas);
},
backToList() {
this.$router.push("/message/directed_push");
......@@ -175,9 +217,8 @@ export default {
this.$router.go(-1);
},
next() {
this.$refs["basicInformation"].validate(valid => {
this.$refs["basicInformation"].validate((valid) => {
if (valid) {
console.log("sss")
this.step++;
} else {
}
......@@ -187,9 +228,32 @@ export default {
this.step--;
},
complete() {
this.verification();
let self = this;
let res = self.verification();
if (res) {
let query = {
name: self.basic_form.name,
workarea: self.basic_form.workplace,
describe: self.basic_form.desc,
...res,
};
this.$api.workbench.addProcess(query).then((response) => {
if (response.data.success == 1) {
}
});
}
},
getNameSpaceList() {
this.$api.workbench.getProcessNamespaceList().then((response) => {
if (response.data.success == 1) {
this.workplace_list = response.data.data.workareas;
}
});
},
},
mounted() {
this.getNameSpaceList();
},
};
</script>
......
......@@ -57,6 +57,23 @@ const workbench = {
getServiceTopology() {
return axios.get(`/apaas/istio/v3/api/namespaces/graph`)
},
// add process
addProcess(params) {
return axios.post(`/apaas/serviceapp/v3/workflows/add`, params)
},
// edit process
editProcess(params) {
return axios.post(`/apaas/serviceapp/v3/workflows/update`, params)
},
// get process detail
getProcessDetail(params) {
return axios.get(`/apaas/serviceapp/v3/workflows/detail?id=${params.id}`)
},
// get process namespace list
getProcessNamespaceList() {
return axios.get(`/apaas/serviceapp/v3/workflows/searchConditions`)
},
}
export default workbench;
......@@ -284,6 +284,11 @@ export default new Router({
name: "process_design",
component: () => import("@/pages/workbench/component-center/process-management/process-design/index"),
}, // 流程设计
{
path: "/progress/designer/design_edit/:id",
name: "process_design_edit",
component: () => import("@/pages/workbench/component-center/process-management/process-design/edit"),
}, // 流程编辑
],
}, // 流程设计
{
......@@ -445,6 +450,16 @@ export default new Router({
name: "serviceControl",
component: () => import("@/pages/data-analysis/service-control"),
},
{
path: "/data_analysis/super_service", // 数据分析中心服务-组织
name: "superServiceDataAnalysis",
component: () => import("@/pages/data-analysis/super-service"),
},
{
path: "/data_analysis/super_application", // 数据分析中心应用-组织
name: "superApplicationDataAnalysis",
component: () => import("@/pages/data-analysis/super-application"),
},
],
},
{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment