|
@@ -1,115 +1,251 @@
|
|
<template>
|
|
<template>
|
|
<div class="props">
|
|
<div class="props">
|
|
- <div
|
|
|
|
- class="real-times"
|
|
|
|
- v-if="props.pen.realTimes && props.pen.realTimes.length"
|
|
|
|
|
|
+ <t-collapse
|
|
|
|
+ :defaultValue="['3']"
|
|
|
|
+ expandIconPlacement="right"
|
|
|
|
+ :borderless="true"
|
|
>
|
|
>
|
|
- <div class="grid head">
|
|
|
|
- <div class="title">数据名</div>
|
|
|
|
- <div class="title">值</div>
|
|
|
|
- <div class="title">触发器</div>
|
|
|
|
- <div class="actions">
|
|
|
|
- <t-icon name="more" />
|
|
|
|
- </div>
|
|
|
|
- </div>
|
|
|
|
- <div class="grid" v-for="(item, i) in props.pen.realTimes">
|
|
|
|
- <t-tooltip :content="item.key" placement="top">
|
|
|
|
- <label class="label">{{ item.label }}</label>
|
|
|
|
- </t-tooltip>
|
|
|
|
- <div class="value">
|
|
|
|
- <t-input
|
|
|
|
- v-if="item.type === 'integer'"
|
|
|
|
- v-model.number="props.pen[item.key]"
|
|
|
|
- placeholder="整数"
|
|
|
|
- @change="changeValue(item.key)"
|
|
|
|
- />
|
|
|
|
- <t-input-number
|
|
|
|
- v-else-if="item.type === 'float'"
|
|
|
|
- v-model="props.pen[item.key]"
|
|
|
|
- placeholder="浮点数"
|
|
|
|
- theme="normal"
|
|
|
|
- @change="changeValue(item.key)"
|
|
|
|
- />
|
|
|
|
- <t-switch
|
|
|
|
- v-else-if="item.type === 'bool'"
|
|
|
|
- v-model="props.pen[item.key]"
|
|
|
|
- class="ml-8"
|
|
|
|
- size="small"
|
|
|
|
- @change="changeValue(item.key)"
|
|
|
|
- />
|
|
|
|
- <t-button
|
|
|
|
- v-else-if="item.type === 'array' || item.type === 'object'"
|
|
|
|
- variant="outline"
|
|
|
|
- style="padding: 0px 2px 0 4px; margin: 0 4px"
|
|
|
|
- @click="editObject(item)"
|
|
|
|
- >
|
|
|
|
- <t-icon name="ellipsis" />
|
|
|
|
- </t-button>
|
|
|
|
- <t-input
|
|
|
|
- v-else
|
|
|
|
- v-model="props.pen[item.key]"
|
|
|
|
- placeholder="字符串"
|
|
|
|
- @change="changeValue(item.key)"
|
|
|
|
- />
|
|
|
|
-
|
|
|
|
- <t-tooltip :content="getBindsDesc(item)" placement="top">
|
|
|
|
- <t-icon
|
|
|
|
- name="link"
|
|
|
|
- class="hover ml-4"
|
|
|
|
- :class="{ primary: item.enableMock || item.bind?.id }"
|
|
|
|
- @click="onBind(item)"
|
|
|
|
|
|
+ <t-collapse-panel v-if="props.pen.props.custom" value="1" header="属性">
|
|
|
|
+ <t-space direction="vertical" size="small" class="w-full">
|
|
|
|
+ <div v-for="item in props.pen.props.custom" class="form-item">
|
|
|
|
+ <label :title="item.label">{{ item.label }}</label>
|
|
|
|
+ <t-checkbox
|
|
|
|
+ class="ml-8"
|
|
|
|
+ v-if="item.type === 'bool'"
|
|
|
|
+ v-model="props.pen[item.key]"
|
|
|
|
+ @change="changeValue(item.key)"
|
|
/>
|
|
/>
|
|
- </t-tooltip>
|
|
|
|
- </div>
|
|
|
|
- <div>
|
|
|
|
- <t-tooltip :content="item.triggers?.length || '触发器'">
|
|
|
|
- <t-badge
|
|
|
|
- :count="item.triggers?.length"
|
|
|
|
|
|
+ <t-input-number
|
|
|
|
+ class="w-full"
|
|
|
|
+ v-else-if="item.type === 'number'"
|
|
|
|
+ v-model.number="props.pen[item.key]"
|
|
|
|
+ theme="column"
|
|
|
|
+ :max="item.max"
|
|
|
|
+ :min="item.min"
|
|
|
|
+ @change="changeValue(item.key)"
|
|
|
|
+ :placeholder="item.placeholder"
|
|
|
|
+ />
|
|
|
|
+ <t-color-picker
|
|
|
|
+ class="w-full"
|
|
|
|
+ v-else-if="item.type === 'color'"
|
|
|
|
+ :enable-alpha="true"
|
|
|
|
+ :recent-colors="null"
|
|
|
|
+ format="CSS"
|
|
|
|
+ :swatch-colors="defaultPureColor"
|
|
|
|
+ :color-modes="['monochrome']"
|
|
|
|
+ :show-primary-color-preview="false"
|
|
|
|
+ v-model="props.pen[item.key]"
|
|
|
|
+ @change="changeValue(item.key)"
|
|
|
|
+ :placeholder="item.placeholder"
|
|
|
|
+ />
|
|
|
|
+ <t-select
|
|
|
|
+ class="w-full"
|
|
|
|
+ v-else-if="item.type === 'select'"
|
|
size="small"
|
|
size="small"
|
|
- dot
|
|
|
|
- :offset="[0, 5]"
|
|
|
|
|
|
+ :options="item.options"
|
|
|
|
+ v-model="props.pen[item.key]"
|
|
|
|
+ @change="changeValue(item.key)"
|
|
|
|
+ :placeholder="item.placeholder"
|
|
|
|
+ />
|
|
|
|
+ <t-button
|
|
|
|
+ v-else-if="item.type === 'code'"
|
|
|
|
+ shape="square"
|
|
|
|
+ variant="outline"
|
|
|
|
+ style="width: 24px"
|
|
|
|
+ @click="showPropsEdit(item)"
|
|
>
|
|
>
|
|
- <t-icon
|
|
|
|
- name="relativity"
|
|
|
|
- class="hover"
|
|
|
|
- @click="onTrigger(item)"
|
|
|
|
|
|
+ <t-icon name="ellipsis" slot="icon"
|
|
|
|
+ /></t-button>
|
|
|
|
+ <t-slider
|
|
|
|
+ v-else-if="item.type === 'slider'"
|
|
|
|
+ v-model="props.pen[item.key]"
|
|
|
|
+ :min="0"
|
|
|
|
+ :max="1"
|
|
|
|
+ :step="0.01"
|
|
|
|
+ @change="changeValue(item.key)"
|
|
|
|
+ />
|
|
|
|
+ <t-switch
|
|
|
|
+ class="mt-8"
|
|
|
|
+ v-else-if="item.type === 'switch'"
|
|
|
|
+ v-model="props.pen[item.key]"
|
|
|
|
+ @change="changeValue(item.key)"
|
|
|
|
+ />
|
|
|
|
+ <t-input
|
|
|
|
+ class="w-full"
|
|
|
|
+ v-else
|
|
|
|
+ v-model="props.pen[item.key]"
|
|
|
|
+ @change="changeValue(item.key)"
|
|
|
|
+ :placeholder="item.placeholder"
|
|
|
|
+ />
|
|
|
|
+ </div>
|
|
|
|
+ </t-space>
|
|
|
|
+ </t-collapse-panel>
|
|
|
|
+ <t-collapse-panel value="2" header="通信">
|
|
|
|
+ <t-space direction="vertical" size="small" class="w-full">
|
|
|
|
+ <div class="form-item">
|
|
|
|
+ <label title="http地址">http地址 </label>
|
|
|
|
+ <t-input
|
|
|
|
+ class="w-full"
|
|
|
|
+ v-model="props.pen.apiUrl"
|
|
|
|
+ @change="changeValue('apiUrl')"
|
|
|
|
+ />
|
|
|
|
+ </div>
|
|
|
|
+ <div class="form-item">
|
|
|
|
+ <label title="请求方式">请求方式</label>
|
|
|
|
+ <t-select
|
|
|
|
+ v-model="props.pen.apiMethod"
|
|
|
|
+ @change="changeValue('apiMethod')"
|
|
|
|
+ >
|
|
|
|
+ <t-option key="GET" value="GET" label="GET" />
|
|
|
|
+ <t-option key="POST" value="POST" label="POST" />
|
|
|
|
+ </t-select>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="form-item">
|
|
|
|
+ <label title="请求头">请求头</label>
|
|
|
|
+ <CodeEditor
|
|
|
|
+ :json="true"
|
|
|
|
+ :key="props.pen.id"
|
|
|
|
+ v-model="props.pen.apiHeaders"
|
|
|
|
+ class="mt-4"
|
|
|
|
+ style="height: 50px"
|
|
|
|
+ />
|
|
|
|
+ </div>
|
|
|
|
+ <div class="form-item" v-if="props.pen.apiMethod === 'POST'">
|
|
|
|
+ <label title="请求体">请求体</label>
|
|
|
|
+ <CodeEditor
|
|
|
|
+ :json="true"
|
|
|
|
+ :key="props.pen.id"
|
|
|
|
+ v-model="props.pen.apiBody"
|
|
|
|
+ class="mt-4"
|
|
|
|
+ style="height: 50px"
|
|
|
|
+ />
|
|
|
|
+ </div>
|
|
|
|
+ <div class="form-item">
|
|
|
|
+ <label title="开启轮询">开启轮询</label>
|
|
|
|
+ <t-switch
|
|
|
|
+ class="mt-8"
|
|
|
|
+ v-model="props.pen.apiEnable"
|
|
|
|
+ size="small"
|
|
|
|
+ @change="changeValue('apiEnable')"
|
|
|
|
+ />
|
|
|
|
+ </div>
|
|
|
|
+ </t-space>
|
|
|
|
+ </t-collapse-panel>
|
|
|
|
+ <t-collapse-panel value="3" header="动态数据">
|
|
|
|
+ <div
|
|
|
|
+ class="real-times"
|
|
|
|
+ v-if="props.pen.realTimes && props.pen.realTimes.length"
|
|
|
|
+ >
|
|
|
|
+ <div class="grid head">
|
|
|
|
+ <div class="title">数据名</div>
|
|
|
|
+ <div class="title">值</div>
|
|
|
|
+ <div class="title">触发器</div>
|
|
|
|
+ <div class="actions">
|
|
|
|
+ <t-icon name="more" />
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="grid" v-for="(item, i) in props.pen.realTimes">
|
|
|
|
+ <t-tooltip :content="item.key" placement="top">
|
|
|
|
+ <label class="label">{{ item.label }}</label>
|
|
|
|
+ </t-tooltip>
|
|
|
|
+ <div class="value">
|
|
|
|
+ <t-input
|
|
|
|
+ v-if="item.type === 'integer'"
|
|
|
|
+ v-model.number="props.pen[item.key]"
|
|
|
|
+ placeholder="整数"
|
|
|
|
+ @change="changeValue(item.key)"
|
|
|
|
+ />
|
|
|
|
+ <t-input-number
|
|
|
|
+ v-else-if="item.type === 'float'"
|
|
|
|
+ v-model="props.pen[item.key]"
|
|
|
|
+ placeholder="浮点数"
|
|
|
|
+ theme="normal"
|
|
|
|
+ @change="changeValue(item.key)"
|
|
|
|
+ />
|
|
|
|
+ <t-switch
|
|
|
|
+ v-else-if="item.type === 'bool'"
|
|
|
|
+ v-model="props.pen[item.key]"
|
|
|
|
+ class="ml-8"
|
|
|
|
+ size="small"
|
|
|
|
+ @change="changeValue(item.key)"
|
|
|
|
+ />
|
|
|
|
+ <t-button
|
|
|
|
+ v-else-if="item.type === 'array' || item.type === 'object'"
|
|
|
|
+ variant="outline"
|
|
|
|
+ style="padding: 0px 2px 0 4px; margin: 0 4px"
|
|
|
|
+ @click="editObject(item)"
|
|
|
|
+ >
|
|
|
|
+ <t-icon name="ellipsis" />
|
|
|
|
+ </t-button>
|
|
|
|
+ <t-input
|
|
|
|
+ v-else
|
|
|
|
+ v-model="props.pen[item.key]"
|
|
|
|
+ placeholder="字符串"
|
|
|
|
+ @change="changeValue(item.key)"
|
|
/>
|
|
/>
|
|
- </t-badge>
|
|
|
|
- </t-tooltip>
|
|
|
|
|
|
+
|
|
|
|
+ <t-tooltip :content="getBindsDesc(item)" placement="top">
|
|
|
|
+ <t-icon
|
|
|
|
+ name="link"
|
|
|
|
+ class="hover ml-4"
|
|
|
|
+ :class="{ primary: item.enableMock || item.bind?.id }"
|
|
|
|
+ @click="onBind(item)"
|
|
|
|
+ />
|
|
|
|
+ </t-tooltip>
|
|
|
|
+ </div>
|
|
|
|
+ <div>
|
|
|
|
+ <t-tooltip :content="item.triggers?.length || '触发器'">
|
|
|
|
+ <t-badge
|
|
|
|
+ :count="item.triggers?.length"
|
|
|
|
+ size="small"
|
|
|
|
+ dot
|
|
|
|
+ :offset="[0, 5]"
|
|
|
|
+ >
|
|
|
|
+ <t-icon
|
|
|
|
+ name="relativity"
|
|
|
|
+ class="hover"
|
|
|
|
+ @click="onTrigger(item)"
|
|
|
|
+ />
|
|
|
|
+ </t-badge>
|
|
|
|
+ </t-tooltip>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="actions">
|
|
|
|
+ <t-dropdown
|
|
|
|
+ :options="moreOptions"
|
|
|
|
+ @click="onMenuMore($event, item, i)"
|
|
|
|
+ :minColumnWidth="80"
|
|
|
|
+ >
|
|
|
|
+ <t-icon name="more" class="more hover" />
|
|
|
|
+ </t-dropdown>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="mt-8 pb-16">
|
|
|
|
+ <t-dropdown
|
|
|
|
+ :options="options"
|
|
|
|
+ @click="addRealTime"
|
|
|
|
+ :minColumnWidth="150"
|
|
|
|
+ >
|
|
|
|
+ <a class="ml-12">
|
|
|
|
+ <t-icon name="add-rectangle" /> 添加动态数据
|
|
|
|
+ </a>
|
|
|
|
+ </t-dropdown>
|
|
|
|
+ </div>
|
|
</div>
|
|
</div>
|
|
- <div class="actions">
|
|
|
|
- <t-dropdown
|
|
|
|
- :options="moreOptions"
|
|
|
|
- @click="onMenuMore($event, item, i)"
|
|
|
|
- :minColumnWidth="80"
|
|
|
|
- >
|
|
|
|
- <t-icon name="more" class="more hover" />
|
|
|
|
- </t-dropdown>
|
|
|
|
|
|
+ <div class="flex column center blank" v-else>
|
|
|
|
+ <img src="/img/blank.png" />
|
|
|
|
+ <div class="gray center">还没有动态数据</div>
|
|
|
|
+ <div class="mt-8">
|
|
|
|
+ <t-dropdown
|
|
|
|
+ :options="options"
|
|
|
|
+ @click="addRealTime"
|
|
|
|
+ :minColumnWidth="150"
|
|
|
|
+ >
|
|
|
|
+ <t-button style="height: 30px"> 添加动态数据 </t-button>
|
|
|
|
+ </t-dropdown>
|
|
|
|
+ </div>
|
|
</div>
|
|
</div>
|
|
- </div>
|
|
|
|
- <div class="mt-8 pb-16">
|
|
|
|
- <t-dropdown
|
|
|
|
- :options="options"
|
|
|
|
- @click="addRealTime"
|
|
|
|
- :minColumnWidth="150"
|
|
|
|
- >
|
|
|
|
- <a class="ml-12"> <t-icon name="add-rectangle" /> 添加动态数据 </a>
|
|
|
|
- </t-dropdown>
|
|
|
|
- </div>
|
|
|
|
- </div>
|
|
|
|
- <div class="flex column center blank" v-else>
|
|
|
|
- <img src="/img/blank.png" />
|
|
|
|
- <div class="gray center">还没有动态数据</div>
|
|
|
|
- <div class="mt-8">
|
|
|
|
- <t-dropdown
|
|
|
|
- :options="options"
|
|
|
|
- @click="addRealTime"
|
|
|
|
- :minColumnWidth="150"
|
|
|
|
- >
|
|
|
|
- <t-button style="height: 30px"> 添加动态数据 </t-button>
|
|
|
|
- </t-dropdown>
|
|
|
|
- </div>
|
|
|
|
- </div>
|
|
|
|
|
|
+ </t-collapse-panel>
|
|
|
|
+ </t-collapse>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<t-dialog
|
|
<t-dialog
|
|
@@ -459,6 +595,26 @@
|
|
/>
|
|
/>
|
|
</div>
|
|
</div>
|
|
</t-dialog>
|
|
</t-dialog>
|
|
|
|
+ <t-dialog
|
|
|
|
+ v-if="propsDialog.show"
|
|
|
|
+ :visible="true"
|
|
|
|
+ :header="propsDialog.header"
|
|
|
|
+ @confirm="onOkPropsEdit"
|
|
|
|
+ @close="propsDialog.show = false"
|
|
|
|
+ :width="700"
|
|
|
|
+ >
|
|
|
|
+ <div class="py-8">
|
|
|
|
+ <CodeEditor
|
|
|
|
+ :json="true"
|
|
|
|
+ :language="'json'"
|
|
|
|
+ v-model="propsDialog.value"
|
|
|
|
+ style="height: 300px"
|
|
|
|
+ />
|
|
|
|
+ </div>
|
|
|
|
+ <div class="gray" style="font-size: 12px">
|
|
|
|
+ {{ propsDialog.placeholder }}
|
|
|
|
+ </div>
|
|
|
|
+ </t-dialog>
|
|
</template>
|
|
</template>
|
|
|
|
|
|
<script lang="ts" setup>
|
|
<script lang="ts" setup>
|
|
@@ -482,6 +638,7 @@ import { updatePen } from './pen';
|
|
import CodeEditor from '@/views/components/common/CodeEditor.vue';
|
|
import CodeEditor from '@/views/components/common/CodeEditor.vue';
|
|
import Actions from './Actions.vue';
|
|
import Actions from './Actions.vue';
|
|
import { useSelection } from '@/services/selections';
|
|
import { useSelection } from '@/services/selections';
|
|
|
|
+import { defaultGradientColor, defaultPureColor } from '@/services/defaults';
|
|
|
|
|
|
const route = useRoute();
|
|
const route = useRoute();
|
|
const router = useRouter();
|
|
const router = useRouter();
|
|
@@ -928,6 +1085,9 @@ const { selections } = useSelection();
|
|
const changeValue = (prop: string) => {
|
|
const changeValue = (prop: string) => {
|
|
updatePen(props.pen, prop);
|
|
updatePen(props.pen, prop);
|
|
selections.pen[prop] = getter(props.pen, prop);
|
|
selections.pen[prop] = getter(props.pen, prop);
|
|
|
|
+ if (prop === 'iframe') {
|
|
|
|
+ getThumbImg();
|
|
|
|
+ }
|
|
};
|
|
};
|
|
|
|
|
|
const onTrigger = (item: any) => {
|
|
const onTrigger = (item: any) => {
|
|
@@ -1046,6 +1206,62 @@ const onOkEditOjbect = () => {
|
|
}
|
|
}
|
|
};
|
|
};
|
|
|
|
|
|
|
|
+const propsDialog = reactive<any>({
|
|
|
|
+ show: false,
|
|
|
|
+});
|
|
|
|
+
|
|
|
|
+// const changeValue = (prop: string) => {
|
|
|
|
+// updatePen(props.pen, prop);
|
|
|
|
+// selections.pen[prop] = getter(props.pen, prop);
|
|
|
|
+// if (prop === 'iframe') {
|
|
|
|
+// getThumbImg();
|
|
|
|
+// }
|
|
|
|
+// };
|
|
|
|
+
|
|
|
|
+const getThumbImg = async () => {
|
|
|
|
+ //改iframe地址后
|
|
|
|
+ let arr = props.pen.iframe.split('?');
|
|
|
|
+ let id = queryURLParams(arr[1]).id;
|
|
|
|
+ if (!id) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ let projection = {
|
|
|
|
+ image: 1,
|
|
|
|
+ _id: 1,
|
|
|
|
+ name: 1,
|
|
|
|
+ };
|
|
|
|
+ let res: any;
|
|
|
|
+ if (arr[0].indexOf('2d.le5le') !== -1) {
|
|
|
|
+ res = await getLe5le2d(id, projection);
|
|
|
|
+ } else if (arr[0].indexOf('v.le5le') !== -1) {
|
|
|
|
+ res = await getLe5leV(id, projection);
|
|
|
|
+ } else if (arr[0].indexOf('3d.le5le') !== -1) {
|
|
|
|
+ res = await getLe5le3d(id, projection);
|
|
|
|
+ }
|
|
|
|
+ if (res) {
|
|
|
|
+ props.pen.thumbImg = res.image;
|
|
|
|
+ }
|
|
|
|
+ props.pen.onRenderPenRaw?.(props.pen);
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+const showPropsEdit = (item: any) => {
|
|
|
|
+ propsDialog.key = item.key;
|
|
|
|
+ propsDialog.header = `${item.label}(${item.key})`;
|
|
|
|
+ propsDialog.value = props.pen[item.key];
|
|
|
|
+ propsDialog.placeholder = item.placeholder;
|
|
|
|
+ propsDialog.show = true;
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+const onOkPropsEdit = () => {
|
|
|
|
+ if (!propsDialog.value) {
|
|
|
|
+ MessagePlugin.error('数据不满足json格式');
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ props.pen[propsDialog.key] = propsDialog.value;
|
|
|
|
+ updatePen(props.pen, propsDialog.key);
|
|
|
|
+ propsDialog.show = false;
|
|
|
|
+};
|
|
|
|
+
|
|
onUnmounted(() => {
|
|
onUnmounted(() => {
|
|
clearInterval(timer);
|
|
clearInterval(timer);
|
|
});
|
|
});
|