You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
199 lines
6.6 KiB
199 lines
6.6 KiB
<!DOCTYPE html>
|
|
<html>
|
|
|
|
<head>
|
|
<title>TMP</title>
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<script src="./vue.global.js"></script>
|
|
<script src="./dayjs/dayjs.min.js"></script>
|
|
<script src="./dayjs/plugin/customParseFormat.js"></script>
|
|
<script src="./dayjs/plugin/weekday.js"></script>
|
|
<script src="./dayjs/plugin/localeData.js"></script>
|
|
<script src="./dayjs/plugin/weekOfYear.js"></script>
|
|
<script src="./dayjs/plugin/weekYear.js"></script>
|
|
<script src="./dayjs/plugin/advancedFormat.js"></script>
|
|
<script src="./dayjs/plugin/quarterOfYear.js"></script>
|
|
<script src="./ant-design-vue/antd.min.js"></script>
|
|
<link href="./ant-design-vue/reset.min.css" rel="stylesheet">
|
|
</head>
|
|
|
|
<body>
|
|
<div id="app" class="h-full">
|
|
<a-row class="h-full">
|
|
<a-col :span="6">
|
|
<div style="display:flex;padding:5px;">
|
|
<a-input v-model:value="wsUrl" style="margin-right:5px;"></a-input>
|
|
<a-button v-if="null === ws" @click="actionConnect">Connect</a-button>
|
|
<a-button v-else @click="actionDisconnect">DisConnect</a-button>
|
|
</div>
|
|
<a-menu mode="inline" :items="actionMenuItems" @click="actionGroupMenuItemClick"></a-menu>
|
|
</a-col>
|
|
<a-col :span="12" style="background-color: #f1f1f1;display:flex;flex-direction: column;">
|
|
<div v-if="null !== actionActiveGroup"
|
|
style="height:0;flex-grow: 1;overflow-y: auto;margin-bottom: 10px;padding: 10px;">
|
|
<div v-for="item in actionActiveGroup.items" class="action" style="margin-bottom: 5px;">
|
|
<div style="margin-right:5px;">
|
|
<a-input :value="item.fnName" disabled />
|
|
</div>
|
|
<div v-for="param in item.params">
|
|
<a-input v-model:value="item.values[param]" :placeholder="param" />
|
|
</div>
|
|
<a-button style="margin-left:5px;" @click="actionActionExecute(item)">DOIT</a-button>
|
|
</div>
|
|
</div>
|
|
<div style="padding:10px;">
|
|
<a-textarea v-model:value="rawRequestContent" style="margin-bottom: 5px;"></a-textarea>
|
|
<div>
|
|
<a-button @click="actionSendRawRequest">Send</a-button>
|
|
</div>
|
|
</div>
|
|
</a-col>
|
|
<a-col :span="6" style="overflow-y: auto;height: 100%;">
|
|
<a-collapse v-model:activeKey="activeKey">
|
|
<a-collapse-panel v-for="(entry,index) in logs" :key="index" :header="entry.title">
|
|
<div style="white-space: pre-wrap;">
|
|
{{entry.content}}
|
|
</div>
|
|
</a-collapse-panel>
|
|
</a-collapse>
|
|
</a-col>
|
|
</a-row>
|
|
</div>
|
|
<script>
|
|
const { createApp } = Vue
|
|
createApp({
|
|
data() {
|
|
return {
|
|
actions: [],
|
|
actionActiveGroup: null,
|
|
rawRequestContent: '',
|
|
logs: [],
|
|
wsUrl: "ws://" + window.location.hostname + ":19001",
|
|
ws: null,
|
|
wsMessageIndex: 0,
|
|
requests: {},
|
|
}
|
|
},
|
|
computed: {
|
|
actionMenuItems() {
|
|
return this.actions.map(i => ({ key: i.key, label: i.key }));
|
|
}
|
|
},
|
|
methods: {
|
|
// connect
|
|
actionConnect() {
|
|
this.ws = new WebSocket(this.wsUrl);
|
|
this.ws.onclose = () => this.ws = null;
|
|
this.ws.onmessage = event => {
|
|
let data = JSON.parse(event.data);
|
|
let responseEntry = {};
|
|
responseEntry.title = `${data.messageType}`;
|
|
responseEntry.content = JSON.stringify(data, null, 2);
|
|
this.logs.push(responseEntry);
|
|
if ('Ack' === data.messageType && 'FNScheduler' === data.fromClass && 'geFnList' === data.fromFn) {
|
|
this.actionListReload(data);
|
|
}
|
|
};
|
|
this.ws.onopen = () => {
|
|
this.wsMessageIndex++;
|
|
let request = {};
|
|
request.messageId = this.wsMessageIndex;
|
|
request.timeStamp = Math.floor(Date.now() / 1000);
|
|
request.messageType = 'Command';
|
|
request.className = 'FNScheduler';
|
|
request.fnName = 'geFnList';
|
|
request.params = {};
|
|
this.wsCall(request);
|
|
}
|
|
},
|
|
|
|
// disconnect
|
|
actionDisconnect() {
|
|
this.ws.close();
|
|
},
|
|
|
|
// action list reload
|
|
actionListReload(response) {
|
|
let data = response.rely;
|
|
if (undefined === data) {
|
|
return;
|
|
}
|
|
|
|
this.actions = [];
|
|
for (let action of data.fnlist) {
|
|
let group = this.actions.find(i => i.key === action.className);
|
|
if (undefined === group) {
|
|
group = { key: action.className, items: [] };
|
|
this.actions.push(group);
|
|
}
|
|
item = structuredClone(action);
|
|
item.values = {};
|
|
group.items.push(item);
|
|
}
|
|
},
|
|
|
|
// action group menu item click
|
|
actionGroupMenuItemClick(event) {
|
|
this.actionActiveGroup = this.actions.find(i => i.key === event.key);
|
|
},
|
|
|
|
// action execute
|
|
actionActionExecute(item) {
|
|
this.wsMessageIndex++;
|
|
|
|
let request = {};
|
|
request.messageId = this.wsMessageIndex;
|
|
request.timeStamp = Math.floor(Date.now() / 1000);
|
|
request.messageType = 'Command';
|
|
request.className = item.className;
|
|
request.fnName = item.fnName;
|
|
request.params = {};
|
|
for (let i = 0; i < item.params.length; i++) {
|
|
let param = item.params[i];
|
|
let type = item.paramsTypeInfo[i];
|
|
let value = item.values[param];
|
|
switch (type) {
|
|
case 'int32_t': value *= 1; break;
|
|
case 'string': /* nothing to do here */ break;
|
|
default: /* throw an exception is required. */
|
|
}
|
|
request.params[param] = value;
|
|
}
|
|
this.wsCall(request);
|
|
},
|
|
|
|
// raw request send
|
|
actionSendRawRequest() {
|
|
let request = JSON.parse(this.rawRequestContent);
|
|
this.wsCall(request);
|
|
},
|
|
|
|
// ws call
|
|
wsCall(request) {
|
|
if (null === this.ws) {
|
|
return;
|
|
}
|
|
let requestEntry = {};
|
|
requestEntry.title = `${request.messageType} : ${request.className}.${request.fnName}`;
|
|
requestEntry.content = JSON.stringify(request, null, 2);
|
|
this.logs.push(requestEntry);
|
|
this.ws.send(JSON.stringify(request));
|
|
},
|
|
},
|
|
})
|
|
.use(antd)
|
|
.mount('#app');
|
|
</script>
|
|
<style>
|
|
.h-full {
|
|
height: 100%;
|
|
}
|
|
|
|
.action {
|
|
display: flex;
|
|
flex-direction: row;
|
|
}
|
|
</style>
|
|
</body>
|
|
|
|
</html>
|