富文本内新增:插入视频,上传视频
This commit is contained in:
		
							parent
							
								
									776dbb5c69
								
							
						
					
					
						commit
						be7c359f6c
					
				| @ -140,9 +140,6 @@ const toolbarConfig = { | |||||||
|   showLinkImg: false, |   showLinkImg: false, | ||||||
|   uploadImgShowBase64: true, |   uploadImgShowBase64: true, | ||||||
|   excludeKeys: [ |   excludeKeys: [ | ||||||
|     'insertVideo', // 删除视频 |  | ||||||
|     'uploadVideo', |  | ||||||
|     'group-video', |  | ||||||
|     'insertImage',// 删除网络图片上传 |     'insertImage',// 删除网络图片上传 | ||||||
|     'insertLink',// 删除链接 |     'insertLink',// 删除链接 | ||||||
|     'insertTable',// 删除表格 |     'insertTable',// 删除表格 | ||||||
| @ -172,6 +169,25 @@ const editorConfig = { | |||||||
|           koiNoticeError('图片限制为1M,请调整好再上传!'); |           koiNoticeError('图片限制为1M,请调整好再上传!'); | ||||||
|         } |         } | ||||||
|       }, |       }, | ||||||
|  |     }, | ||||||
|  |     uploadVideo: { | ||||||
|  |       maxFileSize: 50 * 1024 * 1024, | ||||||
|  |       server: import.meta.env.VITE_WEB_BASE_API + '/api/common/upload', | ||||||
|  |       fieldName: 'file', | ||||||
|  |       meta: { | ||||||
|  |         association_id: 0, | ||||||
|  |       }, | ||||||
|  |       customInsert(res, insertFn) {  // TS 语法 | ||||||
|  |         // customInsert(res, insertFn) {                  // JS 语法 | ||||||
|  |         // res 即服务端的返回结果 | ||||||
|  |         console.log(res); | ||||||
|  |         // 从 res 中找到 url alt href ,然后插入图片 | ||||||
|  |         insertFn(res.data.fullurl, '', '') | ||||||
|  |       }, onError: (file, err, res) => { | ||||||
|  |         if (err.message.indexOf('exceeds maximum allowed size') !== -1) { | ||||||
|  |           koiNoticeError('视频限制为50M,请调整好再上传!'); | ||||||
|  |         } | ||||||
|  |       }, | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  | |||||||
| @ -4,16 +4,17 @@ | |||||||
|       <el-row :gutter="20"> |       <el-row :gutter="20"> | ||||||
|         <el-col :span="8"> |         <el-col :span="8"> | ||||||
|           <div style="padding: 0px 20px 20px 0px;font-weight: 600">请在图片边框内选定区域</div> |           <div style="padding: 0px 20px 20px 0px;font-weight: 600">请在图片边框内选定区域</div> | ||||||
|           <el-card :body-style="{padding:'0'}" style="padding: 0;position:relative;"> |           <el-card :body-style="{ padding: '0' }" style="padding: 0;position:relative;"> | ||||||
|             <div @mousedown="startDrag" @mousemove="onDrag" @mouseup="endDrag" @mouseleave="endDrag" style="width: 100%"> |             <div @mousedown="startDrag" @mousemove="onDrag" @mouseup="endDrag" @mouseleave="endDrag" | ||||||
|  |               style="width: 100%"> | ||||||
|               <!-- 图片 --> |               <!-- 图片 --> | ||||||
|               <img draggable="false" id="image-selector" :src="bmInfoData.bm_img" ref="image" alt="image" |               <img draggable="false" id="image-selector" :src="bmInfoData.bm_img" ref="image" alt="image" | ||||||
|                    @click="handleClick" |                 @click="handleClick" | ||||||
|                    style="cursor: crosshair; position: relative; user-select: none; width: 100%; height: auto;" |                 style="cursor: crosshair; position: relative; user-select: none; width: 100%; height: auto;" | ||||||
|                    @load="onImageLoad"/> |                 @load="onImageLoad" /> | ||||||
|               <!-- 画布用于绘制矩形路径 --> |               <!-- 画布用于绘制矩形路径 --> | ||||||
|               <canvas id="myCanvas" ref="canvas" :width="imageWidth" :height="imageHeight" |               <canvas id="myCanvas" ref="canvas" :width="imageWidth" :height="imageHeight" | ||||||
|                       style="position: absolute; top: 0; left: 0; pointer-events: none;"> |                 style="position: absolute; top: 0; left: 0; pointer-events: none;"> | ||||||
|               </canvas> |               </canvas> | ||||||
|             </div> |             </div> | ||||||
|           </el-card> |           </el-card> | ||||||
| @ -21,29 +22,29 @@ | |||||||
|         <el-col :span="16"> |         <el-col :span="16"> | ||||||
|           <el-form :model="form" label-width="auto"> |           <el-form :model="form" label-width="auto"> | ||||||
|             <el-form-item label="新闻标题" required> |             <el-form-item label="新闻标题" required> | ||||||
|               <el-input v-model="form.new_name" placeholder="请输入新闻标题" size="large"/> |               <el-input v-model="form.new_name" placeholder="请输入新闻标题" size="large" /> | ||||||
|             </el-form-item> |             </el-form-item> | ||||||
|             <el-form-item label="新闻副标题"> |             <el-form-item label="新闻副标题"> | ||||||
|               <el-input v-model="form.subtitle" placeholder="请输入新闻副标题" size="large"/> |               <el-input v-model="form.subtitle" placeholder="请输入新闻副标题" size="large" /> | ||||||
|             </el-form-item> |             </el-form-item> | ||||||
|             <el-form-item label="新闻记者" required> |             <el-form-item label="新闻记者" required> | ||||||
|               <el-input v-model="form.reporter" placeholder="请输入新闻记者" size="large"/> |               <el-input v-model="form.reporter" placeholder="请输入新闻记者" size="large" /> | ||||||
|             </el-form-item> |             </el-form-item> | ||||||
|             <el-form-item label="新闻坐标" required> |             <el-form-item label="新闻坐标" required> | ||||||
|               <el-input disabled v-model="coordinate" placeholder="请选择新闻坐标" size="large"/> |               <el-input disabled v-model="coordinate" placeholder="请选择新闻坐标" size="large" /> | ||||||
|               <el-button class="mt-2" @click="allowClickTrue()">重新选择</el-button> |               <el-button class="mt-2" @click="allowClickTrue()">重新选择</el-button> | ||||||
|             </el-form-item> |             </el-form-item> | ||||||
|             <el-form-item label="媒体链接"> |             <el-form-item label="媒体链接"> | ||||||
|               <el-input v-model="form.video" placeholder="请输入媒体链接" size="large"/> |               <el-input v-model="form.video" placeholder="请输入媒体链接" size="large" /> | ||||||
|             </el-form-item> |             </el-form-item> | ||||||
|             <el-form-item label="跳转链接"> |             <el-form-item label="跳转链接"> | ||||||
|               <el-input v-model="form.jump_link" placeholder="请输入跳转链接" size="large"/> |               <el-input v-model="form.jump_link" placeholder="请输入跳转链接" size="large" /> | ||||||
|             </el-form-item> |             </el-form-item> | ||||||
|             <el-form-item label="新闻详情" required> |             <el-form-item label="新闻详情" required> | ||||||
|               <el-card shadow="hover"> |               <el-card shadow="hover"> | ||||||
|                 <Toolbar style="border-bottom: 1px solid #ccc" :editor="editorRef" :defaultConfig="toolbarConfig"/> |                 <Toolbar style="border-bottom: 1px solid #ccc" :editor="editorRef" :defaultConfig="toolbarConfig" /> | ||||||
|                 <Editor style="height: 300px; overflow-y: hidden;" v-model="form.content" :defaultConfig="editorConfig" |                 <Editor style="height: 300px; overflow-y: hidden;" v-model="form.content" :defaultConfig="editorConfig" | ||||||
|                         @onCreated="handleCreated"/> |                   @onCreated="handleCreated" /> | ||||||
|               </el-card> |               </el-card> | ||||||
|             </el-form-item> |             </el-form-item> | ||||||
|             <el-form-item label=" "> |             <el-form-item label=" "> | ||||||
| @ -59,24 +60,24 @@ | |||||||
| 
 | 
 | ||||||
| <script setup lang="ts"> | <script setup lang="ts"> | ||||||
| import '@wangeditor/editor/dist/css/style.css' // 引入 css | import '@wangeditor/editor/dist/css/style.css' // 引入 css | ||||||
| import {getAssets} from "@/utils/index.ts"; | import { getAssets } from "@/utils/index.ts"; | ||||||
| import {onBeforeUnmount, ref, shallowRef, onMounted, reactive, nextTick} from 'vue' | import { onBeforeUnmount, ref, shallowRef, onMounted, reactive, nextTick } from 'vue' | ||||||
| import {Editor, Toolbar} from '@wangeditor/editor-for-vue' | import { Editor, Toolbar } from '@wangeditor/editor-for-vue' | ||||||
| import {bmInfo, newsAdd, newsInfo, newsUpdate} from "@/api/system/post"; | import { bmInfo, newsAdd, newsInfo, newsUpdate } from "@/api/system/post"; | ||||||
| import {koiNoticeError, koiNoticeSuccess} from "@/utils/koi.ts"; | import { koiNoticeError, koiNoticeSuccess } from "@/utils/koi.ts"; | ||||||
| import {useRoute, useRouter} from 'vue-router'; | import { useRoute, useRouter } from 'vue-router'; | ||||||
| import useTabsStore from "@/stores/modules/tabs.ts"; // 导入 useRoute | import useTabsStore from "@/stores/modules/tabs.ts"; // 导入 useRoute | ||||||
| const router = useRouter(); | const router = useRouter(); | ||||||
| const tabsStore = useTabsStore(); | const tabsStore = useTabsStore(); | ||||||
| const form = reactive({ | const form = reactive({ | ||||||
|   new_name: '', |   new_name: '', | ||||||
|   coordinate: '', |   coordinate: '', | ||||||
|   coordinate_show:'', |   coordinate_show: '', | ||||||
|   subtitle: '', |   subtitle: '', | ||||||
|   reporter: '', |   reporter: '', | ||||||
|   content: '', |   content: '', | ||||||
|   video: '', |   video: '', | ||||||
|   jump_link:'', |   jump_link: '', | ||||||
| }); | }); | ||||||
| /*新闻坐标  真实的*/ | /*新闻坐标  真实的*/ | ||||||
| const coordinate = ref(); | const coordinate = ref(); | ||||||
| @ -92,7 +93,7 @@ onMounted(() => { | |||||||
| }) | }) | ||||||
| const getNewsInfo = async () => { | const getNewsInfo = async () => { | ||||||
|   try { |   try { | ||||||
|     const res: any = await newsInfo({id: id.value}); |     const res: any = await newsInfo({ id: id.value }); | ||||||
|     console.log("菜单数据表格数据->", res.data); |     console.log("菜单数据表格数据->", res.data); | ||||||
|     form.new_name = res.data.new_name; |     form.new_name = res.data.new_name; | ||||||
|     form.subtitle = res.data.subtitle; |     form.subtitle = res.data.subtitle; | ||||||
| @ -101,7 +102,7 @@ const getNewsInfo = async () => { | |||||||
|     form.id = res.data.id; |     form.id = res.data.id; | ||||||
|     form.bm_id = res.data.bm_id; |     form.bm_id = res.data.bm_id; | ||||||
|     form.coordinate = res.data.coordinate; |     form.coordinate = res.data.coordinate; | ||||||
|     form.coordinate_show=res.data.coordinate_show; |     form.coordinate_show = res.data.coordinate_show; | ||||||
|     form.video = res.data.video; |     form.video = res.data.video; | ||||||
|     form.jump_link = res.data.jump_link; |     form.jump_link = res.data.jump_link; | ||||||
|     coordinate.value = res.data.coordinate; |     coordinate.value = res.data.coordinate; | ||||||
| @ -117,7 +118,7 @@ const getNewsInfo = async () => { | |||||||
| } | } | ||||||
| const getBmInfo = async (bm_id) => { | const getBmInfo = async (bm_id) => { | ||||||
|   try { |   try { | ||||||
|     const res: any = await bmInfo({id: bm_id}); |     const res: any = await bmInfo({ id: bm_id }); | ||||||
|     console.log("菜单数据表格数据->", res.data); |     console.log("菜单数据表格数据->", res.data); | ||||||
|     bmInfoData.value = res.data; |     bmInfoData.value = res.data; | ||||||
|     var coordArray = coordinateShow.value.split(","); |     var coordArray = coordinateShow.value.split(","); | ||||||
| @ -126,7 +127,7 @@ const getBmInfo = async (bm_id) => { | |||||||
|     var yy1 = parseInt(sArray[1]); |     var yy1 = parseInt(sArray[1]); | ||||||
|     var xx2 = parseInt(sArray[2]); |     var xx2 = parseInt(sArray[2]); | ||||||
|     var yy2 = parseInt(sArray[3]); |     var yy2 = parseInt(sArray[3]); | ||||||
|     s.value = {xx1, yy1, xx2, yy2}; |     s.value = { xx1, yy1, xx2, yy2 }; | ||||||
|     var x1 = parseInt(coordArray[0]); |     var x1 = parseInt(coordArray[0]); | ||||||
|     var y1 = parseInt(coordArray[1]); |     var y1 = parseInt(coordArray[1]); | ||||||
|     var x2 = parseInt(coordArray[2]); |     var x2 = parseInt(coordArray[2]); | ||||||
| @ -139,7 +140,7 @@ const getBmInfo = async (bm_id) => { | |||||||
|   } |   } | ||||||
| } | } | ||||||
| const updateDrawRectanglePath = (x1, y1, x2, y2) => { | const updateDrawRectanglePath = (x1, y1, x2, y2) => { | ||||||
|   rectCoordinates.value = {x1, y1, x2, y2}; |   rectCoordinates.value = { x1, y1, x2, y2 }; | ||||||
|   // 显示矩形(用于视觉反馈) |   // 显示矩形(用于视觉反馈) | ||||||
|   rect.value = { |   rect.value = { | ||||||
|     left: `${x1}px`, |     left: `${x1}px`, | ||||||
| @ -161,7 +162,7 @@ const updateDrawRectanglePath = (x1, y1, x2, y2) => { | |||||||
| /*文章保存*/ | /*文章保存*/ | ||||||
| const onSubmit = async () => { | const onSubmit = async () => { | ||||||
|   form.coordinate = coordinate.value; |   form.coordinate = coordinate.value; | ||||||
|   form.coordinate_show=coordinateShow.value ; |   form.coordinate_show = coordinateShow.value; | ||||||
|   console.log(form); |   console.log(form); | ||||||
|   try { |   try { | ||||||
|     const res: any = await newsUpdate(form); |     const res: any = await newsUpdate(form); | ||||||
| @ -179,9 +180,6 @@ const toolbarConfig = { | |||||||
|   showLinkImg: false, |   showLinkImg: false, | ||||||
|   uploadImgShowBase64: true, |   uploadImgShowBase64: true, | ||||||
|   excludeKeys: [ |   excludeKeys: [ | ||||||
|     'insertVideo', // 删除视频 |  | ||||||
|     'uploadVideo', |  | ||||||
|     'group-video', |  | ||||||
|     'insertImage',// 删除网络图片上传 |     'insertImage',// 删除网络图片上传 | ||||||
|     'insertLink',// 删除链接 |     'insertLink',// 删除链接 | ||||||
|     'insertTable',// 删除表格 |     'insertTable',// 删除表格 | ||||||
| @ -206,11 +204,30 @@ const editorConfig = { | |||||||
|         console.log(res); |         console.log(res); | ||||||
|         // 从 res 中找到 url alt href ,然后插入图片 |         // 从 res 中找到 url alt href ,然后插入图片 | ||||||
|         insertFn(res.data.fullurl, '', '') |         insertFn(res.data.fullurl, '', '') | ||||||
|       }, onError:(file, err, res)=>{ |       }, onError: (file, err, res) => { | ||||||
|         if(err.message.indexOf('exceeds maximum allowed size') !== -1){ |         if (err.message.indexOf('exceeds maximum allowed size') !== -1) { | ||||||
|           koiNoticeError('图片限制为1M,请调整好再上传!'); |           koiNoticeError('图片限制为1M,请调整好再上传!'); | ||||||
|         } |         } | ||||||
|       }, |       }, | ||||||
|  |     }, | ||||||
|  |     uploadVideo: { | ||||||
|  |       maxFileSize: 50 * 1024 * 1024, | ||||||
|  |       server: import.meta.env.VITE_WEB_BASE_API + '/api/common/upload', | ||||||
|  |       fieldName: 'file', | ||||||
|  |       meta: { | ||||||
|  |         association_id: 0, | ||||||
|  |       }, | ||||||
|  |       customInsert(res, insertFn) {  // TS 语法 | ||||||
|  |         // customInsert(res, insertFn) {                  // JS 语法 | ||||||
|  |         // res 即服务端的返回结果 | ||||||
|  |         console.log(res); | ||||||
|  |         // 从 res 中找到 url alt href ,然后插入图片 | ||||||
|  |         insertFn(res.data.fullurl, '', '') | ||||||
|  |       }, onError: (file, err, res) => { | ||||||
|  |         if (err.message.indexOf('exceeds maximum allowed size') !== -1) { | ||||||
|  |           koiNoticeError('视频限制为50M,请调整好再上传!'); | ||||||
|  |         } | ||||||
|  |       }, | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
| @ -238,7 +255,7 @@ const imageWidth = ref(0); // 图片宽度 | |||||||
| const imageHeight = ref(0); // 图片高度 | const imageHeight = ref(0); // 图片高度 | ||||||
| const imageLoaded = ref(false); // 确保图片加载完成 | const imageLoaded = ref(false); // 确保图片加载完成 | ||||||
| const isDragging = ref(false); // 是否正在拖动 | const isDragging = ref(false); // 是否正在拖动 | ||||||
| const dragStart = ref({x: 0, y: 0}); // 拖动开始的坐标 | const dragStart = ref({ x: 0, y: 0 }); // 拖动开始的坐标 | ||||||
| const allowClick = ref(true); // 是否允许点击 | const allowClick = ref(true); // 是否允许点击 | ||||||
| 
 | 
 | ||||||
| const allowClickTrue = () => { | const allowClickTrue = () => { | ||||||
| @ -274,8 +291,8 @@ const handleClick = (event) => { | |||||||
|   const x = event.clientX - rect.left; |   const x = event.clientX - rect.left; | ||||||
|   const y = event.clientY - rect.top; |   const y = event.clientY - rect.top; | ||||||
|   // 保存点击的坐标 |   // 保存点击的坐标 | ||||||
|   points.value.push({x, y}); |   points.value.push({ x, y }); | ||||||
|   showPoints.value.push({xx, yy}); |   showPoints.value.push({ xx, yy }); | ||||||
|   console.log(`Clicked at: (${x}, ${y})`); // 调试信息 |   console.log(`Clicked at: (${x}, ${y})`); // 调试信息 | ||||||
|   console.log(`Clicked at a: (${xx}, ${yy})`); // 调试信息 |   console.log(`Clicked at a: (${xx}, ${yy})`); // 调试信息 | ||||||
|   // 确保 canvas 元素存在后再绘制 |   // 确保 canvas 元素存在后再绘制 | ||||||
| @ -333,8 +350,8 @@ const showCalculateRectangle = () => { | |||||||
|   const yy1 = Math.min(p1.yy, p2.yy, p3.yy, p4.yy); |   const yy1 = Math.min(p1.yy, p2.yy, p3.yy, p4.yy); | ||||||
|   const xx2 = Math.max(p1.xx, p2.xx, p3.xx, p4.xx); |   const xx2 = Math.max(p1.xx, p2.xx, p3.xx, p4.xx); | ||||||
|   const yy2 = Math.max(p1.yy, p2.yy, p3.yy, p4.yy); |   const yy2 = Math.max(p1.yy, p2.yy, p3.yy, p4.yy); | ||||||
|   s.value = {xx1, yy1, xx2, yy2}; |   s.value = { xx1, yy1, xx2, yy2 }; | ||||||
|   console.log('s',  s.value); |   console.log('s', s.value); | ||||||
|   coordinate.value = `${xx1},${yy1},${xx2},${yy2}`; |   coordinate.value = `${xx1},${yy1},${xx2},${yy2}`; | ||||||
| }; | }; | ||||||
| // 计算矩形坐标 | // 计算矩形坐标 | ||||||
| @ -346,7 +363,7 @@ const calculateRectangle = () => { | |||||||
|   const x2 = Math.max(p1.x, p2.x, p3.x, p4.x); |   const x2 = Math.max(p1.x, p2.x, p3.x, p4.x); | ||||||
|   const y2 = Math.max(p1.y, p2.y, p3.y, p4.y); |   const y2 = Math.max(p1.y, p2.y, p3.y, p4.y); | ||||||
| 
 | 
 | ||||||
|   rectCoordinates.value = {x1, y1, x2, y2}; |   rectCoordinates.value = { x1, y1, x2, y2 }; | ||||||
| 
 | 
 | ||||||
|   // 显示矩形(用于视觉反馈) |   // 显示矩形(用于视觉反馈) | ||||||
|   rect.value = { |   rect.value = { | ||||||
| @ -401,7 +418,7 @@ const startDrag = (event: MouseEvent) => { | |||||||
|   if (rectCoordinates.value) { // 确保矩形已绘制 |   if (rectCoordinates.value) { // 确保矩形已绘制 | ||||||
|     isDragging.value = true; |     isDragging.value = true; | ||||||
|     allowClick.value = false; // 禁止点击 |     allowClick.value = false; // 禁止点击 | ||||||
|     dragStart.value = {x: event.clientX, y: event.clientY}; |     dragStart.value = { x: event.clientX, y: event.clientY }; | ||||||
|   } |   } | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| @ -415,15 +432,15 @@ const onDrag = (event) => { | |||||||
|     rectCoordinates.value.y1 += dy; |     rectCoordinates.value.y1 += dy; | ||||||
|     rectCoordinates.value.x2 += dx; |     rectCoordinates.value.x2 += dx; | ||||||
|     rectCoordinates.value.y2 += dy; |     rectCoordinates.value.y2 += dy; | ||||||
|     console.log( s.value) |     console.log(s.value) | ||||||
|     // 更新矩形坐标 |     // 更新矩形坐标 | ||||||
|      s.value.xx1 += dx; |     s.value.xx1 += dx; | ||||||
|      s.value.yy1 += dy; |     s.value.yy1 += dy; | ||||||
|      s.value.xx2 += dx; |     s.value.xx2 += dx; | ||||||
|      s.value.yy2 += dy; |     s.value.yy2 += dy; | ||||||
|     coordinate.value = `${s.value.xx1},${s.value.yy1},${s.value.xx2},${s.value.yy2}`; |     coordinate.value = `${s.value.xx1},${s.value.yy1},${s.value.xx2},${s.value.yy2}`; | ||||||
|     // 更新拖动起始点 |     // 更新拖动起始点 | ||||||
|     dragStart.value = {x: event.clientX, y: event.clientY}; |     dragStart.value = { x: event.clientX, y: event.clientY }; | ||||||
|     // 重新绘制矩形 |     // 重新绘制矩形 | ||||||
|     drawRectanglePath(rectCoordinates.value.x1, rectCoordinates.value.y1, rectCoordinates.value.x2, rectCoordinates.value.y2); |     drawRectanglePath(rectCoordinates.value.x1, rectCoordinates.value.y1, rectCoordinates.value.x2, rectCoordinates.value.y2); | ||||||
|   } |   } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user