sige 1 year ago
parent
commit
8588a27008
  1. 3
      package.json
  2. 78
      src/components/ServiceConfiguration.vue
  3. 20
      src/components/ServiceConfigurationActionLog.vue
  4. 45
      src/components/ServiceConfigurationActionParamFile.vue
  5. 4
      src/components/ServiceConfigurationParamValueObjectEdit.vue
  6. 4
      src/utils/ApiClient.js

3
package.json

@ -42,7 +42,8 @@
},
"rules": {
"no-debugger": "off",
"no-undef": "off"
"no-undef": "off",
"no-unused-vars" : "off"
}
},
"browserslist": [

78
src/components/ServiceConfiguration.vue

@ -1,10 +1,5 @@
<template>
<div class="h-full flex flex-col">
<div class="bg-white border-b p-5">
<div v-for="(status,index) in statuses" :key="index" class="inline-block py-1 px-2 rounded border ml-1">
{{ status.name }} : {{ status.value }}
</div>
</div>
<a-row class="h-0 grow">
<a-col class="border-r h-full overflow-y-auto" :span="16">
<div class="p-5 border-t border-b" v-if="0 < params.length">
@ -28,33 +23,48 @@
<a-button @click="actionServiceParamSave">保存</a-button>
</div>
</div>
<div class="p-5">
<fieldset v-for="(group,groupIndex) in actions" :key="groupIndex" class="border my-1 p-1">
<legend>{{ group.name }}</legend>
<div v-for="action in group.items" :key="action.key" :class="{'inline-block ml-1':0 === action.params.length}">
<a-button v-if="0 === action.params.length" class="my-1 w-64 text-left"
:loading="action.isExecuting"
@click="actionServiceExecute(action)"
>{{ action.name }}</a-button>
<div v-else class="border rounded-md my-1 pr-3 bg-white">
<a-button class="m-1 w-64 text-left" :loading="action.isExecuting" @click="actionServiceExecute(action)">{{ action.name }}</a-button>
<div class="inline-block mx-2" v-for="actionParam in action.params" :key="actionParam.key">
{{ actionParam.name }} :
<a-switch v-if="'java.lang.Boolean' === actionParam.type" v-model:checked="actionParam.value" />
<a-input v-else-if="'java.lang.String' === actionParam.type" class="w-24" v-model:value="actionParam.value" />
<a-input-number v-else-if="'java.lang.Integer' === actionParam.type" class="w-24" v-model:value="actionParam.value" />
<a-select v-else-if="'Enum' === actionParam.type" v-model:value="actionParam.value" :dropdownMatchSelectWidth="false">
<a-select-option v-for="(enumItem,enumIndex) in actionParam.options" :key="enumIndex" :value="enumItem.value">{{ enumItem.name }}</a-select-option>
</a-select>
<span v-else>{{ actionParam }}</span>
</div>
</div>
</div>
</fieldset>
<div class="p-3">
<a-row>
<a-col class="p-1" :span="12" v-for="(group,groupIndex) in actions" :key="groupIndex">
<fieldset class="border my-1 p-1">
<legend>{{ group.name }}</legend>
<table class="w-full">
<tr v-for="action in group.items" :key="action.key">
<td>
<a-button class="m-1 w-full text-left" :loading="action.isExecuting" @click="actionServiceExecute(action)"
>{{ action.name }}</a-button>
</td>
<td>
<div class="inline-block ml-2" v-for="actionParam in action.params" :key="actionParam.key">
<a-select v-if="'java.lang.Boolean' === actionParam.type" v-model:value="actionParam.value" :dropdownMatchSelectWidth="false">
<a-select-option :value="true">TRUE</a-select-option>
<a-select-option :value="false">FALSE</a-select-option>
</a-select>
<a-input v-else-if="'java.lang.String' === actionParam.type" class="w-24" v-model:value="actionParam.value" :placeholder="actionParam.name"/>
<a-input-number v-else-if="'java.lang.Integer' === actionParam.type" class="w-24" v-model:value="actionParam.value" :placeholder="actionParam.name"/>
<a-select v-else-if="'Enum' === actionParam.type" v-model:value="actionParam.value" :dropdownMatchSelectWidth="false">
<a-select-option v-for="(enumItem,enumIndex) in actionParam.options" :key="enumIndex" :value="enumItem.value">{{ enumItem.name }}</a-select-option>
</a-select>
<service-configuration-action-param-file v-else-if="'a8k.utils.HardwareParamFile' === actionParam.type" v-model:value="actionParam.value" />
<span v-else>{{ actionParam }}</span>
</div>
</td>
</tr>
</table>
</fieldset>
</a-col>
</a-row>
</div>
</a-col>
<a-col :span="8" class="p-5 h-full">
<service-configuration-action-log :log="actionLog"/>
<a-col :span="8" class="h-full flex flex-col">
<a-row class="bg-white border-b p-5">
<a-col :span="8" v-for="(status,index) in statuses" :key="index" class="p-1">
<div class="py-1 px-2 rounded border">{{ status.name }} : {{ status.value }}</div>
</a-col>
</a-row>
<div class="h-0 grow p-5">
<service-configuration-action-log :log="actionLog"/>
</div>
</a-col>
</a-row>
</div>
@ -64,6 +74,7 @@ import { onUnmounted, ref, watch } from 'vue';
import ApiClient from '@/utils/ApiClient';
import ServiceConfigurationParamValueEdit from './ServiceConfigurationParamValueEdit.vue'
import ServiceConfigurationActionLog from './ServiceConfigurationActionLog.vue'
import ServiceConfigurationActionParamFile from './ServiceConfigurationActionParamFile.vue'
/** @var {Object} */
const props = defineProps({
serviceKey : String,
@ -167,13 +178,16 @@ async function serviceActionReload() {
for ( let item of list ) {
let group = actions.value.find(i => i.name === item.group);
if ( undefined === group ) {
group = {name:item.group, items:[]};
group = {name:item.group, items:[], order:0};
actions.value.push(group);
}
if ( item.groupOrder > group.order ) {
group.order = item.groupOrder;
}
group.items.push(item);
group.items.sort((a,b) => b.order - a.order || a.params.length - b.params.length);
}
actions.value.sort((a,b) => a.name.localeCompare(b.name));
actions.value.sort((a,b) => b.order - a.order || b.items.length - a.items.length || a.name.localeCompare(b.name));
} catch ( e ) {/** nothing to do here */}
}

20
src/components/ServiceConfigurationActionLog.vue

@ -11,13 +11,14 @@
</div>
</div>
<div v-if="chartEnable" ref="chartContainer" class="h-96 w-full bg-white mb-3 border rounded"></div>
<div class="border rounded p-3 whitespace-pre bg-white mb-3 h-0 grow overflow-y-auto">
<div>响应内容</div>
<div>{{ JSON.stringify(props.log.response, null, 2) }}</div>
<div class="select-all">{{ JSON.stringify(props.log.response, null, 2) }}</div>
</div>
<a-modal v-model:open="chartEnable" title="曲线" width="90%" @ok="chartEnable = false">
<div ref="chartContainer" class="w-full bg-white mb-3 border rounded" style="height:600px;"></div>
</a-modal>
</div>
</template>
<script setup>
@ -50,6 +51,9 @@ async function handleLogChange() {
if ( 'A8kScanCurve' === props.log.response.$dataType ) {
chartEnable.value = true;
let minY = Math.min(... props.log.response.scanDataCurve) - 100;
let maxY = Math.max(... props.log.response.scanDataCurve) + 100;
let refLine = props.log.response.refLine.map((v,i) => [i,v]);
let scanDataCurve = props.log.response.scanDataCurve.map((v,i) => [i,v]);
let refCurve = props.log.response.refCurve || [];
@ -58,17 +62,23 @@ async function handleLogChange() {
await nextTick();
chart = echarts.init(chartContainer.value);
chart.setOption({
xAxis: {type: 'value', axisLabel : {show:false}},
yAxis: {type: 'value', axisLabel : {show:false}},
xAxis: {type: 'value', axisLabel : {show:true}},
yAxis: {type: 'value', axisLabel : {show:true}, min:minY, max:maxY},
grid: {left: '3%', right: '4%', bottom: '3%', top:'3%', containLabel: true},
dataZoom : [{type:'inside'},{type:'inside',orient:'vertical'}],
tooltip: {trigger:'axis'},
series: [{
name: 'RefLine',
type: 'line',
itemStyle : {normal:{lineStyle:{width:1},color:'#ffb2b3'}},
showSymbol : false,
data: refLine
}, {
name: 'ScanDataCurve',
type: 'line',
data: scanDataCurve,
itemStyle : {normal:{lineStyle:{width:1},color:'#4d90ff'}},
showSymbol : false,
markLine : {
slient : true,
symbol : 'none',

45
src/components/ServiceConfigurationActionParamFile.vue

@ -0,0 +1,45 @@
<template>
<a-button @click="actionSelectFile">选择文件</a-button>
<input ref="file" type="file" class="hidden" @change="actionFileChange"/>
</template>
<script setup>
import { ref } from 'vue';
/** @var {Function} */
const emits = defineEmits(['update:value', 'change']);
/** @var {Object} */
const props = defineProps({
value : Object
});
/** @var {Element} */
const file=ref(null);
// select file
function actionSelectFile() {
file.value.click();
}
// action on file change
async function actionFileChange( event ) {
if ( 0 === event.target.files.length ) {
return ;
}
let content = await fileToBase64(event.target.files[0]);
emits('update:value', content);
emits('change');
}
// convert file to base64
function fileToBase64(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function () {
const base64String = reader.result.split(",")[1];
resolve(base64String);
};
reader.onerror = function () {
reject(new Error("Failed to load file"));
};
});
}
</script>

4
src/components/ServiceConfigurationParamValueObjectEdit.vue

@ -47,7 +47,6 @@ onMounted(mounted);
// on mounted
async function mounted() {
tableData.value = await setupTableData(props.structClassName);
console.log(tableData.value);
}
// setup tree data
@ -111,11 +110,10 @@ function actionEditEable() {
// ok
async function actionOk() {
let newValue = generateJsonData(tableData.value);
console.log(newValue);
emits('update:value', newValue);
emits('change');
await nextTick();
emits('save-request');
isModalOpen.value = true;
isModalOpen.value = false;
}
</script>

4
src/utils/ApiClient.js

@ -29,7 +29,9 @@ export default class ApiClient {
Modal.error({title: '请求错误',content:content,width:800});
throw new Error(`API【${name}】调用失败 : ${response.data}`);
}
response.data.data.$dataType = response.data.dataType;
if ( 'object' === typeof(response.data.data) ) {
response.data.data.$dataType = response.data.dataType;
}
return response.data.data;
}
}
Loading…
Cancel
Save