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


    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>
    

    .

  • 相关阅读:
    修改spring boot 启动logo
    查看jvm常用命令
    intellij IDEA破解
    hdu 新生晚会
    How many prime numbers(素数)
    2077 汉诺塔IV
    Factorial
    双人黑白块
    EasyX
    七夕情人节
  • 原文地址:https://www.cnblogs.com/crazycode2/p/12481854.html
Copyright © 2020-2023  润新知