dedsudiyu месяцев назад: 2
Сommit
425baab603
100 измененных файлов с 32955 добавлено и 0 удалено
  1. 30 0
      .babelrc
  2. 15392 0
      .devtools/build/backend.js
  3. 1 0
      .devtools/build/background.js
  4. 1 0
      .devtools/build/detector.js
  5. 1 0
      .devtools/build/devtools-background.js
  6. 22 0
      .devtools/build/devtools.js
  7. 10 0
      .devtools/build/hook.js
  8. 1 0
      .devtools/build/proxy.js
  9. 2 0
      .devtools/devtools-background.html
  10. 22 0
      .devtools/devtools.html
  11. BIN
      .devtools/icons/128-beta.png
  12. BIN
      .devtools/icons/128-gray.png
  13. BIN
      .devtools/icons/128.nuxt.png
  14. BIN
      .devtools/icons/128.png
  15. BIN
      .devtools/icons/16-beta.png
  16. BIN
      .devtools/icons/16-gray.png
  17. BIN
      .devtools/icons/16.nuxt.png
  18. BIN
      .devtools/icons/16.png
  19. BIN
      .devtools/icons/48-beta.png
  20. BIN
      .devtools/icons/48-gray.png
  21. BIN
      .devtools/icons/48.nuxt.png
  22. BIN
      .devtools/icons/48.png
  23. 60 0
      .devtools/manifest.json
  24. 6 0
      .devtools/popups/disabled.html
  25. 6 0
      .devtools/popups/disabled.nuxt.html
  26. 5 0
      .devtools/popups/enabled.html
  27. 5 0
      .devtools/popups/enabled.nuxt.html
  28. 4 0
      .devtools/popups/not-found.html
  29. 40 0
      .devtools/src/backend.js
  30. 123 0
      .devtools/src/background.js
  31. 71 0
      .devtools/src/detector.js
  32. 125 0
      .devtools/src/devtools-background.js
  33. 75 0
      .devtools/src/devtools.js
  34. 18 0
      .devtools/src/hook.js
  35. 32 0
      .devtools/src/proxy.js
  36. 21 0
      .devtools/webpack.config.js
  37. 150 0
      .electron-vue/build.js
  38. 40 0
      .electron-vue/dev-client.js
  39. 191 0
      .electron-vue/dev-runner.js
  40. 72 0
      .electron-vue/webpack.main.config.js
  41. 191 0
      .electron-vue/webpack.renderer.config.js
  42. 152 0
      .electron-vue/webpack.web.config.js
  43. 12 0
      .gitignore
  44. 36 0
      .travis.yml
  45. 51 0
      README.md
  46. 29 0
      appveyor.yml
  47. BIN
      build/icons/256x256.png
  48. BIN
      build/icons/icon.icns
  49. BIN
      build/icons/icon.ico
  50. 0 0
      dist/electron/.gitkeep
  51. 0 0
      dist/web/.gitkeep
  52. 14772 0
      package-lock.json
  53. 115 0
      package.json
  54. 24 0
      src/index.ejs
  55. 18 0
      src/main/electronApi.js
  56. 31 0
      src/main/index.dev.js
  57. 99 0
      src/main/index.js
  58. 44 0
      src/main/update.js
  59. 88 0
      src/renderer/App.vue
  60. 169 0
      src/renderer/api/basicsModules/index.js
  61. 182 0
      src/renderer/api/commonality/noPermission.js
  62. 412 0
      src/renderer/api/commonality/permission.js
  63. 4 0
      src/renderer/api/config.js
  64. 0 0
      src/renderer/assets/.gitkeep
  65. BIN
      src/renderer/assets/ZDimages/basicsModules/1.png
  66. BIN
      src/renderer/assets/ZDimages/basicsModules/10.png
  67. BIN
      src/renderer/assets/ZDimages/basicsModules/2.png
  68. BIN
      src/renderer/assets/ZDimages/basicsModules/3.png
  69. BIN
      src/renderer/assets/ZDimages/basicsModules/4.png
  70. BIN
      src/renderer/assets/ZDimages/basicsModules/5.png
  71. BIN
      src/renderer/assets/ZDimages/basicsModules/6.png
  72. BIN
      src/renderer/assets/ZDimages/basicsModules/7.png
  73. BIN
      src/renderer/assets/ZDimages/basicsModules/8.png
  74. BIN
      src/renderer/assets/ZDimages/basicsModules/9.png
  75. BIN
      src/renderer/assets/ZDimages/basicsModules/code.png
  76. BIN
      src/renderer/assets/ZDimages/basicsModules/icon_dl_bbg.png
  77. BIN
      src/renderer/assets/ZDimages/basicsModules/icon_dl_mm.png
  78. BIN
      src/renderer/assets/ZDimages/basicsModules/icon_dl_yzm.png
  79. BIN
      src/renderer/assets/ZDimages/basicsModules/icon_dl_zh.png
  80. BIN
      src/renderer/assets/ZDimages/basicsModules/icon_grzx_bgl.png
  81. BIN
      src/renderer/assets/ZDimages/basicsModules/icon_grzx_sjh.png
  82. BIN
      src/renderer/assets/ZDimages/basicsModules/icon_grzx_xl.png
  83. BIN
      src/renderer/assets/ZDimages/basicsModules/icon_grzx_yx.png
  84. BIN
      src/renderer/assets/ZDimages/basicsModules/icon_grzx_zc.png
  85. BIN
      src/renderer/assets/ZDimages/basicsModules/icon_grzx_zw.png
  86. BIN
      src/renderer/assets/ZDimages/basicsModules/icon_grzx_zy.png
  87. BIN
      src/renderer/assets/ZDimages/basicsModules/icon_jzggl_xljt.png
  88. BIN
      src/renderer/assets/ZDimages/basicsModules/icon_jzgxx_dr.png
  89. BIN
      src/renderer/assets/ZDimages/basicsModules/icon_jzgxx_sc.png
  90. BIN
      src/renderer/assets/ZDimages/basicsModules/icon_scdzqm_sl.png
  91. BIN
      src/renderer/assets/ZDimages/basicsModules/icon_sy_aqda.png
  92. BIN
      src/renderer/assets/ZDimages/basicsModules/icon_sy_aqjc.png
  93. BIN
      src/renderer/assets/ZDimages/basicsModules/icon_sy_aqyuyks.png
  94. BIN
      src/renderer/assets/ZDimages/basicsModules/icon_sy_aqzr.png
  95. BIN
      src/renderer/assets/ZDimages/basicsModules/icon_sy_fjgk.png
  96. BIN
      src/renderer/assets/ZDimages/basicsModules/icon_sy_hxpgl.png
  97. BIN
      src/renderer/assets/ZDimages/basicsModules/icon_sy_qpjc.png
  98. BIN
      src/renderer/assets/ZDimages/basicsModules/icon_sy_xygl.png
  99. BIN
      src/renderer/assets/ZDimages/basicsModules/icon_sy_yjyj.png
  100. 0 0
      src/renderer/assets/ZDimages/basicsModules/icon_sy_zhgl.png

+ 30 - 0
.babelrc

@@ -0,0 +1,30 @@
+{
+  "comments": false,
+  "env": {
+    "main": {
+      "presets": [
+        ["env", {
+          "targets": { "node": 7 }
+        }],
+        "stage-0"
+      ]
+    },
+    "renderer": {
+      "presets": [
+        ["env", {
+          "modules": false
+        }],
+        "stage-0"
+      ]
+    },
+    "web": {
+      "presets": [
+        ["env", {
+          "modules": false
+        }],
+        "stage-0"
+      ]
+    }
+  },
+  "plugins": ["transform-runtime"]
+}

Разница между файлами не показана из-за своего большого размера
+ 15392 - 0
.devtools/build/backend.js


Разница между файлами не показана из-за своего большого размера
+ 1 - 0
.devtools/build/background.js


Разница между файлами не показана из-за своего большого размера
+ 1 - 0
.devtools/build/detector.js


Разница между файлами не показана из-за своего большого размера
+ 1 - 0
.devtools/build/devtools-background.js


Разница между файлами не показана из-за своего большого размера
+ 22 - 0
.devtools/build/devtools.js


Разница между файлами не показана из-за своего большого размера
+ 10 - 0
.devtools/build/hook.js


Разница между файлами не показана из-за своего большого размера
+ 1 - 0
.devtools/build/proxy.js


+ 2 - 0
.devtools/devtools-background.html

@@ -0,0 +1,2 @@
+<meta charset="utf-8">
+<script src="./build/devtools-background.js"></script>

+ 22 - 0
.devtools/devtools.html

@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="utf-8">
+    <title></title>
+    <style>
+      html, body {
+        height: 100%;
+      }
+      #container {
+        display: flex;
+        height: 100%;
+      }
+    </style>
+  </head>
+  <body>
+    <div id="container">
+      <div id="app"></div>
+    </div>
+    <script src="./build/devtools.js"></script>
+  </body>
+</html>

BIN
.devtools/icons/128-beta.png


BIN
.devtools/icons/128-gray.png


BIN
.devtools/icons/128.nuxt.png


BIN
.devtools/icons/128.png


BIN
.devtools/icons/16-beta.png


BIN
.devtools/icons/16-gray.png


BIN
.devtools/icons/16.nuxt.png


BIN
.devtools/icons/16.png


BIN
.devtools/icons/48-beta.png


BIN
.devtools/icons/48-gray.png


BIN
.devtools/icons/48.nuxt.png


BIN
.devtools/icons/48.png


+ 60 - 0
.devtools/manifest.json

@@ -0,0 +1,60 @@
+{
+  "name": "Vue.js devtools",
+  "version": "5.1.1",
+  "version_name": "5.1.1",
+  "description": "Chrome and Firefox DevTools extension for debugging Vue.js applications.",
+  "manifest_version": 2,
+  "icons": {
+    "16": "icons/16.png",
+    "48": "icons/48.png",
+    "128": "icons/128.png"
+  },
+  "browser_action": {
+    "default_icon": {
+      "16": "icons/16-gray.png",
+      "48": "icons/48-gray.png",
+      "128": "icons/128-gray.png"
+    },
+    "default_title": "Vue Devtools",
+    "default_popup": "popups/not-found.html"
+  },
+  "web_accessible_resources": [
+    "devtools.html",
+    "devtools-background.html",
+    "build/backend.js"
+  ],
+  "devtools_page": "devtools-background.html",
+  "background": {
+    "scripts": [
+      "build/background.js"
+    ],
+    "persistent": false
+  },
+  "permissions": [
+    "http://*/*",
+    "https://*/*",
+    "file:///*",
+    "contextMenus",
+    "storage"
+  ],
+  "content_scripts": [
+    {
+      "matches": [
+        "<all_urls>"
+      ],
+      "js": [
+        "build/hook.js"
+      ],
+      "run_at": "document_start"
+    },
+    {
+      "matches": [
+        "<all_urls>"
+      ],
+      "js": [
+        "build/detector.js"
+      ],
+      "run_at": "document_idle"
+    }
+  ]
+}

+ 6 - 0
.devtools/popups/disabled.html

@@ -0,0 +1,6 @@
+<meta charset="utf-8">
+<p style="width: 200px">
+  Vue.js is detected on this page.
+  Devtools inspection is not available because it's in
+  production mode or explicitly disabled by the author.
+</p>

+ 6 - 0
.devtools/popups/disabled.nuxt.html

@@ -0,0 +1,6 @@
+<meta charset="utf-8">
+<p style="width: 200px">
+  Nuxt.js + Vue.js is detected on this page.
+  Devtools inspection is not available because it's in
+  production mode or explicitly disabled by the author.
+</p>

+ 5 - 0
.devtools/popups/enabled.html

@@ -0,0 +1,5 @@
+<meta charset="utf-8">
+<p style="width: 180px;">
+  Vue.js is detected on this page.
+  Open DevTools and look for the Vue panel.
+</p>

+ 5 - 0
.devtools/popups/enabled.nuxt.html

@@ -0,0 +1,5 @@
+<meta charset="utf-8">
+<p style="width: 180px;">
+  Nuxt.js + Vue.js is detected on this page.
+  Open DevTools and look for the Vue panel.
+</p>

+ 4 - 0
.devtools/popups/not-found.html

@@ -0,0 +1,4 @@
+<meta charset="utf-8">
+<p style="white-space: nowrap">
+  Vue.js not detected
+</p>

+ 40 - 0
.devtools/src/backend.js

@@ -0,0 +1,40 @@
+// this is injected to the app page when the panel is activated.
+
+import { initBackend } from 'src/backend'
+import Bridge from 'src/bridge'
+
+window.addEventListener('message', handshake)
+
+function handshake (e) {
+  if (e.data.source === 'vue-devtools-proxy' && e.data.payload === 'init') {
+    window.removeEventListener('message', handshake)
+
+    let listeners = []
+    const bridge = new Bridge({
+      listen (fn) {
+        var listener = evt => {
+          if (evt.data.source === 'vue-devtools-proxy' && evt.data.payload) {
+            fn(evt.data.payload)
+          }
+        }
+        window.addEventListener('message', listener)
+        listeners.push(listener)
+      },
+      send (data) {
+        window.postMessage({
+          source: 'vue-devtools-backend',
+          payload: data
+        }, '*')
+      }
+    })
+
+    bridge.on('shutdown', () => {
+      listeners.forEach(l => {
+        window.removeEventListener('message', l)
+      })
+      listeners = []
+    })
+
+    initBackend(bridge)
+  }
+}

+ 123 - 0
.devtools/src/background.js

@@ -0,0 +1,123 @@
+// the background script runs all the time and serves as a central message
+// hub for each vue devtools (panel + proxy + backend) instance.
+
+const ports = {}
+
+chrome.runtime.onConnect.addListener(port => {
+  let tab
+  let name
+  if (isNumeric(port.name)) {
+    tab = port.name
+    name = 'devtools'
+    installProxy(+port.name)
+  } else {
+    tab = port.sender.tab.id
+    name = 'backend'
+  }
+
+  if (!ports[tab]) {
+    ports[tab] = {
+      devtools: null,
+      backend: null
+    }
+  }
+  ports[tab][name] = port
+
+  if (ports[tab].devtools && ports[tab].backend) {
+    doublePipe(tab, ports[tab].devtools, ports[tab].backend)
+  }
+})
+
+function isNumeric (str) {
+  return +str + '' === str
+}
+
+function installProxy (tabId) {
+  chrome.tabs.executeScript(tabId, {
+    file: '/build/proxy.js'
+  }, function (res) {
+    if (!res) {
+      ports[tabId].devtools.postMessage('proxy-fail')
+    } else {
+      console.log('injected proxy to tab ' + tabId)
+    }
+  })
+}
+
+function doublePipe (id, one, two) {
+  one.onMessage.addListener(lOne)
+  function lOne (message) {
+    if (message.event === 'log') {
+      return console.log('tab ' + id, message.payload)
+    }
+    console.log('devtools -> backend', message)
+    two.postMessage(message)
+  }
+  two.onMessage.addListener(lTwo)
+  function lTwo (message) {
+    if (message.event === 'log') {
+      return console.log('tab ' + id, message.payload)
+    }
+    console.log('backend -> devtools', message)
+    one.postMessage(message)
+  }
+  function shutdown () {
+    console.log('tab ' + id + ' disconnected.')
+    one.onMessage.removeListener(lOne)
+    two.onMessage.removeListener(lTwo)
+    one.disconnect()
+    two.disconnect()
+    ports[id] = null
+    updateContextMenuItem()
+  }
+  one.onDisconnect.addListener(shutdown)
+  two.onDisconnect.addListener(shutdown)
+  console.log('tab ' + id + ' connected.')
+  updateContextMenuItem()
+}
+
+chrome.runtime.onMessage.addListener((req, sender) => {
+  if (sender.tab && req.vueDetected) {
+    const suffix = req.nuxtDetected ? '.nuxt' : ''
+
+    chrome.browserAction.setIcon({
+      tabId: sender.tab.id,
+      path: {
+        16: `icons/16${suffix}.png`,
+        48: `icons/48${suffix}.png`,
+        128: `icons/128${suffix}.png`
+      }
+    })
+    chrome.browserAction.setPopup({
+      tabId: sender.tab.id,
+      popup: req.devtoolsEnabled ? `popups/enabled${suffix}.html` : `popups/disabled${suffix}.html`
+    })
+  }
+})
+
+// Right-click inspect context menu entry
+let activeTabId
+chrome.tabs.onActivated.addListener(({ tabId }) => {
+  activeTabId = tabId
+  updateContextMenuItem()
+})
+
+function updateContextMenuItem () {
+  chrome.contextMenus.removeAll(() => {
+    if (ports[activeTabId]) {
+      chrome.contextMenus.create({
+        id: 'vue-inspect-instance',
+        title: 'Inspect Vue component',
+        contexts: ['all']
+      })
+    }
+  })
+}
+
+chrome.contextMenus.onClicked.addListener((info, tab) => {
+  chrome.runtime.sendMessage({
+    vueContextMenu: {
+      id: info.menuItemId
+    }
+  })
+})

+ 71 - 0
.devtools/src/detector.js

@@ -0,0 +1,71 @@
+import { installToast } from 'src/backend/toast'
+import { isFirefox } from 'src/devtools/env'
+
+window.addEventListener('message', e => {
+  if (e.source === window && e.data.vueDetected) {
+    chrome.runtime.sendMessage(e.data)
+  }
+})
+
+function detect (win) {
+  setTimeout(() => {
+    // Method 1: Check Nuxt.js
+    const nuxtDetected = Boolean(window.__NUXT__ || window.$nuxt)
+
+    if (nuxtDetected) {
+      let Vue
+
+      if (window.$nuxt) {
+        Vue = window.$nuxt.$root.constructor
+      }
+
+      win.postMessage({
+        devtoolsEnabled: Vue && Vue.config.devtools,
+        vueDetected: true,
+        nuxtDetected: true
+      }, '*')
+
+      return
+    }
+
+    // Method 2: Scan all elements inside document
+    const all = document.querySelectorAll('*')
+    let el
+    for (let i = 0; i < all.length; i++) {
+      if (all[i].__vue__) {
+        el = all[i]
+        break
+      }
+    }
+    if (el) {
+      let Vue = Object.getPrototypeOf(el.__vue__).constructor
+      while (Vue.super) {
+        Vue = Vue.super
+      }
+      win.postMessage({
+        devtoolsEnabled: Vue.config.devtools,
+        vueDetected: true
+      }, '*')
+    }
+  }, 100)
+}
+
+// inject the hook
+if (document instanceof HTMLDocument) {
+  installScript(detect)
+  installScript(installToast)
+}
+
+function installScript (fn) {
+  const source = ';(' + fn.toString() + ')(window)'
+
+  if (isFirefox) {
+    // eslint-disable-next-line no-eval
+    window.eval(source) // in Firefox, this evaluates on the content window
+  } else {
+    const script = document.createElement('script')
+    script.textContent = source
+    document.documentElement.appendChild(script)
+    script.parentNode.removeChild(script)
+  }
+}

+ 125 - 0
.devtools/src/devtools-background.js

@@ -0,0 +1,125 @@
+// This is the devtools script, which is called when the user opens the
+// Chrome devtool on a page. We check to see if we global hook has detected
+// Vue presence on the page. If yes, create the Vue panel; otherwise poll
+// for 10 seconds.
+
+let panelLoaded = false
+let panelShown = false
+let pendingAction
+let created = false
+let checkCount = 0
+
+chrome.devtools.network.onNavigated.addListener(createPanelIfHasVue)
+const checkVueInterval = setInterval(createPanelIfHasVue, 1000)
+createPanelIfHasVue()
+
+function createPanelIfHasVue () {
+  if (created || checkCount++ > 10) {
+    return
+  }
+  panelLoaded = false
+  panelShown = false
+  chrome.devtools.inspectedWindow.eval(
+    '!!(window.__VUE_DEVTOOLS_GLOBAL_HOOK__.Vue)',
+    function (hasVue) {
+      if (!hasVue || created) {
+        return
+      }
+      clearInterval(checkVueInterval)
+      created = true
+      chrome.devtools.panels.create(
+        'Vue', 'icons/128.png', 'devtools.html',
+        panel => {
+          // panel loaded
+          panel.onShown.addListener(onPanelShown)
+          panel.onHidden.addListener(onPanelHidden)
+        }
+      )
+    }
+  )
+}
+
+// Runtime messages
+
+chrome.runtime.onMessage.addListener(request => {
+  if (request === 'vue-panel-load') {
+    onPanelLoad()
+  } else if (request.vueToast) {
+    toast(request.vueToast.message, request.vueToast.type)
+  } else if (request.vueContextMenu) {
+    onContextMenu(request.vueContextMenu)
+  }
+})
+
+// Page context menu entry
+
+function onContextMenu ({ id }) {
+  if (id === 'vue-inspect-instance') {
+    const src = `window.__VUE_DEVTOOLS_CONTEXT_MENU_HAS_TARGET__`
+
+    chrome.devtools.inspectedWindow.eval(src, function (res, err) {
+      if (err) {
+        console.log(err)
+      }
+      if (typeof res !== 'undefined' && res) {
+        panelAction(() => {
+          chrome.runtime.sendMessage('vue-get-context-menu-target')
+        }, 'Open Vue devtools to see component details')
+      } else {
+        pendingAction = null
+        toast('No Vue component was found', 'warn')
+      }
+    })
+  }
+}
+
+// Action that may execute immediatly
+// or later when the Vue panel is ready
+
+function panelAction (cb, message = null) {
+  if (created && panelLoaded && panelShown) {
+    cb()
+  } else {
+    pendingAction = cb
+    message && toast(message)
+  }
+}
+
+function executePendingAction () {
+  pendingAction && pendingAction()
+  pendingAction = null
+}
+
+// Execute pending action when Vue panel is ready
+
+function onPanelLoad () {
+  executePendingAction()
+  panelLoaded = true
+}
+
+// Manage panel visibility
+
+function onPanelShown () {
+  chrome.runtime.sendMessage('vue-panel-shown')
+  panelShown = true
+  panelLoaded && executePendingAction()
+}
+
+function onPanelHidden () {
+  chrome.runtime.sendMessage('vue-panel-hidden')
+  panelShown = false
+}
+
+// Toasts
+
+function toast (message, type = 'normal') {
+  const src = `(function() {
+    __VUE_DEVTOOLS_TOAST__(\`${message}\`, '${type}');
+  })()`
+
+  chrome.devtools.inspectedWindow.eval(src, function (res, err) {
+    if (err) {
+      console.log(err)
+    }
+  })
+}

+ 75 - 0
.devtools/src/devtools.js

@@ -0,0 +1,75 @@
+// this script is called when the VueDevtools panel is activated.
+
+import { initDevTools } from 'src/devtools'
+import Bridge from 'src/bridge'
+
+initDevTools({
+
+  /**
+   * Inject backend, connect to background, and send back the bridge.
+   *
+   * @param {Function} cb
+   */
+
+  connect (cb) {
+    // 1. inject backend code into page
+    injectScript(chrome.runtime.getURL('build/backend.js'), () => {
+      // 2. connect to background to setup proxy
+      const port = chrome.runtime.connect({
+        name: '' + chrome.devtools.inspectedWindow.tabId
+      })
+      let disconnected = false
+      port.onDisconnect.addListener(() => {
+        disconnected = true
+      })
+
+      const bridge = new Bridge({
+        listen (fn) {
+          port.onMessage.addListener(fn)
+        },
+        send (data) {
+          if (!disconnected) {
+            port.postMessage(data)
+          }
+        }
+      })
+      // 3. send a proxy API to the panel
+      cb(bridge)
+    })
+  },
+
+  /**
+   * Register a function to reload the devtools app.
+   *
+   * @param {Function} reloadFn
+   */
+
+  onReload (reloadFn) {
+    chrome.devtools.network.onNavigated.addListener(reloadFn)
+  }
+})
+
+/**
+ * Inject a globally evaluated script, in the same context with the actual
+ * user app.
+ *
+ * @param {String} scriptName
+ * @param {Function} cb
+ */
+
+function injectScript (scriptName, cb) {
+  const src = `
+    (function() {
+      var script = document.constructor.prototype.createElement.call(document, 'script');
+      script.src = "${scriptName}";
+      document.documentElement.appendChild(script);
+      script.parentNode.removeChild(script);
+    })()
+  `
+  chrome.devtools.inspectedWindow.eval(src, function (res, err) {
+    if (err) {
+      console.log(err)
+    }
+    cb()
+  })
+}

+ 18 - 0
.devtools/src/hook.js

@@ -0,0 +1,18 @@
+// This script is injected into every page.
+import { installHook } from 'src/backend/hook'
+import { isFirefox } from 'src/devtools/env'
+
+// inject the hook
+if (document instanceof HTMLDocument) {
+  const source = ';(' + installHook.toString() + ')(window)'
+
+  if (isFirefox) {
+    // eslint-disable-next-line no-eval
+    window.eval(source) // in Firefox, this evaluates on the content window
+  } else {
+    const script = document.createElement('script')
+    script.textContent = source
+    document.documentElement.appendChild(script)
+    script.parentNode.removeChild(script)
+  }
+}

+ 32 - 0
.devtools/src/proxy.js

@@ -0,0 +1,32 @@
+// This is a content-script that is injected only when the devtools are
+// activated. Because it is not injected using eval, it has full privilege
+// to the chrome runtime API. It serves as a proxy between the injected
+// backend and the Vue devtools panel.
+
+const port = chrome.runtime.connect({
+  name: 'content-script'
+})
+
+port.onMessage.addListener(sendMessageToBackend)
+window.addEventListener('message', sendMessageToDevtools)
+port.onDisconnect.addListener(handleDisconnect)
+
+sendMessageToBackend('init')
+
+function sendMessageToBackend (payload) {
+  window.postMessage({
+    source: 'vue-devtools-proxy',
+    payload: payload
+  }, '*')
+}
+
+function sendMessageToDevtools (e) {
+  if (e.data && e.data.source === 'vue-devtools-backend') {
+    port.postMessage(e.data.payload)
+  }
+}
+
+function handleDisconnect () {
+  window.removeEventListener('message', sendMessageToDevtools)
+  sendMessageToBackend('shutdown')
+}

+ 21 - 0
.devtools/webpack.config.js

@@ -0,0 +1,21 @@
+const path = require('path')
+const createConfig = require('../createConfig')
+
+module.exports = createConfig({
+  entry: {
+    hook: './src/hook.js',
+    devtools: './src/devtools.js',
+    background: './src/background.js',
+    'devtools-background': './src/devtools-background.js',
+    backend: './src/backend.js',
+    proxy: './src/proxy.js',
+    detector: './src/detector.js'
+  },
+  output: {
+    path: path.join(__dirname, 'build'),
+    filename: '[name].js'
+  },
+  devtool: process.env.NODE_ENV !== 'production'
+    ? '#inline-source-map'
+    : false
+})

+ 150 - 0
.electron-vue/build.js

@@ -0,0 +1,150 @@
+'use strict'
+
+process.env.NODE_ENV = 'production'
+
+const { say } = require('cfonts')
+const chalk = require('chalk')
+const del = require('del')
+const { spawn } = require('child_process')
+const webpack = require('webpack')
+const Listr = require('listr')
+
+
+const mainConfig = require('./webpack.main.config')
+const rendererConfig = require('./webpack.renderer.config')
+const webConfig = require('./webpack.web.config')
+
+const doneLog = chalk.bgGreen.white(' DONE ') + ' '
+const errorLog = chalk.bgRed.white(' ERROR ') + ' '
+const okayLog = chalk.bgBlue.white(' OKAY ') + ' '
+const isCI = process.env.CI || false
+const Multispinner = require('multispinner')
+
+if (process.env.BUILD_TARGET === 'clean') clean()
+else if (process.env.BUILD_TARGET === 'web') web()
+else build()
+
+function clean () {
+  del.sync(['build/*', '!build/icons', '!build/icons/icon.*'])
+  console.log(`\n${doneLog}\n`)
+  process.exit()
+}
+
+async function build () {
+  greeting()
+
+  del.sync(['dist/electron/*', '!.gitkeep'])
+
+  const tasks1 = ['main', 'renderer']
+  const m = new Multispinner(tasks1, {
+    preText: 'building',
+    postText: 'process'
+  })
+
+  let results = ''
+
+  const tasks = new Listr(
+    [
+      {
+        title: 'building master process',
+        task: async () => {
+          await pack(mainConfig)
+            .then(result => {
+              results += result + '\n\n'
+            })
+            .catch(err => {
+              console.log(`\n  ${errorLog}failed to build main process`)
+              console.error(`\n${err}\n`)
+            })
+        }
+      },
+      {
+        title: 'building renderer process',
+        task: async () => {
+          await pack(rendererConfig)
+            .then(result => {
+              results += result + '\n\n'
+            })
+            .catch(err => {
+              console.log(`\n  ${errorLog}failed to build renderer process`)
+              console.error(`\n${err}\n`)
+            })
+        }
+      }
+    ],
+    { concurrent: 2 }
+  )
+
+  await tasks
+    .run()
+    .then(() => {
+      process.stdout.write('\x1B[2J\x1B[0f')
+      console.log(`\n\n${results}`)
+      console.log(`${okayLog}take it away ${chalk.yellow('`electron-builder`')}\n`)
+      process.exit()
+    })
+    .catch(err => {
+      process.exit(1)
+    })
+}
+
+function pack (config) {
+  return new Promise((resolve, reject) => {
+    config.mode = 'production'
+    webpack(config, (err, stats) => {
+      if (err) reject(err.stack || err)
+      else if (stats.hasErrors()) {
+        let err = ''
+
+        stats.toString({
+          chunks: false,
+          colors: true
+        })
+        .split(/\r?\n/)
+        .forEach(line => {
+          err += `    ${line}\n`
+        })
+
+        reject(err)
+      } else {
+        resolve(stats.toString({
+          chunks: false,
+          colors: true
+        }))
+      }
+    })
+  })
+}
+
+function web () {
+  del.sync(['dist/web/*', '!.gitkeep'])
+  webConfig.mode = 'production'
+  webpack(webConfig, (err, stats) => {
+    if (err || stats.hasErrors()) console.log(err)
+
+    console.log(stats.toString({
+      chunks: false,
+      colors: true
+    }))
+
+    process.exit()
+  })
+}
+
+function greeting () {
+  const cols = process.stdout.columns
+  let text = ''
+
+  if (cols > 85) text = 'lets-build'
+  else if (cols > 60) text = 'lets-|build'
+  else text = false
+
+  if (text && !isCI) {
+    say(text, {
+      colors: ['yellow'],
+      font: 'simple3d',
+      space: false
+    })
+  } else console.log(chalk.yellow.bold('\n  lets-build'))
+  console.log()
+}

+ 40 - 0
.electron-vue/dev-client.js

@@ -0,0 +1,40 @@
+const hotClient = require('webpack-hot-middleware/client?noInfo=true&reload=true')
+
+hotClient.subscribe(event => {
+  /**
+   * Reload browser when HTMLWebpackPlugin emits a new index.html
+   *
+   * Currently disabled until jantimon/html-webpack-plugin#680 is resolved.
+   * https://github.com/SimulatedGREG/electron-vue/issues/437
+   * https://github.com/jantimon/html-webpack-plugin/issues/680
+   */
+  // if (event.action === 'reload') {
+  //   window.location.reload()
+  // }
+
+  /**
+   * Notify `mainWindow` when `main` process is compiling,
+   * giving notice for an expected reload of the `electron` process
+   */
+  if (event.action === 'compiling') {
+    document.body.innerHTML += `
+      <style>
+        #dev-client {
+          background: #4fc08d;
+          border-radius: 4px;
+          bottom: 20px;
+          box-shadow: 0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12), 0 2px 4px -1px rgba(0, 0, 0, 0.3);
+          color: #fff;
+          font-family: 'Source Sans Pro', sans-serif;
+          left: 20px;
+          padding: 8px 12px;
+          position: absolute;
+        }
+      </style>
+
+      <div id="dev-client">
+        Compiling Main Process...
+      </div>
+    `
+  }
+})

+ 191 - 0
.electron-vue/dev-runner.js

@@ -0,0 +1,191 @@
+'use strict'
+
+const chalk = require('chalk')
+const electron = require('electron')
+const path = require('path')
+const { say } = require('cfonts')
+const { spawn } = require('child_process')
+const webpack = require('webpack')
+const WebpackDevServer = require('webpack-dev-server')
+const webpackHotMiddleware = require('webpack-hot-middleware')
+
+const mainConfig = require('./webpack.main.config')
+const rendererConfig = require('./webpack.renderer.config')
+
+let electronProcess = null
+let manualRestart = false
+let hotMiddleware
+
+function logStats (proc, data) {
+  let log = ''
+
+  log += chalk.yellow.bold(`┏ ${proc} Process ${new Array((19 - proc.length) + 1).join('-')}`)
+  log += '\n\n'
+
+  if (typeof data === 'object') {
+    data.toString({
+      colors: true,
+      chunks: false
+    }).split(/\r?\n/).forEach(line => {
+      log += '  ' + line + '\n'
+    })
+  } else {
+    log += `  ${data}\n`
+  }
+
+  log += '\n' + chalk.yellow.bold(`┗ ${new Array(28 + 1).join('-')}`) + '\n'
+
+  console.log(log)
+}
+
+function startRenderer () {
+  return new Promise((resolve, reject) => {
+    rendererConfig.entry.renderer = [path.join(__dirname, 'dev-client')].concat(rendererConfig.entry.renderer)
+    rendererConfig.mode = 'development'
+    const compiler = webpack(rendererConfig)
+    hotMiddleware = webpackHotMiddleware(compiler, {
+      log: false,
+      heartbeat: 2500
+    })
+
+    compiler.hooks.compilation.tap('compilation', compilation => {
+      compilation.hooks.htmlWebpackPluginAfterEmit.tapAsync('html-webpack-plugin-after-emit', (data, cb) => {
+        hotMiddleware.publish({ action: 'reload' })
+        cb()
+      })
+    })
+
+    compiler.hooks.done.tap('done', stats => {
+      logStats('Renderer', stats)
+    })
+
+    const server = new WebpackDevServer(
+      compiler,
+      {
+        contentBase: path.join(__dirname, '../'),
+        quiet: true,
+        hot: true,
+        before (app, ctx) {
+          app.use(hotMiddleware)
+          ctx.middleware.waitUntilValid(() => {
+            resolve()
+          })
+        }
+      }
+    )
+
+    server.listen(9080)
+  })
+}
+
+function startMain () {
+  return new Promise((resolve, reject) => {
+    mainConfig.entry.main = [path.join(__dirname, '../src/main/index.dev.js')].concat(mainConfig.entry.main)
+    mainConfig.mode = 'development'
+    const compiler = webpack(mainConfig)
+
+    compiler.hooks.watchRun.tapAsync('watch-run', (compilation, done) => {
+      logStats('Main', chalk.white.bold('compiling...'))
+      hotMiddleware.publish({ action: 'compiling' })
+      done()
+    })
+
+    compiler.watch({}, (err, stats) => {
+      if (err) {
+        console.log(err)
+        return
+      }
+
+      logStats('Main', stats)
+
+      if (electronProcess && electronProcess.kill) {
+        manualRestart = true
+        process.kill(electronProcess.pid)
+        electronProcess = null
+        startElectron()
+
+        setTimeout(() => {
+          manualRestart = false
+        }, 5000)
+      }
+
+      resolve()
+    })
+  })
+}
+
+function startElectron () {
+  var args = [
+    '--inspect=5858',
+    path.join(__dirname, '../dist/electron/main.js')
+  ]
+
+  // detect yarn or npm and process commandline args accordingly
+  if (process.env.npm_execpath.endsWith('yarn.js')) {
+    args = args.concat(process.argv.slice(3))
+  } else if (process.env.npm_execpath.endsWith('npm-cli.js')) {
+    args = args.concat(process.argv.slice(2))
+  }
+
+  electronProcess = spawn(electron, args)
+
+  electronProcess.stdout.on('data', data => {
+    electronLog(data, 'blue')
+  })
+  electronProcess.stderr.on('data', data => {
+    electronLog(data, 'red')
+  })
+
+  electronProcess.on('close', () => {
+    if (!manualRestart) process.exit()
+  })
+}
+
+function electronLog (data, color) {
+  let log = ''
+  data = data.toString().split(/\r?\n/)
+  data.forEach(line => {
+    log += `  ${line}\n`
+  })
+  if (/[0-9A-z]+/.test(log)) {
+    console.log(
+      chalk[color].bold('┏ Electron -------------------') +
+      '\n\n' +
+      log +
+      chalk[color].bold('┗ ----------------------------') +
+      '\n'
+    )
+  }
+}
+
+function greeting () {
+  const cols = process.stdout.columns
+  let text = ''
+
+  if (cols > 104) text = 'electron-vue'
+  else if (cols > 76) text = 'electron-|vue'
+  else text = false
+
+  if (text) {
+    say(text, {
+      colors: ['yellow'],
+      font: 'simple3d',
+      space: false
+    })
+  } else console.log(chalk.yellow.bold('\n  electron-vue'))
+  console.log(chalk.blue('  getting ready...') + '\n')
+}
+
+function init () {
+  greeting()
+
+  Promise.all([startRenderer(), startMain()])
+    .then(() => {
+      startElectron()
+    })
+    .catch(err => {
+      console.error(err)
+    })
+}
+
+init()

+ 72 - 0
.electron-vue/webpack.main.config.js

@@ -0,0 +1,72 @@
+'use strict'
+
+process.env.BABEL_ENV = 'main'
+
+const path = require('path')
+const { dependencies } = require('../package.json')
+const webpack = require('webpack')
+
+const MinifyPlugin = require("babel-minify-webpack-plugin")
+
+let mainConfig = {
+  entry: {
+    main: path.join(__dirname, '../src/main/index.js')
+  },
+  externals: [
+    ...Object.keys(dependencies || {})
+  ],
+  module: {
+    rules: [
+      {
+        test: /\.js$/,
+        use: 'babel-loader',
+        exclude: /node_modules/
+      },
+      {
+        test: /\.node$/,
+        use: 'node-loader'
+      }
+    ]
+  },
+  node: {
+    __dirname: process.env.NODE_ENV !== 'production',
+    __filename: process.env.NODE_ENV !== 'production'
+  },
+  output: {
+    filename: '[name].js',
+    libraryTarget: 'commonjs2',
+    path: path.join(__dirname, '../dist/electron')
+  },
+  plugins: [
+    new webpack.NoEmitOnErrorsPlugin()
+  ],
+  resolve: {
+    extensions: ['.js', '.json', '.node']
+  },
+  target: 'electron-main'
+}
+
+/**
+ * Adjust mainConfig for development settings
+ */
+if (process.env.NODE_ENV !== 'production') {
+  mainConfig.plugins.push(
+    new webpack.DefinePlugin({
+      '__static': `"${path.join(__dirname, '../static').replace(/\\/g, '\\\\')}"`
+    })
+  )
+}
+
+/**
+ * Adjust mainConfig for production settings
+ */
+if (process.env.NODE_ENV === 'production') {
+  mainConfig.plugins.push(
+    new MinifyPlugin(),
+    new webpack.DefinePlugin({
+      'process.env.NODE_ENV': '"production"'
+    })
+  )
+}
+
+module.exports = mainConfig

+ 191 - 0
.electron-vue/webpack.renderer.config.js

@@ -0,0 +1,191 @@
+'use strict'
+
+process.env.BABEL_ENV = 'renderer'
+
+const path = require('path')
+const { dependencies } = require('../package.json')
+const webpack = require('webpack')
+
+const MinifyPlugin = require("babel-minify-webpack-plugin")
+const CopyWebpackPlugin = require('copy-webpack-plugin')
+const MiniCssExtractPlugin = require('mini-css-extract-plugin')
+const HtmlWebpackPlugin = require('html-webpack-plugin')
+const { VueLoaderPlugin } = require('vue-loader')
+
+/**
+ * List of node_modules to include in webpack bundle
+ *
+ * Required for specific packages like Vue UI libraries
+ * that provide pure *.vue files that need compiling
+ * https://simulatedgreg.gitbooks.io/electron-vue/content/en/webpack-configurations.html#white-listing-externals
+ */
+let whiteListedModules = ['vue']
+
+let rendererConfig = {
+  devtool: '#cheap-module-eval-source-map',
+  entry: {
+    renderer: path.join(__dirname, '../src/renderer/main.js')
+  },
+  externals: [
+    ...Object.keys(dependencies || {}).filter(d => !whiteListedModules.includes(d))
+  ],
+  module: {
+    rules: [
+      {
+        test: /\.scss$/,
+        use: ['vue-style-loader', 'css-loader', 'sass-loader']
+      },
+      {
+        test: /\.sass$/,
+        use: ['vue-style-loader', 'css-loader', 'sass-loader?indentedSyntax']
+      },
+      {
+        test: /\.less$/,
+        use: ['vue-style-loader', 'css-loader', 'less-loader']
+      },
+      {
+        test: /\.css$/,
+        use: ['vue-style-loader', 'css-loader']
+      },
+      {
+        test: /\.html$/,
+        use: 'vue-html-loader'
+      },
+      {
+        test: /\.js$/,
+        use: 'babel-loader',
+        exclude: /node_modules/
+      },
+      {
+        test: /\.node$/,
+        use: 'node-loader'
+      },
+      {
+        test: /\.vue$/,
+        use: {
+          loader: 'vue-loader',
+          options: {
+            extractCSS: process.env.NODE_ENV === 'production',
+            loaders: {
+              sass: 'vue-style-loader!css-loader!sass-loader?indentedSyntax=1',
+              scss: 'vue-style-loader!css-loader!sass-loader',
+              less: 'vue-style-loader!css-loader!less-loader'
+            }
+          }
+        }
+      },
+      {
+        test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
+        use: {
+          loader: 'url-loader',
+          query: {
+            limit: 10000,
+            name: 'imgs/[name]--[folder].[ext]'
+          }
+        }
+      },
+      {
+        test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
+        loader: 'url-loader',
+        options: {
+          limit: 10000,
+          name: 'media/[name]--[folder].[ext]'
+        }
+      },
+      {
+        test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
+        use: {
+          loader: 'url-loader',
+          query: {
+            limit: 10000,
+            name: 'fonts/[name]--[folder].[ext]'
+          }
+        }
+      }
+    ]
+  },
+  node: {
+    __dirname: process.env.NODE_ENV !== 'production',
+    __filename: process.env.NODE_ENV !== 'production'
+  },
+  plugins: [
+    new VueLoaderPlugin(),
+    new MiniCssExtractPlugin({filename: 'styles.css'}),
+    new HtmlWebpackPlugin({
+      filename: 'index.html',
+      template: path.resolve(__dirname, '../src/index.ejs'),
+      templateParameters(compilation, assets, options) {
+        return {
+          compilation: compilation,
+          webpack: compilation.getStats().toJson(),
+          webpackConfig: compilation.options,
+          htmlWebpackPlugin: {
+            files: assets,
+            options: options,
+          },
+          process,
+        };
+      },
+      minify: {
+        collapseWhitespace: true,
+        removeAttributeQuotes: true,
+        removeComments: true
+      },
+      nodeModules: process.env.NODE_ENV !== 'production'
+        ? path.resolve(__dirname, '../node_modules')
+        : false
+    }),
+    new webpack.NoEmitOnErrorsPlugin()
+  ],
+  output: {
+    filename: '[name].js',
+    libraryTarget: 'commonjs2',
+    path: path.join(__dirname, '../dist/electron')
+  },
+  resolve: {
+    alias: {
+      '@': path.join(__dirname, '../src/renderer'),
+      'vue$': 'vue/dist/vue.esm.js'
+    },
+    extensions: ['.js', '.vue', '.json', '.css', '.node']
+  },
+  target: 'electron-renderer'
+}
+
+/**
+ * Adjust rendererConfig for development settings
+ */
+if (process.env.NODE_ENV !== 'production') {
+  rendererConfig.plugins.push(
+    new webpack.HotModuleReplacementPlugin(),
+    new webpack.DefinePlugin({
+      '__static': `"${path.join(__dirname, '../static').replace(/\\/g, '\\\\')}"`
+    })
+  )
+}
+
+/**
+ * Adjust rendererConfig for production settings
+ */
+if (process.env.NODE_ENV === 'production') {
+  rendererConfig.devtool = ''
+
+  rendererConfig.plugins.push(
+    new MinifyPlugin(),
+    new CopyWebpackPlugin([
+      {
+        from: path.join(__dirname, '../static'),
+        to: path.join(__dirname, '../dist/electron/static'),
+        ignore: ['.*']
+      }
+    ]),
+    new webpack.DefinePlugin({
+      'process.env.NODE_ENV': '"production"'
+    }),
+    new webpack.LoaderOptionsPlugin({
+      minimize: true
+    })
+  )
+}
+
+module.exports = rendererConfig

+ 152 - 0
.electron-vue/webpack.web.config.js

@@ -0,0 +1,152 @@
+'use strict'
+
+process.env.BABEL_ENV = 'web'
+
+const path = require('path')
+const webpack = require('webpack')
+
+const MinifyPlugin = require("babel-minify-webpack-plugin")
+const CopyWebpackPlugin = require('copy-webpack-plugin')
+const MiniCssExtractPlugin = require('mini-css-extract-plugin')
+const HtmlWebpackPlugin = require('html-webpack-plugin')
+const { VueLoaderPlugin } = require('vue-loader')
+
+let webConfig = {
+  devtool: '#cheap-module-eval-source-map',
+  entry: {
+    web: path.join(__dirname, '../src/renderer/main.js')
+  },
+  module: {
+    rules: [
+      {
+        test: /\.scss$/,
+        use: ['vue-style-loader', 'css-loader', 'sass-loader']
+      },
+      {
+        test: /\.sass$/,
+        use: ['vue-style-loader', 'css-loader', 'sass-loader?indentedSyntax']
+      },
+      {
+        test: /\.less$/,
+        use: ['vue-style-loader', 'css-loader', 'less-loader']
+      },
+      {
+        test: /\.css$/,
+        use: ['vue-style-loader', 'css-loader']
+      },
+      {
+        test: /\.html$/,
+        use: 'vue-html-loader'
+      },
+      {
+        test: /\.js$/,
+        use: 'babel-loader',
+        include: [ path.resolve(__dirname, '../src/renderer') ],
+        exclude: /node_modules/
+      },
+      {
+        test: /\.vue$/,
+        use: {
+          loader: 'vue-loader',
+          options: {
+            extractCSS: true,
+            loaders: {
+              sass: 'vue-style-loader!css-loader!sass-loader?indentedSyntax=1',
+              scss: 'vue-style-loader!css-loader!sass-loader',
+              less: 'vue-style-loader!css-loader!less-loader'
+            }
+          }
+        }
+      },
+      {
+        test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
+        use: {
+          loader: 'url-loader',
+          query: {
+            limit: 10000,
+            name: 'imgs/[name].[ext]'
+          }
+        }
+      },
+      {
+        test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
+        use: {
+          loader: 'url-loader',
+          query: {
+            limit: 10000,
+            name: 'fonts/[name].[ext]'
+          }
+        }
+      }
+    ]
+  },
+  plugins: [
+    new VueLoaderPlugin(),
+    new MiniCssExtractPlugin({filename: 'styles.css'}),
+    new HtmlWebpackPlugin({
+      filename: 'index.html',
+      template: path.resolve(__dirname, '../src/index.ejs'),
+      templateParameters(compilation, assets, options) {
+        return {
+          compilation: compilation,
+          webpack: compilation.getStats().toJson(),
+          webpackConfig: compilation.options,
+          htmlWebpackPlugin: {
+            files: assets,
+            options: options,
+          },
+          process,
+        };
+      },
+      minify: {
+        collapseWhitespace: true,
+        removeAttributeQuotes: true,
+        removeComments: true
+      },
+      nodeModules: false
+    }),
+    new webpack.DefinePlugin({
+      'process.env.IS_WEB': 'true'
+    }),
+    new webpack.HotModuleReplacementPlugin(),
+    new webpack.NoEmitOnErrorsPlugin()
+  ],
+  output: {
+    filename: '[name].js',
+    path: path.join(__dirname, '../dist/web')
+  },
+  resolve: {
+    alias: {
+      '@': path.join(__dirname, '../src/renderer'),
+      'vue$': 'vue/dist/vue.esm.js'
+    },
+    extensions: ['.js', '.vue', '.json', '.css']
+  },
+  target: 'web'
+}
+
+/**
+ * Adjust webConfig for production settings
+ */
+if (process.env.NODE_ENV === 'production') {
+  webConfig.devtool = ''
+
+  webConfig.plugins.push(
+    new MinifyPlugin(),
+    new CopyWebpackPlugin([
+      {
+        from: path.join(__dirname, '../static'),
+        to: path.join(__dirname, '../dist/web/static'),
+        ignore: ['.*']
+      }
+    ]),
+    new webpack.DefinePlugin({
+      'process.env.NODE_ENV': '"production"'
+    }),
+    new webpack.LoaderOptionsPlugin({
+      minimize: true
+    })
+  )
+}
+
+module.exports = webConfig

+ 12 - 0
.gitignore

@@ -0,0 +1,12 @@
+.DS_Store
+dist/electron/*
+dist/web/*
+build/*
+!build/icons
+node_modules/
+npm-debug.log
+npm-debug.log.*
+thumbs.db
+!.gitkeep
+.idea
+/.idea

+ 36 - 0
.travis.yml

@@ -0,0 +1,36 @@
+osx_image: xcode8.3
+sudo: required
+dist: trusty
+language: c
+matrix:
+  include:
+  - os: osx
+  - os: linux
+    env: CC=clang CXX=clang++ npm_config_clang=1
+    compiler: clang
+cache:
+  directories:
+  - node_modules
+  - "$HOME/.electron"
+  - "$HOME/.cache"
+addons:
+  apt:
+    packages:
+    - libgnome-keyring-dev
+    - icnsutils
+before_install:
+- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install git-lfs; fi
+- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get install --no-install-recommends -y icnsutils graphicsmagick xz-utils; fi
+install:
+- nvm install 10
+- curl -o- -L https://yarnpkg.com/install.sh | bash
+- source ~/.bashrc
+- npm install -g xvfb-maybe
+- yarn
+before_script:
+- git lfs pull
+script:
+- yarn run build
+branches:
+  only:
+  - master

+ 51 - 0
README.md

@@ -0,0 +1,51 @@
+## 一.开发
+
+    # 建议使用淘宝镜像
+    npm config set registry http://registry.npm.taobao.org/
+    
+    # 安装依赖
+    npm install
+    
+    # 启动服务
+    npm run dev
+    
+## 二.发布
+
+    # 打包32位应用程序
+    npm run build:win32
+    
+    # 打包64位应用程序
+    npm run build
+    
+## 三.项目配置
+
+### 1.后台接口配置
+
+    config.js 内 apiUrl 配置后台接口地址
+    
+    ├─src
+    │  └─renderer
+    │    └─api
+    │      └─config.js
+
+### 2.应用更新配置
+
+    build目录下所有文件放置至线上服务器可访问地址即可
+    latest.yml文件内包含版本信息
+    更新模块会检测本地版本号是否低于线上版本
+    低于则会提示更新
+    
+    package.json 文件内 
+        version 字段 配置版本号(打包与更新检测会用到);
+        build --> publish --> url 字段 配置更新地址
+        
+    ├─src
+    │  └─package.json
+    
+### 3.更新调试相关
+
+    dev 下载的更新包位置在 C:\Users\DED\AppData\Roaming\Electron\__update__
+    build 下载的更新包位置在 C:\Users\DED\AppData\Roaming\learn_exam\__update__
+
+    
+    

+ 29 - 0
appveyor.yml

@@ -0,0 +1,29 @@
+version: 0.1.{build}
+
+branches:
+  only:
+    - master
+
+image: Visual Studio 2017
+platform:
+  - x64
+
+cache:
+  - node_modules
+  - '%APPDATA%\npm-cache'
+  - '%USERPROFILE%\.electron'
+  - '%USERPROFILE%\AppData\Local\Yarn\cache'
+
+init:
+  - git config --global core.autocrlf input
+
+install:
+  - ps: Install-Product node 8 x64
+  - git reset --hard HEAD
+  - yarn
+  - node --version
+
+build_script:
+  - yarn build
+
+test: off

BIN
build/icons/256x256.png


BIN
build/icons/icon.icns


BIN
build/icons/icon.ico


+ 0 - 0
dist/electron/.gitkeep


+ 0 - 0
dist/web/.gitkeep


Разница между файлами не показана из-за своего большого размера
+ 14772 - 0
package-lock.json


+ 115 - 0
package.json

@@ -0,0 +1,115 @@
+{
+  "name": "learn_exam",
+  "author": "dedsudiyu <42059156+dedsudiyu@users.noreply.github.com>",
+  "description": "An electron-vue project",
+  "license": null,
+  "main": "./dist/electron/main.js",
+  "scripts": {
+    "build": "node .electron-vue/build.js && electron-builder",
+    "build:win32": "node .electron-vue/build.js && electron-builder  --platform=win32 --arch=ia32",
+    "build:dir": "node .electron-vue/build.js && electron-builder --dir",
+    "build:clean": "cross-env BUILD_TARGET=clean node .electron-vue/build.js",
+    "build:web": "cross-env BUILD_TARGET=web node .electron-vue/build.js",
+    "dev": "node .electron-vue/dev-runner.js",
+    "pack": "npm run pack:main && npm run pack:renderer",
+    "pack:main": "cross-env NODE_ENV=production webpack --progress --colors --config .electron-vue/webpack.main.config.js",
+    "pack:renderer": "cross-env NODE_ENV=production webpack --progress --colors --config .electron-vue/webpack.renderer.config.js",
+    "postinstall": ""
+  },
+  "version": "0.0.1",
+  "build": {
+    "productName": "learn_exam",
+    "appId": "com.example.yourapp",
+    "publish": [
+      {
+        "provider": "generic",
+        "url": "http://192.168.1.43/labSystem/admin/statics/zhouchou/"
+      }
+    ],
+    "directories": {
+      "output": "build"
+    },
+    "files": [
+      "dist/electron/**/*"
+    ],
+    "dmg": {
+      "contents": [
+        {
+          "x": 410,
+          "y": 150,
+          "type": "link",
+          "path": "/Applications"
+        },
+        {
+          "x": 130,
+          "y": 150,
+          "type": "file"
+        }
+      ]
+    },
+    "mac": {
+      "icon": "build/icons/icon.icns"
+    },
+    "win": {
+      "icon": "build/icons/icon.ico"
+    },
+    "linux": {
+      "icon": "build/icons"
+    }
+  },
+  "dependencies": {
+    "axios": "^0.18.0",
+    "element-ui": "^2.15.14",
+    "font-awesome": "^4.7.0",
+    "js-cookie": "^3.0.5",
+    "js-md5": "^0.8.3",
+    "jsencrypt": "^3.3.2",
+    "vue": "^2.5.16",
+    "vue-electron": "^1.0.6",
+    "vue-router": "^3.0.1",
+    "vuex": "^3.0.1",
+    "vuex-electron": "^1.0.0"
+  },
+  "devDependencies": {
+    "ajv": "^6.5.0",
+    "babel-core": "^6.26.3",
+    "babel-loader": "^7.1.4",
+    "babel-minify-webpack-plugin": "^0.3.1",
+    "babel-plugin-transform-runtime": "^6.23.0",
+    "babel-preset-env": "^1.7.0",
+    "babel-preset-stage-0": "^6.24.1",
+    "babel-register": "^6.26.0",
+    "cfonts": "^2.1.2",
+    "chalk": "^2.4.1",
+    "copy-webpack-plugin": "^4.5.1",
+    "cross-env": "^5.1.6",
+    "css-loader": "^0.28.11",
+    "del": "^3.0.0",
+    "devtron": "^1.4.0",
+    "electron": "^2.0.4",
+    "electron-builder": "^20.44.4",
+    "electron-debug": "^1.5.0",
+    "electron-devtools-installer": "^2.2.4",
+    "electron-updater": "^3.1.2",
+    "file-loader": "^1.1.11",
+    "html-webpack-plugin": "^3.2.0",
+    "listr": "^0.14.3",
+    "mini-css-extract-plugin": "0.4.0",
+    "multispinner": "^0.2.1",
+    "node-loader": "^0.6.0",
+    "node-sass": "^4.14.1",
+    "sass-loader": "^7.3.1",
+    "style-loader": "^0.21.0",
+    "url-loader": "^1.0.1",
+    "vue-devtools": "^5.1.4",
+    "vue-html-loader": "^1.2.4",
+    "vue-loader": "^15.2.4",
+    "vue-style-loader": "^4.1.0",
+    "vue-template-compiler": "^2.5.16",
+    "webpack": "^4.15.1",
+    "webpack-cli": "^3.0.8",
+    "webpack-dev-server": "^3.1.4",
+    "webpack-hot-middleware": "^2.22.2",
+    "webpack-merge": "^4.1.3"
+  }
+}

+ 24 - 0
src/index.ejs

@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <title>learn_exam</title>
+    <% if (htmlWebpackPlugin.options.nodeModules) { %>
+      <!-- Add `node_modules/` to global paths so `require` works properly in development -->
+      <script>
+        require('module').globalPaths.push('<%= htmlWebpackPlugin.options.nodeModules.replace(/\\/g, '\\\\') %>')
+      </script>
+    <% } %>
+  </head>
+  <body>
+    <div id="app"></div>
+    <!-- Set `__static` path to static files in production -->
+    <% if (!process.browser) { %>
+      <script>
+        if (process.env.NODE_ENV !== 'development') window.__static = require('path').join(__dirname, '/static').replace(/\\/g, '\\\\')
+      </script>
+    <% } %>
+
+    <!-- webpack builds are automatically injected -->
+  </body>
+</html>

+ 18 - 0
src/main/electronApi.js

@@ -0,0 +1,18 @@
+const { app,ipcMain } = require('electron')
+const { autoUpdater } = require("electron-updater")
+// 退出程序
+ipcMain.on('app-close', () => {
+    app.quit();
+});
+// 安装更新 ev-update-now
+ipcMain.on('install-update', () => {
+    autoUpdater.quitAndInstall()
+})
+// 检查更新 ev-check-for-update
+ipcMain.on('inspect-update', () => {
+    autoUpdater.checkForUpdates()
+})
+// 下载更新 confirmDownloadUpdate
+ipcMain.on('download-update', () => {
+    autoUpdater.downloadUpdate();
+});

+ 31 - 0
src/main/index.dev.js

@@ -0,0 +1,31 @@
+/**
+ * This file is used specifically and only for development. It installs
+ * `electron-debug` & `vue-devtools`. There shouldn't be any need to
+ *  modify this file, but it can be used to extend your development
+ *  environment.
+ */
+
+/* eslint-disable */
+
+import { BrowserWindow } from 'electron' // new devtools
+const path = require('path'); // new devtools
+
+// Install `electron-debug` with `devtron`
+
+//解决报错(source: chrome-devtools://devtools/bundled/inspector.js)
+// require('electron-debug')({ showDevTools: true });
+require('electron-debug')();
+
+// Install `vue-devtools`
+require('electron').app.on('ready', () => {
+  // let installExtension = require('electron-devtools-installer')
+  // installExtension.default(installExtension.VUEJS_DEVTOOLS)
+  //   .then(() => {})
+  //   .catch(err => {
+  //     console.log('Unable to install `vue-devtools`: \n', err)
+  //   })
+    BrowserWindow.addDevToolsExtension(path.resolve(__dirname, '../../.devtools')) // new devtools
+});
+
+// Require `main` process to boot app
+require('./index');

+ 99 - 0
src/main/index.js

@@ -0,0 +1,99 @@
+import { app, BrowserWindow, screen } from 'electron'
+import '../renderer/store'
+const path = require('path')
+const { handleUpdate } = require('./update')
+const electronApi = require('./electronApi.js')
+
+/**
+ * Set `__static` path to static files in production
+ * https://simulatedgreg.gitbooks.io/electron-vue/content/en/using-static-assets.html
+ */
+if (process.env.NODE_ENV !== 'development') {
+  global.__static = require('path').join(__dirname, '/static').replace(/\\/g, '\\\\')
+}
+
+let mainWindow
+const winURL = process.env.NODE_ENV === 'development'
+  ? `http://localhost:9080`
+  : `file://${__dirname}/index.html`
+
+function createWindow () {
+  /**
+   * Initial window options
+   */
+  mainWindow = new BrowserWindow({
+    height: 563,
+    useContentSize: true,
+    width: 1000,
+    //配置
+    // 全屏
+    fullscreen: false,
+    autoHideMenuBar: true, //隐藏菜单
+    webPreferences: {
+        // 使渲染进程拥有node环境
+        nodeIntegration: true,
+        //关闭web权限检查,允许跨域
+        webSecurity: false,
+    },
+  })
+
+  mainWindow.loadURL(winURL)
+
+  //解决报错(source: chrome-devtools://devtools/bundled/inspector.js)
+  if (process.env.NODE_ENV === "development") {
+    mainWindow.webContents.on("did-frame-finish-load", () => {
+      mainWindow.webContents.once("devtools-opened", () => {
+        mainWindow.focus();
+      });
+      mainWindow.webContents.openDevTools();
+    });
+  }
+
+
+  mainWindow.on('closed', () => {
+    mainWindow = null
+  })
+
+  handleUpdate(mainWindow) // 在这里执行,并把mainWindow传入
+}
+
+app.on('ready', createWindow)
+
+
+app.on('window-all-closed', () => {
+  if (process.platform !== 'darwin') {
+    app.quit()
+  }
+})
+
+app.on('activate', () => {
+  if (mainWindow === null) {
+    createWindow()
+  }
+})
+
+app.on('ready', () => {
+    if (process.env.NODE_ENV !== 'production') {
+        require('vue-devtools').install()
+    }
+})
+
+/**
+ * Auto Updater
+ *
+ * Uncomment the following code below and install `electron-updater` to
+ * support auto updating. Code Signing with a valid certificate is required.
+ * https://simulatedgreg.gitbooks.io/electron-vue/content/en/using-electron-builder.html#auto-updating
+ */
+
+/*
+import { autoUpdater } from 'electron-updater'
+
+autoUpdater.on('update-downloaded', () => {
+  autoUpdater.quitAndInstall()
+})
+
+app.on('ready', () => {
+  if (process.env.NODE_ENV === 'production') autoUpdater.checkForUpdates()
+})
+ */

+ 44 - 0
src/main/update.js

@@ -0,0 +1,44 @@
+const { autoUpdater } = require("electron-updater")
+const { build } = require("../../package.json")
+function handleUpdate(mainWindow) {
+    autoUpdater.setFeedURL(build.publish[0].url);    // 设置下载地址
+    autoUpdater.autoDownload = false;                // 是否自动更新
+    // 检查更新出错
+    autoUpdater.on('error', (res) => {
+        sendUpdateMessage('error',res,'检查更新出错')
+    })
+    // 检查是否有版本更新
+    autoUpdater.on('checking-for-update', (res) => {
+        sendUpdateMessage('checking-for-update',res,'检查是否有版本更新')
+    })
+    // 检测到有版本更新
+    autoUpdater.on('update-available', (res) => {
+        sendUpdateMessage('update-available',res,'检测到有版本更新')
+    })
+    // 未发现有新版本
+    autoUpdater.on('update-not-available', (res) => {
+        sendUpdateMessage('update-not-available',res,'未发现有新版本')
+    })
+    // 更新下载进度事件
+    autoUpdater.on('download-progress', progressObj => {
+        // mainWindow.setProgressBar(progressObj.percent / 100)
+        sendUpdateMessage('download-progress',progressObj,'更新下载进度事件')
+    })
+    // 下载完成,询问用户是否更新
+    autoUpdater.on('update-downloaded', (event, releaseNotes, releaseName, releaseDate, updateUrl, quitAndUpdate) => {
+        mainWindow.webContents.send('ev-should-update', {
+            event,
+            releaseNotes,
+            releaseName,
+            releaseDate,
+            updateUrl,
+            quitAndUpdate
+        })
+    })
+    function sendUpdateMessage(type,res,text) {
+        mainWindow.webContents.send('ev-message', type,res,text)
+    }
+}
+module.exports = {
+    handleUpdate
+}

+ 88 - 0
src/renderer/App.vue

@@ -0,0 +1,88 @@
+<template>
+  <div id="app" :class="$route.path == '/codeHtml'?'codeHtmlPage':''"
+       :style="$route.path == '/codeHtml'?'width:'+innerWidth+'px!important;height:'+innerHeight+'px!important;':''">
+    <router-view></router-view>
+    <softwareUpdate></softwareUpdate>
+  </div>
+</template>
+
+<script>
+    import softwareUpdate from './components/softwareUpdate'
+  export default {
+    name: 'learn_exam',
+      components: {
+          softwareUpdate
+      },
+      data(){
+          return{
+              innerHeight:window.innerHeight,
+              innerWidth:window.innerWidth,
+          }
+      },
+      metaInfo() {
+          return {
+              title: this.$store.state.settings.dynamicTitle && this.$store.state.settings.title,
+              titleTemplate: title => {
+                  return title ? `${title} - ${process.env.VUE_APP_TITLE}` : process.env.VUE_APP_TITLE
+              },
+          }
+      },
+      mounted(){
+
+
+
+
+          this.banZoom();
+          //根据当前浏览器宽度与额定尺寸计算transform缩放值
+          document.getElementById('app').style.transform = `scale(${document.documentElement.clientWidth / 1920})`;
+          //根据当前浏览器宽度与额定尺寸计算当前浏览器可观看尺寸高度
+          document.getElementById('app').style.height = (window.innerHeight/(document.documentElement.clientWidth / 1920*100))*100+'px';
+          //当尺寸改变后从新计算
+          window.onresize = () => {
+              return (() => {
+                  document.getElementById('app').style.transform = `scale(${document.documentElement.clientWidth / 1920})`;
+                  document.getElementById('app').style.height = (window.innerHeight/(document.documentElement.clientWidth / 1920*100))*100+'px';
+
+              })();
+          };
+      },
+      methods:{
+          banZoom(){
+              // 禁止通过 ctrl + +/- 和  ctrl + 滚轮 对页面进行缩放
+              document.addEventListener('keydown', function (event) {
+                  if ((event.ctrlKey === true || event.metaKey === true) &&
+                      (event.which === 61 || event.which === 107 ||
+                          event.which === 173 || event.which === 109 ||
+                          event.which === 187 || event.which === 189)) {
+                      event.preventDefault()
+                  }
+              }, false)
+              // Chrome IE 360
+              window.addEventListener('mousewheel', function (event) {
+                  if (event.ctrlKey === true || event.metaKey) {
+                      event.preventDefault()
+                  }
+              }, {
+                  passive: false
+              })
+              // firefox
+              window.addEventListener('DOMMouseScroll', function (event) {
+                  if (event.ctrlKey === true || event.metaKey) {
+                      event.preventDefault()
+                  }
+              }, {
+                  passive: false
+              })
+          },
+      }
+  }
+</script>
+
+<style>
+  .el-drawer__container,.el-dialog__wrapper,.el-message-box__wrapper{
+    background: rgba(0,0,0,0.4);
+  }
+  .codeHtmlPage{
+    transform: scale(1)!important;
+  }
+</style>

+ 169 - 0
src/renderer/api/basicsModules/index.js

@@ -0,0 +1,169 @@
+import request from '@/utils/request'
+// 获取路由
+export const getRouters = () => {
+  return request({
+    url: '/system/menu/getRouters',
+    method: 'get'
+  })
+}
+
+// 登录方法
+export function login(account, password, code, uuid, userType) {
+  return request({
+    url: '/auth/login',
+    method: 'post',
+      data: { account, password, code, uuid,userType }
+  })
+}
+
+//手机号码登录
+export function phoneLogin(data) {
+  return request({
+    url: '/auth/login',
+    method: 'post',
+    data: data
+  })
+}
+//获取验证码
+export function sendCode(username) {
+  return request({
+    url: '/auth/send/code',
+    method: 'post',
+    data: { username }
+  })
+}
+
+// 注册方法
+export function register(data) {
+  return request({
+    url: '/auth/register',
+    headers: {
+      isToken: false
+    },
+    method: 'post',
+    data: data
+  })
+}
+
+// 刷新方法
+export function refreshToken() {
+  return request({
+    url: '/auth/refresh',
+    method: 'post'
+  })
+}
+
+// 获取用户详细信息
+export function getInfo() {
+  return request({
+    url: '/system/user/permission',
+    method: 'get'
+  })
+}
+
+// 退出方法
+export function logout() {
+  return request({
+    url: '/auth/logout',
+    method: 'get'
+  })
+}
+
+// 获取验证码
+export function getCodeImg() {
+  return request({
+    url: '/auth/captcha',
+    method: 'get'
+  })
+}
+
+// 获取首页配置
+export function initPage() {
+  return request({
+    url: '/system/config/initPage',
+    method: 'get'
+  })
+}
+
+// 查询用户个人信息
+export function getUserProfile() {
+  return request({
+    url: '/system/user/profile',
+    method: 'get'
+  })
+}
+
+// 用户密码重置
+export function updateUserPwd(oldPassword, newPassword) {
+  const data = {
+    oldPassword,
+    newPassword
+  }
+  return request({
+    url: '/system/user/profile/updatePwd',
+    method: 'put',
+    params: data
+  })
+}
+
+// 修改用户手机号
+export function changePhone(data) {
+  return request({
+    url: '/system/user/change/phone',
+    method: 'put',
+    params: data
+  })
+}
+
+// 上传电子签名
+export function genSign(data) {
+  return request({
+    url: '/system/user/genSign',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改电子签名
+export function updateSignature(data) {
+  return request({
+    url: '/system/user/updateSignature  ',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改用户信息
+export function upDataProfile(data) {
+  return request({
+    url: '/system/user/profile',
+    method: 'put',
+    data: data
+  })
+}
+
+//指纹-查询用户指纹录取数量
+export const fingerprintQuantity  = (data) => {
+  return request({
+    url: `/laboratory/haikang/userFinger/queryCount/`+data,
+    method: 'GET',
+  })
+};
+
+// 用户头像上传
+export function uploadAvatar(data) {
+  return request({
+    url: '/system/user/profile/avatar',
+    method: 'post',
+    data: data
+  })
+}
+
+//获取认证信息
+export function authInfo(query) {
+  return request({
+    url: '/auth/info',
+    method: 'get',
+    params: query
+  })
+}

+ 182 - 0
src/renderer/api/commonality/noPermission.js

@@ -0,0 +1,182 @@
+import request from '@/utils/request'
+
+// 根据参数键名查询参数值
+export function getConfigKey(configKey) {
+  return request({
+    url: '/system/config/configKey/' + configKey,
+    method: 'get'
+  })
+}
+
+// 根据字典类型查询字典数据信息
+export function getDicts(dictType) {
+  return request({
+    url: '/system/dict/item/option?dictCode=' + dictType,
+    method: 'get'
+  })
+}
+
+//查询当前用户下的预案触发数据
+export function selectTriggerInfo(query) {
+  return request({
+    url: '/laboratory/plan/selectTriggerInfo',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询我的所有消息
+export function myAlllistContent(query) {
+  return request({
+    url: '/laboratory/content/myAll/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询院系列表
+export function listDepartments() {
+  return request({
+    url: '/system/dept/departments/list',
+    method: 'get'
+  })
+}
+
+//查询楼栋/根据楼栋ID查询楼层(无权限)
+export function buildFloorGetlist(query) {
+  return request({
+    url: '/laboratory/buildFloor/getlist',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询用户列表
+export function listUser(query) {
+  return request({
+    url: '/system/user/getNotAuthList',
+    method: 'get',
+    params: query
+  })
+}
+
+//获取职位列表
+export function optionselect(query) {
+  return request({
+    url: '/system/post/optionselect',
+    method: 'get',
+    params: query
+  })
+}
+
+//查询分级管控管理工作详情
+export function gradeManageWorkInfo(recordId) {
+  return request({
+    url: '/laboratory/gradeManageWork/'+recordId,
+    method: 'get',
+  })
+}
+
+//向对应实验室发送语音(文字转语音)
+export function mangerVoice(data,id) {
+  return request({
+    url: '/laboratory/subject/manger/voice/'+id,
+    method: 'post',
+    params: data
+  })
+}
+
+// 删除安全准入资格
+export function delGroup(id) {
+  return request({
+    url: '/laboratory/group/' + id,
+    method: 'delete'
+  })
+}
+
+//获取当前用户登录信息
+export function getLoginUser(query) {
+  return request({
+    url: '/bottle/usegasApply/getLoginUser',
+    method: 'get',
+    params: query
+  })
+}
+
+//报警记录处理
+export function handle(data) {
+  return request({
+    url: '/chemical/hxpAlarmRecord/handleProcessing',
+    method: 'put',
+    data: data
+  })
+}
+
+// 查询检查推送信息配置列表
+export function listCheckConfig() {
+  return request({
+    url: '/laboratory/checkConfig/info',
+    method: 'get'
+  })
+}
+
+//获取当前用户登录信息
+export function getLoginUserAirbottle(query) {
+  return request({
+    url: '/airbottle/qualificationApplyManage/getLoginUser',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询实验室字典列表
+export function subjectDictList(data) {
+  return request({
+    url: '/laboratory/subject/getSubjectDict',
+    method: 'get',
+    params: data
+  })
+}
+// 上传电子签名
+export function genSign(data) {
+  return request({
+    url: '/system/user/genSign',
+    method: 'post',
+    data: data
+  })
+}
+// 修改电子签名
+export function updateSignature(data) {
+  return request({
+    url: '/system/user/updateSignature  ',
+    method: 'post',
+    data: data
+  })
+}
+
+//获取个人信息
+export function profile(query) {
+  return request({
+    url: '/system/user/profile',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询公共配置
+export function configInfo(data) {
+  return request({
+    url: '/auth/configInfo',
+    method: 'get',
+    params: data
+  })
+}
+/*=================================V3=================================*/
+//查询人员下拉裂变
+export function systemUserSelectUser(data) {
+  return request({
+    url: '/system/user/selectUser',
+    method: 'post',
+    data: data
+  })
+}

+ 412 - 0
src/renderer/api/commonality/permission.js

@@ -0,0 +1,412 @@
+import request from '@/utils/request'
+
+/*查询用户列表-下拉列表
+* userName : '', 名称
+* userType: '',  0.系统 1.老师 2.学生
+*/
+export function systemUserSelectUser(data) {
+  return request({
+    url: '/system/user/selectUser',
+    method: 'post',
+    data: data
+  })
+}
+
+//根据名称查询实验室
+export function subjectList(query) {
+  return request({
+    url: '/laboratory/subject/list/listAdmin',
+    method: 'get',
+    params: query
+  })
+}
+
+//获取实验室列表
+export function listInfo(query) {
+  return request({
+    url: '/laboratory/subject/listInfo',
+    method: 'get',
+    params: query
+  })
+}
+
+//获取当前账号学院数据
+export function filterDept(query) {
+  return request({
+    url: '/system/dept/filterDept',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询实验室类型下啦列表
+export function queryOption(data) {
+  return request({
+    url: '/laboratory/labMold/queryOption/',
+    method: 'post',
+    data: data
+  })
+}
+
+//获取检查单位
+export function treeselect(query) {
+  return request({
+    url: '/system/dept/treeselect',
+    method: 'get',
+    params: query
+  })
+}
+
+//查询学院列表(根据数据权限)
+export function getDeptNoAuthList(data) {
+  return request({
+    url: '/system/dept/getDeptNoAuthList?deptType=1',
+    method: 'get',
+    data: data
+  })
+}
+
+/*=================================V3=================================*/
+
+/*                分类获取公共配置
+* category        1.系统参数 2.公共配置
+* configType      1.基础配置 2.管控一体机 3.化学品终端 4.小程序配置 5.开发配置 6.首页配置
+*/
+export function getConfigByType(data) {
+  return request({
+    url: '/system/config/info/getConfigByType',
+    method: 'post',
+    data: data
+  })
+}
+
+/*                分类获取公共配置列表
+* category        1.系统参数 2.公共配置(系统参数页面 传1)
+* configType      1.基础配置 2.管控一体机 3.化学品终端 4.小程序配置 5.开发配置 6.首页配置(系统参数页面 传0)
+*/
+export function getConfigList(data) {
+  return request({
+    url: '/system/config/info/list',
+    method: 'post',
+    data: data
+  })
+}
+
+// 部门列表
+export function getDeptList(data) {
+  return request({
+    url: '/system/dept/list',
+    method: 'post',
+    data: data
+  })
+}
+
+//组织架构
+export function getDeptOrganizeStructure(data) {
+  return request({
+    url: '/system/dept/organizeStructure',
+    method: 'post',
+    data: data
+  })
+}
+
+
+/*                部门下拉列表
+* deptName        名称
+* level           查询级别
+* deptType        1.学院 0.非学院
+*/
+export function getDeptDropList(data) {
+  return request({
+    url: '/system/dept/dropList',
+    method: 'post',
+    data: data
+  })
+}
+
+// 新增部门
+export function setDeptAdd(data) {
+  return request({
+    url: '/system/dept/add',
+    method: 'post',
+    data: data
+  })
+}
+
+// 编辑部门
+export function setDeptUpdate(data) {
+  return request({
+    url: '/system/dept/update',
+    method: 'post',
+    data: data
+  })
+}
+
+// 删除部门
+export function setDeptDelete(data) {
+  return request({
+    url: '/system/dept/delete',
+    method: 'post',
+    data: data
+  })
+}
+
+// 部门排序
+export function setDeptSort(data) {
+  return request({
+    url: '/system/dept/sort',
+    method: 'post',
+    data: data
+  })
+}
+
+// 获取用户列表 userType 0.系统 1.教职工 2.学生 3.大屏(暂无用处)
+export function systemUserList(data) {
+  return request({
+    url: '/system/user/list',
+    method: 'post',
+    data: data
+  })
+}
+
+//新增用户数据
+export function systemUserAdd(data) {
+  return request({
+    url: '/system/user/add',
+    method: 'post',
+    data: data
+  })
+}
+
+//编辑用户数据
+export function systemUserUpdate(data) {
+  return request({
+    url: '/system/user/update',
+    method: 'post',
+    data: data
+  })
+}
+
+//修改用户状态(启用/停用&在职/离职)
+export function systemUserEditState(data) {
+  return request({
+    url: '/system/user/editState',
+    method: 'post',
+    data: data
+  })
+}
+
+//修改密码
+export function systemUserEditPasswd(data) {
+  return request({
+    url: '/system/user/editPasswd',
+    method: 'post',
+    data: data
+  })
+}
+
+//删除用户
+export function systemUserDelete(data) {
+  return request({
+    url: '/system/user/delete',
+    method: 'post',
+    data: data
+  })
+}
+
+//获取用户详情
+export function systemUserDetail(query) {
+  return request({
+    url: '/system/user/detail',
+    method: 'get',
+    params: query
+  })
+}
+
+//获取个人信息
+export function systemUserProfile(query) {
+  return request({
+    url: '/system/user/profile',
+    method: 'get',
+    params: query
+  })
+}
+
+//重置密码
+export function systemUserResetPasswd(data) {
+  return request({
+    url: '/system/user/resetPasswd',
+    method: 'post',
+    data: data
+  })
+}
+
+
+/*                自定义用户查询
+* userType        0.系统用户 1.教职工 2.学生  (必传)
+* userName        用户名
+* mobile          手机号
+* cardNum         卡号
+* account         账号
+* userIds         用户IDS
+* pageSize        不传默认返回10条
+*/
+export function systemUserSelect(data) {
+  return request({
+    url: '/system/user/select',
+    method: 'post',
+    data: data
+  })
+}
+
+/*                自定义获取专业/班级下拉列表
+* type            1.专业 2.班级 (必传)
+* referId         父类ID(院系ID,专业ID)
+* name            名称
+* state           状态
+*/
+export function systemUserMajorSelect(data) {
+  return request({
+    url: '/system/user/major/select',
+    method: 'post',
+    data: data
+  })
+}
+
+//添加-更新人脸
+export function systemUserFaceAddOrUpdate(data) {
+  return request({
+    url: '/system/user/face/addOrUpdate',
+    method: 'post',
+    data: data
+  })
+}
+
+//检测人脸
+export function systemUserFaceCheckFace(data) {
+  return request({
+    url: '/system/user/face/checkFace',
+    method: 'post',
+    data: data
+  })
+}
+
+//人脸信息详情
+export function systemUserFaceAddOrInfo(query) {
+  return request({
+    url: '/system/user/face/info',
+    method: 'get',
+    params: query
+  })
+}
+
+//通用上传接口
+export function systemFileUpload(data) {
+  return request({
+    url: '/system/file/upload',
+    method: 'post',
+    data: data
+  })
+}
+
+//商户下拉列表
+export function tenantDropList(data) {
+  return request({
+    url: '/system/tenant/dropList',
+    method: 'post',
+    data: data
+  })
+}
+
+//认证信息下拉列表
+export function authCustomerDropList(data) {
+  return request({
+    url: '/auth/customer/dropList',
+    method: 'post',
+    data: data
+  })
+}
+
+//角色下拉列表
+export function systemRoleDropList(data) {
+  return request({
+    url: '/system/role/dropList',
+    method: 'post',
+    data: data
+  })
+}
+
+//告警方式下拉列表
+export function iotAlarmTypeSelect(data) {
+  return request({
+    url: '/iot/alarm/type/select',
+    method: 'post',
+    data: data
+  })
+}
+
+/******************楼栋楼层*******************/
+//楼栋tree列表
+export function systemBuildingGetTreeList(data) {
+  return request({
+    url: '/system/building/getTreeList',
+    method: 'post',
+    data: data
+  })
+}
+
+// 查询实验室类型列表(不带分页)
+export function laboratoryClassMoldGetList(data) {
+  return request({
+    url: '/laboratory/classMold/getList',
+    method: 'post',
+    data: data
+  })
+}
+
+// 查询安全分级列表(不带分页)
+export function laboratoryClassLevelGetList(data) {
+  return request({
+    url: '/laboratory/classLevel/getList',
+    method: 'post',
+    data: data
+  })
+}
+
+// 查询安全分类列表(不带分页)
+export function laboratoryClassTypeGetList(data) {
+  return request({
+    url: '/laboratory/classType/getList',
+    method: 'post',
+    data: data
+  })
+}
+
+/* 查询楼栋楼层下拉列表(不带分页)
+* type        1.校区 2.楼栋 3.楼层
+*/
+export function systemBuildingGetOptList(data) {
+  return request({
+    url: '/system/building/getOptList',
+    method: 'post',
+    data: data
+  })
+}
+// 查询楼层下房间列表
+export function systemRoomInfoGetList(data) {
+  return request({
+    url: '/system/roomInfo/getList',
+    method: 'post',
+    data: data
+  })
+}
+
+//查询部门下拉树
+export function systemDeptList(data) {
+  return request({
+    url: '/system/dept/list',
+    method: 'post',
+    data: data
+  })
+}
+

+ 4 - 0
src/renderer/api/config.js

@@ -0,0 +1,4 @@
+const configData = {
+    apiUrl: 'http://192.168.1.9:8080',
+};
+export { configData }

+ 0 - 0
src/renderer/assets/.gitkeep


BIN
src/renderer/assets/ZDimages/basicsModules/1.png


BIN
src/renderer/assets/ZDimages/basicsModules/10.png


BIN
src/renderer/assets/ZDimages/basicsModules/2.png


BIN
src/renderer/assets/ZDimages/basicsModules/3.png


BIN
src/renderer/assets/ZDimages/basicsModules/4.png


BIN
src/renderer/assets/ZDimages/basicsModules/5.png


BIN
src/renderer/assets/ZDimages/basicsModules/6.png


BIN
src/renderer/assets/ZDimages/basicsModules/7.png


BIN
src/renderer/assets/ZDimages/basicsModules/8.png


BIN
src/renderer/assets/ZDimages/basicsModules/9.png


BIN
src/renderer/assets/ZDimages/basicsModules/code.png


BIN
src/renderer/assets/ZDimages/basicsModules/icon_dl_bbg.png


BIN
src/renderer/assets/ZDimages/basicsModules/icon_dl_mm.png


BIN
src/renderer/assets/ZDimages/basicsModules/icon_dl_yzm.png


BIN
src/renderer/assets/ZDimages/basicsModules/icon_dl_zh.png


BIN
src/renderer/assets/ZDimages/basicsModules/icon_grzx_bgl.png


BIN
src/renderer/assets/ZDimages/basicsModules/icon_grzx_sjh.png


BIN
src/renderer/assets/ZDimages/basicsModules/icon_grzx_xl.png


BIN
src/renderer/assets/ZDimages/basicsModules/icon_grzx_yx.png


BIN
src/renderer/assets/ZDimages/basicsModules/icon_grzx_zc.png


BIN
src/renderer/assets/ZDimages/basicsModules/icon_grzx_zw.png


BIN
src/renderer/assets/ZDimages/basicsModules/icon_grzx_zy.png


BIN
src/renderer/assets/ZDimages/basicsModules/icon_jzggl_xljt.png


BIN
src/renderer/assets/ZDimages/basicsModules/icon_jzgxx_dr.png


BIN
src/renderer/assets/ZDimages/basicsModules/icon_jzgxx_sc.png


BIN
src/renderer/assets/ZDimages/basicsModules/icon_scdzqm_sl.png


BIN
src/renderer/assets/ZDimages/basicsModules/icon_sy_aqda.png


BIN
src/renderer/assets/ZDimages/basicsModules/icon_sy_aqjc.png


BIN
src/renderer/assets/ZDimages/basicsModules/icon_sy_aqyuyks.png


BIN
src/renderer/assets/ZDimages/basicsModules/icon_sy_aqzr.png


BIN
src/renderer/assets/ZDimages/basicsModules/icon_sy_fjgk.png


BIN
src/renderer/assets/ZDimages/basicsModules/icon_sy_hxpgl.png


BIN
src/renderer/assets/ZDimages/basicsModules/icon_sy_qpjc.png


BIN
src/renderer/assets/ZDimages/basicsModules/icon_sy_xygl.png


BIN
src/renderer/assets/ZDimages/basicsModules/icon_sy_yjyj.png


+ 0 - 0
src/renderer/assets/ZDimages/basicsModules/icon_sy_zhgl.png


Некоторые файлы не были показаны из-за большого количества измененных файлов