houzhongjian
2024-07-23 0f23f7b9796d0b0f8259ad2ce0b4987e7c4467e5
1、升级框架
2、迁移柠条塔数据平台和模型管理代码
已修改11个文件
274 ■■■■■ 文件已修改
.env.dev 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
.env.prod 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package.json 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/directive/permission/hasPermi.js 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main.js 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/index.js 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/settings.js 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/dict.js 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/index.js 103 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/request.js 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
vue.config.js 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.env.dev
@@ -24,7 +24,7 @@
VUE_APP_TENANT_ENABLE = true
# 验证码的开关
VUE_APP_CAPTCHA_ENABLE = true
VUE_APP_CAPTCHA_ENABLE = false
# 文档的开关
VUE_APP_DOC_ENABLE = true
.env.prod
@@ -1,16 +1,25 @@
# 生产环境配置
NODE_ENV = 'production'
# 开发环境配置
ENV = 'production'
# 页面标题
VUE_APP_TITLE = 工业互联网微服务平台
# 工业互联网微服务平台/生产环境
VUE_APP_BASE_API = '/prod-api'
# 工业互联网微服务平台/本地环境
#VUE_APP_BASE_API = '/proxy-api'
VUE_APP_BASE_API = 'http://172.16.8.100:48080'
# 根据服务器或域名修改
PUBLIC_PATH = 'http://my-pi.com:8888/iailab-admin/'
# 二级部署路径
VUE_APP_APP_NAME ='iailab-admin'
# 监控地址
VITE_APP_MONITOR_ADMIN = 'http://172.16.8.100:9111'
# xxl-job 控制台地址
VITE_APP_XXLJOB_ADMIN = 'http://172.16.8.100:9090'
# druid 控制台地址
VITE_APP_DRUID_ADMIN = 'http://172.16.8.100:48082'
# 路由懒加载
VUE_CLI_BABEL_TRANSPILE_MODULES = true
# 多租户的开关
VUE_APP_TENANT_ENABLE = true
@@ -19,7 +28,7 @@
VUE_APP_CAPTCHA_ENABLE = true
# 文档的开关
VUE_APP_DOC_ENABLE = false
VUE_APP_DOC_ENABLE = true
# 百度统计
VUE_APP_BAIDU_CODE = fadc1bd5db1a1d6f581df60a1807f8ab
package.json
@@ -72,7 +72,13 @@
    "vue-video-player": "^5.0.2",
    "vuedraggable": "2.24.3",
    "vuex": "3.6.2",
    "xml-js": "1.6.11"
    "xml-js": "1.6.11",
    "js-cookie": "^2.2.1",
    "relation-graph": "^2.1.42",
    "vue-cron": "^1.0.9",
    "vue-i18n": "^8.18.2",
    "xlsx": "^0.18.5",
    "xlsx-style": "^0.8.13"
  },
  "devDependencies": {
    "@vue/cli-plugin-babel": "4.5.18",
src/directive/permission/hasPermi.js
@@ -9,7 +9,6 @@
    const { value } = binding
    const all_permission = "*:*:*"; // 全部权限
    const permissions = store.getters && store.getters.permissions // 用户拥有的权限标识的数组
    if (value && value instanceof Array && value.length > 0) {
      // 判断是否有权限
      const permissionFlag = value
src/main.js
@@ -10,10 +10,17 @@
import router from './router'
import directive from './directive' // directive
import plugins from './plugins' // plugins
//ruoyi
import { hasPermission, getDictLabel } from '@/utils'
import service from '@/utils/request'
import {getDictItem} from '@/utils/dict'
import * as echarts from 'echarts'
import customed from '@/assets/json/customed.json'
import i18n from '@/i18n'
import './assets/icons' // icon
import './permission' // permission control
import './tongji' // 百度统计
// import './tongji' // 百度统计
import { getDicts } from "@/api/system/dict/data";
import { getConfigKey } from "@/api/infra/config";
import { parseTime, resetForm, handleTree, addBeginAndEndTime, divide} from "@/utils/ruoyi";
@@ -37,6 +44,14 @@
Vue.prototype.handleTree = handleTree
Vue.prototype.addBeginAndEndTime = addBeginAndEndTime
Vue.prototype.divide = divide
//ruoyi
echarts.registerTheme('customed', customed)
Vue.use(echarts)
Vue.prototype.$http = service
Vue.prototype.$hasPermission = hasPermission
Vue.prototype.$echarts = echarts
Vue.prototype.$getDictItem = getDictItem
// 全局组件挂载
Vue.component('DictTag', DictTag)
@@ -68,7 +83,6 @@
Vue.component('tinymce', Tinymce)
import '@/assets/icons'
import request from "@/utils/request" // 实现 form generator 使用自己定义的 axios request 对象
console.log(request)
Vue.prototype.$axios = request
import '@/styles/index.scss'
@@ -87,12 +101,14 @@
Vue.use(Element, {
  size: localStorage.getItem("size") || "medium", // set element-ui default size
  i18n: (key, value) => i18n.t(key, value)
});
Vue.config.productionTip = false
new Vue({
  el: '#app',
  i18n,
  router,
  store,
  render: h => h(App)
src/router/index.js
@@ -3,6 +3,8 @@
/* Layout */
import Layout from '@/layout'
import service from '@/utils/request'
Vue.use(Router)
/**
@@ -180,6 +182,45 @@
  },
]
const router = new Router({
  mode: 'hash',
  scrollBehavior: () => ({ y: 0 }),
  routes: constantRoutes
})
//TODO 初始化字典
router.beforeEach((to, from, next) => {
  // 获取字典列表, 添加并全局变量保存
  service.get('/admin-api/sys/dict/all-dict-item').then(({ data: res }) => {
    if (res.code !== 0) {
      return
    }
    window.localStorage.setItem('DICT_ITEM_MAP', JSON.stringify(res.data || {}))
  }).catch(() => {})
  service.get('/admin-api/sys/dict/all-dict-obj').then(({ data: res }) => {
    if (res.code !== 0) {
      return
    }
    window.localStorage.setItem('DICT_ITEM_OBJ', JSON.stringify(res.data || {}))
  }).catch(() => {})
  // 获取菜单列表, 添加并全局变量保存
  service.get('/admin-api/sys/app/apps').then(({ data: res }) => {
    if (res.code !== 0) {
      Vue.prototype.$message.error(res.msg)
      return next({ name: 'login' })
    }
    let appList = res.data
    if (appList.length === 0) {
      Vue.prototype.$message.error('未配置访问权限,请联系管理员!')
      return next({ name: 'login' })
    }
    sessionStorage.setItem('appList', JSON.stringify(appList || '[]'))
    next({ ...to, replace: true })
  }).catch(() => {
    next({ name: 'login' })
  })
})
// 防止连续点击多次路由报错
let routerPush = Router.prototype.push;
Router.prototype.push = function push(location) {
src/settings.js
@@ -13,7 +13,7 @@
  /**
   * 是否显示顶部导航
   */
  topNav: false,
  topNav: true,
  /**
   * 是否显示 tagsView
src/utils/dict.js
@@ -139,3 +139,12 @@
  const dict = getDictData(dictType, value);
  return dict ? dict.label : '';
}
//若以
export function getDictItem(dictCode, itemValue) {
  let dictItemObj = JSON.parse(window.localStorage.getItem('DICT_ITEM_OBJ'))
  if (dictItemObj && dictItemObj[dictCode]) {
    return dictItemObj[dictCode][itemValue].itemText
  }
  return {}
}
src/utils/index.js
@@ -1,5 +1,6 @@
import { parseTime } from './ruoyi'
import Cookies from 'js-cookie'
import store from '@/store'
/**
 * 表格时间格式化
 */
@@ -438,3 +439,103 @@
  return str;
}
//若以
/**
 * 权限
 * @param {*} key
 */
export function hasPermission (key) {
  return window.SITE_CONFIG['permissions'].indexOf(key) !== -1 || false
}
/**
 * 获取字典数据列表
 * @param dictType  字典类型
 */
export function getDictDataList (dictType) {
  debugger
  const type = window.SITE_CONFIG['dictList'].find((element) => (element.dictType === dictType))
  if (type) {
    return type.dataList
  } else {
    return []
  }
}
/**
 * 获取字典名称
 * @param dictType  字典类型
 * @param dictValue  字典值
 */
export function getDictLabel (dictType, dictValue) {
  const type = window.SITE_CONFIG['dictList'].find((element) => (element.dictType === dictType))
  if (type) {
    const val = type.dataList.find((element) => (element.dictValue === dictValue + ''))
    if (val) {
      return val.dictLabel
    } else {
      return dictValue
    }
  } else {
    return dictValue
  }
}
/**
 * 清除登录信息
 */
export function clearLoginInfo () {
  store.commit('resetStore')
  Cookies.remove('token')
  window.SITE_CONFIG['dynamicMenuRoutesHasAdded'] = false
}
/**
 * 获取uuid
 */
export function getUUID () {
  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
    return (c === 'x' ? (Math.random() * 16 | 0) : ('r&0x3' | '0x8')).toString(16)
  })
}
/**
 * 获取svg图标(id)列表
 */
export function getIconList () {
  var res = []
  var list = document.querySelectorAll('svg symbol')
  for (var i = 0; i < list.length; i++) {
    res.push(list[i].id)
  }
  return res
}
/**
 * 树形数据转换
 * @param {*} data
 * @param {*} id
 * @param {*} pid
 */
export function treeDataTranslate (data, id = 'id', pid = 'pid') {
  var res = []
  var temp = {}
  for (var i = 0; i < data.length; i++) {
    temp[data[i][id]] = data[i]
  }
  for (var k = 0; k < data.length; k++) {
    if (!temp[data[k][pid]] || data[k][id] === data[k][pid]) {
      res.push(data[k])
      continue
    }
    if (!temp[data[k][pid]]['children']) {
      temp[data[k][pid]]['children'] = []
    }
    temp[data[k][pid]]['children'].push(data[k])
    data[k]['_level'] = (temp[data[k][pid]]._level || 0) + 1
  }
  return res
}
src/utils/request.js
@@ -5,12 +5,23 @@
import errorCode from '@/utils/errorCode'
import {getPath, getTenantEnable} from "@/utils/ruoyi";
import {refreshToken} from "@/api/login";
import merge from 'lodash/merge'
import isPlainObject from 'lodash/isPlainObject'
import qs from 'qs'
import { clearLoginInfo } from '@/utils'
import router from '@/router'
// 需要忽略的提示。忽略后,自动 Promise.reject('error')
const ignoreMsgs = [
  "无效的刷新令牌", // 刷新令牌被删除时,不用提示
  "刷新令牌已过期" // 使用刷新令牌,刷新获取新的访问令牌时,结果因为过期失败,此时需要忽略。否则,会导致继续 401,无法跳转到登出界面
]
// const http = axios.create({
//   baseURL: process.env.VUE_APP_BASE_API,
//   timeout: 1000 * 180,
//   withCredentials: true
// })
// 是否显示重新登录
export let isRelogin = { show: false };
@@ -32,6 +43,8 @@
})
// request拦截器
service.interceptors.request.use(config => {
  // 默认参数
  const defaults = {}
  // 是否需要设置 token
  const isToken = (config.headers || {}).isToken === false
  if (getAccessToken() && !isToken) {
@@ -209,4 +222,49 @@
  return Promise.reject('无效的会话,或者会话已过期,请重新登录。')
}
/**
 * 请求地址处理
 * @param {*} actionName action方法名称
 */
service.adornUrl = (actionName) => {
  return '/proxyApiDataConfig' + actionName
}
/**
 * 请求地址处理
 * @param {*} actionName action方法名称
 */
service.adornUrlrRtd = (actionName) => {
  // 开启代理, 接口前缀统一使用[/real-time-data/]前缀做代理拦截!
  return (process.env.OPEN_PROXY ? '/realTimeDataApi' : window.SITE_CONFIG.baseUrl) + actionName
}
/**
 * get请求参数处理
 * @param {*} params 参数对象
 * @param {*} openDefultParams 是否开启默认参数?
 */
service.adornParams = (params = {}, openDefultParams = true) => {
  var defaults = {
    't': new Date().getTime()
  }
  return openDefultParams ? merge(defaults, params) : params
}
/**
 * post请求数据处理
 * @param {*} data 数据对象
 * @param {*} openDefultdata 是否开启默认数据?
 * @param {*} contentType 数据格式
 *  json: 'application/json; charset=utf-8'
 *  form: 'application/x-www-form-urlencoded; charset=utf-8'
 */
service.adornData = (data = {}, openDefultdata = true, contentType = 'json') => {
  var defaults = {
    't': new Date().getTime()
  }
  data = openDefultdata ? merge(defaults, data) : data
  return contentType === 'json' ? JSON.stringify(data) : qs.stringify(data)
}
export default service
vue.config.js
@@ -70,6 +70,9 @@
        minRatio: 0.8                   // 压缩率小于1才会压缩
      })
    ],
    externals: {
      './cptable': 'var cptable'
    }
  },
  chainWebpack(config) {
    config.plugins.delete('preload') // TODO: need test