Files
2026-08-08 18:27:38 +08:00

96 lines
3.6 KiB
PHP

@props(['name' => 'body', 'value' => ''])
{{-- Quill 富文本编辑器(本地化,零构建,不依赖外部 CDN)。提交前把 HTML 同步进隐藏 textarea。 --}}
<link rel="stylesheet" href="{{ asset('vendor/quill/quill.snow.css') }}">
<div class="rich-editor">
<div id="quill-{{ $name }}"></div>
</div>
<textarea name="{{ $name }}" id="quill-input-{{ $name }}" hidden>{{ $value }}</textarea>
<script src="{{ asset('vendor/quill/quill.js') }}"></script>
<script>
(function () {
var FIELD = '{{ $name }}';
var input = document.getElementById('quill-input-' + FIELD);
if (typeof Quill === 'undefined' || !input) return;
var quill = new Quill('#quill-' + FIELD, {
theme: 'snow',
placeholder: '在此撰写文章正文,支持标题、列表、引用、代码与插入图片…',
modules: {
toolbar: {
container: [
[{ header: [1, 2, 3, false] }],
['bold', 'italic', 'underline', 'strike'],
[{ list: 'ordered' }, { list: 'bullet' }],
['blockquote', 'code-block'],
['link', 'image'],
['clean']
],
handlers: { image: imageHandler }
}
}
});
quill.root.innerHTML = input.value || '';
var form = input.closest('form');
if (form) {
form.addEventListener('submit', function () {
input.value = quill.root.innerHTML;
});
}
function imageHandler() {
var fileInput = document.createElement('input');
fileInput.type = 'file';
fileInput.accept = 'image/*';
fileInput.click();
fileInput.onchange = function () {
if (!fileInput.files.length) return;
var fd = new FormData();
fd.append('file', fileInput.files[0]);
var token = (document.querySelector('input[name=_token]') || {}).value || '';
fetch('{{ route('upload') }}', {
method: 'POST',
headers: { 'X-CSRF-TOKEN': token },
body: fd
})
.then(function (r) { return r.json(); })
.then(function (d) {
if (d.url) {
var range = quill.getSelection(true);
quill.insertEmbed(range.index, 'image', d.url, 'user');
} else if (d.errors && d.errors.file) {
alert(d.errors.file[0]);
} else {
alert('图片上传失败,请重试');
}
})
.catch(function () { alert('图片上传失败,请重试'); });
};
}
// 通用文件上传(封面图等),供表单内上传按钮 onclick="uploadFile('cover')" 调用
window.uploadFile = function (field) {
var fileInput = document.getElementById(field + '-file');
if (!fileInput || !fileInput.files.length) { alert('请先选择文件'); return; }
var fd = new FormData();
fd.append('file', fileInput.files[0]);
var token = (document.querySelector('input[name=_token]') || {}).value || '';
fetch('{{ route('upload') }}', {
method: 'POST',
headers: { 'X-CSRF-TOKEN': token },
body: fd
})
.then(function (r) { return r.json(); })
.then(function (d) {
if (d.url) { document.getElementById(field + '-url').value = d.url; }
else if (d.errors && d.errors.file) { alert(d.errors.file[0]); }
else { alert('上传失败,请重试'); }
})
.catch(function () { alert('上传失败,请重试'); });
};
})();
</script>