first commit
This commit is contained in:
116
front/src/components/common/markdown.vue
Normal file
116
front/src/components/common/markdown.vue
Normal file
@@ -0,0 +1,116 @@
|
||||
<script setup lang="ts">
|
||||
import { onMounted, onUnmounted, ref, watch } from 'vue';
|
||||
import Vditor from 'vditor';
|
||||
import 'vditor/dist/index.css';
|
||||
import { useThemeStore } from '@/store/modules/theme';
|
||||
import { localStg } from '@/utils/storage';
|
||||
import { getServiceBaseURL } from '@/utils/service';
|
||||
import { isExternal } from '@/utils/ruoyi';
|
||||
|
||||
defineOptions({
|
||||
// eslint-disable-next-line vue/multi-word-component-names
|
||||
name: 'Markdown'
|
||||
});
|
||||
|
||||
const { placeholder, height } = defineProps<{
|
||||
placeholder?: string;
|
||||
height?: number;
|
||||
}>();
|
||||
|
||||
const isHttpProxy = import.meta.env.DEV && import.meta.env.VITE_HTTP_PROXY === 'Y';
|
||||
const { baseURL } = getServiceBaseURL(import.meta.env, isHttpProxy);
|
||||
|
||||
const value = defineModel<string>('value', { default: '' });
|
||||
|
||||
const theme = useThemeStore();
|
||||
|
||||
const vditor = ref<Vditor>();
|
||||
const domRef = ref<HTMLElement>();
|
||||
|
||||
function renderVditor() {
|
||||
if (!domRef.value) return;
|
||||
vditor.value = new Vditor(domRef.value, {
|
||||
height: height || 300,
|
||||
mode: 'wysiwyg',
|
||||
width: '100%',
|
||||
theme: theme.darkMode ? 'dark' : 'classic',
|
||||
placeholder: placeholder || '请输入内容...',
|
||||
cache: { enable: false },
|
||||
value: value.value, // 初始值
|
||||
blur: val => {
|
||||
value.value = val;
|
||||
},
|
||||
upload: {
|
||||
// 文件上传的接口地址
|
||||
url: `${import.meta.env.VITE_SERVICE_BASE_URL}/${import.meta.env.VITE_SERVICE_UPLOAD}`,
|
||||
// 图片链接转图片的接口地址
|
||||
linkToImgUrl: `${import.meta.env.VITE_SERVICE_BASE_URL}/${import.meta.env.VITE_SERVICE_UPLOAD}`,
|
||||
// 请求头,携带认证信息
|
||||
headers: {
|
||||
Authorization: `Bearer ${localStg.get('token')}` as string
|
||||
},
|
||||
// 是否允许多文件上传
|
||||
multiple: false,
|
||||
// 文件上传后的格式处理函数
|
||||
format: (files: File[], responseText: string): string => {
|
||||
// 解析服务器返回的响应
|
||||
const res = JSON.parse(responseText);
|
||||
// 如果上传成功,返回格式化的数据
|
||||
if (res.code === 200) {
|
||||
let url = res.data.url;
|
||||
if (!url.includes(baseURL) && !isExternal(url)) {
|
||||
url = `${baseURL}${url}`;
|
||||
}
|
||||
return JSON.stringify({
|
||||
msg: res.msg,
|
||||
data: {
|
||||
succMap: {
|
||||
[url]: url // 成功上传的文件 URL
|
||||
},
|
||||
errFiles: [] // 失败的文件列表
|
||||
}
|
||||
});
|
||||
}
|
||||
// 如果上传失败,返回错误信息
|
||||
return JSON.stringify({
|
||||
msg: res.msg,
|
||||
data: {
|
||||
succMap: {},
|
||||
errFiles: files.map(file => file.name) // 所有文件标记为失败
|
||||
}
|
||||
});
|
||||
},
|
||||
// 文件上传的字段名
|
||||
fieldName: 'file',
|
||||
// 文件大小限制(单位:字节)
|
||||
max: 10 * 1024 * 1024 // 10MB
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const stopHandle = watch(
|
||||
() => theme.darkMode,
|
||||
newValue => {
|
||||
const themeMode = newValue ? 'dark' : 'classic';
|
||||
vditor.value?.setTheme(themeMode);
|
||||
}
|
||||
);
|
||||
|
||||
onMounted(() => {
|
||||
renderVditor();
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
stopHandle();
|
||||
});
|
||||
|
||||
defineExpose({
|
||||
vditor
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div ref="domRef"></div>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
Reference in New Issue
Block a user