Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
phsl
/
admin
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
813e7d27
authored
Apr 14, 2023
by
dhb52
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
refactor: 使用Editor组件替换WxEditor
parent
f25a4d73
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
310 additions
and
378 deletions
+310
-378
src/components/Editor/src/Editor.vue
+2
-1
src/views/mp/components/wx-editor/WxEditor.vue
+0
-104
src/views/mp/components/wx-editor/quill-options.js
+0
-45
src/views/mp/draft/editor-config.ts
+72
-0
src/views/mp/draft/index.vue
+236
-228
No files found.
src/components/Editor/src/Editor.vue
View file @
813e7d27
...
@@ -20,7 +20,7 @@ const props = defineProps({
...
@@ -20,7 +20,7 @@ const props = defineProps({
editorId
:
propTypes
.
string
.
def
(
'wangeEditor-1'
),
editorId
:
propTypes
.
string
.
def
(
'wangeEditor-1'
),
height
:
propTypes
.
oneOfType
([
Number
,
String
]).
def
(
'500px'
),
height
:
propTypes
.
oneOfType
([
Number
,
String
]).
def
(
'500px'
),
editorConfig
:
{
editorConfig
:
{
type
:
Object
as
PropType
<
IEditorConfig
>
,
type
:
Object
as
PropType
<
Partial
<
IEditorConfig
>
>
,
default
:
()
=>
undefined
default
:
()
=>
undefined
},
},
readonly
:
propTypes
.
bool
.
def
(
false
),
readonly
:
propTypes
.
bool
.
def
(
false
),
...
@@ -147,6 +147,7 @@ const editorConfig = computed((): IEditorConfig => {
...
@@ -147,6 +147,7 @@ const editorConfig = computed((): IEditorConfig => {
props
.
editorConfig
||
{}
props
.
editorConfig
||
{}
)
)
})
})
const
editorStyle
=
computed
(()
=>
{
const
editorStyle
=
computed
(()
=>
{
return
{
return
{
height
:
isNumber
(
props
.
height
)
?
`
${
props
.
height
}
px`
:
props
.
height
height
:
isNumber
(
props
.
height
)
?
`
${
props
.
height
}
px`
:
props
.
height
...
...
src/views/mp/components/wx-editor/WxEditor.vue
deleted
100644 → 0
View file @
f25a4d73
<
script
setup
>
import
{
ref
,
reactive
}
from
'vue'
import
{
getAccessToken
}
from
'@/utils/auth'
import
{
Editor
}
from
'@/components/Editor'
const
BASE_URL
=
import
.
meta
.
env
.
VITE_BASE_URL
const
actionUrl
=
BASE_URL
+
'/admin-api/mp/material/upload-news-image'
// 这里写你要上传的图片服务器地址
const
headers
=
{
Authorization
:
'Bearer '
+
getAccessToken
()
}
// 设置上传的请求头部
const
message
=
useMessage
()
const
props
=
defineProps
({
/* 公众号账号编号 */
accountId
:
{
type
:
Number
,
required
:
true
},
/* 编辑器的内容 */
value
:
{
type
:
String
,
default
:
''
},
/* 图片大小 */
maxSize
:
{
type
:
Number
,
default
:
4000
// kb
}
})
const
emit
=
defineEmits
([
'input'
])
const
myQuillEditorRef
=
ref
()
const
content
=
ref
(
props
.
value
.
replace
(
/data-src/g
,
'src'
))
const
loading
=
ref
(
false
)
// 根据图片上传状态来确定是否显示loading动画,刚开始是false,不显示
const
uploadData
=
reactive
({
type
:
'image'
,
// TODO 芋艿:试试要不要换成 thumb
accountId
:
props
.
accountId
})
const
onEditorChange
=
(
text
)
=>
{
//内容改变事件
emit
(
'input'
,
text
)
}
// 富文本图片上传前
const
beforeUpload
=
()
=>
{
// 显示 loading 动画
loading
.
value
=
true
}
// 图片上传成功
// 注意!由于微信公众号的图片有访问限制,所以会显示“此图片来自微信公众号,未经允许不可引用”
const
uploadSuccess
=
(
res
)
=>
{
// res为图片服务器返回的数据
// 获取富文本组件实例
const
quill
=
myQuillEditorRef
.
value
.
quill
// 如果上传成功
const
link
=
res
.
data
if
(
link
)
{
// 获取光标所在位置
let
length
=
quill
.
getSelection
().
index
// 插入图片 res.info为服务器返回的图片地址
quill
.
insertEmbed
(
length
,
'image'
,
link
)
// 调整光标到最后
quill
.
setSelection
(
length
+
1
)
}
else
{
message
.
error
(
'图片插入失败'
)
}
// loading 动画消失
loading
.
value
=
false
}
// 富文本图片上传失败
const
uploadError
=
()
=>
{
// loading 动画消失
loading
.
value
=
false
message
.
error
(
'图片插入失败'
)
}
</
script
>
<
template
>
<div
id=
"wxEditor"
>
<div
v-loading=
"loading"
element-loading-text=
"请稍等,图片上传中"
>
<!-- 图片上传组件辅助-->
<el-upload
class=
"avatar-uploader"
name=
"file"
:action=
"actionUrl"
:headers=
"headers"
:show-file-list=
"false"
:data=
"uploadData"
:on-success=
"uploadSuccess"
:on-error=
"uploadError"
:before-upload=
"beforeUpload"
/>
<Editor
editor-id=
"wxEditor"
ref=
"quillEditorRef"
:modelValue=
"content"
@
change=
"(editor) => onEditorChange(editor.getText())"
/>
</div>
</div>
</
template
>
src/views/mp/components/wx-editor/quill-options.js
deleted
100644 → 0
View file @
f25a4d73
const
toolbarOptions
=
[
[
'bold'
,
'italic'
,
'underline'
,
'strike'
],
// 加粗 斜体 下划线 删除线
[
'blockquote'
,
'code-block'
],
// 引用 代码块
[{
header
:
1
},
{
header
:
2
}],
// 1、2 级标题
[{
list
:
'ordered'
},
{
list
:
'bullet'
}],
// 有序、无序列表
[{
script
:
'sub'
},
{
script
:
'super'
}],
// 上标/下标
[{
indent
:
'-1'
},
{
indent
:
'+1'
}],
// 缩进
// [{'direction': 'rtl'}], // 文本方向
[{
size
:
[
'small'
,
false
,
'large'
,
'huge'
]
}],
// 字体大小
[{
header
:
[
1
,
2
,
3
,
4
,
5
,
6
,
false
]
}],
// 标题
[{
color
:
[]
},
{
background
:
[]
}],
// 字体颜色、字体背景颜色
[{
font
:
[]
}],
// 字体种类
[{
align
:
[]
}],
// 对齐方式
[
'clean'
],
// 清除文本格式
[
'link'
,
'image'
,
'video'
]
// 链接、图片、视频
]
export
default
{
theme
:
'snow'
,
placeholder
:
'请输入文章内容'
,
modules
:
{
toolbar
:
{
container
:
toolbarOptions
,
// container: "#toolbar",
handlers
:
{
image
:
function
(
value
)
{
if
(
value
)
{
// 触发input框选择图片文件
document
.
querySelector
(
'.avatar-uploader input'
).
click
()
}
else
{
this
.
quill
.
format
(
'image'
,
false
)
}
},
link
:
function
(
value
)
{
if
(
value
)
{
const
href
=
prompt
(
'注意!只支持公众号图文链接'
)
this
.
quill
.
format
(
'link'
,
href
)
}
else
{
this
.
quill
.
format
(
'link'
,
false
)
}
}
}
}
}
}
src/views/mp/draft/editor-config.ts
0 → 100644
View file @
813e7d27
import
{
IEditorConfig
}
from
'@wangeditor/editor'
import
{
getAccessToken
,
getTenantId
}
from
'@/utils/auth'
const
message
=
useMessage
()
type
InsertFnType
=
(
url
:
string
,
alt
:
string
,
href
:
string
)
=>
void
export
const
createEditorConfig
=
(
server
:
string
,
accountId
:
number
|
undefined
):
Partial
<
IEditorConfig
>
=>
{
return
{
MENU_CONF
:
{
[
'uploadImage'
]:
{
server
,
// 单个文件的最大体积限制,默认为 2M
maxFileSize
:
5
*
1024
*
1024
,
// 最多可上传几个文件,默认为 100
maxNumberOfFiles
:
10
,
// 选择文件时的类型限制,默认为 ['image/*'] 。如不想限制,则设置为 []
allowedFileTypes
:
[
'image/*'
],
// 自定义上传参数,例如传递验证的 token 等。参数会被添加到 formData 中,一起上传到服务端。
meta
:
{
accountId
:
accountId
},
// 将 meta 拼接到 url 参数中,默认 false
metaWithUrl
:
true
,
// 自定义增加 http header
headers
:
{
Accept
:
'*'
,
Authorization
:
'Bearer '
+
getAccessToken
(),
'tenant-id'
:
getTenantId
()
},
// 跨域是否传递 cookie ,默认为 false
withCredentials
:
true
,
// 超时时间,默认为 10 秒
timeout
:
5
*
1000
,
// 5 秒
// form-data fieldName,后端接口参数名称,默认值wangeditor-uploaded-image
fieldName
:
'file'
,
// 上传之前触发
onBeforeUpload
(
file
:
File
)
{
console
.
log
(
file
)
return
file
},
// 上传进度的回调函数
onProgress
(
progress
:
number
)
{
// progress 是 0-100 的数字
console
.
log
(
'progress'
,
progress
)
},
onSuccess
(
file
:
File
,
res
:
any
)
{
console
.
log
(
'onSuccess'
,
file
,
res
)
},
onFailed
(
file
:
File
,
res
:
any
)
{
message
.
alertError
(
res
.
message
)
console
.
log
(
'onFailed'
,
file
,
res
)
},
onError
(
file
:
File
,
err
:
any
,
res
:
any
)
{
message
.
alertError
(
err
.
message
)
console
.
error
(
'onError'
,
file
,
err
,
res
)
},
// 自定义插入图片
customInsert
(
res
:
any
,
insertFn
:
InsertFnType
)
{
insertFn
(
res
.
data
,
'image'
,
res
.
data
)
}
}
}
}
}
src/views/mp/draft/index.vue
View file @
813e7d27
...
@@ -71,168 +71,182 @@
...
@@ -71,168 +71,182 @@
<el-dialog
<el-dialog
:title=
"operateMaterial === 'add' ? '新建图文' : '修改图文'"
:title=
"operateMaterial === 'add' ? '新建图文' : '修改图文'"
width=
"80%"
width=
"80%"
top=
"20px"
v-model=
"dialogNewsVisible"
v-model=
"dialogNewsVisible"
:before-close=
"dialogNewsClose"
:before-close=
"dialogNewsClose"
:close-on-click-modal=
"false"
destroy-on-close
>
>
<div
class=
"left"
>
<el-container>
<div
class=
"select-item"
>
<el-aside
width=
"40%"
>
<div
v-for=
"(news, index) in articlesAdd"
:key=
"news.id"
>
<div
class=
"select-item"
>
<div
<div
v-for=
"(news, index) in articlesAdd"
:key=
"news.id"
>
class=
"news-main father"
<div
v-if=
"index === 0"
class=
"news-main father"
:class=
"{ activeAddNews: isActiveAddNews === index }"
v-if=
"index === 0"
@
click=
"activeNews(index)"
:class=
"{ activeAddNews: isActiveAddNews === index }"
>
@
click=
"activeNews(index)"
<div
class=
"news-content"
>
>
<img
class=
"material-img"
v-if=
"news.thumbUrl"
:src=
"news.thumbUrl"
/>
<div
class=
"news-content"
>
<div
class=
"news-content-title"
>
{{ news.title }}
</div>
<img
class=
"material-img"
v-if=
"news.thumbUrl"
:src=
"news.thumbUrl"
/>
</div>
<div
class=
"news-content-title"
>
{{ news.title }}
</div>
<div
class=
"child"
v-if=
"articlesAdd.length > 1"
>
</div>
<el-button
size=
"small"
@
click=
"downNews(index)"
<div
class=
"child"
v-if=
"articlesAdd.length > 1"
>
><Icon
icon=
"ep:sort-down"
/>
下移
</el-button
<el-button
size=
"small"
@
click=
"downNews(index)"
>
><Icon
icon=
"ep:sort-down"
/>
下移
</el-button
<el-button
v-if=
"operateMaterial === 'add'"
size=
"small"
@
click=
"minusNews(index)"
>
><Icon
icon=
"ep:delete"
/>
删除
<el-button
v-if=
"operateMaterial === 'add'"
size=
"small"
@
click=
"minusNews(index)"
</el-button>
><Icon
icon=
"ep:delete"
/>
删除
</div>
</el-button>
</div>
<div
class=
"news-main-item father"
v-if=
"index > 0"
:class=
"{ activeAddNews: isActiveAddNews === index }"
@
click=
"activeNews(index)"
>
<div
class=
"news-content-item"
>
<div
class=
"news-content-item-title"
>
{{ news.title }}
</div>
<div
class=
"news-content-item-img"
>
<img
class=
"material-img"
v-if=
"news.thumbUrl"
:src=
"news.thumbUrl"
height=
"100%"
/>
</div>
</div>
</div>
</div>
<div
class=
"child"
>
<div
<el-button
class=
"news-main-item father"
v-if=
"articlesAdd.length > index + 1"
v-if=
"index > 0"
size=
"small"
:class=
"{ activeAddNews: isActiveAddNews === index }"
@
click=
"downNews(index)"
@
click=
"activeNews(index)"
><Icon
icon=
"ep:sort-down"
/>
下移
>
</el-button>
<div
class=
"news-content-item"
>
<el-button
size=
"small"
@
click=
"upNews(index)"
<div
class=
"news-content-item-title"
>
{{ news.title }}
</div>
><Icon
icon=
"ep:sort-up"
/>
上移
</el-button
<div
class=
"news-content-item-img"
>
>
<img
<el-button
class=
"material-img"
v-if=
"operateMaterial === 'add'"
v-if=
"news.thumbUrl"
type=
"danger"
:src=
"news.thumbUrl"
size=
"small"
width=
"100%"
@
click=
"minusNews(index)"
/>
><Icon
icon=
"ep:delete"
/>
删除
</div>
</el-button>
</div>
<div
class=
"child"
>
<el-button
v-if=
"articlesAdd.length > index + 1"
size=
"small"
@
click=
"downNews(index)"
><Icon
icon=
"ep:sort-down"
/>
下移
</el-button>
<el-button
size=
"small"
@
click=
"upNews(index)"
><Icon
icon=
"ep:sort-up"
/>
上移
</el-button
>
<el-button
v-if=
"operateMaterial === 'add'"
type=
"danger"
size=
"small"
@
click=
"minusNews(index)"
><Icon
icon=
"ep:delete"
/>
删除
</el-button>
</div>
</div>
</div>
</div>
</div>
</div>
<el-row
justify=
"center"
class=
"ope-row"
>
<el-row
justify=
"center"
class=
"ope-row"
>
<el-button
<el-button
type=
"primary"
type=
"primary"
circle
circle
@
click=
"plusNews"
@
click=
"plusNews"
v-if=
"articlesAdd.length < 8 && operateMaterial === 'add'"
v-if=
"articlesAdd.length < 8 && operateMaterial === 'add'"
>
<Icon
icon=
"ep:plus"
/>
</el-button>
</el-row>
</div>
</div>
<div
class=
"right"
v-loading=
"addMaterialLoading"
v-if=
"articlesAdd.length > 0"
>
<br
/>
<br
/>
<br
/>
<br
/>
<!-- 标题、作者、原文地址 -->
<el-input
v-model=
"articlesAdd[isActiveAddNews].title"
placeholder=
"请输入标题(必填)"
/>
<el-input
v-model=
"articlesAdd[isActiveAddNews].author"
placeholder=
"请输入作者"
style=
"margin-top: 5px"
/>
<el-input
v-model=
"articlesAdd[isActiveAddNews].contentSourceUrl"
placeholder=
"请输入原文地址"
style=
"margin-top: 5px"
/>
<!-- 封面和摘要 -->
<div
class=
"input-tt"
>
封面和摘要:
</div>
<div>
<div
class=
"thumb-div"
>
<img
class=
"material-img"
v-if=
"articlesAdd[isActiveAddNews].thumbUrl"
:src=
"articlesAdd[isActiveAddNews].thumbUrl"
:class=
"isActiveAddNews === 0 ? 'avatar' : 'avatar1'"
/>
<Icon
v-else
icon=
"ep:plus"
class=
"avatar-uploader-icon"
:class=
"isActiveAddNews === 0 ? 'avatar' : 'avatar1'"
/>
<div
class=
"thumb-but"
>
<el-upload
:action=
"uploadUrl"
:headers=
"headers"
multiple
:limit=
"1"
:file-list=
"fileList"
:data=
"uploadData"
:before-upload=
"beforeThumbImageUpload"
:on-success=
"handleUploadSuccess"
>
>
<
template
#
trigger
>
<Icon
icon=
"ep:plus"
/>
<el-button
size=
"small"
type=
"primary"
>
本地上传
</el-button>
</el-button>
</
template
>
</el-row>
<el-button
</div>
size=
"small"
</el-aside>
type=
"primary"
<el-main>
@
click=
"openMaterial"
<div
class=
""
v-loading=
"addMaterialLoading"
v-if=
"articlesAdd.length > 0"
>
style=
"margin-left: 5px"
<!-- 标题、作者、原文地址 -->
>
素材库选择
</el-button
<el-row
:gutter=
"20"
>
>
<el-input
<
template
#
tip
>
v-model=
"articlesAdd[isActiveAddNews].title"
<div
class=
"el-upload__tip"
>
支持 bmp/png/jpeg/jpg/gif 格式,大小不超过 2M
</div>
placeholder=
"请输入标题(必填)"
</
template
>
/>
</el-upload>
<el-input
</div>
v-model=
"articlesAdd[isActiveAddNews].author"
<el-dialog
title=
"选择图片"
v-model=
"dialogImageVisible"
width=
"80%"
append-to-body
>
placeholder=
"请输入作者"
<WxMaterialSelect
style=
"margin-top: 5px"
ref=
"materialSelectRef"
:objData=
"{ type: 'image', accountId: queryParams.accountId }"
@
select-material=
"selectMaterial"
/>
/>
</el-dialog>
<el-input
v-model=
"articlesAdd[isActiveAddNews].contentSourceUrl"
placeholder=
"请输入原文地址"
style=
"margin-top: 5px"
/>
</el-row>
<!-- 封面和摘要 -->
<el-row
:gutter=
"20"
>
<el-col
:span=
"12"
>
<p>
封面:
</p>
<div
class=
"thumb-div"
>
<el-image
v-if=
"articlesAdd[isActiveAddNews].thumbUrl"
style=
"width: 300px; max-height: 300px"
:src=
"articlesAdd[isActiveAddNews].thumbUrl"
fit=
"contain"
/>
<Icon
v-else
icon=
"ep:plus"
class=
"avatar-uploader-icon"
:class=
"isActiveAddNews === 0 ? 'avatar' : 'avatar1'"
/>
<div
class=
"thumb-but"
>
<el-upload
:action=
"uploadUrl"
:headers=
"headers"
multiple
:limit=
"1"
:file-list=
"fileList"
:data=
"uploadData"
:before-upload=
"beforeThumbImageUpload"
:on-success=
"handleUploadSuccess"
>
<
template
#
trigger
>
<el-button
size=
"small"
type=
"primary"
>
本地上传
</el-button>
</
template
>
<el-button
size=
"small"
type=
"primary"
@
click=
"openMaterial"
style=
"margin-left: 5px"
>
素材库选择
</el-button
>
<
template
#
tip
>
<div
class=
"el-upload__tip"
>
支持 bmp/png/jpeg/jpg/gif 格式,大小不超过 2M
</div
>
</
template
>
</el-upload>
</div>
<el-dialog
title=
"选择图片"
v-model=
"dialogImageVisible"
width=
"80%"
append-to-body
>
<WxMaterialSelect
ref=
"materialSelectRef"
:objData=
"{ type: 'image', accountId: queryParams.accountId }"
@
select-material=
"selectMaterial"
/>
</el-dialog>
</div>
</el-col>
<el-col
:span=
"12"
>
<p>
摘要:
</p>
<el-input
:rows=
"8"
type=
"textarea"
v-model=
"articlesAdd[isActiveAddNews].digest"
placeholder=
"请输入摘要"
class=
"digest"
maxlength=
"120"
/>
</el-col>
</el-row>
<!--富文本编辑器组件-->
<el-row>
<Editor
v-model=
"articlesAdd[isActiveAddNews].content"
:editor-config=
"editorConfig"
/>
</el-row>
</div>
</div>
<el-input
</el-main>
:rows=
"8"
</el-container>
type=
"textarea"
v-model=
"articlesAdd[isActiveAddNews].digest"
placeholder=
"请输入摘要"
class=
"digest"
maxlength=
"120"
style=
"float: right"
/>
</div>
<!--富文本编辑器组件-->
<el-row>
<WxEditor
v-model=
"articlesAdd[isActiveAddNews].content"
:account-id=
"uploadData.accountId"
v-if=
"hackResetEditor"
/>
</el-row>
</div>
<
template
#
footer
>
<
template
#
footer
>
<el-button
@
click=
"dialogNewsVisible = false"
>
取 消
</el-button>
<el-button
@
click=
"dialogNewsVisible = false"
>
取 消
</el-button>
<el-button
type=
"primary"
@
click=
"submitForm"
>
提 交
</el-button>
<el-button
type=
"primary"
@
click=
"submitForm"
>
提 交
</el-button>
...
@@ -242,7 +256,7 @@
...
@@ -242,7 +256,7 @@
</template>
</template>
<
script
setup
lang=
"ts"
name=
"MpDraft"
>
<
script
setup
lang=
"ts"
name=
"MpDraft"
>
import
WxEditor
from
'@/views/mp/components/wx-editor/WxEditor.vue
'
import
{
Editor
}
from
'@/components/Editor
'
import
WxNews
from
'@/views/mp/components/wx-news/main.vue'
import
WxNews
from
'@/views/mp/components/wx-news/main.vue'
import
WxMaterialSelect
from
'@/views/mp/components/wx-material-select/main.vue'
import
WxMaterialSelect
from
'@/views/mp/components/wx-material-select/main.vue'
import
WxMpSelect
from
'@/views/mp/components/WxMpSelect.vue'
import
WxMpSelect
from
'@/views/mp/components/WxMpSelect.vue'
...
@@ -250,8 +264,11 @@ import { getAccessToken } from '@/utils/auth'
...
@@ -250,8 +264,11 @@ import { getAccessToken } from '@/utils/auth'
import
*
as
MpDraftApi
from
'@/api/mp/draft'
import
*
as
MpDraftApi
from
'@/api/mp/draft'
import
*
as
MpFreePublishApi
from
'@/api/mp/freePublish'
import
*
as
MpFreePublishApi
from
'@/api/mp/freePublish'
import
type
{
UploadFiles
,
UploadProps
,
UploadRawFile
}
from
'element-plus'
import
type
{
UploadFiles
,
UploadProps
,
UploadRawFile
}
from
'element-plus'
import
{
createEditorConfig
}
from
'./editor-config'
// 可以用改本地数据模拟,避免API调用超限
// 可以用改本地数据模拟,避免API调用超限
// import drafts from './mock'
import
drafts
from
'./mock'
import
{
IEditorConfig
}
from
'@wangeditor/editor'
const
message
=
useMessage
()
// 消息
const
message
=
useMessage
()
// 消息
const
loading
=
ref
(
true
)
// 列表的加载中
const
loading
=
ref
(
true
)
// 列表的加载中
...
@@ -285,14 +302,25 @@ const uploadData: UploadData = reactive({
...
@@ -285,14 +302,25 @@ const uploadData: UploadData = reactive({
})
})
// ========== 草稿新建 or 修改 ==========
// ========== 草稿新建 or 修改 ==========
interface
Article
{
title
:
string
thumbMediaId
:
string
author
:
string
digest
:
string
showCoverPic
:
string
content
:
string
contentSourceUrl
:
string
needOpenComment
:
string
onlyFansCanComment
:
string
thumbUrl
:
string
}
const
dialogNewsVisible
=
ref
(
false
)
const
dialogNewsVisible
=
ref
(
false
)
const
addMaterialLoading
=
ref
(
false
)
// 添加草稿的 loading 标识
const
addMaterialLoading
=
ref
(
false
)
// 添加草稿的 loading 标识
const
articlesAdd
=
ref
<
any
[]
>
([])
const
articlesAdd
=
ref
<
Article
[]
>
([])
const
isActiveAddNews
=
ref
(
0
)
const
isActiveAddNews
=
ref
(
0
)
const
dialogImageVisible
=
ref
(
false
)
const
dialogImageVisible
=
ref
(
false
)
const
operateMaterial
=
ref
<
'add'
|
'edit'
>
(
'add'
)
const
operateMaterial
=
ref
<
'add'
|
'edit'
>
(
'add'
)
const
articlesMediaId
=
ref
(
''
)
const
articlesMediaId
=
ref
(
''
)
const
hackResetEditor
=
ref
(
false
)
/** 侦听公众号变化 **/
/** 侦听公众号变化 **/
const
onAccountChanged
=
(
id
?:
number
)
=>
{
const
onAccountChanged
=
(
id
?:
number
)
=>
{
...
@@ -305,13 +333,16 @@ const onAccountChanged = (id?: number) => {
...
@@ -305,13 +333,16 @@ const onAccountChanged = (id?: number) => {
const
setAccountId
=
(
id
?:
number
)
=>
{
const
setAccountId
=
(
id
?:
number
)
=>
{
queryParams
.
accountId
=
id
queryParams
.
accountId
=
id
uploadData
.
accountId
=
id
uploadData
.
accountId
=
id
editorConfig
.
value
=
createEditorConfig
(
uploadUrl
,
queryParams
.
accountId
)
}
}
const
editorConfig
=
ref
<
Partial
<
IEditorConfig
>>
({})
/** 查询列表 */
/** 查询列表 */
const
getList
=
async
()
=>
{
const
getList
=
async
()
=>
{
loading
.
value
=
true
loading
.
value
=
true
try
{
try
{
const
drafts
=
await
MpDraftApi
.
getDraftPage
(
queryParams
)
//
const drafts = await MpDraftApi.getDraftPage(queryParams)
drafts
.
list
.
forEach
((
item
)
=>
{
drafts
.
list
.
forEach
((
item
)
=>
{
const
newsItem
=
item
.
content
.
newsItem
const
newsItem
=
item
.
content
.
newsItem
// 将 thumbUrl 转成 picUrl,保证 wx-news 组件可以预览封面
// 将 thumbUrl 转成 picUrl,保证 wx-news 组件可以预览封面
...
@@ -329,7 +360,6 @@ const getList = async () => {
...
@@ -329,7 +360,6 @@ const getList = async () => {
// ======================== 新增/修改草稿 ========================
// ======================== 新增/修改草稿 ========================
/** 新增按钮操作 */
/** 新增按钮操作 */
const
handleAdd
=
()
=>
{
const
handleAdd
=
()
=>
{
resetEditor
()
reset
()
reset
()
// 打开表单,并设置初始化
// 打开表单,并设置初始化
operateMaterial
.
value
=
'add'
operateMaterial
.
value
=
'add'
...
@@ -338,7 +368,6 @@ const handleAdd = () => {
...
@@ -338,7 +368,6 @@ const handleAdd = () => {
/** 更新按钮操作 */
/** 更新按钮操作 */
const
handleUpdate
=
(
item
:
any
)
=>
{
const
handleUpdate
=
(
item
:
any
)
=>
{
resetEditor
()
reset
()
reset
()
articlesMediaId
.
value
=
item
.
mediaId
articlesMediaId
.
value
=
item
.
mediaId
articlesAdd
.
value
=
JSON
.
parse
(
JSON
.
stringify
(
item
.
content
.
newsItem
))
articlesAdd
.
value
=
JSON
.
parse
(
JSON
.
stringify
(
item
.
content
.
newsItem
))
...
@@ -370,7 +399,6 @@ const dialogNewsClose = async (onDone: () => {}) => {
...
@@ -370,7 +399,6 @@ const dialogNewsClose = async (onDone: () => {}) => {
try
{
try
{
await
message
.
confirm
(
'修改内容可能还未保存,确定关闭吗?'
)
await
message
.
confirm
(
'修改内容可能还未保存,确定关闭吗?'
)
reset
()
reset
()
resetEditor
()
onDone
()
onDone
()
}
catch
{}
}
catch
{}
}
}
...
@@ -381,14 +409,6 @@ const reset = () => {
...
@@ -381,14 +409,6 @@ const reset = () => {
articlesAdd
.
value
=
[
buildEmptyArticle
()]
articlesAdd
.
value
=
[
buildEmptyArticle
()]
}
}
// 表单 Editor 重置
const
resetEditor
=
()
=>
{
hackResetEditor
.
value
=
false
// 销毁组件
nextTick
(()
=>
{
hackResetEditor
.
value
=
true
// 重建组件
})
}
// 将图文向下移动
// 将图文向下移动
const
downNews
=
(
index
:
number
)
=>
{
const
downNews
=
(
index
:
number
)
=>
{
let
temp
=
articlesAdd
.
value
[
index
]
let
temp
=
articlesAdd
.
value
[
index
]
...
@@ -398,8 +418,8 @@ const downNews = (index: number) => {
...
@@ -398,8 +418,8 @@ const downNews = (index: number) => {
}
}
// 将图文向上移动
// 将图文向上移动
const
upNews
=
(
index
)
=>
{
const
upNews
=
(
index
:
number
)
=>
{
le
t
temp
=
articlesAdd
.
value
[
index
]
cons
t
temp
=
articlesAdd
.
value
[
index
]
articlesAdd
.
value
[
index
]
=
articlesAdd
.
value
[
index
-
1
]
articlesAdd
.
value
[
index
]
=
articlesAdd
.
value
[
index
-
1
]
articlesAdd
.
value
[
index
-
1
]
=
temp
articlesAdd
.
value
[
index
-
1
]
=
temp
isActiveAddNews
.
value
=
index
-
1
isActiveAddNews
.
value
=
index
-
1
...
@@ -407,7 +427,6 @@ const upNews = (index) => {
...
@@ -407,7 +427,6 @@ const upNews = (index) => {
// 选中指定 index 的图文
// 选中指定 index 的图文
const
activeNews
=
(
index
:
number
)
=>
{
const
activeNews
=
(
index
:
number
)
=>
{
resetEditor
()
isActiveAddNews
.
value
=
index
isActiveAddNews
.
value
=
index
}
}
...
@@ -429,7 +448,7 @@ const plusNews = () => {
...
@@ -429,7 +448,7 @@ const plusNews = () => {
}
}
// 创建空的 article
// 创建空的 article
const
buildEmptyArticle
=
()
=>
{
const
buildEmptyArticle
=
()
:
Article
=>
{
return
{
return
{
title
:
''
,
title
:
''
,
thumbMediaId
:
''
,
thumbMediaId
:
''
,
...
@@ -455,8 +474,8 @@ const beforeThumbImageUpload: UploadProps['beforeUpload'] = (rawFile: UploadRawF
...
@@ -455,8 +474,8 @@ const beforeThumbImageUpload: UploadProps['beforeUpload'] = (rawFile: UploadRawF
addMaterialLoading
.
value
=
false
addMaterialLoading
.
value
=
false
return
false
return
false
}
}
const
isLt
=
rawFile
.
size
/
1024
/
1024
<
2
if
(
!
isLt
)
{
if
(
rawFile
.
size
/
1024
/
1024
>
2
)
{
message
.
error
(
'上传图片大小不能超过 2M!'
)
message
.
error
(
'上传图片大小不能超过 2M!'
)
addMaterialLoading
.
value
=
false
addMaterialLoading
.
value
=
false
return
false
return
false
...
@@ -465,10 +484,10 @@ const beforeThumbImageUpload: UploadProps['beforeUpload'] = (rawFile: UploadRawF
...
@@ -465,10 +484,10 @@ const beforeThumbImageUpload: UploadProps['beforeUpload'] = (rawFile: UploadRawF
return
true
return
true
}
}
const
handleUploadSuccess
:
UploadProps
[
'onSuccess'
]
=
(
res
ponse
:
any
)
=>
{
const
handleUploadSuccess
:
UploadProps
[
'onSuccess'
]
=
(
res
:
any
)
=>
{
addMaterialLoading
.
value
=
false
addMaterialLoading
.
value
=
false
if
(
res
ponse
.
code
!==
0
)
{
if
(
res
.
code
!==
0
)
{
message
.
error
(
'上传出错:'
+
res
ponse
.
msg
)
message
.
error
(
'上传出错:'
+
res
.
msg
)
return
false
return
false
}
}
...
@@ -476,8 +495,8 @@ const handleUploadSuccess: UploadProps['onSuccess'] = (response: any) => {
...
@@ -476,8 +495,8 @@ const handleUploadSuccess: UploadProps['onSuccess'] = (response: any) => {
fileList
.
value
=
[]
fileList
.
value
=
[]
// 设置草稿的封面字段
// 设置草稿的封面字段
articlesAdd
.
value
[
isActiveAddNews
.
value
].
thumbMediaId
=
res
ponse
.
data
.
mediaId
articlesAdd
.
value
[
isActiveAddNews
.
value
].
thumbMediaId
=
res
.
data
.
mediaId
articlesAdd
.
value
[
isActiveAddNews
.
value
].
thumbUrl
=
res
ponse
.
data
.
url
articlesAdd
.
value
[
isActiveAddNews
.
value
].
thumbUrl
=
res
.
data
.
url
}
}
// 选择 or 上传完素材,设置回草稿
// 选择 or 上传完素材,设置回草稿
...
@@ -502,7 +521,7 @@ const handlePublish = async (item: any) => {
...
@@ -502,7 +521,7 @@ const handlePublish = async (item: any) => {
await
message
.
confirm
(
content
)
await
message
.
confirm
(
content
)
await
MpFreePublishApi
.
submitFreePublish
(
accountId
,
mediaId
)
await
MpFreePublishApi
.
submitFreePublish
(
accountId
,
mediaId
)
message
.
notifySuccess
(
'发布成功'
)
message
.
notifySuccess
(
'发布成功'
)
getList
()
await
getList
()
}
catch
{}
}
catch
{}
}
}
...
@@ -514,7 +533,7 @@ const handleDelete = async (item: any) => {
...
@@ -514,7 +533,7 @@ const handleDelete = async (item: any) => {
await
message
.
confirm
(
'此操作将永久删除该草稿, 是否继续?'
)
await
message
.
confirm
(
'此操作将永久删除该草稿, 是否继续?'
)
await
MpDraftApi
.
deleteDraft
(
accountId
,
mediaId
)
await
MpDraftApi
.
deleteDraft
(
accountId
,
mediaId
)
message
.
notifySuccess
(
'删除成功'
)
message
.
notifySuccess
(
'删除成功'
)
getList
()
await
getList
()
}
catch
{}
}
catch
{}
}
}
</
script
>
</
script
>
...
@@ -535,6 +554,13 @@ const handleDelete = async (item: any) => {
...
@@ -535,6 +554,13 @@ const handleDelete = async (item: any) => {
padding-top
:
5px
;
padding-top
:
5px
;
}
}
.el-row
{
margin-bottom
:
20px
;
}
.el-row
:last-child
{
margin-bottom
:
0
;
}
.item-name
{
.item-name
{
font-size
:
12px
;
font-size
:
12px
;
overflow
:
hidden
;
overflow
:
hidden
;
...
@@ -548,35 +574,33 @@ const handleDelete = async (item: any) => {
...
@@ -548,35 +574,33 @@ const handleDelete = async (item: any) => {
}
}
/*新增图文*/
/*新增图文*/
.left
{
//
.left
{
display
:
inline-block
;
//
display
:
inline-block
;
width
:
35%
;
//
vertical-align
:
top
;
vertical-align
:
top
;
//
margin-top
:
200px
;
margin-top
:
200px
;
//
}
}
//
.right
{
.right
{
//
display
:
inline-block
;
display
:
inline-block
;
//
width
:
100%
;
width
:
60%
;
//
}
margin-top
:
-40px
;
}
//
.avatar-uploader
{
//
width
:
20%
;
.avatar-uploader
{
//
display
:
inline-block
;
width
:
20%
;
//
}
display
:
inline-block
;
}
//
.avatar-uploader
.el-upload
{
//
border-radius
:
6px
;
.avatar-uploader
.el-upload
{
//
cursor
:
pointer
;
border-radius
:
6px
;
//
position
:
relative
;
cursor
:
pointer
;
//
overflow
:
hidden
;
position
:
relative
;
//
text-align
:
unset
!important
;
overflow
:
hidden
;
//
}
text-align
:
unset
!important
;
}
//
.avatar-uploader
.el-upload
:hover
{
//
border-color
:
#165dff
;
.avatar-uploader
.el-upload
:hover
{
//
}
border-color
:
#165dff
;
}
.avatar-uploader-icon
{
.avatar-uploader-icon
{
border
:
1px
solid
#d9d9d9
;
border
:
1px
solid
#d9d9d9
;
...
@@ -599,7 +623,7 @@ const handleDelete = async (item: any) => {
...
@@ -599,7 +623,7 @@ const handleDelete = async (item: any) => {
}
}
.digest
{
.digest
{
width
:
6
0%
;
width
:
10
0%
;
display
:
inline-block
;
display
:
inline-block
;
vertical-align
:
top
;
vertical-align
:
top
;
}
}
...
@@ -620,28 +644,16 @@ const handleDelete = async (item: any) => {
...
@@ -620,28 +644,16 @@ const handleDelete = async (item: any) => {
border
:
1px
solid
#eaeaea
;
border
:
1px
solid
#eaeaea
;
}
}
p
{
line-height
:
30px
;
}
@media
(
min-width
:
992px
)
and
(
max-width
:
1300px
)
{
@media
(
min-width
:
992px
)
and
(
max-width
:
1300px
)
{
.waterfall
{
.waterfall
{
column-count
:
3
;
column-count
:
3
;
}
}
p
{
color
:
red
;
}
}
}
@media
(
min-width
:
768px
)
and
(
max-width
:
991px
)
{
@media
(
min-width
:
768px
)
and
(
max-width
:
991px
)
{
.waterfall
{
.waterfall
{
column-count
:
2
;
column-count
:
2
;
}
}
p
{
color
:
orange
;
}
}
}
@media
(
max-width
:
767px
)
{
@media
(
max-width
:
767px
)
{
...
@@ -707,10 +719,6 @@ p {
...
@@ -707,10 +719,6 @@ p {
background-color
:
#acadae
;
background-color
:
#acadae
;
}
}
.input-tt
{
padding
:
5px
;
}
.activeAddNews
{
.activeAddNews
{
border
:
5px
solid
#2bb673
;
border
:
5px
solid
#2bb673
;
}
}
...
@@ -747,7 +755,7 @@ p {
...
@@ -747,7 +755,7 @@ p {
.thumb-div
{
.thumb-div
{
display
:
inline-block
;
display
:
inline-block
;
width
:
3
0%
;
width
:
10
0%
;
text-align
:
center
;
text-align
:
center
;
}
}
...
...
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