Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

从零打造企业级电商后台管理系统 #28

Open
MrZWH opened this issue Aug 11, 2019 · 2 comments
Open

从零打造企业级电商后台管理系统 #28

MrZWH opened this issue Aug 11, 2019 · 2 comments

Comments

@MrZWH
Copy link
Owner

MrZWH commented Aug 11, 2019

dns-prefetch

<link rel="dns-prefetch" href="">

session

  • 服务端保存请求信息的机制
  • sessionId 通常存放在 cookie 里,可以放在请求参数、header 里的 token
  • 会话有浏览器控制,会话结束 session 失效

前端框架分析

what:
框:指的是约束
架:支撑
框架会控制我们书写代码时各个部分的结构,以及它们之间的依赖关系和交互流程,简单点说就是按照框架的要求来写业务,而与业务无关的内容由框架完成,从而提高开发能力和开发效率。框架发展到后来会变得不那么单纯,随着框架的发展会出现很多插件和工具,这些一起形成了框架的生态系统。

why:
随着业务越来越复杂,很多时候原生 js 开发已经搞不定了,这个可能不是技术上的,也可能是成本开发效率或者是团队合作效率上的问题。

How:

前端框架要解决的问题

传统的原生开发方式的不足

  • 代码层面问题
    • 缺少规划,代码混乱。(结构化开发
    • 缺少限制,容易冲突。(独立文件,独立作用域
    • 缺少支撑,能力要求高。(提供支持,只关注业务
  • 效率问题
    • 关注所有流程。(关注业务
    • 团队效率低。(并行开发
    • 测试效率低。(模块测试,自动化测试
  • 多页应用问题
    • 路由体验问题。(单页路由
    • 无页面切换效果。(可以添加过场动画
    • 浪费服务器资源。(减少服务器请求

框架开发的不足

  • 兼容性不好,SEO 不友好
  • 有场景要求,开发自动度降低
  • 黑盒开发,框架本身又出错的风险
  • 有学习成本
@MrZWH MrZWH changed the title React 开发后台管理系统 从零打造企业级电商后台管理系统 Aug 11, 2019
@MrZWH
Copy link
Owner Author

MrZWH commented Sep 25, 2019

控制访问 /login 与主页面的路由

<Router>
  <Switch>
    <Route path="/login" component={Login}/>
    <Route path="/" render={props => (
      <Layout>
        <Switch>
          <Route exact path="/" component={Login}/>
          <Route path="/product" component={Login}/>
          <Route path="/product-category" component={Login}/>
        </Switch>
      </Layout>
    )}/>
  </Switch>
</Router>

表单绑定一个 onChange 事件

onInputChange(e) {
  let inputValue = e.target.value,
      inputName = e.target.name;
  this.setState({
    [inputName]: inputValue
  })
}

强制跳转登录页需做 redirect

window.location.href = '/login?redirect=' + encodeURIComponent(window.location.pathname);

// 获取 URL 参数
getUrlParam(name) {
  // param=123&param1=345
  let queryString = window.location.search.split('?')[1] || '';
  let reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
  let result = queryString.match(reg)
  // result: ['param=123', '', '123', '&']
  return result ? decodeURIComponent(result[2]) : null
}

封装 localStorage

setStorage(name, data) {
  let dataType = typeof data;

  if (dataType === 'object') {
    window.localStorage.setItem(name, JSON.stringify(data))
  } else if (['number', 'string', 'boolean'].indexOf(dataType)) {
    window.localStorage.setItem(name, data)
  } else {
    alert('该类型不能用于本地存储')
  }
}

将时间戳格式化

new Date(time).toLocaleString()

分路由的配置

按顺序删除图片

onImageDelete(e) {
  let index = parseInt(e.target.getAttribute('index')),
      subImages = this.state.subImages;
  subImages.splice(index, 1);
  this.setState({
    subImages
  })
}

富文本组件

simditor
如何将依赖 jQuery 的组件改造成 React 的组件:

import React from 'react';
import Simditor from 'simditor';
import 'simditor/styles/simditor.scss';

export default class RichEditor extends React.Component {
  constructor(props) {
    super(props);
  }

  componentDidMount() {
    this.loadEditor();
  }

  loadEditor() {
    let element = this.refs['textarea']
    this.simditor = new Simditor({
      textarea: $(element),
      defaultValue: this.props.placeholder || '请输入内容',
      upload: {
        url: '/manage/product/richtext_img_upload.do',
        defaultImage: '',
        fileKey: 'upload_file'
      }
    });
    this.bindEditorEvent();
  }

  bindEditorEvent() {
    this.simditor.on('valuechanged', e => {
      this.props.onVlaueChange(this.simditor.getValue());
    })
  }

  render() {
    return (
      <div className="rich-editor">
        <textarea ref="textarea"></textarea>
      </div>
    )
  }
}

项目上线

@MrZWH
Copy link
Owner Author

MrZWH commented Sep 26, 2019

项目上线

生产环境配置

  • 安装 nodeJs
    • ssh [email protected] 链接服务器
    • wget https://nodejs.org/download/release/vx.x.x 下载 nodejs
    • tar -xzvf nodexxxx.tar.gz 解压
    • mv nodexxxxx /usr/local/node 将解压后文件夹放到经常装文件的地方
    • ln -s /usr/local/node/bin/node /usr/local/bin/ 给 node 做软链使可以全局访问
    • ln -s /usr/local/node/bin/npm /usr/local/bin/ 给 npm 做软链使可以全局访问
  • 安装 yarn
    • 官网查看安装方式
  • 安装 git,并配置权限
    • 使用 yum 安装 yum install git
    • 配置 git 密钥
      • ssh-keygen -t rsa -C '你的git邮箱.com'
    • 查看公钥 cat ~/.ssh.id_rsa.pub
  • 安装 nginx
    • yum install nginx

代码发布

  • 在服务器上拉去最新 master 分支的代码
  • 项目初始化
  • 执行线上环境的打包编译
  • 复制 dist 目录到目标目录
    • cp -R /developer/git-repository/admin-v2-fe/dist ./ 在生产环境目录下,将打包好的前端项目复制到当前目录下

自动化发布脚本

# fe-deploy.sh
#!/bin/sh

GIT_HOME=/developer/git-repository
DEST_PATH=/product/front/

if [ ! -n "$1"];
then
  echo -e "Please input a project name! You can input as follows:"
  echo -e "./fe-deploy.sh admin-v2-fe"
  exit
fi

if [ $1 = "admin-v2-fe"];
then
  echo -e "-------Enter Project------"
  cd $GIT_HOME$1
else
  echo -e "Invalid Project Name"
  exit
fi

#clear dist
echo -e "-------Clean Dist------"
rm -rf ./dist

echo -e "-------Git Pull------"
git pull

echo -e "-------Yarn Install------"
yarn

echo -e "-------Yarn Run Dist------"
yarn run dist

if [ -d "./dist" ];
then
  echo -e "-------clean Dest------"
  rm -rf $DEST_PATH/dist

  echo -e "-------copy Dest------"
  cp -R ./dist $DEST_PATH/$1/

  echo -e "-------Deploy Success------"
then
  echo -e "-------Deploy Fail------"
fi

将此文件放到 developer 目录下,并更改权限: chmod 775 fe-deploy.sh, ./fe-deploy.sh

nginx 和域名配置

  • nginx 中 vhost 的配置,用来配置 nginx 对各个域名的处理方式
    • cd /etc/nginx/ 进入 nginx 目录
    • mkdir vhost
    • vim nginx.conf
    • include vhost/*.conf 在最后一行 } 前输入
    • cd vhost/
    • touch adminv2.jianliwu.com.conf
    • touch s.jianliwu.com.conf
    • (文件内容在下文)输入文件内容后进行下一步
    • nginx -t 检查文件是否有问题
    • nginx -s reload
    • nginx -c /etc/nginx/nginx.conf 报错nginx:[error] invalid PID number "" in "/run/nginx.pid" 后输入此行, 然后再次nginx -s reload
  • 通过指定 hosts 方式做线上回归测试
  • 测试没问题后,更改域名解析

adminv2.jianliwu.com.conf

server {
  listen 80;
  server_name adminv2.jianliwu.com;
  access_log /etc/nginx/logs/access.log combined;
  index index.html index.jsp index.php

  location = / {
    root /product/front/admin-v2-fe/dist;
    index index.html;
  }

  location ~ .*\.html$ {
    root /product/front/admin-v2-fe/dist;
    index index.html;
  }

  location ~ .*\.do$ {
    proxy_pass http://admintest.happymmall.com;
  }

  location / {
    try_files $uri $uri/ /index.html;
  }
}

s.jianliwu.com.conf

server {
  listen 80;
  server_name s.jianliwu.com;
  access_log /etc/nginx/logs/access.log combined;
  index index.html index.jsp index.php

  location ~ /admin-v2-fe/dist/view/* {
    deny all;
  }

  location / {
    root /product/front/;
    add_header Access-Control-Allow-Origin '*';
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant