mirror of
https://gitee.com/dromara/go-view.git
synced 2024-12-02 03:38:27 +08:00
Merge branch 'dev'
This commit is contained in:
commit
b94b44090b
@ -172,7 +172,9 @@ export const customizeHttp = (targetParams: RequestConfigType, globalParams: Req
|
||||
|
||||
case RequestBodyEnum.JSON:
|
||||
headers['Content-Type'] = ContentTypeEnum.JSON
|
||||
data = translateStr(JSON.parse(targetRequestParams.Body['json']))
|
||||
//json对象也能使用'javasctipt:'来动态拼接参数
|
||||
data = translateStr(targetRequestParams.Body['json'])
|
||||
if(typeof data === 'string') data = JSON.parse(data)
|
||||
// json 赋值给 data
|
||||
break
|
||||
|
||||
|
BIN
src/assets/images/chart/informations/photo_carousel.png
Normal file
BIN
src/assets/images/chart/informations/photo_carousel.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
@ -12,7 +12,8 @@ export enum DragKeyEnum {
|
||||
// 不同页面保存操作
|
||||
export enum SavePageEnum {
|
||||
CHART = 'SaveChart',
|
||||
JSON = 'SaveJSON'
|
||||
JSON = 'SaveJSON',
|
||||
CLOSE = 'close'
|
||||
}
|
||||
|
||||
// 操作枚举
|
||||
|
@ -7,15 +7,15 @@ export enum BaseEvent {
|
||||
// 移入
|
||||
ON_MOUSE_ENTER = 'mouseenter',
|
||||
// 移出
|
||||
ON_MOUSE_LEAVE = 'mouseleave',
|
||||
ON_MOUSE_LEAVE = 'mouseleave'
|
||||
}
|
||||
|
||||
// vue3 生命周期事件
|
||||
export enum EventLife {
|
||||
export enum EventLife {
|
||||
// 渲染之后
|
||||
VNODE_MOUNTED = 'vnodeMounted',
|
||||
// 渲染之前
|
||||
VNODE_BEFORE_MOUNT = 'vnodeBeforeMount',
|
||||
VNODE_BEFORE_MOUNT = 'vnodeBeforeMount'
|
||||
}
|
||||
|
||||
// 内置字符串函数对象列表
|
||||
@ -28,4 +28,9 @@ export const excludeParseEventKeyList = [
|
||||
BaseEvent.ON_MOUSE_LEAVE,
|
||||
//过滤器
|
||||
'filter'
|
||||
]
|
||||
]
|
||||
// 内置字符串函数键值列表
|
||||
export const excludeParseEventValueList = [
|
||||
// 请求里的函数语句
|
||||
'javascript:'
|
||||
]
|
||||
|
@ -29,7 +29,7 @@ import { ThemeColorSelect } from '@/components/Pages/ThemeColorSelect'
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
$min-width: 400px;
|
||||
$min-width: 520px;
|
||||
@include go(header) {
|
||||
&-box {
|
||||
display: grid;
|
||||
|
@ -59,13 +59,14 @@ const getGeojson = (regionId: string) => {
|
||||
}
|
||||
|
||||
//异步时先注册空的 保证初始化不报错
|
||||
registerMap(props.chartConfig.option.mapRegion.adcode, { geoJSON: {} as any, specialAreas: {} })
|
||||
registerMap(`${props.chartConfig.option.mapRegion.adcode}`, { geoJSON: {} as any, specialAreas: {} })
|
||||
|
||||
// 进行更换初始化地图 如果为china 单独处理
|
||||
const registerMapInitAsync = async () => {
|
||||
await nextTick()
|
||||
if (props.chartConfig.option.mapRegion.adcode != 'china') {
|
||||
await getGeojson(props.chartConfig.option.mapRegion.adcode)
|
||||
const adCode = `${props.chartConfig.option.mapRegion.adcode}`;
|
||||
if (adCode !== 'china') {
|
||||
await getGeojson(adCode)
|
||||
} else {
|
||||
await hainanLandsHandle(props.chartConfig.option.mapRegion.showHainanIsLands)
|
||||
}
|
||||
@ -127,7 +128,7 @@ watch(
|
||||
|
||||
//监听地图展示区域发生变化
|
||||
watch(
|
||||
() => props.chartConfig.option.mapRegion.adcode,
|
||||
() => `${props.chartConfig.option.mapRegion.adcode}`,
|
||||
async newData => {
|
||||
try {
|
||||
await getGeojson(newData)
|
||||
|
@ -0,0 +1,44 @@
|
||||
import { PublicConfigClass } from '@/packages/public'
|
||||
import { CreateComponentType } from '@/packages/index.d'
|
||||
import { ImageCarouselConfig } from './index'
|
||||
import cloneDeep from 'lodash/cloneDeep'
|
||||
import logo from '@/assets/logo.png'
|
||||
|
||||
export const option = {
|
||||
// 图片资源列表
|
||||
dataset: [
|
||||
'https://naive-ui.oss-cn-beijing.aliyuncs.com/carousel-img/carousel1.jpeg',
|
||||
'https://naive-ui.oss-cn-beijing.aliyuncs.com/carousel-img/carousel2.jpeg',
|
||||
'https://naive-ui.oss-cn-beijing.aliyuncs.com/carousel-img/carousel3.jpeg',
|
||||
],
|
||||
// 自动播放
|
||||
autoplay: true,
|
||||
// 自动播放的间隔(豪秒)
|
||||
interval: 5000,
|
||||
// 每页显示的图片数量
|
||||
slidesPerview: 1,
|
||||
// 轮播方向
|
||||
direction: "horizontal",
|
||||
// 拖曳切换
|
||||
draggable: true,
|
||||
// 居中显示
|
||||
centeredSlides: false,
|
||||
// 过渡效果
|
||||
effect: "slide",
|
||||
// 是否显示指示点
|
||||
showDots: true,
|
||||
// 指示器样式
|
||||
dotType: "dot",
|
||||
// 指示器位置
|
||||
dotPlacement: "bottom",
|
||||
// 显示箭头
|
||||
showArrow: false,
|
||||
// 图片样式
|
||||
fit: "contain",
|
||||
}
|
||||
|
||||
export default class Config extends PublicConfigClass implements CreateComponentType {
|
||||
public key = ImageCarouselConfig.key
|
||||
public chartConfig = cloneDeep(ImageCarouselConfig)
|
||||
public option = cloneDeep(option)
|
||||
}
|
@ -0,0 +1,168 @@
|
||||
<template>
|
||||
<collapse-item name="路径" :expanded="true">
|
||||
<setting-item v-for="(item, index) in optionData.dataset" :key="index">
|
||||
<n-input-group>
|
||||
<n-input v-model:value="optionData.dataset[index]" size="small" placeholder="请输入图片地址"></n-input>
|
||||
<n-button ghost @click="optionData.dataset.splice(index, 1)"> - </n-button>
|
||||
</n-input-group>
|
||||
</setting-item>
|
||||
<setting-item>
|
||||
<n-button size="small" @click="optionData.dataset.push('')"> + 新增</n-button>
|
||||
</setting-item>
|
||||
</collapse-item>
|
||||
<collapse-item name="轮播属性" :expanded="true">
|
||||
<setting-item-box name="播放器">
|
||||
<setting-item>
|
||||
<n-space>
|
||||
<n-switch v-model:value="optionData.autoplay" size="small" />
|
||||
<n-text>自动播放</n-text>
|
||||
</n-space>
|
||||
</setting-item>
|
||||
<!-- 开启自动播放时,设置间隔时间 -->
|
||||
<setting-item name="间隔时间">
|
||||
<n-input-number v-model:value="optionData.interval" size="small" placeholder="">
|
||||
<template #suffix> 毫秒 </template>
|
||||
</n-input-number>
|
||||
</setting-item>
|
||||
<setting-item name="轮播方向">
|
||||
<n-select v-model:value="optionData.direction" :options="directions" placeholder="选择方向" />
|
||||
</setting-item>
|
||||
<setting-item name="过渡效果">
|
||||
<n-select v-model:value="optionData.effect" :options="effects" placeholder="效果" />
|
||||
</setting-item>
|
||||
<setting-item name="每页数量">
|
||||
<n-input-number v-model:value="optionData.slidesPerview" size="small" placeholder=""></n-input-number>
|
||||
</setting-item>
|
||||
<setting-item>
|
||||
<n-space>
|
||||
<n-switch v-model:value="optionData.centeredSlides" size="small" />
|
||||
<n-text>居中显示</n-text>
|
||||
</n-space>
|
||||
</setting-item>
|
||||
<setting-item name="图片样式">
|
||||
<n-select v-model:value="optionData.fit" :options="fitList" placeholder="样式" />
|
||||
</setting-item>
|
||||
</setting-item-box>
|
||||
<setting-item-box name="指示器">
|
||||
<setting-item name="样式">
|
||||
<n-select v-model:value="optionData.dotType" :options="dotTypes" placeholder="选择样式" />
|
||||
</setting-item>
|
||||
<setting-item name="位置">
|
||||
<n-select v-model:value="optionData.dotPlacement" :options="dotPlacements" placeholder="选择位置" />
|
||||
</setting-item>
|
||||
<setting-item>
|
||||
<n-space>
|
||||
<n-switch v-model:value="optionData.showDots" size="small" />
|
||||
<n-text>显示</n-text>
|
||||
</n-space>
|
||||
</setting-item>
|
||||
<setting-item>
|
||||
<n-space>
|
||||
<n-switch v-model:value="optionData.showArrow" size="small" />
|
||||
<n-text>箭头</n-text>
|
||||
</n-space>
|
||||
</setting-item>
|
||||
<setting-item>
|
||||
<n-space>
|
||||
<n-switch v-model:value="optionData.draggable" size="small" />
|
||||
<n-text>拖曳切换</n-text>
|
||||
</n-space>
|
||||
</setting-item>
|
||||
</setting-item-box>
|
||||
</collapse-item>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { PropType } from 'vue'
|
||||
import { option } from './config'
|
||||
import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
|
||||
|
||||
const props = defineProps({
|
||||
optionData: {
|
||||
type: Object as PropType<typeof option>,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
|
||||
// 字典
|
||||
const dotTypes = [
|
||||
{
|
||||
label: '点',
|
||||
value: 'dot'
|
||||
},
|
||||
{
|
||||
label: '线',
|
||||
value: 'line'
|
||||
}
|
||||
]
|
||||
const directions = [
|
||||
{
|
||||
label: '水平方向',
|
||||
value: 'horizontal'
|
||||
},
|
||||
{
|
||||
label: '垂直方向',
|
||||
value: 'vertical'
|
||||
}
|
||||
]
|
||||
const effects = [
|
||||
{
|
||||
label: 'slide',
|
||||
value: 'slide'
|
||||
},
|
||||
{
|
||||
label: 'fade',
|
||||
value: 'fade'
|
||||
},
|
||||
{
|
||||
label: 'card',
|
||||
value: 'card'
|
||||
},
|
||||
{
|
||||
label: 'custom',
|
||||
value: 'custom'
|
||||
}
|
||||
]
|
||||
const dotPlacements = [
|
||||
{
|
||||
label: '上边',
|
||||
value: 'top'
|
||||
},
|
||||
{
|
||||
label: '下边',
|
||||
value: 'bottom'
|
||||
},
|
||||
{
|
||||
label: '左边',
|
||||
value: 'left'
|
||||
},
|
||||
{
|
||||
label: '右边',
|
||||
value: 'right'
|
||||
}
|
||||
]
|
||||
|
||||
// 适应类型
|
||||
const fitList = [
|
||||
{
|
||||
value: 'fill',
|
||||
label: 'fill'
|
||||
},
|
||||
{
|
||||
value: 'contain',
|
||||
label: 'contain'
|
||||
},
|
||||
{
|
||||
value: 'cover',
|
||||
label: 'cover'
|
||||
},
|
||||
{
|
||||
value: 'scale-down',
|
||||
label: 'scale-down'
|
||||
},
|
||||
{
|
||||
value: 'none',
|
||||
label: 'none'
|
||||
}
|
||||
]
|
||||
</script>
|
@ -0,0 +1,14 @@
|
||||
import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d'
|
||||
import { ChatCategoryEnum, ChatCategoryEnumName } from '../../index.d'
|
||||
|
||||
export const ImageCarouselConfig: ConfigType = {
|
||||
key: 'ImageCarousel',
|
||||
chartKey: 'VImageCarousel',
|
||||
conKey: 'VCImageCarousel',
|
||||
title: '轮播图',
|
||||
category: ChatCategoryEnum.MORE,
|
||||
categoryName: ChatCategoryEnumName.MORE,
|
||||
package: PackagesCategoryEnum.INFORMATIONS,
|
||||
chartFrame: ChartFrameEnum.NAIVE_UI,
|
||||
image: 'photo_carousel.png'
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
<template>
|
||||
<div>
|
||||
<n-carousel
|
||||
:autoplay="autoplay"
|
||||
:interval="interval"
|
||||
:centered-slides="centeredSlides"
|
||||
:direction="direction"
|
||||
:dot-placement="dotPlacement"
|
||||
:dot-type="dotType"
|
||||
:draggable="draggable"
|
||||
:effect="effect"
|
||||
:slides-per-view="slidesPerview"
|
||||
:show-arrow="showArrow"
|
||||
:show-dots="showDots"
|
||||
>
|
||||
<n-image
|
||||
v-for="(url, index) in option.dataset"
|
||||
preview-disabled
|
||||
:key="index"
|
||||
:object-fit="fit"
|
||||
:src="url"
|
||||
:fallback-src="requireErrorImg()"
|
||||
:width="w"
|
||||
:height="h"
|
||||
></n-image>
|
||||
</n-carousel>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { PropType, toRefs, shallowReactive, watch } from 'vue'
|
||||
import { CreateComponentType } from '@/packages/index.d'
|
||||
import { requireErrorImg } from '@/utils'
|
||||
import { useChartDataFetch } from '@/hooks'
|
||||
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
|
||||
import { option as configOption } from './config'
|
||||
|
||||
const props = defineProps({
|
||||
chartConfig: {
|
||||
type: Object as PropType<CreateComponentType>,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
|
||||
const option = shallowReactive({
|
||||
dataset: configOption.dataset
|
||||
})
|
||||
|
||||
const { w, h } = toRefs(props.chartConfig.attr)
|
||||
const {
|
||||
autoplay,
|
||||
interval,
|
||||
slidesPerview,
|
||||
direction,
|
||||
draggable,
|
||||
centeredSlides,
|
||||
effect,
|
||||
dotType,
|
||||
dotPlacement,
|
||||
showArrow,
|
||||
showDots,
|
||||
fit
|
||||
} = toRefs(props.chartConfig.option)
|
||||
|
||||
watch(
|
||||
() => props.chartConfig.option.dataset,
|
||||
(newData: any) => {
|
||||
option.dataset = newData
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
deep: false
|
||||
}
|
||||
)
|
||||
|
||||
useChartDataFetch(props.chartConfig, useChartEditStore, (newData: any) => {
|
||||
option.dataset = newData
|
||||
})
|
||||
</script>
|
@ -1,7 +1,8 @@
|
||||
import { ImageConfig } from './Image/index'
|
||||
import { ImageCarouselConfig } from './ImageCarousel/index'
|
||||
import { IframeConfig } from './Iframe/index'
|
||||
import { VideoConfig } from './Video/index'
|
||||
import { WordCloudConfig } from './WordCloud/index'
|
||||
import { CarouselConfig } from './Carousel/index'
|
||||
|
||||
export default [WordCloudConfig, ImageConfig, VideoConfig, IframeConfig, CarouselConfig]
|
||||
export default [ImageConfig, ImageCarouselConfig, VideoConfig, IframeConfig, WordCloudConfig]
|
||||
|
@ -66,7 +66,8 @@ import {
|
||||
List as ListIcon,
|
||||
EyeOutline as EyeOutlineIcon,
|
||||
EyeOffOutline as EyeOffOutlineIcon,
|
||||
Albums as AlbumsIcon
|
||||
Albums as AlbumsIcon,
|
||||
Analytics as AnalyticsIcon
|
||||
} from '@vicons/ionicons5'
|
||||
|
||||
import {
|
||||
@ -238,7 +239,9 @@ const ionicons5 = {
|
||||
EyeOutlineIcon,
|
||||
EyeOffOutlineIcon,
|
||||
// 图表列表
|
||||
AlbumsIcon
|
||||
AlbumsIcon,
|
||||
// 分析
|
||||
AnalyticsIcon
|
||||
}
|
||||
|
||||
const carbon = {
|
||||
|
@ -22,7 +22,8 @@ export enum EditCanvasTypeEnum {
|
||||
LOCK_SCALE = 'lockScale',
|
||||
IS_CREATE = 'isCreate',
|
||||
IS_DRAG = 'isDrag',
|
||||
IS_SELECT = 'isSelect'
|
||||
IS_SELECT = 'isSelect',
|
||||
IS_CODE_EDIT="isCodeEdit"
|
||||
}
|
||||
|
||||
// 编辑区域
|
||||
@ -44,6 +45,8 @@ export type EditCanvasType = {
|
||||
[EditCanvasTypeEnum.IS_DRAG]: boolean
|
||||
// 框选中
|
||||
[EditCanvasTypeEnum.IS_SELECT]: boolean
|
||||
// 代码编辑中
|
||||
[EditCanvasTypeEnum.IS_CODE_EDIT]: boolean
|
||||
}
|
||||
|
||||
// 滤镜/背景色/宽高主题等
|
||||
|
@ -54,7 +54,9 @@ export const useChartEditStore = defineStore({
|
||||
// 拖拽中
|
||||
isDrag: false,
|
||||
// 框选中
|
||||
isSelect: false
|
||||
isSelect: false,
|
||||
// 代码编辑中
|
||||
isCodeEdit: false
|
||||
},
|
||||
// 右键菜单
|
||||
rightMenuShow: false,
|
||||
|
@ -10,7 +10,7 @@ import cloneDeep from 'lodash/cloneDeep'
|
||||
import { WinKeyboard } from '@/enums/editPageEnum'
|
||||
import { RequestHttpIntervalEnum, RequestParamsObjType } from '@/enums/httpEnum'
|
||||
import { CreateComponentType, CreateComponentGroupType } from '@/packages/index.d'
|
||||
import { excludeParseEventKeyList } from '@/enums/eventEnum'
|
||||
import { excludeParseEventKeyList, excludeParseEventValueList } from '@/enums/eventEnum'
|
||||
|
||||
/**
|
||||
* * 判断是否是开发环境
|
||||
@ -320,10 +320,17 @@ export const JSONStringify = <T>(data: T) => {
|
||||
*/
|
||||
export const JSONParse = (data: string) => {
|
||||
return JSON.parse(data, (k, v) => {
|
||||
// 过滤函数字符串
|
||||
if (excludeParseEventKeyList.includes(k)) return v
|
||||
// 过滤函数值表达式
|
||||
if (typeof v === 'string') {
|
||||
const someValue = excludeParseEventValueList.some(excludeValue => v.indexOf(excludeValue) > -1)
|
||||
if (someValue) return v
|
||||
}
|
||||
// 还原函数值
|
||||
if (typeof v === 'string' && v.indexOf && (v.indexOf('function') > -1 || v.indexOf('=>') > -1)) {
|
||||
return eval(`(function(){return ${v}})()`)
|
||||
} else if (typeof v === 'string' && v.indexOf && (v.indexOf('return ') > -1)) {
|
||||
} else if (typeof v === 'string' && v.indexOf && v.indexOf('return ') > -1) {
|
||||
const baseLeftIndex = v.indexOf('(')
|
||||
if (baseLeftIndex > -1) {
|
||||
const newFn = `function ${v.substring(baseLeftIndex)}`
|
||||
@ -340,4 +347,4 @@ export const JSONParse = (data: string) => {
|
||||
*/
|
||||
export const setTitle = (title?: string) => {
|
||||
title && (document.title = title)
|
||||
}
|
||||
}
|
||||
|
@ -1,42 +1,68 @@
|
||||
import { watch } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import throttle from 'lodash/throttle'
|
||||
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
|
||||
import { EditCanvasTypeEnum } from '@/store/modules/chartEditStore/chartEditStore.d'
|
||||
import { useSync } from '@/views/chart/hooks/useSync.hook'
|
||||
import { ChartEnum } from '@/enums/pageEnum'
|
||||
import { SavePageEnum } from '@/enums/editPageEnum'
|
||||
import { editToJsonInterval } from '@/settings/designSetting'
|
||||
import { goDialog } from '@/utils'
|
||||
|
||||
const { updateComponent } = useSync()
|
||||
const chartEditStore = useChartEditStore()
|
||||
|
||||
export const syncData = () => {
|
||||
goDialog({
|
||||
message: '是否覆盖源视图内容,此操作不可撤回?',
|
||||
isMaskClosable: true,
|
||||
transformOrigin: 'center',
|
||||
onPositiveCallback: () => {
|
||||
window['$message'].success('正在同步编辑器...')
|
||||
dispatchEvent(new CustomEvent(SavePageEnum.CHART, { detail: chartEditStore.getStorageInfo }))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 侦听器更新
|
||||
const useSyncUpdateHandle = () => {
|
||||
// 定义侦听器变量
|
||||
let timer: any
|
||||
const updateFn = (e: any) => updateComponent(e!.detail, true, false)
|
||||
const syncData = async () => {
|
||||
dispatchEvent(new CustomEvent(SavePageEnum.CHART, { detail: chartEditStore.getStorageInfo }))
|
||||
|
||||
// 更新处理
|
||||
const updateFn = (e: any) => {
|
||||
window['$message'].success('正在进行更新...')
|
||||
updateComponent(e!.detail, true)
|
||||
}
|
||||
|
||||
// 页面关闭处理
|
||||
const closeFn = () => {
|
||||
chartEditStore.setEditCanvas(EditCanvasTypeEnum.IS_CODE_EDIT, false)
|
||||
}
|
||||
|
||||
// 开启侦听
|
||||
const use = () => {
|
||||
// // 1、定时同步数据
|
||||
// 定时同步数据(暂不开启)
|
||||
// timer = setInterval(() => {
|
||||
// // 窗口激活并且处于工作台
|
||||
// document.hasFocus() && syncData()
|
||||
// }, editToJsonInterval)
|
||||
// 2、失焦同步数据
|
||||
addEventListener('blur', syncData)
|
||||
|
||||
// 【监听JSON代码 刷新工作台图表】
|
||||
// 失焦同步数据(暂不开启)
|
||||
// addEventListener('blur', syncData)
|
||||
|
||||
// 监听编辑器保存事件 刷新工作台图表
|
||||
addEventListener(SavePageEnum.JSON, updateFn)
|
||||
|
||||
// 监听编辑页关闭
|
||||
addEventListener(SavePageEnum.CLOSE, throttle(closeFn, 1000))
|
||||
}
|
||||
|
||||
// 关闭侦听
|
||||
const unUse = () => {
|
||||
// clearInterval(timer)
|
||||
// removeEventListener('blur', syncData)
|
||||
removeEventListener(SavePageEnum.JSON, updateFn)
|
||||
removeEventListener('blur', syncData)
|
||||
}
|
||||
|
||||
// 路由变更时处理
|
||||
@ -48,11 +74,11 @@ const useSyncUpdateHandle = () => {
|
||||
use()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return watchHandler
|
||||
}
|
||||
|
||||
export const useSyncUpdate = () => {
|
||||
const routerParamsInfo = useRoute()
|
||||
watch(() => routerParamsInfo.name, useSyncUpdateHandle(), { immediate: true })
|
||||
}
|
||||
}
|
||||
|
@ -66,7 +66,14 @@ import { ref, computed } from 'vue'
|
||||
import { useSettingStore } from '@/store/modules/settingStore/settingStore'
|
||||
import { ToolsStatusEnum } from '@/store/modules/settingStore/settingStore.d'
|
||||
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
|
||||
import { fetchRouteParamsLocation, fetchPathByName, routerTurnByPath, setSessionStorage, getLocalStorage } from '@/utils'
|
||||
import { EditCanvasTypeEnum } from '@/store/modules/chartEditStore/chartEditStore.d'
|
||||
import {
|
||||
fetchRouteParamsLocation,
|
||||
fetchPathByName,
|
||||
routerTurnByPath,
|
||||
setSessionStorage,
|
||||
getLocalStorage
|
||||
} from '@/utils'
|
||||
import { EditEnum } from '@/enums/pageEnum'
|
||||
import { StorageEnum } from '@/enums/storageEnum'
|
||||
import { useRoute } from 'vue-router'
|
||||
@ -137,8 +144,8 @@ const toolsMouseoutHandle = () => {
|
||||
|
||||
// 编辑处理
|
||||
const editHandle = () => {
|
||||
window['$message'].warning('将开启失焦更新!')
|
||||
// window['$message'].warning('将开启失焦更新与 5 秒同步更新!')
|
||||
window['$message'].warning('请通过顶部【同步内容】按钮同步最新数据!')
|
||||
chartEditStore.setEditCanvas(EditCanvasTypeEnum.IS_CODE_EDIT, true)
|
||||
setTimeout(() => {
|
||||
// 获取id路径
|
||||
const path = fetchPathByName(EditEnum.CHART_EDIT_NAME, 'href')
|
||||
@ -146,7 +153,7 @@ const editHandle = () => {
|
||||
const id = fetchRouteParamsLocation()
|
||||
updateToSession(id)
|
||||
routerTurnByPath(path, [id], undefined, true)
|
||||
}, 1000)
|
||||
}, 2000)
|
||||
}
|
||||
|
||||
// 把内存中的数据同步到SessionStorage 便于传递给新窗口初始化数据
|
||||
@ -169,7 +176,6 @@ const updateToSession = (id: string) => {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 配置列表
|
||||
const btnList: BtnListType[] = [
|
||||
{
|
||||
|
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<n-space class="go-mt-0">
|
||||
<n-button v-for="item in btnList" :key="item.title" ghost @click="item.event">
|
||||
<n-button v-for="item in comBtnList" :key="item.title" :type="item.type" ghost @click="item.event">
|
||||
<template #icon>
|
||||
<component :is="item.icon"></component>
|
||||
</template>
|
||||
@ -10,16 +10,17 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { shallowReactive } from 'vue'
|
||||
import { computed } from 'vue'
|
||||
import { renderIcon, goDialog, fetchPathByName, routerTurnByPath, setSessionStorage, getLocalStorage } from '@/utils'
|
||||
import { PreviewEnum } from '@/enums/pageEnum'
|
||||
import { StorageEnum } from '@/enums/storageEnum'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
|
||||
import { EditCanvasTypeEnum } from '@/store/modules/chartEditStore/chartEditStore.d'
|
||||
import { syncData } from '../../ContentEdit/components/EditTools/hooks/useSyncUpdate.hook'
|
||||
import { icon } from '@/plugins'
|
||||
import { cloneDeep } from 'lodash'
|
||||
|
||||
const { BrowsersOutlineIcon, SendIcon } = icon.ionicons5
|
||||
const { BrowsersOutlineIcon, SendIcon, AnalyticsIcon } = icon.ionicons5
|
||||
const chartEditStore = useChartEditStore()
|
||||
|
||||
const routerParamsInfo = useRoute()
|
||||
@ -42,7 +43,8 @@ const previewHandle = () => {
|
||||
setSessionStorage(StorageEnum.GO_CHART_STORAGE_LIST, sessionStorageInfo)
|
||||
} else {
|
||||
sessionStorageInfo.push({
|
||||
id: previewId, ...storageInfo
|
||||
id: previewId,
|
||||
...storageInfo
|
||||
})
|
||||
setSessionStorage(StorageEnum.GO_CHART_STORAGE_LIST, sessionStorageInfo)
|
||||
}
|
||||
@ -63,7 +65,14 @@ const sendHandle = () => {
|
||||
})
|
||||
}
|
||||
|
||||
const btnList = shallowReactive([
|
||||
const btnList = [
|
||||
{
|
||||
select: true,
|
||||
title: '同步内容',
|
||||
type: 'primary',
|
||||
icon: renderIcon(AnalyticsIcon),
|
||||
event: syncData
|
||||
},
|
||||
{
|
||||
select: true,
|
||||
title: '预览',
|
||||
@ -76,9 +85,18 @@ const btnList = shallowReactive([
|
||||
icon: renderIcon(SendIcon),
|
||||
event: sendHandle
|
||||
}
|
||||
])
|
||||
]
|
||||
|
||||
const comBtnList = computed(() => {
|
||||
if (chartEditStore.getEditCanvas.isCodeEdit) {
|
||||
return btnList
|
||||
}
|
||||
const cloneList = cloneDeep(btnList)
|
||||
cloneList.shift()
|
||||
return cloneList
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.align-center {
|
||||
margin-top: -4px;
|
||||
|
@ -14,8 +14,17 @@
|
||||
</n-button>
|
||||
</div>
|
||||
<n-space>
|
||||
<n-tag :bordered="false" type="warning"> 「页面失焦保存」 </n-tag>
|
||||
<n-tag :bordered="false" type="warning"> 「ctrl + s 保存」 </n-tag>
|
||||
<!-- 暂时关闭 -->
|
||||
<!-- <n-tag :bordered="false" type="warning"> 「页面失焦保存」 </n-tag> -->
|
||||
<n-tag :bordered="false" type="warning"> 「Ctrl + S 更新视图」 </n-tag>
|
||||
<n-button v-if="showOpenFilePicker" class="go-mr-3" size="medium" @click="updateSync">
|
||||
<template #icon>
|
||||
<n-icon>
|
||||
<analytics-icon></analytics-icon>
|
||||
</n-icon>
|
||||
</template>
|
||||
保存
|
||||
</n-button>
|
||||
</n-space>
|
||||
</n-layout-header>
|
||||
<n-layout-content>
|
||||
@ -26,28 +35,31 @@
|
||||
lineNumbers: 'on',
|
||||
minimap: { enabled: true }
|
||||
}"
|
||||
/>
|
||||
/>
|
||||
</n-layout-content>
|
||||
</n-layout>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, ref, watch } from 'vue'
|
||||
import { ref } from 'vue'
|
||||
import { MonacoEditor } from '@/components/Pages/MonacoEditor'
|
||||
import { SavePageEnum } from '@/enums/editPageEnum'
|
||||
import { getSessionStorageInfo } from '../preview/utils'
|
||||
import type { ChartEditStorageType } from '../preview/index.d'
|
||||
import { setSessionStorage, JSONStringify, JSONParse, setTitle } from '@/utils'
|
||||
import { setSessionStorage, JSONStringify, JSONParse, setTitle, goDialog } from '@/utils'
|
||||
import { StorageEnum } from '@/enums/storageEnum'
|
||||
import { icon } from '@/plugins'
|
||||
import type { ChartEditStorageType } from '../preview/index.d'
|
||||
|
||||
const { ChevronBackOutlineIcon, DownloadIcon } = icon.ionicons5
|
||||
const { ChevronBackOutlineIcon, DownloadIcon, AnalyticsIcon } = icon.ionicons5
|
||||
const showOpenFilePicker: Function = (window as any).showOpenFilePicker
|
||||
const content = ref('')
|
||||
|
||||
window['$message'].warning('请不要刷新此窗口!')
|
||||
|
||||
// 从sessionStorage 获取数据
|
||||
async function getDataBySession() {
|
||||
const localStorageInfo: ChartEditStorageType = await getSessionStorageInfo() as unknown as ChartEditStorageType
|
||||
const localStorageInfo: ChartEditStorageType = (await getSessionStorageInfo()) as unknown as ChartEditStorageType
|
||||
setTitle(`编辑-${localStorageInfo.editCanvasConfig.projectName}`)
|
||||
content.value = JSONStringify(localStorageInfo)
|
||||
}
|
||||
@ -60,44 +72,75 @@ function back() {
|
||||
}
|
||||
|
||||
// 导入json文本
|
||||
async function importJSON() {
|
||||
const files = await showOpenFilePicker()
|
||||
const file = await files[0].getFile()
|
||||
const fr = new FileReader()
|
||||
fr.readAsText(file)
|
||||
fr.onloadend = () => {
|
||||
content.value = (fr.result || '').toString()
|
||||
}
|
||||
function importJSON() {
|
||||
goDialog({
|
||||
message: '导入数据将覆盖内容,此操作不可撤回,是否继续?',
|
||||
isMaskClosable: true,
|
||||
transformOrigin: 'center',
|
||||
onPositiveCallback: async () => {
|
||||
try {
|
||||
const files = await showOpenFilePicker()
|
||||
const file = await files[0].getFile()
|
||||
const fr = new FileReader()
|
||||
fr.readAsText(file)
|
||||
fr.onloadend = () => {
|
||||
content.value = (fr.result || '').toString()
|
||||
}
|
||||
window['$message'].success('导入成功!')
|
||||
} catch (error) {
|
||||
window['$message'].error('导入失败,请检查文件是否损坏!')
|
||||
console.log(error)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 同步 [画布页失去焦点时同步数据到JSON页,JSON页Ctrl+S 时同步数据到画布页]
|
||||
// 同步数据编辑页
|
||||
window.opener.addEventListener(SavePageEnum.CHART, (e: any) => {
|
||||
window['$message'].success('正在进行更新...')
|
||||
setSessionStorage(StorageEnum.GO_CHART_STORAGE_LIST, [e.detail])
|
||||
content.value = JSONStringify(e.detail)
|
||||
})
|
||||
|
||||
// 窗口失焦 + 保存 => 同步数据
|
||||
// 保存按钮同步数据
|
||||
document.addEventListener('keydown', function (e) {
|
||||
if (e.keyCode == 83 && (navigator.platform.match('Mac') ? e.metaKey : e.ctrlKey)) {
|
||||
e.preventDefault()
|
||||
updateSync()
|
||||
}
|
||||
})
|
||||
addEventListener('blur', updateSync)
|
||||
|
||||
// 失焦保存(暂时关闭)
|
||||
// addEventListener('blur', updateSync)
|
||||
|
||||
// 同步更新
|
||||
async function updateSync() {
|
||||
if (!window.opener) {
|
||||
return window['$message'].error('源窗口已关闭,视图同步失败')
|
||||
return window['$message'].error('源窗口已关闭,视图同步失败!')
|
||||
}
|
||||
try {
|
||||
const detail = JSONParse(content.value)
|
||||
delete detail.id
|
||||
// 保持id不变
|
||||
window.opener.dispatchEvent(new CustomEvent(SavePageEnum.JSON, { detail }))
|
||||
} catch (e) {
|
||||
window['$message'].error('内容格式有误')
|
||||
console.log(e)
|
||||
goDialog({
|
||||
message: '是否覆盖源视图内容? 此操作不可撤!',
|
||||
isMaskClosable: true,
|
||||
transformOrigin: 'center',
|
||||
onPositiveCallback: () => {
|
||||
try {
|
||||
const detail = JSONParse(content.value)
|
||||
delete detail.id
|
||||
// 保持id不变
|
||||
window.opener.dispatchEvent(new CustomEvent(SavePageEnum.JSON, { detail }))
|
||||
window['$message'].success('正在同步内容...')
|
||||
} catch (e) {
|
||||
window['$message'].error('内容格式有误')
|
||||
console.log(e)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 关闭页面发送关闭事件
|
||||
window.onbeforeunload = () => {
|
||||
if (window.opener) {
|
||||
window.opener.dispatchEvent(new CustomEvent(SavePageEnum.CLOSE))
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
Loading…
Reference in New Issue
Block a user