Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit eaedd25

Browse files
committed
图片支持拖拽、截图粘贴等方式上传
1 parent 41d1d63 commit eaedd25

File tree

7 files changed

+212
-15
lines changed

7 files changed

+212
-15
lines changed

src/http/controller/image.go

Lines changed: 75 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,59 @@ type ImageController struct{}
2929

3030
func (self ImageController) RegisterRoute(g *echo.Group) {
3131
g.POST("/image/upload", self.Upload)
32+
g.POST("/image/paste_upload", self.PasteUpload)
3233
g.POST("/image/quick_upload", self.QuickUpload)
3334
g.Match([]string{"GET", "POST"}, "/image/transfer", self.Transfer)
3435
}
3536

37+
// PasteUpload jquery 粘贴上传图片
38+
func (self ImageController) PasteUpload(ctx echo.Context) error {
39+
objLogger := getLogger(ctx)
40+
41+
file, fileHeader, err := Request(ctx).FormFile("imageFile")
42+
if err != nil {
43+
objLogger.Errorln("upload error:", err)
44+
return self.pasteUploadFail(ctx, err.Error())
45+
}
46+
defer file.Close()
47+
48+
// 如果是临时文件,存在硬盘中,则是 *os.File(大于32M),直接报错
49+
if _, ok := file.(*os.File); ok {
50+
objLogger.Errorln("upload error:file too large!")
51+
return self.pasteUploadFail(ctx, "文件太大!")
52+
}
53+
54+
buf, err := ioutil.ReadAll(file)
55+
if err != nil {
56+
return self.pasteUploadFail(ctx, "文件读取失败!")
57+
}
58+
if len(buf) > logic.MaxImageSize {
59+
return self.pasteUploadFail(ctx, "文件太大!")
60+
}
61+
62+
imgDir := times.Format("ymd")
63+
file.Seek(0, io.SeekStart)
64+
path, err := logic.DefaultUploader.UploadImage(ctx, file, imgDir, buf, filepath.Ext(fileHeader.Filename))
65+
if err != nil {
66+
return self.pasteUploadFail(ctx, "文件上传失败!")
67+
}
68+
69+
cdnDomain := global.App.CDNHttp
70+
if CheckIsHttps(ctx) {
71+
cdnDomain = global.App.CDNHttps
72+
}
73+
74+
data := map[string]interface{}{
75+
"success": 1,
76+
"message": cdnDomain + path,
77+
}
78+
b, err := json.Marshal(data)
79+
if err != nil {
80+
return err
81+
}
82+
return ctx.JSONBlob(http.StatusOK, b)
83+
}
84+
3685
// QuickUpload CKEditor 编辑器,上传图片,支持粘贴方式上传
3786
func (self ImageController) QuickUpload(ctx echo.Context) error {
3887
objLogger := getLogger(ctx)
@@ -83,20 +132,6 @@ func (self ImageController) QuickUpload(ctx echo.Context) error {
83132
return ctx.JSONBlob(http.StatusOK, b)
84133
}
85134

86-
func (ImageController) quickUploadFail(ctx echo.Context, message string) error {
87-
data := map[string]interface{}{
88-
"uploaded": 0,
89-
"error": map[string]string{
90-
"message": message,
91-
},
92-
}
93-
b, err := json.Marshal(data)
94-
if err != nil {
95-
return err
96-
}
97-
return ctx.JSONBlob(http.StatusOK, b)
98-
}
99-
100135
// Upload 上传图片
101136
func (ImageController) Upload(ctx echo.Context) error {
102137
objLogger := getLogger(ctx)
@@ -166,3 +201,29 @@ func (ImageController) Transfer(ctx echo.Context) error {
166201

167202
return success(ctx, map[string]interface{}{"url": cdnDomain + path})
168203
}
204+
205+
func (ImageController) quickUploadFail(ctx echo.Context, message string) error {
206+
data := map[string]interface{}{
207+
"uploaded": 0,
208+
"error": map[string]string{
209+
"message": message,
210+
},
211+
}
212+
b, err := json.Marshal(data)
213+
if err != nil {
214+
return err
215+
}
216+
return ctx.JSONBlob(http.StatusOK, b)
217+
}
218+
219+
func (ImageController) pasteUploadFail(ctx echo.Context, message string) error {
220+
data := map[string]interface{}{
221+
"success": 0,
222+
"message": message,
223+
}
224+
b, err := json.Marshal(data)
225+
if err != nil {
226+
return err
227+
}
228+
return ctx.JSONBlob(http.StatusOK, b)
229+
}

static/js/comment.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,9 @@
8787
$(this).parents('.reply-to').addClass('dn').data('floor', '').data('username', '');
8888
});
8989

90+
// 支持粘贴上传图片
91+
$('#comment-content').pasteUploadImage('/image/paste_upload');
92+
9093
emojify.setConfig({
9194
// emojify_tag_type : 'span',
9295
only_crawl_id : null,

static/js/libs/paste-upload-image.js

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
(function ($) {
2+
var $this;
3+
var $ajaxUrl = '';
4+
$.fn.pasteUploadImage = function (ajaxUrl) {
5+
$this = $(this);
6+
$ajaxUrl = ajaxUrl;
7+
$this.on('paste', function (event) {
8+
var filename, image, pasteEvent, text;
9+
pasteEvent = event.originalEvent;
10+
if (pasteEvent.clipboardData && pasteEvent.clipboardData.items) {
11+
image = isImage(pasteEvent);
12+
if (image) {
13+
event.preventDefault();
14+
filename = getFilename(pasteEvent) || "image.png";
15+
text = "{{" + filename + "(uploading...)}}";
16+
pasteText(text);
17+
return uploadFile(image.getAsFile(), filename);
18+
}
19+
}
20+
});
21+
$this.on('drop', function (event) {
22+
var filename, image, pasteEvent, text;
23+
pasteEvent = event.originalEvent;
24+
if (pasteEvent.dataTransfer && pasteEvent.dataTransfer.files) {
25+
image = isImageForDrop(pasteEvent);
26+
if (image) {
27+
event.preventDefault();
28+
filename = pasteEvent.dataTransfer.files[0].name || "image.png";
29+
text = "{{" + filename + "(uploading...)}}";
30+
pasteText(text);
31+
return uploadFile(image, filename);
32+
}
33+
}
34+
});
35+
};
36+
37+
pasteText = function (text) {
38+
var afterSelection, beforeSelection, caretEnd, caretStart, textEnd;
39+
caretStart = $this[0].selectionStart;
40+
caretEnd = $this[0].selectionEnd;
41+
textEnd = $this.val().length;
42+
beforeSelection = $this.val().substring(0, caretStart);
43+
afterSelection = $this.val().substring(caretEnd, textEnd);
44+
$this.val(beforeSelection + text + afterSelection);
45+
$this.get(0).setSelectionRange(caretStart + text.length, caretEnd + text.length);
46+
return $this.trigger("input");
47+
};
48+
isImage = function (data) {
49+
var i, item;
50+
i = 0;
51+
while (i < data.clipboardData.items.length) {
52+
item = data.clipboardData.items[i];
53+
if (item.type.indexOf("image") !== -1) {
54+
return item;
55+
}
56+
i++;
57+
}
58+
return false;
59+
};
60+
isImageForDrop = function (data) {
61+
var i, item;
62+
i = 0;
63+
while (i < data.dataTransfer.files.length) {
64+
item = data.dataTransfer.files[i];
65+
if (item.type.indexOf("image") !== -1) {
66+
return item;
67+
}
68+
i++;
69+
}
70+
return false;
71+
};
72+
getFilename = function (e) {
73+
var value;
74+
if (window.clipboardData && window.clipboardData.getData) {
75+
value = window.clipboardData.getData("Text");
76+
} else if (e.clipboardData && e.clipboardData.getData) {
77+
value = e.clipboardData.getData("text/plain");
78+
}
79+
value = value.split("\r");
80+
return value[0];
81+
};
82+
getMimeType = function (file, filename) {
83+
var mimeType = file.type;
84+
var extendName = filename.substring(filename.lastIndexOf('.') + 1);
85+
if (mimeType != 'image/' + extendName) {
86+
return 'image/' + extendName;
87+
}
88+
return mimeType
89+
};
90+
uploadFile = function (file, filename) {
91+
var formData = new FormData();
92+
formData.append('imageFile', file);
93+
formData.append("mimeType", getMimeType(file, filename));
94+
95+
$.ajax({
96+
url: $ajaxUrl,
97+
data: formData,
98+
type: 'post',
99+
processData: false,
100+
contentType: false,
101+
dataType: 'json',
102+
xhrFields: {
103+
withCredentials: true
104+
},
105+
success: function (data) {
106+
if (data.success) {
107+
return insertToTextArea(filename, data.message);
108+
}
109+
return replaceLoadingTest(filename);
110+
},
111+
error: function (xOptions, textStatus) {
112+
replaceLoadingTest(filename);
113+
console.log(xOptions.responseText);
114+
}
115+
});
116+
};
117+
insertToTextArea = function (filename, url) {
118+
return $this.val(function (index, val) {
119+
return val.replace("{{" + filename + "(uploading...)}}", "![" + filename + "](" + url + ")" + "\n");
120+
});
121+
};
122+
replaceLoadingTest = function (filename) {
123+
return $this.val(function (index, val) {
124+
return val.replace("{{" + filename + "(uploading...)}}", filename + "\n");
125+
});
126+
};
127+
})(jQuery);

template/common/comment.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
<li>请尽量让自己的回复能够对别人有帮助</li>
3535
<li class="markdown_tip">支持 Markdown 格式, <strong>**粗体**</strong>、~~删除线~~、<code>`单行代码`</code></li>
3636
<li>支持 @ 本站用户;支持表情(输入 : 提示),见 <a href="http://www.emoji-cheat-sheet.com/" target="_blank">Emoji cheat sheet</a></li>
37+
<li>图片支持拖拽、截图粘贴等方式上传</li>
3738
</ul>
3839
<div class="col-md-2 text-right"><button id="comment-submit" type="submit" title="提交" class="btn btn-default">提交</button></div>
3940
</div>

template/common/layout.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,7 @@
266266
</script>
267267
<script src="/static/js/common.js?v=1.2"></script>
268268
<script src="//cdn.bootcss.com/lscache/1.1.0/lscache.min.js"></script>
269+
<script type="text/javascript" src="/static/js/libs/paste-upload-image.js"></script>
269270
{{template "js" .}}
270271
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/jsrender/0.9.84/jsrender.min.js"></script>
271272
<script type="text/javascript">

template/topics/detail.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ <h1>
144144
<script type="text/javascript" src="/static/js/libs/emojis.js"></script>
145145
<script type="text/javascript" src="/static/js/libs/plupload.full.min.js"></script>
146146
<script type="text/javascript" src="/static/js/topics.js?v=1.4"></script>
147-
<script type="text/javascript" src="/static/js/comment.js?v=1.25"></script>
147+
<script type="text/javascript" src="/static/js/comment.js?v=1.26"></script>
148148
<script type="text/javascript" src="/static/js/puploader.js?v=1.2"></script>
149149
<script type="text/javascript">
150150
// 需要加载的侧边栏

template/topics/new.html

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,8 @@ <h3 class="title"><i class="glyphicon glyphicon-list-alt"></i>&nbsp;发帖提示
123123
<!-- <li>支持嵌入 Wide 的Playground 代码直接运行</li> -->
124124
</ul>
125125
<div class="sep10"></div>
126+
<div>图片支持拖拽、截图粘贴等方式上传。</div>
127+
<div class="sep10"></div>
126128
</li>
127129
<li>
128130
<span class="f13">选择节点</span>
@@ -243,6 +245,8 @@ <h3 class="title"><i class="glyphicon glyphicon-list-alt"></i>&nbsp;发帖提示
243245
$('#title,#content,#nid').on('change', function() {
244246
saveTopicComposeDraft();
245247
});
248+
249+
$('#content').pasteUploadImage('/image/paste_upload');
246250
});
247251
</script>
248252
{{end}}

0 commit comments

Comments
 (0)