Merge branch 'master' into deploy
This commit is contained in:
		@@ -50,6 +50,7 @@ It is a magical vue admin based on the newest development stack of vue, built-in
 | 
			
		||||
 | 
			
		||||
- Base template recommends using: [vue-admin-template](https://github.com/PanJiaChen/vue-admin-template)
 | 
			
		||||
- Desktop: [electron-vue-admin](https://github.com/PanJiaChen/electron-vue-admin)
 | 
			
		||||
- Typescript: [vue-typescript-admin-template](https://github.com/Armour/vue-typescript-admin-template) (Credits: [@Armour](https://github.com/Armour))
 | 
			
		||||
 | 
			
		||||
**This project does not support low version browsers (e.g. IE). Please add polyfill yourself if you need them.**
 | 
			
		||||
 | 
			
		||||
@@ -128,7 +129,7 @@ Understanding and learning this knowledge in advance will greatly help the use o
 | 
			
		||||
- Error Log
 | 
			
		||||
- Dashboard
 | 
			
		||||
- Guide Page
 | 
			
		||||
- Echarts
 | 
			
		||||
- ECharts
 | 
			
		||||
- Clipboard
 | 
			
		||||
- Markdown to html
 | 
			
		||||
```
 | 
			
		||||
 
 | 
			
		||||
@@ -50,6 +50,7 @@
 | 
			
		||||
 | 
			
		||||
- 模板建议使用: [vue-admin-template](https://github.com/PanJiaChen/vue-admin-template)
 | 
			
		||||
- 桌面端: [electron-vue-admin](https://github.com/PanJiaChen/electron-vue-admin)
 | 
			
		||||
- Typescript版: [vue-typescript-admin-template](https://github.com/Armour/vue-typescript-admin-template) (鸣谢: [@Armour](https://github.com/Armour))
 | 
			
		||||
 | 
			
		||||
群主 **[圈子](https://jianshiapp.com/circles/1209)** 楼主会经常分享一些技术相关的东西,或者加入[qq 群](https://github.com/PanJiaChen/vue-element-admin/issues/602)
 | 
			
		||||
 | 
			
		||||
@@ -140,7 +141,7 @@
 | 
			
		||||
- 错误日志
 | 
			
		||||
- Dashboard
 | 
			
		||||
- 引导页
 | 
			
		||||
- Echarts 图表
 | 
			
		||||
- ECharts 图表
 | 
			
		||||
- Clipboard(剪贴复制)
 | 
			
		||||
- Markdown2html
 | 
			
		||||
```
 | 
			
		||||
@@ -154,7 +155,7 @@ git clone https://github.com/PanJiaChen/vue-element-admin.git
 | 
			
		||||
# 安装依赖
 | 
			
		||||
npm install
 | 
			
		||||
 | 
			
		||||
# 建议不要用cnpm安装 会有各种诡异的bug 可以通过如下操作解决 npm 下载速度慢的问题
 | 
			
		||||
# 建议不要用 cnpm 安装 会有各种诡异的bug 可以通过如下操作解决 npm 下载速度慢的问题
 | 
			
		||||
npm install --registry=https://registry.npm.taobao.org
 | 
			
		||||
 | 
			
		||||
# 启动服务
 | 
			
		||||
 
 | 
			
		||||
@@ -116,7 +116,7 @@ const webpackConfig = merge(baseWebpackConfig, {
 | 
			
		||||
          test: /[\\/]node_modules[\\/]element-ui[\\/]/
 | 
			
		||||
        },
 | 
			
		||||
        commons: {
 | 
			
		||||
          name: 'chunk-comomns',
 | 
			
		||||
          name: 'chunk-commons',
 | 
			
		||||
          test: resolve('src/components'), // 可自定义拓展你的规则
 | 
			
		||||
          minChunks: 3, // 最小公用次数
 | 
			
		||||
          priority: 5,
 | 
			
		||||
 
 | 
			
		||||
@@ -50,7 +50,7 @@
 | 
			
		||||
    "mockjs": "1.0.1-beta3",
 | 
			
		||||
    "normalize.css": "7.0.0",
 | 
			
		||||
    "nprogress": "0.2.0",
 | 
			
		||||
    "screenfull": "3.3.2",
 | 
			
		||||
    "screenfull": "3.3.3",
 | 
			
		||||
    "showdown": "1.8.6",
 | 
			
		||||
    "simplemde": "1.11.2",
 | 
			
		||||
    "sortablejs": "1.7.0",
 | 
			
		||||
@@ -86,7 +86,7 @@
 | 
			
		||||
    "file-loader": "1.1.11",
 | 
			
		||||
    "friendly-errors-webpack-plugin": "1.7.0",
 | 
			
		||||
    "hash-sum": "1.0.2",
 | 
			
		||||
    "html-webpack-plugin": "^4.0.0-alpha",
 | 
			
		||||
    "html-webpack-plugin": "4.0.0-alpha",
 | 
			
		||||
    "husky": "0.14.3",
 | 
			
		||||
    "lint-staged": "7.2.2",
 | 
			
		||||
    "mini-css-extract-plugin": "0.4.1",
 | 
			
		||||
 
 | 
			
		||||
@@ -56,6 +56,10 @@ export default {
 | 
			
		||||
      this.chart.setOption(
 | 
			
		||||
        {
 | 
			
		||||
          backgroundColor: '#08263a',
 | 
			
		||||
          grid: {
 | 
			
		||||
            left: '5%',
 | 
			
		||||
            right: '5%'
 | 
			
		||||
          },
 | 
			
		||||
          xAxis: [{
 | 
			
		||||
            show: false,
 | 
			
		||||
            data: xAxisData
 | 
			
		||||
 
 | 
			
		||||
@@ -80,8 +80,8 @@ export default {
 | 
			
		||||
        },
 | 
			
		||||
        grid: {
 | 
			
		||||
          top: 100,
 | 
			
		||||
          left: '3%',
 | 
			
		||||
          right: '4%',
 | 
			
		||||
          left: '2%',
 | 
			
		||||
          right: '2%',
 | 
			
		||||
          bottom: '2%',
 | 
			
		||||
          containLabel: true
 | 
			
		||||
        },
 | 
			
		||||
 
 | 
			
		||||
@@ -75,8 +75,10 @@ export default {
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        grid: {
 | 
			
		||||
          left: '5%',
 | 
			
		||||
          right: '5%',
 | 
			
		||||
          borderWidth: 0,
 | 
			
		||||
          top: 110,
 | 
			
		||||
          top: 150,
 | 
			
		||||
          bottom: 95,
 | 
			
		||||
          textStyle: {
 | 
			
		||||
            color: '#fff'
 | 
			
		||||
 
 | 
			
		||||
@@ -2,14 +2,27 @@ import { debounce } from '@/utils'
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  mounted() {
 | 
			
		||||
    this.__resizeHanlder = debounce(() => {
 | 
			
		||||
    this.__resizeHandler = debounce(() => {
 | 
			
		||||
      if (this.chart) {
 | 
			
		||||
        this.chart.resize()
 | 
			
		||||
      }
 | 
			
		||||
    }, 100)
 | 
			
		||||
    window.addEventListener('resize', this.__resizeHanlder)
 | 
			
		||||
    window.addEventListener('resize', this.__resizeHandler)
 | 
			
		||||
 | 
			
		||||
    const sidebarElm = document.getElementsByClassName('sidebar-container')[0]
 | 
			
		||||
    sidebarElm.addEventListener('transitionend', this.sidebarResizeHandler)
 | 
			
		||||
  },
 | 
			
		||||
  beforeDestroy() {
 | 
			
		||||
    window.removeEventListener('resize', this.__resizeHanlder)
 | 
			
		||||
    window.removeEventListener('resize', this.__resizeHandler)
 | 
			
		||||
 | 
			
		||||
    const sidebarElm = document.getElementsByClassName('sidebar-container')[0]
 | 
			
		||||
    sidebarElm.removeEventListener('transitionend', this.sidebarResizeHandler)
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
    sidebarResizeHandler(e) {
 | 
			
		||||
      if (e.propertyName === 'width') {
 | 
			
		||||
        this.__resizeHandler()
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -49,7 +49,6 @@ export default {
 | 
			
		||||
        this.$message('请等待所有图片上传成功 或 出现了网络问题,请刷新页面重新上传!')
 | 
			
		||||
        return
 | 
			
		||||
      }
 | 
			
		||||
      console.log(arr)
 | 
			
		||||
      this.$emit('successCBK', arr)
 | 
			
		||||
      this.listObj = {}
 | 
			
		||||
      this.fileList = []
 | 
			
		||||
 
 | 
			
		||||
@@ -26,7 +26,7 @@ export default {
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
    generateDate({ header, results }) {
 | 
			
		||||
    generateData({ header, results }) {
 | 
			
		||||
      this.excelData.header = header
 | 
			
		||||
      this.excelData.results = results
 | 
			
		||||
      this.onSuccess && this.onSuccess(this.excelData)
 | 
			
		||||
@@ -82,20 +82,20 @@ export default {
 | 
			
		||||
        const reader = new FileReader()
 | 
			
		||||
        reader.onload = e => {
 | 
			
		||||
          const data = e.target.result
 | 
			
		||||
          const fixedData = this.fixdata(data)
 | 
			
		||||
          const fixedData = this.fixData(data)
 | 
			
		||||
          const workbook = XLSX.read(btoa(fixedData), { type: 'base64' })
 | 
			
		||||
          const firstSheetName = workbook.SheetNames[0]
 | 
			
		||||
          const worksheet = workbook.Sheets[firstSheetName]
 | 
			
		||||
          const header = this.get_header_row(worksheet)
 | 
			
		||||
          const header = this.getHeaderRow(worksheet)
 | 
			
		||||
          const results = XLSX.utils.sheet_to_json(worksheet)
 | 
			
		||||
          this.generateDate({ header, results })
 | 
			
		||||
          this.generateData({ header, results })
 | 
			
		||||
          this.loading = false
 | 
			
		||||
          resolve()
 | 
			
		||||
        }
 | 
			
		||||
        reader.readAsArrayBuffer(rawFile)
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
    fixdata(data) {
 | 
			
		||||
    fixData(data) {
 | 
			
		||||
      let o = ''
 | 
			
		||||
      let l = 0
 | 
			
		||||
      const w = 10240
 | 
			
		||||
@@ -103,14 +103,16 @@ export default {
 | 
			
		||||
      o += String.fromCharCode.apply(null, new Uint8Array(data.slice(l * w)))
 | 
			
		||||
      return o
 | 
			
		||||
    },
 | 
			
		||||
    get_header_row(sheet) {
 | 
			
		||||
    getHeaderRow(sheet) {
 | 
			
		||||
      const headers = []
 | 
			
		||||
      const range = XLSX.utils.decode_range(sheet['!ref'])
 | 
			
		||||
      let C
 | 
			
		||||
      const R = range.s.r /* start in the first row */
 | 
			
		||||
      const R = range.s.r
 | 
			
		||||
      /* start in the first row */
 | 
			
		||||
      for (C = range.s.c; C <= range.e.c; ++C) { /* walk every column in the range */
 | 
			
		||||
        var cell = sheet[XLSX.utils.encode_cell({ c: C, r: R })] /* find the cell in the first row */
 | 
			
		||||
        var hdr = 'UNKNOWN ' + C // <-- replace with your desired default
 | 
			
		||||
        const cell = sheet[XLSX.utils.encode_cell({ c: C, r: R })]
 | 
			
		||||
        /* find the cell in the first row */
 | 
			
		||||
        let hdr = 'UNKNOWN ' + C // <-- replace with your desired default
 | 
			
		||||
        if (cell && cell.t) hdr = XLSX.utils.format_cell(cell)
 | 
			
		||||
        headers.push(hdr)
 | 
			
		||||
      }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
// Inspired by https://github.com/Inndy/vue-clipboard2
 | 
			
		||||
const Clipboard = require('clipboard')
 | 
			
		||||
if (!Clipboard) {
 | 
			
		||||
  throw new Error('you shold npm install `clipboard` --save at first ')
 | 
			
		||||
  throw new Error('you should npm install `clipboard` --save at first ')
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
 
 | 
			
		||||
@@ -20,7 +20,7 @@ export default{
 | 
			
		||||
      const disY = e.clientY - dialogHeaderEl.offsetTop
 | 
			
		||||
 | 
			
		||||
      const dragDomWidth = dragDom.offsetWidth
 | 
			
		||||
      const dragDomheight = dragDom.offsetHeight
 | 
			
		||||
      const dragDomHeight = dragDom.offsetHeight
 | 
			
		||||
 | 
			
		||||
      const screenWidth = document.body.clientWidth
 | 
			
		||||
      const screenHeight = document.body.clientHeight
 | 
			
		||||
@@ -29,7 +29,7 @@ export default{
 | 
			
		||||
      const maxDragDomLeft = screenWidth - dragDom.offsetLeft - dragDomWidth
 | 
			
		||||
 | 
			
		||||
      const minDragDomTop = dragDom.offsetTop
 | 
			
		||||
      const maxDragDomTop = screenHeight - dragDom.offsetTop - dragDomheight
 | 
			
		||||
      const maxDragDomTop = screenHeight - dragDom.offsetTop - dragDomHeight
 | 
			
		||||
 | 
			
		||||
      // 获取到的值带px 正则匹配替换
 | 
			
		||||
      let styL = getStyle(dragDom, 'left')
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,7 @@ export default{
 | 
			
		||||
      const customOpts = Object.assign({}, binding.value)
 | 
			
		||||
      const opts = Object.assign({
 | 
			
		||||
        ele: el, // 波纹作用元素
 | 
			
		||||
        type: 'hit', // hit点击位置扩散center中心点扩展
 | 
			
		||||
        type: 'hit', // hit 点击位置扩散 center中心点扩展
 | 
			
		||||
        color: 'rgba(0, 0, 0, 0.15)' // 波纹颜色
 | 
			
		||||
      }, customOpts)
 | 
			
		||||
      const target = opts.ele
 | 
			
		||||
 
 | 
			
		||||
@@ -37,6 +37,6 @@ export function numberFormatter(num, digits) {
 | 
			
		||||
  return num.toString()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function toThousandslsFilter(num) {
 | 
			
		||||
export function toThousandFilter(num) {
 | 
			
		||||
  return (+num || 0).toString().replace(/^-?\d+/g, m => m.replace(/(?=(?!\b)(\d{3})+$)/g, ','))
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,12 +1,9 @@
 | 
			
		||||
import Vue from 'vue'
 | 
			
		||||
import SvgIcon from '@/components/SvgIcon'// svg组件
 | 
			
		||||
import generateIconsView from '@/views/svg-icons/generateIconsView.js'// just for @/views/icons , you can delete it
 | 
			
		||||
 | 
			
		||||
// register globally
 | 
			
		||||
Vue.component('svg-icon', SvgIcon)
 | 
			
		||||
 | 
			
		||||
const requireAll = requireContext => requireContext.keys().map(requireContext)
 | 
			
		||||
const req = require.context('./svg', false, /\.svg$/)
 | 
			
		||||
const iconMap = requireAll(req)
 | 
			
		||||
 | 
			
		||||
generateIconsView.generate(iconMap) // just for @/views/icons , you can delete it
 | 
			
		||||
const requireAll = requireContext => requireContext.keys().map(requireContext)
 | 
			
		||||
requireAll(req)
 | 
			
		||||
 
 | 
			
		||||
@@ -14,7 +14,7 @@ function hasPermission(roles, permissionRoles) {
 | 
			
		||||
  return roles.some(role => permissionRoles.indexOf(role) >= 0)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const whiteList = ['/login', '/authredirect']// no redirect whitelist
 | 
			
		||||
const whiteList = ['/login', '/auth-redirect']// no redirect whitelist
 | 
			
		||||
 | 
			
		||||
router.beforeEach((to, from, next) => {
 | 
			
		||||
  NProgress.start() // start progress bar
 | 
			
		||||
@@ -52,7 +52,7 @@ router.beforeEach((to, from, next) => {
 | 
			
		||||
    if (whiteList.indexOf(to.path) !== -1) { // 在免登录白名单,直接进入
 | 
			
		||||
      next()
 | 
			
		||||
    } else {
 | 
			
		||||
      next('/login') // 否则全部重定向到登录页
 | 
			
		||||
      next(`/login?redirect=${to.path}`) // 否则全部重定向到登录页
 | 
			
		||||
      NProgress.done() // if current page is login will not trigger afterEach hook, so manually handle it
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 
 | 
			
		||||
@@ -12,7 +12,7 @@ import chartsRouter from './modules/charts'
 | 
			
		||||
import tableRouter from './modules/table'
 | 
			
		||||
import nestedRouter from './modules/nested'
 | 
			
		||||
 | 
			
		||||
/** note: submenu only apppear when children.length>=1
 | 
			
		||||
/** note: Submenu only appear when children.length>=1
 | 
			
		||||
 *  detail see  https://panjiachen.github.io/vue-element-admin-site/guide/essentials/router-and-nav.html
 | 
			
		||||
 **/
 | 
			
		||||
 | 
			
		||||
@@ -21,7 +21,7 @@ import nestedRouter from './modules/nested'
 | 
			
		||||
* alwaysShow: true               if set true, will always show the root menu, whatever its child routes length
 | 
			
		||||
*                                if not set alwaysShow, only more than one route under the children
 | 
			
		||||
*                                it will becomes nested mode, otherwise not show the root menu
 | 
			
		||||
* redirect: noredirect           if `redirect:noredirect` will no redirct in the breadcrumb
 | 
			
		||||
* redirect: noredirect           if `redirect:noredirect` will no redirect in the breadcrumb
 | 
			
		||||
* name:'router-name'             the name is used by <keep-alive> (must set!!!)
 | 
			
		||||
* meta : {
 | 
			
		||||
    roles: ['admin','editor']     will control the page roles (you can set multiple roles)
 | 
			
		||||
@@ -48,7 +48,7 @@ export const constantRouterMap = [
 | 
			
		||||
    hidden: true
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    path: '/authredirect',
 | 
			
		||||
    path: '/auth-redirect',
 | 
			
		||||
    component: () => import('@/views/login/authredirect'),
 | 
			
		||||
    hidden: true
 | 
			
		||||
  },
 | 
			
		||||
 
 | 
			
		||||
@@ -23,7 +23,6 @@ const tagsView = {
 | 
			
		||||
      for (const [i, v] of state.visitedViews.entries()) {
 | 
			
		||||
        if (v.path === view.path) {
 | 
			
		||||
          state.visitedViews.splice(i, 1)
 | 
			
		||||
          console.log('1')
 | 
			
		||||
          break
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 
 | 
			
		||||
@@ -28,6 +28,9 @@
 | 
			
		||||
        height: 100%;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    .el-scrollbar__bar.is-vertical{
 | 
			
		||||
      right: 0px;
 | 
			
		||||
    }
 | 
			
		||||
    .is-horizontal {
 | 
			
		||||
      display: none;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -169,7 +169,6 @@ export function scrollTo(element, to, duration) {
 | 
			
		||||
  const difference = to - element.scrollTop
 | 
			
		||||
  const perTick = (difference / duration) * 10
 | 
			
		||||
  setTimeout(() => {
 | 
			
		||||
    console.log(new Date())
 | 
			
		||||
    element.scrollTop = element.scrollTop + perTick
 | 
			
		||||
    if (element.scrollTop === to) return
 | 
			
		||||
    scrollTo(element, to, duration - 10)
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,7 @@ import { getToken } from '@/utils/auth'
 | 
			
		||||
 | 
			
		||||
// create an axios instance
 | 
			
		||||
const service = axios.create({
 | 
			
		||||
  baseURL: process.env.BASE_API, // api的base_url
 | 
			
		||||
  baseURL: process.env.BASE_API, // api 的 base_url
 | 
			
		||||
  timeout: 5000 // request timeout
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
@@ -26,13 +26,13 @@ service.interceptors.request.use(
 | 
			
		||||
  }
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// respone interceptor
 | 
			
		||||
// response interceptor
 | 
			
		||||
service.interceptors.response.use(
 | 
			
		||||
  response => response,
 | 
			
		||||
  /**
 | 
			
		||||
   * 下面的注释为通过在response里,自定义code来标示请求状态
 | 
			
		||||
   * 当code返回如下情况则说明权限有问题,登出并返回到登录页
 | 
			
		||||
   * 如想通过xmlhttprequest来状态码标识 逻辑可写在下面error中
 | 
			
		||||
   * 如想通过 xmlhttprequest 来状态码标识 逻辑可写在下面error中
 | 
			
		||||
   * 以下代码均为样例,请结合自生需求加以修改,若不需要,则可删除
 | 
			
		||||
   */
 | 
			
		||||
  // response => {
 | 
			
		||||
 
 | 
			
		||||
@@ -16,9 +16,8 @@ export default {
 | 
			
		||||
<style scoped>
 | 
			
		||||
.chart-container{
 | 
			
		||||
  position: relative;
 | 
			
		||||
  padding: 20px;
 | 
			
		||||
  width: 100%;
 | 
			
		||||
  height: 85vh;
 | 
			
		||||
  height: calc(100vh - 84px);
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -16,9 +16,8 @@ export default {
 | 
			
		||||
<style scoped>
 | 
			
		||||
.chart-container{
 | 
			
		||||
  position: relative;
 | 
			
		||||
  padding:20px;
 | 
			
		||||
  width: 100%;
 | 
			
		||||
  height:85vh;
 | 
			
		||||
  height: calc(100vh - 84px);
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -16,9 +16,8 @@ export default {
 | 
			
		||||
<style scoped>
 | 
			
		||||
.chart-container{
 | 
			
		||||
  position: relative;
 | 
			
		||||
  padding: 20px;
 | 
			
		||||
  width: 100%;
 | 
			
		||||
  height:85vh;
 | 
			
		||||
  height: calc(100vh - 84px);
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -2,11 +2,11 @@
 | 
			
		||||
  <div class="app-container">
 | 
			
		||||
    <el-tabs v-model="activeName">
 | 
			
		||||
      <el-tab-pane label="use clipboard  directly" name="directly">
 | 
			
		||||
        <el-input v-model="inputData" placeholder="Please input" style="width:400px;"/>
 | 
			
		||||
        <el-input v-model="inputData" placeholder="Please input" style="width:400px;max-width:100%;"/>
 | 
			
		||||
        <el-button type="primary" icon="document" @click="handleCopy(inputData,$event)">copy</el-button>
 | 
			
		||||
      </el-tab-pane>
 | 
			
		||||
      <el-tab-pane label="use clipboard by v-directive" name="v-directive">
 | 
			
		||||
        <el-input v-model="inputData" placeholder="Please input" style="width:400px;"/>
 | 
			
		||||
        <el-input v-model="inputData" placeholder="Please input" style="width:400px;max-width:100%;"/>
 | 
			
		||||
        <el-button v-clipboard:copy="inputData" v-clipboard:success="clipboardSuccess" type="primary" icon="document">copy</el-button>
 | 
			
		||||
      </el-tab-pane>
 | 
			
		||||
    </el-tabs>
 | 
			
		||||
 
 | 
			
		||||
@@ -31,18 +31,18 @@ export default {
 | 
			
		||||
  },
 | 
			
		||||
  mounted() {
 | 
			
		||||
    this.initChart()
 | 
			
		||||
    this.__resizeHanlder = debounce(() => {
 | 
			
		||||
    this.__resizeHandler = debounce(() => {
 | 
			
		||||
      if (this.chart) {
 | 
			
		||||
        this.chart.resize()
 | 
			
		||||
      }
 | 
			
		||||
    }, 100)
 | 
			
		||||
    window.addEventListener('resize', this.__resizeHanlder)
 | 
			
		||||
    window.addEventListener('resize', this.__resizeHandler)
 | 
			
		||||
  },
 | 
			
		||||
  beforeDestroy() {
 | 
			
		||||
    if (!this.chart) {
 | 
			
		||||
      return
 | 
			
		||||
    }
 | 
			
		||||
    window.removeEventListener('resize', this.__resizeHanlder)
 | 
			
		||||
    window.removeEventListener('resize', this.__resizeHandler)
 | 
			
		||||
    this.chart.dispose()
 | 
			
		||||
    this.chart = null
 | 
			
		||||
  },
 | 
			
		||||
 
 | 
			
		||||
@@ -46,33 +46,38 @@ export default {
 | 
			
		||||
  mounted() {
 | 
			
		||||
    this.initChart()
 | 
			
		||||
    if (this.autoResize) {
 | 
			
		||||
      this.__resizeHanlder = debounce(() => {
 | 
			
		||||
      this.__resizeHandler = debounce(() => {
 | 
			
		||||
        if (this.chart) {
 | 
			
		||||
          this.chart.resize()
 | 
			
		||||
        }
 | 
			
		||||
      }, 100)
 | 
			
		||||
      window.addEventListener('resize', this.__resizeHanlder)
 | 
			
		||||
      window.addEventListener('resize', this.__resizeHandler)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // 监听侧边栏的变化
 | 
			
		||||
    const sidebarElm = document.getElementsByClassName('sidebar-container')[0]
 | 
			
		||||
    sidebarElm.addEventListener('transitionend', this.__resizeHanlder)
 | 
			
		||||
    sidebarElm.addEventListener('transitionend', this.sidebarResizeHandler)
 | 
			
		||||
  },
 | 
			
		||||
  beforeDestroy() {
 | 
			
		||||
    if (!this.chart) {
 | 
			
		||||
      return
 | 
			
		||||
    }
 | 
			
		||||
    if (this.autoResize) {
 | 
			
		||||
      window.removeEventListener('resize', this.__resizeHanlder)
 | 
			
		||||
      window.removeEventListener('resize', this.__resizeHandler)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const sidebarElm = document.getElementsByClassName('sidebar-container')[0]
 | 
			
		||||
    sidebarElm.removeEventListener('transitionend', this.__resizeHanlder)
 | 
			
		||||
    sidebarElm.removeEventListener('transitionend', this.sidebarResizeHandler)
 | 
			
		||||
 | 
			
		||||
    this.chart.dispose()
 | 
			
		||||
    this.chart = null
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
    sidebarResizeHandler(e) {
 | 
			
		||||
      if (e.propertyName === 'width') {
 | 
			
		||||
        this.__resizeHandler()
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    setOptions({ expectedData, actualData } = {}) {
 | 
			
		||||
      this.chart.setOption({
 | 
			
		||||
        xAxis: {
 | 
			
		||||
 
 | 
			
		||||
@@ -29,18 +29,18 @@ export default {
 | 
			
		||||
  },
 | 
			
		||||
  mounted() {
 | 
			
		||||
    this.initChart()
 | 
			
		||||
    this.__resizeHanlder = debounce(() => {
 | 
			
		||||
    this.__resizeHandler = debounce(() => {
 | 
			
		||||
      if (this.chart) {
 | 
			
		||||
        this.chart.resize()
 | 
			
		||||
      }
 | 
			
		||||
    }, 100)
 | 
			
		||||
    window.addEventListener('resize', this.__resizeHanlder)
 | 
			
		||||
    window.addEventListener('resize', this.__resizeHandler)
 | 
			
		||||
  },
 | 
			
		||||
  beforeDestroy() {
 | 
			
		||||
    if (!this.chart) {
 | 
			
		||||
      return
 | 
			
		||||
    }
 | 
			
		||||
    window.removeEventListener('resize', this.__resizeHanlder)
 | 
			
		||||
    window.removeEventListener('resize', this.__resizeHandler)
 | 
			
		||||
    this.chart.dispose()
 | 
			
		||||
    this.chart = null
 | 
			
		||||
  },
 | 
			
		||||
 
 | 
			
		||||
@@ -31,18 +31,18 @@ export default {
 | 
			
		||||
  },
 | 
			
		||||
  mounted() {
 | 
			
		||||
    this.initChart()
 | 
			
		||||
    this.__resizeHanlder = debounce(() => {
 | 
			
		||||
    this.__resizeHandler = debounce(() => {
 | 
			
		||||
      if (this.chart) {
 | 
			
		||||
        this.chart.resize()
 | 
			
		||||
      }
 | 
			
		||||
    }, 100)
 | 
			
		||||
    window.addEventListener('resize', this.__resizeHanlder)
 | 
			
		||||
    window.addEventListener('resize', this.__resizeHandler)
 | 
			
		||||
  },
 | 
			
		||||
  beforeDestroy() {
 | 
			
		||||
    if (!this.chart) {
 | 
			
		||||
      return
 | 
			
		||||
    }
 | 
			
		||||
    window.removeEventListener('resize', this.__resizeHanlder)
 | 
			
		||||
    window.removeEventListener('resize', this.__resizeHandler)
 | 
			
		||||
    this.chart.dispose()
 | 
			
		||||
    this.chart = null
 | 
			
		||||
  },
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@
 | 
			
		||||
    </el-table-column>
 | 
			
		||||
    <el-table-column label="Price" width="195" align="center">
 | 
			
		||||
      <template slot-scope="scope">
 | 
			
		||||
        ¥{{ scope.row.price | toThousandslsFilter }}
 | 
			
		||||
        ¥{{ scope.row.price | toThousandFilter }}
 | 
			
		||||
      </template>
 | 
			
		||||
    </el-table-column>
 | 
			
		||||
    <el-table-column label="Status" width="100" align="center">
 | 
			
		||||
 
 | 
			
		||||
@@ -35,7 +35,6 @@ export default {
 | 
			
		||||
  .document-btn {
 | 
			
		||||
    float: left;
 | 
			
		||||
    margin-left: 50px;
 | 
			
		||||
    vertical-align: middle;
 | 
			
		||||
    display: block;
 | 
			
		||||
    cursor: pointer;
 | 
			
		||||
    background: black;
 | 
			
		||||
 
 | 
			
		||||
@@ -53,6 +53,7 @@ export default {
 | 
			
		||||
<style rel="stylesheet/scss" lang="scss" scoped>
 | 
			
		||||
  .errPage-container {
 | 
			
		||||
    width: 800px;
 | 
			
		||||
    max-width: 100%;
 | 
			
		||||
    margin: 100px auto;
 | 
			
		||||
    .pan-back-btn {
 | 
			
		||||
      background: #008489;
 | 
			
		||||
 
 | 
			
		||||
@@ -15,7 +15,7 @@
 | 
			
		||||
    </el-card>
 | 
			
		||||
 | 
			
		||||
    <el-row :gutter="20" style="margin:100px 15px 50px;">
 | 
			
		||||
      <el-col :span="12">
 | 
			
		||||
      <el-col :span="12" :xs="24">
 | 
			
		||||
        <div class="block">
 | 
			
		||||
          <el-date-picker v-model="date" :placeholder="$t('i18nView.datePlaceholder')" type="date"/>
 | 
			
		||||
        </div>
 | 
			
		||||
@@ -37,7 +37,7 @@
 | 
			
		||||
          <el-button class="item-btn" size="small" type="danger">{{ $t('i18nView.danger') }}</el-button>
 | 
			
		||||
        </div>
 | 
			
		||||
      </el-col>
 | 
			
		||||
      <el-col :span="12">
 | 
			
		||||
      <el-col :span="12" :xs="24">
 | 
			
		||||
        <el-table :data="tableData" fit highlight-current-row border style="width: 100%">
 | 
			
		||||
          <el-table-column :label="$t('i18nView.tableName')" prop="name" width="100" align="center"/>
 | 
			
		||||
          <el-table-column :label="$t('i18nView.tableDate')" prop="date" width="120" align="center"/>
 | 
			
		||||
@@ -103,6 +103,7 @@ export default {
 | 
			
		||||
<style scoped>
 | 
			
		||||
.box-card {
 | 
			
		||||
  width: 600px;
 | 
			
		||||
  max-width: 100%;
 | 
			
		||||
  margin: 20px auto;
 | 
			
		||||
}
 | 
			
		||||
.item-btn{
 | 
			
		||||
 
 | 
			
		||||
@@ -26,6 +26,7 @@ export default {
 | 
			
		||||
.app-main {
 | 
			
		||||
  /*84 = navbar + tags-view = 50 +34 */
 | 
			
		||||
  min-height: calc(100vh - 84px);
 | 
			
		||||
  width: 100%;
 | 
			
		||||
  position: relative;
 | 
			
		||||
  overflow: hidden;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,25 +1,27 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <el-menu class="navbar" mode="horizontal">
 | 
			
		||||
  <div class="navbar">
 | 
			
		||||
    <hamburger :toggle-click="toggleSideBar" :is-active="sidebar.opened" class="hamburger-container"/>
 | 
			
		||||
 | 
			
		||||
    <breadcrumb class="breadcrumb-container"/>
 | 
			
		||||
 | 
			
		||||
    <div class="right-menu">
 | 
			
		||||
      <error-log class="errLog-container right-menu-item"/>
 | 
			
		||||
      <template v-if="device!=='mobile'">
 | 
			
		||||
        <error-log class="errLog-container right-menu-item"/>
 | 
			
		||||
 | 
			
		||||
      <el-tooltip :content="$t('navbar.screenfull')" effect="dark" placement="bottom">
 | 
			
		||||
        <screenfull class="screenfull right-menu-item"/>
 | 
			
		||||
      </el-tooltip>
 | 
			
		||||
        <el-tooltip :content="$t('navbar.screenfull')" effect="dark" placement="bottom">
 | 
			
		||||
          <screenfull class="screenfull right-menu-item"/>
 | 
			
		||||
        </el-tooltip>
 | 
			
		||||
 | 
			
		||||
      <el-tooltip :content="$t('navbar.size')" effect="dark" placement="bottom">
 | 
			
		||||
        <size-select class="international right-menu-item"/>
 | 
			
		||||
      </el-tooltip>
 | 
			
		||||
        <el-tooltip :content="$t('navbar.size')" effect="dark" placement="bottom">
 | 
			
		||||
          <size-select class="international right-menu-item"/>
 | 
			
		||||
        </el-tooltip>
 | 
			
		||||
 | 
			
		||||
      <lang-select class="international right-menu-item"/>
 | 
			
		||||
        <lang-select class="international right-menu-item"/>
 | 
			
		||||
 | 
			
		||||
      <el-tooltip :content="$t('navbar.theme')" effect="dark" placement="bottom">
 | 
			
		||||
        <theme-picker class="theme-switch right-menu-item"/>
 | 
			
		||||
      </el-tooltip>
 | 
			
		||||
        <el-tooltip :content="$t('navbar.theme')" effect="dark" placement="bottom">
 | 
			
		||||
          <theme-picker class="theme-switch right-menu-item"/>
 | 
			
		||||
        </el-tooltip>
 | 
			
		||||
      </template>
 | 
			
		||||
 | 
			
		||||
      <el-dropdown class="avatar-container right-menu-item" trigger="click">
 | 
			
		||||
        <div class="avatar-wrapper">
 | 
			
		||||
@@ -43,7 +45,7 @@
 | 
			
		||||
        </el-dropdown-menu>
 | 
			
		||||
      </el-dropdown>
 | 
			
		||||
    </div>
 | 
			
		||||
  </el-menu>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
@@ -70,7 +72,8 @@ export default {
 | 
			
		||||
    ...mapGetters([
 | 
			
		||||
      'sidebar',
 | 
			
		||||
      'name',
 | 
			
		||||
      'avatar'
 | 
			
		||||
      'avatar',
 | 
			
		||||
      'device'
 | 
			
		||||
    ])
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
<script>
 | 
			
		||||
export default {
 | 
			
		||||
  name: 'Authredirect',
 | 
			
		||||
  name: 'AuthRedirect',
 | 
			
		||||
  created() {
 | 
			
		||||
    const hash = window.location.search.slice(1)
 | 
			
		||||
    window.opener.location.href = window.location.origin + '/login#' + hash
 | 
			
		||||
 
 | 
			
		||||
@@ -96,9 +96,19 @@ export default {
 | 
			
		||||
      },
 | 
			
		||||
      passwordType: 'password',
 | 
			
		||||
      loading: false,
 | 
			
		||||
      showDialog: false
 | 
			
		||||
      showDialog: false,
 | 
			
		||||
      redirect: undefined
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  watch: {
 | 
			
		||||
    $route: {
 | 
			
		||||
      handler: function(route) {
 | 
			
		||||
        this.redirect = route.query && route.query.redirect
 | 
			
		||||
      },
 | 
			
		||||
      immediate: true
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  },
 | 
			
		||||
  created() {
 | 
			
		||||
    // window.addEventListener('hashchange', this.afterQRScan)
 | 
			
		||||
  },
 | 
			
		||||
@@ -119,7 +129,7 @@ export default {
 | 
			
		||||
          this.loading = true
 | 
			
		||||
          this.$store.dispatch('LoginByUsername', this.loginForm).then(() => {
 | 
			
		||||
            this.loading = false
 | 
			
		||||
            this.$router.push({ path: '/' })
 | 
			
		||||
            this.$router.push({ path: this.redirect || '/' })
 | 
			
		||||
          }).catch(() => {
 | 
			
		||||
            this.loading = false
 | 
			
		||||
          })
 | 
			
		||||
@@ -213,6 +223,7 @@ $light_gray:#eee;
 | 
			
		||||
    left: 0;
 | 
			
		||||
    right: 0;
 | 
			
		||||
    width: 520px;
 | 
			
		||||
    max-width: 100%;
 | 
			
		||||
    padding: 35px 35px 15px 35px;
 | 
			
		||||
    margin: 120px auto;
 | 
			
		||||
  }
 | 
			
		||||
 
 | 
			
		||||
@@ -10,24 +10,26 @@
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import openWindow from '@/utils/openWindow'
 | 
			
		||||
// import openWindow from '@/utils/openWindow'
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  name: 'SocialSignin',
 | 
			
		||||
  methods: {
 | 
			
		||||
    wechatHandleClick(thirdpart) {
 | 
			
		||||
      this.$store.commit('SET_AUTH_TYPE', thirdpart)
 | 
			
		||||
      const appid = 'xxxxx'
 | 
			
		||||
      const redirect_uri = encodeURIComponent('xxx/redirect?redirect=' + window.location.origin + '/authredirect')
 | 
			
		||||
      const url = 'https://open.weixin.qq.com/connect/qrconnect?appid=' + appid + '&redirect_uri=' + redirect_uri + '&response_type=code&scope=snsapi_login#wechat_redirect'
 | 
			
		||||
      openWindow(url, thirdpart, 540, 540)
 | 
			
		||||
      alert('ok')
 | 
			
		||||
      // this.$store.commit('SET_AUTH_TYPE', thirdpart)
 | 
			
		||||
      // const appid = 'xxxxx'
 | 
			
		||||
      // const redirect_uri = encodeURIComponent('xxx/redirect?redirect=' + window.location.origin + '/auth-redirect')
 | 
			
		||||
      // const url = 'https://open.weixin.qq.com/connect/qrconnect?appid=' + appid + '&redirect_uri=' + redirect_uri + '&response_type=code&scope=snsapi_login#wechat_redirect'
 | 
			
		||||
      // openWindow(url, thirdpart, 540, 540)
 | 
			
		||||
    },
 | 
			
		||||
    tencentHandleClick(thirdpart) {
 | 
			
		||||
      this.$store.commit('SET_AUTH_TYPE', thirdpart)
 | 
			
		||||
      const client_id = 'xxxxx'
 | 
			
		||||
      const redirect_uri = encodeURIComponent('xxx/redirect?redirect=' + window.location.origin + '/authredirect')
 | 
			
		||||
      const url = 'https://graph.qq.com/oauth2.0/authorize?response_type=code&client_id=' + client_id + '&redirect_uri=' + redirect_uri
 | 
			
		||||
      openWindow(url, thirdpart, 540, 540)
 | 
			
		||||
      alert('ok')
 | 
			
		||||
      // this.$store.commit('SET_AUTH_TYPE', thirdpart)
 | 
			
		||||
      // const client_id = 'xxxxx'
 | 
			
		||||
      // const redirect_uri = encodeURIComponent('xxx/redirect?redirect=' + window.location.origin + '/auth-redirect')
 | 
			
		||||
      // const url = 'https://graph.qq.com/oauth2.0/authorize?response_type=code&client_id=' + client_id + '&redirect_uri=' + redirect_uri
 | 
			
		||||
      // openWindow(url, thirdpart, 540, 540)
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,10 +0,0 @@
 | 
			
		||||
const data = {
 | 
			
		||||
  state: {
 | 
			
		||||
    iconsMap: []
 | 
			
		||||
  },
 | 
			
		||||
  generate(iconsMap) {
 | 
			
		||||
    this.state.iconsMap = iconsMap
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default data
 | 
			
		||||
@@ -21,22 +21,16 @@
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import icons from './generateIconsView'
 | 
			
		||||
import icons from './requireIcons'
 | 
			
		||||
import clipboard from '@/utils/clipboard'
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  name: 'Icons',
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      iconsMap: []
 | 
			
		||||
      iconsMap: icons
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  mounted() {
 | 
			
		||||
    const iconsMap = icons.state.iconsMap.map((i) => {
 | 
			
		||||
      return i.default.id.split('-')[1]
 | 
			
		||||
    })
 | 
			
		||||
    this.iconsMap = iconsMap
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
    generateIconCode(symbol) {
 | 
			
		||||
      return `<svg-icon icon-class="${symbol}" />`
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										11
									
								
								src/views/svg-icons/requireIcons.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								src/views/svg-icons/requireIcons.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
			
		||||
 | 
			
		||||
const req = require.context('../../icons/svg', false, /\.svg$/)
 | 
			
		||||
const requireAll = requireContext => requireContext.keys()
 | 
			
		||||
 | 
			
		||||
const re = /\.\/(.*)\.svg/
 | 
			
		||||
 | 
			
		||||
const icons = requireAll(req).map(i => {
 | 
			
		||||
  return i.match(re)[1]
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
export default icons
 | 
			
		||||
@@ -87,6 +87,7 @@ export default {
 | 
			
		||||
}
 | 
			
		||||
.box-card {
 | 
			
		||||
  width: 400px;
 | 
			
		||||
  max-width: 100%;
 | 
			
		||||
  margin: 20px auto;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user