咋想的
每次上传图到七牛云,都需要登录七牛云找到仓库,上传。步骤有些繁琐。所以自己做个上传的小工具。
- 自己画的原型图————简单、明了、好看

步骤
- 1、拖拽和选择图片,获取图片信息
- 2、获取上传token
- 3、点击上传
- 4、包装electron —— 简简单单的四步
搭建
- 1、
create-react-app image-updata搭建一个名字为image-updata的项目 这一步有必要且先执行这一步 这时候yarn start就可以看到react页面里
- 2、
yarn eject||npm run eject可以显示出webpack配置文件 (修改了启动端口,默认3000 —— 不改也行,修改了静态文件打包路径,改成了相对路径 --不改也行。。。)- 修改启动端口
修改scripts/start.js 的DEFAULT_PORT (scripts文件夹没有?执行yarn eject)

- 修改静态文件打包路径
在yarn build 的时候build文件夹下的index.html里引入文件都用的是绝对路径,会找不到,---所以可以修改打包路径
修改config/paths.js 的 getServedPage方法里的 servedUrl这块'/'改成'./'
在执行
yarn eject之后可能会报错,一般是缺少包,缺啥补啥就好
yarn add @babel/helper-create-regexp-features-plugin
- 修改启动端口
修改scripts/start.js 的DEFAULT_PORT (scripts文件夹没有?执行yarn eject)
开始写页面
- 这里就比较简单,就一个页面所以把App.js改改就好
- 一开始是这样的

- 简单改改之后(结构就这样的)
<div className="App">
<div className="content" key="content">
<div className="set-button">
<span onClick={()=>{}}>上传</span>
</div>
<div className="select-content">
<div className="into">
<ul>
<li>图片名称</li>
</ul>
<p>将图片拖入</p>
<p style={{marginTop:'30px',paddingTop:0}}>100%</p>
<p style={{marginTop:'30px',paddingTop:0}}>提示文字</p>
</div>
<div className="select-image-button">
<input className="iamge-file" type="file" onChange={()=>{}}/>
<span>选择图片</span>
</div>
</div>
</div>
<div className="updata-url" key="updata-url">
<p>图片url:</p>
<p className="image-url">图片地址</p>
<p className="copy" onClick={this.urlCopy}>点击复制</p>
<input
className="copy_content"
type="text"
value=""
onChange={()=>{}}
style={{position: 'absolute','top':0,'left': 0,'opacity': 0,'zIndex':'-10'}}
/>
</div>
</div>
- 样式修改App.css,我就不多说了
- 这时候的页面

开始步骤 1 拖拽和选择图片获取图片信息
- 1、拖拽图片放下的时候获取图片信息
pullImageFunct(){ // 拖拽图片获取
this.dropEle = document.querySelector('.into'); // 监听的鼠标放下区域
const thse = this;
this.dropEle.addEventListener("dragenter", function (e) { //文件拖拽进
e.preventDefault();
e.stopPropagation();
}, false);
this.dropEle.addEventListener("dragover", function (e) { //文件拖拽在悬浮
e.preventDefault();
e.stopPropagation();
}, false);
this.dropEle.addEventListener("dragleave", function (e) {//文件拖拽离开
e.preventDefault();
e.stopPropagation();
}, false);
this.dropEle.addEventListener("drop", function (e) {//文件拖拽放下
e.preventDefault();
e.stopPropagation();
// 处理拖拽文件的逻辑
var df = e.dataTransfer;
for(var i = 0; i < df.items.length; i++) {
var item = df.items[i];
if(item.kind === "file" && item.webkitGetAsEntry().isFile) {
var file = item.getAsFile();
thse.setImageInfo(file); // 统一设置文件信息
}
}
});
}
- 要禁止拖进、悬浮、拖出事件,否则会跳转
componentDidMount(){
this.pullImageFunct();
}
- 拖拽事件需要监听
- 2、文件选择
inputFunct(e){ // 选择图片
const path = e.target.files[0]['path']; // 文件路径
const type = e.target.files[0]['type'];
// 正则去文件名字 /.*\/([^\/]+)\..+/
const rgx = /.*\/([^\/]+)/;
const name = rgx.exec(path)[1];
this.setImageInfo({path,name,type}) // 统一设置文件信息
}
- 需要在input的change事件执行
- 统一设置文件信息
setImageInfo(info){ // 设置上传参数
this.setState({
imagePath:info.path,
selectImgName:info.name,
imageType:info.type,
showMessage:false,
})
}
- 这个时候就可以拿到文件的path、type、name。第一步完成
开始步骤 2 获取上传token
七牛上传的时候需要token,获取tokan,需要accessKey,secretKey,都可以在七牛找到 可以在密钥管理中找到

- 获取token
yarn add qiniu安装qnniu
import nodeQiniu from 'qiniu';
const accessKey = ''; // 你的密钥
const secretKey = ''; // 你的密钥
getToKen(){ // 获取token
return new Promise((res,rej)=>{
const bucket = 'image_list'; // 这是你的图片仓库名
let mac = new nodeQiniu.auth.digest.Mac(accessKey, secretKey);
let options = {
scope: bucket,
expires: 3600 * 24 // 密钥过期时间
};
let putPolicy = new nodeQiniu.rs.PutPolicy(options);
let uploadToken= putPolicy.uploadToken(mac);
if(uploadToken){
res(uploadToken); // 你的上传token
}else{
rej();
}
});
}
- 这是好你的密钥和图片仓库名,就可以拿到密钥
开始步骤 3 上传图片
qiniu.upload 是七牛上传图片的api,需要blob格式的图片
图片设置blob,在点击上传click执行
imageBlob(){ //获取图片 blob
const ther = this;
const {imagePath} = this.state; //文件路径
if(!imagePath){
this.setState({
showMessage:true,
message:'未获取到图片'
})
return;
}
const xhr = new XMLHttpRequest(); // ajax请求图片
xhr.open("get", `file://${imagePath}`, true);
xhr.responseType = "blob";
xhr.onload = async function () {
if (this.status === 200) {
//得到一个blob对象
var blob = this.response; // 图片blob
const token = await ther.getToKen(); // 获取token
ther.imageUpData({token,blob}) // 上传图片
}
}
xhr.send();
}
上传
yarn add qiniu-js 安装
imageUpData({token,blob}){ // 上传图片 token,blob
const {selectImgName,imageType} = this.state; //图片名称和图片type
const ther = this;
const putExtra = { // 上传需要的参数
fname: "",
params: {},
mimeType: [imageType]
};
const config = { // 上传需要的参数
useCdnDomain: true,
region: qiniu.region.z2
};
const observable = qiniu.upload(blob,selectImgName,token,putExtra,config);
observable.subscribe({
next(res){
ther.setState({
progress:res.total.percent.toFixed(2) // 进度
})
},
error(err){ // 失败
if(err.code == 401){
ther.setState({
showMessage:true,
message:'密钥错误,检查密钥'
})
}else{
ther.setState({
showMessage:true,
message:err.message
})
}
},
complete(res){ // 成功
ther.setState({
loadUrl:res.key,
progress:0,
isSuccess:true,
message:'成功--点击下方复制url'
})
}
})
}
- 这时候就可以上传图片了
- 点击复制
- 需要设置个图片仓库中使用的域名
const host = ''; //你的图片仓库使用的域名
urlCopy(){ //点击复制url
const {loadUrl} = this.state; // 上传后返回的路径
const inputElement = document.querySelector('.copy_content'); // 点击复制只能在input上
inputElement.value = host+loadUrl;
inputElement.select(); // 必须
document.execCommand("Copy"); // 浏览器提供
global.alert('复制成功');
}
开始步骤 4 包装electron
npm install electron --save-dev 安装 这一步会很慢,可以转taobao的源
- 在根目录创建 main.js 和 renderer.js

- main.js 本地测试注意端口号
const { app, BrowserWindow } = require('electron');
const path = require('path');
let mainWindow = null;
//判断命令行脚本的第二参数是否含--debug
const debug = /--debug/.test(process.argv[2]);
function makeSingleInstance () {
if (process.mas) return;
app.requestSingleInstanceLock();
app.on('second-instance', () => {
if (mainWindow) {
if (mainWindow.isMinimized()) mainWindow.restore()
mainWindow.focus()
}
})
}
function createWindow () {
mainWindow = new BrowserWindow({
width: 300,
height: 500,
webPreferences: {
javascript: true,
plugins: true,
nodeIntegration: true, // 是否集成 Nodejs
webSecurity: false,
preload: path.join(__dirname, './renderer.js') // 但预加载的 js 文件内仍可以使用 Nodejs 的 API
}
})
mainWindow.loadURL("http://localhost:8403/"); //本地测试注意端口号
// mainWindow.loadURL(path.join('file://',__dirname,'/build/index.html')); //打包使用
//接收渲染进程的信息
const ipc = require('electron').ipcMain;
ipc.on('min', function () {
mainWindow.minimize();
});
ipc.on('max', function () {
mainWindow.maximize();
});
ipc.on("login",function () {
mainWindow.maximize();
});
mainWindow.on('closed', () => {
mainWindow = null
})
}
makeSingleInstance();
//app主进程的事件和方法
app.on('ready', () => {
createWindow();
});
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
});
app.on('activate', () => {
if (mainWindow === null) {
createWindow();
}
});
module.exports = mainWindow;
- renderer.js 必须
global.electron = require('electron');
修改package.json
- 添加main.js

- 设置启动命令
"start": "node scripts/start.js | electron . --debug",
*这个时候关闭服务,在启动服务yarn start,就可以在electron中启动了
有时候会出现端口占用的情况
mac 可以 lsof -i :端口号 看端口占中 kill -9 PID 关闭进程
*
*
-
最后一步打包
npm install electron-packager --save-dev安装electron 打包工具- package.json 添加打包命令
"package": "electron-packager ./"
- 修改main.js中的mainWindow.loadURL
mainWindow.loadURL(path.join('file://',__dirname,'/build/index.html'))
- package.json 添加打包命令
-
执行
yarn package会在根目录创建一个打包文件可以直接使用 -
可以修改
yarn package命令定制打包名称、地址、打包系统、图标 -
什么都没设置会根据本地系统生成打包文件(我在mac上可以)

-
到此结束