大屏设计器
This commit is contained in:
@@ -54,7 +54,8 @@
|
||||
"vue-draggable-next": "^2.2.1",
|
||||
"vue-i18n": "9.2.2",
|
||||
"vue-router": "^4.4.0",
|
||||
"vue-types": "^4.2.1"
|
||||
"vue-types": "^4.2.1",
|
||||
"vue3-sketch-ruler": "^2.2.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/element-resize-detector": "^1.1.6",
|
||||
|
||||
10
Report-V3-TS/pnpm-lock.yaml
generated
10
Report-V3-TS/pnpm-lock.yaml
generated
@@ -88,6 +88,9 @@ dependencies:
|
||||
vue-types:
|
||||
specifier: ^4.2.1
|
||||
version: 4.2.1(vue@3.5.12)
|
||||
vue3-sketch-ruler:
|
||||
specifier: ^2.2.7
|
||||
version: 2.2.7
|
||||
|
||||
devDependencies:
|
||||
'@types/element-resize-detector':
|
||||
@@ -3398,6 +3401,7 @@ packages:
|
||||
|
||||
/fast-uri@3.0.3:
|
||||
resolution: {integrity: sha512-aLrHthzCjH5He4Z2H9YZ+v6Ujb9ocRuW6ZzkJQOrTxleEijANq4v1TsaPaVG1PZcuurEzrLcWRyYBYXD5cEiaw==}
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
|
||||
/fastest-levenshtein@1.0.16:
|
||||
@@ -4146,6 +4150,7 @@ packages:
|
||||
|
||||
/json-schema-traverse@1.0.0:
|
||||
resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==}
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
|
||||
/json-stable-stringify-without-jsonify@1.0.1:
|
||||
@@ -5292,6 +5297,7 @@ packages:
|
||||
/require-from-string@2.0.2:
|
||||
resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
|
||||
/require-main-filename@2.0.0:
|
||||
@@ -6434,6 +6440,10 @@ packages:
|
||||
resolution: {integrity: sha512-YFK6u5yltqtAOfTBcij/KGAS2SoZvzbNIAf9qTULauPObEp53xj22tDuohrrM2vNkgoD5kejXICIUBt2Q4ZDqQ==}
|
||||
dev: true
|
||||
|
||||
/vue3-sketch-ruler@2.2.7:
|
||||
resolution: {integrity: sha512-vzw/CsMjBgi0rqDz2GpPoTirUXUES+okgJDQGXlUC/mPFHQDvQBa2iEqw+af2L9E8cKjtWBd5IA9oHE7VFTSCg==}
|
||||
dev: false
|
||||
|
||||
/vue@3.5.12(typescript@4.9.5):
|
||||
resolution: {integrity: sha512-CLVZtXtn2ItBIi/zHZ0Sg1Xkb7+PU32bJJ8Bmy7ts3jxXTcbfsEfBivFYYWz1Hur+lalqGAh65Coin0r+HRUfg==}
|
||||
peerDependencies:
|
||||
|
||||
BIN
Report-V3-TS/src/assets/echImgs/bar_line.png
Normal file
BIN
Report-V3-TS/src/assets/echImgs/bar_line.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 26 KiB |
62
Report-V3-TS/src/assets/stlyes/font.css
Normal file
62
Report-V3-TS/src/assets/stlyes/font.css
Normal file
@@ -0,0 +1,62 @@
|
||||
@font-face {
|
||||
font-family: "iconfont"; /* Project id 4809046 */
|
||||
src: url('//at.alicdn.com/t/c/font_4809046_35va4vzemas.woff2?t=1737061376697') format('woff2'),
|
||||
url('//at.alicdn.com/t/c/font_4809046_35va4vzemas.woff?t=1737061376697') format('woff'),
|
||||
url('//at.alicdn.com/t/c/font_4809046_35va4vzemas.ttf?t=1737061376697') format('truetype');
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
font-family: "iconfont" !important;
|
||||
font-size: 16px;
|
||||
font-style: normal;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.icon-guanbi:before {
|
||||
content: "\e66d";
|
||||
}
|
||||
|
||||
.icon-shouye:before {
|
||||
content: "\e639";
|
||||
}
|
||||
|
||||
.icon-tubiao-qiapian:before {
|
||||
content: "\eb95";
|
||||
}
|
||||
|
||||
.icon-peizhi-fenqupeizhi:before {
|
||||
content: "\e617";
|
||||
}
|
||||
|
||||
.icon-tuceng:before {
|
||||
content: "\e636";
|
||||
}
|
||||
|
||||
.icon-lishijilu:before {
|
||||
content: "\e85f";
|
||||
}
|
||||
|
||||
.icon-zujianku:before {
|
||||
content: "\e6e4";
|
||||
}
|
||||
|
||||
.icon-chakan:before {
|
||||
content: "\e600";
|
||||
}
|
||||
|
||||
.icon-fenxiang1:before {
|
||||
content: "\e608";
|
||||
}
|
||||
|
||||
.icon-bianji:before {
|
||||
content: "\e616";
|
||||
}
|
||||
|
||||
.icon-icon_function_shouqi:before {
|
||||
content: "\e891";
|
||||
}
|
||||
|
||||
.icon-zhankai:before {
|
||||
content: "\e607";
|
||||
}
|
||||
@@ -23,7 +23,6 @@
|
||||
type: Number,
|
||||
},
|
||||
});
|
||||
|
||||
const computedStyle = computed(() =>
|
||||
props.size
|
||||
? { width: props.size + "px", height: props.size + "px", color: props.color }
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -2,11 +2,12 @@
|
||||
* @Description:
|
||||
* @Author: qianlishi
|
||||
* @Date: 2024-12-30 18:16:00
|
||||
* @LastEditors: qianlishi
|
||||
* @LastEditTime: 2025-01-11 22:10:56
|
||||
* @LastEditors: Do not edit
|
||||
* @LastEditTime: 2025-01-17 02:05:48
|
||||
*/
|
||||
import './styles/tailwind.css';
|
||||
import './styles/index.less';
|
||||
import '@/assets/stlyes/font.css'
|
||||
import '@/font/iconfont.js';
|
||||
import { createApp } from 'vue';
|
||||
import { setupNaiveDiscreteApi, setupNaive, setupDirectives } from '@/plugins';
|
||||
|
||||
@@ -6,12 +6,14 @@ import { isObject } from './is/index';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
import { storage } from './Storage';
|
||||
import { GLOBAL_DICT_CODE_NAME } from '@/enums/common';
|
||||
|
||||
/**
|
||||
* render 图标
|
||||
* */
|
||||
export function renderIcon(icon) {
|
||||
return () => h(NIcon, null, { default: () => h(icon) });
|
||||
}
|
||||
|
||||
/**
|
||||
* font 图标(Font class)
|
||||
* */
|
||||
|
||||
@@ -1,6 +1,41 @@
|
||||
<!--
|
||||
* @Author: qianlishi 1432731663@qq.com
|
||||
* @Date: 2025-01-16 15:34:57
|
||||
* @LastEditors: Do not edit
|
||||
* @LastEditTime: 2025-01-17 08:13:07
|
||||
-->
|
||||
<template>
|
||||
<div>大屏设计器</div>
|
||||
<div class="designContainer">
|
||||
<n-layout>
|
||||
<n-layout-header>
|
||||
<!-- 顶部 -->
|
||||
<LayoutHeader />
|
||||
</n-layout-header>
|
||||
<n-layout has-sider sider-placement="right">
|
||||
<!-- 左侧 -->
|
||||
<LayoutLeft />
|
||||
<n-layout-content>
|
||||
<!-- 中间画布 -->
|
||||
<LayOutContent />
|
||||
</n-layout-content>
|
||||
<!-- 右侧配置 -->
|
||||
<LayOutRight />
|
||||
</n-layout>
|
||||
</n-layout>
|
||||
</div>
|
||||
</template>
|
||||
<script lang='ts' setup>
|
||||
|
||||
import LayoutHeader from './layout/LayoutHeader/index.vue'
|
||||
import LayoutLeft from './layout/LayoutLeft/index.vue'
|
||||
import LayOutContent from './layout/LayoutContent/index.vue'
|
||||
import LayOutRight from './layout/LayoutRight/index.vue'
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.designContainer {
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
overflow: hidden;
|
||||
background: red;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
<template>
|
||||
<div class="layContent wrapper whitewrapper" id="layContent">
|
||||
<sketch-rule
|
||||
:scale="scale"
|
||||
:rate="rate"
|
||||
:thick="thick"
|
||||
:canvasWidth="canvasWidth"
|
||||
:canvasHeight="canvasHeight"
|
||||
:width="width"
|
||||
:height="height"
|
||||
:palette="paletteStyle"
|
||||
:gridRatio="gridRatio"
|
||||
:autoCenter="false"
|
||||
>
|
||||
<div>图表</div>
|
||||
</sketch-rule>
|
||||
</div>
|
||||
</template>
|
||||
<script lang='ts' setup>
|
||||
import { ref, reactive } from 'vue'
|
||||
import 'vue3-sketch-ruler/lib/style.css'
|
||||
import SketchRule from 'vue3-sketch-ruler'
|
||||
|
||||
const scale = ref(1) // 初始化标尺的缩放及画布
|
||||
const rate = ref(1) // 初始化标尺的缩放
|
||||
const thick = ref(20) // 标尺的厚度
|
||||
const width = ref(1920) // 放置标尺窗口的宽度
|
||||
const height = ref(1080) // 放置标尺窗口的高度
|
||||
const canvasWidth = ref(1920) // 画布宽
|
||||
const canvasHeight = ref(1080) // 画布高
|
||||
const gridRatio = ref(0.5) // 刻度分散比例(颗粒度)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const paletteStyle = ref({
|
||||
bgColor: "transparent",
|
||||
lineType: "dashed",
|
||||
longfgColor: '#4d4d4d',
|
||||
shortfgColor: '#1d2129',
|
||||
fontColor: '#1d2129',
|
||||
shadowColor: '#18181c',
|
||||
borderColor: '#18181c',
|
||||
cornerActiveColor: '#18181c'
|
||||
})
|
||||
|
||||
</script>
|
||||
<style lang='less' scoped>
|
||||
|
||||
.layContent {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
z-index: 0;
|
||||
}
|
||||
.wrapper {
|
||||
background-size: 15px 15px, 15px 15px;
|
||||
border: 1px solid #dadadc;
|
||||
|
||||
}
|
||||
.whitewrapper {
|
||||
background-color: #fafafc;
|
||||
background-image: linear-gradient(#fafafc 14px, transparent 0),
|
||||
linear-gradient(90deg, transparent 14px, #373739 0);
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,58 @@
|
||||
<!--
|
||||
* @Description: 设计器头部组件
|
||||
* @Author: qianlishi
|
||||
* @Date: 2025-01-16 16:30:35
|
||||
* @LastEditors: Do not edit
|
||||
* @LastEditTime: 2025-01-17 05:00:53
|
||||
-->
|
||||
<template>
|
||||
<div class="header">
|
||||
<div class="nav-left">
|
||||
<div class="home mr-20">
|
||||
<n-popover trigger="hover">
|
||||
<template #trigger>
|
||||
<span class="iconfont icon-shouye" />
|
||||
</template>
|
||||
<span>首页</span>
|
||||
</n-popover>
|
||||
</div>
|
||||
<div class="echarts mr-10">
|
||||
<n-popover trigger="hover">
|
||||
<template #trigger>
|
||||
<span class="iconfont icon-tubiao-qiapian" />
|
||||
</template>
|
||||
<span>图标收缩</span>
|
||||
</n-popover>
|
||||
</div>
|
||||
<div class="config mr-10">
|
||||
<n-popover trigger="hover">
|
||||
<template #trigger>
|
||||
<span class="iconfont icon-peizhi-fenqupeizhi" />
|
||||
</template>
|
||||
<span>配置项收缩</span>
|
||||
</n-popover>
|
||||
</div>
|
||||
</div>
|
||||
<div class="nav-content"></div>
|
||||
<div class="nav-right"></div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang='ts' setup>
|
||||
</script>
|
||||
<style lang='less' scoped>
|
||||
.header {
|
||||
width: 100%;
|
||||
height: 60px;
|
||||
border-bottom: 2px solid #fafafa;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
padding: 0 20px;
|
||||
.nav-left {
|
||||
display: flex;
|
||||
line-height: 60px;
|
||||
.iconfont {
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
220
Report-V3-TS/src/views/designScreen/layout/LayoutLeft/index.vue
Normal file
220
Report-V3-TS/src/views/designScreen/layout/LayoutLeft/index.vue
Normal file
@@ -0,0 +1,220 @@
|
||||
<template>
|
||||
<div class="menu-left">
|
||||
<div class="menu-nav">
|
||||
<n-menu v-model:value="selectValue" class="menu" :options="menuOptions" />
|
||||
</div>
|
||||
<div class="menu-sub" :class="[ isActive ? '' : 'active']">
|
||||
<div class="title">
|
||||
<span>组件列表</span>
|
||||
<span class="iconfont icon-guanbi" @click="close"></span>
|
||||
</div>
|
||||
<div class="menu-sub-box">
|
||||
<div class="menu-sub-box-one">
|
||||
<n-menu v-model:value="selectValue1" class="menu" :options="menuOptions1" />
|
||||
</div>
|
||||
<div class="menu-sub-box-two">
|
||||
<n-menu v-model:value="selectValue2" class="menu" :options="menuOptions2" />
|
||||
</div>
|
||||
|
||||
<div class="menu-sub-box-imgs">
|
||||
<div class="input">
|
||||
<n-input type="text" size="small" placeholder="搜索组件" />
|
||||
</div>
|
||||
<n-scrollbar>
|
||||
<div class="item" v-for="item in 10">
|
||||
<div class="item-title">柱状图</div>
|
||||
<div class="item-box">
|
||||
<img src="@/assets/echImgs/bar_line.png" class="item-box-img" alt="">
|
||||
</div>
|
||||
</div>
|
||||
</n-scrollbar>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang='ts' setup>
|
||||
import { reactive, ref } from 'vue'
|
||||
import { renderFontClassIcon } from '@/utils';
|
||||
const menuOptions = reactive([
|
||||
{
|
||||
label: '组件库',
|
||||
key: 'pinball-1973',
|
||||
icon: renderFontClassIcon('icon-zujianku')
|
||||
},
|
||||
{
|
||||
label: '图层',
|
||||
key: 'pinball-1974',
|
||||
icon: renderFontClassIcon('icon-tuceng')
|
||||
},
|
||||
{
|
||||
label: '历史记录',
|
||||
key: 'pinball-1975',
|
||||
icon: renderFontClassIcon('icon-lishijilu')
|
||||
}
|
||||
])
|
||||
const menuOptions1 = [
|
||||
{
|
||||
label: '所有',
|
||||
icon: renderFontClassIcon('icon-zujianku'),
|
||||
key: '1'
|
||||
},
|
||||
{
|
||||
label: '图表',
|
||||
icon: renderFontClassIcon('icon-zujianku'),
|
||||
key: '2'
|
||||
}
|
||||
]
|
||||
const menuOptions2 = [
|
||||
{
|
||||
label: '全部',
|
||||
key: '1'
|
||||
},
|
||||
{
|
||||
label: '柱状图',
|
||||
key: '2'
|
||||
},
|
||||
]
|
||||
const selectValue = ref<string>(menuOptions[0].key)
|
||||
const selectValue1 = ref('1')
|
||||
const selectValue2 = ref('1')
|
||||
const isActive = ref(true)
|
||||
const close = () => {
|
||||
isActive.value = false
|
||||
}
|
||||
</script>
|
||||
<style lang='less' scoped>
|
||||
.menu-left {
|
||||
height: calc(100vh - 60px);
|
||||
display: flex;
|
||||
.menu-nav {
|
||||
width: 70px;
|
||||
height: 100%;
|
||||
background: #fafafa;
|
||||
// background: red;
|
||||
::v-deep .menu {
|
||||
.n-menu-item {
|
||||
height: auto !important;
|
||||
&.n-menu-item--selected {
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 2px;
|
||||
top: 0;
|
||||
height: 100%;
|
||||
width: 3px;
|
||||
border-top-right-radius: 3px;
|
||||
border-bottom-right-radius: 3px;
|
||||
}
|
||||
}
|
||||
.n-menu-item-content {
|
||||
// &.n-menu-item-content:not(.n-menu-item-content--disabled):hover {
|
||||
// background: none;
|
||||
// }
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 6px 12px !important;
|
||||
font-size: 14px !important;
|
||||
}
|
||||
.n-menu-item-content__icon {
|
||||
font-size: 18px !important;
|
||||
margin-right: 0 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.menu-sub {
|
||||
overflow: hidden;
|
||||
&.active {
|
||||
width: 0;
|
||||
}
|
||||
.title {
|
||||
width: 100%;
|
||||
line-height: 50px;
|
||||
border-bottom: 2px solid #fafafa;
|
||||
padding:0 20px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
::v-deep .menu-sub-box {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
transition: all 1s;
|
||||
&-one {
|
||||
width: 60px;
|
||||
height: 30px;
|
||||
.n-menu-item-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 0 !important;
|
||||
font-size: 12px !important;
|
||||
box-sizing: border-box;
|
||||
&.n-menu-item-content__icon{
|
||||
margin-right: 0!important;
|
||||
}
|
||||
&.n-menu-item-content:not(.n-menu-item-content--disabled):hover::before {
|
||||
background: none;
|
||||
}
|
||||
&.n-menu-item-content.n-menu-item-content--selected::before {
|
||||
background: none;
|
||||
}
|
||||
}
|
||||
.n-menu-item-content__icon {
|
||||
margin-right: 0px !important;
|
||||
}
|
||||
}
|
||||
&-two {
|
||||
width: 70px;
|
||||
background: #fafafa;
|
||||
.menu {
|
||||
.n-menu-item {
|
||||
height: 30px;
|
||||
.n-menu-item-content {
|
||||
display: grid;
|
||||
text-align: center;
|
||||
padding: 6px 12px !important;
|
||||
font-size: 12px !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
&-imgs {
|
||||
width: 160px;
|
||||
.input {
|
||||
margin: 4px;
|
||||
}
|
||||
.item {
|
||||
margin-top: 6px;
|
||||
&-title {
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
padding: 4px;
|
||||
background: #e5e6eb;
|
||||
border-radius: 5px 5px 0 0;
|
||||
}
|
||||
&-box {
|
||||
background: #f3f3f3;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
padding: 6px 0;
|
||||
overflow: hidden;
|
||||
&-img {
|
||||
max-width: 140px;
|
||||
height: 100px;
|
||||
border-radius: 5px;
|
||||
object-fit: contain;
|
||||
&:hover {
|
||||
transform: scale(1.1);
|
||||
transition: all 0.5s;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,34 @@
|
||||
<template>
|
||||
<n-layout-sider
|
||||
collapse-mode="transform"
|
||||
:collapsed-width="0"
|
||||
:width="350"
|
||||
:native-scrollbar="false"
|
||||
show-trigger="bar"
|
||||
>
|
||||
<div class="config">
|
||||
<n-scrollbar trigger="none">
|
||||
<n-tabs size="small" type="segment">
|
||||
<n-tab-pane name="chap1" tab="配置">
|
||||
配置
|
||||
</n-tab-pane>
|
||||
<n-tab-pane name="chap2" tab="动画">动画</n-tab-pane>
|
||||
<n-tab-pane name="chap3" tab="数据">数据</n-tab-pane>
|
||||
<n-tab-pane name="chap4" tab="事件">事件</n-tab-pane>
|
||||
</n-tabs>
|
||||
</n-scrollbar>
|
||||
</div>
|
||||
</n-layout-sider>
|
||||
</template>
|
||||
<script lang='ts' setup>
|
||||
|
||||
</script>
|
||||
<style lang='less' scoped>
|
||||
.config {
|
||||
height: calc(100vh - 60px);
|
||||
background: #f7f7fa;
|
||||
::v-deep .n-tab-pane {
|
||||
background:#f7f7fa;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user