core net vue 图片上传_.net core vue+wangEditor (双向绑定) 上传图片和视频功能

最终效果,是这样的,现在开始记录怎么做:

开始 npm 安装 wangEditor

安装好后,

因为要用vue 双向绑定 ,所以 我就把wangwangEditor 做成了一个封装组件,先看一下目录 :

我是把wangEditor写在了my-components这个项目下,新建一个 vue组件,代码如下:

import E from 'wangeditor'

export default {

name: 'editorElem',

data() {

return {

editor: null,

editorContent: ''

}

},

props: ['catchData', 'content'], // 接收父组件的方法

watch: {

content() {

this.editor.txt.html(this.content)

}

},

mounted() {

var imgUrl = "";

this.editor = new E(this.$refs.editorElem)

this.editor.customConfig.onchange = (html) => {

this.editorContent = html

this.catchData(this.editorContent) // 把这个html通过catchData的方法传入父组件

}

this.editor.customConfig.uploadImgServer = '/api/Media/OnPostUpload'

this.editor.customConfig.uploadVideoServer="/api/Media/OnPostUploadVideo" // 或 /node_modules/wangeditor/release/wangEditor.js 里直接写上传视频接口

// 下面是最重要的的方法

this.editor.customConfig.uploadImgHooks = {

before: function (xhr, editor, files) {

// 图片上传之前触发

// xhr 是 XMLHttpRequst 对象,editor 是编辑器对象,files 是选择的图片文件

// 如果返回的结果是 {prevent: true, msg: 'xxxx'} 则表示用户放弃上传

// return {

// prevent: true,

// msg: '放弃上传'

// }

},

success: function (xhr, editor, result) {

// 图片上传并返回结果,图片插入成功之后触发

// xhr 是 XMLHttpRequst 对象,editor 是编辑器对象,result 是服务器端返回的结果

this.imgUrl = Object.values(result.data).toString()

},

fail: function (xhr, editor, result) {

debugger;

var res = xhr.data;

// 图片上传并返回结果,但图片插入错误时触发

// xhr 是 XMLHttpRequst 对象,editor 是编辑器对象,result 是服务器端返回的结果

},

error: function (xhr, editor) {

debugger;

// 图片上传出错时触发

// xhr 是 XMLHttpRequst 对象,editor 是编辑器对象

},

timeout: function (xhr, editor) {

// 图片上传超时时触发

// xhr 是 XMLHttpRequst 对象,editor 是编辑器对象

},

// 如果服务器端返回的不是 {errno:0, data: [...]} 这种格式,可使用该配置

// (但是,服务器端返回的必须是一个 JSON 格式字符串!!!否则会报错)

customInsert: function (insertImg, result, editor) {

// 图片上传并返回结果,自定义插入图片的事件(而不是编辑器自动插入图片!!!)

// insertImg 是插入图片的函数,editor 是编辑器对象,result 是服务器端返回的结果

// 举例:假如上传图片成功后,服务器端返回的是 {url:'....'} 这种格式,即可这样插入图片:

let url = Object.values(result.data) // result.data就是服务器返回的图片名字和链接

JSON.stringify(url) // 在这里转成JSON格式

insertImg(url)

// result 必须是一个 JSON 格式字符串!!!否则报错

},

};

this.editor.customConfig.debug = true;

this.editor.create() // 创建富文本实例

if (!this.content) {

this.editor.txt.html('请编辑内容1')

}

}

}

然后,再在主页面上,引用 ,和感觉和后端差不多

(:content 这里就是双向绑定)

import editorElem from "../../my-components/Editor.vue";

export default {

name: "editor",

components: {

editorElem

}

}

接着,开始改wangEidotr的视频上传代码,原wangEidotr上传视频用的不怎么好,所以我就去网上找了大神的( https://blog.csdn.net/m0_37885651/article/details/83660206 )代码修改了一下,

先找到wangEidotr.js

//

/*menu - video*/

//构造函数

function Video(editor) {this.editor =editor;this.$elem = $('

this._active = false;

}//原型

Video.prototype ={

constructor: Video,

onClick: function onClick() {this._createInsertPanel();

},

_createInsertPanel: function _createInsertPanel() {var editor = this.editor;var uploadVideo =editor.uploadVideo;var config =editor.config;//id

var upTriggerId = getRandom('up-trigger');var upFileId = getRandom('up-file');//tabs 的配置

var tabsConfig =[{

title:'上传 video',

tpl:'

\n' +

'

\n' +

'\n

\n' +

'

\n \n' +

'

\n
',

events: [{//触发选择视频

selector: '#' +upTriggerId,

type:'click',

fn: function fn() {var $file = $('#' +upFileId);var fileElem = $file[0];if(fileElem) {

fileElem.click();

}else{//返回 true 可关闭 panel

return true;

}

}

}, {//选择视频完毕

selector: '#' +upFileId,

type:'change',

fn: function fn() {var $file = $('#' +upFileId);var fileElem = $file[0];if (!fileElem) {//返回 true 可关闭 panel

return true;

}//获取选中的 file 对象列表

var fileList =fileElem.files;if(fileList.length) {

uploadVideo.uploadVideo(fileList);

}//返回 true 可关闭 panel

return true;

}

}]

}

];//tabs end//判断 tabs 的显示

var tabsConfigResult =[];

tabsConfigResult.push(tabsConfig[0]);//创建 panel 并显示

var panel = new Panel(this, {

width:300,

tabs: tabsConfigResult

});

panel.show();//记录属性

this.panel =panel;

},//试图改变 active 状态

tryChangeActive: function tryChangeActive(e) {var editor = this.editor;var $elem = this.$elem;if(editor._selectedImg) {this._active = true;

$elem.addClass('w-e-active');

}else{this._active = false;

$elem.removeClass('w-e-active');

}

}

};/*所有菜单的汇总*/

//存储菜单的构造函数

var MenuConstructors ={};

MenuConstructors.video= Video;

//构造函数

function UploadVideo(editor) {this.editor =editor;

}//原型

UploadVideo.prototype ={

constructor: UploadVideo,//根据 debug 弹出不同的信息

_alert: function _alert(alertInfo, debugInfo) {var editor = this.editor;var debug =editor.config.debug;//var debug = true;

var customAlert =editor.config.customAlert;if(debug) {throw new Error('wangEditor:' + (debugInfo ||alertInfo));

}else{if (customAlert && typeof customAlert === 'function') {

customAlert(alertInfo);

}else{

alert(alertInfo);

}

}

},//插入视频的方法 需要单独定义

insertLinkVideo:function(link){var _this3 = this;if (!link) {return;

}var editor = this.editor;var config =editor.config;//校验格式

var linkVideoCheck =config.linkVideoCheck;var checkResult = void 0;if (linkVideoCheck && linkVideoCheck === 'function') {

checkResult=linkVideoCheck(link);if (typeof checkResult === 'string') {//校验失败,提示信息

alert(checkResult);return;

}

}

editor.cmd.do('insertHTML', '');//验证视频 url 是否有效,无效的话给出提示

var video = document.createElement('video');

video.οnlοad=function () {var callback =config.linkVideoCallback;if (callback && typeof callback === 'function') {

callback(link);

}

video= null;

};

video.οnerrοr=function () {

video= null;//无法成功下载图片

_this2._alert('插入视频错误', 'wangEditor: \u63D2\u5165\u56FE\u7247\u51FA\u9519\uFF0C\u56FE\u7247\u94FE\u63A5\u662F "' + link + '"\uFF0C\u4E0B\u8F7D\u8BE5\u94FE\u63A5\u5931\u8D25');return;

};

video.οnabοrt=function () {

video= null;

};

video.src=link;

},//上传视频

uploadVideo: function uploadVideo(files) {var _this3 = this;if (!files || !files.length) {return;

}//------------------------------ 获取配置信息 ------------------------------

var editor = this.editor;var config =editor.config;var uploadVideoServer = "/video/uploadVideo";//上传地址

var maxSize = 100 * 1024 * 1024; //100M

var maxSizeM = maxSize / 1000 / 1000;var maxLength = 1;var uploadFileName = "file";var uploadVideoParams = config.uploadVideoParams ||{};var uploadVideoHeaders ={};var hooks =config.uploadImgHooks ||{};var timeout = 5 * 60 * 1000; //5 min

var withCredentials =config.withCredentials;if (withCredentials == null) {

withCredentials= false;

}//------------------------------ 验证文件信息 ------------------------------

var resultFiles =[];var errInfo =[];

arrForEach(files, function (file) {var name =file.name;var size =file.size;//chrome 低版本 name === undefined

if (!name || !size) {return;

}if (/\.(mp4)$/i.test(name) === false) {//后缀名不合法,不是视频

errInfo.push('\u3010' + name + '\u3011\u4e0d\u662f\u89c6\u9891');return;

}if (maxSize

errInfo.push('\u3010' + name + '\u3011\u5927\u4E8E' + maxSizeM + 'M');return;

}//验证通过的加入结果列表

resultFiles.push(file);

});//抛出验证信息

if(errInfo.length) {this._alert('视频验证未通过: \n' + errInfo.join('\n'));return;

}if (resultFiles.length >maxLength) {this._alert('一次最多上传' + maxLength + '个视频');return;

}//------------------------------ 自定义上传 ------------------------------//添加视频数据

var formdata = newFormData();

arrForEach(resultFiles, function (file) {var name = uploadFileName ||file.name;

formdata.append(name, file);

});//------------------------------ 上传视频 ------------------------------

if (uploadVideoServer && typeof uploadVideoServer === 'string') {//添加参数

var uploadVideoServer = uploadVideoServer.split('#');

uploadVideoServer= uploadVideoServer[0];var uploadVideoServerHash = uploadVideoServer[1] || '';

objForEach(uploadVideoParams, function (key, val) {

val=encodeURIComponent(val);//第一,将参数拼接到 url 中

if(uploadVideoParamsWithUrl) {if (uploadVideoServer.indexOf('?') > 0) {

uploadVideoServer+= '&';

}else{

uploadVideoServer+= '?';

}

uploadVideoServer= uploadVideoServer + key + '=' +val;

}//第二,将参数添加到 formdata 中

formdata.append(key, val);

});if(uploadVideoServerHash) {

uploadVideoServer+= '#' +uploadVideoServerHash;

}//定义 xhr

var xhr = newXMLHttpRequest();

xhr.open('POST', uploadVideoServer);//设置超时

xhr.timeout =timeout;

xhr.ontimeout=function () {//hook - timeout

if (hooks.timeout && typeof hooks.timeout === 'function') {

hooks.timeout(xhr, editor);

}

_this3._alert('上传视频超时');

};//监控 progress

if(xhr.upload) {

xhr.upload.οnprοgress=function (e) {var percent = void 0;//进度条

var progressBar = newProgress(editor);if(e.lengthComputable) {

percent= e.loaded /e.total;

progressBar.show(percent);

}

};

}//返回数据

xhr.onreadystatechange =function () {var result = void 0;if (xhr.readyState === 4) {if (xhr.status < 200 || xhr.status >= 300) {//hook - error

if (hooks.error && typeof hooks.error === 'function') {

hooks.error(xhr, editor);

}//xhr 返回状态错误

_this3._alert('上传视频发生错误', '\u4E0A\u4F20\u56FE\u7247\u53D1\u751F\u9519\u8BEF\uFF0C\u670D\u52A1\u5668\u8FD4\u56DE\u72B6\u6001\u662F' +xhr.status);return;

}

result=xhr.responseText;if ((typeof result === 'undefined' ? 'undefined' : _typeof(result)) !== 'object') {try{

console.log(result);

result=JSON.parse(result);

}catch(ex) {//hook - fail

if (hooks.fail && typeof hooks.fail === 'function') {

hooks.fail(xhr, editor, result);

}

_this3._alert('上传视频失败', '上传视频返回结果错误,返回结果是:' +result);return;

}

}if (!hooks.customInsert && result.errno == '0') {//hook - fail

if (hooks.fail && typeof hooks.fail === 'function') {

hooks.fail(xhr, editor, result);

}//数据错误

_this3._alert('上传视频失败', '上传视频返回结果错误,返回结果 errno=' +result.errno);

}else{if (hooks.customInsert && typeof hooks.customInsert === 'function') {

hooks.customInsert(_this3.insertLinkVideo.bind(_this3), result, editor);

}else{//将视频插入编辑器

var data = result ||[];//data.forEach(function (link) {//console.log(link);//

//});

_this3.insertLinkVideo(data.url);

}//hook - success

if (hooks.success && typeof hooks.success === 'function') {

hooks.success(xhr, editor, result);

}

}

}

};//hook - before

if (hooks.before && typeof hooks.before === 'function') {var beforeResult =hooks.before(xhr, editor, resultFiles);if (beforeResult && (typeof beforeResult === 'undefined' ? 'undefined' : _typeof(beforeResult)) === 'object') {if(beforeResult.prevent) {//如果返回的结果是 {prevent: true, msg: 'xxxx'} 则表示用户放弃上传

this._alert(beforeResult.msg);return;

}

}

}//自定义 headers

objForEach(uploadVideoHeaders, function (key, val) {

xhr.setRequestHeader(key, val);

});//跨域传 cookie

xhr.withCredentials =withCredentials;//发送请求

xhr.send(formdata);//注意,要 return 。不去操作接下来的 base64 显示方式

return;

}

}

};

//修改原型

Editor.prototype ={

constructor: Editor,//添加视频上传

_initUploadVideo: function _initUploadVideo() {this.uploadVideo = new UploadVideo(this);

},//创建编辑器

create: function create() {//添加 视频上传

this._initUploadVideo();

},

};

1,源码里找到Video 的构造函数 还有它的prototype,替换成第一部分。(有版本是一样的,可以不替换)

2,找到UploadImg的构造函数,还有它的prototype,这是上传图片的,相应的 你在这后面 加上第二部分UploadVideo的构造和原型,这是专门写的上传视频的。

3,在Editor原型上加个方法,_initUploadVideo , 然后在 创建编辑器 create 里面执行 this._initUploadVideo() ,加上就可以。

下面是后端代码:

#region 上传图片 OnPostUpload[HttpPost]public async TaskOnPostUpload([FromServices]IHostingEnvironment environment)

{

List fileUrl = new List();var files =Request.Form.Files;if (string.IsNullOrWhiteSpace(environment.WebRootPath))

{

environment.WebRootPath= Path.Combine(Directory.GetCurrentDirectory(), "wwwroot");

}string webRootPath =environment.WebRootPath;string filePath = Path.Combine(webRootPath + "\\upload\\images");if (!Directory.Exists(filePath))

{

Directory.CreateDirectory(filePath);

}foreach (var formFile infiles)

{if (formFile.Length > 0)

{var ext =Path.GetExtension(formFile.FileName);if (!pictureFormatArray.Contains(ext.Split('.')[1]))

{return new JsonResult(TmpUrl.ErrorInfo("图片格式不正确!", null));

}var fileName = Guid.NewGuid().ToString() +ext;var path = Path.Combine(webRootPath + "\\upload\\images", fileName);using (var stream = newFileStream(path, FileMode.CreateNew))

{awaitformFile.CopyToAsync(stream);

fileUrl.Add($"/api/Media/ShowNoticeImg?filePath={fileName}");

}

}

}return new JsonResult(TmpUrl.SuccessInfo("ok!", fileUrl));

}#endregion

#region 上传视频 OnPostUploadVideo[HttpPost]public async TaskOnPostUploadVideo([FromServices]IHostingEnvironment environment)

{

List fileUrl = new List();var files =Request.Form.Files;if (string.IsNullOrWhiteSpace(environment.WebRootPath))

{

environment.WebRootPath= Path.Combine(Directory.GetCurrentDirectory(), "wwwroot");

}string webRootPath =environment.WebRootPath;string filePath = Path.Combine(webRootPath + "\\upload\\videos");if (!Directory.Exists(filePath))

{

Directory.CreateDirectory(filePath);

}foreach (var formFile infiles)

{if (formFile.Length > 0)

{var ext =Path.GetExtension(formFile.FileName);if (!videoFormatArray.Contains(ext.Split('.')[1]))

{return new JsonResult(TmpUrl.ErrorInfo("视频格式不正确!", null));

}var fileName = Guid.NewGuid().ToString() +ext;var path = Path.Combine(webRootPath + "\\upload\\videos", fileName);using (var stream = newFileStream(path, FileMode.CreateNew))

{awaitformFile.CopyToAsync(stream);//fileUrl.Add($"/upload/videos/{fileName}");

fileUrl.Add("http://localhost:15429/upload/videos/8e11ae8e-8ecc-4b7c-afac-43601530493f.mp4");

}

}

}return new JsonResult(TmpUrl.SuccessInfo("ok!", fileUrl));

}#endregion

#region 获取图片流 ShowNoticeImg

public IActionResult ShowNoticeImg(stringfilePath)

{var contentTypeStr = "image/jpeg";string webRootPath = Path.Combine(Directory.GetCurrentDirectory(), $"wwwroot\\upload\\images\\{filePath}");using (var sw = newFileStream(webRootPath, FileMode.Open))

{var bytes = new byte[sw.Length];

sw.Read(bytes,0, bytes.Length);

sw.Close();return newFileContentResult(bytes, contentTypeStr);

}

}#endregion

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值