Ai_GirlFriend/xunifriend_RaeeC/public/assets/js/addons.js
2026-01-31 19:15:41 +08:00

410 lines
20 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

define([], function () {
if (typeof Config.upload.storage !== 'undefined' && Config.upload.storage === 'alioss') {
require(['upload'], function (Upload) {
//获取文件MD5值
var getFileMd5 = function (file, cb) {
//如果savekey中未检测到md5则无需获取文件md5直接返回upload的uuid
if (!Config.upload.savekey.match(/\{(file)?md5\}/)) {
cb && cb(file.upload.uuid);
return;
}
require(['../addons/alioss/js/spark'], function (SparkMD5) {
var blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice,
chunkSize = 10 * 1024 * 1024,
chunks = Math.ceil(file.size / chunkSize),
currentChunk = 0,
spark = new SparkMD5.ArrayBuffer(),
fileReader = new FileReader();
fileReader.onload = function (e) {
spark.append(e.target.result);
currentChunk++;
if (currentChunk < chunks) {
loadNext();
} else {
cb && cb(spark.end());
}
};
fileReader.onerror = function () {
console.warn('文件读取错误');
};
function loadNext() {
var start = currentChunk * chunkSize,
end = ((start + chunkSize) >= file.size) ? file.size : start + chunkSize;
fileReader.readAsArrayBuffer(blobSlice.call(file, start, end));
}
loadNext();
});
};
var _onInit = Upload.events.onInit;
//初始化中完成判断
Upload.events.onInit = function () {
_onInit.apply(this, Array.prototype.slice.apply(arguments));
//如果上传接口不是阿里OSS则不处理
if (this.options.url !== Config.upload.uploadurl) {
return;
}
$.extend(this.options, {
//关闭自动处理队列功能
autoQueue: false,
params: function (files, xhr, chunk) {
var params = Config.upload.multipart;
if (chunk) {
return $.extend({}, params, {
filesize: chunk.file.size,
filename: chunk.file.name,
chunkid: chunk.file.upload.uuid,
chunkindex: chunk.index,
chunkcount: chunk.file.upload.totalChunkCount,
chunksize: this.options.chunkSize,
chunkfilesize: chunk.dataBlock.data.size,
width: chunk.file.width || 0,
height: chunk.file.height || 0,
type: chunk.file.type,
uploadId: chunk.file.uploadId,
key: chunk.file.key,
});
} else {
params = $.extend({}, params, files[0].params);
params.category = files[0].category || '';
}
return params;
},
chunkSuccess: function (chunk, file, response) {
var etag = chunk.xhr.getResponseHeader("ETag").replace(/(^")|("$)/g, '');
file.etags = file.etags ? file.etags : [];
file.etags[chunk.index] = etag;
},
chunksUploaded: function (file, done) {
var that = this;
Fast.api.ajax({
url: "/addons/alioss/index/upload",
data: {
action: 'merge',
filesize: file.size,
filename: file.name,
chunkid: file.upload.uuid,
chunkcount: file.upload.totalChunkCount,
md5: file.md5,
key: file.key,
uploadId: file.uploadId,
etags: file.etags,
category: file.category || '',
aliosstoken: Config.upload.multipart.aliosstoken,
},
}, function (data, ret) {
done(JSON.stringify(ret));
return false;
}, function (data, ret) {
file.accepted = false;
that._errorProcessing([file], ret.msg);
return false;
});
},
});
var _success = this.options.success;
//先移除已有的事件
this.off("success", _success).on("success", function (file, response) {
var ret = {code: 0, msg: response};
try {
if (response) {
ret = typeof response === 'string' ? JSON.parse(response) : response;
}
if (file.xhr.status === 200) {
if (Config.upload.uploadmode === 'client') {
ret = {code: 1, data: {url: '/' + file.key}};
var url = ret.data.url || '';
Fast.api.ajax({
url: "/addons/alioss/index/notify",
data: {name: file.name, url: url, md5: file.md5, size: file.size, width: file.width || 0, height: file.height || 0, type: file.type, category: file.category || '', aliosstoken: Config.upload.multipart.aliosstoken}
}, function () {
return false;
}, function () {
return false;
});
}
} else {
console.error(file.xhr);
}
} catch (e) {
console.error(e);
}
_success.call(this, file, ret);
});
this.on("addedfile", function (file) {
var that = this;
setTimeout(function () {
if (file.status === 'error') {
return;
}
getFileMd5(file, function (md5) {
var chunk = that.options.chunking && file.size > that.options.chunkSize ? 1 : 0;
var params = $(that.element).data("params") || {};
var category = typeof params.category !== 'undefined' ? params.category : ($(that.element).data("category") || '');
category = typeof category === 'function' ? category.call(that, file) : category;
Fast.api.ajax({
url: "/addons/alioss/index/params",
data: {method: 'POST', category: category, md5: md5, name: file.name, type: file.type, size: file.size, chunk: chunk, chunksize: that.options.chunkSize, aliosstoken: Config.upload.multipart.aliosstoken},
}, function (data) {
file.md5 = md5;
file.id = data.id;
file.key = data.key;
file.date = data.date;
file.uploadId = data.uploadId;
file.policy = data.policy;
file.signature = data.signature;
file.partsAuthorization = data.partsAuthorization;
file.params = data;
file.category = category;
if (file.status != 'error') {
//开始上传
that.enqueueFile(file);
} else {
that.removeFile(file);
}
return false;
}, function () {
that.removeFile(file);
});
});
}, 0);
});
if (Config.upload.uploadmode === 'client') {
var _method = this.options.method;
var _url = this.options.url;
this.options.method = function (files) {
if (files[0].upload.chunked) {
var chunk = null;
files[0].upload.chunks.forEach(function (item) {
if (item.status === 'uploading') {
chunk = item;
}
});
if (!chunk) {
return "POST";
} else {
return "PUT";
}
}
return _method;
};
this.options.url = function (files) {
if (files[0].upload.chunked) {
var chunk = null;
files[0].upload.chunks.forEach(function (item) {
if (item.status === 'uploading') {
chunk = item;
}
});
var index = chunk.dataBlock.chunkIndex;
// debugger;
this.options.headers = {"Authorization": "OSS " + files[0]['id'] + ":" + files[0]['partsAuthorization'][index], "x-oss-date": files[0]['date']};
if (!chunk) {
return Config.upload.uploadurl + "/" + files[0].key + "?uploadId=" + files[0].uploadId;
} else {
return Config.upload.uploadurl + "/" + files[0].key + "?partNumber=" + (index + 1) + "&uploadId=" + files[0].uploadId;
}
}
return _url;
};
this.on("sending", function (file, xhr, formData) {
var that = this;
if (file.upload.chunked) {
var _send = xhr.send;
xhr.send = function () {
var chunk = null;
file.upload.chunks.forEach(function (item) {
if (item.status == 'uploading') {
chunk = item;
}
});
if (chunk) {
_send.call(xhr, chunk.dataBlock.data);
}
};
}
});
}
};
});
}
require.config({
paths: {
'summernote': '../addons/summernote/lang/summernote-zh-CN.min',
'purify': '../addons/summernote/js/purify.min'
},
shim: {
'summernote': ['../addons/summernote/js/summernote.min', 'css!../addons/summernote/css/summernote.min.css'],
}
});
require(['form', 'upload'], function (Form, Upload) {
var _bindevent = Form.events.bindevent;
Form.events.bindevent = function (form) {
_bindevent.apply(this, [form]);
try {
//绑定summernote事件
if ($(Config.summernote.classname || '.editor', form).length > 0) {
var selectUrl = typeof Config !== 'undefined' && Config.modulename === 'index' ? 'user/attachment' : 'general/attachment/select';
require(['summernote', 'purify'], function (undefined, DOMPurify) {
var imageButton = function (context) {
var ui = $.summernote.ui;
var button = ui.button({
contents: '<i class="fa fa-file-image-o"/>',
tooltip: __('Choose'),
click: function () {
parent.Fast.api.open(selectUrl + "?element_id=&multiple=true&mimetype=image/", __('Choose'), {
callback: function (data) {
var urlArr = data.url.split(/\,/);
$.each(urlArr, function () {
var url = Fast.api.cdnurl(this, true);
context.invoke('editor.insertImage', url);
});
}
});
return false;
}
});
return button.render();
};
var attachmentButton = function (context) {
var ui = $.summernote.ui;
var button = ui.button({
contents: '<i class="fa fa-file"/>',
tooltip: __('Choose'),
click: function () {
parent.Fast.api.open(selectUrl + "?element_id=&multiple=true&mimetype=*", __('Choose'), {
callback: function (data) {
var urlArr = data.url.split(/\,/);
$.each(urlArr, function () {
var url = Fast.api.cdnurl(this, true);
var node = $("<a href='" + url + "'>" + url + "</a>");
context.invoke('insertNode', node[0]);
});
}
});
return false;
}
});
return button.render();
};
if (Config.summernote.isdompurify) {
// 添加 hook 过滤 iframe 来源
DOMPurify.addHook('uponSanitizeElement', function (node, data, config) {
if (data.tagName === 'iframe') {
var allowedIframePrefixes = Config.summernote.allowiframeprefixs || [];
var src = node.getAttribute('src');
// 判断是否匹配允许的前缀
var isAllowed = false;
for (var i = 0; i < allowedIframePrefixes.length; i++) {
if (src && src.indexOf(allowedIframePrefixes[i]) === 0) {
isAllowed = true;
break;
}
}
if (!isAllowed) {
// 不符合要求则移除该节点
return node.parentNode.removeChild(node);
}
// 添加安全属性
node.setAttribute('allowfullscreen', '');
node.setAttribute('allow', 'fullscreen');
}
});
var purifyOptions = {
ADD_TAGS: ['iframe'],
FORCE_REJECT_IFRAME: false
};
$.extend($.summernote.plugins, {
'dompurify': function (context) {
// 重写代码过滤方法
const originalPurify = context.options.modules.codeview.prototype.purify;
context.options.modules.codeview.prototype.purify = function (html) {
html = DOMPurify.sanitize(html, purifyOptions);
return originalPurify.call(this, html);
};
}
});
}
$(Config.summernote.classname || '.editor', form).each(function () {
$(this).summernote($.extend(true, {}, {
height: isNaN(Config.summernote.height) ? null : parseInt(Config.summernote.height),
minHeight: parseInt(Config.summernote.minHeight || 250),
toolbar: Config.summernote.toolbar,
followingToolbar: parseInt(Config.summernote.followingToolbar),
placeholder: Config.summernote.placeholder || '',
airMode: parseInt(Config.summernote.airMode) || false,
lang: 'zh-CN',
fontNames: Config.summernote.fontNames || [],
fontNamesIgnoreCheck: ["Open Sans", "Microsoft YaHei", '微软雅黑', '宋体', '黑体', '仿宋', '楷体', '幼圆'],
buttons: {
image: imageButton,
attachment: attachmentButton,
},
plugins: {
'dompurify': true
},
dialogsInBody: true,
callbacks: {
onChange: function (contents) {
if (Config.summernote.isdompurify) {
contents = DOMPurify.sanitize(contents, purifyOptions);
}
$(this).val(contents);
$(this).trigger('change');
},
onInit: function () {
},
onImageUpload: function (files) {
var that = this;
//依次上传图片
for (var i = 0; i < files.length; i++) {
Upload.api.send(files[i], function (data) {
var url = Fast.api.cdnurl(data.url, true);
$(that).summernote("insertImage", url, 'filename');
});
}
},
onPaste: function (e) {
if (Config.summernote.pasteAsPlainText || false) {
var bufferText = ((e.originalEvent || e).clipboardData || window.clipboardData).getData('Text');
e.preventDefault();
setTimeout(function () {
document.execCommand('insertText', false, bufferText);
}, 10);
}
}
}
}, $(this).data("summernote-options") || {}));
});
});
}
} catch (e) {
}
};
});
if (Config.modulename === 'index' && Config.controllername === 'user' && ['login', 'register'].indexOf(Config.actionname) > -1 && $("#register-form,#login-form").length > 0 && $(".social-login").length == 0) {
$("#register-form,#login-form").append(Config.third.loginhtml || '');
}
});