Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
D
dataease
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
zhu
dataease
Commits
8a04a2d1
提交
8a04a2d1
authored
6月 24, 2021
作者:
taojinlong
浏览文件
操作
浏览文件
下载
差异文件
refactor: 去掉 unused imports
上级
1ec001c3
ce4d20b8
全部展开
隐藏空白字符变更
内嵌
并排
正在显示
51 个修改的文件
包含
700 行增加
和
667 行删除
+700
-667
README.md
README.md
+11
-11
JWTFilter.java
backend/src/main/java/io/dataease/auth/filter/JWTFilter.java
+2
-1
AuthServer.java
...end/src/main/java/io/dataease/auth/server/AuthServer.java
+4
-3
JWTUtils.java
backend/src/main/java/io/dataease/auth/util/JWTUtils.java
+2
-1
LicenseController.java
...c/main/java/io/dataease/controller/LicenseController.java
+5
-3
JdbcProvider.java
...in/java/io/dataease/datasource/provider/JdbcProvider.java
+21
-17
DatasourceService.java
...ava/io/dataease/datasource/service/DatasourceService.java
+2
-1
EasyExcelExporter.java
.../main/java/io/dataease/excel/utils/EasyExcelExporter.java
+3
-2
ScheduleManager.java
.../main/java/io/dataease/job/sechedule/ScheduleManager.java
+11
-25
DataSetTableService.java
...java/io/dataease/service/dataset/DataSetTableService.java
+4
-3
DataSetTableTaskService.java
.../io/dataease/service/dataset/DataSetTableTaskService.java
+3
-2
ExtractDataService.java
.../java/io/dataease/service/dataset/ExtractDataService.java
+2
-1
PanelGroupService.java
...ain/java/io/dataease/service/panel/PanelGroupService.java
+2
-1
PanelSubjectService.java
...n/java/io/dataease/service/panel/PanelSubjectService.java
+5
-2
PanelTemplateService.java
.../java/io/dataease/service/panel/PanelTemplateService.java
+3
-2
V8__demo.sql
backend/src/main/resources/db/migration/V8__demo.sql
+0
-0
.eslintrc.js
frontend/.eslintrc.js
+3
-1
index.vue
frontend/src/components/DeDrag/index.vue
+2
-2
index.vue
frontend/src/components/RightPanel/index.vue
+3
-3
iconfont.js
frontend/src/components/canvas/assets/iconfont/iconfont.js
+0
-0
AnimationList.vue
frontend/src/components/canvas/components/AnimationList.vue
+60
-60
ContextMenu.vue
...d/src/components/canvas/components/Editor/ContextMenu.vue
+1
-1
EventList.vue
frontend/src/components/canvas/components/EventList.vue
+45
-45
Modal.vue
frontend/src/components/canvas/components/Modal.vue
+22
-23
Toolbar.vue
frontend/src/components/canvas/components/Toolbar.vue
+2
-2
Group.vue
frontend/src/components/canvas/custom-component/Group.vue
+42
-42
Picture.vue
frontend/src/components/canvas/custom-component/Picture.vue
+10
-11
VButton.vue
frontend/src/components/canvas/custom-component/VButton.vue
+8
-9
animation.js
frontend/src/components/canvas/store/animation.js
+9
-10
contextmenu.js
frontend/src/components/canvas/store/contextmenu.js
+15
-16
copy.js
frontend/src/components/canvas/store/copy.js
+52
-52
event.js
frontend/src/components/canvas/store/event.js
+9
-10
lock.js
frontend/src/components/canvas/store/lock.js
+9
-10
animationClassData.js
frontend/src/components/canvas/utils/animationClassData.js
+92
-92
decomposeComponent.js
frontend/src/components/canvas/utils/decomposeComponent.js
+14
-15
eventBus.js
frontend/src/components/canvas/utils/eventBus.js
+1
-2
events.js
frontend/src/components/canvas/utils/events.js
+27
-28
generateID.js
frontend/src/components/canvas/utils/generateID.js
+2
-3
runAnimation.js
frontend/src/components/canvas/utils/runAnimation.js
+15
-15
shortcutKey.js
frontend/src/components/canvas/utils/shortcutKey.js
+75
-75
toast.js
frontend/src/components/canvas/utils/toast.js
+6
-7
utils.js
frontend/src/components/canvas/utils/utils.js
+18
-19
en.js
frontend/src/lang/en.js
+7
-0
tw.js
frontend/src/lang/tw.js
+7
-0
zh.js
frontend/src/lang/zh.js
+7
-0
demo_index.html
frontend/src/styles/deicon/demo_index.html
+0
-0
iconfont.js
frontend/src/styles/deicon/iconfont.js
+0
-0
index.vue
frontend/src/views/link/pwd/index.vue
+51
-33
SubjectTemplateItemback.vue
...nel/SubjectSetting/PreSubject/SubjectTemplateItemback.vue
+1
-1
index.vue
frontend/src/views/panel/SubjectSetting/index.vue
+4
-4
PanelList.vue
frontend/src/views/panel/list/PanelList.vue
+1
-1
没有找到文件。
README.md
浏览文件 @
8a04a2d1
...
...
@@ -2,7 +2,7 @@
<h3
align=
"center"
>
人人可用的开源数据可视化分析工具
</h3>
<p
align=
"center"
>
<a
href=
"https://www.gnu.org/licenses/old-licenses/gpl-2.0"
><img
src=
"https://img.shields.io/github/license/dataease/dataease?color=%231890FF&style=flat-square"
alt=
"License: GPL v2"
></a>
<a
href=
"https://app.codacy.com/gh/
metersphere/metersphere?utm_source=github.com&utm_medium=referral&utm_content=metersphere/metersphere&utm_campaign=Badge_Grade_Dashboard"
><img
src=
"https://api.codacy.com/project/badge/Grade/176186d132df448b955f8bdd5e6ef9c0
"
alt=
"Codacy"
></a>
<a
href=
"https://app.codacy.com/gh/
dataease/dataease?utm_source=github.com&utm_medium=referral&utm_content=dataease/dataease&utm_campaign=Badge_Grade_Dashboard"
><img
src=
"https://app.codacy.com/project/badge/Grade/da67574fd82b473992781d1386b937ef
"
alt=
"Codacy"
></a>
<a
href=
"https://github.com/dataease/dataease/releases/latest"
><img
src=
"https://img.shields.io/github/v/release/dataease/dataease"
alt=
"Latest release"
></a>
<a
href=
"https://github.com/dataease/dataease"
><img
src=
"https://img.shields.io/github/stars/dataease/dataease?color=%231890FF&style=flat-square"
alt=
"Stars"
></a>
<a
href=
"https://github.com/dataease/dataease/releases/latest"
><img
src=
"https://img.shields.io/github/downloads/dataease/dataease/total"
alt=
"Downloads"
></a>
...
...
@@ -12,17 +12,17 @@ DataEase 是开源的数据可视化分析工具,帮助用户快速分析数
### DataEase 的功能:
-
图表展示:支持 PC 端、移动端及大屏;
-
图表制作:支持丰富的图表类型(基于 Apache ECharts 实现)、支持拖拉拽方式快速制作仪表板;
-
数据引擎:支持直连模式、本地模式(基于 Apache Doris / Kettle 实现);
-
数据连接:支持关系型数据库、Excel 等文件、Hadoop 等大数据平台、NoSQL 等各种数据源。
-
图表展示:支持 PC 端、移动端及大屏;
-
图表制作:支持丰富的图表类型(基于 Apache ECharts 实现)、支持拖拉拽方式快速制作仪表板;
-
数据引擎:支持直连模式、本地模式(基于 Apache Doris / Kettle 实现);
-
数据连接:支持关系型数据库、Excel 等文件、Hadoop 等大数据平台、NoSQL 等各种数据源。
### DataEase 的优势:
-
开源开放:零门槛,线上快速获取和安装;快速获取用户反馈、按月发布新版本;
-
简单易用:极易上手,通过鼠标点击和拖拽即可完成分析;
-
秒级响应:集成 Apache Doris,超大数据量下秒级查询返回延时;
-
安全分享:支持多种数据分享方式,确保数据安全。
-
开源开放:零门槛,线上快速获取和安装;快速获取用户反馈、按月发布新版本;
-
简单易用:极易上手,通过鼠标点击和拖拽即可完成分析;
-
秒级响应:集成 Apache Doris,超大数据量下秒级查询返回延时;
-
安全分享:支持多种数据分享方式,确保数据安全。
## UI 展示
...
...
@@ -49,8 +49,8 @@ DataEase 是开源的数据可视化分析工具,帮助用户快速分析数
curl
-sSL
https://github.com/dataease/dataease/releases/latest/download/quick_start.sh | sh
```
-
[
在线文档
](
https://dataease.io/docs/
)
-
[
演示视频
](
https://dataease.oss-cn-hangzhou.aliyuncs.com/video/de-v1-demo.mp4
)
-
[
在线文档
](
https://dataease.io/docs/
)
-
[
演示视频
](
https://dataease.oss-cn-hangzhou.aliyuncs.com/video/de-v1-demo.mp4
)
## 微信群
...
...
backend/src/main/java/io/dataease/auth/filter/JWTFilter.java
浏览文件 @
8a04a2d1
...
...
@@ -7,6 +7,7 @@ import io.dataease.auth.service.AuthUserService;
import
io.dataease.auth.util.JWTUtils
;
import
io.dataease.commons.utils.CommonBeanFactory
;
import
io.dataease.commons.utils.LogUtil
;
import
io.dataease.exception.DataEaseException
;
import
io.dataease.i18n.Translator
;
import
org.apache.commons.lang3.StringUtils
;
import
org.apache.shiro.authc.AuthenticationException
;
...
...
@@ -95,7 +96,7 @@ public class JWTFilter extends BasicHttpAuthenticationFilter {
AuthUserService
authUserService
=
CommonBeanFactory
.
getBean
(
AuthUserService
.
class
);
SysUserEntity
user
=
authUserService
.
getUserById
(
tokenInfo
.
getUserId
());
if
(
user
==
null
){
throw
new
Exception
(
Translator
.
get
(
"i18n_not_find_user"
));
DataEaseException
.
throw
Exception
(
Translator
.
get
(
"i18n_not_find_user"
));
}
String
password
=
user
.
getPassword
();
...
...
backend/src/main/java/io/dataease/auth/server/AuthServer.java
浏览文件 @
8a04a2d1
...
...
@@ -14,6 +14,7 @@ import io.dataease.commons.utils.BeanUtils;
import
io.dataease.commons.utils.CodingUtil
;
import
io.dataease.commons.utils.ServletUtils
;
import
io.dataease.exception.DataEaseException
;
import
io.dataease.i18n.Translator
;
import
org.apache.commons.lang3.ObjectUtils
;
import
org.apache.commons.lang3.StringUtils
;
...
...
@@ -40,10 +41,10 @@ public class AuthServer implements AuthApi {
SysUserEntity
user
=
authUserService
.
getUserByName
(
username
);
if
(
ObjectUtils
.
isEmpty
(
user
))
{
throw
new
Runtime
Exception
(
Translator
.
get
(
"i18n_id_or_pwd_error"
));
DataEaseException
.
throw
Exception
(
Translator
.
get
(
"i18n_id_or_pwd_error"
));
}
if
(
user
.
getEnabled
()
==
0
)
{
throw
new
Runtime
Exception
(
Translator
.
get
(
"i18n_id_or_pwd_error"
));
DataEaseException
.
throw
Exception
(
Translator
.
get
(
"i18n_id_or_pwd_error"
));
}
String
realPwd
=
user
.
getPassword
();
//私钥解密
...
...
@@ -52,7 +53,7 @@ public class AuthServer implements AuthApi {
pwd
=
CodingUtil
.
md5
(
pwd
);
if
(!
StringUtils
.
equals
(
pwd
,
realPwd
))
{
throw
new
Runtime
Exception
(
Translator
.
get
(
"i18n_id_or_pwd_error"
));
DataEaseException
.
throw
Exception
(
Translator
.
get
(
"i18n_id_or_pwd_error"
));
}
Map
<
String
,
Object
>
result
=
new
HashMap
<>();
TokenInfo
tokenInfo
=
TokenInfo
.
builder
().
userId
(
user
.
getUserId
()).
username
(
username
).
build
();
...
...
backend/src/main/java/io/dataease/auth/util/JWTUtils.java
浏览文件 @
8a04a2d1
...
...
@@ -7,6 +7,7 @@ import com.auth0.jwt.exceptions.JWTDecodeException;
import
com.auth0.jwt.interfaces.DecodedJWT
;
import
io.dataease.auth.entity.TokenInfo
;
import
io.dataease.commons.utils.CommonBeanFactory
;
import
io.dataease.exception.DataEaseException
;
import
org.apache.commons.lang3.ObjectUtils
;
import
org.apache.commons.lang3.StringUtils
;
import
org.springframework.core.env.Environment
;
...
...
@@ -50,7 +51,7 @@ public class JWTUtils {
String
username
=
jwt
.
getClaim
(
"username"
).
asString
();
Long
userId
=
jwt
.
getClaim
(
"userId"
).
asLong
();
if
(
StringUtils
.
isEmpty
(
username
)
||
ObjectUtils
.
isEmpty
(
userId
)
){
throw
new
Runtime
Exception
(
"token格式错误!"
);
DataEaseException
.
throw
Exception
(
"token格式错误!"
);
}
TokenInfo
tokenInfo
=
TokenInfo
.
builder
().
username
(
username
).
userId
(
userId
).
build
();
return
tokenInfo
;
...
...
backend/src/main/java/io/dataease/controller/LicenseController.java
浏览文件 @
8a04a2d1
...
...
@@ -5,6 +5,7 @@ package io.dataease.controller;
import
com.google.gson.Gson
;
import
io.dataease.commons.license.DefaultLicenseService
;
import
io.dataease.commons.license.F2CLicenseResponse
;
import
io.dataease.exception.DataEaseException
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.web.bind.annotation.GetMapping
;
import
org.springframework.web.bind.annotation.RequestMapping
;
...
...
@@ -35,11 +36,12 @@ public class LicenseController {
return
ResultHolder
.
success
(
null
);
case
expired:
String
expired
=
f2CLicenseResponse
.
getLicense
().
getExpired
();
throw
new
Exception
(
"License has expired since "
+
expired
+
", please update license."
);
DataEaseException
.
throw
Exception
(
"License has expired since "
+
expired
+
", please update license."
);
case
invalid:
throw
new
Exception
(
f2CLicenseResponse
.
getMessage
());
DataEaseException
.
throw
Exception
(
f2CLicenseResponse
.
getMessage
());
default
:
throw
new
Exception
(
"Invalid License."
);
DataEaseException
.
throw
Exception
(
"Invalid License."
);
}
return
new
ResultHolder
();
}
}
backend/src/main/java/io/dataease/datasource/provider/JdbcProvider.java
浏览文件 @
8a04a2d1
...
...
@@ -7,6 +7,7 @@ import io.dataease.datasource.dto.MysqlConfigration;
import
io.dataease.datasource.dto.SqlServerConfigration
;
import
io.dataease.datasource.dto.TableFiled
;
import
io.dataease.datasource.request.DatasourceRequest
;
import
io.dataease.exception.DataEaseException
;
import
org.apache.commons.lang3.StringUtils
;
import
org.springframework.stereotype.Service
;
...
...
@@ -31,9 +32,9 @@ public class JdbcProvider extends DatasourceProvider {
ResultSet
rs
=
stat
.
executeQuery
(
datasourceRequest
.
getQuery
());
list
=
fetchResult
(
rs
);
}
catch
(
SQLException
e
)
{
throw
new
Exception
(
"ERROR:"
+
e
.
getMessage
(),
e
);
DataEaseException
.
throwException
(
e
);
}
catch
(
Exception
e
)
{
throw
new
Exception
(
"ERROR:"
+
e
.
getMessage
(),
e
);
DataEaseException
.
throwException
(
e
);
}
finally
{
if
(
connection
!=
null
){
connection
.
close
();
...
...
@@ -50,9 +51,9 @@ public class JdbcProvider extends DatasourceProvider {
Boolean
result
=
stat
.
execute
(
datasourceRequest
.
getQuery
());
stat
.
close
();
}
catch
(
SQLException
e
)
{
throw
new
Exception
(
"ERROR:"
+
e
.
getMessage
(),
e
);
DataEaseException
.
throwException
(
e
);
}
catch
(
Exception
e
)
{
throw
new
Exception
(
"ERROR:"
+
e
.
getMessage
(),
e
);
DataEaseException
.
throwException
(
e
);
}
finally
{
if
(
connection
!=
null
){
connection
.
close
();
...
...
@@ -70,14 +71,15 @@ public class JdbcProvider extends DatasourceProvider {
rs
=
stat
.
executeQuery
(
datasourceRequest
.
getQuery
());
return
fetchResult
(
rs
);
}
catch
(
SQLException
e
)
{
throw
new
Exception
(
"ERROR:"
+
e
.
getMessage
(),
e
);
DataEaseException
.
throwException
(
e
);
}
catch
(
Exception
e
)
{
throw
new
Exception
(
"ERROR:"
+
e
.
getMessage
(),
e
);
DataEaseException
.
throwException
(
e
);
}
finally
{
if
(
connection
!=
null
){
connection
.
close
();
}
}
return
new
ArrayList
<>();
}
private
List
<
String
[]>
fetchResult
(
ResultSet
rs
)
throws
Exception
{
...
...
@@ -112,14 +114,15 @@ public class JdbcProvider extends DatasourceProvider {
rs
=
stat
.
executeQuery
(
datasourceRequest
.
getQuery
());
return
fetchResultField
(
rs
);
}
catch
(
SQLException
e
)
{
throw
new
Exception
(
"ERROR:"
+
e
.
getMessage
(),
e
);
DataEaseException
.
throwException
(
e
);
}
catch
(
Exception
e
)
{
throw
new
Exception
(
"ERROR:"
+
e
.
getMessage
(),
e
);
DataEaseException
.
throwException
(
e
);
}
finally
{
if
(
connection
!=
null
){
connection
.
close
();
}
}
return
new
ArrayList
<>();
}
@Override
...
...
@@ -139,14 +142,15 @@ public class JdbcProvider extends DatasourceProvider {
result
.
put
(
"fieldList"
,
fieldList
);
return
result
;
}
catch
(
SQLException
e
)
{
throw
new
Exception
(
"ERROR:"
+
e
.
getMessage
(),
e
);
DataEaseException
.
throwException
(
e
);
}
catch
(
Exception
e
)
{
throw
new
Exception
(
"ERROR:"
+
e
.
getMessage
(),
e
);
DataEaseException
.
throwException
(
e
);
}
finally
{
if
(
connection
!=
null
){
connection
.
close
();
}
}
return
new
HashMap
<>();
}
private
List
<
TableFiled
>
fetchResultField
(
ResultSet
rs
)
throws
Exception
{
...
...
@@ -183,12 +187,13 @@ public class JdbcProvider extends DatasourceProvider {
statement
.
close
();
return
tables
;
}
catch
(
Exception
e
)
{
throw
new
Exception
(
"ERROR: "
+
e
.
getMessage
(),
e
);
DataEaseException
.
throwException
(
e
);
}
finally
{
if
(
con
!=
null
){
con
.
close
();
}
}
return
new
ArrayList
<>();
}
@Override
...
...
@@ -222,9 +227,9 @@ public class JdbcProvider extends DatasourceProvider {
}
resultSet
.
close
();
}
catch
(
SQLException
e
)
{
throw
new
Exception
(
"ERROR:"
+
e
.
getMessage
(),
e
);
DataEaseException
.
throwException
(
e
);
}
catch
(
Exception
e
)
{
throw
new
Exception
(
"ERROR:"
+
e
.
getMessage
(),
e
);
DataEaseException
.
throwException
(
e
);
}
finally
{
if
(
connection
!=
null
){
connection
.
close
();
...
...
@@ -244,7 +249,7 @@ public class JdbcProvider extends DatasourceProvider {
resultSet
.
close
();
ps
.
close
();
}
catch
(
Exception
e
)
{
throw
new
Exception
(
"ERROR: "
+
e
.
getMessage
(),
e
);
DataEaseException
.
throwException
(
e
);
}
finally
{
if
(
con
!=
null
){
con
.
close
();}
}
...
...
@@ -261,7 +266,7 @@ public class JdbcProvider extends DatasourceProvider {
return
resultSet
.
getLong
(
1
);
}
}
catch
(
Exception
e
)
{
throw
new
Exception
(
"ERROR: "
+
e
.
getMessage
(),
e
);
DataEaseException
.
throwException
(
e
);
}
finally
{
con
.
close
();
}
...
...
@@ -423,4 +428,4 @@ public class JdbcProvider extends DatasourceProvider {
return
"show tables;"
;
}
}
}
\ No newline at end of file
}
backend/src/main/java/io/dataease/datasource/service/DatasourceService.java
浏览文件 @
8a04a2d1
...
...
@@ -18,6 +18,7 @@ import io.dataease.datasource.provider.ProviderFactory;
import
io.dataease.datasource.request.DatasourceRequest
;
import
io.dataease.dto.DatasourceDTO
;
import
io.dataease.dto.dataset.DataTableInfoDTO
;
import
io.dataease.exception.DataEaseException
;
import
io.dataease.i18n.Translator
;
import
io.dataease.service.dataset.DataSetGroupService
;
import
org.apache.commons.collections4.CollectionUtils
;
...
...
@@ -97,7 +98,7 @@ public class DatasourceService {
example
.
createCriteria
().
andDataSourceIdEqualTo
(
datasourceId
);
List
<
DatasetTable
>
datasetTables
=
datasetTableMapper
.
selectByExample
(
example
);
if
(
CollectionUtils
.
isNotEmpty
(
datasetTables
)){
throw
new
Exception
(
datasetTables
.
size
()
+
Translator
.
get
(
"i18n_datasource_not_allow_delete_msg"
));
DataEaseException
.
throw
Exception
(
datasetTables
.
size
()
+
Translator
.
get
(
"i18n_datasource_not_allow_delete_msg"
));
}
datasourceMapper
.
deleteByPrimaryKey
(
datasourceId
);
}
...
...
backend/src/main/java/io/dataease/excel/utils/EasyExcelExporter.java
浏览文件 @
8a04a2d1
...
...
@@ -4,6 +4,7 @@ import com.alibaba.excel.EasyExcel;
import
com.alibaba.excel.write.metadata.style.WriteCellStyle
;
import
com.alibaba.excel.write.style.HorizontalCellStyleStrategy
;
import
io.dataease.commons.utils.LogUtil
;
import
io.dataease.exception.DataEaseException
;
import
io.dataease.exception.ExcelException
;
import
javax.servlet.http.HttpServletResponse
;
...
...
@@ -31,10 +32,10 @@ public class EasyExcelExporter {
EasyExcel
.
write
(
response
.
getOutputStream
(),
this
.
clazz
).
registerWriteHandler
(
horizontalCellStyleStrategy
).
sheet
(
sheetName
).
doWrite
(
data
);
}
catch
(
UnsupportedEncodingException
e
)
{
LogUtil
.
error
(
e
.
getMessage
(),
e
);
throw
new
Excel
Exception
(
"Utf-8 encoding is not supported"
);
DataEaseException
.
throw
Exception
(
"Utf-8 encoding is not supported"
);
}
catch
(
IOException
e
)
{
LogUtil
.
error
(
e
.
getMessage
(),
e
);
throw
new
Excel
Exception
(
"IO exception"
);
DataEaseException
.
throw
Exception
(
"IO exception"
);
}
}
...
...
backend/src/main/java/io/dataease/job/sechedule/ScheduleManager.java
浏览文件 @
8a04a2d1
package
io
.
dataease
.
job
.
sechedule
;
import
io.dataease.commons.utils.LogUtil
;
import
org.quartz.Job
;
import
org.quartz.JobDataMap
;
import
org.quartz.JobKey
;
import
org.quartz.Scheduler
;
import
org.quartz.SchedulerException
;
import
org.quartz.TriggerKey
;
import
org.quartz.JobBuilder
;
import
org.quartz.JobDetail
;
import
org.quartz.SimpleTrigger
;
import
org.quartz.TriggerBuilder
;
import
org.quartz.SimpleScheduleBuilder
;
import
org.quartz.Trigger
;
import
org.quartz.CronScheduleBuilder
;
import
org.quartz.CronTrigger
;
import
org.quartz.CronExpression
;
import
org.quartz.JobExecutionContext
;
import
io.dataease.exception.DataEaseException
;
import
org.quartz.*
;
import
org.springframework.stereotype.Component
;
import
javax.annotation.Resource
;
...
...
@@ -111,7 +97,7 @@ public class ScheduleManager {
}
catch
(
Exception
e
)
{
LogUtil
.
error
(
e
.
getMessage
(),
e
);
throw
new
Runtime
Exception
(
e
);
DataEaseException
.
throw
Exception
(
e
);
}
}
...
...
@@ -141,7 +127,7 @@ public class ScheduleManager {
}
catch
(
Exception
e
)
{
LogUtil
.
error
(
e
.
getMessage
(),
e
);
throw
new
Runtime
Exception
(
e
);
DataEaseException
.
throw
Exception
(
e
);
}
}
...
...
@@ -202,7 +188,7 @@ public class ScheduleManager {
// addJob(jobName, jobGroupName, triggerName, triggerGroupName, jobClass, cron);
/** 方式二 :先删除,然后在创建一个新的Job */
}
catch
(
Exception
e
)
{
throw
new
Runtime
Exception
(
e
);
DataEaseException
.
throw
Exception
(
e
);
}
}
...
...
@@ -254,7 +240,7 @@ public class ScheduleManager {
}
catch
(
Exception
e
)
{
LogUtil
.
error
(
e
.
getMessage
(),
e
);
throw
new
Runtime
Exception
(
e
);
DataEaseException
.
throw
Exception
(
e
);
}
}
...
...
@@ -286,7 +272,7 @@ public class ScheduleManager {
}
}
catch
(
Exception
e
)
{
LogUtil
.
error
(
e
.
getMessage
(),
e
);
throw
new
Runtime
Exception
(
e
);
DataEaseException
.
throw
Exception
(
e
);
}
}
...
...
@@ -310,7 +296,7 @@ public class ScheduleManager {
}
catch
(
Exception
e
)
{
LogUtil
.
error
(
e
.
getMessage
(),
e
);
throw
new
Runtime
Exception
(
e
);
DataEaseException
.
throw
Exception
(
e
);
}
}
...
...
@@ -320,7 +306,7 @@ public class ScheduleManager {
sched
.
start
();
}
catch
(
Exception
e
)
{
LogUtil
.
error
(
e
.
getMessage
(),
e
);
throw
new
Runtime
Exception
(
e
);
DataEaseException
.
throw
Exception
(
e
);
}
}
...
...
@@ -332,7 +318,7 @@ public class ScheduleManager {
}
}
catch
(
Exception
e
)
{
LogUtil
.
error
(
e
.
getMessage
(),
e
);
throw
new
Runtime
Exception
(
e
);
DataEaseException
.
throw
Exception
(
e
);
}
}
...
...
@@ -431,7 +417,7 @@ public class ScheduleManager {
public
static
CronTrigger
getCronTrigger
(
String
cron
)
{
if
(!
CronExpression
.
isValidExpression
(
cron
))
{
throw
new
Runtime
Exception
(
"cron :"
+
cron
+
" error"
);
DataEaseException
.
throw
Exception
(
"cron :"
+
cron
+
" error"
);
}
return
TriggerBuilder
.
newTrigger
().
withIdentity
(
"Calculate Date"
).
withSchedule
(
CronScheduleBuilder
.
cronSchedule
(
cron
)).
build
();
...
...
backend/src/main/java/io/dataease/service/dataset/DataSetTableService.java
浏览文件 @
8a04a2d1
...
...
@@ -18,6 +18,7 @@ import io.dataease.datasource.provider.JdbcProvider;
import
io.dataease.datasource.provider.ProviderFactory
;
import
io.dataease.datasource.request.DatasourceRequest
;
import
io.dataease.dto.dataset.*
;
import
io.dataease.exception.DataEaseException
;
import
io.dataease.i18n.Translator
;
import
io.dataease.provider.DDLProvider
;
import
io.dataease.provider.QueryProvider
;
...
...
@@ -412,7 +413,7 @@ public class DataSetTableService {
String
sql
=
new
Gson
().
fromJson
(
dataSetTableRequest
.
getInfo
(),
DataTableInfoDTO
.
class
).
getSql
();
if
(
StringUtils
.
isEmpty
(
sql
))
{
throw
new
Exception
(
Translator
.
get
(
"i18n_sql_not_empty"
));
DataEaseException
.
throw
Exception
(
Translator
.
get
(
"i18n_sql_not_empty"
));
}
QueryProvider
qp
=
ProviderFactory
.
getQueryProvider
(
ds
.
getType
());
String
sqlAsTable
=
qp
.
createSQLPreview
(
sql
,
null
);
...
...
@@ -734,7 +735,7 @@ public class DataSetTableService {
});
sort
(
sqlFileds
);
if
(!
originNameFileds
.
equals
(
sqlFileds
))
{
throw
new
Exception
(
Translator
.
get
(
"i18n_sql_add_not_matching"
)
+
sqlFileds
.
toString
());
DataEaseException
.
throw
Exception
(
Translator
.
get
(
"i18n_sql_add_not_matching"
)
+
sqlFileds
.
toString
());
}
}
if
(
StringUtils
.
isNotEmpty
(
datasetTableIncrementalConfig
.
getIncrementalDelete
())
&&
StringUtils
.
isNotEmpty
(
datasetTableIncrementalConfig
.
getIncrementalDelete
().
replace
(
" "
,
""
)))
{
// 增量删除
...
...
@@ -747,7 +748,7 @@ public class DataSetTableService {
});
sort
(
sqlFileds
);
if
(!
originNameFileds
.
equals
(
sqlFileds
))
{
throw
new
Exception
(
Translator
.
get
(
"i18n_sql_delete_not_matching"
)
+
sqlFileds
.
toString
());
DataEaseException
.
throw
Exception
(
Translator
.
get
(
"i18n_sql_delete_not_matching"
)
+
sqlFileds
.
toString
());
}
}
}
...
...
backend/src/main/java/io/dataease/service/dataset/DataSetTableTaskService.java
浏览文件 @
8a04a2d1
...
...
@@ -8,6 +8,7 @@ import io.dataease.base.mapper.DatasetTableTaskMapper;
import
io.dataease.commons.constants.JobStatus
;
import
io.dataease.commons.constants.ScheduleType
;
import
io.dataease.controller.request.dataset.DataSetTaskRequest
;
import
io.dataease.exception.DataEaseException
;
import
io.dataease.i18n.Translator
;
import
io.dataease.service.ScheduleService
;
import
org.apache.commons.lang3.ObjectUtils
;
...
...
@@ -71,11 +72,11 @@ public class DataSetTableTaskService {
if
(
datasetTableTask
.
getType
().
equalsIgnoreCase
(
"add_scope"
))
{
DatasetTable
datasetTable
=
dataSetTableService
.
get
(
datasetTableTask
.
getTableId
());
if
(
datasetTable
.
getLastUpdateTime
()
==
0
||
datasetTable
.
getLastUpdateTime
()
==
null
)
{
throw
new
Exception
(
Translator
.
get
(
"i18n_not_exec_add_sync"
));
DataEaseException
.
throw
Exception
(
Translator
.
get
(
"i18n_not_exec_add_sync"
));
}
}
if
(
extractDataService
.
updateSyncStatusIsNone
(
dataSetTableService
.
get
(
datasetTableTask
.
getTableId
())))
{
throw
new
Exception
(
Translator
.
get
(
"i18n_sync_job_exists"
));
DataEaseException
.
throw
Exception
(
Translator
.
get
(
"i18n_sync_job_exists"
));
}
else
{
//write log
DatasetTableTaskLog
datasetTableTaskLog
=
new
DatasetTableTaskLog
();
...
...
backend/src/main/java/io/dataease/service/dataset/ExtractDataService.java
浏览文件 @
8a04a2d1
...
...
@@ -21,6 +21,7 @@ import io.dataease.datasource.provider.JdbcProvider;
import
io.dataease.datasource.provider.ProviderFactory
;
import
io.dataease.datasource.request.DatasourceRequest
;
import
io.dataease.dto.dataset.DataTableInfoDTO
;
import
io.dataease.exception.DataEaseException
;
import
io.dataease.provider.QueryProvider
;
import
org.apache.commons.collections4.CollectionUtils
;
import
org.apache.commons.io.FileUtils
;
...
...
@@ -460,7 +461,7 @@ public class ExtractDataService {
if
(
jobStatus
.
getStatusDescription
().
equals
(
"Finished"
))
{
return
;
}
else
{
throw
new
Exception
(
jobStatus
.
getLoggingString
(
));
DataEaseException
.
throwException
((
jobStatus
.
getLoggingString
()
));
}
}
...
...
backend/src/main/java/io/dataease/service/panel/PanelGroupService.java
浏览文件 @
8a04a2d1
...
...
@@ -10,6 +10,7 @@ import io.dataease.commons.utils.TreeUtils;
import
io.dataease.controller.request.panel.PanelGroupRequest
;
import
io.dataease.dto.chart.ChartViewDTO
;
import
io.dataease.dto.panel.PanelGroupDTO
;
import
io.dataease.exception.DataEaseException
;
import
io.dataease.i18n.Translator
;
import
io.dataease.service.chart.ChartViewService
;
import
io.dataease.service.sys.SysAuthService
;
...
...
@@ -119,7 +120,7 @@ public class PanelGroupService {
List
<
PanelGroup
>
checkResult
=
panelGroupMapper
.
selectByExample
(
groupExample
);
if
(
CollectionUtils
.
isNotEmpty
(
checkResult
))
{
throw
new
Runtime
Exception
(
Translator
.
get
(
"i18n_same_folder_can_not_repeat"
));
DataEaseException
.
throw
Exception
(
Translator
.
get
(
"i18n_same_folder_can_not_repeat"
));
}
}
...
...
backend/src/main/java/io/dataease/service/panel/PanelSubjectService.java
浏览文件 @
8a04a2d1
...
...
@@ -41,13 +41,16 @@ public class PanelSubjectService {
public
List
<
PanelSubject
>
query
(
PanelSubjectRequest
request
){
PanelSubjectExample
example
=
new
PanelSubjectExample
();
return
panelSubjectMapper
.
selectByExampleWithBLOBs
(
null
);
example
.
setOrderByClause
(
"create_time asc"
);
return
panelSubjectMapper
.
selectByExampleWithBLOBs
(
example
);
}
public
List
querySubjectWithGroup
(
PanelSubjectRequest
request
){
List
result
=
new
ArrayList
();
int
pageSize
=
4
;
List
<
PanelSubject
>
allInfo
=
panelSubjectMapper
.
selectByExampleWithBLOBs
(
null
);
PanelSubjectExample
example
=
new
PanelSubjectExample
();
example
.
setOrderByClause
(
"create_time asc"
);
List
<
PanelSubject
>
allInfo
=
panelSubjectMapper
.
selectByExampleWithBLOBs
(
example
);
for
(
int
i
=
0
;
i
<
allInfo
.
size
();
i
=
i
+
pageSize
){
List
<
PanelSubject
>
tmp
=
allInfo
.
subList
(
i
,
i
+
pageSize
<
allInfo
.
size
()?
i
+
pageSize:
allInfo
.
size
());
result
.
add
(
tmp
);
...
...
backend/src/main/java/io/dataease/service/panel/PanelTemplateService.java
浏览文件 @
8a04a2d1
...
...
@@ -8,6 +8,7 @@ import io.dataease.commons.utils.AuthUtils;
import
io.dataease.commons.utils.BeanUtils
;
import
io.dataease.controller.request.panel.PanelTemplateRequest
;
import
io.dataease.dto.panel.PanelTemplateDTO
;
import
io.dataease.exception.DataEaseException
;
import
io.dataease.i18n.Translator
;
import
org.apache.commons.lang3.StringUtils
;
import
org.slf4j.Logger
;
...
...
@@ -70,7 +71,7 @@ public class PanelTemplateService {
request
.
setPid
(
request
.
getTemplateType
());
String
nameCheckResult
=
this
.
nameCheck
(
CommonConstants
.
OPT_TYPE
.
INSERT
,
request
.
getName
(),
request
.
getPid
(),
null
);
if
(
CommonConstants
.
CHECK_RESULT
.
EXIST_ALL
.
equals
(
nameCheckResult
)){
throw
new
Runtime
Exception
(
Translator
.
get
(
"i18n_same_folder_can_not_repeat"
));
DataEaseException
.
throw
Exception
(
Translator
.
get
(
"i18n_same_folder_can_not_repeat"
));
}
}
else
{
//模板插入 相同文件夹同名的模板进行覆盖(先删除)
PanelTemplateExample
exampleDelete
=
new
PanelTemplateExample
();
...
...
@@ -81,7 +82,7 @@ public class PanelTemplateService {
}
else
{
String
nameCheckResult
=
this
.
nameCheck
(
CommonConstants
.
OPT_TYPE
.
UPDATE
,
request
.
getName
(),
request
.
getPid
(),
request
.
getId
());
if
(
CommonConstants
.
CHECK_RESULT
.
EXIST_ALL
.
equals
(
nameCheckResult
)){
throw
new
Runtime
Exception
(
Translator
.
get
(
"i18n_same_folder_can_not_repeat"
));
DataEaseException
.
throw
Exception
(
Translator
.
get
(
"i18n_same_folder_can_not_repeat"
));
}
panelTemplateMapper
.
updateByPrimaryKeySelective
(
request
);
}
...
...
backend/src/main/resources/db/migration/V8__demo.sql
浏览文件 @
8a04a2d1
差异被折叠。
点击展开。
frontend/.eslintrc.js
浏览文件 @
8a04a2d1
...
...
@@ -47,7 +47,9 @@ module.exports = {
'curly'
:
[
2
,
'multi-line'
],
'dot-location'
:
[
2
,
'property'
],
'eol-last'
:
2
,
'eqeqeq'
:
[
"error"
,
"always"
,
{
"null"
:
"ignore"
}],
'eqeqeq'
:
[
"error"
,
"always"
,
{
"null"
:
"ignore"
}],
'generator-star-spacing'
:
[
2
,
{
'before'
:
true
,
'after'
:
true
...
...
frontend/src/components/DeDrag/index.vue
浏览文件 @
8a04a2d1
...
...
@@ -1495,9 +1495,9 @@ export default {
addEvent
(
window
,
'resize'
,
this
.
checkParentSize
)
},
createdFunction
()
{
//
eslint-disable-next-line 无效的prop:
minWidth不能大于maxWidth
// minWidth不能大于maxWidth
if
(
this
.
maxWidth
&&
this
.
minWidth
>
this
.
maxWidth
)
console
.
warn
(
'[Vdr warn]: Invalid prop: minWidth cannot be greater than maxWidth'
)
//
eslint-disable-next-line 无效prop:minHeight不能大于maxHeight'
//
minHeight不能大于maxHeight
if
(
this
.
maxWidth
&&
this
.
minHeight
>
this
.
maxHeight
)
console
.
warn
(
'[Vdr warn]: Invalid prop: minHeight cannot be greater than maxHeight'
)
this
.
elmX
=
0
this
.
elmY
=
0
...
...
frontend/src/components/RightPanel/index.vue
浏览文件 @
8a04a2d1
...
...
@@ -2,9 +2,9 @@
<div
ref=
"rightPanel"
:class=
"
{show:show}" class="rightPanel-container">
<div
class=
"rightPanel-background"
/>
<div
class=
"rightPanel"
>
<!--
<div
class=
"handle-button"
:style=
"
{'top':buttonTop+'px','background-color':theme}" @click="show=!show">-->
<!--
<i
:class=
"show?'el-icon-close':'el-icon-setting'"
/>
-->
<!--
</div>
-->
<!--
<div
class=
"handle-button"
:style=
"
{'top':buttonTop+'px','background-color':theme}" @click="show=!show">-->
<!--
<i
:class=
"show?'el-icon-close':'el-icon-setting'"
/>
-->
<!--
</div>
-->
<div
class=
"rightPanel-items"
>
<slot
/>
</div>
...
...
frontend/src/components/canvas/assets/iconfont/iconfont.js
浏览文件 @
8a04a2d1
差异被折叠。
点击展开。
frontend/src/components/canvas/components/AnimationList.vue
浏览文件 @
8a04a2d1
<
template
>
<div
class=
"animation-list"
>
<div
class=
"div-animation"
>
<el-button
@
click=
"isShowAnimation = true"
>
添加动画
</el-button>
<el-button
@
click=
"previewAnimate"
>
预览动画
</el-button>
<div>
<el-tag
v-for=
"(tag, index) in curComponent.animations"
:key=
"index"
closable
@
close=
"removeAnimation(index)"
>
{{
tag
.
label
}}
</el-tag>
</div>
</div>
<!-- 选择动画 -->
<Modal
v-model=
"isShowAnimation"
>
<el-tabs
v-model=
"animationActiveName"
>
<el-tab-pane
v-for=
"item in animationClassData"
:key=
"item.label"
:label=
"item.label"
:name=
"item.label"
>
<el-scrollbar
class=
"animate-container"
>
<div
class=
"animate"
v-for=
"(animate, index) in item.children"
:key=
"index"
@
mouseover=
"hoverPreviewAnimate = animate.value"
@
click=
"addAnimation(animate)"
>
<div
:class=
"[hoverPreviewAnimate === animate.value && animate.value + ' animated']"
>
{{
animate
.
label
}}
</div>
</div>
</el-scrollbar>
</el-tab-pane>
</el-tabs>
</Modal>
<div
class=
"animation-list"
>
<div
class=
"div-animation"
>
<el-button
@
click=
"isShowAnimation = true"
>
添加动画
</el-button>
<el-button
@
click=
"previewAnimate"
>
预览动画
</el-button>
<div>
<el-tag
v-for=
"(tag, index) in curComponent.animations"
:key=
"index"
closable
@
close=
"removeAnimation(index)"
>
{{
tag
.
label
}}
</el-tag>
</div>
</div>
<!-- 选择动画 -->
<Modal
v-model=
"isShowAnimation"
>
<el-tabs
v-model=
"animationActiveName"
>
<el-tab-pane
v-for=
"item in animationClassData"
:key=
"item.label"
:label=
"item.label"
:name=
"item.label"
>
<el-scrollbar
class=
"animate-container"
>
<div
v-for=
"(animate, index) in item.children"
:key=
"index"
class=
"animate"
@
mouseover=
"hoverPreviewAnimate = animate.value"
@
click=
"addAnimation(animate)"
>
<div
:class=
"[hoverPreviewAnimate === animate.value && animate.value + ' animated']"
>
{{
animate
.
label
}}
</div>
</div>
</el-scrollbar>
</el-tab-pane>
</el-tabs>
</Modal>
</div>
</
template
>
<
script
>
...
...
@@ -45,33 +45,33 @@ import animationClassData from '@/components/canvas/utils/animationClassData'
import
{
mapState
}
from
'vuex'
export
default
{
components
:
{
Modal
},
data
()
{
return
{
isShowAnimation
:
false
,
hoverPreviewAnimate
:
''
,
animationActiveName
:
'进入'
,
animationClassData
,
showAnimatePanel
:
false
,
}
components
:
{
Modal
},
data
()
{
return
{
isShowAnimation
:
false
,
hoverPreviewAnimate
:
''
,
animationActiveName
:
'进入'
,
animationClassData
,
showAnimatePanel
:
false
}
},
computed
:
mapState
([
'curComponent'
]),
methods
:
{
addAnimation
(
animate
)
{
this
.
$store
.
commit
(
'addAnimation'
,
animate
)
this
.
isShowAnimation
=
false
},
computed
:
mapState
([
'curComponent'
,
]),
methods
:
{
addAnimation
(
animate
)
{
this
.
$store
.
commit
(
'addAnimation'
,
animate
)
this
.
isShowAnimation
=
false
},
previewAnimate
()
{
eventBus
.
$emit
(
'runAnimation'
)
},
removeAnimation
(
index
)
{
this
.
$store
.
commit
(
'removeAnimation'
,
index
)
},
previewAnimate
()
{
eventBus
.
$emit
(
'runAnimation'
)
},
removeAnimation
(
index
)
{
this
.
$store
.
commit
(
'removeAnimation'
,
index
)
}
}
}
</
script
>
...
...
frontend/src/components/canvas/components/Editor/ContextMenu.vue
浏览文件 @
8a04a2d1
...
...
@@ -59,7 +59,7 @@ export default {
bus
.
$emit
(
'component-dialog-edit'
)
}
//编辑样式组件
//
编辑样式组件
if
(
this
.
curComponent
.
type
===
'v-text'
||
this
.
curComponent
.
type
===
'rect-shape'
)
{
bus
.
$emit
(
'component-dialog-style'
)
...
...
frontend/src/components/canvas/components/EventList.vue
浏览文件 @
8a04a2d1
<
template
>
<div
class=
"event-list"
>
<div
class=
"div-events"
>
<el-button
@
click=
"isShowEvent = true"
>
添加事件
</el-button>
<div>
<el-tag
v-for=
"event in Object.keys(curComponent.events)"
:key=
"event"
closable
@
close=
"removeEvent(event)"
>
{{
event
}}
</el-tag>
</div>
</div>
<!-- 选择事件 -->
<Modal
v-model=
"isShowEvent"
>
<el-tabs
v-model=
"eventActiveName"
>
<el-tab-pane
v-for=
"item in eventList"
:key=
"item.key"
:label=
"item.label"
:name=
"item.key"
style=
"padding: 0 20px"
>
<el-input
v-if=
"item.key == 'redirect'"
v-model=
"item.param"
type=
"textarea"
placeholder=
"请输入完整的 URL"
/>
<el-input
v-if=
"item.key == 'alert'"
v-model=
"item.param"
type=
"textarea"
placeholder=
"请输入要 alert 的内容"
/>
<el-button
style=
"margin-top: 20px;"
@
click=
"addEvent(item.key, item.param)"
>
确定
</el-button>
</el-tab-pane>
</el-tabs>
</Modal>
<div
class=
"event-list"
>
<div
class=
"div-events"
>
<el-button
@
click=
"isShowEvent = true"
>
添加事件
</el-button>
<div>
<el-tag
v-for=
"event in Object.keys(curComponent.events)"
:key=
"event"
closable
@
close=
"removeEvent(event)"
>
{{
event
}}
</el-tag>
</div>
</div>
<!-- 选择事件 -->
<Modal
v-model=
"isShowEvent"
>
<el-tabs
v-model=
"eventActiveName"
>
<el-tab-pane
v-for=
"item in eventList"
:key=
"item.key"
:label=
"item.label"
:name=
"item.key"
style=
"padding: 0 20px"
>
<el-input
v-if=
"item.key == 'redirect'"
v-model=
"item.param"
type=
"textarea"
placeholder=
"请输入完整的 URL"
/>
<el-input
v-if=
"item.key == 'alert'"
v-model=
"item.param"
type=
"textarea"
placeholder=
"请输入要 alert 的内容"
/>
<el-button
style=
"margin-top: 20px;"
@
click=
"addEvent(item.key, item.param)"
>
确定
</el-button>
</el-tab-pane>
</el-tabs>
</Modal>
</div>
</
template
>
<
script
>
...
...
@@ -33,28 +33,28 @@ import Modal from '@/components/canvas/components/Modal'
import
{
eventList
}
from
'@/components/canvas/utils/events'
export
default
{
components
:
{
Modal
},
data
()
{
return
{
isShowEvent
:
false
,
eventURL
:
''
,
eventActiveName
:
'redirect'
,
eventList
,
}
components
:
{
Modal
},
data
()
{
return
{
isShowEvent
:
false
,
eventURL
:
''
,
eventActiveName
:
'redirect'
,
eventList
}
},
computed
:
mapState
([
'curComponent'
]),
methods
:
{
addEvent
(
event
,
param
)
{
this
.
isShowEvent
=
false
this
.
$store
.
commit
(
'addEvent'
,
{
event
,
param
})
},
computed
:
mapState
([
'curComponent'
,
]),
methods
:
{
addEvent
(
event
,
param
)
{
this
.
isShowEvent
=
false
this
.
$store
.
commit
(
'addEvent'
,
{
event
,
param
})
},
removeEvent
(
event
)
{
this
.
$store
.
commit
(
'removeEvent'
,
event
)
},
},
removeEvent
(
event
)
{
this
.
$store
.
commit
(
'removeEvent'
,
event
)
}
}
}
</
script
>
...
...
frontend/src/components/canvas/components/Modal.vue
浏览文件 @
8a04a2d1
<
template
>
<div
class=
"modal-bg"
v-if=
"show"
@
click=
"hide"
>
<div
class=
"fadeInLeft animated modal"
@
click=
"stopPropagation"
>
<slot></slot>
</div>
<div
v-if=
"show"
class=
"modal-bg"
@
click=
"hide"
>
<div
class=
"fadeInLeft animated modal"
@
click=
"stopPropagation"
>
<slot
/>
</div>
</div>
</
template
>
<
script
>
export
default
{
model
:
{
prop
:
'show'
,
event
:
'change'
,
},
props
:
{
show
:
{
type
:
Boolean
,
default
:
false
,
},
model
:
{
prop
:
'show'
,
event
:
'change'
},
props
:
{
show
:
{
type
:
Boolean
,
default
:
false
}
},
methods
:
{
hide
()
{
this
.
$emit
(
'change'
)
},
methods
:
{
hide
()
{
this
.
$emit
(
'change'
)
},
stopPropagation
(
e
)
{
e
.
stopPropagation
()
},
},
stopPropagation
(
e
)
{
e
.
stopPropagation
()
}
}
}
</
script
>
...
...
@@ -46,4 +46,4 @@ export default {
height
:
100%
;
}
}
</
style
>
\ No newline at end of file
</
style
>
frontend/src/components/canvas/components/Toolbar.vue
浏览文件 @
8a04a2d1
...
...
@@ -3,12 +3,12 @@
<div
class=
"toolbar"
>
<div
class=
"canvas-config"
style=
"margin-right: 10px"
>
<el-switch
v-model=
"canvasStyleData.auxiliaryMatrix"
:width=
"35"
name=
"auxiliaryMatrix"
/>
<el-switch
v-model=
"canvasStyleData.auxiliaryMatrix"
:width=
"35"
name=
"auxiliaryMatrix"
/>
<span>
{{
$t
(
'panel.matrix_design'
)
}}
</span>
</div>
<div
class=
"canvas-config"
style=
"margin-right: 10px"
>
<el-switch
v-model=
"canvasStyleData.selfAdaption"
:width=
"35"
name=
"selfAdaption"
/>
<el-switch
v-model=
"canvasStyleData.selfAdaption"
:width=
"35"
name=
"selfAdaption"
/>
<span>
{{
$t
(
'panel.canvas_self_adaption'
)
}}
</span>
</div>
...
...
frontend/src/components/canvas/custom-component/Group.vue
浏览文件 @
8a04a2d1
<
template
>
<div
class=
"group"
>
<div>
<template
v-for=
"item in propValue"
>
<component
class=
"component"
:is=
"item.component"
:style=
"item.groupStyle"
:propValue=
"item.propValue"
:key=
"item.id"
:id=
"'component' + item.id"
:element=
"item"
/>
</
template
>
</div>
<div
class=
"group"
>
<div>
<template
v-for=
"item in propValue"
>
<component
:is=
"item.component"
:id=
"'component' + item.id"
:key=
"item.id"
class=
"component"
:style=
"item.groupStyle"
:prop-value=
"item.propValue"
:element=
"item"
/>
</
template
>
</div>
</div>
</template>
<
script
>
import
{
getStyle
}
from
'@/components/canvas/utils/style'
export
default
{
props
:
{
propValue
:
{
type
:
Array
,
default
:
()
=>
[],
},
element
:
{
type
:
Object
,
},
},
created
()
{
const
parentStyle
=
this
.
element
.
style
this
.
propValue
.
forEach
(
component
=>
{
// component.groupStyle 的 top left 是相对于 group 组件的位置
// 如果已存在 component.groupStyle,说明已经计算过一次了。不需要再次计算
if
(
!
Object
.
keys
(
component
.
groupStyle
).
length
)
{
const
style
=
{
...
component
.
style
}
component
.
groupStyle
=
getStyle
(
style
)
component
.
groupStyle
.
left
=
this
.
toPercent
((
style
.
left
-
parentStyle
.
left
)
/
parentStyle
.
width
)
component
.
groupStyle
.
top
=
this
.
toPercent
((
style
.
top
-
parentStyle
.
top
)
/
parentStyle
.
height
)
component
.
groupStyle
.
width
=
this
.
toPercent
(
style
.
width
/
parentStyle
.
width
)
component
.
groupStyle
.
height
=
this
.
toPercent
(
style
.
height
/
parentStyle
.
height
)
}
})
},
methods
:
{
toPercent
(
val
)
{
return
val
*
100
+
'%'
},
props
:
{
propValue
:
{
type
:
Array
,
default
:
()
=>
[]
},
element
:
{
type
:
Object
}
},
created
()
{
const
parentStyle
=
this
.
element
.
style
this
.
propValue
.
forEach
(
component
=>
{
// component.groupStyle 的 top left 是相对于 group 组件的位置
// 如果已存在 component.groupStyle,说明已经计算过一次了。不需要再次计算
if
(
!
Object
.
keys
(
component
.
groupStyle
).
length
)
{
const
style
=
{
...
component
.
style
}
component
.
groupStyle
=
getStyle
(
style
)
component
.
groupStyle
.
left
=
this
.
toPercent
((
style
.
left
-
parentStyle
.
left
)
/
parentStyle
.
width
)
component
.
groupStyle
.
top
=
this
.
toPercent
((
style
.
top
-
parentStyle
.
top
)
/
parentStyle
.
height
)
component
.
groupStyle
.
width
=
this
.
toPercent
(
style
.
width
/
parentStyle
.
width
)
component
.
groupStyle
.
height
=
this
.
toPercent
(
style
.
height
/
parentStyle
.
height
)
}
})
},
methods
:
{
toPercent
(
val
)
{
return
val
*
100
+
'%'
}
}
}
</
script
>
...
...
frontend/src/components/canvas/custom-component/Picture.vue
浏览文件 @
8a04a2d1
<
template
>
<div
style=
"overflow: hidden"
>
<img
:src=
"propValue"
>
</div>
<div
style=
"overflow: hidden"
>
<img
:src=
"propValue"
>
</div>
</
template
>
<
script
>
export
default
{
props
:
{
propValue
:
{
type
:
String
,
require
:
true
,
},
},
props
:
{
propValue
:
{
type
:
String
,
require
:
true
}
}
}
</
script
>
...
...
@@ -20,4 +20,4 @@ img {
width
:
100%
;
height
:
100%
;
}
</
style
>
\ No newline at end of file
</
style
>
frontend/src/components/canvas/custom-component/VButton.vue
浏览文件 @
8a04a2d1
<
template
>
<button
class=
"v-button"
>
{{
propValue
}}
</button>
<button
class=
"v-button"
>
{{
propValue
}}
</button>
</
template
>
<
script
>
export
default
{
props
:
{
propValue
:
{
type
:
String
,
default
:
''
,
},
},
props
:
{
propValue
:
{
type
:
String
,
default
:
''
}
}
}
</
script
>
...
...
@@ -44,4 +44,4 @@ export default {
color
:
#3a8ee6
;
}
}
</
style
>
\ No newline at end of file
</
style
>
frontend/src/components/canvas/store/animation.js
浏览文件 @
8a04a2d1
export
default
{
mutations
:
{
addAnimation
({
curComponent
},
animation
)
{
curComponent
.
animations
.
push
(
animation
)
},
removeAnimation
({
curComponent
},
index
)
{
curComponent
.
animations
.
splice
(
index
,
1
)
},
mutations
:
{
addAnimation
({
curComponent
},
animation
)
{
curComponent
.
animations
.
push
(
animation
)
},
}
\ No newline at end of file
removeAnimation
({
curComponent
},
index
)
{
curComponent
.
animations
.
splice
(
index
,
1
)
}
}
}
frontend/src/components/canvas/store/contextmenu.js
浏览文件 @
8a04a2d1
export
default
{
state
:
{
menuTop
:
0
,
// 右击菜单数据
menuLeft
:
0
,
menuShow
:
false
,
state
:
{
menuTop
:
0
,
// 右击菜单数据
menuLeft
:
0
,
menuShow
:
false
},
mutations
:
{
showContextMenu
(
state
,
{
top
,
left
})
{
state
.
menuShow
=
true
state
.
menuTop
=
top
state
.
menuLeft
=
left
},
mutations
:
{
showContextMenu
(
state
,
{
top
,
left
})
{
state
.
menuShow
=
true
state
.
menuTop
=
top
state
.
menuLeft
=
left
},
hideContextMenu
(
state
)
{
state
.
menuShow
=
false
},
},
}
\ No newline at end of file
hideContextMenu
(
state
)
{
state
.
menuShow
=
false
}
}
}
frontend/src/components/canvas/store/copy.js
浏览文件 @
8a04a2d1
...
...
@@ -4,64 +4,64 @@ import generateID from '@/components/canvas/utils/generateID'
import
{
deepCopy
}
from
'@/components/canvas/utils/utils'
export
default
{
state
:
{
copyData
:
null
,
// 复制粘贴剪切
isCut
:
false
,
},
mutations
:
{
copy
(
state
)
{
if
(
!
state
.
curComponent
)
return
state
.
copyData
=
{
data
:
deepCopy
(
state
.
curComponent
),
index
:
state
.
curComponentIndex
,
}
state
:
{
copyData
:
null
,
// 复制粘贴剪切
isCut
:
false
},
mutations
:
{
copy
(
state
)
{
if
(
!
state
.
curComponent
)
return
state
.
copyData
=
{
data
:
deepCopy
(
state
.
curComponent
),
index
:
state
.
curComponentIndex
}
state
.
isCut
=
false
},
state
.
isCut
=
false
},
paste
(
state
,
isMouse
)
{
if
(
!
state
.
copyData
)
{
toast
(
'请选择组件'
)
return
}
paste
(
state
,
isMouse
)
{
if
(
!
state
.
copyData
)
{
toast
(
'请选择组件'
)
return
}
const
data
=
state
.
copyData
.
data
const
data
=
state
.
copyData
.
data
if
(
isMouse
)
{
data
.
style
.
top
=
state
.
menuTop
data
.
style
.
left
=
state
.
menuLeft
}
else
{
data
.
style
.
top
+=
10
data
.
style
.
left
+=
10
}
if
(
isMouse
)
{
data
.
style
.
top
=
state
.
menuTop
data
.
style
.
left
=
state
.
menuLeft
}
else
{
data
.
style
.
top
+=
10
data
.
style
.
left
+=
10
}
data
.
id
=
generateID
()
store
.
commit
(
'addComponent'
,
{
component
:
deepCopy
(
data
)
})
if
(
state
.
isCut
)
{
state
.
copyData
=
null
}
},
data
.
id
=
generateID
()
store
.
commit
(
'addComponent'
,
{
component
:
deepCopy
(
data
)
})
if
(
state
.
isCut
)
{
state
.
copyData
=
null
}
},
cut
(
state
)
{
if
(
!
state
.
curComponent
)
{
toast
(
'请选择组件'
)
return
}
cut
(
state
)
{
if
(
!
state
.
curComponent
)
{
toast
(
'请选择组件'
)
return
}
if
(
state
.
copyData
)
{
const
data
=
deepCopy
(
state
.
copyData
.
data
)
const
index
=
state
.
copyData
.
index
data
.
id
=
generateID
()
store
.
commit
(
'addComponent'
,
{
component
:
data
,
index
})
if
(
state
.
curComponentIndex
>=
index
)
{
// 如果当前组件索引大于等于插入索引,需要加一,因为当前组件往后移了一位
state
.
curComponentIndex
++
}
}
if
(
state
.
copyData
)
{
const
data
=
deepCopy
(
state
.
copyData
.
data
)
const
index
=
state
.
copyData
.
index
data
.
id
=
generateID
()
store
.
commit
(
'addComponent'
,
{
component
:
data
,
index
})
if
(
state
.
curComponentIndex
>=
index
)
{
// 如果当前组件索引大于等于插入索引,需要加一,因为当前组件往后移了一位
state
.
curComponentIndex
++
}
}
store
.
commit
(
'copy'
)
store
.
commit
(
'deleteComponent'
)
state
.
isCut
=
true
},
},
store
.
commit
(
'copy'
)
store
.
commit
(
'deleteComponent'
)
state
.
isCut
=
true
}
}
}
frontend/src/components/canvas/store/event.js
浏览文件 @
8a04a2d1
export
default
{
mutations
:
{
addEvent
({
curComponent
},
{
event
,
param
})
{
curComponent
.
events
[
event
]
=
param
},
removeEvent
({
curComponent
},
event
)
{
delete
curComponent
.
events
[
event
]
},
mutations
:
{
addEvent
({
curComponent
},
{
event
,
param
})
{
curComponent
.
events
[
event
]
=
param
},
}
\ No newline at end of file
removeEvent
({
curComponent
},
event
)
{
delete
curComponent
.
events
[
event
]
}
}
}
frontend/src/components/canvas/store/lock.js
浏览文件 @
8a04a2d1
export
default
{
mutations
:
{
lock
({
curComponent
})
{
curComponent
.
isLock
=
true
},
unlock
({
curComponent
})
{
curComponent
.
isLock
=
false
},
mutations
:
{
lock
({
curComponent
})
{
curComponent
.
isLock
=
true
},
}
\ No newline at end of file
unlock
({
curComponent
})
{
curComponent
.
isLock
=
false
}
}
}
frontend/src/components/canvas/utils/animationClassData.js
浏览文件 @
8a04a2d1
export
default
[
{
label
:
'进入'
,
children
:
[
{
label
:
'渐显'
,
value
:
'fadeIn'
},
{
label
:
'向右进入'
,
value
:
'fadeInLeft'
},
{
label
:
'向左进入'
,
value
:
'fadeInRight'
},
{
label
:
'向上进入'
,
value
:
'fadeInUp'
},
{
label
:
'向下进入'
,
value
:
'fadeInDown'
},
{
label
:
'向右长距进入'
,
value
:
'fadeInLeftBig'
},
{
label
:
'向左长距进入'
,
value
:
'fadeInRightBig'
},
{
label
:
'向上长距进入'
,
value
:
'fadeInUpBig'
},
{
label
:
'向下长距进入'
,
value
:
'fadeInDownBig'
},
{
label
:
'旋转进入'
,
value
:
'rotateIn'
},
{
label
:
'左顺时针旋转'
,
value
:
'rotateInDownLeft'
},
{
label
:
'右逆时针旋转'
,
value
:
'rotateInDownRight'
},
{
label
:
'左逆时针旋转'
,
value
:
'rotateInUpLeft'
},
{
label
:
'右逆时针旋转'
,
value
:
'rotateInUpRight'
},
{
label
:
'弹入'
,
value
:
'bounceIn'
},
{
label
:
'向右弹入'
,
value
:
'bounceInLeft'
},
{
label
:
'向左弹入'
,
value
:
'bounceInRight'
},
{
label
:
'向上弹入'
,
value
:
'bounceInUp'
},
{
label
:
'向下弹入'
,
value
:
'bounceInDown'
},
{
label
:
'光速从右进入'
,
value
:
'lightSpeedInRight'
},
{
label
:
'光速从左进入'
,
value
:
'lightSpeedInLeft'
},
{
label
:
'光速从右退出'
,
value
:
'lightSpeedOutRight'
},
{
label
:
'光速从左退出'
,
value
:
'lightSpeedOutLeft'
},
{
label
:
'Y轴旋转'
,
value
:
'flip'
},
{
label
:
'中心X轴旋转'
,
value
:
'flipInX'
},
{
label
:
'中心Y轴旋转'
,
value
:
'flipInY'
},
{
label
:
'左长半径旋转'
,
value
:
'rollIn'
},
{
label
:
'由小变大进入'
,
value
:
'zoomIn'
},
{
label
:
'左变大进入'
,
value
:
'zoomInLeft'
},
{
label
:
'右变大进入'
,
value
:
'zoomInRight'
},
{
label
:
'向上变大进入'
,
value
:
'zoomInUp'
},
{
label
:
'向下变大进入'
,
value
:
'zoomInDown'
},
{
label
:
'向右滑动展开'
,
value
:
'slideInLeft'
},
{
label
:
'向左滑动展开'
,
value
:
'slideInRight'
},
{
label
:
'向上滑动展开'
,
value
:
'slideInUp'
},
{
label
:
'向下滑动展开'
,
value
:
'slideInDown'
},
],
},
{
label
:
'强调'
,
children
:
[
{
label
:
'弹跳'
,
value
:
'bounce'
},
{
label
:
'闪烁'
,
value
:
'flash'
},
{
label
:
'放大缩小'
,
value
:
'pulse'
},
{
label
:
'放大缩小弹簧'
,
value
:
'rubberBand'
},
{
label
:
'左右晃动'
,
value
:
'headShake'
},
{
label
:
'左右扇形摇摆'
,
value
:
'swing'
},
{
label
:
'放大晃动缩小'
,
value
:
'tada'
},
{
label
:
'扇形摇摆'
,
value
:
'wobble'
},
{
label
:
'左右上下晃动'
,
value
:
'jello'
},
{
label
:
'Y轴旋转'
,
value
:
'flip'
},
],
},
{
label
:
'退出'
,
children
:
[
{
label
:
'渐隐'
,
value
:
'fadeOut'
},
{
label
:
'向左退出'
,
value
:
'fadeOutLeft'
},
{
label
:
'向右退出'
,
value
:
'fadeOutRight'
},
{
label
:
'向上退出'
,
value
:
'fadeOutUp'
},
{
label
:
'向下退出'
,
value
:
'fadeOutDown'
},
{
label
:
'向左长距退出'
,
value
:
'fadeOutLeftBig'
},
{
label
:
'向右长距退出'
,
value
:
'fadeOutRightBig'
},
{
label
:
'向上长距退出'
,
value
:
'fadeOutUpBig'
},
{
label
:
'向下长距退出'
,
value
:
'fadeOutDownBig'
},
{
label
:
'旋转退出'
,
value
:
'rotateOut'
},
{
label
:
'左顺时针旋转'
,
value
:
'rotateOutDownLeft'
},
{
label
:
'右逆时针旋转'
,
value
:
'rotateOutDownRight'
},
{
label
:
'左逆时针旋转'
,
value
:
'rotateOutUpLeft'
},
{
label
:
'右逆时针旋转'
,
value
:
'rotateOutUpRight'
},
{
label
:
'弹出'
,
value
:
'bounceOut'
},
{
label
:
'向左弹出'
,
value
:
'bounceOutLeft'
},
{
label
:
'向右弹出'
,
value
:
'bounceOutRight'
},
{
label
:
'向上弹出'
,
value
:
'bounceOutUp'
},
{
label
:
'向下弹出'
,
value
:
'bounceOutDown'
},
{
label
:
'中心X轴旋转'
,
value
:
'flipOutX'
},
{
label
:
'中心Y轴旋转'
,
value
:
'flipOutY'
},
{
label
:
'左长半径旋转'
,
value
:
'rollOut'
},
{
label
:
'由小变大退出'
,
value
:
'zoomOut'
},
{
label
:
'左变大退出'
,
value
:
'zoomOutLeft'
},
{
label
:
'右变大退出'
,
value
:
'zoomOutRight'
},
{
label
:
'向上变大退出'
,
value
:
'zoomOutUp'
},
{
label
:
'向下变大退出'
,
value
:
'zoomOutDown'
},
{
label
:
'向左滑动收起'
,
value
:
'slideOutLeft'
},
{
label
:
'向右滑动收起'
,
value
:
'slideOutRight'
},
{
label
:
'向上滑动收起'
,
value
:
'slideOutUp'
},
{
label
:
'向下滑动收起'
,
value
:
'slideOutDown'
},
],
},
{
label
:
'进入'
,
children
:
[
{
label
:
'渐显'
,
value
:
'fadeIn'
},
{
label
:
'向右进入'
,
value
:
'fadeInLeft'
},
{
label
:
'向左进入'
,
value
:
'fadeInRight'
},
{
label
:
'向上进入'
,
value
:
'fadeInUp'
},
{
label
:
'向下进入'
,
value
:
'fadeInDown'
},
{
label
:
'向右长距进入'
,
value
:
'fadeInLeftBig'
},
{
label
:
'向左长距进入'
,
value
:
'fadeInRightBig'
},
{
label
:
'向上长距进入'
,
value
:
'fadeInUpBig'
},
{
label
:
'向下长距进入'
,
value
:
'fadeInDownBig'
},
{
label
:
'旋转进入'
,
value
:
'rotateIn'
},
{
label
:
'左顺时针旋转'
,
value
:
'rotateInDownLeft'
},
{
label
:
'右逆时针旋转'
,
value
:
'rotateInDownRight'
},
{
label
:
'左逆时针旋转'
,
value
:
'rotateInUpLeft'
},
{
label
:
'右逆时针旋转'
,
value
:
'rotateInUpRight'
},
{
label
:
'弹入'
,
value
:
'bounceIn'
},
{
label
:
'向右弹入'
,
value
:
'bounceInLeft'
},
{
label
:
'向左弹入'
,
value
:
'bounceInRight'
},
{
label
:
'向上弹入'
,
value
:
'bounceInUp'
},
{
label
:
'向下弹入'
,
value
:
'bounceInDown'
},
{
label
:
'光速从右进入'
,
value
:
'lightSpeedInRight'
},
{
label
:
'光速从左进入'
,
value
:
'lightSpeedInLeft'
},
{
label
:
'光速从右退出'
,
value
:
'lightSpeedOutRight'
},
{
label
:
'光速从左退出'
,
value
:
'lightSpeedOutLeft'
},
{
label
:
'Y轴旋转'
,
value
:
'flip'
},
{
label
:
'中心X轴旋转'
,
value
:
'flipInX'
},
{
label
:
'中心Y轴旋转'
,
value
:
'flipInY'
},
{
label
:
'左长半径旋转'
,
value
:
'rollIn'
},
{
label
:
'由小变大进入'
,
value
:
'zoomIn'
},
{
label
:
'左变大进入'
,
value
:
'zoomInLeft'
},
{
label
:
'右变大进入'
,
value
:
'zoomInRight'
},
{
label
:
'向上变大进入'
,
value
:
'zoomInUp'
},
{
label
:
'向下变大进入'
,
value
:
'zoomInDown'
},
{
label
:
'向右滑动展开'
,
value
:
'slideInLeft'
},
{
label
:
'向左滑动展开'
,
value
:
'slideInRight'
},
{
label
:
'向上滑动展开'
,
value
:
'slideInUp'
},
{
label
:
'向下滑动展开'
,
value
:
'slideInDown'
}
]
},
{
label
:
'强调'
,
children
:
[
{
label
:
'弹跳'
,
value
:
'bounce'
},
{
label
:
'闪烁'
,
value
:
'flash'
},
{
label
:
'放大缩小'
,
value
:
'pulse'
},
{
label
:
'放大缩小弹簧'
,
value
:
'rubberBand'
},
{
label
:
'左右晃动'
,
value
:
'headShake'
},
{
label
:
'左右扇形摇摆'
,
value
:
'swing'
},
{
label
:
'放大晃动缩小'
,
value
:
'tada'
},
{
label
:
'扇形摇摆'
,
value
:
'wobble'
},
{
label
:
'左右上下晃动'
,
value
:
'jello'
},
{
label
:
'Y轴旋转'
,
value
:
'flip'
}
]
},
{
label
:
'退出'
,
children
:
[
{
label
:
'渐隐'
,
value
:
'fadeOut'
},
{
label
:
'向左退出'
,
value
:
'fadeOutLeft'
},
{
label
:
'向右退出'
,
value
:
'fadeOutRight'
},
{
label
:
'向上退出'
,
value
:
'fadeOutUp'
},
{
label
:
'向下退出'
,
value
:
'fadeOutDown'
},
{
label
:
'向左长距退出'
,
value
:
'fadeOutLeftBig'
},
{
label
:
'向右长距退出'
,
value
:
'fadeOutRightBig'
},
{
label
:
'向上长距退出'
,
value
:
'fadeOutUpBig'
},
{
label
:
'向下长距退出'
,
value
:
'fadeOutDownBig'
},
{
label
:
'旋转退出'
,
value
:
'rotateOut'
},
{
label
:
'左顺时针旋转'
,
value
:
'rotateOutDownLeft'
},
{
label
:
'右逆时针旋转'
,
value
:
'rotateOutDownRight'
},
{
label
:
'左逆时针旋转'
,
value
:
'rotateOutUpLeft'
},
{
label
:
'右逆时针旋转'
,
value
:
'rotateOutUpRight'
},
{
label
:
'弹出'
,
value
:
'bounceOut'
},
{
label
:
'向左弹出'
,
value
:
'bounceOutLeft'
},
{
label
:
'向右弹出'
,
value
:
'bounceOutRight'
},
{
label
:
'向上弹出'
,
value
:
'bounceOutUp'
},
{
label
:
'向下弹出'
,
value
:
'bounceOutDown'
},
{
label
:
'中心X轴旋转'
,
value
:
'flipOutX'
},
{
label
:
'中心Y轴旋转'
,
value
:
'flipOutY'
},
{
label
:
'左长半径旋转'
,
value
:
'rollOut'
},
{
label
:
'由小变大退出'
,
value
:
'zoomOut'
},
{
label
:
'左变大退出'
,
value
:
'zoomOutLeft'
},
{
label
:
'右变大退出'
,
value
:
'zoomOutRight'
},
{
label
:
'向上变大退出'
,
value
:
'zoomOutUp'
},
{
label
:
'向下变大退出'
,
value
:
'zoomOutDown'
},
{
label
:
'向左滑动收起'
,
value
:
'slideOutLeft'
},
{
label
:
'向右滑动收起'
,
value
:
'slideOutRight'
},
{
label
:
'向上滑动收起'
,
value
:
'slideOutUp'
},
{
label
:
'向下滑动收起'
,
value
:
'slideOutDown'
}
]
}
]
frontend/src/components/canvas/utils/decomposeComponent.js
浏览文件 @
8a04a2d1
...
...
@@ -3,18 +3,18 @@ import { mod360 } from './translate'
// 将组合中的各个子组件拆分出来,并计算它们新的 style
export
default
function
decomposeComponent
(
component
,
editorRect
,
parentStyle
)
{
const
componentRect
=
$
(
`#component
${
component
.
id
}
`
).
getBoundingClientRect
()
// 获取元素的中心点坐标
const
center
=
{
x
:
componentRect
.
left
-
editorRect
.
left
+
componentRect
.
width
/
2
,
y
:
componentRect
.
top
-
editorRect
.
top
+
componentRect
.
height
/
2
,
}
const
componentRect
=
$
(
`#component
${
component
.
id
}
`
).
getBoundingClientRect
()
// 获取元素的中心点坐标
const
center
=
{
x
:
componentRect
.
left
-
editorRect
.
left
+
componentRect
.
width
/
2
,
y
:
componentRect
.
top
-
editorRect
.
top
+
componentRect
.
height
/
2
}
component
.
style
.
rotate
=
mod360
(
component
.
style
.
rotate
+
parentStyle
.
rotate
)
component
.
style
.
width
=
parseFloat
(
component
.
groupStyle
.
width
)
/
100
*
parentStyle
.
width
component
.
style
.
height
=
parseFloat
(
component
.
groupStyle
.
height
)
/
100
*
parentStyle
.
height
// 计算出元素新的 top left 坐标
component
.
style
.
left
=
center
.
x
-
component
.
style
.
width
/
2
component
.
style
.
top
=
center
.
y
-
component
.
style
.
height
/
2
component
.
groupStyle
=
{}
}
\ No newline at end of file
component
.
style
.
rotate
=
mod360
(
component
.
style
.
rotate
+
parentStyle
.
rotate
)
component
.
style
.
width
=
parseFloat
(
component
.
groupStyle
.
width
)
/
100
*
parentStyle
.
width
component
.
style
.
height
=
parseFloat
(
component
.
groupStyle
.
height
)
/
100
*
parentStyle
.
height
// 计算出元素新的 top left 坐标
component
.
style
.
left
=
center
.
x
-
component
.
style
.
width
/
2
component
.
style
.
top
=
center
.
y
-
component
.
style
.
height
/
2
component
.
groupStyle
=
{}
}
frontend/src/components/canvas/utils/eventBus.js
浏览文件 @
8a04a2d1
import
Vue
from
'vue'
// 用于监听、触发事件
export
default
new
Vue
()
\ No newline at end of file
export
default
new
Vue
()
frontend/src/components/canvas/utils/events.js
浏览文件 @
8a04a2d1
// 编辑器自定义事件
const
events
=
{
redirect
(
url
)
{
if
(
url
)
{
window
.
location
.
href
=
url
}
},
redirect
(
url
)
{
if
(
url
)
{
window
.
location
.
href
=
url
}
},
alert
(
msg
)
{
if
(
msg
)
{
alert
(
msg
)
}
},
alert
(
msg
)
{
if
(
msg
)
{
alert
(
msg
)
}
}
}
const
mixins
=
{
methods
:
events
,
methods
:
events
}
const
eventList
=
[
{
key
:
'redirect'
,
label
:
'跳转事件'
,
event
:
events
.
redirect
,
param
:
''
,
},
{
key
:
'alert'
,
label
:
'alert 事件'
,
event
:
events
.
alert
,
param
:
''
,
},
{
key
:
'redirect'
,
label
:
'跳转事件'
,
event
:
events
.
redirect
,
param
:
''
},
{
key
:
'alert'
,
label
:
'alert 事件'
,
event
:
events
.
alert
,
param
:
''
}
]
export
{
mixins
,
events
,
eventList
,
}
\ No newline at end of file
mixins
,
events
,
eventList
}
frontend/src/components/canvas/utils/generateID.js
浏览文件 @
8a04a2d1
let
id
=
0
// 主要用于 Vue 的 diff 算法,为每个元素创建一个独一无二的 ID
export
default
function
generateID
()
{
return
id
++
}
\ No newline at end of file
return
id
++
}
frontend/src/components/canvas/utils/runAnimation.js
浏览文件 @
8a04a2d1
export
default
async
function
runAnimation
(
$el
,
animations
=
[])
{
const
play
=
(
animation
)
=>
new
Promise
(
resolve
=>
{
$el
.
classList
.
add
(
animation
.
value
,
'animated'
)
const
removeAnimation
=
()
=>
{
$el
.
removeEventListener
(
'animationend'
,
removeAnimation
)
$el
.
removeEventListener
(
'animationcancel'
,
removeAnimation
)
$el
.
classList
.
remove
(
animation
.
value
,
'animated'
)
resolve
()
}
$el
.
addEventListener
(
'animationend'
,
removeAnimation
)
$el
.
addEventListener
(
'animationcancel'
,
removeAnimation
)
})
for
(
let
i
=
0
,
len
=
animations
.
length
;
i
<
len
;
i
++
)
{
await
play
(
animations
[
i
])
const
play
=
(
animation
)
=>
new
Promise
(
resolve
=>
{
$el
.
classList
.
add
(
animation
.
value
,
'animated'
)
const
removeAnimation
=
()
=>
{
$el
.
removeEventListener
(
'animationend'
,
removeAnimation
)
$el
.
removeEventListener
(
'animationcancel'
,
removeAnimation
)
$el
.
classList
.
remove
(
animation
.
value
,
'animated'
)
resolve
()
}
$el
.
addEventListener
(
'animationend'
,
removeAnimation
)
$el
.
addEventListener
(
'animationcancel'
,
removeAnimation
)
})
for
(
let
i
=
0
,
len
=
animations
.
length
;
i
<
len
;
i
++
)
{
await
play
(
animations
[
i
])
}
}
frontend/src/components/canvas/utils/shortcutKey.js
浏览文件 @
8a04a2d1
import
store
from
'@/store'
import
eventBus
from
'@/components/canvas/utils/eventBus'
const
ctrlKey
=
17
,
vKey
=
86
,
// 粘贴
cKey
=
67
,
// 复制
xKey
=
88
,
// 剪切
const
ctrlKey
=
17
const
vKey
=
86
// 粘贴
const
cKey
=
67
// 复制
const
xKey
=
88
// 剪切
yKey
=
89
,
// 重做
zKey
=
90
,
// 撤销
const
yKey
=
89
// 重做
const
zKey
=
90
// 撤销
gKey
=
71
,
// 组合
bKey
=
66
,
// 拆分
const
gKey
=
71
// 组合
const
bKey
=
66
// 拆分
lKey
=
76
,
// 锁定
uKey
=
85
,
// 解锁
const
lKey
=
76
// 锁定
const
uKey
=
85
// 解锁
sKey
=
83
,
// 保存
pKey
=
80
,
// 预览
dKey
=
68
,
// 删除
deleteKey
=
46
,
// 删除
eKey
=
69
// 清空画布
const
sKey
=
83
// 保存
const
pKey
=
80
// 预览
const
dKey
=
68
// 删除
const
deleteKey
=
46
// 删除
const
eKey
=
69
// 清空画布
export
const
keycodes
=
[
66
,
67
,
68
,
69
,
71
,
76
,
80
,
83
,
85
,
86
,
88
,
89
,
90
]
// 与组件状态无关的操作
const
basemap
=
{
[
vKey
]:
paste
,
[
yKey
]:
redo
,
[
zKey
]:
undo
,
[
sKey
]:
save
,
[
pKey
]:
preview
,
[
eKey
]:
clearCanvas
,
[
vKey
]:
paste
,
[
yKey
]:
redo
,
[
zKey
]:
undo
,
[
sKey
]:
save
,
[
pKey
]:
preview
,
[
eKey
]:
clearCanvas
}
// 组件锁定状态下可以执行的操作
const
lockMap
=
{
...
basemap
,
[
uKey
]:
unlock
,
...
basemap
,
[
uKey
]:
unlock
}
// 组件未锁定状态下可以执行的操作
const
unlockMap
=
{
...
basemap
,
[
cKey
]:
copy
,
[
xKey
]:
cut
,
[
gKey
]:
compose
,
[
bKey
]:
decompose
,
[
dKey
]:
deleteComponent
,
[
deleteKey
]:
deleteComponent
,
[
lKey
]:
lock
,
...
basemap
,
[
cKey
]:
copy
,
[
xKey
]:
cut
,
[
gKey
]:
compose
,
[
bKey
]:
decompose
,
[
dKey
]:
deleteComponent
,
[
deleteKey
]:
deleteComponent
,
[
lKey
]:
lock
}
let
isCtrlDown
=
false
// 全局监听按键操作并执行相应命令
export
function
listenGlobalKeyDown
()
{
window
.
onkeydown
=
(
e
)
=>
{
const
{
curComponent
}
=
store
.
state
if
(
e
.
keyCode
==
ctrlKey
)
{
isCtrlDown
=
true
}
else
if
(
e
.
keyCode
==
deleteKey
&&
curComponent
)
{
store
.
commit
(
'deleteComponent'
)
store
.
commit
(
'recordSnapshot'
)
}
else
if
(
isCtrlDown
)
{
if
(
!
curComponent
||
!
curComponent
.
isLock
)
{
e
.
preventDefault
()
unlockMap
[
e
.
keyCode
]
&&
unlockMap
[
e
.
keyCode
]()
}
else
if
(
curComponent
&&
curComponent
.
isLock
)
{
e
.
preventDefault
()
lockMap
[
e
.
keyCode
]
&&
lockMap
[
e
.
keyCode
]()
}
}
window
.
onkeydown
=
(
e
)
=>
{
const
{
curComponent
}
=
store
.
state
if
(
e
.
keyCode
==
ctrlKey
)
{
isCtrlDown
=
true
}
else
if
(
e
.
keyCode
==
deleteKey
&&
curComponent
)
{
store
.
commit
(
'deleteComponent'
)
store
.
commit
(
'recordSnapshot'
)
}
else
if
(
isCtrlDown
)
{
if
(
!
curComponent
||
!
curComponent
.
isLock
)
{
e
.
preventDefault
()
unlockMap
[
e
.
keyCode
]
&&
unlockMap
[
e
.
keyCode
]()
}
else
if
(
curComponent
&&
curComponent
.
isLock
)
{
e
.
preventDefault
()
lockMap
[
e
.
keyCode
]
&&
lockMap
[
e
.
keyCode
]()
}
}
}
window
.
onkeyup
=
(
e
)
=>
{
if
(
e
.
keyCode
==
ctrlKey
)
{
isCtrlDown
=
false
}
window
.
onkeyup
=
(
e
)
=>
{
if
(
e
.
keyCode
==
ctrlKey
)
{
isCtrlDown
=
false
}
}
}
function
copy
()
{
store
.
commit
(
'copy'
)
store
.
commit
(
'copy'
)
}
function
paste
()
{
store
.
commit
(
'paste'
)
store
.
commit
(
'recordSnapshot'
)
store
.
commit
(
'paste'
)
store
.
commit
(
'recordSnapshot'
)
}
function
cut
()
{
store
.
commit
(
'cut'
)
store
.
commit
(
'cut'
)
}
function
redo
()
{
store
.
commit
(
'redo'
)
store
.
commit
(
'redo'
)
}
function
undo
()
{
store
.
commit
(
'undo'
)
store
.
commit
(
'undo'
)
}
function
compose
()
{
if
(
store
.
state
.
areaData
.
components
.
length
)
{
store
.
commit
(
'compose'
)
store
.
commit
(
'recordSnapshot'
)
}
if
(
store
.
state
.
areaData
.
components
.
length
)
{
store
.
commit
(
'compose'
)
store
.
commit
(
'recordSnapshot'
)
}
}
function
decompose
()
{
const
curComponent
=
store
.
state
.
curComponent
if
(
curComponent
&&
!
curComponent
.
isLock
&&
curComponent
.
component
==
'Group'
)
{
store
.
commit
(
'decompose'
)
store
.
commit
(
'recordSnapshot'
)
}
const
curComponent
=
store
.
state
.
curComponent
if
(
curComponent
&&
!
curComponent
.
isLock
&&
curComponent
.
component
==
'Group'
)
{
store
.
commit
(
'decompose'
)
store
.
commit
(
'recordSnapshot'
)
}
}
function
save
()
{
eventBus
.
$emit
(
'save'
)
eventBus
.
$emit
(
'save'
)
}
function
preview
()
{
eventBus
.
$emit
(
'preview'
)
eventBus
.
$emit
(
'preview'
)
}
function
deleteComponent
()
{
if
(
store
.
state
.
curComponent
)
{
store
.
commit
(
'deleteComponent'
)
store
.
commit
(
'recordSnapshot'
)
}
if
(
store
.
state
.
curComponent
)
{
store
.
commit
(
'deleteComponent'
)
store
.
commit
(
'recordSnapshot'
)
}
}
function
clearCanvas
()
{
eventBus
.
$emit
(
'clearCanvas'
)
eventBus
.
$emit
(
'clearCanvas'
)
}
function
lock
()
{
store
.
commit
(
'lock'
)
store
.
commit
(
'lock'
)
}
function
unlock
()
{
store
.
commit
(
'unlock'
)
store
.
commit
(
'unlock'
)
}
frontend/src/components/canvas/utils/toast.js
浏览文件 @
8a04a2d1
import
{
Message
}
from
'element-ui'
export
default
function
toast
(
message
=
''
,
type
=
'error'
,
duration
=
1500
)
{
Message
({
message
,
type
,
duration
,
})
}
\ No newline at end of file
Message
({
message
,
type
,
duration
})
}
frontend/src/components/canvas/utils/utils.js
浏览文件 @
8a04a2d1
export
function
deepCopy
(
target
)
{
if
(
typeof
target
==
'object'
)
{
const
result
=
Array
.
isArray
(
target
)?
[]
:
{}
for
(
const
key
in
target
)
{
if
(
typeof
target
[
key
]
==
'object'
)
{
result
[
key
]
=
deepCopy
(
target
[
key
])
}
else
{
result
[
key
]
=
target
[
key
]
}
}
return
result
if
(
typeof
target
===
'object'
)
{
const
result
=
Array
.
isArray
(
target
)
?
[]
:
{}
for
(
const
key
in
target
)
{
if
(
typeof
target
[
key
]
===
'object'
)
{
result
[
key
]
=
deepCopy
(
target
[
key
])
}
else
{
result
[
key
]
=
target
[
key
]
}
}
return
target
return
result
}
return
target
}
export
function
swap
(
arr
,
i
,
j
)
{
const
temp
=
arr
[
i
]
arr
[
i
]
=
arr
[
j
]
arr
[
j
]
=
temp
const
temp
=
arr
[
i
]
arr
[
i
]
=
arr
[
j
]
arr
[
j
]
=
temp
}
export
function
$
(
selector
)
{
return
document
.
querySelector
(
selector
)
}
\ No newline at end of file
return
document
.
querySelector
(
selector
)
}
frontend/src/lang/en.js
浏览文件 @
8a04a2d1
...
...
@@ -871,6 +871,13 @@ export default {
input_limit_2_25
:
'2-25 chars'
,
input_limit_0_50
:
'0-50 chars'
},
pblink
:
{
key_pwd
:
'Please enter the password to open the link'
,
input_placeholder
:
'Please enter the 4-digit password'
,
pwd_error
:
'Wrong password'
,
pwd_format_error
:
'Please enter the 4-digit password'
,
sure_bt
:
'Confirm'
},
panel
:
{
no_auth_role
:
'Unshared roles'
,
auth_role
:
'Shared roles'
,
...
...
frontend/src/lang/tw.js
浏览文件 @
8a04a2d1
...
...
@@ -871,6 +871,13 @@ export default {
input_limit_2_25
:
'2-25字符'
,
input_limit_0_50
:
'0-50字符'
},
pblink
:
{
key_pwd
:
'請輸入密碼打開鏈接'
,
input_placeholder
:
'請輸入4位數字密碼'
,
pwd_error
:
'密碼錯誤'
,
pwd_format_error
:
'請輸入4位數字密碼'
,
sure_bt
:
'確定'
},
panel
:
{
no_auth_role
:
'未分享角色'
,
auth_role
:
'已分享角色'
,
...
...
frontend/src/lang/zh.js
浏览文件 @
8a04a2d1
...
...
@@ -871,6 +871,13 @@ export default {
input_limit_2_25
:
'2-25字符'
,
input_limit_0_50
:
'0-50字符'
},
pblink
:
{
key_pwd
:
'请输入密码打开链接'
,
input_placeholder
:
'请输入4位数字密码'
,
pwd_error
:
'密码错误'
,
pwd_format_error
:
'请输入4位数字密码'
,
sure_bt
:
'确定'
},
panel
:
{
no_auth_role
:
'未分享角色'
,
auth_role
:
'已分享角色'
,
...
...
frontend/src/styles/deicon/demo_index.html
浏览文件 @
8a04a2d1
差异被折叠。
点击展开。
frontend/src/styles/deicon/iconfont.js
浏览文件 @
8a04a2d1
差异被折叠。
点击展开。
frontend/src/views/link/pwd/index.vue
浏览文件 @
8a04a2d1
...
...
@@ -5,14 +5,18 @@
<div
class=
"span-header"
>
<div
class=
"bi-text"
>
请输入密码打开链接
{{
$t
(
'pblink.key_pwd'
)
}}
</div>
</div>
<div
class=
"input-layout"
>
<div
class=
"input-main"
>
<div
class=
"div-input"
>
<el-input
v-model=
"pwd"
class=
"real-input"
/>
<el-form
ref=
"pwdForm"
:model=
"form"
:rules=
"rule"
size=
"small"
>
<el-form-item
prop=
"password"
>
<el-input
v-model=
"form.password"
maxlength=
"4"
show-password
class=
"real-input"
:placeholder=
"$t('pblink.input_placeholder')"
/>
</el-form-item>
</el-form>
</div>
</div>
<div
class=
"abs-input"
>
...
...
@@ -22,7 +26,7 @@
<div
class=
"auth-root-class"
>
<span
slot=
"footer"
>
<el-button
size=
"mini"
type=
"primary"
@
click=
"refresh"
>
确定
</el-button>
<el-button
size=
"mini"
type=
"primary"
@
click=
"refresh"
>
{{
$t
(
'pblink.sure_bt'
)
}}
</el-button>
</span>
</div>
</div>
...
...
@@ -45,24 +49,38 @@ export default {
},
data
()
{
return
{
pwd
:
null
,
msg
:
null
msg
:
null
,
form
:
{
password
:
null
},
rule
:
{
password
:
[
{
required
:
true
,
message
:
this
.
$t
(
'pblink.key_pwd'
),
trigger
:
'blur'
},
{
required
:
true
,
pattern
:
/^
\d{4}
$/
,
message
:
this
.
$t
(
'pblink.pwd_format_error'
),
trigger
:
'blur'
}
]
}
}
},
methods
:
{
// 验证密码是否正确 如果正确 设置请求头部带LINK-PWD-TOKEN=entrypt(pwd)再刷新页面
refresh
()
{
const
param
=
{
password
:
encrypt
(
this
.
pwd
),
resourceId
:
this
.
resourceId
}
validatePwd
(
param
).
then
(
res
=>
{
if
(
!
res
.
data
)
{
this
.
msg
=
'密码错误'
}
else
{
window
.
location
.
reload
()
this
.
$refs
.
pwdForm
.
validate
(
valid
=>
{
if
(
!
valid
)
return
false
const
param
=
{
password
:
encrypt
(
this
.
form
.
password
),
resourceId
:
this
.
resourceId
}
validatePwd
(
param
).
then
(
res
=>
{
if
(
!
res
.
data
)
{
this
.
msg
=
this
.
$t
(
'pblink.pwd_error'
)
}
else
{
window
.
location
.
reload
()
}
})
})
}
}
...
...
@@ -145,25 +163,25 @@ export default {
display
:
block
;
}
.input-layout
{
width
:
152
px
;
width
:
200
px
;
position
:
relative
;
margin
:
0px
auto
;
padding
:
0
;
display
:
block
;
}
.input-main
{
width
:
1
50
px
;
height
:
3
0
px
;
width
:
1
92
px
;
height
:
3
5
px
;
position
:
relative
;
margin-top
:
30px
;
border
:
1px
solid
#e8eaed
;
display
:
block
;
}
.div-input
{
inset
:
2px
4px
;
position
:
absolute
;
display
:
block
;
}
//
.div-input {
//
inset: 2px 4px;
//
position: absolute;
//
display: block;
//
}
.abs-input
{
height
:
20px
;
position
:
relative
;
...
...
@@ -183,18 +201,18 @@ export default {
color
:
#E65251
;
box-sizing
:
border-box
;
}
.real-input
{
width
:
100%
;
height
:
100%
;
border
:
none
;
outline
:
none
;
padding
:
0px
;
margin
:
0px
;
inset
:
0px
;
position
:
absolute
;
display
:
block
;
//
.real-input {
//
width: 100%;
//
height: 100%;
//
border: none;
//
outline: none;
//
padding: 0px;
//
margin: 0px;
//
inset: 0px;
//
position: absolute;
//
display: block;
}
//
}
.auth-root-class
{
margin
:
15px
0px
5px
;
text-align
:
center
;
...
...
frontend/src/views/panel/SubjectSetting/PreSubject/SubjectTemplateItemback.vue
浏览文件 @
8a04a2d1
...
...
@@ -80,7 +80,7 @@ export default {
background
:
'0% 0% / cover rgb(239, 241, 244)'
}
if
(
this
.
subjectItemDetails
)
{
if
(
this
.
subjectItemDetails
.
panel
.
backgroundType
===
'image'
&&
this
.
subjectItemDetails
.
panel
.
imageUrl
)
{
if
(
this
.
subjectItemDetails
.
panel
.
backgroundType
===
'image'
&&
this
.
subjectItemDetails
.
panel
.
imageUrl
)
{
style
=
{
width
:
'100%'
,
height
:
'100%'
,
...
...
frontend/src/views/panel/SubjectSetting/index.vue
浏览文件 @
8a04a2d1
...
...
@@ -20,14 +20,14 @@
<background-color-selector
v-if=
"chart"
class=
"attr-selector"
:chart=
"chart"
@
onChangeBackgroundForm=
"onChangeBackgroundForm"
/>
</el-row>
</el-collapse-item>
<el-collapse-item
:title=
"$t('
panel.table')"
name=
"table
"
>
<el-collapse-item
:title=
"$t('
chart.shape_attr')"
name=
"graphical
"
>
<el-row
style=
"background-color: #f7f8fa; margin: 5px"
>
<color-selector
index=
"10002"
:source-type=
"'panelTable'"
class=
"attr-selector"
:chart=
"tableChart"
@
onColorChange=
"onTable
ColorChange"
/>
<color-selector
:source-type=
"'panelEchart'"
class=
"attr-selector"
:chart=
"chart"
@
onColorChange=
"on
ColorChange"
/>
</el-row>
</el-collapse-item>
<el-collapse-item
:title=
"$t('
chart.shape_attr')"
name=
"graphical
"
>
<el-collapse-item
:title=
"$t('
panel.table')"
name=
"table
"
>
<el-row
style=
"background-color: #f7f8fa; margin: 5px"
>
<color-selector
:source-type=
"'panelEchart'"
class=
"attr-selector"
:chart=
"chart"
@
onColorChange=
"on
ColorChange"
/>
<color-selector
index=
"10002"
:source-type=
"'panelTable'"
class=
"attr-selector"
:chart=
"tableChart"
@
onColorChange=
"onTable
ColorChange"
/>
</el-row>
</el-collapse-item>
</el-collapse>
...
...
frontend/src/views/panel/list/PanelList.vue
浏览文件 @
8a04a2d1
...
...
@@ -178,7 +178,7 @@ import bus from '@/utils/bus'
import
EditPanel
from
'./EditPanel'
import
{
addGroup
,
delGroup
,
groupTree
,
defaultTree
,
findOne
}
from
'@/api/panel/panel'
import
{
DEFAULT_COMMON_CANVAS_STYLE_STRING
DEFAULT_COMMON_CANVAS_STYLE_STRING
}
from
'@/views/panel/panel'
export
default
{
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论