Added: cos support

This commit is contained in:
Molunerfinn 2017-12-21 11:18:54 +08:00
parent 6cf3a50023
commit 63f8cb631a
12 changed files with 269 additions and 6 deletions

View File

@ -59,6 +59,15 @@ function createTray () {
db.read().set('picBed.current', 'qiniu') db.read().set('picBed.current', 'qiniu')
.write() .write()
} }
},
{
label: '腾讯云COS',
type: 'radio',
checked: db.read().get('picBed.current').value() === 'tcyun',
click () {
db.read().set('picBed.current', 'tcyun')
.write()
}
} }
] ]
}, },

View File

@ -0,0 +1,90 @@
import request from 'request-promise'
import * as img2Base64 from './img2base64'
import db from '../../datastore/index'
import { Notification, clipboard } from 'electron'
import crypto from 'crypto'
// generate COS signature string
const generateSignature = () => {
const options = db.read().get('picBed.tcyun').value()
const secretId = options.secretId
const secretKey = options.secretKey
const appId = options.appId
const bucket = options.bucket
const random = Math.floor(Math.random() * 10000000000)
const current = parseInt(new Date().getTime() / 1000) - 1
const expired = current + 3600
const multiSignature = `a=${appId}&b=${bucket}&k=${secretId}&e=${expired}&t=${current}&r=${random}&f=`
const signHexKey = crypto.createHmac('sha1', secretKey).update(multiSignature).digest()
const tempString = Buffer.concat([signHexKey, Buffer.from(multiSignature)])
const signature = Buffer.from(tempString).toString('base64')
return {
signature,
appId,
bucket
}
}
const postOptions = (fileName, signature, imgBase64) => {
const area = db.read().get('picBed.tcyun.area').value()
const path = db.read().get('picBed.tcyun.path').value()
return {
method: 'POST',
url: `http://${area}.file.myqcloud.com/files/v2/${signature.appId}/${signature.bucket}/${path}${fileName}`,
headers: {
Host: `${area}.file.myqcloud.com`,
Authorization: signature.signature,
contentType: 'multipart/form-data'
},
formData: {
op: 'upload',
filecontent: Buffer.from(imgBase64, 'base64')
}
}
}
const tcYunUpload = async (img, type, webContents) => {
try {
webContents.send('uploadProgress', 0)
const imgList = await img2Base64[type](img)
webContents.send('uploadProgress', 30)
const singature = generateSignature()
const length = imgList.length
for (let i in imgList) {
const options = postOptions(imgList[i].fileName, singature, imgList[i].base64Image)
const res = await request(options)
const body = JSON.parse(res)
if (body.message === 'SUCCESS') {
delete imgList[i].base64Image
imgList[i]['imgUrl'] = body.data.source_url
imgList[i]['type'] = 'tcyun'
if (i - length === -1) {
webContents.send('uploadProgress', 60)
}
} else {
webContents.send('uploadProgress', -1)
const notification = new Notification({
title: '上传失败!',
body: res.body.msg
})
notification.show()
}
}
webContents.send('uploadProgress', 100)
return imgList
} catch (err) {
const body = JSON.parse(err.error)
webContents.send('uploadProgress', -1)
const notification = new Notification({
title: '上传失败!',
body: `错误码:${body.code},请打开浏览器粘贴地址查看相关原因。`
})
notification.show()
clipboard.writeText('https://cloud.tencent.com/document/product/436/8432')
throw new Error(err)
}
}
export default tcYunUpload

View File

@ -1,5 +1,6 @@
import weiboUpload from './weiboUpload' import weiboUpload from './weiboUpload'
import qiniuUpload from './qiniuUpload' import qiniuUpload from './qiniuUpload'
import tcYunUpload from './tcYunUpload'
import db from '../../datastore/index' import db from '../../datastore/index'
const uploader = (img, type, webContents) => { const uploader = (img, type, webContents) => {
const uploadType = db.read().get('picBed.current').value() const uploadType = db.read().get('picBed.current').value()
@ -8,6 +9,8 @@ const uploader = (img, type, webContents) => {
return weiboUpload(img, type, webContents) return weiboUpload(img, type, webContents)
case 'qiniu': case 'qiniu':
return qiniuUpload(img, type, webContents) return qiniuUpload(img, type, webContents)
case 'tcyun':
return tcYunUpload(img, type, webContents)
} }
} }

View File

@ -6,7 +6,7 @@ const j = request.jar()
const rp = request.defaults({jar: j}) const rp = request.defaults({jar: j})
const UPLOAD_URL = 'http://picupload.service.weibo.com/interface/pic_upload.php?ori=1&mime=image%2Fjpeg&data=base64&url=0&markpos=1&logo=&nick=0&marks=1&app=miniblog' const UPLOAD_URL = 'http://picupload.service.weibo.com/interface/pic_upload.php?ori=1&mime=image%2Fjpeg&data=base64&url=0&markpos=1&logo=&nick=0&marks=1&app=miniblog'
function postOptions (formData) { const postOptions = (formData) => {
return { return {
method: 'POST', method: 'POST',
url: 'https://passport.weibo.cn/sso/login', url: 'https://passport.weibo.cn/sso/login',

View File

@ -1,10 +1,10 @@
@font-face {font-family: "iconfont"; @font-face {font-family: "iconfont";
src: url('iconfont.eot?t=1512627299425'); /* IE9*/ src: url('iconfont.eot?t=1513753554908'); /* IE9*/
src: url('iconfont.eot?t=1512627299425#iefix') format('embedded-opentype'), /* IE6-IE8 */ src: url('iconfont.eot?t=1513753554908#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('data:application/x-font-woff;charset=utf-8;base64,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') format('woff'), url('data:application/x-font-woff;charset=utf-8;base64,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') format('woff'),
url('iconfont.ttf?t=1512627299425') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/ url('iconfont.ttf?t=1513753554908') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/
url('iconfont.svg?t=1512627299425#iconfont') format('svg'); /* iOS 4.1- */ url('iconfont.svg?t=1513753554908#iconfont') format('svg'); /* iOS 4.1- */
} }
[class*=" el-icon-ui"], [class^=el-icon-ui] { [class*=" el-icon-ui"], [class^=el-icon-ui] {
@ -17,7 +17,11 @@
.el-icon-ui-weibo:before { content: "\e61c"; } .el-icon-ui-weibo:before { content: "\e61c"; }
.el-icon-ui-tcyun:before { content: "\e64c"; }
.el-icon-ui-upload:before { content: "\e61b"; } .el-icon-ui-upload:before { content: "\e61b"; }
.el-icon-ui-qiniu:before { content: "\e601"; } .el-icon-ui-qiniu:before { content: "\e601"; }
.el-icon-ui-upyun:before { content: "\e602"; }

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 6.8 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -26,6 +26,10 @@
<i class="el-icon-ui-qiniu"></i> <i class="el-icon-ui-qiniu"></i>
<span slot="title">七牛设置</span> <span slot="title">七牛设置</span>
</el-menu-item> </el-menu-item>
<el-menu-item index="tcyun">
<i class="el-icon-ui-tcyun"></i>
<span slot="title">腾讯COS设置</span>
</el-menu-item>
</el-menu> </el-menu>
</el-col> </el-col>
<el-col :span="19" :offset="5"> <el-col :span="19" :offset="5">

View File

@ -0,0 +1,142 @@
<template>
<div id="tcyun-view">
<el-row :gutter="16">
<el-col :span="16" :offset="4">
<div class="view-title">
腾讯云COS设置
</div>
<el-form
ref="tcyun"
label-position="right"
label-width="120px"
:model="form"
size="mini">
<el-form-item
label="设定SecretId"
prop="secretId"
:rules="{
required: true, message: 'SecretId不能为空', trigger: 'blur'
}">
<el-input v-model="form.secretId" placeholder="SecretId" @keyup.native.enter="confirm('weiboForm')"></el-input>
</el-form-item>
<el-form-item
label="设定SecretKey"
prop="secretKey"
:rules="{
required: true, message: 'SecretKey不能为空', trigger: 'blur'
}">
<el-input v-model="form.secretKey" type="password" @keyup.native.enter="confirm" placeholder="SecretKey"></el-input>
</el-form-item>
<el-form-item
label="设定APPID"
prop="appId"
:rules="{
required: true, message: 'APPID不能为空', trigger: 'blur'
}">
<el-input v-model="form.appId" @keyup.native.enter="confirm" placeholder="例如1234567890"></el-input>
</el-form-item>
<el-form-item
label="设定存储空间名"
prop="bucket"
:rules="{
required: true, message: 'Bucket不能为空', trigger: 'blur'
}">
<el-input v-model="form.bucket" @keyup.native.enter="confirm" placeholder="Bucket"></el-input>
</el-form-item>
<el-form-item
label="确认存储区域"
prop="area"
:rules="{
required: true, message: '区域代码不能为空', trigger: 'blur'
}">
<el-input v-model="form.area" @keyup.native.enter="confirm" placeholder="例如tj"></el-input>
</el-form-item>
<el-form-item
label="指定存储路径"
>
<el-input v-model="form.path" @keyup.native.enter="confirm" placeholder="例如img/"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="confirm">确定</el-button>
</el-form-item>
</el-form>
</el-col>
</el-row>
</div>
</template>
<script>
import mixin from '../mixin'
export default {
name: 'tcyun',
mixins: [mixin],
data () {
return {
form: {
secretId: '',
secretKey: '',
bucket: '',
appId: '',
area: '',
path: ''
}
}
},
created () {
const config = this.$db.get('picBed.tcyun').value()
if (config) {
for (let i in config) {
this.form[i] = config[i]
}
}
},
methods: {
confirm () {
this.$refs.tcyun.validate((valid) => {
if (valid) {
this.$db.set('picBed.tcyun', this.form).write()
const successNotification = new window.Notification('设置结果', {
body: '设置成功'
})
successNotification.onclick = () => {
return true
}
} else {
return false
}
})
}
}
}
</script>
<style lang='stylus'>
.view-title
color #eee
font-size 20px
text-align center
margin 20px auto
#tcyun-view
.el-form
label
line-height 22px
padding-bottom 0
color #eee
.el-button
width 100%
border-radius 19px
.el-input__inner
border-radius 19px
.el-radio-group
width 100%
label
width 25%
.el-radio-button__inner
width 100%
.el-radio-button:first-child
.el-radio-button__inner
border-left none
border-radius 14px 0 0 14px
.el-radio-button:last-child
.el-radio-button__inner
border-left none
border-radius 0 14px 14px 0
</style>

View File

@ -30,6 +30,11 @@ export default new Router({
component: require('@/components/SettingView/Qiniu').default, component: require('@/components/SettingView/Qiniu').default,
name: 'qiniu' name: 'qiniu'
}, },
{
path: 'tcyun',
component: require('@/components/SettingView/TcYun').default,
name: 'tcyun'
},
{ {
path: 'gallery', path: 'gallery',
component: require('@/components/SettingView/Gallery').default, component: require('@/components/SettingView/Gallery').default,