|
|
@ -1,7 +1,7 @@ |
|
|
|
<!-- 编辑弹窗 --> |
|
|
|
<template> |
|
|
|
<ele-modal |
|
|
|
width="75%" |
|
|
|
<a-drawer |
|
|
|
width="70%" |
|
|
|
:visible="visible" |
|
|
|
:maskClosable="false" |
|
|
|
:maxable="maxable" |
|
|
@ -11,6 +11,9 @@ |
|
|
|
:confirm-loading="loading" |
|
|
|
@ok="save" |
|
|
|
> |
|
|
|
<template #extra> |
|
|
|
<a-button type="primary" style="margin-right: 8px" @click="save">保存</a-button> |
|
|
|
</template> |
|
|
|
<a-form |
|
|
|
ref="formRef" |
|
|
|
:model="form" |
|
|
@ -21,221 +24,212 @@ |
|
|
|
" |
|
|
|
> |
|
|
|
<a-spin :spinning="loading"> |
|
|
|
<a-tabs type="card" v-model:active-key="active" @change="onChange"> |
|
|
|
<!-- <template #rightExtra>--> |
|
|
|
<!-- <a-radio-group v-model:value="editor" v-if="active == 'content'" @change="onEditor">--> |
|
|
|
<!-- <a-radio :value="1">富文本</a-radio>--> |
|
|
|
<!-- <a-radio :value="2">Markdown</a-radio>--> |
|
|
|
<!-- </a-radio-group>--> |
|
|
|
<!-- </template>--> |
|
|
|
<a-tab-pane tab="基本信息" key="base"> |
|
|
|
<a-form-item label="封面图" name="files"> |
|
|
|
<SelectFile |
|
|
|
:placeholder="`请选择图片`" |
|
|
|
:limit="6" |
|
|
|
:data="files" |
|
|
|
@done="chooseFile" |
|
|
|
@del="onDeleteFile" |
|
|
|
/> |
|
|
|
</a-form-item> |
|
|
|
<a-form-item label="所属栏目" name="categoryId"> |
|
|
|
<a-tree-select |
|
|
|
allow-clear |
|
|
|
:tree-data="navigationList" |
|
|
|
tree-default-expand-all |
|
|
|
style="width: 320px" |
|
|
|
placeholder="请选择栏目" |
|
|
|
:value="form.categoryId || undefined" |
|
|
|
:listHeight="700" |
|
|
|
:dropdown-style="{ overflow: 'auto' }" |
|
|
|
@update:value="(value?: number) => (form.categoryId = value)" |
|
|
|
@change="onCategoryId" |
|
|
|
/> |
|
|
|
</a-form-item> |
|
|
|
<a-form-item label="文章标题" name="title"> |
|
|
|
<div class="title-input-container"> |
|
|
|
<a-input |
|
|
|
allow-clear |
|
|
|
placeholder="文章标题" |
|
|
|
v-model:value="form.title" |
|
|
|
@pressEnter="save" |
|
|
|
:maxlength="100" |
|
|
|
/> |
|
|
|
</div> |
|
|
|
</a-form-item> |
|
|
|
<a-form-item label="内容详情"> |
|
|
|
<!-- 富文本编辑器 --> |
|
|
|
<div v-if="editor == 1"> |
|
|
|
<tinymce-editor |
|
|
|
ref="editorRef" |
|
|
|
class="editor-content" |
|
|
|
v-model:value="content" |
|
|
|
:disabled="disabled" |
|
|
|
:init="config" |
|
|
|
placeholder="支持直接粘贴或拖拽图片,也可点击工具栏图片按钮从文件库选择" |
|
|
|
/> |
|
|
|
<div class="file-selector-tip"> |
|
|
|
💡 提示:工具栏"图片"按钮从图片库选择,"上传"按钮快速上传图片;"视频"按钮从视频库选择,"上传视频"按钮快速上传视频;"一键排版"按钮自动优化文章格式;"首行缩进"按钮切换段落缩进 |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
<!-- Markdown编辑器 --> |
|
|
|
<div v-if="editor == 2"> |
|
|
|
<!-- 📝 Markdown编辑器工具栏扩展 --> |
|
|
|
<div class="markdown-toolbar-extension"> |
|
|
|
<a-button |
|
|
|
type="primary" |
|
|
|
size="small" |
|
|
|
@click="openMarkdownImageSelector" |
|
|
|
style="margin-right: 8px;" |
|
|
|
> |
|
|
|
📷 从图片库选择 |
|
|
|
</a-button> |
|
|
|
<a-button |
|
|
|
type="default" |
|
|
|
size="small" |
|
|
|
@click="openMarkdownVideoSelector" |
|
|
|
style="margin-right: 8px;" |
|
|
|
> |
|
|
|
🎬 从视频库选择 |
|
|
|
</a-button> |
|
|
|
</div> |
|
|
|
|
|
|
|
<MdEditor |
|
|
|
v-model="content" |
|
|
|
:disabled="disabled" |
|
|
|
height="500px" |
|
|
|
:placeholder="'请输入Markdown内容...'" |
|
|
|
:toolbars="markdownToolbars" |
|
|
|
:onUploadImg="onMarkdownUploadImg" |
|
|
|
/> |
|
|
|
<div class="file-selector-tip"> |
|
|
|
💡 提示:支持Markdown语法,可以使用工具栏按钮从文件库选择图片/视频,也可以直接拖拽上传文件 |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
<a-space |
|
|
|
class="py-2 flex items-center text-gray-400" |
|
|
|
v-if="lang == 'zh_CN'" |
|
|
|
<!-- <a-tabs type="card" v-model:active-key="active" @change="onChange">--> |
|
|
|
<!-- <a-tab-pane tab="基本信息" key="base">--> |
|
|
|
<a-form-item label="封面图" name="files"> |
|
|
|
<SelectFile |
|
|
|
:placeholder="`请选择图片`" |
|
|
|
:limit="6" |
|
|
|
:data="files" |
|
|
|
@done="chooseFile" |
|
|
|
@del="onDeleteFile" |
|
|
|
/> |
|
|
|
</a-form-item> |
|
|
|
<a-form-item label="所属栏目" name="categoryId"> |
|
|
|
<a-tree-select |
|
|
|
allow-clear |
|
|
|
:tree-data="navigationList" |
|
|
|
tree-default-expand-all |
|
|
|
style="width: 320px" |
|
|
|
placeholder="请选择栏目" |
|
|
|
:value="form.categoryId || undefined" |
|
|
|
:listHeight="700" |
|
|
|
:dropdown-style="{ overflow: 'auto' }" |
|
|
|
@update:value="(value?: number) => (form.categoryId = value)" |
|
|
|
@change="onCategoryId" |
|
|
|
/> |
|
|
|
</a-form-item> |
|
|
|
<a-form-item label="文章标题" name="title"> |
|
|
|
<div class="title-input-container"> |
|
|
|
<a-input |
|
|
|
allow-clear |
|
|
|
placeholder="文章标题" |
|
|
|
v-model:value="form.title" |
|
|
|
@pressEnter="save" |
|
|
|
:maxlength="100" |
|
|
|
/> |
|
|
|
</div> |
|
|
|
</a-form-item> |
|
|
|
<a-form-item label="内容详情" name="content"> |
|
|
|
<!-- 富文本编辑器 --> |
|
|
|
<div v-if="editor == 1"> |
|
|
|
<tinymce-editor |
|
|
|
ref="editorRef" |
|
|
|
class="editor-content" |
|
|
|
v-model:value="content" |
|
|
|
:disabled="disabled" |
|
|
|
:init="config" |
|
|
|
placeholder="支持直接粘贴或拖拽图片,也可点击工具栏图片按钮从文件库选择" |
|
|
|
/> |
|
|
|
<div class="file-selector-tip"> |
|
|
|
💡 提示:工具栏"图片"按钮从图片库选择,"上传"按钮快速上传图片;"视频"按钮从视频库选择,"上传视频"按钮快速上传视频;"一键排版"按钮自动优化文章格式;"首行缩进"按钮切换段落缩进 |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
<!-- Markdown编辑器 --> |
|
|
|
<div v-if="editor == 2"> |
|
|
|
<!-- 📝 Markdown编辑器工具栏扩展 --> |
|
|
|
<div class="markdown-toolbar-extension"> |
|
|
|
<a-button |
|
|
|
type="primary" |
|
|
|
size="small" |
|
|
|
@click="openMarkdownImageSelector" |
|
|
|
style="margin-right: 8px;" |
|
|
|
> |
|
|
|
<a-switch |
|
|
|
checked-children="AI翻译" |
|
|
|
v-model:checked="form.translation" |
|
|
|
/> |
|
|
|
<div v-if="form.translation">启用后,将自动翻译其他语言版本</div> |
|
|
|
</a-space> |
|
|
|
</a-form-item> |
|
|
|
<a-form-item label="摘要"> |
|
|
|
<a-textarea |
|
|
|
:rows="3" |
|
|
|
:maxlength="200" |
|
|
|
show-count |
|
|
|
placeholder="请输入文章摘要" |
|
|
|
@focus="onComments" |
|
|
|
v-model:value="form.comments" |
|
|
|
/> |
|
|
|
</a-form-item> |
|
|
|
<a-form-item label="排序" name="sortNumber"> |
|
|
|
<a-input-number |
|
|
|
:min="0" |
|
|
|
:max="9999" |
|
|
|
style="width: 206px" |
|
|
|
placeholder="请输入排序号" |
|
|
|
v-model:value="form.sortNumber" |
|
|
|
/> |
|
|
|
</a-form-item> |
|
|
|
<a-form-item |
|
|
|
label="状态" |
|
|
|
name="status" |
|
|
|
v-if="setting.setting?.articleReview" |
|
|
|
> |
|
|
|
<a-radio-group v-model:value="form.status"> |
|
|
|
<a-radio :value="1">待审核</a-radio> |
|
|
|
<a-radio :value="0">已发布</a-radio> |
|
|
|
</a-radio-group> |
|
|
|
</a-form-item> |
|
|
|
</a-tab-pane> |
|
|
|
<a-tab-pane tab="其他选项" key="other"> |
|
|
|
<a-form-item label="关键词" name="tags"> |
|
|
|
<a-select |
|
|
|
v-model:value="form.tags" |
|
|
|
mode="tags" |
|
|
|
style="width: 558px" |
|
|
|
placeholder="按回车分隔" |
|
|
|
></a-select> |
|
|
|
</a-form-item> |
|
|
|
<a-form-item label="产品概述" name="overview"> |
|
|
|
<a-textarea |
|
|
|
:rows="3" |
|
|
|
style="width: 558px" |
|
|
|
show-count |
|
|
|
placeholder="请输入产品概述" |
|
|
|
v-model:value="form.overview" |
|
|
|
/> |
|
|
|
</a-form-item> |
|
|
|
<a-form-item label="文章来源" name="source"> |
|
|
|
<source-select |
|
|
|
v-model:value="form.source" |
|
|
|
:placeholder="`文章来源`" |
|
|
|
style="width: 206px" |
|
|
|
/> |
|
|
|
</a-form-item> |
|
|
|
<a-form-item label="PDF" name="pdfUrl"> |
|
|
|
<a-input |
|
|
|
allow-clear |
|
|
|
style="width: 558px" |
|
|
|
placeholder="https://" |
|
|
|
v-model:value="form.pdfUrl" |
|
|
|
/> |
|
|
|
</a-form-item> |
|
|
|
<a-form-item |
|
|
|
label="虚拟阅读量" |
|
|
|
name="virtualViews" |
|
|
|
:extra="`用户看到的阅读量(${ |
|
|
|
📷 从图片库选择 |
|
|
|
</a-button> |
|
|
|
<a-button |
|
|
|
type="default" |
|
|
|
size="small" |
|
|
|
@click="openMarkdownVideoSelector" |
|
|
|
style="margin-right: 8px;" |
|
|
|
> |
|
|
|
🎬 从视频库选择 |
|
|
|
</a-button> |
|
|
|
</div> |
|
|
|
|
|
|
|
<MdEditor |
|
|
|
v-model="content" |
|
|
|
:disabled="disabled" |
|
|
|
height="500px" |
|
|
|
:placeholder="'请输入Markdown内容...'" |
|
|
|
:toolbars="markdownToolbars" |
|
|
|
:onUploadImg="onMarkdownUploadImg" |
|
|
|
/> |
|
|
|
<div class="file-selector-tip"> |
|
|
|
💡 提示:支持Markdown语法,可以使用工具栏按钮从文件库选择图片/视频,也可以直接拖拽上传文件 |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
<a-space |
|
|
|
class="py-2 flex items-center text-gray-400" |
|
|
|
v-if="lang == 'zh_CN'" |
|
|
|
> |
|
|
|
<a-switch |
|
|
|
checked-children="AI翻译" |
|
|
|
v-model:checked="form.translation" |
|
|
|
/> |
|
|
|
<div v-if="form.translation">启用后,将自动翻译其他语言版本</div> |
|
|
|
</a-space> |
|
|
|
</a-form-item> |
|
|
|
<a-form-item label="摘要"> |
|
|
|
<a-textarea |
|
|
|
:rows="3" |
|
|
|
:maxlength="200" |
|
|
|
show-count |
|
|
|
placeholder="请输入文章摘要" |
|
|
|
@focus="onComments" |
|
|
|
v-model:value="form.comments" |
|
|
|
/> |
|
|
|
</a-form-item> |
|
|
|
<a-form-item |
|
|
|
label="状态" |
|
|
|
name="status" |
|
|
|
v-if="setting.setting?.articleReview" |
|
|
|
> |
|
|
|
<a-radio-group v-model:value="form.status"> |
|
|
|
<a-radio :value="1">待审核</a-radio> |
|
|
|
<a-radio :value="0">已发布</a-radio> |
|
|
|
</a-radio-group> |
|
|
|
</a-form-item> |
|
|
|
<a-divider class="py-4 mb-3" style="height: 20px" /> |
|
|
|
<a-form-item label="关键词" name="tags"> |
|
|
|
<a-select |
|
|
|
v-model:value="form.tags" |
|
|
|
mode="tags" |
|
|
|
placeholder="按回车分隔" |
|
|
|
></a-select> |
|
|
|
</a-form-item> |
|
|
|
<a-form-item label="描述" name="overview"> |
|
|
|
<a-textarea |
|
|
|
:rows="3" |
|
|
|
show-count |
|
|
|
placeholder="请输入描述" |
|
|
|
v-model:value="form.overview" |
|
|
|
/> |
|
|
|
</a-form-item> |
|
|
|
<a-form-item label="自定义链接" name="pdfUrl"> |
|
|
|
<a-input |
|
|
|
allow-clear |
|
|
|
placeholder="https://" |
|
|
|
v-model:value="form.pdfUrl" |
|
|
|
/> |
|
|
|
</a-form-item> |
|
|
|
<a-form-item label="文章来源" name="source"> |
|
|
|
<source-select |
|
|
|
v-model:value="form.source" |
|
|
|
style="width: 206px" |
|
|
|
:placeholder="`文章来源`" |
|
|
|
/> |
|
|
|
</a-form-item> |
|
|
|
<a-form-item |
|
|
|
label="虚拟阅读量" |
|
|
|
name="virtualViews" |
|
|
|
:extra="`用户看到的阅读量(${ |
|
|
|
Number(form?.actualViews) + Number(form?.virtualViews) |
|
|
|
}) = 实际阅读量(${form.actualViews}) + 虚拟阅读量(${ |
|
|
|
form.virtualViews |
|
|
|
})`" |
|
|
|
> |
|
|
|
<a-input-number |
|
|
|
:min="0" |
|
|
|
:max="999999999" |
|
|
|
style="width: 206px" |
|
|
|
placeholder="请输入虚拟阅读量" |
|
|
|
v-model:value="form.virtualViews" |
|
|
|
/> |
|
|
|
</a-form-item> |
|
|
|
<a-form-item label="访问权限" name="permission"> |
|
|
|
<a-radio-group v-model:value="form.permission"> |
|
|
|
<a-radio :value="0">所有人可见</a-radio> |
|
|
|
<a-radio :value="1">登录可见</a-radio> |
|
|
|
<a-radio :value="2">密码可见</a-radio> |
|
|
|
</a-radio-group> |
|
|
|
</a-form-item> |
|
|
|
<a-form-item |
|
|
|
label="访问密码" |
|
|
|
name="password" |
|
|
|
v-if="form.permission == 2" |
|
|
|
> |
|
|
|
<a-input-password |
|
|
|
allow-clear |
|
|
|
placeholder="请输入查看密码" |
|
|
|
v-model:value="password" |
|
|
|
/> |
|
|
|
</a-form-item> |
|
|
|
<a-form-item label="发布时间" name="createTime" v-if="isUpdate"> |
|
|
|
<a-date-picker |
|
|
|
v-model:value="form.createTime" |
|
|
|
show-time |
|
|
|
placeholder="Select Time" |
|
|
|
value-format="YYYY-MM-DD HH:mm:ss" |
|
|
|
/> |
|
|
|
</a-form-item> |
|
|
|
</a-tab-pane> |
|
|
|
</a-tabs> |
|
|
|
> |
|
|
|
<a-input-number |
|
|
|
:min="0" |
|
|
|
:max="999999999" |
|
|
|
style="width: 206px" |
|
|
|
placeholder="请输入虚拟阅读量" |
|
|
|
v-model:value="form.virtualViews" |
|
|
|
/> |
|
|
|
</a-form-item> |
|
|
|
<a-form-item label="访问权限" name="permission"> |
|
|
|
<a-radio-group v-model:value="form.permission"> |
|
|
|
<a-radio :value="0">所有人可见</a-radio> |
|
|
|
<a-radio :value="1">登录可见</a-radio> |
|
|
|
<a-radio :value="2">密码可见</a-radio> |
|
|
|
</a-radio-group> |
|
|
|
</a-form-item> |
|
|
|
<a-form-item |
|
|
|
label="访问密码" |
|
|
|
name="password" |
|
|
|
v-if="form.permission == 2" |
|
|
|
> |
|
|
|
<a-input-password |
|
|
|
allow-clear |
|
|
|
placeholder="请输入查看密码" |
|
|
|
v-model:value="password" |
|
|
|
/> |
|
|
|
</a-form-item> |
|
|
|
<a-form-item label="排序" name="sortNumber"> |
|
|
|
<a-input-number |
|
|
|
:min="0" |
|
|
|
:max="9999" |
|
|
|
style="width: 206px" |
|
|
|
placeholder="请输入排序号" |
|
|
|
v-model:value="form.sortNumber" |
|
|
|
/> |
|
|
|
</a-form-item> |
|
|
|
<a-form-item label="发布时间" name="createTime" v-if="isUpdate"> |
|
|
|
<a-date-picker |
|
|
|
v-model:value="form.createTime" |
|
|
|
show-time |
|
|
|
placeholder="Select Time" |
|
|
|
value-format="YYYY-MM-DD HH:mm:ss" |
|
|
|
/> |
|
|
|
</a-form-item> |
|
|
|
<!-- </a-tab-pane>--> |
|
|
|
<!-- <a-tab-pane tab="其他选项" key="other">--> |
|
|
|
<!-- </a-tabs>--> |
|
|
|
</a-spin> |
|
|
|
</a-form> |
|
|
|
</ele-modal> |
|
|
|
</a-drawer> |
|
|
|
|
|
|
|
<!-- 文件库选择弹窗 --> |
|
|
|
<SelectData |
|
|
@ -321,7 +315,7 @@ const images = ref<ItemType[]>([]); |
|
|
|
const content = ref(''); |
|
|
|
const disabled = ref(false); |
|
|
|
// 当前选项卡 |
|
|
|
const active = ref('base'); |
|
|
|
// const active = ref('base'); |
|
|
|
const files = ref<ItemType[]>([]); |
|
|
|
const category = ref<string[]>([]); |
|
|
|
const password = ref(); |
|
|
@ -707,7 +701,7 @@ const insertMarkdownText = (text: string) => { |
|
|
|
}; |
|
|
|
|
|
|
|
const config = ref({ |
|
|
|
height: 620, |
|
|
|
height: 420, |
|
|
|
paste_data_images: true, |
|
|
|
automatic_uploads: true, |
|
|
|
|
|
|
@ -1194,10 +1188,6 @@ const save = () => { |
|
|
|
if (!formRef.value) { |
|
|
|
return; |
|
|
|
} |
|
|
|
if (content.value == '') { |
|
|
|
message.error('请输入文章内容'); |
|
|
|
return; |
|
|
|
} |
|
|
|
formRef.value |
|
|
|
.validate() |
|
|
|
.then(() => { |
|
|
@ -1209,9 +1199,12 @@ const save = () => { |
|
|
|
form.tags = JSON.stringify(form.tags); |
|
|
|
} |
|
|
|
// 取第一张图片作为封面图 |
|
|
|
if (form.files) { |
|
|
|
const arr = JSON.parse(form.files); |
|
|
|
form.image = arr[0]; |
|
|
|
if (files.value.length > 0) { |
|
|
|
form.image = files.value[0].url; |
|
|
|
form.files = JSON.stringify(files.value.map((d) => d.url)); |
|
|
|
}else { |
|
|
|
form.image = ''; |
|
|
|
form.files = ''; |
|
|
|
} |
|
|
|
const formData = { |
|
|
|
...form, |
|
|
|