MVC+API는 tinymce 서식 있는 텍스트 편집기를 구현하여 사진을 업로드하고 비디오를 업로드합니다.

첫 번째는 버전을 다운로드하는 것입니다. 여기에서는 제가 직접 사용할 수 있도록 GitHub에 올려 놓았습니다.

https://github.com/dhgr1/tinymce

예전에 공식 홈페이지나 다른 곳에서 해봤는데 오류가 뜨고 이유를 알 수가 없네요 직접 해보셔도 됩니다 제 버전은 이미 중국어 패키지와 다중 이미지에 필요한 플러그인 axupimgs가 포함되어 있습니다 업로드합니다.

여기서는 프로젝트의 Content에 있는 Scripts에 넣었습니다. 또 다른 포인트는 파일에 tinymce.d.ts 파일이 있다는 것입니다. 삭제하지 않으면 오류를 보고하겠습니다. 잘 모르겠습니다. 내 환경 문제라면 삭제해도 오류가 없고 달성하려는 작업에 영향을 미치지 않습니다.

첫 번째는 플러그인과 중국어 패키지를 인용하는 것입니다.

<script src="~/Content/Scripts/tinymce/js/tinymce/tinymce.min.js"></script>
<script src="~/Content/Scripts/tinymce/js/tinymce/langs/zh-Hans.js"></script>

그런 다음 초기화

<div><textarea id="mytextarea"></textarea></div>

<script>

    tinymce.init({
        menubar: false,
        //statusbar: false,
        selector: '#mytextarea',
        language: 'zh_CN',
        height: 500,
        branding: false,
        forced_root_block: '',
        plugins: "lists advlist anchor autosave code charmap codesample directionality emoticons hr image imagetools insertdatetime link table media pagebreak wordcount preview  nonbreaking print searchreplace toc code image axupimgs", //依赖lists插件
        toolbar1: "formatselect fontselect fontsizeselect | bold italic underline strikethrough /*link*/ hr removeformat | forecolor backcolor  | alignleft aligncenter alignright alignjustify | axupimgs media table  ",
        toolbar2: "preview print| subscript superscript anchor charmap emoticons nonbreaking pagebreak |  toc  searchreplace  insertdatetime | ltr rtl undo redo wordcount",
        images_upload_url: 'http://localhost:51624/api/JSL/pc_UploadServiceImg',
        
        images_upload_base_path: 'http://localhost:51624/',
        
        imagetools_cors_hosts: ['mydomain.com', 'otherdomain.com'],
        imagetools_proxy: 'proxy.php',
        images_upload_handler: function (blobInfo, succFun, failFun) {
            var xhr, formData;
            var file = blobInfo.blob();//转化为易于理解的file对象
            xhr = new XMLHttpRequest();
            xhr.withCredentials = false;
            xhr.open('POST', 'http://localhost:51624/api/JSL/pc_UploadServiceImg');
            xhr.onload = function () {
                var json;
                if (xhr.status != 200) {
                    failFun('HTTP Error: ' + xhr.status);
                    return;
                }
                json = JSON.parse(xhr.responseText);
                if (!json || typeof json.location != 'string') {
                    failFun('Invalid JSON: ' + xhr.responseText);
                    return;
                }
                succFun(json.location);
            };
            formData = new FormData();
            formData.append('file', file, file.name);
            xhr.send(formData);
        },
        //自定义文件选择器的回调内容 此方法只有在点击上方图片按钮才会触发
        file_picker_callback: function (callback, value, meta) {
            if (meta.filetype === "media") {
                // 模拟上传本地视频
                let input = document.createElement("input");
                input.setAttribute("type", "file");
                input.setAttribute("accept", ".mp4");
                input.onchange = function () {
                    let file = this.files[0];
                    // console.log(file);
                    let fd = new FormData();
                    fd.append("img", file);
                    $axfile("/api/JSL/pc_UploadVideo", fd, true, "POST", "json", header, function (data) {
                        //debugger
                        console.log(data)
                        let rr = data.result;
                        // callback 回调的作用是将所选择的视频的url显示在输入框中
                        callback($autoCompleteUrl()+rr);
                       
                    });
                };
                input.click();
            }
        },
        init_instance_callback: function (editor) {
              editor.setContent(item.商品步骤)
        }
    });

</script>

menubar 속성은 맨 위 줄을 표시하지 않는 텍스트 탐색을 설정하는 데 사용됩니다.

 selector는 컨테이너를 바인딩하는 데 사용되는 고유 식별자입니다.

언어는 구속력 있는 언어이고 다른 언어도 있습니다. 자세한 내용은 공식 웹사이트에서 확인할 수 있으므로 더 이상 언급하지 않겠습니다.

1. 사진 업로드

단일 이미지만 업로드하려면 images_upload_url 및 images_upload_base_path만 구성하면 됩니다.

여러 이미지를 업로드하려면 먼저 플러그인에 코드 이미지 axupimgs를 추가해야 합니다. 여기에 직접 사용할 수 있습니다. 경로를 자신의 API로 바꾸십시오.

/// <summary>
        /// 图片上传
        /// </summary>
        [AllowAnonymous]
        [HttpPost]
        public Object pc_UploadServiceImg()
        {
            var files = HttpContext.Current.Request.Files;
            var form = HttpContext.Current.Request.Form;
            string basePath = AppDomain.CurrentDomain.BaseDirectory;
            string filePath = "Files/wttp";
            int limitFileSize = 1024 * 1024 * 20;

            string fullPath = basePath + filePath;
            string savePath = "";

            //如果目录不存在,则创建目录
            if (!Directory.Exists(fullPath))
            {
                Directory.CreateDirectory(fullPath);
            }

            if (files.Count > 0)
            {
                foreach (var key in files.AllKeys)
                {
                    var file = files[key];
                    //校验文件类型
                    string fileExtension = Path.GetExtension(file.FileName);
                    string fileMimeType = MimeMapping.GetMimeMapping(file.FileName);
                    string[] fileTypeWhiteList = new string[] { ".jpg", ".jpeg", ".png", ".gif" };
                    string[] fileMimeTypeWhiteList = new string[] { "image/jpg", "image/jpeg", "image/png", "image/gif" };
                    if (!fileTypeWhiteList.Contains(fileExtension.ToLower()) || !fileMimeTypeWhiteList.Contains(fileMimeType))
                    {
                        throw new Exception($"文件{file.FileName}是不支持的文件类型!");
                    }

                    if (file.ContentLength > limitFileSize)
                    {
                        throw new Exception($"文件{file.FileName}超出大小限制,请处理后上传!");
                    }

                    if (!string.IsNullOrEmpty(file.FileName))
                    {
                        string fileName = Guid.NewGuid().ToString("N") + Path.GetExtension(file.FileName);
                        savePath = filePath + "/" + fileName;
                        file.SaveAs(fullPath + "/" + fileName);
                    }
                }
                var obj = new { location = savePath };
                //return new Response
                //{
                //    Result = savePath  //savePath
                //};
                return obj;
            }
            else
            {
                throw new Exception("上传失败,未接收到请求文件!");
            }
        }

제 배경화면에 사진을 올리는 방식입니다 반환되는 형식에 주의하세요 형식이 틀리면 사진이 나오지 않습니다

2. 동영상 업로드

배포 file_picker_callback

내 백엔드 비디오 업로드를 위한 인터페이스는 다음과 같습니다.

public object pc_UploadVideo()
        {
            StringBuilder builder = new StringBuilder();

            HttpRequest request = HttpContext.Current.Request;

            //if (request.ContentLength > 20 * 1024 * 1024)
            //{
            //    throw new Exception("上传的文件不能超过20M!");
            //}

            string sFileName = "";
            string FilePath = "";

            HttpPostedFile postedFile = null;
            int sl = HttpContext.Current.Request.Files.Count;
            if (sl > 0)
            {
                for (int i = 0; i < sl; i++)
                {
                    postedFile = HttpContext.Current.Request.Files[i];

                    string rootDictory = AppDomain.CurrentDomain.BaseDirectory;
                    string filePath = "Files/jslgoodsvideo/";
                    rootDictory += filePath;
                    if (!Directory.Exists(rootDictory))
                    {
                        Directory.CreateDirectory(rootDictory);
                    }

                    string filename = Path.GetFileName(postedFile.FileName);

                    string fileExtension = Path.GetExtension(postedFile.FileName);//文件后缀

                    string gid = Guid.NewGuid().ToString().Replace("-", "");

                    sFileName = rootDictory + gid + fileExtension; //文件地址 + 文件名

                    FilePath = filePath + gid + fileExtension;

                    postedFile.SaveAs(sFileName);


                }
                return new Response
                {
                    Result = FilePath  //savePath
                };
            }
            else
            {
                throw new Exception("上传失败,未接收到请求文件!");
            }
        }

3. 개발 중 만난 버그 및 해결 방법

1. 리치 텍스트 콘텐츠 설정 시 null의 'setContent' 속성을 읽을 수 없습니다.

init_instance_callback에서 이 설정의 내용을 설정해야 합니다. 즉, 코드가 초기화될 때까지 기다려야 합니다.

2. 여러 서식 있는 텍스트 편집기를 순환하려는 경우 첫 번째 편집기만 작동합니다.

이는 선택자 바인딩이 고유성을 보장해야 하고 동일한 항목이 한 번만 초기화될 수 있기 때문입니다.

따라서 해당 값을 동적으로 변경해야 하므로 접합 방법 var id = 'mytextarea' + item.id(동적으로 변경된 값), var domId = '#' + id;

선택기는 domId에 바인딩되어 있으며 정상입니다.

3. 인터페이스에서 값을 가져와서 서식 있는 텍스트에 할당하기 위해 반복해야 하는 경우 마지막 값만 가져옵니다.

전에는 값을 할당하기 위해 for 루프를 사용했는데 이런 문제가 발생합니다. 여기서는 foreach 루프만 사용할 수 있습니다. 이는 for 루프가 순간적으로 실행되고, 변수가 하나뿐이기 때문입니다. 하나의 값, 즉 마지막 값을 저장하는 반면 forEach()는 각 루프가 기록할 다른 변수를 생성하기 때문에 해당 값을 올바르게 찾을 수 있습니다.

4. 리치텍스트 편집기의 내용을 백그라운드로 옮겨서 데이터베이스에 저장해야 할 때 내용이 틀리다

이는 리치 텍스트의 콘텐츠가 html 콘텐츠이고 프런트 엔드 값이 필요할 때 encodeURIComponent가 추가되기 때문입니다.()

전달해야 하는 값을 괄호 안에 넣어 모든 태그의 스타일이 지정되고 올바르게 전달될 수 있도록 합니다.

Java에서 들어오는 문자열에 대해 작업해야 하는 경우 다음과 같은 방법으로 디코딩할 수 있습니다.

 java.net.URLDecoder.decode(works, "UTF-8");

데이터가 에코되면 올바른 데이터를 표시하기 위해 js의 decodeURIComponent()에 의해 디코딩됩니다 .

위의 내용은 저의 개발 과정을 요약한 것입니다. 여러분에게 도움이 되기를 바랍니다.

추천

출처blog.csdn.net/growb/article/details/124660164