diff --git a/build/constant.ts b/build/constant.ts index d7cda99c..38ff0454 100644 --- a/build/constant.ts +++ b/build/constant.ts @@ -1,6 +1,8 @@ -// 打包路径 export const OUTPUT_DIR = 'dist' +// monaco-editor 路径 +export const prefix = `monaco-editor/esm/vs` + // chunk 警告大小 export const chunkSizeWarningLimit = 2000 @@ -12,7 +14,14 @@ export const rollupOptions = { output: { chunkFileNames: 'static/js/[name]-[hash].js', entryFileNames: 'static/js/[name]-[hash].js', - assetFileNames: 'static/[ext]/[name]-[hash].[ext]' + assetFileNames: 'static/[ext]/[name]-[hash].[ext]', + manualChunks: { + jsonWorker: [`${prefix}/language/json/json.worker`], + cssWorker: [`${prefix}/language/css/css.worker`], + htmlWorker: [`${prefix}/language/html/html.worker`], + tsWorker: [`${prefix}/language/typescript/ts.worker`], + editorWorker: [`${prefix}/editor/editor.worker`] + } } } @@ -23,4 +32,4 @@ export const terserOptions = { drop_console: true, drop_debugger: true } -} \ No newline at end of file +} diff --git a/package.json b/package.json index 7d2569a2..2904606a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "go-view", - "version": "2.0.1", + "version": "2.0.2", "scripts": { "dev": "vite --host", "build": "vue-tsc --noEmit && vite build", @@ -20,7 +20,8 @@ "highlight.js": "^11.5.0", "html2canvas": "^1.4.1", "keymaster": "^1.6.2", - "naive-ui": "^2.30.3", + "monaco-editor": "^0.33.0", + "naive-ui": "2.30.3", "pinia": "^2.0.13", "screenfull": "^6.0.1", "vue": "^3.2.31", @@ -63,6 +64,7 @@ "vite-plugin-compression": "^0.5.1", "vite-plugin-importer": "^0.2.5", "vite-plugin-mock": "^2.9.6", + "vite-plugin-monaco-editor": "^1.1.0", "vue-echarts": "^6.0.2", "vue-tsc": "^0.28.10" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a9ea1c2b..7361e67b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -34,7 +34,8 @@ specifiers: keymaster: ^1.6.2 lodash: ~4.17.21 mockjs: ^1.1.0 - naive-ui: ^2.30.3 + monaco-editor: ^0.33.0 + naive-ui: 2.30.3 pinia: ^2.0.13 plop: ^3.0.5 prettier: ^2.6.2 @@ -46,6 +47,7 @@ specifiers: vite-plugin-compression: ^0.5.1 vite-plugin-importer: ^0.2.5 vite-plugin-mock: ^2.9.6 + vite-plugin-monaco-editor: ^1.1.0 vue: ^3.2.31 vue-demi: ^0.13.1 vue-echarts: ^6.0.2 @@ -68,6 +70,7 @@ dependencies: highlight.js: 11.5.1 html2canvas: 1.4.1 keymaster: 1.6.2 + monaco-editor: 0.33.0 naive-ui: 2.30.3_vue@3.2.37 pinia: 2.0.14_vcmyupim4cga7k7f5hngmth5py screenfull: 6.0.1 @@ -111,6 +114,7 @@ devDependencies: vite-plugin-compression: 0.5.1_vite@2.9.5 vite-plugin-importer: 0.2.5 vite-plugin-mock: 2.9.6_mockjs@1.1.0+vite@2.9.5 + vite-plugin-monaco-editor: 1.1.0_monaco-editor@0.33.0 vue-echarts: 6.0.3_echarts@5.3.3+vue@3.2.37 vue-tsc: 0.28.10_typescript@4.7.3 @@ -3756,6 +3760,10 @@ packages: commander: 9.3.0 dev: true + /monaco-editor/0.33.0: + resolution: {integrity: sha512-VcRWPSLIUEgQJQIE0pVT8FcGBIgFoxz7jtqctE+IiCxWugD0DwgyQBcZBhdSrdMC84eumoqMZsGl2GTreOzwqw==} + dev: false + /ms/2.0.0: resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} dev: true @@ -5105,6 +5113,14 @@ packages: - supports-color dev: true + /vite-plugin-monaco-editor/1.1.0_monaco-editor@0.33.0: + resolution: {integrity: sha512-IvtUqZotrRoVqwT0PBBDIZPNraya3BxN/bfcNfnxZ5rkJiGcNtO5eAOWWSgT7zullIAEqQwxMU83yL9J5k7gww==} + peerDependencies: + monaco-editor: '>=0.33.0' + dependencies: + monaco-editor: 0.33.0 + dev: true + /vite/2.9.5_sass@1.52.3: resolution: {integrity: sha512-dvMN64X2YEQgSXF1lYabKXw3BbN6e+BL67+P3Vy4MacnY+UzT1AfkHiioFSi9+uiDUiaDy7Ax/LQqivk6orilg==} engines: {node: '>=12.2.0'} diff --git a/src/components/Pages/MonacoEditor/EditorWorker.vue b/src/components/Pages/MonacoEditor/EditorWorker.vue new file mode 100644 index 00000000..5e2a6350 --- /dev/null +++ b/src/components/Pages/MonacoEditor/EditorWorker.vue @@ -0,0 +1,20 @@ + + + diff --git a/src/components/Pages/MonacoEditor/index.hook.ts b/src/components/Pages/MonacoEditor/index.hook.ts new file mode 100644 index 00000000..89b5a752 --- /dev/null +++ b/src/components/Pages/MonacoEditor/index.hook.ts @@ -0,0 +1,76 @@ +import { ref, onBeforeUnmount, nextTick } from 'vue' +import { useDesignStore } from '@/store/modules/designStore/designStore' +import * as monaco from 'monaco-editor/esm/vs/editor/editor.api.js' + +export const useMonacoEditor = (language = 'javascript') => { +const designStore = useDesignStore() + + let monacoEditor: monaco.editor.IStandaloneCodeEditor | null = null + let initReadOnly = false + const el = ref(null) + + // 格式化 + const onFormatDoc = async () => { + await monacoEditor?.getAction('monacoEditor.action.formatDocument')?.run() + } + + // 更新 + const updateVal = (val: string) => { + nextTick(async () => { + monacoEditor?.setValue(val) + initReadOnly && monacoEditor?.updateOptions({ readOnly: false }) + await onFormatDoc() + initReadOnly && monacoEditor?.updateOptions({ readOnly: true }) + }) + } + + // 创建实例 + const createEditor = (editorOption: monaco.editor.IStandaloneEditorConstructionOptions = {}) => { + if (!el.value) return + const javascriptModel = monaco.editor.createModel('', language) + initReadOnly = !!editorOption.readOnly + // 创建 + monacoEditor = monaco.editor.create(el.value, { + model: javascriptModel, + // 是否启用预览图 + minimap: { enabled: false }, + // 圆角 + roundedSelection: true, + // 主题 + theme: designStore.getDarkTheme ? 'vs-dark' : 'vs', + // 主键 + multiCursorModifier: 'ctrlCmd', + // 滚动条 + scrollbar: { + verticalScrollbarSize: 8, + horizontalScrollbarSize: 8 + }, + // 行号 + lineNumbers: 'off', + // tab大小 + tabSize: 2, + //字体大小 + fontSize: 16, + // 控制编辑器在用户键入、粘贴、移动或缩进行时是否应自动调整缩进 + autoIndent: 'advanced', + // 自动布局 + automaticLayout: true, + ...editorOption + }) + + return monacoEditor + } + + // 卸载 + onBeforeUnmount(() => { + if (monacoEditor) monacoEditor.dispose() + }) + + return { + el, + updateVal, + getEditor: () => monacoEditor, + createEditor, + onFormatDoc + } +} diff --git a/src/components/Pages/MonacoEditor/index.ts b/src/components/Pages/MonacoEditor/index.ts new file mode 100644 index 00000000..675bfe91 --- /dev/null +++ b/src/components/Pages/MonacoEditor/index.ts @@ -0,0 +1,4 @@ +import MonacoEditor from './index.vue'; +import EditorWorker from './EditorWorker.vue'; + +export { MonacoEditor, EditorWorker }; diff --git a/src/components/Pages/MonacoEditor/index.vue b/src/components/Pages/MonacoEditor/index.vue new file mode 100644 index 00000000..1a1349ce --- /dev/null +++ b/src/components/Pages/MonacoEditor/index.vue @@ -0,0 +1,92 @@ + + + + + diff --git a/src/components/Pages/ThemeColorSelect/index.vue b/src/components/Pages/ThemeColorSelect/index.vue index 96ce958c..38c9d819 100644 --- a/src/components/Pages/ThemeColorSelect/index.vue +++ b/src/components/Pages/ThemeColorSelect/index.vue @@ -20,7 +20,7 @@
{{ appThemeDetail.name }} - 中国色 + 中国色 (null) let fetchInterval: any = 0 - const requestInterval = () => { + const requestIntervalFn = () => { const chartEditStore = useChartEditStore() - const { requestOriginUrl, requestInterval } = toRefs( - chartEditStore.getRequestGlobalConfig - ) + const { requestOriginUrl, requestInterval } = toRefs(chartEditStore.getRequestGlobalConfig) // 组件类型 const { chartFrame } = targetComponent.chartConfig // 请求配置 - const { requestDataType, requestHttpType, requestUrl } = toRefs( - targetComponent.data - ) + const { requestDataType, requestHttpType, requestUrl } = toRefs(targetComponent.data) // 非请求类型 if (requestDataType.value !== RequestDataTypeEnum.AJAX) return // 处理地址 if (requestUrl?.value && requestInterval.value > 0) { // requestOriginUrl 允许为空 - const completePath = - requestOriginUrl && requestOriginUrl.value + requestUrl.value + const completePath = requestOriginUrl && requestOriginUrl.value + requestUrl.value if (!completePath) return + clearInterval(fetchInterval) + const fetchFn = async () => { const res = await http(requestHttpType.value)(completePath || '', {}) as unknown as MyResponseType if (res.data) { try { + const filter = targetComponent.filter // 更新回调函数 if (updateCallback) { - updateCallback(res.data) + updateCallback(newFunctionHandle(res.data, filter)) } else { // eCharts 组件配合 vChart 库更新方式 if (chartFrame === ChartFrameEnum.ECHARTS) { if (vChartRef.value) { - vChartRef.value.setOption({ dataset: res.data }) + vChartRef.value.setOption({ dataset: newFunctionHandle(res.data, filter) }) } } } @@ -63,15 +62,15 @@ export const useChartDataFetch = ( } } } - + // 立即调用 fetchFn() // 开启定时 - setInterval(fetchFn, requestInterval.value * 1000) + fetchInterval = setInterval(fetchFn, requestInterval.value * 1000) } } - isPreview() && requestInterval() + isPreview() && requestIntervalFn() return { vChartRef } } diff --git a/src/packages/components/Charts/Mores/Process/index.vue b/src/packages/components/Charts/Mores/Process/index.vue index 60818b1d..fb0b7b7f 100644 --- a/src/packages/components/Charts/Mores/Process/index.vue +++ b/src/packages/components/Charts/Mores/Process/index.vue @@ -15,7 +15,7 @@ fontSize: `${indicatorTextSize}px` }" > - {{option.dataset}} {{unit}} + {{ option.dataset }} {{ unit }} @@ -24,7 +24,8 @@ import { PropType, toRefs, watch, shallowReactive } from 'vue' import { useChartDataFetch } from '@/hooks' import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore' -import config, { option as configOption } from './config' +import config, { option as configOption } from './config' +import { toNumber } from '@/utils' const props = defineProps({ chartConfig: { @@ -39,7 +40,6 @@ const { type, unit, color, - fontSize, processing, railColor, indicatorTextColor, @@ -57,11 +57,11 @@ const option = shallowReactive({ watch( () => props.chartConfig.option.dataset, (newData: any) => { - option.dataset = newData + option.dataset = toNumber(newData, 2) } ) // 预览更新 useChartDataFetch(props.chartConfig, useChartEditStore, (newData: number) => { - option.dataset = newData + option.dataset = toNumber(newData, 2) }) diff --git a/src/packages/components/Charts/Mores/WaterPolo/index.vue b/src/packages/components/Charts/Mores/WaterPolo/index.vue index 36af753b..270f0137 100644 --- a/src/packages/components/Charts/Mores/WaterPolo/index.vue +++ b/src/packages/components/Charts/Mores/WaterPolo/index.vue @@ -10,7 +10,7 @@ import 'echarts-liquidfill/src/liquidFill.js' import { CanvasRenderer } from 'echarts/renderers' import { GridComponent } from 'echarts/components' import config from './config' -import { isPreview } from '@/utils' +import { isPreview, isString } from '@/utils' import { chartColorsSearch, defaultTheme } from '@/settings/chartThemes/index' import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore' import { useChartDataFetch } from '@/hooks' @@ -66,7 +66,8 @@ watch( ) // 数据处理 -const dataHandle = (newData: number) => { +const dataHandle = (newData: number | string) => { + newData = isString(newData) ? parseFloat(newData) : newData return parseFloat(newData.toFixed(2)) } @@ -74,7 +75,6 @@ const dataHandle = (newData: number) => { watch( () => props.chartConfig.option.dataset, newData => { - console.log(dataHandle(newData)) props.chartConfig.option.series[0].data = [dataHandle(newData)] option.value = props.chartConfig.option }, diff --git a/src/packages/index.d.ts b/src/packages/index.d.ts index 02c50e9b..8d27862e 100644 --- a/src/packages/index.d.ts +++ b/src/packages/index.d.ts @@ -2,9 +2,14 @@ import type { GlobalThemeJsonType } from '@/settings/chartThemes/index' import type { RequestConfigType } from '@/store/modules/chartEditStore/chartEditStore.d' export enum ChartFrameEnum { - COMMON = 'common', + // echarts 框架 ECHARTS = 'echarts', - NAIVE_UI = 'naiveUI' + // UI 组件框架 + NAIVE_UI = 'naiveUI', + // 自定义带数据组件 + COMMON = 'common', + // 无数据变更 + STATIC = 'static' } // 组件配置 @@ -77,6 +82,7 @@ export interface PublicConfigType extends requestConfig { // 动画 animations: string[] } + filter?: string setPosition: Function } diff --git a/src/packages/public/publicConfig.ts b/src/packages/public/publicConfig.ts index 25d75d7f..05df5e28 100644 --- a/src/packages/public/publicConfig.ts +++ b/src/packages/public/publicConfig.ts @@ -45,6 +45,8 @@ export class publicConfig implements PublicConfigType { public data = { ...requestConfig } // 数据获取 public requestData = [] + // 数据过滤 + public filter = undefined // 设置坐标 public setPosition(x: number, y: number): void { diff --git a/src/store/modules/chartEditStore/chartEditStore.ts b/src/store/modules/chartEditStore/chartEditStore.ts index 86ed7b3c..b1052b87 100644 --- a/src/store/modules/chartEditStore/chartEditStore.ts +++ b/src/store/modules/chartEditStore/chartEditStore.ts @@ -188,6 +188,9 @@ export const useChartEditStore = defineStore({ }, // * 设置目标数据 select setTargetSelectChart(selectId?: string | string[], push: boolean = false) { + // 重复选中 + if(this.targetChart.selectId.find((e: string) => e === selectId)) return + // 无 id 清空 if(!selectId) { this.targetChart.selectId = [] diff --git a/src/utils/style.ts b/src/utils/style.ts index 1d7a4a84..ee1bec51 100644 --- a/src/utils/style.ts +++ b/src/utils/style.ts @@ -24,7 +24,7 @@ export const getFilterStyle = (styles: StylesType | EditCanvasConfigType) => { } // 变换 -export const getTranstormStyle = (styles: StylesType) => { +export const getTransformStyle = (styles: StylesType) => { const { rotateZ, rotateX, rotateY, skewX, skewY } = styles return { transform: `rotateZ(${rotateZ || 0}deg) rotateX(${rotateX || 0}deg) rotateY(${rotateY || 0}deg) skewX(${skewX || 0}deg) skewY(${skewY || 0}deg)`, diff --git a/src/utils/type.ts b/src/utils/type.ts index 57a925d6..7b86c022 100644 --- a/src/utils/type.ts +++ b/src/utils/type.ts @@ -1,3 +1,5 @@ +import isObject from 'lodash/isObject' + export function isString(p: any): p is string { return typeof p === 'string' } @@ -21,3 +23,11 @@ export function isNull(p: any): p is null { export function isArray(p: any): p is [] { return Array.isArray(p) } + +export const toNumber = (number: number | string, toFixedNumber = 2) => { + return isString(number) ? parseFloat(parseFloat(number).toFixed(2)) : number +} + +export const toString = (str: any) => { + return isNumber(str) ? `${str}` : (isObject(str) ? JSON.stringify(str) : str) +} \ No newline at end of file diff --git a/src/utils/utils.ts b/src/utils/utils.ts index 1059ebe8..92b625b2 100644 --- a/src/utils/utils.ts +++ b/src/utils/utils.ts @@ -5,6 +5,8 @@ import throttle from 'lodash/throttle' import Image_404 from '../assets/images/exception/image-404.png' import html2canvas from 'html2canvas' import { downloadByA } from './file' +import { toString } from './type' +import cloneDeep from 'lodash/cloneDeep'; /** * * 判断是否是开发环境 @@ -19,9 +21,7 @@ export const isDev = () => { * @param { Number } randomLength */ export const getUUID = (randomLength = 10) => { - return Number( - Math.random().toString().substr(2, randomLength) + Date.now() - ).toString(36) + return Number(Math.random().toString().substr(2, randomLength) + Date.now()).toString(36) } /** @@ -90,10 +90,7 @@ export const screenfullFn = (isFullscreen?: boolean, isEnabled?: boolean) => { * @param key 键名 * @param value 键值 */ -export const setDomAttribute = < - K extends keyof CSSStyleDeclaration, - V extends CSSStyleDeclaration[K] ->( +export const setDomAttribute = ( HTMLElement: HTMLElement, key: K, value: V @@ -126,7 +123,7 @@ export const addEventListener = ( type, throttle(listener, delay || 300, { leading: true, - trailing: false, + trailing: false }), options ) @@ -163,3 +160,34 @@ export const canvasCut = (html: HTMLElement | null, callback?: Function) => { if (callback) callback() }) } + +/** + * * 函数过滤器 + * @param data 数据值 + * @param funcStr 函数字符串 + * @param toString 转为字符串 + * @param errorCallBack 错误回调函数 + * @param successCallBack 成功回调函数 + * @returns + */ +export const newFunctionHandle = ( + data: any, + funcStr?: string, + isToString?: boolean, + errorCallBack?: Function, + successCallBack?: Function +) => { + try { + if (!funcStr) return data + const fn = new Function('data', funcStr) + const fnRes = fn( cloneDeep(data)) + const resHandle = isToString ? toString(fnRes) : fnRes + // 成功回调 + successCallBack && successCallBack(resHandle) + return resHandle + } catch (error) { + // 失败回调 + errorCallBack && errorCallBack(error) + return '函数执行错误' + } +} diff --git a/src/views/chart/ContentConfigurations/components/ChartData/components/ChartDataAjax/index.vue b/src/views/chart/ContentConfigurations/components/ChartData/components/ChartDataAjax/index.vue index 3098f6f1..c9e32045 100644 --- a/src/views/chart/ContentConfigurations/components/ChartData/components/ChartDataAjax/index.vue +++ b/src/views/chart/ContentConfigurations/components/ChartData/components/ChartDataAjax/index.vue @@ -1,10 +1,7 @@ - + - + + diff --git a/src/views/chart/ContentConfigurations/components/ChartData/components/ChartDataStatic/index.vue b/src/views/chart/ContentConfigurations/components/ChartData/components/ChartDataStatic/index.vue index 78f91e6e..d2867918 100644 --- a/src/views/chart/ContentConfigurations/components/ChartData/components/ChartDataStatic/index.vue +++ b/src/views/chart/ContentConfigurations/components/ChartData/components/ChartDataStatic/index.vue @@ -1,6 +1,6 @@ diff --git a/src/views/chart/ContentConfigurations/components/ChartData/index.d.ts b/src/views/chart/ContentConfigurations/components/ChartData/index.d.ts index d12766ad..c6707bcb 100644 --- a/src/views/chart/ContentConfigurations/components/ChartData/index.d.ts +++ b/src/views/chart/ContentConfigurations/components/ChartData/index.d.ts @@ -8,6 +8,7 @@ export enum DataResultEnum { } export enum TimelineTitleEnum { + FILTER = '数据过滤', MAPPING = '数据映射', CONTENT = '数据内容', } diff --git a/src/views/chart/ContentEdit/index.vue b/src/views/chart/ContentEdit/index.vue index 3b80d192..129a55a1 100644 --- a/src/views/chart/ContentEdit/index.vue +++ b/src/views/chart/ContentEdit/index.vue @@ -42,7 +42,7 @@ :style="{ ...useSizeStyle(item.attr), ...getFilterStyle(item.styles), - ...getTranstormStyle(item.styles), + ...getTransformStyle(item.styles), }" > @@ -65,7 +65,7 @@