Browse Source

修复:编辑器图片、视频上传功能替换为从文件库选取。

dev
科技小王子 2 months ago
parent
commit
547e713195
  1. 5
      src/components/SelectFile/components/select-data.vue
  2. 315
      src/views/cms/cmsArticle/components/articleEdit.vue
  3. 10
      src/views/system/profile/index.vue

5
src/components/SelectFile/components/select-data.vue

@ -143,7 +143,7 @@
import {pageFiles, removeFile, uploadOss, uploadOssByGroupId} from '@/api/system/file';
import { EleProTable, messageLoading } from 'ele-admin-pro';
import { FileRecord, FileRecordParam } from '@/api/system/file/model';
import { EditOutlined, UploadOutlined,DeleteOutlined } from '@ant-design/icons-vue';
import { EditOutlined, UploadOutlined } from '@ant-design/icons-vue';
import { DictData } from '@/api/system/dict-data/model';
import { pageDictData } from '@/api/system/dict-data';
import {isImage, isMobileDevice, openUrl} from '@/utils/common';
@ -354,8 +354,9 @@
onDblclick: () => {
updateVisible(false);
if(!isMobileDevice()){
record.path = record.url;
record.path = record.url || record.downloadUrl;
}
console.log(record,'rec......')
emit('done', record);
}
};

315
src/views/cms/cmsArticle/components/articleEdit.vue

@ -109,8 +109,11 @@
v-model:value="content"
:disabled="disabled"
:init="config"
placeholder="本地图片支持直接粘贴或拖拽至光标处"
placeholder="支持直接粘贴或拖拽图片,也可点击工具栏图片按钮从文件库选择"
/>
<div class="file-selector-tip" v-if="editor == 1">
💡 提示工具栏"图片"按钮从图片库选择"上传"按钮快速上传图片"视频"按钮从视频库选择"上传视频"按钮快速上传视频
</div>
<MdEditor
v-if="editor == 2"
v-model="content"
@ -208,6 +211,24 @@
</a-spin>
</a-form>
</ele-modal>
<!-- 文件库选择弹窗 -->
<SelectData
v-model:visible="showFileSelector"
title="选择图片"
type="image"
class="file-selector-modal"
@done="onFileSelected"
/>
<!-- 视频库选择弹窗 -->
<SelectData
v-model:visible="showVideoSelector"
title="选择视频"
type="video"
class="file-selector-modal"
@done="onVideoSelected"
/>
</template>
<script lang="ts" setup>
@ -231,6 +252,7 @@
import { CmsNavigation } from '@/api/cms/cmsNavigation/model';
import SourceSelect from '@/views/cms/cmsArticle/dictionary/source-select.vue';
import { useWebsiteSettingStore } from '@/store/modules/setting';
import SelectData from '@/components/SelectFile/components/select-data.vue';
//
const isUpdate = ref(false);
@ -351,42 +373,6 @@
trigger: 'blur'
}
],
// image: [
// {
// required: true,
// message: '',
// type: 'string',
// trigger: 'blur'
// }
// ],
// files: [
// {
// required: true,
// message: '',
// type: 'string',
// trigger: 'blur',
// validator: async (_rule: RuleObject, value: string) => {
// if (form.files == '') {
// return Promise.reject('');
// }
// return Promise.resolve();
// }
// }
// ],
// categoryId: [
// {
// required: true,
// type: 'number',
// message: '',
// trigger: 'blur',
// validator: async (_rule: RuleObject, value: string) => {
// if (!form.categoryId) {
// return Promise.reject('');
// }
// return Promise.resolve();
// }
// }
// ],
content: [
{
required: true,
@ -451,21 +437,225 @@
};
const editorRef = ref<InstanceType<typeof TinymceEditor> | null>(null);
//
const showFileSelector = ref(false);
const fileSelectCallback = ref<((url: string) => void) | null>(null);
//
const showVideoSelector = ref(false);
const videoSelectCallback = ref<((url: string) => void) | null>(null);
const config = ref({
height: 620,
paste_data_images: true,
automatic_uploads: true,
// imagemedia
toolbar: [
'fullscreen preview code codesample emoticons custom_image_selector quick_upload custom_video_selector quick_video_upload',
'undo redo | forecolor backcolor',
'bold italic underline strikethrough',
'alignleft aligncenter alignright alignjustify',
'outdent indent | numlist bullist',
'formatselect fontselect fontsizeselect',
'link charmap anchor pagebreak | ltr rtl'
].join(' | '),
// -
images_upload_handler: (blobInfo, success, error) => {
const file = blobInfo.blob();
// 10MB
if (file.size > 10 * 1024 * 1024) {
error('图片大小不能超过10MB');
return;
}
//
if (!file.type.startsWith('image/')) {
error('只能上传图片文件');
return;
}
//
const loadingMsg = message.loading('图片上传中...', 0);
uploadOss(file)
.then((res) => {
loadingMsg();
success(res.url || res.path);
message.success('图片上传成功');
})
.catch((msg) => {
loadingMsg();
error(msg || '图片上传失败');
message.error('图片上传失败:' + msg);
});
},
//
image_toolbar: 'alignleft aligncenter alignright | rotateleft rotateright | imageoptions',
//
image_title: true,
//
image_description: true,
//
image_dimensions: true,
//
image_class_list: [
{ title: '无样式', value: '' },
{ title: '响应式图片', value: 'img-responsive' },
{ title: '圆角图片', value: 'img-rounded' },
{ title: '圆形图片', value: 'img-circle' }
],
//
setup: (editor: any) => {
//
editor.ui.registry.addButton('custom_image_selector', {
text: '图片',
icon: 'image',
tooltip: '插入图片(从文件库选择或上传)',
onAction: () => {
//
fileSelectCallback.value = (url: string) => {
editor.insertContent(`<img src="${url}" alt="图片" style="max-width: 100%;" />`);
};
showFileSelector.value = true;
}
});
//
editor.ui.registry.addButton('quick_upload', {
text: '上传',
icon: 'upload',
tooltip: '快速上传图片',
onAction: () => {
const input = document.createElement('input');
input.type = 'file';
input.accept = 'image/*';
input.onchange = (e: any) => {
const file = e.target.files[0];
if (file) {
//
if (file.size > 10 * 1024 * 1024) {
message.error('图片大小不能超过10MB');
return;
}
const loadingMsg = message.loading('图片上传中...', 0);
uploadOss(file)
.then((res) => {
loadingMsg();
const imageUrl = res.url || res.path;
editor.insertContent(`<img src="${imageUrl}" alt="${file.name}" style="max-width: 100%;" />`);
message.success('图片上传成功');
})
.catch((msg) => {
loadingMsg();
message.error('图片上传失败:' + msg);
});
}
};
input.click();
}
});
//
editor.ui.registry.addButton('custom_video_selector', {
text: '视频',
icon: 'embed',
tooltip: '插入视频(从视频库选择)',
onAction: () => {
//
videoSelectCallback.value = (url: string) => {
// 使HTML5 video
editor.insertContent(`
<video controls style="max-width: 100%; height: auto;">
<source src="${url}" type="video/mp4">
您的浏览器不支持视频播放
</video>
`);
};
showVideoSelector.value = true;
}
});
//
editor.ui.registry.addButton('quick_video_upload', {
text: '上传视频',
icon: 'upload',
tooltip: '快速上传视频',
onAction: () => {
const input = document.createElement('input');
input.type = 'file';
input.accept = 'video/*';
input.onchange = (e: any) => {
const file = e.target.files[0];
if (file) {
// 100MB
if (file.size > 100 * 1024 * 1024) {
message.error('视频大小不能超过100MB');
return;
}
const loadingMsg = message.loading('视频上传中...', 0);
uploadOss(file)
.then((res) => {
success(res.url);
loadingMsg();
const videoUrl = res.path || res.downloadUrl;
editor.insertContent(`
<video controls style="max-width: 100%; height: auto;">
<source src="${videoUrl}" type="video/mp4">
您的浏览器不支持视频播放
</video>
`);
message.success('视频上传成功');
})
.catch((msg) => {
error(msg);
loadingMsg();
message.error('视频上传失败:' + msg);
});
}
};
input.click();
}
});
}
});
//
const onFileSelected = (data: FileRecord) => {
if (fileSelectCallback.value) {
// 使URL
const imageUrl = data.url || data.path || '';
if (imageUrl) {
fileSelectCallback.value(imageUrl);
message.success('图片插入成功');
}
fileSelectCallback.value = null;
}
showFileSelector.value = false;
};
//
const onVideoSelected = (data: FileRecord) => {
if (videoSelectCallback.value) {
// 使URL
const videoUrl = data.path || data.downloadUrl || '';
if (videoUrl) {
videoSelectCallback.value(videoUrl);
message.success('视频插入成功');
}
videoSelectCallback.value = null;
}
showVideoSelector.value = false;
};
const { resetFields } = useForm(form, rules);
@ -585,3 +775,50 @@
{ immediate: true }
);
</script>
<style lang="less" scoped>
.editor-content {
:deep(.tox-tinymce) {
border-radius: 6px;
}
//
:deep(.mce-content-body) {
img {
max-width: 100%;
height: auto;
&.img-responsive {
width: 100%;
height: auto;
}
&.img-rounded {
border-radius: 8px;
}
&.img-circle {
border-radius: 50%;
}
}
}
}
//
.file-selector-tip {
color: #666;
font-size: 12px;
margin-top: 4px;
}
//
:deep(.file-selector-modal) {
.ant-modal {
z-index: 10000 !important;
}
.ant-modal-mask {
z-index: 9999 !important;
}
}
</style>

10
src/views/system/profile/index.vue

@ -45,8 +45,8 @@
</a-form-item>
<a-form-item label="专属域名">
<a-space class="justify">
<a class="cursor-pointer" @click="openSpmUrl(`https://${form.domain}`)">{{ `${form.domain}` }}</a>
<a @click="onEdit('专属域名', 'freeDomain', form.freeDomain)">修改</a>
<a class="cursor-pointer" @click="openSpmUrl(`${form.adminUrl}`)">{{ `${form.adminUrl}` }}</a>
<a @click="onEdit('专属域名', 'adminUrl', form.adminUrl)">修改</a>
</a-space>
</a-form-item>
<!-- <a-form-item label="应用类型">-->
@ -62,7 +62,7 @@
<!-- </a-form-item>-->
<a-form-item label="应用版本">
<a-space class="justify">
<a-tag color="red" v-if="form.version === 10" class="cursor-pointer" @click="updateVersion(form.version)">基础版</a-tag>
<a-tag v-if="form.version === 10" class="cursor-pointer" @click="updateVersion(form.version)">基础版</a-tag>
<a-tag color="blue" v-if="form.version === 20" class="cursor-pointer" @click="updateVersion(form.version)">专业版</a-tag>
<a-tag color="cyan" v-if="form.version === 30">永久授权</a-tag>
</a-space>
@ -77,8 +77,10 @@
<span class="ele-text-heading">{{ form.createTime }}</span>
</a-form-item>
<a-form-item label="到期时间" v-if="form.version != 30">
<a-tag color="red">已到期</a-tag>
<a-space>
<span class="ele-text-heading">{{ form.expirationTime }}</span>
<a-tag color="red">已到期</a-tag>
</a-space>
</a-form-item>
<a-divider style="padding-bottom: 20px" />
<!-- <a-form-item label="主体名称">-->

Loading…
Cancel
Save