196 lines
4.4 KiB
Vue
196 lines
4.4 KiB
Vue
<script lang="ts" setup>
|
|
import {MdEditor,MdPreview} from 'md-editor-v3';
|
|
import 'md-editor-v3/lib/style.css';
|
|
import {v4 as uuidv4} from 'uuid';
|
|
import {useMainLayoutStore} from "~/strores/UseMainLayoutStore";
|
|
import {useToast} from "vue-toastification";
|
|
import dayjs from "dayjs";
|
|
|
|
const props=defineProps({
|
|
wordId:{
|
|
type:String,
|
|
default:null
|
|
},
|
|
preview:{
|
|
type:Boolean,
|
|
default:false
|
|
},
|
|
template:{
|
|
type:String,
|
|
default: `# ${dayjs().format()}`
|
|
},
|
|
closeCallBack:{
|
|
type:Function,
|
|
default:()=>{}
|
|
}
|
|
})
|
|
const text = ref<string>(props.template);
|
|
const mainLayoutStore=useMainLayoutStore()
|
|
const toast=useToast()
|
|
const filenameVisible=ref(false)
|
|
|
|
let id = uuidv4();
|
|
const fileName = ref<string|null>(null);
|
|
const saveFileName=()=>{
|
|
if(fileName.value===null||fileName.value===''){
|
|
toast.error('文件名不能为空')
|
|
if(fileName.value!==null&&fileName.value.length<=6){
|
|
toast.error('文件名不能小于6位')
|
|
}
|
|
return
|
|
}
|
|
filenameVisible.value=false
|
|
uploadFile()
|
|
}
|
|
const onUploadImg = async (files: any[], callback: Function) => {
|
|
const res = await Promise.all(
|
|
files.map((file) => {
|
|
return new Promise((rev, rej) => {
|
|
const form = new FormData();
|
|
form.append('file', file);
|
|
$fetch('/Api/PublicFile/UploadImage', {
|
|
method: 'POST',
|
|
body: form,
|
|
headers: {
|
|
'Authorization': "Bearer " + useCookie('token').value
|
|
},
|
|
baseURL: useRuntimeConfig().public.baseUrl,
|
|
}).then(
|
|
|
|
(res:any) => {
|
|
toast.success('上传成功')
|
|
rev(`${useRuntimeConfig().public.baseUrl}${res.fileUrl}`)
|
|
},
|
|
).catch((err) => {
|
|
toast.error('上传失败'+err)
|
|
rej(err)
|
|
})
|
|
})
|
|
})
|
|
);
|
|
|
|
callback(res.map((item) => item));
|
|
};
|
|
const onSave = (v:string, _:string) => {
|
|
if(fileName.value===null||fileName.value===''&&fileName.value.length<=6){
|
|
filenameVisible.value=true
|
|
return
|
|
}
|
|
uploadFile()
|
|
};
|
|
const uploadFile=()=>{
|
|
$fetch('/Api/Server/UpLoadWord', {
|
|
method: 'POST',
|
|
params:{
|
|
serverId: mainLayoutStore.SelectServer.value,
|
|
userName:mainLayoutStore.UserInfo.userName,
|
|
wordId: id,
|
|
},
|
|
body: {
|
|
name: fileName.value,
|
|
content: text.value
|
|
},
|
|
headers: {
|
|
'Authorization': "Bearer " + useCookie('token').value
|
|
},
|
|
baseURL: useRuntimeConfig().public.baseUrl,
|
|
}).then(
|
|
(res:any) => {
|
|
toast.success(res,{
|
|
timeout:1000
|
|
})
|
|
},
|
|
)
|
|
}
|
|
onBeforeMount(()=>{
|
|
if(props.wordId){
|
|
id=props.wordId
|
|
$fetch('/Api/Server/GetWordContent', {
|
|
method: 'GET',
|
|
params:{
|
|
serverId: mainLayoutStore.SelectServer.value,
|
|
wordId: props.wordId,
|
|
},
|
|
headers: {
|
|
"content-type": "application/json",
|
|
'Authorization': "Bearer " + useCookie('token').value
|
|
},
|
|
baseURL: useRuntimeConfig().public.baseUrl,
|
|
}).then(
|
|
(res:any) =>{
|
|
text.value=res.content
|
|
fileName.value=res.wordName
|
|
}
|
|
)
|
|
}
|
|
})
|
|
</script>
|
|
|
|
<template>
|
|
<div class="editor-layout">
|
|
<n-modal
|
|
v-model:show="filenameVisible"
|
|
preset="dialog"
|
|
title="输入文件名"
|
|
>
|
|
<div class="fileName">
|
|
<input v-model="fileName">
|
|
<n-button type="info" @click="saveFileName">
|
|
保存
|
|
</n-button>
|
|
</div>
|
|
</n-modal>
|
|
<MdEditor v-model="text" v-if="!preview" :theme="$colorMode.value as 'light'| 'dark'" class="editor" codeTheme="kimbie"
|
|
@onSave="onSave" @onUploadImg="onUploadImg" />
|
|
<MdPreview :modelValue="text" v-else class="editor-preview"/>
|
|
</div>
|
|
</template>
|
|
|
|
<style lang="scss" scoped>
|
|
@import "base";
|
|
|
|
.editor-layout {
|
|
height: 80vh;
|
|
display: flex;
|
|
justify-content: center;
|
|
}
|
|
|
|
.editor {
|
|
width: 80vw;
|
|
height: 100%;
|
|
border-radius: $radius;
|
|
border: $border;
|
|
}
|
|
.editor-preview{
|
|
border-radius: $radius;
|
|
width: 40vw;
|
|
min-width: 1000px;
|
|
}
|
|
.fileName{
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
gap: $gap*4;
|
|
input{
|
|
flex: 1;
|
|
border: $border;
|
|
background: rgba(51, 51, 51, 0.1);
|
|
border-radius: $radius;
|
|
padding: $padding;
|
|
}
|
|
}
|
|
.actions{
|
|
position: absolute;
|
|
z-index: 20;
|
|
top: 10px;
|
|
right: 10px;
|
|
svg{
|
|
cursor: pointer;
|
|
stroke: $light-text-color;
|
|
color: $light-text-color;
|
|
&:hover{
|
|
stroke: red;
|
|
}
|
|
}
|
|
}
|
|
</style> |