Egg.js 实现向服务器上传图片

摘要:
流动文件名){break;}constfieldname=流。字段名;//文件表单的名称//上载图像的目录constdir=awaitthis.service.tools。getUploadFile;consttarget=目录。uploadDir;constwriteStream=fs。createWriteStream;抽水泵;files=对象。赋值;}如果{ctx.body={代码:200,消息:“图像上传成功”,数据:文件}}否则{ctx.body={代码:500,消息:‘图像上传失败’,数据:{代码:500}5.配置路由//上传图像/头像/封面路由器。邮递6.客户端页面逻辑代码封装了组件src/components/UploadAvatar Js/***UploadAvatar/cover*/importReactfrom'rec';从“td”导入{Upload,Icon,message};从“../../utils/常量”导入{BaseUrl};函数getBase64{consteader=newFileReader();reader.addEventListener;reader.readAsDataURL;}functionbeforeUpload{constisJpgOrPng=file.type=='image/jpe'||file.type==='image/png';if(!IsLt2M){message.error('图片必须小于2MB!');}returnisJpgOrPng&&isLt2M;}类可用扩展反应。组件{state={loading:false,};componentDidMount(){ifthis.setState;}handleChange=info=>{const{name=“avatar”}=this。道具;如果{this.setState;return;}如果{//获取服务器返回值const{response}=info。文件如果{this.props.onChange&&this.props.onChange;}getBase64;}};render(){constuploadButton=(<div><Icontype={this.state.loading?

1.安装时间处理 及 压缩 模块

yarn add silly-datetime pump

2.文件保存路径

config/config.default.js

config.uploadDir = 'app/public/avatar/upload';

3.创建tools service
app/service/tools.js

'use strict';

const Service = require('egg').Service;
const path = require("path");
const sd = require('silly-datetime');
const mkdirp = require('mkdirp');

class ToolsService extends Service {
  /**
   * 获取文件上传目录
   * @param {*} filename
   */
  async getUploadFile(filename) {
    // 1.获取当前日期
    let day = sd.format(new Date(), 'YYYYMMDD');
    // 2.创建图片保存的路径
    let dir = path.join(this.config.uploadDir, day);
    await mkdirp(dir); // 不存在就创建目录
    let date = Date.now(); // 毫秒数
    // 返回图片保存的路径
    let uploadDir = path.join(dir, date + path.extname(filename));
    // apppublicavatarupload202003121536895331666.png
    return {
      uploadDir,
      saveDir: this.ctx.origin + uploadDir.slice(3).replace(/\/g, '/')
    }
  }
}

module.exports = ToolsService;

4.调用 controller
app/controller/article.js

// 保存头像/封面
async saveAvatar() {
  const { ctx } = this;
  const parts = ctx.multipart({ autoFields: true });
  let files = {};
  let stream;
  while ((stream = await parts()) != null) {
    if(!stream.filename){
      break;
    }
    const fieldname = stream.fieldname; // file表单的名字
    // 上传图片的目录
    const dir = await this.service.tools.getUploadFile(stream.filename);
    const target = dir.uploadDir;
    const writeStream = fs.createWriteStream(target);

    await pump(stream, writeStream);

    files = Object.assign(files, {
      [fieldname]: dir.saveDir
    });
  }

  if(Object.keys(files).length > 0){
    ctx.body = {
      code: 200,
      message: '图片上传成功',
      data: files
    }
  }else{
    ctx.body = {
      code: 500,
      message: '图片上传失败',
      data: {}
    }
  }
}

5.配置路由

// 上传图片/头像/封面
router.post('/tools/saveavatar', controller.article.saveAvatar);

6.客户端页面逻辑代码
封装组件
src/components/UploadAvatar.js

/**
 * 上传头像/封面
 */
import React from 'react';
import { Upload, Icon, message } from 'antd';
import { BaseUrl } from '../../utils/constants';

function getBase64(img, callback) {
  const reader = new FileReader();
  reader.addEventListener('load', () => callback(reader.result));
  reader.readAsDataURL(img);
}

function beforeUpload(file) {
  const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
  if (!isJpgOrPng) {
    message.error('仅支持JPG/PNG文件');
  }
  const isLt2M = file.size / 1024 / 1024 < 2;
  if (!isLt2M) {
    message.error('图片必须小于2MB!');
  }
  return isJpgOrPng && isLt2M;
}

class Avatar extends React.Component {
  state = {
    loading: false,
  };

  componentDidMount() {
    if(this.props.value) this.setState({ imageUrl: this.props.value});
  }

  handleChange = info => {
    const { name = "avatar"} = this.props;
    if (info.file.status === 'uploading') {
      this.setState({ loading: true });
      return;
    }
    if (info.file.status === 'done') {
      // 获取服务器返回值
      const { response } = info.file;
      if(response.data){
        this.props.onChange && this.props.onChange(response.data[name]);
      }

      getBase64(info.file.originFileObj, imageUrl =>
        this.setState({
          imageUrl,
          loading: false,
        }),
      );
    }
  };

  render() {
    const uploadButton = (
      <div>
        <Icon type={this.state.loading ? 'loading' : 'plus'} />
        <div className="ant-upload-text">上传</div>
      </div>
    );
    const { imageUrl } = this.state;
    const { name = "avatar" } = this.props;
    return (
      <Upload
        name={name}
        listType="picture-card"
        className="avatar-uploader"
        showUploadList={false}
        action={`${BaseUrl}/tools/saveavatar`}
        beforeUpload={beforeUpload}
        onChange={this.handleChange}
      >
        {imageUrl ? <img src={imageUrl} alt="avatar" style={{  '100%' }} /> : uploadButton}
      </Upload>
    );
  }
}

export default Avatar;

调用

<Form.Item label="封面">
  {getFieldDecorator('cover', {
    rules: [{ required: true, message: '请上传封面' }],
    initialValue: 'https://img2.mukewang.com/szimg/5d1032ab08719e0906000338.jpg'
  })(<UploadAvatar name={"cover"} />)}
</Form.Item>

.

免责声明:文章转载自《Egg.js 实现向服务器上传图片》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇SpringMVC实现Excel导出winform程序登陆后关闭登录窗体下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

eldialog添加拖拽功能

import Vue from 'vue' Vue.directive('dialogDrag', { bind(el, binding, vnode, oldVnode) { const dialogHeaderEl = el.querySelector('.el-dialog__header') const dragDom = e...

cppcheck,代码简单分析,以及实现一个简单的模块

经过半天的分析和了解,大致明白了这个工具的使用方法和原理。 这个工具,会将一个源文件(目前我是用单一源文件测试的,没有使用目录测试), 每一个有效符号或者元素都解析出来,之后储存在一个大list里面,供后续模块检测时使用, 但是一些特殊的元素,不会被列入list,如调用约定(__stdcall 此类等等),其他应该还有,但是还没使用到, 目前看到的情况是,...

QT QString类型转换为const char*(toLatin1)

Qstring str = "helloworld"; char *s; QByteArray ba = str.toLatin1(); s = ba.data(); toLatin1、toLocal8Bit都是QString转QByteArray的方法,Latin1代表ASCII,Local8Bit代表unicode。 const char* -- 指...

vue 数组去重

test() { const arr =[ { name: '张三', age: 22}, { name: '李四', age: 22}, { name: '张三', age:...

boost之ThreadPool

threadpool是基于boost库实现的一个线程池子库,但线程池实现起来不是很复杂。我们从threadpool中又能学到什么东西呢? 它是基于boost库实现的,如果大家对boost库有兴趣,看看一个简单的实现还是可以学到点东西的。 threadpool基本功能 1、任务封装,包括普通任务(task_func)和优先级任务(prio_task_fun...

前端js图片上传

前端js图片上传,原理用input type="file"获取图片然后把图片转换成base64编码传到后台. 图片上传 <!DOCTYPE html><html><head><meta charset="UTF-8"><meta name="viewport" content="width=device...