Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
Y
yqlh-dataEase
概览
Overview
Details
Activity
Cycle Analytics
版本库
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
问题
0
Issues
0
列表
Board
标记
里程碑
合并请求
0
Merge Requests
0
CI / CD
CI / CD
流水线
作业
日程表
图表
维基
Wiki
代码片段
Snippets
成员
Collapse sidebar
Close sidebar
活动
图像
聊天
创建新问题
作业
提交
Issue Boards
Open sidebar
frontend
yqlh-dataEase
Commits
a752cff5
Commit
a752cff5
authored
Jul 27, 2023
by
Tippi.Rao
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
源码更新
parent
65f48332
隐藏空白字符变更
内嵌
并排
正在显示
43 个修改的文件
包含
848 行增加
和
776 行删除
+848
-776
src/App.vue
+22
-18
src/components/asyncComponent/index.vue
+9
-4
src/components/canvas/components/editor/EditBar.vue
+4
-4
src/components/canvas/components/editor/LinkageField.vue
+4
-8
src/components/canvas/customComponent/UserView.vue
+1
-1
src/components/canvas/utils/utils.js
+4
-1
src/components/dragItem/index.vue
+15
-1
src/components/elTreeSelect/index.vue
+1
-1
src/components/elVisualSelect/index.vue
+9
-4
src/components/widget/deWidget/DeSelectGrid.vue
+2
-2
src/components/widget/deWidget/DeSelectTree.vue
+1
-1
src/lang/en.js
+2
-1
src/lang/tw.js
+2
-1
src/lang/zh.js
+3
-2
src/layout/components/Licbar.vue
+36
-29
src/layout/components/Topbar.vue
+1
-1
src/main.js
+108
-111
src/permission.js
+192
-222
src/router/index.js
+51
-55
src/utils/index.js
+200
-225
src/views/chart/components/ChartComponent.vue
+4
-2
src/views/chart/components/componentStyle/dialog/RemarkEditor.vue
+16
-0
src/views/chart/components/dragItem/QuotaExtItem.vue
+1
-1
src/views/chart/components/filter/QuotaFilterEditor.vue
+7
-0
src/views/chart/components/filter/ResultFilterEditor.vue
+14
-0
src/views/chart/view/ChartEdit.vue
+6
-3
src/views/chart/view/PositionAdjust.vue
+1
-1
src/views/chart/view/TitleRemark.vue
+1
-1
src/views/dataset/common/DatasetChartDetail.vue
+2
-2
src/views/dataset/data/components/LazyTree.vue
+1
-1
src/views/dataset/group/GroupMoveSelector.vue
+1
-1
src/views/login/index.vue
+22
-1
src/views/panel/export/PDFPreExport.vue
+1
-1
src/views/panel/filter/FilterDialog.vue
+18
-0
src/views/panel/filter/filterMain/FilterHead.vue
+7
-1
src/views/panel/list/PanelList.vue
+5
-2
src/views/panel/list/PanelViewShow.vue
+8
-0
src/views/system/user/index.vue
+1
-1
src/views/wizard/WizardCard.vue
+1
-1
src/views/wizard/WizardCardEnterprise.vue
+1
-1
src/views/wizard/details/CardDetail.vue
+1
-1
src/views/wizard/details/LatestDevelopments.vue
+1
-1
vue.config.js
+61
-62
没有找到文件。
src/App.vue
查看文件 @
a752cff5
<
template
>
<div
id=
"app"
>
<router-view
/>
<plugin-com
v-show=
"false"
ref=
"de-theme"
component-name=
"ThemeSetting"
/>
<plugin-com
v-show=
"false"
ref=
"de-theme"
component-name=
"ThemeSetting"
/>
<el-dialog
v-if=
"$route.path !== '/login'"
:visible
.
sync=
"showPasswordModifiedDialog"
...
...
@@ -15,36 +19,36 @@
</
template
>
<
script
>
import
PluginCom
from
"@/views/system/plugin/PluginCom"
;
import
{
mapState
}
from
"vuex"
;
import
PasswordUpdateForm
from
"@/views/system/user/PasswordUpdateForm.vue"
;
import
PluginCom
from
'@/views/system/plugin/PluginCom'
import
{
mapState
}
from
'vuex'
import
PasswordUpdateForm
from
'@/views/system/user/PasswordUpdateForm.vue'
export
default
{
name
:
"App"
,
name
:
'App'
,
components
:
{
PluginCom
,
PasswordUpdateForm
},
computed
:
{
...
mapState
(
"user"
,
[
"passwordModified"
]),
...
mapState
(
'user'
,
[
'passwordModified'
,
])
},
data
()
{
return
{
showPasswordModifiedDialog
:
false
,
}
;
showPasswordModifiedDialog
:
false
}
},
mounted
()
{
const
passwordModified
=
JSON
.
parse
(
localStorage
.
getItem
(
"passwordModified"
)
);
if
(
typeof
passwordModified
===
"boolean"
)
{
this
.
$store
.
commit
(
"user/SET_PASSWORD_MODIFIED"
,
passwordModified
);
const
passwordModified
=
JSON
.
parse
(
localStorage
.
getItem
(
'passwordModified'
))
if
(
typeof
passwordModified
===
'boolean'
)
{
this
.
$store
.
commit
(
'user/SET_PASSWORD_MODIFIED'
,
passwordModified
)
}
},
watch
:
{
passwordModified
:
{
handler
(
val
)
{
this
.
showPasswordModifiedDialog
=
!
val
;
this
.
showPasswordModifiedDialog
=
!
val
},
immediate
:
true
,
}
,
}
,
}
;
immediate
:
true
}
}
}
</
script
>
src/components/asyncComponent/index.vue
查看文件 @
a752cff5
...
...
@@ -3,6 +3,8 @@
:is=
"mode"
:ref=
"refId"
:obj=
"obj"
:bus=
"bus"
:axios-request=
"request"
v-bind=
"$attrs"
v-on=
"$listeners"
/>
...
...
@@ -11,6 +13,9 @@
<
script
>
import
{
uuid
}
from
'vue-uuid'
import
{
get
}
from
'@/api/system/dynamic'
import
bus
from
'@/utils/bus'
import
request
from
'@/utils/request'
export
default
{
name
:
'AsyncComponent'
,
inheritAttrs
:
true
,
...
...
@@ -29,7 +34,9 @@ export default {
return
{
resData
:
''
,
mode
:
''
,
refId
:
null
refId
:
null
,
bus
:
bus
,
request
:
request
}
},
watch
:
{
...
...
@@ -47,15 +54,13 @@ export default {
// window.SyncComponentCache[this.url] = Axios.get(this.url)
res
=
await
window
.
SyncComponentCache
[
this
.
url
]
}
else
{
this
.
mode
=
await
window
.
SyncComponentCache
[
this
.
url
]
return
res
=
await
window
.
SyncComponentCache
[
this
.
url
]
}
if
(
res
)
{
const
Fn
=
Function
const
dynamicCode
=
res
.
data
||
res
const
component
=
new
Fn
(
`return
${
dynamicCode
}
`
)()
this
.
mode
=
component
.
default
||
component
window
.
SyncComponentCache
[
this
.
url
]
=
this
.
mode
}
}
}
...
...
src/components/canvas/components/editor/EditBar.vue
查看文件 @
a752cff5
...
...
@@ -82,10 +82,10 @@
/>
</span>
<span
:title=
"$t('route.exportExcel')"
>
<
svg-icon
<
i
v-if=
"exportExcelShow"
style=
"
color: white
"
icon-class=
"file-excel
"
style=
"
line-height: 24px
"
class=
"el-icon-document-delete
"
@
click
.
stop=
"exportExcelDownload()"
/>
</span>
...
...
@@ -469,7 +469,7 @@ export default {
this
.
$emit
(
'showViewDetails'
,
{
openType
:
openType
})
},
exportExcelDownload
()
{
exportExcelDownload
(
this
.
chart
,
null
,
null
,
null
,
null
,
null
)
exportExcelDownload
(
this
.
chart
)
},
auxiliaryMatrixChange
()
{
if
(
this
.
curComponent
.
auxiliaryMatrix
)
{
...
...
src/components/canvas/components/editor/LinkageField.vue
查看文件 @
a752cff5
...
...
@@ -171,23 +171,19 @@ export default {
return
this
.
targetLinkageInfo
[
this
.
curLinkageView
.
propValue
.
viewId
]
},
...
mapState
([
'menuTop'
,
'menuLeft'
,
'menuShow'
,
'curComponent'
,
'componentData'
,
'canvasStyleData'
,
'linkageSettingStatus'
,
'targetLinkageInfo'
,
'curLinkageView'
])
},
mounted
()
{
const
_this
=
this
// 初始化映射关系 如果当前是相同的数据集且没有关联关系,则自动补充映射关系
checkSameDataSet
(
this
.
curLinkageView
.
propValue
.
viewId
,
this
.
element
.
propValue
.
viewId
).
then
(
res
=>
{
if
(
res
.
data
===
'YES'
&&
this
.
linkageInfo
.
linkageFields
.
length
===
0
)
{
this
.
sourceLinkageInfo
.
targetViewFields
.
forEach
(
item
=>
{
this
.
addLinkageField
(
item
.
id
,
item
.
id
)
_this
.
$nextTick
(()
=>
{
this
.
addLinkageField
(
item
.
id
,
item
.
id
)
})
})
}
})
...
...
src/components/canvas/customComponent/UserView.vue
查看文件 @
a752cff5
...
...
@@ -360,7 +360,7 @@ export default {
computed
:
{
// 首次加载且非编辑状态新复制的视图,使用外部filter
initLoad
()
{
return
!
(
this
.
isEdit
&&
this
.
currentCanvasNewId
.
includes
(
this
.
element
.
id
))
&&
this
.
isFirstLoad
return
!
(
this
.
isEdit
&&
this
.
currentCanvasNewId
.
includes
(
this
.
element
.
id
))
&&
this
.
isFirstLoad
&&
this
.
canvasId
===
'canvas-main'
},
scaleCoefficient
()
{
if
(
this
.
terminal
===
'pc'
&&
!
this
.
mobileLayoutStatus
)
{
...
...
src/components/canvas/utils/utils.js
查看文件 @
a752cff5
...
...
@@ -429,7 +429,10 @@ export function getCacheTree(treeName) {
}
export
function
exportExcelDownload
(
chart
,
snapshot
,
width
,
height
,
loadingWrapper
,
callBack
)
{
if
(
!
chart
.
data
?.
data
?.
length
)
{
if
(
chart
.
render
===
'antv'
&&
!
chart
.
data
?.
data
?.
length
)
{
return
}
if
(
chart
.
type
===
'echarts'
&&
!
(
chart
.
data
?.
series
?.
length
&&
chart
.
data
?.
series
[
0
].
data
?.
length
))
{
return
}
const
fields
=
JSON
.
parse
(
JSON
.
stringify
(
chart
.
data
.
fields
))
...
...
src/components/dragItem/index.vue
查看文件 @
a752cff5
...
...
@@ -6,7 +6,16 @@
class=
"item-axis"
@
close=
"removeItem"
>
{{
item
.
name
}}
<el-tooltip
v-if=
"toolTip"
class=
"item"
effect=
"dark"
:content=
"toolTip || item.name"
placement=
"top"
>
<span>
{{
item
.
name
}}
</span>
</el-tooltip>
<span
v-else
>
{{
item
.
name
}}
</span>
</el-tag>
</span>
</
template
>
...
...
@@ -22,6 +31,11 @@ export default {
index
:
{
type
:
Number
,
required
:
true
},
toolTip
:
{
type
:
String
,
required
:
false
,
default
:
''
}
},
...
...
src/components/elTreeSelect/index.vue
查看文件 @
a752cff5
...
...
@@ -410,7 +410,7 @@ export default {
},
_filterFun
(
value
,
data
,
node
)
{
if
(
!
value
)
return
true
return
data
[
this
.
propsLabel
].
indexOf
(
value
)
!==
-
1
return
data
[
this
.
propsLabel
?.
toLocaleUpperCase
()].
indexOf
(
value
.
toLocaleUpperCase
()
)
!==
-
1
},
_treeNodeClickFun
(
data
,
node
,
vm
)
{
const
{
multiple
}
=
this
.
selectParams
...
...
src/components/elVisualSelect/index.vue
查看文件 @
a752cff5
...
...
@@ -121,7 +121,7 @@ export default {
},
keyWord
(
val
,
old
)
{
if
(
val
===
old
)
return
const
results
=
val
?
this
.
list
.
filter
(
item
=>
item
.
text
.
includes
(
val
)
)
:
null
const
results
=
val
?
this
.
vagueFilter
(
val
,
this
.
list
)
:
null
this
.
resetList
(
results
)
this
.
reCacularHeight
()
this
.
$nextTick
(()
=>
{
...
...
@@ -136,6 +136,11 @@ export default {
})
},
methods
:
{
vagueFilter
(
val
,
nodes
)
{
if
(
!
val
||
!
val
.
trim
())
return
nodes
const
results
=
nodes
.
filter
(
item
=>
item
.
text
?.
toLocaleUpperCase
().
includes
(
val
.
toLocaleUpperCase
()))
return
results
},
resetSelectAll
()
{
this
.
selectAll
=
false
},
...
...
@@ -148,7 +153,7 @@ export default {
selectAllChange
(
val
)
{
let
vals
=
val
?
[...
this
.
list
.
map
(
ele
=>
ele
.
id
)]
:
[]
if
(
this
.
keyWord
.
trim
()
&&
val
)
{
vals
=
this
.
list
.
filter
(
item
=>
item
.
text
.
includes
(
this
.
keyWord
.
trim
())
).
map
(
ele
=>
ele
.
id
)
vals
=
this
.
vagueFilter
(
this
.
keyWord
.
trim
(),
this
.
list
).
map
(
ele
=>
ele
.
id
)
}
this
.
visualChange
(
vals
)
this
.
selectValue
=
vals
...
...
@@ -233,14 +238,14 @@ export default {
isAllSelect
()
{
let
vals
=
this
.
list
.
length
if
(
this
.
keyWord
.
trim
())
{
vals
=
this
.
list
.
filter
(
item
=>
item
.
text
.
includes
(
this
.
keyWord
.
trim
())
).
map
(
ele
=>
ele
.
id
).
filter
(
ele
=>
this
.
selectValue
.
includes
(
ele
)).
length
vals
=
this
.
vagueFilter
(
this
.
keyWord
.
trim
(),
this
.
list
).
map
(
ele
=>
ele
.
id
).
filter
(
ele
=>
this
.
selectValue
.
includes
(
ele
)).
length
}
return
vals
},
halfSelect
()
{
let
vals
=
this
.
list
.
length
if
(
this
.
keyWord
.
trim
())
{
vals
=
this
.
list
.
filter
(
item
=>
item
.
text
.
includes
(
this
.
keyWord
.
trim
())
).
map
(
ele
=>
ele
.
id
).
length
vals
=
this
.
vagueFilter
(
this
.
keyWord
.
trim
(),
this
.
list
).
map
(
ele
=>
ele
.
id
).
length
}
return
vals
},
...
...
src/components/widget/deWidget/DeSelectGrid.vue
查看文件 @
a752cff5
...
...
@@ -31,7 +31,7 @@
v-model=
"value"
@
change=
"handleCheckedChange"
>
<template
v-for=
"item in data.filter(node => !keyWord || (node.id && node.id.
includes(keyWord
)))"
>
<template
v-for=
"item in data.filter(node => !keyWord || (node.id && node.id.
toLocaleUpperCase().includes(keyWord.toLocaleUpperCase()
)))"
>
<el-checkbox
:key=
"item.id"
:label=
"item.id"
...
...
@@ -51,7 +51,7 @@
@
change=
"changeRadioBox"
>
<el-radio
v-for=
"(item, index) in data.filter(node => !keyWord || (node.id && node.id.
includes(keyWord
)))"
v-for=
"(item, index) in data.filter(node => !keyWord || (node.id && node.id.
toLocaleUpperCase().includes(keyWord.toLocaleUpperCase()
)))"
:key=
"index"
:label=
"item.id"
@
click
.
native
.
prevent=
"testChange(item)"
...
...
src/components/widget/deWidget/DeSelectTree.vue
查看文件 @
a752cff5
...
...
@@ -381,7 +381,7 @@ export default {
_filterFun
(
value
,
data
,
node
)
{
if
(
!
value
)
return
true
return
data
.
id
.
toString
().
indexOf
(
value
.
toString
())
!==
-
1
return
data
.
id
.
toString
().
toLocaleUpperCase
().
indexOf
(
value
.
toString
().
toLocaleUpperCase
())
!==
-
1
},
// 树点击
_nodeClickFun
(
data
,
node
,
vm
)
{
...
...
src/lang/en.js
查看文件 @
a752cff5
...
...
@@ -626,7 +626,8 @@ export default {
status
:
'Authorization status'
,
valid
:
'Valid'
,
invalid
:
'Invalid'
,
expired
:
'Expired'
expired
:
'Expired'
,
expired_msg
:
'license has expired since {0}. It is recommended to update the license, which does not affect the use of enterprise version functions'
},
member
:
{
create
:
'Add members'
,
...
...
src/lang/tw.js
查看文件 @
a752cff5
...
...
@@ -626,7 +626,8 @@ export default {
status
:
'授權狀態'
,
valid
:
'有效'
,
invalid
:
'無效'
,
expired
:
'已過期'
expired
:
'已過期'
,
expired_msg
:
'License已過期,過期時間:{0},為了不影響企業版功能的使用,建議您更新License'
},
member
:
{
create
:
'添加成員'
,
...
...
src/lang/zh.js
查看文件 @
a752cff5
...
...
@@ -625,7 +625,8 @@ export default {
status
:
'授权状态'
,
valid
:
'有效'
,
invalid
:
'无效'
,
expired
:
'已过期'
expired
:
'已过期'
,
expired_msg
:
'License已过期,过期时间:{0},为了不影响企业版功能的使用,建议您更新License'
},
member
:
{
create
:
'添加成员'
,
...
...
@@ -1938,7 +1939,7 @@ export default {
jsonpath_info
:
'请填入JsonPath'
,
req_param
:
'请求参数'
,
headers
:
'请求头'
,
query_param
:
"QUERY
參數
"
,
query_param
:
"QUERY
参数
"
,
query_info
:
"地址栏中跟在?后面的参数,如: updateapi?id=112"
,
key
:
'键'
,
value
:
'值'
,
...
...
src/layout/components/Licbar.vue
查看文件 @
a752cff5
<
template
>
<div
v-if=
"!licValidate && licStatus !== 'no_record'"
class=
"lic"
v-if=
"!licValidate && licStatus !== 'no_record'
&& !tipClosed
"
class=
"lic
_tips
"
>
<strong>
{{
$t
(
licMsg
)
}}
</strong>
<el-alert
class=
"lic_alert"
:title=
"$t(licMsg)"
type=
"warning"
show-icon
center
@
close=
"closeTip"
/>
</div>
</
template
>
...
...
@@ -20,9 +29,7 @@ export default {
}
},
computed
:
{
/* theme() {
return this.$store.state.settings.theme
}, */
licValidate
()
{
return
this
.
$store
.
state
.
lic
.
validate
},
...
...
@@ -30,40 +37,40 @@ export default {
return
this
.
$store
.
state
.
lic
.
licStatus
||
''
},
licMsg
()
{
if
(
this
.
$store
.
state
.
lic
?.
licMsg
?.
includes
(
'expired'
))
{
const
message
=
this
.
$store
.
state
.
lic
.
licMsg
const
exp
=
message
.
substring
(
message
.
indexOf
(
'since '
)
+
6
,
message
.
indexOf
(
','
))
return
this
.
$t
(
'license.expired_msg'
).
replace
(
'{0}'
,
exp
)
}
return
this
.
$store
.
state
.
lic
.
licMsg
?
(
'license.'
+
this
.
$store
.
state
.
lic
.
licMsg
)
:
null
},
tipClosed
()
{
return
localStorage
.
getItem
(
'lic_closed'
)
}
},
mounted
()
{
// this.validate()
},
methods
:
{
// validate() {
// validateLic().then(res => {
// this.lic = true
// this.$store.dispatch('lic/setValidate', true)
// }).catch((e) => {
// this.msg = e.response.data.message
// this.lic = false
// this.$store.dispatch('lic/setValidate', false)
// })
// }
closeTip
()
{
localStorage
.
setItem
(
'lic_closed'
,
true
)
}
}
}
</
script
>
<
style
lang=
"scss"
scoped
>
.lic
{
height
:
24px
;
background-color
:
#c92100
;
color
:
#fff
;
text-align
:
center
;
/* padding: 6px 11px; */
position
:
fixed
;
z-index
:
1002
;
top
:
0
;
width
:
100%
;
}
.lic_tips
{
position
:
absolute
;
z-index
:
2000
;
position
:
absolute
;
top
:
0
;
left
:
0
;
right
:
0
;
margin
:
auto
;
}
.lic_alert
::v-deep
.el-icon-close
{
top
:
16px
!important
;
right
:
10px
!important
;
}
</
style
>
src/layout/components/Topbar.vue
查看文件 @
a752cff5
...
...
@@ -281,7 +281,7 @@ export default {
unloadHandler
(
e
)
{
this
.
gap_time
=
new
Date
().
getTime
()
-
this
.
beforeUnload_time
if
(
this
.
gap_time
<=
5
)
{
this
.
logout
().
then
(
res
=>
{})
//
this.logout().then(res => {})
}
},
...
...
src/main.js
查看文件 @
a752cff5
import
Vue
from
"vue"
;
import
Cookies
from
"js-cookie"
;
import
"@/styles/index.scss"
;
// global css
import
ElementUI
from
"element-ui"
;
import
Vuetify
from
"vuetify"
;
import
Fit2CloudUI
from
"fit2cloud-ui"
;
import
i18n
from
"./lang"
;
// internationalization
import
App
from
"./App"
;
import
store
from
"./store"
;
import
router
from
"./router"
;
import
message
from
"./utils/message"
;
import
"@/icons"
;
// icon
import
"@/permission"
;
// permission control
import
api
from
"@/api/index.js"
;
import
filter
from
"@/filter/filter"
;
import
directives
from
"./directive"
;
import
VueClipboard
from
"vue-clipboard2"
;
import
widgets
from
"@/components/widget"
;
import
Treeselect
from
"@riophae/vue-treeselect"
;
import
"@riophae/vue-treeselect/dist/vue-treeselect.css"
;
import
"./utils/dialog"
;
import
DeComplexInput
from
"@/components/business/conditionTable/DeComplexInput"
;
import
DeComplexSelect
from
"@/components/business/conditionTable/DeComplexSelect"
;
import
DeViewSelect
from
"@/components/deViewSelect"
;
import
RemarkEditor
from
"@/views/chart/components/componentStyle/dialog/RemarkEditor"
;
import
TitleRemark
from
"@/views/chart/view/TitleRemark"
;
import
"@/components/canvas/customComponent"
;
// 注册自定义组件
import
deBtn
from
"@/components/deCustomCm/DeBtn.vue"
;
import
"@/utils/DateUtil"
;
import
draggable
from
"vuedraggable"
;
import
deWebsocket
from
"@/websocket"
;
import
{
GaodeMap
}
from
"@antv/l7-maps"
;
import
*
as
echarts
from
"echarts"
;
import
UmyUi
from
"umy-ui"
;
import
Vue
from
'vue'
import
Cookies
from
'js-cookie'
import
'@/styles/index.scss'
// global css
import
ElementUI
from
'element-ui'
import
Vuetify
from
'vuetify'
import
Fit2CloudUI
from
'fit2cloud-ui'
import
i18n
from
'./lang'
// internationalization
import
App
from
'./App'
import
store
from
'./store'
import
router
from
'./router'
import
message
from
'./utils/message'
import
'@/icons'
// icon
import
'@/permission'
// permission control
import
api
from
'@/api/index.js'
import
filter
from
'@/filter/filter'
import
directives
from
'./directive'
import
VueClipboard
from
'vue-clipboard2'
import
widgets
from
'@/components/widget'
import
Treeselect
from
'@riophae/vue-treeselect'
import
'@riophae/vue-treeselect/dist/vue-treeselect.css'
import
'./utils/dialog'
import
DeComplexInput
from
'@/components/business/conditionTable/DeComplexInput'
import
DeComplexSelect
from
'@/components/business/conditionTable/DeComplexSelect'
import
DeViewSelect
from
'@/components/deViewSelect'
import
RemarkEditor
from
'@/views/chart/components/componentStyle/dialog/RemarkEditor'
import
TitleRemark
from
'@/views/chart/view/TitleRemark'
import
'@/components/canvas/customComponent'
// 注册自定义组件
import
deBtn
from
'@/components/deCustomCm/DeBtn.vue'
import
'@/utils/DateUtil'
import
draggable
from
'vuedraggable'
import
deWebsocket
from
'@/websocket'
import
{
GaodeMap
}
from
'@antv/l7-maps'
import
*
as
echarts
from
'echarts'
import
UmyUi
from
'umy-ui'
// 全屏插件
import
fullscreen
from
"vue-fullscreen"
;
import
VueFriendlyIframe
from
"vue-friendly-iframe"
;
import
vueToPdf
from
"vue-to-pdf"
;
import
VueVideoPlayer
from
"vue-video-player"
;
import
"video.js/dist/video-js.css"
;
import
fullscreen
from
'vue-fullscreen'
import
VueFriendlyIframe
from
'vue-friendly-iframe'
import
vueToPdf
from
'vue-to-pdf'
import
VueVideoPlayer
from
'vue-video-player'
import
'video.js/dist/video-js.css'
// 控制标签宽高成比例的指令
import
proportion
from
"vue-proportion-directive"
;
import
proportion
from
'vue-proportion-directive'
import
xss
from
"xss"
;
import
xss
from
'xss'
// 定义全局XSS解决方法
Object
.
defineProperty
(
Vue
.
prototype
,
"$xss"
,
{
value
:
xss
,
})
;
Object
.
defineProperty
(
Vue
.
prototype
,
'$xss'
,
{
value
:
xss
})
Vue
.
config
.
productionTip
=
false
;
Vue
.
use
(
VueClipboard
)
;
Vue
.
use
(
widgets
)
;
Vue
.
component
(
"Draggable"
,
draggable
);
Vue
.
prototype
.
$api
=
api
;
Vue
.
config
.
productionTip
=
false
Vue
.
use
(
VueClipboard
)
Vue
.
use
(
widgets
)
Vue
.
component
(
'Draggable'
,
draggable
)
Vue
.
prototype
.
$api
=
api
Vue
.
prototype
.
$echarts
=
echarts
;
Vue
.
prototype
.
$gaodeMap
=
GaodeMap
;
Vue
.
prototype
.
$echarts
=
echarts
Vue
.
prototype
.
$gaodeMap
=
GaodeMap
Vue
.
use
(
UmyUi
)
;
Vue
.
use
(
UmyUi
)
Vue
.
use
(
fullscreen
)
;
Vue
.
use
(
fullscreen
)
Vue
.
use
(
VueFriendlyIframe
)
;
Vue
.
use
(
Vuetify
)
;
Vue
.
use
(
VueFriendlyIframe
)
Vue
.
use
(
Vuetify
)
// import TEditor from '@/components/Tinymce/index.vue'
// Vue.component('TEditor', TEditor)
...
...
@@ -75,83 +75,80 @@ Vue.use(Vuetify);
* Currently MockJs will be used in the production environment,
* please remove it before going online ! ! !
*/
if
(
process
.
env
.
NODE_ENV
===
"production"
)
{
// const { mockXHR } = require('../mock')
// mockXHR()
if
(
process
.
env
.
NODE_ENV
===
'production'
)
{
// const { mockXHR } = require('../mock')
// mockXHR()
}
// set ElementUI lang to EN
// Vue.use(ElementUI, { locale })
// 如果想要中文版 element-ui,按如下方式声明
ElementUI
.
Dialog
.
props
.
closeOnClickModal
.
default
=
false
;
ElementUI
.
Dialog
.
props
.
closeOnPressEscape
.
default
=
false
;
ElementUI
.
Dialog
.
props
.
closeOnClickModal
.
default
=
false
ElementUI
.
Dialog
.
props
.
closeOnPressEscape
.
default
=
false
Vue
.
use
(
ElementUI
,
{
size
:
Cookies
.
get
(
"size"
)
||
"medium"
,
// set element-ui default size
i18n
:
(
key
,
value
)
=>
i18n
.
t
(
key
,
value
)
,
})
;
size
:
Cookies
.
get
(
'size'
)
||
'medium'
,
// set element-ui default size
i18n
:
(
key
,
value
)
=>
i18n
.
t
(
key
,
value
)
})
Vue
.
use
(
Fit2CloudUI
,
{
i18n
:
(
key
,
value
)
=>
i18n
.
t
(
key
,
value
)
,
})
;
i18n
:
(
key
,
value
)
=>
i18n
.
t
(
key
,
value
)
})
// Vue.use(VueAxios, axios)
Vue
.
use
(
filter
)
;
Vue
.
use
(
directives
)
;
Vue
.
use
(
message
)
;
Vue
.
component
(
"Treeselect"
,
Treeselect
);
Vue
.
component
(
"DeComplexInput"
,
DeComplexInput
);
Vue
.
component
(
"DeComplexSelect"
,
DeComplexSelect
);
Vue
.
component
(
"DeViewSelect"
,
DeViewSelect
);
Vue
.
component
(
"RemarkEditor"
,
RemarkEditor
);
Vue
.
component
(
"TitleRemark"
,
TitleRemark
);
Vue
.
component
(
"DeBtn"
,
deBtn
);
Vue
.
use
(
filter
)
Vue
.
use
(
directives
)
Vue
.
use
(
message
)
Vue
.
component
(
'Treeselect'
,
Treeselect
)
Vue
.
component
(
'DeComplexInput'
,
DeComplexInput
)
Vue
.
component
(
'DeComplexSelect'
,
DeComplexSelect
)
Vue
.
component
(
'DeViewSelect'
,
DeViewSelect
)
Vue
.
component
(
'RemarkEditor'
,
RemarkEditor
)
Vue
.
component
(
'TitleRemark'
,
TitleRemark
)
Vue
.
component
(
'DeBtn'
,
deBtn
)
Vue
.
config
.
productionTip
=
false
;
Vue
.
config
.
productionTip
=
false
Vue
.
use
(
vueToPdf
)
;
Vue
.
use
(
vueToPdf
)
Vue
.
use
(
VueVideoPlayer
)
;
Vue
.
use
(
VueVideoPlayer
)
Vue
.
use
(
proportion
)
;
Vue
.
use
(
proportion
)
Vue
.
prototype
.
hasDataPermission
=
function
(
pTarget
,
pSource
)
{
if
(
this
.
$store
.
state
.
user
.
user
.
isAdmin
||
pSource
===
"ignore"
)
{
return
true
;
Vue
.
prototype
.
hasDataPermission
=
function
(
pTarget
,
pSource
)
{
if
(
this
.
$store
.
state
.
user
.
user
.
isAdmin
||
pSource
===
'ignore'
)
{
return
true
}
if
(
pSource
&&
pTarget
)
{
return
pSource
.
indexOf
(
pTarget
)
>
-
1
;
return
pSource
.
indexOf
(
pTarget
)
>
-
1
}
return
false
;
}
;
Vue
.
prototype
.
checkPermission
=
function
(
pers
)
{
const
permissions
=
store
.
getters
.
permissions
;
const
hasPermission
=
pers
.
every
(
(
needP
)
=>
{
const
result
=
permissions
.
includes
(
needP
)
;
return
result
;
})
;
return
hasPermission
;
}
;
Vue
.
use
(
deWebsocket
)
;
Vue
.
prototype
.
$currentHttpRequestList
=
new
Map
()
;
Vue
.
prototype
.
$cancelRequest
=
function
(
cancelkey
)
{
return
false
}
Vue
.
prototype
.
checkPermission
=
function
(
pers
)
{
const
permissions
=
store
.
getters
.
permissions
const
hasPermission
=
pers
.
every
(
needP
=>
{
const
result
=
permissions
.
includes
(
needP
)
return
result
})
return
hasPermission
}
Vue
.
use
(
deWebsocket
)
Vue
.
prototype
.
$currentHttpRequestList
=
new
Map
()
Vue
.
prototype
.
$cancelRequest
=
function
(
cancelkey
)
{
if
(
cancelkey
)
{
if
(
cancelkey
.
indexOf
(
"/**"
)
>
-
1
)
{
if
(
cancelkey
.
indexOf
(
'/**'
)
>
-
1
)
{
Vue
.
prototype
.
$currentHttpRequestList
.
forEach
((
item
,
key
)
=>
{
key
.
indexOf
(
cancelkey
.
split
(
"/**"
)[
0
])
>
-
1
&&
item
(
"Operation canceled by the user."
);
});
key
.
indexOf
(
cancelkey
.
split
(
'/**'
)[
0
])
>
-
1
&&
item
(
'Operation canceled by the user.'
)
})
}
else
{
Vue
.
prototype
.
$currentHttpRequestList
.
get
(
cancelkey
)
&&
Vue
.
prototype
.
$currentHttpRequestList
.
get
(
cancelkey
)(
"Operation canceled by the user."
);
Vue
.
prototype
.
$currentHttpRequestList
.
get
(
cancelkey
)
&&
Vue
.
prototype
.
$currentHttpRequestList
.
get
(
cancelkey
)(
'Operation canceled by the user.'
)
}
}
}
;
}
new
Vue
({
router
,
store
,
i18n
,
render
:
(
h
)
=>
h
(
App
),
}).
$mount
(
"#app"
);
render
:
h
=>
h
(
App
)
}).
$mount
(
'#app'
)
src/permission.js
查看文件 @
a752cff5
import
router
from
"@/router"
;
import
store
from
"./store"
;
import
router
from
'@/router'
import
store
from
'./store'
// import { Message } from 'element-ui'
import
NProgress
from
"nprogress"
;
// progress bar
import
"nprogress/nprogress.css"
;
// progress bar style
import
{
getToken
}
from
"@/utils/auth"
;
// get token from cookie
import
getPageTitle
from
"@/utils/get-page-title"
;
import
{
buildMenus
}
from
"@/api/system/menu"
;
import
{
filterAsyncRouter
}
from
"@/store/modules/permission"
;
import
{
isMobile
,
changeFavicon
}
from
"@/utils/index"
;
import
Layout
from
"@/layout/index"
;
import
{
getSysUI
}
from
"@/utils/auth"
;
import
NProgress
from
'nprogress'
// progress bar
import
'nprogress/nprogress.css'
// progress bar style
import
{
getToken
}
from
'@/utils/auth'
// get token from cookie
import
getPageTitle
from
'@/utils/get-page-title'
import
{
buildMenus
}
from
'@/api/system/menu'
import
{
filterAsyncRouter
}
from
'@/store/modules/permission'
import
{
isMobile
,
changeFavicon
}
from
'@/utils/index'
import
Layout
from
'@/layout/index'
import
{
getSysUI
}
from
'@/utils/auth'
import
{
getSocket
}
from
"@/websocket"
;
import
{
getSocket
}
from
'@/websocket'
NProgress
.
configure
({
showSpinner
:
false
,
})
;
// NProgress Configuration
showSpinner
:
false
})
// NProgress Configuration
const
whiteList
=
[
"/login"
,
"/401"
,
"/404"
,
"/delink"
,
"/nolic"
,
"/de-auto-login"
,
];
// no redirect whitelist
const
whiteList
=
[
'/login'
,
'/401'
,
'/404'
,
'/delink'
,
'/nolic'
,
'/de-auto-login'
]
// no redirect whitelist
const
routeBefore
=
(
callBack
)
=>
{
let
uiInfo
=
getSysUI
()
;
let
uiInfo
=
getSysUI
()
if
(
!
uiInfo
||
Object
.
keys
(
uiInfo
).
length
===
0
)
{
store
.
dispatch
(
"user/getUI"
)
.
then
(()
=>
{
document
.
title
=
getPageTitle
();
uiInfo
=
getSysUI
();
if
(
uiInfo
[
"ui.favicon"
]
&&
uiInfo
[
"ui.favicon"
].
paramValue
)
{
const
faviconUrl
=
"/system/ui/image/"
+
uiInfo
[
"ui.favicon"
].
paramValue
;
changeFavicon
(
faviconUrl
);
}
callBack
();
})
.
catch
((
err
)
=>
{
document
.
title
=
getPageTitle
();
console
.
error
(
err
);
callBack
();
});
store
.
dispatch
(
'user/getUI'
).
then
(()
=>
{
document
.
title
=
getPageTitle
()
uiInfo
=
getSysUI
()
if
(
uiInfo
[
'ui.favicon'
]
&&
uiInfo
[
'ui.favicon'
].
paramValue
)
{
const
faviconUrl
=
'/system/ui/image/'
+
uiInfo
[
'ui.favicon'
].
paramValue
changeFavicon
(
faviconUrl
)
}
callBack
()
}).
catch
(
err
=>
{
document
.
title
=
getPageTitle
()
console
.
error
(
err
)
callBack
()
})
}
else
{
document
.
title
=
getPageTitle
()
;
if
(
!!
uiInfo
&&
uiInfo
[
"ui.favicon"
]
&&
uiInfo
[
"ui.favicon"
].
paramValue
)
{
const
faviconUrl
=
"/system/ui/image/"
+
uiInfo
[
"ui.favicon"
].
paramValue
;
changeFavicon
(
faviconUrl
)
;
document
.
title
=
getPageTitle
()
if
(
!!
uiInfo
&&
uiInfo
[
'ui.favicon'
]
&&
uiInfo
[
'ui.favicon'
].
paramValue
)
{
const
faviconUrl
=
'/system/ui/image/'
+
uiInfo
[
'ui.favicon'
].
paramValue
changeFavicon
(
faviconUrl
)
}
callBack
()
;
callBack
()
}
};
router
.
beforeEach
(
async
(
to
,
from
,
next
)
=>
routeBefore
(()
=>
{
// start progress bar
NProgress
.
start
();
const
mobileIgnores
=
[
"/delink"
,
"/de-auto-login"
];
const
mobilePreview
=
"/preview/"
;
const
hasToken
=
getToken
();
}
router
.
beforeEach
(
async
(
to
,
from
,
next
)
=>
routeBefore
(()
=>
{
// start progress bar
NProgress
.
start
()
const
mobileIgnores
=
[
'/delink'
,
'/de-auto-login'
]
const
mobilePreview
=
'/preview/'
const
hasToken
=
getToken
()
if
(
isMobile
()
&&
!
to
.
path
.
includes
(
mobilePreview
)
&&
mobileIgnores
.
indexOf
(
to
.
path
)
===
-
1
)
{
let
urlSuffix
=
"/app.html"
;
if
(
hasToken
)
{
urlSuffix
+=
"?detoken="
+
hasToken
;
}
localStorage
.
removeItem
(
"user-info"
);
localStorage
.
removeItem
(
"userId"
);
localStorage
.
removeItem
(
"Authorization"
);
window
.
location
.
href
=
window
.
origin
+
urlSuffix
;
NProgress
.
done
();
if
(
isMobile
()
&&
!
to
.
path
.
includes
(
mobilePreview
)
&&
mobileIgnores
.
indexOf
(
to
.
path
)
===
-
1
)
{
let
urlSuffix
=
'/app.html'
if
(
hasToken
)
{
urlSuffix
+=
(
'?detoken='
+
hasToken
)
}
localStorage
.
removeItem
(
'user-info'
)
localStorage
.
removeItem
(
'userId'
)
localStorage
.
removeItem
(
'Authorization'
)
window
.
location
.
href
=
window
.
origin
+
urlSuffix
NProgress
.
done
()
}
// set page title
document
.
title
=
getPageTitle
(
to
.
meta
.
title
);
// set page title
document
.
title
=
getPageTitle
(
to
.
meta
.
title
)
// determine whether the user has logged in
debugger
;
if
(
hasToken
)
{
if
(
to
.
path
===
"/login"
)
{
// if is logged in, redirect to the home page
next
({
path
:
"/"
,
});
NProgress
.
done
();
// determine whether the user has logged in
if
(
hasToken
)
{
if
(
to
.
path
===
'/login'
)
{
// if is logged in, redirect to the home page
next
({
path
:
'/'
})
NProgress
.
done
()
}
else
{
const
hasGetUserInfo
=
store
.
getters
.
name
if
(
hasGetUserInfo
||
to
.
path
.
indexOf
(
'/previewScreenShot/'
)
>
-
1
||
to
.
path
.
indexOf
(
'/preview/'
)
>
-
1
||
to
.
path
.
indexOf
(
'/delink'
)
>
-
1
||
to
.
path
.
indexOf
(
'/nolic'
)
>
-
1
)
{
next
()
store
.
dispatch
(
'permission/setCurrentPath'
,
to
.
path
)
let
route
=
store
.
getters
.
permission_routes
.
find
(
item
=>
item
.
path
===
'/'
+
to
.
path
.
split
(
'/'
)[
1
]
)
// 如果找不到这个路由,说明是首页
if
(
!
route
)
{
route
=
store
.
getters
.
permission_routes
.
find
(
item
=>
item
.
path
===
'/'
)
}
store
.
commit
(
'permission/SET_CURRENT_ROUTES'
,
route
)
if
([
'system'
].
includes
(
route
.
name
))
{
store
.
dispatch
(
'app/toggleSideBarHide'
,
false
)
}
}
else
{
const
hasGetUserInfo
=
store
.
getters
.
name
;
if
(
hasGetUserInfo
||
to
.
path
.
indexOf
(
"/previewScreenShot/"
)
>
-
1
||
to
.
path
.
indexOf
(
"/preview/"
)
>
-
1
||
to
.
path
.
indexOf
(
"/delink"
)
>
-
1
||
to
.
path
.
indexOf
(
"/nolic"
)
>
-
1
)
{
next
();
store
.
dispatch
(
"permission/setCurrentPath"
,
to
.
path
);
let
route
=
store
.
getters
.
permission_routes
.
find
(
(
item
)
=>
item
.
path
===
"/"
+
to
.
path
.
split
(
"/"
)[
1
]
);
// 如果找不到这个路由,说明是首页
if
(
!
route
)
{
route
=
store
.
getters
.
permission_routes
.
find
(
(
item
)
=>
item
.
path
===
"/"
);
}
store
.
commit
(
"permission/SET_CURRENT_ROUTES"
,
route
);
if
([
"system"
].
includes
(
route
.
name
))
{
store
.
dispatch
(
"app/toggleSideBarHide"
,
false
);
}
if
(
store
.
getters
.
roles
.
length
===
0
)
{
// 判断当前用户是否已拉取完user_info信息
// get user info
store
.
dispatch
(
'user/getInfo'
).
then
(()
=>
{
const
deWebsocket
=
getSocket
()
deWebsocket
&&
deWebsocket
.
reconnect
&&
deWebsocket
.
reconnect
()
store
.
dispatch
(
'lic/getLicInfo'
).
then
(()
=>
{
loadMenus
(
next
,
to
)
}).
catch
(()
=>
{
loadMenus
(
next
,
to
)
})
}).
catch
(()
=>
{
store
.
dispatch
(
'user/logout'
).
then
(()
=>
{
location
.
reload
()
// 为了重新实例化vue-router对象 避免bug
})
})
}
else
if
(
store
.
getters
.
loadMenus
)
{
// 修改成false,防止死循环
store
.
dispatch
(
'user/updateLoadMenus'
)
store
.
dispatch
(
'lic/getLicInfo'
).
then
(()
=>
{
loadMenus
(
next
,
to
)
}).
catch
(()
=>
{
loadMenus
(
next
,
to
)
}
)
}
else
{
if
(
store
.
getters
.
roles
.
length
===
0
)
{
// 判断当前用户是否已拉取完user_info信息
// get user info
store
.
dispatch
(
"user/getInfo"
)
.
then
(()
=>
{
const
deWebsocket
=
getSocket
();
deWebsocket
&&
deWebsocket
.
reconnect
&&
deWebsocket
.
reconnect
();
store
.
dispatch
(
"lic/getLicInfo"
)
.
then
(()
=>
{
loadMenus
(
next
,
to
);
})
.
catch
(()
=>
{
loadMenus
(
next
,
to
);
});
})
.
catch
(()
=>
{
store
.
dispatch
(
"user/logout"
).
then
(()
=>
{
location
.
reload
();
// 为了重新实例化vue-router对象 避免bug
});
});
}
else
if
(
store
.
getters
.
loadMenus
)
{
// 修改成false,防止死循环
store
.
dispatch
(
"user/updateLoadMenus"
);
store
.
dispatch
(
"lic/getLicInfo"
)
.
then
(()
=>
{
loadMenus
(
next
,
to
);
})
.
catch
(()
=>
{
loadMenus
(
next
,
to
);
});
}
else
{
next
();
}
next
()
}
}
}
else
{
/* has no token*/
}
}
else
{
/* has no token*/
if
(
whiteList
.
indexOf
(
to
.
path
)
!==
-
1
)
{
// in the free login whitelist, go directly
next
();
}
else
{
// other pages that do not have permission to access are redirected to the login page.
next
(
`/login?redirect=
${
to
.
fullPath
}
`
);
NProgress
.
done
();
}
if
(
whiteList
.
indexOf
(
to
.
path
)
!==
-
1
)
{
// in the free login whitelist, go directly
next
()
}
else
{
// other pages that do not have permission to access are redirected to the login page.
next
(
`/login?redirect=
${
to
.
fullPath
}
`
)
NProgress
.
done
()
}
}
)
);
}
}))
export
const
loadMenus
=
(
next
,
to
)
=>
{
buildMenus
().
then
(
(
res
)
=>
{
const
data
=
res
.
data
;
const
filterData
=
filterRouter
(
data
)
;
const
asyncRouter
=
filterAsyncRouter
(
filterData
)
;
buildMenus
().
then
(
res
=>
{
const
data
=
res
.
data
const
filterData
=
filterRouter
(
data
)
const
asyncRouter
=
filterAsyncRouter
(
filterData
)
// 如果包含首页 则默认页面是 首页 否则默认页面是仪表板页面
if
(
JSON
.
stringify
(
data
).
indexOf
(
"wizard"
)
>
-
1
)
{
if
(
JSON
.
stringify
(
data
).
indexOf
(
'wizard'
)
>
-
1
)
{
asyncRouter
.
push
({
path
:
"/"
,
path
:
'/'
,
component
:
Layout
,
redirect
:
"/wizard/index"
,
hidden
:
true
,
})
;
redirect
:
'/wizard/index'
,
hidden
:
true
})
}
else
{
asyncRouter
.
push
({
path
:
"/"
,
path
:
'/'
,
component
:
Layout
,
redirect
:
"/panel/index"
,
hidden
:
true
,
})
;
redirect
:
'/panel/index'
,
hidden
:
true
})
}
asyncRouter
.
push
({
path
:
"*"
,
redirect
:
"/404"
,
hidden
:
true
,
});
store
.
dispatch
(
"permission/GenerateRoutes"
,
asyncRouter
).
then
(()
=>
{
// 存储路由
router
.
addRoutes
(
asyncRouter
);
path
:
'*'
,
redirect
:
'/404'
,
hidden
:
true
})
store
.
dispatch
(
'permission/GenerateRoutes'
,
asyncRouter
).
then
(()
=>
{
// 存储路由
router
.
addRoutes
(
asyncRouter
)
if
(
pathValid
(
to
.
path
,
asyncRouter
))
{
next
({
...
to
,
replace
:
true
,
})
;
replace
:
true
})
}
else
{
next
(
"/"
);
next
(
'/'
)
}
})
;
})
;
}
;
})
})
}
/**
* 验证path是否有效
...
...
@@ -217,14 +194,14 @@ export const loadMenus = (next, to) => {
* @returns
*/
const
pathValid
=
(
path
,
routers
)
=>
{
const
temp
=
path
.
startsWith
(
"/"
)
?
path
.
substr
(
1
)
:
path
;
const
locations
=
temp
.
split
(
"/"
);
const
temp
=
path
.
startsWith
(
'/'
)
?
path
.
substr
(
1
)
:
path
const
locations
=
temp
.
split
(
'/'
)
if
(
locations
.
length
===
0
)
{
return
false
;
return
false
}
return
hasCurrentRouter
(
locations
,
routers
,
0
)
;
}
;
return
hasCurrentRouter
(
locations
,
routers
,
0
)
}
/**
* 递归验证every level
* @param {*} locations
...
...
@@ -233,69 +210,62 @@ const pathValid = (path, routers) => {
* @returns
*/
const
hasCurrentRouter
=
(
locations
,
routers
,
index
)
=>
{
const
location
=
locations
[
index
]
;
let
kids
=
[]
;
const
isvalid
=
routers
.
some
(
(
router
)
=>
{
kids
=
router
.
children
;
return
router
.
path
===
location
||
"/"
+
location
===
router
.
path
;
})
;
const
location
=
locations
[
index
]
let
kids
=
[]
const
isvalid
=
routers
.
some
(
router
=>
{
kids
=
router
.
children
return
(
router
.
path
===
location
||
(
'/'
+
location
)
===
router
.
path
)
})
if
(
isvalid
&&
index
<
locations
.
length
-
1
)
{
return
hasCurrentRouter
(
locations
,
kids
,
index
+
1
)
;
return
hasCurrentRouter
(
locations
,
kids
,
index
+
1
)
}
return
isvalid
;
}
;
return
isvalid
}
// 根据权限过滤菜单
const
filterRouter
=
(
routers
)
=>
{
const
user_permissions
=
store
.
getters
.
permissions
;
const
filterRouter
=
routers
=>
{
const
user_permissions
=
store
.
getters
.
permissions
// if (!user_permissions || user_permissions.length === 0) {
// return routers
// }
const
tempResults
=
routers
.
filter
((
router
)
=>
hasPermission
(
router
,
user_permissions
)
);
const
tempResults
=
routers
.
filter
(
router
=>
hasPermission
(
router
,
user_permissions
))
// 如果是一级菜单(目录) 没有字菜单 那就移除
return
tempResults
.
filter
(
(
item
)
=>
{
return
tempResults
.
filter
(
item
=>
{
if
(
item
.
type
===
0
&&
(
!
item
.
children
||
item
.
children
.
length
===
0
))
{
return
false
;
return
false
}
return
true
;
})
;
}
;
return
true
})
}
const
hasPermission
=
(
router
,
user_permissions
)
=>
{
// 判断是否有符合权限 eg. user:read,user:delete
if
(
router
.
permission
&&
router
.
permission
.
indexOf
(
","
)
>
-
1
)
{
const
permissions
=
router
.
permission
.
split
(
","
);
const
permissionsFilter
=
permissions
.
filter
(
(
permission
)
=>
{
return
user_permissions
.
includes
(
permission
)
;
})
;
if
(
router
.
permission
&&
router
.
permission
.
indexOf
(
','
)
>
-
1
)
{
const
permissions
=
router
.
permission
.
split
(
','
)
const
permissionsFilter
=
permissions
.
filter
(
permission
=>
{
return
user_permissions
.
includes
(
permission
)
})
if
(
!
permissionsFilter
||
permissionsFilter
.
length
===
0
)
{
return
false
;
return
false
}
}
else
if
(
router
.
permission
&&
!
user_permissions
.
includes
(
router
.
permission
)
)
{
}
else
if
(
router
.
permission
&&
!
user_permissions
.
includes
(
router
.
permission
))
{
// 菜单要求权限 但是当前用户权限没有包含菜单权限
return
false
;
return
false
}
if
(
!
filterLic
(
router
))
{
return
false
;
return
false
}
// 如果有字菜单 则 判断是否满足 ‘任意一个子菜单有权限’
if
(
router
.
children
&&
router
.
children
.
length
)
{
const
permissionChildren
=
router
.
children
.
filter
((
item
)
=>
hasPermission
(
item
,
user_permissions
)
);
router
.
children
=
permissionChildren
;
return
router
.
children
.
length
>
0
;
const
permissionChildren
=
router
.
children
.
filter
(
item
=>
hasPermission
(
item
,
user_permissions
))
router
.
children
=
permissionChildren
return
router
.
children
.
length
>
0
}
return
true
;
}
;
return
true
}
const
filterLic
=
(
router
)
=>
{
return
!
router
.
isPlugin
||
store
.
getters
.
validate
;
}
;
return
!
router
.
isPlugin
||
store
.
getters
.
validate
}
router
.
afterEach
(()
=>
{
// finish progress bar
NProgress
.
done
()
;
})
;
NProgress
.
done
()
})
src/router/index.js
查看文件 @
a752cff5
import
Vue
from
"vue"
;
import
Router
from
"vue-router"
;
import
Vue
from
'vue'
import
Router
from
'vue-router'
Vue
.
use
(
Router
)
;
Vue
.
use
(
Router
)
/* Layout */
import
Layout
from
"@/layout"
;
import
Layout
from
'@/layout'
/**
* Note: sub-menu only appear when route children.length >= 1
...
...
@@ -32,74 +32,71 @@ import Layout from "@/layout";
*/
export
const
constantRoutes
=
[
{
path
:
"/redirect"
,
path
:
'/redirect'
,
component
:
Layout
,
hidden
:
true
,
children
:
[
{
path
:
"/redirect/:path(.*)"
,
component
:
()
=>
import
(
"@/views/redirect/index"
),
}
,
]
,
path
:
'/redirect/:path(.*)'
,
component
:
()
=>
import
(
'@/views/redirect/index'
)
}
]
},
{
path
:
"/login"
,
component
:
()
=>
import
(
"@/views/login/index"
),
hidden
:
true
,
path
:
'/login'
,
component
:
()
=>
import
(
'@/views/login/index'
),
hidden
:
true
},
{
path
:
"/404"
,
component
:
()
=>
import
(
"@/views/404"
),
hidden
:
true
,
path
:
'/404'
,
component
:
()
=>
import
(
'@/views/404'
),
hidden
:
true
},
{
path
:
"/401"
,
component
:
(
resolve
)
=>
require
([
"@/views/401"
],
resolve
),
hidden
:
true
,
path
:
'/401'
,
component
:
(
resolve
)
=>
require
([
'@/views/401'
],
resolve
),
hidden
:
true
},
{
path
:
"/panelEdit"
,
path
:
'/panelEdit'
,
component
:
Layout
,
redirect
:
"/panelEdit/edit"
,
redirect
:
'/panelEdit/edit'
,
hidden
:
true
,
children
:
[
{
path
:
"edit"
,
component
:
()
=>
import
(
"@/views/panel/edit"
),
}
,
]
,
path
:
'edit'
,
component
:
()
=>
import
(
'@/views/panel/edit'
)
}
]
},
{
path
:
"/delink"
,
component
:
()
=>
import
(
"@/views/link"
),
hidden
:
true
,
path
:
'/delink'
,
component
:
()
=>
import
(
'@/views/link'
),
hidden
:
true
},
{
path
:
"/preview/:reportId"
,
component
:
()
=>
import
(
"@/components/canvas/components/editor/PreviewEject"
),
hidden
:
true
,
path
:
'/preview/:reportId'
,
component
:
()
=>
import
(
'@/components/canvas/components/editor/PreviewEject'
),
hidden
:
true
},
{
path
:
"/previewScreenShot/:reportId/:backScreenShot"
,
component
:
()
=>
import
(
"@/components/canvas/components/editor/PreviewEject"
),
hidden
:
true
,
path
:
'/previewScreenShot/:reportId/:backScreenShot'
,
component
:
()
=>
import
(
'@/components/canvas/components/editor/PreviewEject'
),
hidden
:
true
},
{
path
:
"/previewFullScreen"
,
component
:
()
=>
import
(
"@/components/canvas/components/editor/PreviewFullScreen"
),
hidden
:
true
,
path
:
'/previewFullScreen'
,
component
:
()
=>
import
(
'@/components/canvas/components/editor/PreviewFullScreen'
),
hidden
:
true
},
{
path
:
"/de-auto-login"
,
component
:
()
=>
import
(
"@/views/DeAutoLogin"
),
hidden
:
true
,
}
,
path
:
'/de-auto-login'
,
component
:
()
=>
import
(
'@/views/DeAutoLogin'
),
hidden
:
true
}
// {
// path: '/',
...
...
@@ -217,22 +214,21 @@ export const constantRoutes = [
// },
// 404 page must be placed at the end !!!
// { path: '*', redirect: '/404', hidden: true }
]
;
]
const
createRouter
=
()
=>
new
Router
({
// mode: 'history', // require service support
mode
:
"hash"
,
scrollBehavior
:
()
=>
({
y
:
0
}),
routes
:
[],
});
const
createRouter
=
()
=>
new
Router
({
// mode: 'history', // require service support
mode
:
'hash'
,
scrollBehavior
:
()
=>
({
y
:
0
}),
routes
:
constantRoutes
})
const
router
=
createRouter
()
;
const
router
=
createRouter
()
// Detail see: https://github.com/vuejs/vue-router/issues/1234#issuecomment-357941465
export
function
resetRouter
()
{
const
newRouter
=
createRouter
()
;
router
.
matcher
=
newRouter
.
matcher
;
// reset router
const
newRouter
=
createRouter
()
router
.
matcher
=
newRouter
.
matcher
// reset router
}
export
default
router
;
export
default
router
src/utils/index.js
查看文件 @
a752cff5
import
Cookies
from
"js-cookie"
;
import
i18n
from
"@/lang"
;
import
{
$error
,
$confirm
}
from
"@/utils/message"
;
import
{
seizeLogin
}
from
"@/api/user"
;
import
router
from
"@/router"
;
import
store
from
"@/store"
;
import
{
Loading
}
from
"element-ui"
;
export
function
timeSection
(
date
,
type
,
labelFormat
=
"yyyy-MM-dd"
)
{
import
Cookies
from
'js-cookie'
import
i18n
from
'@/lang'
import
{
$error
,
$confirm
}
from
'@/utils/message'
import
{
seizeLogin
}
from
'@/api/user'
import
router
from
'@/router'
import
store
from
'@/store'
import
{
Loading
}
from
'element-ui'
export
function
timeSection
(
date
,
type
,
labelFormat
=
'yyyy-MM-dd'
)
{
if
(
!
date
)
{
return
null
;
return
null
}
if
(
!
(
date
instanceof
Date
))
{
date
=
new
Date
(
date
)
;
date
=
new
Date
(
date
)
}
const
timeRanger
=
new
Array
(
2
)
;
const
timeRanger
=
new
Array
(
2
)
const
formatArr
=
labelFormat
?
labelFormat
.
split
(
" "
)
:
[];
const
methods
=
[
"setHours"
,
"setMinutes"
,
"setSeconds"
,
"setMilliseconds"
];
let
methodsLen
=
methods
.
length
;
if
(
type
===
"datetime"
&&
formatArr
.
length
>
1
)
{
const
childArr
=
formatArr
[
1
]
?
formatArr
[
1
].
split
(
":"
)
:
[];
const
childArrLength
=
childArr
?
childArr
.
length
:
0
;
const
formatArr
=
labelFormat
?
labelFormat
.
split
(
' '
)
:
[]
const
methods
=
[
'setHours'
,
'setMinutes'
,
'setSeconds'
,
'setMilliseconds'
]
let
methodsLen
=
methods
.
length
if
(
type
===
'datetime'
&&
formatArr
.
length
>
1
)
{
const
childArr
=
formatArr
[
1
]
?
formatArr
[
1
].
split
(
':'
)
:
[]
const
childArrLength
=
childArr
?
childArr
.
length
:
0
while
(
--
methodsLen
>=
childArrLength
)
{
date
[
methods
[
methodsLen
]](
0
)
;
date
[
methods
[
methodsLen
]](
0
)
}
}
else
{
methods
.
forEach
(
(
m
)
=>
date
[
m
](
0
));
methods
.
forEach
(
m
=>
date
[
m
](
0
))
}
const
end
=
new
Date
(
date
)
;
if
(
type
===
"year"
)
{
date
.
setDate
(
1
)
;
date
.
setMonth
(
0
)
;
end
.
setFullYear
(
date
.
getFullYear
()
+
1
)
;
timeRanger
[
1
]
=
end
.
getTime
()
-
1
;
}
if
(
type
===
"month"
)
{
date
.
setDate
(
1
)
;
const
currentMonth
=
date
.
getMonth
()
;
const
end
=
new
Date
(
date
)
if
(
type
===
'year'
)
{
date
.
setDate
(
1
)
date
.
setMonth
(
0
)
end
.
setFullYear
(
date
.
getFullYear
()
+
1
)
timeRanger
[
1
]
=
end
.
getTime
()
-
1
}
if
(
type
===
'month'
)
{
date
.
setDate
(
1
)
const
currentMonth
=
date
.
getMonth
()
if
(
currentMonth
===
11
)
{
end
.
setFullYear
(
date
.
getFullYear
()
+
1
)
;
end
.
setMonth
(
0
)
;
end
.
setFullYear
(
date
.
getFullYear
()
+
1
)
end
.
setMonth
(
0
)
}
else
{
end
.
setMonth
(
date
.
getMonth
()
+
1
)
;
end
.
setMonth
(
date
.
getMonth
()
+
1
)
}
timeRanger
[
1
]
=
end
.
getTime
()
-
1
;
timeRanger
[
1
]
=
end
.
getTime
()
-
1
}
if
(
type
===
"date"
)
{
end
.
setHours
(
23
)
;
end
.
setMinutes
(
59
)
;
end
.
setSeconds
(
59
)
;
end
.
setMilliseconds
(
999
)
;
timeRanger
[
1
]
=
end
.
getTime
()
;
if
(
type
===
'date'
)
{
end
.
setHours
(
23
)
end
.
setMinutes
(
59
)
end
.
setSeconds
(
59
)
end
.
setMilliseconds
(
999
)
timeRanger
[
1
]
=
end
.
getTime
()
}
if
(
type
===
"datetime"
)
{
methodsLen
=
methods
.
length
;
if
(
type
===
'datetime'
)
{
methodsLen
=
methods
.
length
if
(
formatArr
.
length
>
1
)
{
const
childArr
=
formatArr
[
1
]
?
formatArr
[
1
].
split
(
":"
)
:
[];
const
childArrLength
=
childArr
?
childArr
.
length
:
0
;
const
childArr
=
formatArr
[
1
]
?
formatArr
[
1
].
split
(
':'
)
:
[]
const
childArrLength
=
childArr
?
childArr
.
length
:
0
while
(
--
methodsLen
>=
childArrLength
)
{
end
[
methods
[
methodsLen
]](
methodsLen
===
0
?
23
:
methodsLen
===
3
?
999
:
59
);
end
[
methods
[
methodsLen
]](
methodsLen
===
0
?
23
:
methodsLen
===
3
?
999
:
59
)
}
}
else
{
while
(
--
methodsLen
>=
0
)
{
end
[
methods
[
methodsLen
]](
methodsLen
===
0
?
23
:
methodsLen
===
3
?
999
:
59
);
end
[
methods
[
methodsLen
]](
methodsLen
===
0
?
23
:
methodsLen
===
3
?
999
:
59
)
}
}
timeRanger
[
1
]
=
end
.
getTime
()
;
timeRanger
[
1
]
=
end
.
getTime
()
}
timeRanger
[
0
]
=
date
.
getTime
()
;
timeRanger
[
0
]
=
date
.
getTime
()
return
timeRanger
;
return
timeRanger
}
export
function
dateFormat
(
date
,
fmt
)
{
let
ret
;
let
ret
const
opt
=
{
"y+"
:
date
.
getFullYear
().
toString
(),
// 年
"M+"
:
(
date
.
getMonth
()
+
1
).
toString
(),
// 月
"d+"
:
date
.
getDate
().
toString
(),
// 日
"H+"
:
date
.
getHours
().
toString
(),
// 时
"m+"
:
date
.
getMinutes
().
toString
(),
// 分
"s+"
:
date
.
getSeconds
().
toString
(),
// 秒
'y+'
:
date
.
getFullYear
().
toString
(),
// 年
'M+'
:
(
date
.
getMonth
()
+
1
).
toString
(),
// 月
'd+'
:
date
.
getDate
().
toString
(),
// 日
'H+'
:
date
.
getHours
().
toString
(),
// 时
'm+'
:
date
.
getMinutes
().
toString
(),
// 分
's+'
:
date
.
getSeconds
().
toString
()
// 秒
// 有其他格式化字符需求可以继续添加,必须转化成字符串
}
;
}
for
(
const
k
in
opt
)
{
ret
=
new
RegExp
(
"("
+
k
+
")"
).
exec
(
fmt
);
ret
=
new
RegExp
(
'('
+
k
+
')'
).
exec
(
fmt
)
if
(
ret
)
{
fmt
=
fmt
.
replace
(
ret
[
1
],
ret
[
1
].
length
===
1
?
opt
[
k
]
:
opt
[
k
].
padStart
(
ret
[
1
].
length
,
"0"
)
);
fmt
=
fmt
.
replace
(
ret
[
1
],
(
ret
[
1
].
length
===
1
)
?
(
opt
[
k
])
:
(
opt
[
k
].
padStart
(
ret
[
1
].
length
,
'0'
)))
}
}
return
fmt
;
return
fmt
}
/**
...
...
@@ -110,20 +103,20 @@ export function dateFormat(date, fmt) {
*/
export
function
parseTime
(
time
,
cFormat
)
{
if
(
arguments
.
length
===
0
)
{
return
null
;
return
null
}
const
format
=
cFormat
||
"{y}-{m}-{d} {h}:{i}:{s}"
;
let
date
;
if
(
typeof
time
===
"object"
)
{
date
=
time
;
const
format
=
cFormat
||
'{y}-{m}-{d} {h}:{i}:{s}'
let
date
if
(
typeof
time
===
'object'
)
{
date
=
time
}
else
{
if
(
typeof
time
===
"string"
&&
/^
[
0-9
]
+$/
.
test
(
time
))
{
time
=
parseInt
(
time
)
;
if
(
(
typeof
time
===
'string'
)
&&
(
/^
[
0-9
]
+$/
.
test
(
time
)
))
{
time
=
parseInt
(
time
)
}
if
(
typeof
time
===
"number"
&&
time
.
toString
().
length
===
10
)
{
time
=
time
*
1000
;
if
(
(
typeof
time
===
'number'
)
&&
(
time
.
toString
().
length
===
10
)
)
{
time
=
time
*
1000
}
date
=
new
Date
(
time
)
;
date
=
new
Date
(
time
)
}
const
formatObj
=
{
y
:
date
.
getFullYear
(),
...
...
@@ -132,17 +125,17 @@ export function parseTime(time, cFormat) {
h
:
date
.
getHours
(),
i
:
date
.
getMinutes
(),
s
:
date
.
getSeconds
(),
a
:
date
.
getDay
()
,
}
;
a
:
date
.
getDay
()
}
const
time_str
=
format
.
replace
(
/{
([
ymdhisa
])
+}/g
,
(
result
,
key
)
=>
{
const
value
=
formatObj
[
key
]
;
const
value
=
formatObj
[
key
]
// Note: getDay() returns 0 on Sunday
if
(
key
===
"a"
)
{
return
[
"日"
,
"一"
,
"二"
,
"三"
,
"四"
,
"五"
,
"六"
][
value
];
if
(
key
===
'a'
)
{
return
[
'日'
,
'一'
,
'二'
,
'三'
,
'四'
,
'五'
,
'六'
][
value
]
}
return
value
.
toString
().
padStart
(
2
,
"0"
);
})
;
return
time_str
;
return
value
.
toString
().
padStart
(
2
,
'0'
)
})
return
time_str
}
/**
...
...
@@ -152,7 +145,7 @@ export function parseTime(time, cFormat) {
* @returns {boolean}
*/
export
function
hasClass
(
ele
,
cls
)
{
return
!!
ele
.
className
.
match
(
new
RegExp
(
"(
\\
s|^)"
+
cls
+
"(
\\
s|$)"
));
return
!!
ele
.
className
.
match
(
new
RegExp
(
'(
\\
s|^)'
+
cls
+
'(
\\
s|$)'
))
}
/**
...
...
@@ -161,7 +154,7 @@ export function hasClass(ele, cls) {
* @param {string} cls
*/
export
function
addClass
(
ele
,
cls
)
{
if
(
!
hasClass
(
ele
,
cls
))
ele
.
className
+=
" "
+
cls
;
if
(
!
hasClass
(
ele
,
cls
))
ele
.
className
+=
' '
+
cls
}
/**
...
...
@@ -171,8 +164,8 @@ export function addClass(ele, cls) {
*/
export
function
removeClass
(
ele
,
cls
)
{
if
(
hasClass
(
ele
,
cls
))
{
const
reg
=
new
RegExp
(
"(
\\
s|^)"
+
cls
+
"(
\\
s|$)"
);
ele
.
className
=
ele
.
className
.
replace
(
reg
,
" "
);
const
reg
=
new
RegExp
(
'(
\\
s|^)'
+
cls
+
'(
\\
s|$)'
)
ele
.
className
=
ele
.
className
.
replace
(
reg
,
' '
)
}
}
...
...
@@ -182,40 +175,40 @@ export function removeClass(ele, cls) {
* @returns {string}
*/
export
function
formatTime
(
time
,
option
)
{
if
((
""
+
time
).
length
===
10
)
{
time
=
parseInt
(
time
)
*
1000
;
if
((
''
+
time
).
length
===
10
)
{
time
=
parseInt
(
time
)
*
1000
}
else
{
time
=
+
time
;
time
=
+
time
}
const
d
=
new
Date
(
time
)
;
const
now
=
Date
.
now
()
;
const
d
=
new
Date
(
time
)
const
now
=
Date
.
now
()
const
diff
=
(
now
-
d
)
/
1000
;
const
diff
=
(
now
-
d
)
/
1000
if
(
diff
<
30
)
{
return
"刚刚"
;
return
'刚刚'
}
else
if
(
diff
<
3600
)
{
// less 1 hour
return
Math
.
ceil
(
diff
/
60
)
+
"分钟前"
;
return
Math
.
ceil
(
diff
/
60
)
+
'分钟前'
}
else
if
(
diff
<
3600
*
24
)
{
return
Math
.
ceil
(
diff
/
3600
)
+
"小时前"
;
return
Math
.
ceil
(
diff
/
3600
)
+
'小时前'
}
else
if
(
diff
<
3600
*
24
*
2
)
{
return
"1天前"
;
return
'1天前'
}
if
(
option
)
{
return
parseTime
(
time
,
option
)
;
return
parseTime
(
time
,
option
)
}
else
{
return
(
d
.
getMonth
()
+
1
+
"月"
+
'月'
+
d
.
getDate
()
+
"日"
+
'日'
+
d
.
getHours
()
+
"时"
+
'时'
+
d
.
getMinutes
()
+
"分"
)
;
'分'
)
}
}
...
...
@@ -224,33 +217,33 @@ export function formatTime(time, option) {
* @returns {Object}
*/
export
function
param2Obj
(
url
)
{
const
search
=
url
.
split
(
"?"
)[
1
];
const
search
=
url
.
split
(
'?'
)[
1
]
if
(
!
search
)
{
return
{}
;
return
{}
}
return
JSON
.
parse
(
'{"'
+
decodeURIComponent
(
search
)
.
replace
(
/"/g
,
'
\\
"'
)
.
replace
(
/&/g
,
'","'
)
.
replace
(
/=/g
,
'":"'
)
.
replace
(
/
\+
/g
,
" "
)
+
'"}'
)
;
decodeURIComponent
(
search
)
.
replace
(
/"/g
,
'
\\
"'
)
.
replace
(
/&/g
,
'","'
)
.
replace
(
/=/g
,
'":"'
)
.
replace
(
/
\+
/g
,
' '
)
+
'"}'
)
}
export
function
formatCondition
(
param
)
{
if
(
!
param
)
{
return
null
;
return
null
}
const
result
=
{
conditions
:
[]
,
}
;
conditions
:
[]
}
// eslint-disable-next-line no-unused-vars
for
(
const
[
key
,
value
]
of
Object
.
entries
(
param
))
{
result
.
conditions
.
push
(
value
)
;
result
.
conditions
.
push
(
value
)
}
return
result
;
return
result
}
/**
* 驼峰转下划线
...
...
@@ -258,170 +251,152 @@ export function formatCondition(param) {
* @returns
*/
export
function
toLine
(
name
)
{
return
name
.
replace
(
/
([
A-Z
])
/g
,
"_$1"
).
toLowerCase
();
return
name
.
replace
(
/
([
A-Z
])
/g
,
'_$1'
).
toLowerCase
()
}
export
function
addOrder
(
order
,
orders
)
{
order
.
field
=
toLine
(
order
.
field
)
;
if
(
order
.
value
.
startsWith
(
"desc"
))
{
order
.
value
=
"desc"
;
order
.
field
=
toLine
(
order
.
field
)
if
(
order
.
value
.
startsWith
(
'desc'
))
{
order
.
value
=
'desc'
}
else
{
order
.
value
=
"asc"
;
order
.
value
=
'asc'
}
orders
=
orders
||
[]
;
orders
=
orders
||
[]
for
(
let
index
=
0
;
index
<
orders
.
length
;
index
++
)
{
const
element
=
orders
[
index
]
;
const
element
=
orders
[
index
]
if
(
order
.
field
===
element
.
field
)
{
orders
[
index
]
=
order
;
return
;
orders
[
index
]
=
order
return
}
}
orders
.
push
(
order
)
;
orders
.
push
(
order
)
}
export
function
formatOrders
(
orders
)
{
return
orders
.
map
(
(
order
)
=>
order
.
field
+
" "
+
order
.
value
);
return
orders
.
map
(
order
=>
order
.
field
+
' '
+
order
.
value
)
}
export
function
formatQuickCondition
(
param
,
quickField
)
{
let
quickObj
=
null
;
let
quickObj
=
null
if
(
!
param
||
!
(
quickObj
=
param
.
quick
)
||
!
quickField
)
{
quickObj
&&
delete
param
.
quick
;
return
param
;
quickObj
&&
delete
param
.
quick
return
param
}
param
[
quickField
]
=
{
field
:
quickField
,
operator
:
"like"
,
value
:
quickObj
.
value
,
}
;
delete
param
.
quick
;
return
param
;
operator
:
'like'
,
value
:
quickObj
.
value
}
delete
param
.
quick
return
param
}
export
function
getQueryVariable
(
variable
)
{
let
query
=
window
.
location
.
search
.
substring
(
1
)
;
let
query
=
window
.
location
.
search
.
substring
(
1
)
if
(
!
query
)
{
query
=
Cookies
.
get
(
variable
)
;
query
=
Cookies
.
get
(
variable
)
}
if
(
query
!==
undefined
)
{
const
vars
=
query
.
split
(
"&"
);
const
vars
=
query
.
split
(
'&'
)
for
(
var
i
=
0
;
i
<
vars
.
length
;
i
++
)
{
const
pair
=
vars
[
i
].
split
(
"="
);
const
pair
=
vars
[
i
].
split
(
'='
)
if
(
pair
[
0
]
===
variable
)
{
return
pair
[
1
]
;
return
pair
[
1
]
}
}
}
return
false
;
return
(
false
)
}
export
function
isMobile
()
{
const
flag
=
navigator
.
userAgent
.
match
(
/
(
phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone
)
/i
);
return
flag
;
const
flag
=
navigator
.
userAgent
.
match
(
/
(
phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone
)
/i
)
return
flag
}
export
const
isSameVueObj
=
(
source
,
target
)
=>
{
if
(
!
source
&&
!
target
)
return
true
;
if
(
!
source
&&
!
target
)
return
true
if
(
!!
source
&&
!!
target
)
{
return
JSON
.
stringify
(
source
)
===
JSON
.
stringify
(
target
)
;
return
JSON
.
stringify
(
source
)
===
JSON
.
stringify
(
target
)
}
return
false
;
}
;
return
false
}
export
const
isSameArr
=
(
source
,
target
)
=>
{
if
(
!
source
&&
!
target
)
return
true
;
if
(
!
source
&&
!
target
)
return
true
if
(
source
?.
length
&&
target
?.
length
&&
source
.
length
===
target
.
length
)
{
const
sortSource
=
source
.
sort
()
;
const
sortTarget
=
target
.
sort
()
;
return
JSON
.
stringify
(
sortSource
)
===
JSON
.
stringify
(
sortTarget
)
;
const
sortSource
=
source
.
sort
()
const
sortTarget
=
target
.
sort
()
return
JSON
.
stringify
(
sortSource
)
===
JSON
.
stringify
(
sortTarget
)
}
return
false
;
}
;
return
false
}
export
const
changeFavicon
=
(
link
)
=>
{
let
$favicon
=
document
.
querySelector
(
'link[rel="icon"]'
)
;
export
const
changeFavicon
=
link
=>
{
let
$favicon
=
document
.
querySelector
(
'link[rel="icon"]'
)
if
(
$favicon
!==
null
)
{
$favicon
.
href
=
link
;
$favicon
.
href
=
link
}
else
{
$favicon
=
document
.
createElement
(
"link"
);
$favicon
.
rel
=
"icon"
;
$favicon
.
href
=
link
;
document
.
head
.
appendChild
(
$favicon
)
;
$favicon
=
document
.
createElement
(
'link'
)
$favicon
.
rel
=
'icon'
$favicon
.
href
=
link
document
.
head
.
appendChild
(
$favicon
)
}
}
;
}
export
const
mergeCustomSortOption
=
(
customSortList
,
sourceList
)
=>
{
if
(
!
customSortList
?.
length
)
return
sourceList
?.
length
?
sourceList
:
[]
;
if
(
!
customSortList
?.
length
)
return
sourceList
?.
length
?
sourceList
:
[]
if
(
!
sourceList
?.
length
)
return
customSortList
?.
length
?
customSortList
:
[]
;
if
(
!
sourceList
?.
length
)
return
customSortList
?.
length
?
customSortList
:
[]
const
result
=
[...
customSortList
,
...
sourceList
]
;
return
[...
new
Set
(
result
)]
;
}
;
const
result
=
[...
customSortList
,
...
sourceList
]
return
[...
new
Set
(
result
)]
}
export
const
inOtherPlatform
=
()
=>
{
const
cookieStr
=
Cookies
.
get
(
"inOtherPlatform"
);
if
(
cookieStr
&&
cookieStr
===
"true"
)
{
return
true
;
const
cookieStr
=
Cookies
.
get
(
'inOtherPlatform'
)
if
(
cookieStr
&&
cookieStr
===
'true'
)
{
return
true
}
return
false
;
}
;
return
false
}
export
const
showMultiLoginMsg
=
()
=>
{
const
multiLoginError1
=
Cookies
.
get
(
"MultiLoginError1"
);
const
multiLoginError1
=
Cookies
.
get
(
'MultiLoginError1'
)
if
(
multiLoginError1
)
{
Cookies
.
remove
(
"MultiLoginError1"
);
const
infos
=
JSON
.
parse
(
multiLoginError1
);
const
content
=
infos
.
map
((
info
)
=>
buildMultiLoginErrorItem
(
info
))
.
join
(
"</br>"
);
let
msgContent
=
"<strong>"
+
i18n
.
t
(
"multi_login_lang.title"
)
+
"</strong>"
;
msgContent
+=
content
+
"<p>"
+
i18n
.
t
(
"multi_login_lang.label"
)
+
"</p>"
;
$error
(
msgContent
,
10000
,
true
);
}
const
multiLoginError2
=
Cookies
.
get
(
"MultiLoginError2"
);
Cookies
.
remove
(
'MultiLoginError1'
)
const
infos
=
JSON
.
parse
(
multiLoginError1
)
const
content
=
infos
.
map
(
info
=>
buildMultiLoginErrorItem
(
info
)).
join
(
'</br>'
)
let
msgContent
=
'<strong>'
+
i18n
.
t
(
'multi_login_lang.title'
)
+
'</strong>'
msgContent
+=
content
+
'<p>'
+
i18n
.
t
(
'multi_login_lang.label'
)
+
'</p>'
$error
(
msgContent
,
10000
,
true
)
}
const
multiLoginError2
=
Cookies
.
get
(
'MultiLoginError2'
)
if
(
multiLoginError2
)
{
const
infos
=
JSON
.
parse
(
multiLoginError2
);
Cookies
.
remove
(
"MultiLoginError2"
);
const
content
=
infos
.
map
((
info
)
=>
buildMultiLoginErrorItem
(
info
))
.
join
(
"</br>"
);
let
msgContent
=
"<strong>"
+
i18n
.
t
(
"multi_login_lang.confirm_title"
)
+
"</strong>"
;
msgContent
+=
content
+
"<p>"
+
i18n
.
t
(
"multi_login_lang.confirm"
)
+
"</p>"
;
const
infos
=
JSON
.
parse
(
multiLoginError2
)
Cookies
.
remove
(
'MultiLoginError2'
)
const
content
=
infos
.
map
(
info
=>
buildMultiLoginErrorItem
(
info
)).
join
(
'</br>'
)
let
msgContent
=
'<strong>'
+
i18n
.
t
(
'multi_login_lang.confirm_title'
)
+
'</strong>'
msgContent
+=
content
+
'<p>'
+
i18n
.
t
(
'multi_login_lang.confirm'
)
+
'</p>'
$confirm
(
msgContent
,
()
=>
seize
(
infos
[
0
]),
{
dangerouslyUseHTMLString
:
true
,
})
;
dangerouslyUseHTMLString
:
true
})
}
}
;
const
seize
=
(
model
)
=>
{
const
loadingInstance
=
Loading
.
service
({})
;
const
token
=
model
.
token
;
}
const
seize
=
model
=>
{
const
loadingInstance
=
Loading
.
service
({})
const
token
=
model
.
token
const
param
=
{
token
,
}
;
seizeLogin
(
param
).
then
(
(
res
)
=>
{
const
resultToken
=
res
.
data
.
token
;
store
.
dispatch
(
"user/refreshToken"
,
resultToken
);
router
.
push
(
"/"
);
loadingInstance
.
close
()
;
})
;
}
;
token
}
seizeLogin
(
param
).
then
(
res
=>
{
const
resultToken
=
res
.
data
.
token
store
.
dispatch
(
'user/refreshToken'
,
resultToken
)
router
.
push
(
'/'
)
loadingInstance
.
close
()
})
}
const
buildMultiLoginErrorItem
=
(
info
)
=>
{
if
(
!
info
)
return
null
;
const
ip
=
i18n
.
t
(
"multi_login_lang.ip"
);
const
time
=
i18n
.
t
(
"multi_login_lang.time"
);
return
(
"<p>"
+
ip
+
": "
+
info
.
ip
+
", "
+
time
+
": "
+
new
Date
(
info
.
loginTime
).
format
(
"yyyy-MM-dd hh:mm:ss"
)
+
"</p>"
);
};
if
(
!
info
)
return
null
const
ip
=
i18n
.
t
(
'multi_login_lang.ip'
)
const
time
=
i18n
.
t
(
'multi_login_lang.time'
)
return
'<p>'
+
ip
+
': '
+
info
.
ip
+
', '
+
time
+
': '
+
new
Date
(
info
.
loginTime
).
format
(
'yyyy-MM-dd hh:mm:ss'
)
+
'</p>'
}
src/views/chart/components/ChartComponent.vue
查看文件 @
a752cff5
...
...
@@ -481,9 +481,11 @@ export default {
trackClick
(
trackAction
)
{
const
param
=
this
.
pointParam
if
(
!
param
||
!
param
.
data
||
!
param
.
data
.
dimensionList
)
{
// 地图提示没有关联字段 其他没有维度信息的 直接返回
if
(
this
.
chart
.
type
===
'map'
)
{
this
.
$warning
(
this
.
$t
(
'panel.no_drill_field'
))
const
zoom
=
this
.
myChart
.
getOption
().
geo
[
0
].
zoom
if
(
zoom
<=
1
)
{
this
.
$warning
(
this
.
$t
(
'panel.no_drill_field'
))
}
}
return
}
...
...
src/views/chart/components/componentStyle/dialog/RemarkEditor.vue
查看文件 @
a752cff5
...
...
@@ -14,6 +14,22 @@
<
script
>
import
tinymce
from
'tinymce/tinymce'
// tinymce默认hidden,不引入不显示
import
Editor
from
'@tinymce/tinymce-vue'
import
'tinymce/themes/silver/theme'
// 编辑器主题
import
'tinymce/icons/default'
// 引入编辑器图标icon,不引入则不显示对应图标
// 引入编辑器插件(基本免费插件都在这儿了)
import
'tinymce/plugins/advlist'
// 高级列表
import
'tinymce/plugins/autolink'
// 自动链接
import
'tinymce/plugins/link'
// 超链接
import
'tinymce/plugins/image'
// 插入编辑图片
import
'tinymce/plugins/lists'
// 列表插件
import
'tinymce/plugins/charmap'
// 特殊字符
import
'tinymce/plugins/media'
// 插入编辑媒体
import
'tinymce/plugins/wordcount'
// 字数统计
import
'tinymce/plugins/table'
// 表格
import
'tinymce/plugins/contextmenu'
// contextmenu
import
'tinymce/plugins/directionality'
import
'tinymce/plugins/nonbreaking'
import
'tinymce/plugins/pagebreak'
import
{
imgUrlTrans
}
from
'@/components/canvas/utils/utils'
import
{
mapState
}
from
'vuex'
// 编辑器引入
...
...
src/views/chart/components/dragItem/QuotaExtItem.vue
查看文件 @
a752cff5
...
...
@@ -449,7 +449,7 @@ export default {
valueFormatter
()
{
this
.
item
.
index
=
this
.
index
this
.
item
.
formatterType
=
'quota'
this
.
item
.
formatterType
=
'quota
Ext
'
this
.
$emit
(
'valueFormatter'
,
this
.
item
)
}
}
...
...
src/views/chart/components/filter/QuotaFilterEditor.vue
查看文件 @
a752cff5
...
...
@@ -117,6 +117,13 @@ export default {
value
:
'ge'
,
label
:
this
.
$t
(
'chart.filter_ge'
)
}]
},
{
label
:
''
,
options
:
[{
value
:
'not_null'
,
label
:
this
.
$t
(
'chart.filter_not_null'
)
}]
}],
logic
:
''
}
...
...
src/views/chart/components/filter/ResultFilterEditor.vue
查看文件 @
a752cff5
...
...
@@ -194,6 +194,13 @@ export default {
value
:
'ge'
,
label
:
this
.
$t
(
'chart.filter_ge'
)
}]
},
{
label
:
''
,
options
:
[{
value
:
'not_null'
,
label
:
this
.
$t
(
'chart.filter_not_null'
)
}]
}
],
valueOptions
:
[
...
...
@@ -226,6 +233,13 @@ export default {
value
:
'ge'
,
label
:
this
.
$t
(
'chart.filter_ge'
)
}]
},
{
label
:
''
,
options
:
[{
value
:
'not_null'
,
label
:
this
.
$t
(
'chart.filter_not_null'
)
}]
}
],
options
:
[],
...
...
src/views/chart/view/ChartEdit.vue
查看文件 @
a752cff5
...
...
@@ -473,7 +473,8 @@
<plugin-com
v-if=
"view.isPlugin"
:component-name=
"view.type + '-data'"
:obj=
"{view, param, chart, dimensionData, quotaData}"
:obj=
"{view, param, chart, dimension, dimensionData, quota, quotaData}"
:bus=
"bus"
/>
<div
v-else
>
...
...
@@ -819,6 +820,7 @@
@
editItemFilter=
"showQuotaEditFilter"
@
onNameEdit=
"showRename"
@
editItemCompare=
"showQuotaEditCompare"
@
valueFormatter=
"valueFormatter"
/>
</transition-group>
</draggable>
...
...
@@ -1795,7 +1797,7 @@ export default {
DrillPath
,
PluginCom
,
MapMapping
,
MarkMapDataEditor
,
MarkMapDataEditor
},
props
:
{
param
:
{
...
...
@@ -1815,6 +1817,7 @@ export default {
},
data
()
{
return
{
bus
:
bus
,
positionActiveNames
:
'positionAdjust'
,
loading
:
false
,
table
:
{},
...
...
@@ -2954,7 +2957,7 @@ export default {
// 更换数据集
changeChart
()
{
const
optType
=
this
.
view
.
tableId
===
this
.
changeTable
.
id
&&
this
.
view
.
dataFrom
!==
'template'
?
'same'
:
'change'
const
optType
=
this
.
view
.
tableId
===
this
.
changeTable
.
id
&&
this
.
view
.
dataFrom
!==
'template'
?
'same'
:
'change'
// 更换数据集后清空视图字段,并重新请求数据;否则没有操作
if
(
optType
===
'change'
)
{
this
.
view
.
dataFrom
=
'dataset'
...
...
src/views/chart/view/PositionAdjust.vue
查看文件 @
a752cff5
...
...
@@ -81,7 +81,7 @@ export default {
props
:
{},
data
()
{
return
{
maxHeight
:
2
000
,
maxHeight
:
10
000
,
maxTop
:
20000
}
},
...
...
src/views/chart/view/TitleRemark.vue
查看文件 @
a752cff5
...
...
@@ -10,7 +10,7 @@
<div
class=
"remark-style"
:style=
"
{backgroundColor:remarkCfg.bgFill}"
v-html="
remarkCfg.content
"
v-html="
$xss(remarkCfg.content)
"
/>
<i
slot=
"reference"
...
...
src/views/dataset/common/DatasetChartDetail.vue
查看文件 @
a752cff5
...
...
@@ -21,8 +21,8 @@
<el-col
class=
"info-item"
>
<p
class=
"info-title"
>
{{
$t
(
'chart.chart_type'
)
}}
</p>
<svg-icon
v-if=
"
detail.chart.type"
:icon-class=
"detail.chart.type
"
:icon-class=
"detail.chart.isPlugin && detail.chart.type && detail.chart.type !== 'buddle-map' ? ('/api/pluginCommon/staticInfo/' + detail.chart.type + '/svg') :
detail.chart.type"
class=
"chart-icon
"
/>
</el-col>
<el-col
class=
"info-item"
>
...
...
src/views/dataset/data/components/LazyTree.vue
查看文件 @
a752cff5
...
...
@@ -34,7 +34,7 @@
<span>
<span
style=
"margin-left: 6px"
v-html=
"
data.name
"
v-html=
"
$xss(data.name)
"
/>
</span>
<span
...
...
src/views/dataset/group/GroupMoveSelector.vue
查看文件 @
a752cff5
...
...
@@ -34,7 +34,7 @@
text-overflow: ellipsis;
"
:title=
"data.name"
v-html=
"
highlights(data.name
)"
v-html=
"
$xss(highlights(data.name)
)"
/>
</span>
</span>
...
...
src/views/login/index.vue
查看文件 @
a752cff5
...
...
@@ -216,6 +216,7 @@ import { changeFavicon, showMultiLoginMsg } from '@/utils/index'
import
{
initTheme
}
from
'@/utils/ThemeUtil'
import
PluginCom
from
'@/views/system/plugin/PluginCom'
import
Cookies
from
'js-cookie'
import
xss
from
'xss'
export
default
{
name
:
'Login'
,
components
:
{
PluginCom
},
...
...
@@ -449,7 +450,27 @@ export default {
this
.
showFoot
=
this
.
uiInfo
[
'ui.showFoot'
].
paramValue
===
true
||
this
.
uiInfo
[
'ui.showFoot'
].
paramValue
===
'true'
if
(
this
.
showFoot
)
{
const
content
=
this
.
uiInfo
[
'ui.footContent'
]
&&
this
.
uiInfo
[
'ui.footContent'
].
paramValue
this
.
footContent
=
content
const
myXss
=
new
xss
.
FilterXSS
({
css
:
{
whiteList
:
{
'background-color'
:
true
,
'text-align'
:
true
,
'color'
:
true
,
'margin-top'
:
true
,
'margin-bottom'
:
true
,
'line-height'
:
true
,
'box-sizing'
:
true
,
'padding-top'
:
true
,
'padding-bottom'
:
true
}
},
whiteList
:
{
...
xss
.
whiteList
,
p
:
[
'style'
],
span
:
[
'style'
]
}
})
this
.
footContent
=
myXss
.
process
(
content
)
}
}
},
...
...
src/views/panel/export/PDFPreExport.vue
查看文件 @
a752cff5
...
...
@@ -15,7 +15,7 @@
<div
class=
"export_body_inner_class"
:style=
"templateHtmlStyle"
v-html=
"
templateContentChange
"
v-html=
"
$xss(templateContentChange)
"
/>
</div>
</el-row>
...
...
src/views/panel/filter/FilterDialog.vue
查看文件 @
a752cff5
...
...
@@ -266,6 +266,7 @@
<div
v-if=
"currentElement.options && currentElement.options.attrs"
>
<filter-head
:element=
"currentElement"
@
dataset-name=
"dataSetName"
/>
<filter-control
...
...
@@ -463,6 +464,23 @@ export default {
bus
.
$off
(
'valid-values-change'
,
this
.
validateFilterValue
)
},
methods
:
{
dataSetName
(
tableId
,
callback
)
{
let
result
=
null
if
(
tableId
)
{
const
stack
=
[...
this
.
defaultData
]
while
(
stack
.
length
)
{
const
tableNode
=
stack
.
pop
()
if
(
tableNode
.
id
===
tableId
)
{
result
=
tableNode
.
name
break
}
if
(
tableNode
.
children
?.
length
)
{
tableNode
.
children
.
forEach
(
kid
=>
stack
.
push
(
kid
))
}
}
}
callback
&&
callback
(
result
)
},
async
checkSuperior
(
list
,
anotherTableIds
)
{
let
fieldValid
=
false
const
fieldId
=
this
.
myAttrs
?.
fieldId
...
...
src/views/panel/filter/filterMain/FilterHead.vue
查看文件 @
a752cff5
...
...
@@ -25,6 +25,7 @@
:key=
"item.id"
:item=
"item"
:index=
"index"
:tool-tip=
"getTableName(item.tableId)"
@
closeItem=
"closeItem"
/>
...
...
@@ -70,7 +71,12 @@ export default {
},
methods
:
{
getTableName
(
tableId
)
{
let
tableName
=
null
this
.
$emit
(
'dataset-name'
,
tableId
,
t
=>
{
tableName
=
t
})
console
.
log
(
tableName
)
return
tableName
},
onMove
(
e
,
originalEvent
)
{
return
true
},
...
...
src/views/panel/list/PanelList.vue
查看文件 @
a752cff5
...
...
@@ -670,7 +670,10 @@ export default {
if
(
this
.
editPanel
.
optType
===
'toDefaultPanel'
)
{
this
.
defaultTree
(
false
)
}
updateCacheTree
(
this
.
editPanel
.
optType
,
'panel-main-tree'
,
panelInfo
,
this
.
tData
)
updateCacheTree
(
this
.
editPanel
.
optType
,
panelInfo
.
panelType
===
'system'
?
'panel-default-tree'
:
'panel-main-tree'
,
panelInfo
,
panelInfo
.
panelType
===
'system'
?
this
.
defaultData
:
this
.
tData
)
if
(
this
.
editPanel
.
optType
===
'rename'
&&
panelInfo
.
id
===
this
.
$store
.
state
.
panel
.
panelInfo
.
id
)
{
this
.
$store
.
state
.
panel
.
panelInfo
.
name
=
panelInfo
.
name
}
...
...
@@ -850,7 +853,7 @@ export default {
delete
(
data
)
{
const
params
=
{
title
:
data
.
nodeType
===
'folder'
?
'commons.delete_this_folder'
:
'commons.delete_this_dashboard'
,
title
:
data
.
nodeType
===
'folder'
?
'commons.delete_this_folder'
:
'commons.delete_this_dashboard'
,
type
:
'danger'
,
cb
:
()
=>
{
delGroup
(
data
.
id
).
then
((
response
)
=>
{
...
...
src/views/panel/list/PanelViewShow.vue
查看文件 @
a752cff5
...
...
@@ -249,6 +249,7 @@
<Preview
v-if=
"showMainFlag"
ref=
"paneViewPreviewRef"
:class=
"fullscreen && 'fullscreen-visual-selects'"
:component-data=
"mainCanvasComponentData"
:canvas-style-data=
"canvasStyleData"
:active-tab=
"activeTab"
...
...
@@ -923,5 +924,12 @@ export default {
color
:
inherit
;
margin-right
:
5px
;
}
.fullscreen-visual-selects
{
.VisualSelects
{
top
:
inherit
!important
;
left
:
inherit
!important
;
}
}
</
style
>
src/views/system/user/index.vue
查看文件 @
a752cff5
...
...
@@ -202,7 +202,7 @@
<!-- //
{{}}
会将数据解释为普通文本,而非 HTML 代码。 -->
<div
slot=
"content"
v-html=
"
filterRoles(scope.row.roles
)"
v-html=
"
$xss(filterRoles(scope.row.roles)
)"
/>
<div
class=
"de-one-line"
>
{{
filterRoles
(
scope
.
row
.
roles
)
}}
</div>
</el-tooltip>
...
...
src/views/wizard/WizardCard.vue
查看文件 @
a752cff5
...
...
@@ -9,7 +9,7 @@
{{
details
.
head
}}
</el-row>
<el-row
class=
"card_content"
>
<span
v-html=
"
details.content
"
/>
<span
v-html=
"
$xss(details.content)
"
/>
</el-row>
<el-row
class=
"card_bottom"
>
{{
$t
(
'wizard.click_show'
)
}}
...
...
src/views/wizard/WizardCardEnterprise.vue
查看文件 @
a752cff5
...
...
@@ -9,7 +9,7 @@
{{
details
.
head
}}
</el-row>
<el-row
class=
"card_content"
>
<span
v-html=
"
details.content
"
/>
<span
v-html=
"
$xss(details.content)
"
/>
</el-row>
<el-row
class=
"card_bottom"
>
{{
$t
(
'wizard.apply'
)
}}
...
...
src/views/wizard/details/CardDetail.vue
查看文件 @
a752cff5
...
...
@@ -18,7 +18,7 @@
<span>
{{
details
.
head
}}
</span>
</el-row>
<el-row
class=
"content"
>
<span
v-html=
"
details.content
"
/>
<span
v-html=
"
$xss(details.content)
"
/>
</el-row>
<el-row
class=
"bottom"
>
<span
class=
"span-box"
>
{{
details
.
bottom
}}
</span>
...
...
src/views/wizard/details/LatestDevelopments.vue
查看文件 @
a752cff5
...
...
@@ -18,7 +18,7 @@
<span>
{{
details
.
head
}}
</span>
</el-row>
<el-row
class=
"content"
>
<span
v-html=
"
details.content
"
/>
<span
v-html=
"
$xss(details.content)
"
/>
</el-row>
<el-row
class=
"bottom"
>
<span
class=
"span-box"
>
{{
details
.
bottom
}}
</span>
...
...
vue.config.js
查看文件 @
a752cff5
"use strict"
;
const
path
=
require
(
"path"
);
const
defaultSettings
=
require
(
"./src/settings.js"
);
'use strict'
const
path
=
require
(
'path'
)
const
defaultSettings
=
require
(
'./src/settings.js'
)
const
pkg
=
require
(
"./package.json"
);
const
pkg
=
require
(
'./package.json'
)
const
CopyWebpackPlugin
=
require
(
"copy-webpack-plugin"
);
const
CopyWebpackPlugin
=
require
(
'copy-webpack-plugin'
)
// const CompressionPlugin = require('compression-webpack-plugin')
const
webpack
=
require
(
"webpack"
);
const
AddAssetHtmlPlugin
=
require
(
"add-asset-html-webpack-plugin"
);
const
webpack
=
require
(
'webpack'
)
const
AddAssetHtmlPlugin
=
require
(
'add-asset-html-webpack-plugin'
)
function
resolve
(
dir
)
{
return
path
.
join
(
__dirname
,
dir
)
;
return
path
.
join
(
__dirname
,
dir
)
}
const
name
=
defaultSettings
.
title
||
"vue Admin Template"
;
// page title
const
name
=
defaultSettings
.
title
||
'vue Admin Template'
// page title
const
port
=
process
.
env
.
port
||
process
.
env
.
npm_config_port
||
9528
;
// dev port
const
parallel
=
process
.
env
.
NODE_ENV
===
"development"
;
const
port
=
process
.
env
.
port
||
process
.
env
.
npm_config_port
||
9528
// dev port
const
parallel
=
process
.
env
.
NODE_ENV
===
'development'
module
.
exports
=
{
productionSourceMap
:
true
,
parallel
,
...
...
@@ -23,78 +23,76 @@ module.exports = {
devServer
:
{
port
:
port
,
proxy
:
{
"^(?!/login)"
:
{
target
:
"http://192.168.1.100:8081/"
,
ws
:
true
,
}
,
'^(?!/login)'
:
{
target
:
'http://localhost:8081/'
,
ws
:
true
}
},
open
:
true
,
overlay
:
{
warnings
:
false
,
errors
:
true
,
}
,
errors
:
true
}
},
pages
:
{
index
:
{
entry
:
"src/main.js"
,
template
:
"public/index.html"
,
filename
:
"index.html"
,
}
,
entry
:
'src/main.js'
,
template
:
'public/index.html'
,
filename
:
'index.html'
}
},
configureWebpack
:
{
name
:
name
,
devtool
:
"source-map"
,
devtool
:
'source-map'
,
resolve
:
{
alias
:
{
"@"
:
resolve
(
"src"
),
},
'@'
:
resolve
(
'src'
)
}
},
output
:
process
.
env
.
NODE_ENV
===
'development'
?
{}
:
{
filename
:
`js/[name].[contenthash:8].
${
pkg
.
version
}
.js`
,
publicPath
:
'/'
,
chunkFilename
:
`js/[name].[contenthash:8].
${
pkg
.
version
}
.js`
},
output
:
process
.
env
.
NODE_ENV
===
"development"
?
{}
:
{
filename
:
`js/[name].[contenthash:8].
${
pkg
.
version
}
.js`
,
publicPath
:
"/"
,
chunkFilename
:
`js/[name].[contenthash:8].
${
pkg
.
version
}
.js`
,
},
plugins
:
[
new
CopyWebpackPlugin
([
{
from
:
path
.
join
(
__dirname
,
"static"
),
to
:
path
.
join
(
__dirname
,
"dist/static"
),
}
,
from
:
path
.
join
(
__dirname
,
'static'
),
to
:
path
.
join
(
__dirname
,
'dist/static'
)
}
]),
new
webpack
.
DllReferencePlugin
({
context
:
process
.
cwd
(),
manifest
:
require
(
"./public/vendor/vendor-manifest.json"
),
manifest
:
require
(
'./public/vendor/vendor-manifest.json'
)
}),
// 将 dll 注入到 生成的 html 模板中
new
AddAssetHtmlPlugin
({
// dll文件位置
filepath
:
path
.
resolve
(
__dirname
,
"./public/vendor/*.js"
),
filepath
:
path
.
resolve
(
__dirname
,
'./public/vendor/*.js'
),
// dll 引用路径
publicPath
:
"./vendor"
,
publicPath
:
'./vendor'
,
// dll最终输出的目录
outputPath
:
"./vendor"
,
})
,
]
,
outputPath
:
'./vendor'
})
]
},
chainWebpack
:
(
config
)
=>
{
config
.
module
.
rules
.
delete
(
"svg"
);
// 删除默认配置中处理svg,
chainWebpack
:
config
=>
{
config
.
module
.
rules
.
delete
(
'svg'
)
// 删除默认配置中处理svg,
// const svgRule = config.module.rule('svg')
// svgRule.uses.clear()
config
.
module
.
rule
(
"svg-sprite-loader"
)
.
rule
(
'svg-sprite-loader'
)
.
test
(
/
\.
svg$/
)
.
include
.
add
(
resolve
(
"src/icons"
))
// 处理svg目录
.
include
.
add
(
resolve
(
'src/icons'
))
// 处理svg目录
.
end
()
.
use
(
"svg-sprite-loader"
)
.
loader
(
"svg-sprite-loader"
)
.
use
(
'svg-sprite-loader'
)
.
loader
(
'svg-sprite-loader'
)
.
options
({
symbolId
:
"icon-[name]"
,
})
;
if
(
process
.
env
.
NODE_ENV
===
"production"
)
{
symbolId
:
'icon-[name]'
})
if
(
process
.
env
.
NODE_ENV
===
'production'
)
{
/* config.plugin('compressionPlugin').use(new CompressionPlugin({
test: /\.(js|css|less)$/, // 匹配文件名
threshold: 10240, // 对超过10k的数据压缩
...
...
@@ -104,24 +102,25 @@ module.exports = {
}
config
.
module
.
rule
(
"icons"
)
.
rule
(
'icons'
)
.
test
(
/
\.
svg$/
)
.
include
.
add
(
resolve
(
"src/deicons"
))
.
include
.
add
(
resolve
(
'src/deicons'
))
.
end
()
.
use
(
"svg-sprite-loader"
)
.
loader
(
"svg-sprite-loader"
)
.
use
(
'svg-sprite-loader'
)
.
loader
(
'svg-sprite-loader'
)
.
options
({
symbolId
:
"[name]"
,
})
;
symbolId
:
'[name]'
})
},
css
:
{
loaderOptions
:
{
sass
:
{
prependData
:
`@import "@/style/index.scss"`
,
}
,
prependData
:
`@import "@/style/index.scss"`
}
},
extract
:
{
ignoreOrder
:
true
,
},
},
};
ignoreOrder
:
true
}
}
}
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论