Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
O
on-site-service-admin-view
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
external
on-site-service-admin-view
Commits
c7afe541
Commit
c7afe541
authored
Aug 11, 2022
by
shangtx
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
chore: wangeditor v5 版本
parent
b54bf3c1
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
141 additions
and
313 deletions
+141
-313
richtext-editor.vue
src/components/richtext/richtext-editor.vue
+70
-162
ServiceList.vue
src/views/serv/ServiceList.vue
+71
-151
No files found.
src/components/richtext/richtext-editor.vue
View file @
c7afe541
<!--
基于wangEditor的vue的富文本编辑器,请通过组件的ref直接设置和获取富文本内容
由于wangEditor本身的特性(也许是bug),通过双向绑定和回调函数的方式直接修改外部的内容变量会引发末尾回车键失效的问题
文档地址 https://www.wangeditor.com/doc/
-->
<
template
>
<
template
>
<a-spin
:spinning=
"loading"
>
<!--
<a-spin
:spinning=
"loading"
>
-->
<div
class=
"wangeditor-atkj-wrapper"
:id=
"id"
></div>
<div
class=
"wangeditor-atkj-wrapper"
>
</a-spin>
<div
id=
"wangeditor-toolbar-container"
></div>
<div
id=
"wangeditor-editor-container"
:style=
"
{ height: `${height}px` }"
>
</div>
</div>
<!--
</a-spin>
-->
</
template
>
</
template
>
<
script
>
<
script
>
// 引入 wangEditor
// 引入 wangEditor
import
wangEditor
from
'wangeditor'
import
{
createEditor
,
createToolbar
}
from
'@wangeditor/editor'
import
'@wangeditor/editor/dist/css/style.css'
export
default
{
export
default
{
name
:
'RichTextEditor'
,
name
:
'RichTextEditor'
,
props
:
{
props
:
{
id
:
{
type
:
String
,
default
:
()
=>
'wangeditor-atkj-wrapper-default-id'
},
height
:
{
height
:
{
type
:
Number
,
type
:
Number
,
default
:
()
=>
300
default
:
()
=>
300
...
@@ -37,6 +35,7 @@ export default {
...
@@ -37,6 +35,7 @@ export default {
data
()
{
data
()
{
return
{
return
{
editor
:
null
,
editor
:
null
,
toolbar
:
null
,
loading
:
false
loading
:
false
}
}
},
},
...
@@ -45,173 +44,82 @@ export default {
...
@@ -45,173 +44,82 @@ export default {
this
.
editor
=
null
this
.
editor
=
null
},
},
mounted
()
{
mounted
()
{
if
(
this
.
editor
!=
null
)
{
const
editorConfig
=
{
return
MENU_CONF
:
{}
}
this
.
init
()
},
activated
()
{
if
(
this
.
editor
!=
null
)
{
return
}
}
this
.
init
()
// const token = sessionStorage.getItem('Access-Token')
// 上传图片设置
// editorConfig.MENU_CONF['uploadImage'] = {
// server: `${process.env.VUE_APP_URL}upload?fileType=IMG`,
// timeout: 5000,
// fieldName: 'files',
// headers: { Authorization: token },
// customInsert: function (result, insertImgFn) {
// insertImgFn(result.data.urls[0])
// }
// }
// editorConfig.MENU_CONF['uploadVideo'] = {
// server: `${process.env.VUE_APP_URL}upload?fileType=VIDEO`,
// timeout: 5000,
// fieldName: 'files',
// headers: { Authorization: token },
// onBeforeUpload() {
// this.loading = true
// },
// onFailed() {
// this.loading = false
// },
// onError() {
// this.loading = false
// },
// customInsert(res, insertFn) {
// if (res.code == 200) {
// insertFn(res.data.urls[0])
// } else {
// this.$message.error('上传失败')
// this.loading = false
// }
// }
// }
const
editor
=
createEditor
({
selector
:
`#wangeditor-editor-container`
,
config
:
editorConfig
,
mode
:
'default'
})
createToolbar
({
editor
:
editor
,
selector
:
`#wangeditor-toolbar-container`
,
config
:
{},
mode
:
'default'
})
this
.
editor
=
editor
},
},
methods
:
{
methods
:
{
// 设置内容
// 设置内容
setContent
(
v
)
{
setContent
(
v
)
{
this
.
editor
.
txt
.
h
tml
(
v
)
this
.
editor
.
setH
tml
(
v
)
},
},
// 获取内容
// 获取内容
getContent
()
{
getContent
()
{
return
this
.
editor
.
txt
.
h
tml
()
return
this
.
editor
.
getH
tml
()
},
},
// 清空内容
// 清空内容
clear
()
{
clear
()
{
this
.
editor
.
txt
.
clear
()
this
.
editor
.
clear
()
},
init
()
{
const
_this
=
this
const
editor
=
new
wangEditor
(
`.wangeditor-atkj-wrapper#
${
this
.
id
}
`
)
// 配置 onchange 回调函数,将数据同步到 vue 中
editor
.
config
.
showLinkImg
=
false
//关闭网络路径图片方式
editor
.
config
.
uploadImgServer
=
`
${
process
.
env
.
VUE_APP_URL
}
upload?fileType=IMG`
editor
.
config
.
uploadFileName
=
'files'
// formdata中的name属性
var
token
=
''
if
(
this
.
isSessionStorage
)
{
token
=
sessionStorage
.
getItem
(
'Access-Token'
)
}
else
{
token
=
localStorage
.
getItem
(
'Access-Token'
)
}
editor
.
config
.
uploadImgHeaders
=
{
// 设置请求头
Authorization
:
token
// 设置请求头
}
// 设置高度
editor
.
config
.
height
=
this
.
height
editor
.
config
.
uploadVideoServer
=
`
${
process
.
env
.
VUE_APP_URL
}
upload?fileType=VIDEO`
editor
.
config
.
uploadVideoName
=
'files'
editor
.
config
.
uploadVideoHeaders
=
{
Authorization
:
localStorage
.
getItem
(
'token'
)
// 设置请求头
}
editor
.
config
.
uploadVideoMaxSize
=
1024
*
this
.
videoSizeLimit
editor
.
config
.
zIndex
=
0
editor
.
config
.
uploadImgHooks
=
{
// 图片上传并返回结果,但图片插入错误时触发
fail
:
function
(
xhr
,
editor
,
result
)
{
console
.
error
(
'richTextError'
,
result
)
},
// eslint-disable-next-line no-unused-vars
success
:
function
(
xhr
,
editor
,
result
)
{
// 图片上传并返回结果,图片插入成功之后触发
},
/**
* insertImgFn 可把图片插入到编辑器,传入图片 src ,执行函数即可
* result 即服务端返回的接口
*/
customInsert
:
function
(
insertImgFn
,
result
)
{
insertImgFn
(
result
.
data
.
urls
[
0
])
}
}
editor
.
config
.
uploadVideoHooks
=
{
// 视频上传并返回了结果,想要自己把视频插入到编辑器中
// 例如服务器端返回的不是 { errno: 0, data: { url : '.....'} } 这种格式,可使用 customInsert
customInsert
:
function
(
insertVideoFn
,
result
)
{
// result 即服务端返回的接口
// insertVideoFn 可把视频插入到编辑器,传入视频 src ,执行函数即可
if
(
result
.
code
==
200
)
{
insertVideoFn
(
result
.
data
.
urls
[
0
])
}
else
{
_this
.
$message
.
error
(
'上传失败'
)
_this
.
loading
=
false
}
},
before
()
{
_this
.
loading
=
true
},
fail
()
{
_this
.
loading
=
false
},
// 上传视频出错,一般为 http 请求的错误
error
()
{
_this
.
loading
=
false
},
// 上传视频超时
timeout
()
{
_this
.
loading
=
false
}
}
// 自定义插入视频, 主要用来处理loading状态
editor
.
config
.
customInsertVideo
=
function
(
url
)
{
const
videoElement
=
document
.
createElement
(
'video'
)
videoElement
.
setAttribute
(
'controls'
,
'controls'
)
videoElement
.
setAttribute
(
'style'
,
'max-width:100%'
)
videoElement
.
setAttribute
(
'src'
,
url
)
// 4、loadeddata:视频下载监听。当当前帧的数据已加载,但没有足够的数据来播放指定音频/视频的下一帧时触发
// eslint-disable-next-line no-unused-vars
videoElement
.
addEventListener
(
'loadeddata'
,
function
(
e
)
{
_this
.
loading
=
false
})
/**
* 此处参考
* https://github.com/wangeditor-team/wangEditor/blob/master/src/editor/command.ts insertElem
*/
const
range
=
editor
.
selection
.
getRange
()
if
(
range
==
null
)
return
if
(
range
.
insertNode
)
{
range
.
insertNode
(
videoElement
)
}
}
// 内容change
// eslint-disable-next-line no-unused-vars
editor
.
config
.
onchange
=
(
_newHtml
)
=>
{}
// 创建编辑器
editor
.
create
()
this
.
editor
=
editor
}
}
},
}
// beforeDestroy() {
// 调用销毁 API 对当前编辑器实例进行销毁
// }
}
}
</
script
>
</
script
>
<
style
lang=
"less"
>
<
style
lang=
"less"
>
.wangeditor-atkj-wrapper {
.wangeditor-atkj-wrapper {
.home {
border: 1px solid rgb(243, 243, 243);
width: 1200px;
z-index: 100; /* 按需定义 */
margin: auto;
.wangeditor-toolbar-container {
position: relative;
border-bottom: 1px solid #ccc;
}
.home .btn {
position: absolute;
right: 0;
top: 0;
padding: 5px 10px;
cursor: pointer;
}
.home h3 {
margin: 30px 0 15px;
}
.w-e-text-container {
border: 1px solid #c9d8db;
border-top: none;
z-index: 25;
}
.w-e-toolbar {
z-index: 28 !important;
}
}
}
}
</
style
>
</
style
>
src/views/serv/ServiceList.vue
View file @
c7afe541
<
template
>
<
template
>
<table-template
:soul=
"this"
>
<a-spin
:spinning=
"loading"
>
<template
#
action=
"
{ record }">
<div
class=
"wangeditor-atkj-wrapper"
>
<a-space>
<div
id=
"wangeditor-toolbar-container"
></div>
<template
v-if=
"record.type == 1"
>
<div
id=
"wangeditor-editor-container"
></div>
<a
@
click=
"add(record)"
>
添加服务项
</a>
</div>
<a
@
click=
"editCategory(record)"
>
修改信息
</a>
</a-spin>
</
template
>
<
template
v-if=
"record.type == 2"
>
<a
@
click=
"edit(record)"
>
修改信息
</a>
</
template
>
</a-space>
</template>
<
template
#
enable=
"{ record, index }"
>
<a-switch
v-if=
"hasPerm('SYS0210101.ENABLE') && record.type == 2"
:checked=
"record.enabled"
checked-children=
"启用"
un-checked-children=
"禁用"
:loading=
"loadingKeys.includes(record.id)"
@
click=
"enableChange(record, index)"
/>
</
template
>
<
template
#
showInHome=
"{ record, index }"
>
<a-switch
v-if=
"hasPerm('SYS0210101.ENABLE') && record.type == 2"
:checked=
"record.showInHome"
checked-children=
"展示"
un-checked-children=
"隐藏"
:loading=
"showInHomeLoadingKeys.includes(record.id)"
@
click=
"showInHomeChange(record, index)"
/>
</
template
>
<
template
#
free
>
<SubClassEdit
ref=
"SubClassEdit"
:success=
"reset"
/>
<CategoryEdit
ref=
"CategoryEdit"
:success=
"reset"
/>
</
template
>
</table-template>
</
template
>
</
template
>
<
script
>
<
script
>
import
{
TableTemplate
,
TableScript
,
SearchType
}
from
'@/components/table'
import
{
createEditor
,
createToolbar
}
from
'@wangeditor/editor'
import
{
getCategoryList
,
saveOrUpdateSubClass
}
from
'@/api/serv'
import
'@wangeditor/editor/dist/css/style.css'
import
SubClassEdit
from
'./SubClassEdit.vue'
import
CategoryEdit
from
'./CategoryEdit.vue'
import
dayjs
from
'dayjs'
const
columns
=
[
{
title
:
'名称'
,
dataIndex
:
'serviceName'
},
{
title
:
'排序号'
,
width
:
130
,
dataIndex
:
'sequence'
},
{
title
:
'是否启用'
,
scopedSlots
:
{
customRender
:
'enable'
},
enum
:
'SYS0002'
,
dataIndex
:
'enabled'
,
filter
:
{
type
:
SearchType
.
ENUM
}
},
{
title
:
'首页展示'
,
scopedSlots
:
{
customRender
:
'showInHome'
},
enum
:
'SYS0002'
,
dataIndex
:
'showInHome'
,
filter
:
{
type
:
SearchType
.
ENUM
}
},
{
title
:
'创建时间'
,
dataIndex
:
'createTime'
,
width
:
200
,
sorter
:
true
,
customRender
:
(
text
)
=>
dayjs
(
text
).
format
(
'YYYY-MM-DD HH:mm:ss'
)
},
{
title
:
'操作'
,
scopedSlots
:
{
customRender
:
'action'
},
width
:
190
}
]
export
default
{
export
default
{
name
:
'ServiceList'
,
name
:
'ServiceList'
,
mixins
:
[
TableScript
,
{}],
components
:
{
TableTemplate
,
SubClassEdit
,
CategoryEdit
},
data
()
{
data
()
{
return
{
return
{
columns
,
loading
:
false
useYScroll
:
true
,
title
:
'服务管理'
,
pagination
:
false
,
codes
:
[[
'SYS0002'
],
[]],
loadingKeys
:
[],
showInHomeLoadingKeys
:
[],
rowKey
:
'key'
}
}
},
},
methods
:
{
methods
:
{},
queryData
:
getCategoryList
,
mounted
()
{
loadSuccess
()
{
const
editorConfig
=
{
this
.
expandedRowKeys
=
this
.
dataSource
.
map
((
d
)
=>
d
.
id
+
''
)
MENU_CONF
:
{}
},
}
enableChange
(
record
,
index
)
{
const
token
=
sessionStorage
.
getItem
(
'Access-Token'
)
if
(
this
.
loadingKeys
.
includes
(
record
.
id
))
{
// 上传图片设置
return
editorConfig
.
MENU_CONF
[
'uploadImage'
]
=
{
server
:
`
${
process
.
env
.
VUE_APP_URL
}
upload?fileType=IMG`
,
timeout
:
5000
,
fieldName
:
'files'
,
headers
:
{
Authorization
:
token
},
customInsert
:
function
(
result
,
insertImgFn
)
{
insertImgFn
(
result
.
data
.
urls
[
0
])
}
}
this
.
loadingKeys
.
push
(
record
.
id
)
}
saveOrUpdateSubClass
({
id
:
record
.
id
,
enabled
:
!
record
.
enabled
})
.
then
(({
code
})
=>
{
editorConfig
.
MENU_CONF
[
'uploadVideo'
]
=
{
if
(
code
==
200
)
{
server
:
`
${
process
.
env
.
VUE_APP_URL
}
upload?fileType=VIDEO`
,
this
.
$message
.
success
(
'保存成功'
)
timeout
:
5000
,
const
pIndex
=
this
.
dataSource
.
findIndex
(
fieldName
:
'files'
,
(
d
)
=>
d
.
id
==
record
.
categoryId
headers
:
{
Authorization
:
token
},
)
onBeforeUpload
()
{
this
.
dataSource
[
pIndex
].
children
[
index
].
enabled
=
!
record
.
enabled
// _this.loading = true
}
},
})
onFailed
()
{
.
finally
(()
=>
{
// _this.loading = false
this
.
loadingKeys
.
splice
(
this
.
loadingKeys
.
indexOf
(
record
.
id
),
1
)
},
})
onError
()
{
},
// _this.loading = false
showInHomeChange
(
record
,
index
)
{
},
if
(
this
.
loadingKeys
.
includes
(
record
.
id
))
{
customInsert
(
res
,
insertFn
)
{
return
if
(
res
.
code
==
200
)
{
insertFn
(
res
.
data
.
urls
[
0
])
}
else
{
this
.
$message
.
error
(
'上传失败'
)
// _this.loading = false
}
}
}
this
.
showInHomeLoadingKeys
.
push
(
record
.
id
)
saveOrUpdateSubClass
({
id
:
record
.
id
,
showInHome
:
!
record
.
showInHome
})
.
then
(({
code
})
=>
{
if
(
code
==
200
)
{
this
.
$message
.
success
(
'保存成功'
)
const
pIndex
=
this
.
dataSource
.
findIndex
(
(
d
)
=>
d
.
id
==
record
.
categoryId
)
this
.
dataSource
[
pIndex
].
children
[
index
].
showInHome
=
!
record
.
showInHome
}
})
.
finally
(()
=>
{
this
.
showInHomeLoadingKeys
.
splice
(
this
.
showInHomeLoadingKeys
.
indexOf
(
record
.
id
),
1
)
})
},
edit
(
record
)
{
const
categoryName
=
this
.
dataSource
.
filter
(
(
d
)
=>
d
.
id
==
record
.
categoryId
)[
0
].
serviceName
this
.
$refs
.
SubClassEdit
.
show
({
id
:
record
.
id
,
categoryId
:
record
.
categoryId
,
categoryName
})
},
add
(
record
)
{
this
.
$refs
.
SubClassEdit
.
show
({
id
:
null
,
categoryId
:
record
.
id
,
categoryName
:
record
.
serviceName
})
},
editCategory
(
record
)
{
this
.
$refs
.
CategoryEdit
.
show
(
record
.
id
)
}
}
const
editor
=
createEditor
({
selector
:
`#wangeditor-editor-container`
,
config
:
editorConfig
,
mode
:
'default'
})
createToolbar
({
editor
:
editor
,
selector
:
`#wangeditor-toolbar-container`
,
config
:
{},
mode
:
'default'
})
}
}
</
script
>
<
style
lang=
"less"
>
.wangeditor-atkj-wrapper {
border: 1px solid rgb(243, 243, 243);
z-index: 100; /* 按需定义 */
#wangeditor-toolbar-container {
border-bottom: 1px solid rgb(235, 235, 235);
}
#wangeditor-editor-container {
height: 800px;
}
}
}
}
</
script
>
</
style
>
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment