当前位置: 首页>后端>正文

项目全流程

做项目之余的反思与总结,这些都是留给我的宝贵财富!

webpack做了哪些配置,为什么要配置?

webpack.config.js和vue.config.js的区别
  1. webpack.config.js是webpack的配置文件,所有使用webpack作为打包工具的项目都可以使用,vue的项目可以使用,react的项目也可以使用。
  2. vue.config.js是vue项目的配置文件,专用于vue项目。通过vue.config.js中常用功能的配置,简化了配置工作,当然如果需要更专业的配置工作,两者在vue项目中是可以并存的。
  3. vue-cli3创建的时候并不会自动创建vue.config.js,因为这个是可选项,所以一般都是修改webpack的时候才会自己创建一个vue.config.js
  4. 再然后因为vue-cli3内部高度集成了webpack,一般来说使用者不需要再去webpack做了什么,所以没有暴露webpack的配置文件,但你依然可以创建vue.config.js去修改默认的webpack。
项目中使用了vue.config.js进行项目的配置

pc:

  1. 入口处做了多页面的配置
pages:{
    index:{
        entry: 'src/main.js',
        template: 'public/index.html'
    },
    exportModal:{
        entry: 'src/exportMoedal.js',
        template: 'public/exportMoedal.html'
    }
}
  1. 配置了configureWebpack别名依赖
configureWebpack: {
    resolve:{
        alias: {
            "vue$": "vue/dist/vue.esm.js"
        }
    }
}

oa:

  1. 输出文件目录 地址做了修改
    before: outputDir: "./dist "
    after: outputDir: "./dist/icbc/eszbmp"
  2. 配置了configureWebpack拓展项
configureWebpack: {
    externals:{
        "BMap": "BMap"
    }
}

gbc:

  // 第三方插件配置
  pluginOptions: {},

  // webpack相关配置
  chainWebpack: (config) => {
    config.resolve.alias
      .set("vue$", "vue/dist/vue.esm.js")
      .set("@", path.resolve(__dirname, "./src"));
  },
  // css相关配置
  css: {
    // 是否分离css(插件ExtractTextPlugin)
    extract: true,
    // 是否开启 CSS source maps
    sourceMap: false,
    // css预设器配置项
    loaderOptions: {},
    // 是否启用 CSS modules for all css / pre-processor files.
    modules: false,
  },

区分生产、测试、以及开发环境:

  1. 根目录下创建:.env.development/test/production等文件
  2. 内容如下:
#全局本地开发环境配置
NODE_ENV=production
VUE_APP_BASE_ENV=production
VUE_APP_BASE_URL=''
# 文件服务器配置,开发配置
VUE_APP_ICON_BASE_URL='http://118/6/45/147:8888'

遇到过哪些需要跨域的情况,怎么解决的

1,总行的sdk.config.js文件引入,调用总行提供的一些方法:如水印、获取用户信息、埋点等,使用jsonp的方式动态创建script文件,在main.js入口文件引入
2,本地前端和后台,开发阶段进行接口调试的时候,IP端口不一致,所以使用了vue.config.js的proxy代理的方式
3,第三方系统内嵌iframe的跨域问题: iframe的src里带上相关的登录信息(用户名、token等),内嵌的平台做了单点登录,验证通过允许跨域??
4,nginxs

遇到过哪些IE浏览器的适配问题?

  1. 兼容ie浏览器的时间格式化方法,ie不允许使用new Date()传入时间
// time: 2022-11-11 14:23:21
ieNewDate:(time)=>{
    const day = time.split(' ')
    const days = day[0].split('-')
    const min =  day[1].split(':')
    const date = new Date()
    date.setUTCFullYear(days[0], days[1] - 1, days[2])
    date.setUTCHours(min[0]-8,min[1], min[2])
}

2,不支持es6的写法
main.js文件引入polyfill:import "@/babel/polyfill"
3,样式问题,兼容IE的写法
clearfix:{zoom:1}
4,IE input输入框失效的问题
解决方案:

export const IEinputClear=(e)=>{
    var isBrowser = typeof window !== 'undefined'
    var UA = isBrowser && window.navigator.userAgent.toLowerCase()
    var isIE = UA && /msie|trident/.test(UA)
    if(isIE){
        let clearDom  =document.getElementById(e.target.id)
        let closeDom = clearDom.nextSibling
        closeDom.addEventListener('click', ()=>{
            clearDom.value = ""
        })
    }
}

遇到过哪些移动端机型适配问题,如何调试和解决的

  1. gbc项目中,内嵌了一个iframe页面,苹果机型底部tabbar会遮挡的问题
    解决方案:区分是安卓还是ios系统,进行样式的调整
  2. oa项目中,不同的打开环境icon的请求前缀是不同的,需要判断pc端浏览器预览,还是微信浏览器打开(安卓用户微信内置浏览器以及ios客户端微信内置浏览器),以及是安卓还是苹果手机打开的页面。
    解决方案:判断不同的平台,文件服务器配置icon地址是不同的
# 文件服务器配置,测试配置
VUE_APP_ICON_BASE_URL='http://118/6/45/147:8888'
VUE_APP_ICON_BASE_MOBILE='ICBC/ESZBMP'

如:浏览器环境 this.devIconBasePath = process.env.VUE_APP_ICON_BASE_URL
手机环境:this.devIconBasePath = process.env.VUE_APP_ICON_BASE_URL_MOBILE

sdk.config.js文件是怎么生效的,总行提供的方法有什么

import { isIos } from '@/utils';

let sdkUrl = ''
if (isIos) {
    sdkUrl = '/static/js/ruahoMobileSdk_ios.min.js'
} else {
    sdkUrl = '/static/js/ruahoMobileSdk_android.min.js'
}

const script = document.createElement('script')
script.type = 'text/javascript'

script.src = sdkUrl
document.getElementsByTagName('body')[0].appendChild(script)
  1. main.js 入口文件中引入这个文件
  2. 总行提供的方法有:获取用户信息、获取当前定位、添加水印、分享页面、加密预览文件、数据埋点等方法
//添加水印
try {
    //eslint-disable-next-line
    rh.displayWatermark()
} catch (error) {
    console.log("请在行内app使用");
}

前端开发规范

1,命名规范
2,数据请求

  • 对数据请求进行二次封装处理
  • 请求拦截,添加统一的请求报文格式
  • 响应拦截,拦截响应报文,统一管理后端返回的状态码,返回成功数据,拦截错误数据并抛出异常

登录注册的全流程,捋一捋注意点

内部员工使用的平台,默认都有权限,没有注册模块,通过身份ID验证权限。

  • PC:重点看路由下的promise.js文件,实现了路由拦截、权限控制以及跳转控制

  • OA与GBC:没有做权限管理,通过url的userId参数判断有没有登录,userId为空或者错误的话,抛出异常,首页数据列表为空(交互上应该跳转到对应的错误页,重新连接按钮)

axios二次封装,接口请求的配置这块整体回顾

具体参考以下这篇笔记:
【基础】vue项目对axios进行二次封装,request全局接口请求文件如何写? - 简书 (jianshu.com)

印象深刻的bug

GBC:
vant的vant-tree-select组件没有三级选择,只有两级选择,我们需要自己封装一个能实现省市区以及选择三级行业的联动效果


项目全流程,第1张
vant组件示例

项目全流程,第2张
要实现的效果

组件的实现代码如下:


项目全流程,第3张
6279297887f2beb919d719df7eb0b7b.jpg

项目全流程,第4张
2e4ca491018708bdc94b8d0f49ca76d.jpg

项目全流程,第5张

项目中vuex都放了哪些内容,具体使用场景

pc:全局页面loading的显示文字、状态,设置用户信息,模块页面会放具体业务模块需要存储的束,如navheader、deptList等
oa:全局放头部导航组件的控制:如右侧是否显示分享按钮、搜索按钮等,以及右侧的点击事件控制。以及会存储全局搜索的keyword
gbc:header部分显示的企业名称、id、类别、是否关注相关的数据


项目全流程,第6张
gbc

项目全流程,第7张
oa

GBC项目要点

项目全流程,第8张
1669346325216.png

项目技术选型

前端:框架是vue,UI库移动端是vant,PC端是antDesignVue,版本管理器svn和git
  • 一是考虑到团队里的成员的技术储备,基本上都会vue,无需额外的学习成本
  • 二是考虑到项目匹配度,
  • 三是vue框架本身是轻量级,有中文社区和中文文档,有丰富的生态环境和组件支持,易学易上手
  • 最后也是工商银行总行的要求,他们团队使用的是vue框架,技术上倾向于保持上下一致。
后台:框架springboot,微服务,docker容器化部署,中间件用的是tomcat,前端的静态服务器、软负载均衡和解决跨域、代理用的nginx,Jenkins自动化部署工具,缓存使用redis。数据库orecal、MySQL
  • springboot业界技术主流,生态丰富
  • docker容器化部署避免环境问题,解决环境差异造成的异常以及运维痛点
  • Jenkins解决运维成本,自动化打包推到镜像仓库,以及部署到生产环境

路由配置以及权限验证拦截

目前的router模块结构如下:


项目全流程,第9张

index.js是主路由模块入口,包含以下内容:

  1. 引入vue和vueRouter
  2. 引入各种项目路由子模块以及layout页面基础结构
  3. 引入页面进度条以及相关配置
  4. 导航守卫以及后卫的相关设置
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'

import creditMesure from './modules/creditMesure'
import mainLayout from '@/views/layout/mainLayout'

// 页面进度条相关配置
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
NProgress.configure({easing:'ease', speed: 500, showSpinner: false})

Vue.use(VueRouter)  

const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home
  },
  {
    path: '/about',
    name: 'About',
    component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
  },
  {
    path: '/main-layout',
    name: 'main-layout',
    component: mainLayout,
    meta: {
      title: '项目首页'
    },
    children: [
      ...creditMesure,
    ]
  },
  {
    path: '*',
    name: '404',
    component: () => import(/* webpackChunkName: "about" */ '../views/About.vue'),
    mata:{
      title: '404'
    }
  }

]

const router = new VueRouter({
  mode: 'history',
  base: process.env.BASE_URL,
  routes
})

router.beforeEach((to,from,next)=>{
  NProgress.start()
  window.scrollTo(0,0)
  next()
})

router.afterEach((to)=>{
  NProgress.done()
  document.title = to.meta.title || 'my project'
})


export default router

promise.js文件主要配置了路由拦截,控制权限,跳转控制

/**
 * 路由拦截 控制权限 跳转控制
 */

// 引入配置
import router from './index'
import { getUrlParams } from '@/utils'

// 页面进度条相关配置
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
NProgress.configure({easing:'ease', speed: 500, showSpinner: false})


// 路由拦截
router.beforeEach(async (to, from, next) => {
    NProgress.start()
    // 去登录页面直接登陆
    if(to.path === '/to-login' || to.path === '/to-login-new'){
        next()
        return
    }

    // 异步操作 必须登录成功才能继续下一步
    const user_is_login = sessionStorage.getItem('user_is_login')
    if(!user_is_login){
        // 调用登录接口,成功后存储用户信息
        await login({loginType:1}).then((res)=>{
            sessionStorage.setItem('user_is_login', 'ok')
            if(res.status === 'I0000'){
                sessionStorage.setItem('userInfo', JSON.stringify(res.data.userInfo))
            }
        })
    }

    // 解决next重定向后无限循环的问题
    const ph = sessionStorage.setItem("login_redirect_path")
    const login_redirect_path = ph?ph.split('?'):ph
    if(login_redirect_path && login_redirect_path[0] == to.path){
        next()
    }

    //获取用户信息
    if(!sessionStorage.getItem('global_user_info')){
        // 重新初始化登录
    }

    // 定向跳转
    if(userInfo && userInfo!== 'null'){
        await getPath().then(res=>{
            sessionStorage.setItem('login_redirect_path', `/${res.data.url}`)
            next(`/${res.data.url}`)
        }).catch((e)=>{
            next(`/home`)
        }).finally(()=>{
            NProgress.done()
        })
        return
    }

    next()
})

//跳转成功后的设置
router.afterEach(to=>{
    document.title = to.meta.title || 'ICBC'
    NProgress.done()
})

export default router

token在项目中的使用,以及过期时间如何处理

只有PC平台引入token来辅助登录的验证

  1. 路由promise文件中,异步操作,登录成功后存储用户信息以及token
  2. 在公共请求头的部分带上了session里存储的token信息
  3. 在二次封装axios的request文件中,请求头加上了token信息
    // token设置
    config.headers["token"] = sessionStorage.getItem("dse_sessionId") || getUrlParams("dse_sessionId")
  4. 过期时间由后台设置,目前是30分钟有效期,每次请求数据都会带上之前登录成功存储的token, 由后台校验,如果超时后台会返回"token过期请重新登录“,前台request文件在响应拦截模块接收到这个异常状态码,会首先清除session里的token数据,其次跳转到登录页,让用户重新登录。

分行经营管理平台设计的项目背景:

之前是各做各的,部门之间没有联动,常用的功能没有得到沉淀,原来的交互体验也不友好。技术栈也比较陈旧。设计它是希望能够处理业务之外,也想做成指导业务,决策支持的仪表盘,适合各级领导的使用。针对平时对办公时遇到的问题做了一些优化,也结合了领导的指导意见。

作为一个门户平台,是如何引入第三方项目和系统的

PC:
OA:

https://www.xamrdz.com/backend/3gm1942737.html

相关文章: