278 lines
5.6 KiB
Vue
278 lines
5.6 KiB
Vue
<template>
|
|
<div class="editor-box">
|
|
<div class="top">
|
|
<div class="left">
|
|
<span v-for="item in symbolList.filter((t: SymbolType, i: number) => i <= 3)" :key="item.key"
|
|
@click="addOperatorValue(item.value)">
|
|
{{ item.value }}
|
|
</span>
|
|
<span>
|
|
<j-dropdown>
|
|
<AIcon type="MoreOutlined" />
|
|
<template #overlay>
|
|
<j-menu>
|
|
<j-menu-item v-for="item in symbolList.filter((t: SymbolType, i: number) => i > 6)" :key="item.key"
|
|
@click="addOperatorValue(item.value)">
|
|
{{ item.value }}
|
|
</j-menu-item>
|
|
</j-menu>
|
|
</template>
|
|
</j-dropdown>
|
|
</span>
|
|
</div>
|
|
<div class="right">
|
|
<span v-if="mode !== 'advance'">
|
|
<j-tooltip :title="!id ? '请先输入标识' : '设置属性规则'">
|
|
<AIcon type="FullscreenOutlined" :class="!id ? 'disabled' : ''" @click="fullscreenClick" />
|
|
</j-tooltip>
|
|
</span>
|
|
</div>
|
|
</div>
|
|
<div class="editor">
|
|
<j-monaco-editor v-if="loading" v-model:model-value="_value" theme="vs" ref="editor" language="javascript" :registrationTypescript="typescriptTip" :registrationTips="registrationTips"
|
|
:init="editorInit"/>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
<script setup lang="ts" name="Editor">
|
|
import {
|
|
queryTypescript,
|
|
queryProductTs
|
|
} from '@/api/device/instance';
|
|
import { useInstanceStore } from '@/store/instance';
|
|
import { useProductStore } from '@/store/product';
|
|
import { cloneDeep } from 'lodash-es';
|
|
import { inject } from 'vue'
|
|
interface Props {
|
|
mode?: 'advance' | 'simple';
|
|
id?: string;
|
|
value?: string;
|
|
tips?: Array<any>
|
|
}
|
|
const props = defineProps<Props>()
|
|
const target = inject('target')
|
|
const instanceStore = useInstanceStore()
|
|
const productStore = useProductStore()
|
|
interface Emits {
|
|
(e: 'change', data: string): void;
|
|
(e: 'update:value', data: string): void;
|
|
}
|
|
|
|
const emit = defineEmits<Emits>()
|
|
|
|
type editorType = {
|
|
insert(val: string): void
|
|
}
|
|
const editor = ref<editorType>()
|
|
|
|
type SymbolType = {
|
|
key: string,
|
|
value: string
|
|
}
|
|
|
|
const typescriptTip = reactive({
|
|
typescript: ''
|
|
})
|
|
const registrationTips = ref<any>({
|
|
name: 'javascript'
|
|
})
|
|
const editorInit = (editor: any, monaco: any) => {
|
|
monaco.languages.typescript.javascriptDefaults.setDiagnosticsOptions({
|
|
noSemanticValidation: true,
|
|
noSyntaxValidation: false,
|
|
});
|
|
|
|
// compiler options
|
|
monaco.languages.typescript.javascriptDefaults.setCompilerOptions({
|
|
allowJs: true,
|
|
checkJs: true,
|
|
allowNonTsExtensions: true,
|
|
target: monaco.languages.typescript.ScriptTarget.ESNext,
|
|
strictNullChecks: false,
|
|
strictPropertyInitialization: true,
|
|
strictFunctionTypes: true,
|
|
strictBindCallApply: true,
|
|
useDefineForClassFields: true,//permit class static fields with private name to have initializer
|
|
moduleResolution: monaco.languages.typescript.ModuleResolutionKind.NodeJs,
|
|
module: monaco.languages.typescript.ModuleKind.CommonJS,
|
|
typeRoots: ["types"],
|
|
lib: ["esnext"]
|
|
});
|
|
}
|
|
|
|
const symbolList = [
|
|
{
|
|
key: 'add',
|
|
value: '+',
|
|
},
|
|
{
|
|
key: 'subtract',
|
|
value: '-',
|
|
},
|
|
{
|
|
key: 'multiply',
|
|
value: '*',
|
|
},
|
|
{
|
|
key: 'divide',
|
|
value: '/',
|
|
},
|
|
{
|
|
key: 'parentheses',
|
|
value: '()',
|
|
},
|
|
{
|
|
key: 'cubic',
|
|
value: '^',
|
|
},
|
|
{
|
|
key: 'dayu',
|
|
value: '>',
|
|
},
|
|
{
|
|
key: 'dayudengyu',
|
|
value: '>=',
|
|
},
|
|
{
|
|
key: 'dengyudengyu',
|
|
value: '==',
|
|
},
|
|
{
|
|
key: 'xiaoyudengyu',
|
|
value: '<=',
|
|
},
|
|
{
|
|
key: 'xiaoyu',
|
|
value: '<',
|
|
},
|
|
{
|
|
key: 'jiankuohao',
|
|
value: '<>',
|
|
},
|
|
{
|
|
key: 'andand',
|
|
value: '&&',
|
|
},
|
|
{
|
|
key: 'huohuo',
|
|
value: '||',
|
|
},
|
|
{
|
|
key: 'fei',
|
|
value: '!',
|
|
},
|
|
{
|
|
key: 'and',
|
|
value: '&',
|
|
},
|
|
{
|
|
key: 'huo',
|
|
value: '|',
|
|
},
|
|
{
|
|
key: 'bolang',
|
|
value: '~',
|
|
},
|
|
] as SymbolType[];
|
|
|
|
const _value = computed({
|
|
get: () => props.value || '',
|
|
set: (data: string) => {
|
|
emit('update:value', data);
|
|
}
|
|
})
|
|
|
|
const loading = ref(false)
|
|
const queryCode = () => {
|
|
registrationTips.value.suggestions = cloneDeep(props.tips)
|
|
let id = ''
|
|
if(target==='device'){
|
|
id = instanceStore.current.id
|
|
queryTypescript(id).then(res => {
|
|
if (res.status===200) {
|
|
typescriptTip.typescript = res.result
|
|
}
|
|
})
|
|
}else if(target ==='product'){
|
|
id = productStore.current.id
|
|
queryProductTs(id).then(res => {
|
|
if (res.status===200) {
|
|
typescriptTip.typescript = res.result
|
|
}
|
|
})
|
|
}
|
|
|
|
}
|
|
|
|
|
|
const addOperatorValue = (val: string) => {
|
|
editor.value?.insert(val)
|
|
}
|
|
|
|
const fullscreenClick = () => {
|
|
if (props.id) {
|
|
emit('change', 'advance');
|
|
}
|
|
}
|
|
|
|
defineExpose({
|
|
addOperatorValue
|
|
})
|
|
|
|
onMounted(() => {
|
|
setTimeout(() => {
|
|
loading.value = true;
|
|
}, 100);
|
|
})
|
|
|
|
queryCode()
|
|
</script>
|
|
<style lang="less" scoped>
|
|
.editor-box {
|
|
margin-bottom: 10px;
|
|
border: 1px solid lightgray;
|
|
|
|
.top {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
justify-content: space-between;
|
|
width: 100%;
|
|
border-bottom: 1px solid lightgray;
|
|
|
|
.left {
|
|
display: flex;
|
|
align-items: center;
|
|
width: 60%;
|
|
margin: 0 5px;
|
|
|
|
span {
|
|
display: inline-block;
|
|
height: 40px;
|
|
margin: 0 10px;
|
|
line-height: 40px;
|
|
cursor: pointer;
|
|
}
|
|
}
|
|
|
|
.right {
|
|
display: flex;
|
|
align-items: center;
|
|
width: 10%;
|
|
margin: 0 5px;
|
|
|
|
span {
|
|
margin: 0 5px;
|
|
}
|
|
}
|
|
|
|
.disabled {
|
|
color: rgba(#000, 0.5);
|
|
cursor: not-allowed;
|
|
}
|
|
}
|
|
|
|
.editor {
|
|
height: 300px;
|
|
}
|
|
}
|
|
</style> |